Commit a53f72db by Gavin Romig-Koch Committed by Gavin Romig-Koch

Separate the 64 bit version of ABI_32 into ABI_O64.

	* config/mips/abi.h: Use ABI_O64, duplicating ABI_32 usage.
	* config/mips/iris6.h: Same.
	* config/mips/mips.md: Same.
	* config/mips/mips.c: Same; also add "-mabi=o64" option.
	* config/mips/mips.h: Same; also define ABI_O64.

From-SVN: r23809
parent 6bdb985f
Mon Nov 23 17:40:37 1998 Gavin Romig-Koch <gavin@cygnus.com>
* config/mips/abi.h: Use ABI_O64, duplicating ABI_32 usage.
* config/mips/iris6.h: Same.
* config/mips/mips.md: Same.
* config/mips/mips.c: Same; also add "-mabi=o64" option.
* config/mips/mips.h: Same; also define ABI_O64.
Mon Nov 23 17:02:27 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> Mon Nov 23 17:02:27 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* configure.in: Use AC_PREREQ(2.12.1). * configure.in: Use AC_PREREQ(2.12.1).
......
...@@ -27,18 +27,21 @@ Boston, MA 02111-1307, USA. */ ...@@ -27,18 +27,21 @@ Boston, MA 02111-1307, USA. */
#undef STACK_BOUNDARY #undef STACK_BOUNDARY
#define STACK_BOUNDARY \ #define STACK_BOUNDARY \
((mips_abi == ABI_32 || mips_abi == ABI_EABI) ? 64 : 128) ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
? 64 : 128)
#undef MIPS_STACK_ALIGN #undef MIPS_STACK_ALIGN
#define MIPS_STACK_ALIGN(LOC) \ #define MIPS_STACK_ALIGN(LOC) \
((mips_abi == ABI_32 || mips_abi == ABI_EABI) \ ((mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI) \
? ((LOC) + 7) & ~7 \ ? ((LOC) + 7) & ~7 \
: ((LOC) + 15) & ~15) : ((LOC) + 15) & ~15)
#undef GP_ARG_LAST #undef GP_ARG_LAST
#define GP_ARG_LAST (mips_abi == ABI_32 ? GP_REG_FIRST + 7 : GP_REG_FIRST + 11) #define GP_ARG_LAST ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? GP_REG_FIRST + 7 : GP_REG_FIRST + 11)
#undef FP_ARG_LAST #undef FP_ARG_LAST
#define FP_ARG_LAST (mips_abi == ABI_32 ? FP_REG_FIRST + 15 : FP_REG_FIRST + 19) #define FP_ARG_LAST ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? FP_REG_FIRST + 15 : FP_REG_FIRST + 19)
#undef SUBTARGET_CONDITIONAL_REGISTER_USAGE #undef SUBTARGET_CONDITIONAL_REGISTER_USAGE
#define SUBTARGET_CONDITIONAL_REGISTER_USAGE \ #define SUBTARGET_CONDITIONAL_REGISTER_USAGE \
...@@ -60,11 +63,12 @@ Boston, MA 02111-1307, USA. */ ...@@ -60,11 +63,12 @@ Boston, MA 02111-1307, USA. */
} }
#undef MAX_ARGS_IN_REGISTERS #undef MAX_ARGS_IN_REGISTERS
#define MAX_ARGS_IN_REGISTERS (mips_abi == ABI_32 ? 4 : 8) #define MAX_ARGS_IN_REGISTERS ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? 4 : 8)
#undef REG_PARM_STACK_SPACE #undef REG_PARM_STACK_SPACE
#define REG_PARM_STACK_SPACE(FNDECL) \ #define REG_PARM_STACK_SPACE(FNDECL) \
(mips_abi == ABI_32 \ ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? (MAX_ARGS_IN_REGISTERS*UNITS_PER_WORD) - FIRST_PARM_OFFSET (FNDECL) \ ? (MAX_ARGS_IN_REGISTERS*UNITS_PER_WORD) - FIRST_PARM_OFFSET (FNDECL) \
: 0) : 0)
...@@ -75,13 +79,15 @@ Boston, MA 02111-1307, USA. */ ...@@ -75,13 +79,15 @@ Boston, MA 02111-1307, USA. */
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \ ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\ && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\
: (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY \ : (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY \
&& (mips_abi == ABI_32 || mips_abi == ABI_EABI \ && (mips_abi == ABI_32 \
|| mips_abi == ABI_O64 \
|| mips_abi == ABI_EABI \
|| GET_MODE_CLASS (MODE) == MODE_INT))) \ || GET_MODE_CLASS (MODE) == MODE_INT))) \
? downward : upward)) ? downward : upward))
#undef RETURN_IN_MEMORY #undef RETURN_IN_MEMORY
#define RETURN_IN_MEMORY(TYPE) \ #define RETURN_IN_MEMORY(TYPE) \
(mips_abi == ABI_32 \ ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? TYPE_MODE (TYPE) == BLKmode \ ? TYPE_MODE (TYPE) == BLKmode \
: (int_size_in_bytes (TYPE) \ : (int_size_in_bytes (TYPE) \
> (mips_abi == ABI_EABI ? 2 * UNITS_PER_WORD : 16))) > (mips_abi == ABI_EABI ? 2 * UNITS_PER_WORD : 16)))
...@@ -97,7 +103,7 @@ extern struct rtx_def *mips_function_value (); ...@@ -97,7 +103,7 @@ extern struct rtx_def *mips_function_value ();
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \ #define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
{ int mips_off = (! current_function_varargs) && (! (CUM).last_arg_fp); \ { int mips_off = (! current_function_varargs) && (! (CUM).last_arg_fp); \
int mips_fp_off = (! current_function_varargs) && ((CUM).last_arg_fp); \ int mips_fp_off = (! current_function_varargs) && ((CUM).last_arg_fp); \
if ((mips_abi != ABI_32 \ if (((mips_abi != ABI_32 && mips_abi != ABI_O64) \
&& (CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off) \ && (CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off) \
|| (mips_abi == ABI_EABI \ || (mips_abi == ABI_EABI \
&& ! TARGET_SOFT_FLOAT \ && ! TARGET_SOFT_FLOAT \
...@@ -178,7 +184,7 @@ extern struct rtx_def *mips_function_value (); ...@@ -178,7 +184,7 @@ extern struct rtx_def *mips_function_value ();
} \ } \
} }
#define STRICT_ARGUMENT_NAMING (mips_abi != ABI_32) #define STRICT_ARGUMENT_NAMING (mips_abi != ABI_32 && mips_abi != ABI_O64)
/* A C expression that indicates when an argument must be passed by /* A C expression that indicates when an argument must be passed by
reference. If nonzero for an argument, a copy of that argument is reference. If nonzero for an argument, a copy of that argument is
......
...@@ -303,7 +303,7 @@ rdata_section () \ ...@@ -303,7 +303,7 @@ rdata_section () \
{ \ { \
if (in_section != in_rdata) \ if (in_section != in_rdata) \
{ \ { \
if (mips_abi != ABI_32) \ if (mips_abi != ABI_32 && mips_abi != ABI_O64) \
fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP_64); \ fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP_64); \
else \ else \
fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP_32); \ fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP_32); \
...@@ -394,7 +394,7 @@ while (0) ...@@ -394,7 +394,7 @@ while (0)
#define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \ #define ASM_OUTPUT_ALIGNED_LOCAL(STREAM, NAME, SIZE, ALIGN) \
do \ do \
{ \ { \
if (mips_abi != ABI_32) \ if (mips_abi != ABI_32 && mips_abi != ABI_O64) \
{ \ { \
fprintf (STREAM, "%s\n", BSS_SECTION_ASM_OP); \ fprintf (STREAM, "%s\n", BSS_SECTION_ASM_OP); \
mips_declare_object (STREAM, NAME, "", ":\n", 0); \ mips_declare_object (STREAM, NAME, "", ":\n", 0); \
...@@ -455,7 +455,8 @@ do { \ ...@@ -455,7 +455,8 @@ do { \
} while (0) } while (0)
#undef LOCAL_LABEL_PREFIX #undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX (mips_abi == ABI_32 ? "$" : ".") #define LOCAL_LABEL_PREFIX ((mips_abi == ABI_32 || mips_abi == ABI_O64) \
? "$" : ".")
/* Profiling is supported via libprof1.a not -lc_p as in Irix 3. */ /* Profiling is supported via libprof1.a not -lc_p as in Irix 3. */
/* ??? If no mabi=X option give, but a mipsX option is, then should depend /* ??? If no mabi=X option give, but a mipsX option is, then should depend
......
...@@ -565,7 +565,7 @@ mips_const_double_ok (op, mode) ...@@ -565,7 +565,7 @@ mips_const_double_ok (op, mode)
return 1; return 1;
/* ??? li.s does not work right with SGI's Irix 6 assembler. */ /* ??? li.s does not work right with SGI's Irix 6 assembler. */
if (mips_abi != ABI_32 && mips_abi != ABI_EABI) if (mips_abi != ABI_32 && mips_abi != ABI_O64 && mips_abi != ABI_EABI)
return 0; return 0;
REAL_VALUE_FROM_CONST_DOUBLE (d, op); REAL_VALUE_FROM_CONST_DOUBLE (d, op);
...@@ -3690,7 +3690,7 @@ function_arg (cum, mode, type, named) ...@@ -3690,7 +3690,7 @@ function_arg (cum, mode, type, named)
switch (mode) switch (mode)
{ {
case SFmode: case SFmode:
if (mips_abi == ABI_32) if (mips_abi == ABI_32 || mips_abi == ABI_O64)
{ {
if (cum->gp_reg_found || cum->arg_number >= 2 || TARGET_SOFT_FLOAT) if (cum->gp_reg_found || cum->arg_number >= 2 || TARGET_SOFT_FLOAT)
regbase = GP_ARG_FIRST; regbase = GP_ARG_FIRST;
...@@ -3726,7 +3726,7 @@ function_arg (cum, mode, type, named) ...@@ -3726,7 +3726,7 @@ function_arg (cum, mode, type, named)
cum->arg_words += cum->arg_words & 1; cum->arg_words += cum->arg_words & 1;
} }
if (mips_abi == ABI_32) if (mips_abi == ABI_32 || mips_abi == ABI_O64)
regbase = ((cum->gp_reg_found regbase = ((cum->gp_reg_found
|| TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT
|| cum->arg_number >= 2) || cum->arg_number >= 2)
...@@ -3782,7 +3782,7 @@ function_arg (cum, mode, type, named) ...@@ -3782,7 +3782,7 @@ function_arg (cum, mode, type, named)
abort (); abort ();
if (! type || TREE_CODE (type) != RECORD_TYPE || mips_abi == ABI_32 if (! type || TREE_CODE (type) != RECORD_TYPE || mips_abi == ABI_32
|| mips_abi == ABI_EABI || ! named) || mips_abi == ABI_EABI || mips_abi == ABI_O64 || ! named)
ret = gen_rtx (REG, mode, regbase + *arg_words + bias); ret = gen_rtx (REG, mode, regbase + *arg_words + bias);
else else
{ {
...@@ -4042,11 +4042,13 @@ override_options () ...@@ -4042,11 +4042,13 @@ override_options ()
} }
#ifdef MIPS_ABI_DEFAULT #ifdef MIPS_ABI_DEFAULT
/* Get the ABI to use. Currently this code is only used for Irix 6. */ /* Get the ABI to use. */
if (mips_abi_string == (char *) 0) if (mips_abi_string == (char *) 0)
mips_abi = MIPS_ABI_DEFAULT; mips_abi = MIPS_ABI_DEFAULT;
else if (! strcmp (mips_abi_string, "32")) else if (! strcmp (mips_abi_string, "32"))
mips_abi = ABI_32; mips_abi = ABI_32;
else if (! strcmp (mips_abi_string, "o64"))
mips_abi = ABI_O64;
else if (! strcmp (mips_abi_string, "n32")) else if (! strcmp (mips_abi_string, "n32"))
mips_abi = ABI_N32; mips_abi = ABI_N32;
else if (! strcmp (mips_abi_string, "64")) else if (! strcmp (mips_abi_string, "64"))
...@@ -4057,7 +4059,8 @@ override_options () ...@@ -4057,7 +4059,8 @@ override_options ()
error ("bad value (%s) for -mabi= switch", mips_abi_string); error ("bad value (%s) for -mabi= switch", mips_abi_string);
/* A specified ISA defaults the ABI if it was not specified. */ /* A specified ISA defaults the ABI if it was not specified. */
if (mips_abi_string == 0 && mips_isa_string && mips_abi != ABI_EABI) if (mips_abi_string == 0 && mips_isa_string
&& mips_abi != ABI_EABI && mips_abi != ABI_O64)
{ {
if (mips_isa <= 2) if (mips_isa <= 2)
mips_abi = ABI_32; mips_abi = ABI_32;
...@@ -4066,7 +4069,8 @@ override_options () ...@@ -4066,7 +4069,8 @@ override_options ()
} }
/* A specified ABI defaults the ISA if it was not specified. */ /* A specified ABI defaults the ISA if it was not specified. */
else if (mips_isa_string == 0 && mips_abi_string && mips_abi != ABI_EABI) else if (mips_isa_string == 0 && mips_abi_string
&& mips_abi != ABI_EABI && mips_abi != ABI_O64)
{ {
if (mips_abi == ABI_32) if (mips_abi == ABI_32)
mips_isa = 1; mips_isa = 1;
...@@ -4079,7 +4083,8 @@ override_options () ...@@ -4079,7 +4083,8 @@ override_options ()
/* If both ABI and ISA were specified, check for conflicts. */ /* If both ABI and ISA were specified, check for conflicts. */
else if (mips_isa_string && mips_abi_string) else if (mips_isa_string && mips_abi_string)
{ {
if ((mips_isa <= 2 && (mips_abi == ABI_N32 || mips_abi == ABI_64)) if ((mips_isa <= 2 && (mips_abi == ABI_N32 || mips_abi == ABI_64
|| mips_abi == ABI_O64))
|| (mips_isa >= 3 && mips_abi == ABI_32)) || (mips_isa >= 3 && mips_abi == ABI_32))
error ("-mabi=%s does not support -mips%d", mips_abi_string, mips_isa); error ("-mabi=%s does not support -mips%d", mips_abi_string, mips_isa);
} }
...@@ -4253,7 +4258,7 @@ override_options () ...@@ -4253,7 +4258,7 @@ override_options ()
fatal ("Only MIPS-III or MIPS-IV CPUs can support 64 bit gp registers"); fatal ("Only MIPS-III or MIPS-IV CPUs can support 64 bit gp registers");
} }
if (mips_abi != ABI_32) if (mips_abi != ABI_32 && mips_abi != ABI_O64)
flag_pcc_struct_return = 0; flag_pcc_struct_return = 0;
/* Tell halfpic.c that we have half-pic code if we do. */ /* Tell halfpic.c that we have half-pic code if we do. */
...@@ -5247,7 +5252,7 @@ mips_asm_file_start (stream) ...@@ -5247,7 +5252,7 @@ mips_asm_file_start (stream)
/* Start a section, so that the first .popsection directive is guaranteed /* Start a section, so that the first .popsection directive is guaranteed
to have a previously defined section to pop back to. */ to have a previously defined section to pop back to. */
if (mips_abi != ABI_32 && mips_abi != ABI_EABI) if (mips_abi != ABI_32 && mips_abi != ABI_O64 && mips_abi != ABI_EABI)
fprintf (stream, "\t.section\t.text\n"); fprintf (stream, "\t.section\t.text\n");
/* This code exists so that we can put all externs before all symbol /* This code exists so that we can put all externs before all symbol
...@@ -5551,7 +5556,8 @@ compute_frame_size (size) ...@@ -5551,7 +5556,8 @@ compute_frame_size (size)
The gp reg is callee saved in the 64 bit ABI, so all routines must The gp reg is callee saved in the 64 bit ABI, so all routines must
save the gp reg. This is not a leaf routine if -p, because of the save the gp reg. This is not a leaf routine if -p, because of the
call to mcount. */ call to mcount. */
if (total_size == extra_size && (mips_abi == ABI_32 || mips_abi == ABI_EABI) if (total_size == extra_size
&& (mips_abi == ABI_32 || mips_abi == ABI_O64 || mips_abi == ABI_EABI)
&& ! profile_flag) && ! profile_flag)
total_size = extra_size = 0; total_size = extra_size = 0;
else if (TARGET_ABICALLS) else if (TARGET_ABICALLS)
...@@ -5566,7 +5572,7 @@ compute_frame_size (size) ...@@ -5566,7 +5572,7 @@ compute_frame_size (size)
/* Add in space reserved on the stack by the callee for storing arguments /* Add in space reserved on the stack by the callee for storing arguments
passed in registers. */ passed in registers. */
if (mips_abi != ABI_32) if (mips_abi != ABI_32 && mips_abi != ABI_O64)
total_size += MIPS_STACK_ALIGN (current_function_pretend_args_size); total_size += MIPS_STACK_ALIGN (current_function_pretend_args_size);
/* The entry pseudo instruction will allocate 32 bytes on the stack. */ /* The entry pseudo instruction will allocate 32 bytes on the stack. */
...@@ -5821,7 +5827,8 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -5821,7 +5827,8 @@ save_restore_insns (store_p, large_reg, large_offset, file)
insn = emit_move_insn (mem_rtx, reg_rtx); insn = emit_move_insn (mem_rtx, reg_rtx);
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
} }
else if (!TARGET_ABICALLS || mips_abi != ABI_32 else if (!TARGET_ABICALLS
|| (mips_abi != ABI_32 && mips_abi != ABI_O64)
|| regno != (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST)) || regno != (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))
{ {
emit_move_insn (reg_rtx, mem_rtx); emit_move_insn (reg_rtx, mem_rtx);
...@@ -5834,7 +5841,8 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -5834,7 +5841,8 @@ save_restore_insns (store_p, large_reg, large_offset, file)
} }
else else
{ {
if (store_p || !TARGET_ABICALLS || mips_abi != ABI_32 if (store_p || !TARGET_ABICALLS
|| (mips_abi != ABI_32 && mips_abi != ABI_O64)
|| regno != (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST)) || regno != (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))
{ {
int r = regno; int r = regno;
...@@ -6208,7 +6216,7 @@ function_prologue (file, size) ...@@ -6208,7 +6216,7 @@ function_prologue (file, size)
fprintf (file, "\n"); fprintf (file, "\n");
} }
if (TARGET_ABICALLS && mips_abi == ABI_32) if (TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64))
{ {
char *sp_str = reg_names[STACK_POINTER_REGNUM]; char *sp_str = reg_names[STACK_POINTER_REGNUM];
...@@ -6336,7 +6344,7 @@ mips_expand_prologue () ...@@ -6336,7 +6344,7 @@ mips_expand_prologue ()
/* If this function is a varargs function, store any registers that /* If this function is a varargs function, store any registers that
would normally hold arguments ($4 - $7) on the stack. */ would normally hold arguments ($4 - $7) on the stack. */
if (mips_abi == ABI_32 if ((mips_abi == ABI_32 || mips_abi == ABI_O64)
&& (! mips_entry || mips_can_use_return_insn ()) && (! mips_entry || mips_can_use_return_insn ())
&& ((TYPE_ARG_TYPES (fntype) != 0 && ((TYPE_ARG_TYPES (fntype) != 0
&& (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
...@@ -6449,7 +6457,7 @@ mips_expand_prologue () ...@@ -6449,7 +6457,7 @@ mips_expand_prologue ()
/* If we are doing svr4-abi, sp move is done by /* If we are doing svr4-abi, sp move is done by
function_prologue. In mips16 mode with a large frame, we function_prologue. In mips16 mode with a large frame, we
save the registers before adjusting the stack. */ save the registers before adjusting the stack. */
if ((!TARGET_ABICALLS || mips_abi != ABI_32) if ((!TARGET_ABICALLS || (mips_abi != ABI_32 && mips_abi != ABI_O64))
&& (!TARGET_MIPS16 || tsize <= 32767)) && (!TARGET_MIPS16 || tsize <= 32767))
{ {
rtx insn; rtx insn;
...@@ -6496,7 +6504,7 @@ mips_expand_prologue () ...@@ -6496,7 +6504,7 @@ mips_expand_prologue ()
else if (reg_18_save != NULL_RTX) else if (reg_18_save != NULL_RTX)
emit_insn (reg_18_save); emit_insn (reg_18_save);
if ((!TARGET_ABICALLS || mips_abi != ABI_32) if ((!TARGET_ABICALLS || (mips_abi != ABI_32 && mips_abi != ABI_O64))
&& TARGET_MIPS16 && TARGET_MIPS16
&& tsize > 32767) && tsize > 32767)
{ {
...@@ -6527,7 +6535,7 @@ mips_expand_prologue () ...@@ -6527,7 +6535,7 @@ mips_expand_prologue ()
instructions when using the frame pointer by pointing the instructions when using the frame pointer by pointing the
frame pointer ahead of the argument space allocated on frame pointer ahead of the argument space allocated on
the stack. */ the stack. */
if ((! TARGET_ABICALLS || mips_abi != ABI_32) if ((! TARGET_ABICALLS || (mips_abi != ABI_32 && mips_abi != ABI_O64))
&& TARGET_MIPS16 && TARGET_MIPS16
&& tsize > 32767) && tsize > 32767)
{ {
...@@ -6570,7 +6578,7 @@ mips_expand_prologue () ...@@ -6570,7 +6578,7 @@ mips_expand_prologue ()
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
} }
if (TARGET_ABICALLS && mips_abi != ABI_32) if (TARGET_ABICALLS && (mips_abi != ABI_32 && mips_abi != ABI_O64))
emit_insn (gen_loadgp (XEXP (DECL_RTL (current_function_decl), 0), emit_insn (gen_loadgp (XEXP (DECL_RTL (current_function_decl), 0),
gen_rtx (REG, DImode, 25))); gen_rtx (REG, DImode, 25)));
} }
...@@ -6754,7 +6762,7 @@ mips_expand_epilogue () ...@@ -6754,7 +6762,7 @@ mips_expand_epilogue ()
/* The GP/PIC register is implicitly used by all SYMBOL_REFs, so if we /* The GP/PIC register is implicitly used by all SYMBOL_REFs, so if we
are going to restore it, then we must emit a blockage insn to are going to restore it, then we must emit a blockage insn to
prevent the scheduler from moving the restore out of the epilogue. */ prevent the scheduler from moving the restore out of the epilogue. */
else if (TARGET_ABICALLS && mips_abi != ABI_32 else if (TARGET_ABICALLS && mips_abi != ABI_32 && mips_abi != ABI_O64
&& (current_frame_info.mask && (current_frame_info.mask
& (1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST)))) & (1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))))
emit_insn (gen_blockage ()); emit_insn (gen_blockage ());
...@@ -6947,7 +6955,9 @@ mips_function_value (valtype, func) ...@@ -6947,7 +6955,9 @@ mips_function_value (valtype, func)
} }
else if (TREE_CODE (valtype) == RECORD_TYPE else if (TREE_CODE (valtype) == RECORD_TYPE
&& mips_abi != ABI_32 && mips_abi != ABI_EABI) && mips_abi != ABI_32
&& mips_abi != ABI_O64
&& mips_abi != ABI_EABI)
{ {
/* A struct with only one or two floating point fields is returned in /* A struct with only one or two floating point fields is returned in
the floating point registers. */ the floating point registers. */
...@@ -7409,8 +7419,8 @@ mips16_fp_args (file, fp_code, from_fp_p) ...@@ -7409,8 +7419,8 @@ mips16_fp_args (file, fp_code, from_fp_p)
int gparg, fparg; int gparg, fparg;
unsigned int f; unsigned int f;
/* This code only works for the original 32 bit ABI. */ /* This code only works for the original 32 bit ABI and the O64 ABI. */
if (mips_abi != ABI_32) if (mips_abi != ABI_32 && mips_abi != ABI_O64)
abort (); abort ();
if (from_fp_p) if (from_fp_p)
...@@ -7612,9 +7622,9 @@ build_mips16_call_stub (retval, fnmem, arg_size, fp_code) ...@@ -7612,9 +7622,9 @@ build_mips16_call_stub (retval, fnmem, arg_size, fp_code)
&& strncmp (XSTR (fn, 0), "__mips16_", 9) == 0) && strncmp (XSTR (fn, 0), "__mips16_", 9) == 0)
return 0; return 0;
/* This code will only work for the standard ABI. The other ABI's /* This code will only work for o32 and o64 abis. The other ABI's
require more sophisticated support. */ require more sophisticated support. */
if (mips_abi != ABI_32) if (mips_abi != ABI_32 && mips_abi != ABI_O64)
abort (); abort ();
/* We can only handle SFmode and DFmode floating point return /* We can only handle SFmode and DFmode floating point return
......
...@@ -76,12 +76,16 @@ enum processor_type { ...@@ -76,12 +76,16 @@ enum processor_type {
#define mips_cpu_attr ((enum attr_cpu)mips_cpu) #define mips_cpu_attr ((enum attr_cpu)mips_cpu)
/* Which ABI to use. These are constants because abi64.h must check their /* Which ABI to use. These are constants because abi64.h must check their
value at preprocessing time. */ value at preprocessing time.
ABI_32 (original 32, or o32), ABI_N32 (n32), ABI_64 (n64) are all
defined by SGI. ABI_O64 is o32 extended to work on a 64 bit machine. */
#define ABI_32 0 #define ABI_32 0
#define ABI_N32 1 #define ABI_N32 1
#define ABI_64 2 #define ABI_64 2
#define ABI_EABI 3 #define ABI_EABI 3
#define ABI_O64 4
#ifndef MIPS_ABI_DEFAULT #ifndef MIPS_ABI_DEFAULT
/* We define this away so that there is no extra runtime cost if the target /* We define this away so that there is no extra runtime cost if the target
...@@ -2187,12 +2191,16 @@ extern struct mips_frame_info current_frame_info; ...@@ -2187,12 +2191,16 @@ extern struct mips_frame_info current_frame_info;
&& (TO) == HARD_FRAME_POINTER_REGNUM) \ && (TO) == HARD_FRAME_POINTER_REGNUM) \
(OFFSET) = (current_frame_info.total_size \ (OFFSET) = (current_frame_info.total_size \
- current_function_outgoing_args_size \ - current_function_outgoing_args_size \
- ((mips_abi != ABI_32 && mips_abi != ABI_EABI) \ - ((mips_abi != ABI_32 \
&& mips_abi != ABI_O64 \
&& mips_abi != ABI_EABI) \
? current_function_pretend_args_size \ ? current_function_pretend_args_size \
: 0)); \ : 0)); \
else if ((FROM) == ARG_POINTER_REGNUM) \ else if ((FROM) == ARG_POINTER_REGNUM) \
(OFFSET) = (current_frame_info.total_size \ (OFFSET) = (current_frame_info.total_size \
- ((mips_abi != ABI_32 && mips_abi != ABI_EABI) \ - ((mips_abi != ABI_32 \
&& mips_abi != ABI_O64 \
&& mips_abi != ABI_EABI) \
? current_function_pretend_args_size \ ? current_function_pretend_args_size \
: 0)); \ : 0)); \
/* Some ABIs store 64 bits to the stack, but Pmode is 32 bits, \ /* Some ABIs store 64 bits to the stack, but Pmode is 32 bits, \
...@@ -2825,7 +2833,9 @@ typedef struct mips_args { ...@@ -2825,7 +2833,9 @@ typedef struct mips_args {
/* ??? Reject combining an address with a register for the MIPS \ /* ??? Reject combining an address with a register for the MIPS \
64 bit ABI, because the SGI assembler can not handle this. */ \ 64 bit ABI, because the SGI assembler can not handle this. */ \
if (!TARGET_DEBUG_A_MODE \ if (!TARGET_DEBUG_A_MODE \
&& (mips_abi == ABI_32 || mips_abi == ABI_EABI) \ && (mips_abi == ABI_32 \
|| mips_abi == ABI_O64 \
|| mips_abi == ABI_EABI) \
&& CONSTANT_ADDRESS_P (xplus1) \ && CONSTANT_ADDRESS_P (xplus1) \
&& ! mips_split_addresses \ && ! mips_split_addresses \
&& (!TARGET_EMBEDDED_PIC \ && (!TARGET_EMBEDDED_PIC \
...@@ -2856,7 +2866,9 @@ typedef struct mips_args { ...@@ -2856,7 +2866,9 @@ typedef struct mips_args {
|| GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \ || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
|| (GET_CODE (X) == CONST \ || (GET_CODE (X) == CONST \
&& ! (flag_pic && pic_address_needs_scratch (X)) \ && ! (flag_pic && pic_address_needs_scratch (X)) \
&& (mips_abi == ABI_32 || mips_abi == ABI_EABI))) \ && (mips_abi == ABI_32 \
|| mips_abi == ABI_O64 \
|| mips_abi == ABI_EABI))) \
&& (!HALF_PIC_P () || !HALF_PIC_ADDRESS_P (X))) && (!HALF_PIC_P () || !HALF_PIC_ADDRESS_P (X)))
/* Define this, so that when PIC, reload won't try to reload invalid /* Define this, so that when PIC, reload won't try to reload invalid
...@@ -2876,7 +2888,9 @@ typedef struct mips_args { ...@@ -2876,7 +2888,9 @@ typedef struct mips_args {
((GET_CODE (X) != CONST_DOUBLE \ ((GET_CODE (X) != CONST_DOUBLE \
|| mips_const_double_ok (X, GET_MODE (X))) \ || mips_const_double_ok (X, GET_MODE (X))) \
&& ! (GET_CODE (X) == CONST \ && ! (GET_CODE (X) == CONST \
&& mips_abi != ABI_32 && mips_abi != ABI_EABI) \ && mips_abi != ABI_32 \
&& mips_abi != ABI_O64 \
&& mips_abi != ABI_EABI) \
&& (! TARGET_MIPS16 || mips16_constant (X, GET_MODE (X), 0, 0))) && (! TARGET_MIPS16 || mips16_constant (X, GET_MODE (X), 0, 0)))
/* A C compound statement that attempts to replace X with a valid /* A C compound statement that attempts to replace X with a valid
...@@ -2939,7 +2953,9 @@ typedef struct mips_args { ...@@ -2939,7 +2953,9 @@ typedef struct mips_args {
if (GET_CODE (xinsn) == CONST \ if (GET_CODE (xinsn) == CONST \
&& ((flag_pic && pic_address_needs_scratch (xinsn)) \ && ((flag_pic && pic_address_needs_scratch (xinsn)) \
/* ??? SGI's Irix 6 assembler can't handle CONST. */ \ /* ??? SGI's Irix 6 assembler can't handle CONST. */ \
|| (mips_abi != ABI_32 && mips_abi != ABI_EABI))) \ || (mips_abi != ABI_32 \
&& mips_abi != ABI_O64 \
&& mips_abi != ABI_EABI))) \
{ \ { \
rtx ptr_reg = gen_reg_rtx (Pmode); \ rtx ptr_reg = gen_reg_rtx (Pmode); \
rtx constant = XEXP (XEXP (xinsn, 0), 1); \ rtx constant = XEXP (XEXP (xinsn, 0), 1); \
...@@ -4222,7 +4238,7 @@ do { \ ...@@ -4222,7 +4238,7 @@ do { \
fprintf (STREAM, "\t%s\t%sL%d-%sLS%d\n", \ fprintf (STREAM, "\t%s\t%sL%d-%sLS%d\n", \
Pmode == DImode ? ".dword" : ".word", \ Pmode == DImode ? ".dword" : ".word", \
LOCAL_LABEL_PREFIX, VALUE, LOCAL_LABEL_PREFIX, REL); \ LOCAL_LABEL_PREFIX, VALUE, LOCAL_LABEL_PREFIX, REL); \
else if (mips_abi == ABI_32) \ else if (mips_abi == ABI_32 || mips_abi == ABI_O64) \
fprintf (STREAM, "\t%s\t%sL%d\n", \ fprintf (STREAM, "\t%s\t%sL%d\n", \
Pmode == DImode ? ".gpdword" : ".gpword", \ Pmode == DImode ? ".gpdword" : ".gpword", \
LOCAL_LABEL_PREFIX, VALUE); \ LOCAL_LABEL_PREFIX, VALUE); \
...@@ -4479,7 +4495,9 @@ while (0) ...@@ -4479,7 +4495,9 @@ while (0)
/* See mips_expand_prologue's use of loadgp for when this should be /* See mips_expand_prologue's use of loadgp for when this should be
true. */ true. */
#define DONT_ACCESS_GBLS_AFTER_EPILOGUE (TARGET_ABICALLS && mips_abi != ABI_32) #define DONT_ACCESS_GBLS_AFTER_EPILOGUE (TARGET_ABICALLS \
&& mips_abi != ABI_32 \
&& mips_abi != ABI_O64)
/* In mips16 mode, we need to look through the function to check for /* In mips16 mode, we need to look through the function to check for
PC relative loads that are out of range. */ PC relative loads that are out of range. */
......
...@@ -8769,7 +8769,7 @@ move\\t%0,%z4\\n\\ ...@@ -8769,7 +8769,7 @@ move\\t%0,%z4\\n\\
/* ??? I don't know why this is necessary. This works around an /* ??? I don't know why this is necessary. This works around an
assembler problem that appears when a label is defined, then referenced assembler problem that appears when a label is defined, then referenced
in a switch table, then used in a `j' instruction. */ in a switch table, then used in a `j' instruction. */
else if (mips_abi != ABI_32) else if (mips_abi != ABI_32 && mips_abi != ABI_O64)
return \"%*b\\t%l0\"; return \"%*b\\t%l0\";
else else
return \"%*j\\t%l0\"; return \"%*j\\t%l0\";
...@@ -8960,7 +8960,7 @@ move\\t%0,%z4\\n\\ ...@@ -8960,7 +8960,7 @@ move\\t%0,%z4\\n\\
"* "*
{ {
/* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */ /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
if (mips_abi == ABI_32) if (mips_abi == ABI_32 || mips_abi == ABI_O64)
output_asm_insn (\".cpadd\\t%0\", operands); output_asm_insn (\".cpadd\\t%0\", operands);
return \"%*j\\t%0\"; return \"%*j\\t%0\";
}" }"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment