Commit ade6c319 by Jim Wilson

Add -mabi=n32 support.

(mips_const_double_ok, mips_move_1word, mips_move_2words,
function_arg, override_options, mips_asm_file_start,
compute_frame_size, save_restore_insns, function_prologue,
mips_expand_prologue, function_epilogue, mips_function_value): Modify.
(mips_abi, mips_abi_string): Define

From-SVN: r12133
parent 0bc25b2b
...@@ -192,9 +192,16 @@ enum processor_type mips_cpu; ...@@ -192,9 +192,16 @@ enum processor_type mips_cpu;
/* which instruction set architecture to use. */ /* which instruction set architecture to use. */
int mips_isa; int mips_isa;
#ifdef MIPS_ABI_DEFAULT
/* which ABI to use. This is defined to a constant in mips.h if the target
doesn't support multiple ABIs. */
enum mips_abi_type mips_abi;
#endif
/* Strings to hold which cpu and instruction set architecture to use. */ /* Strings to hold which cpu and instruction set architecture to use. */
char *mips_cpu_string; /* for -mcpu=<xxx> */ char *mips_cpu_string; /* for -mcpu=<xxx> */
char *mips_isa_string; /* for -mips{1,2,3,4} */ char *mips_isa_string; /* for -mips{1,2,3,4} */
char *mips_abi_string; /* for -mabi={32,n32,64} */
/* Generating calls to position independent functions? */ /* Generating calls to position independent functions? */
enum mips_abicalls_type mips_abicalls; enum mips_abicalls_type mips_abicalls;
...@@ -487,7 +494,7 @@ mips_const_double_ok (op, mode) ...@@ -487,7 +494,7 @@ mips_const_double_ok (op, mode)
return TRUE; return TRUE;
/* ??? 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 (ABI_64BIT) if (mips_abi != ABI_32)
return FALSE; return FALSE;
REAL_VALUE_FROM_CONST_DOUBLE (d, op); REAL_VALUE_FROM_CONST_DOUBLE (d, op);
...@@ -1076,7 +1083,9 @@ mips_move_1word (operands, insn, unsignedp) ...@@ -1076,7 +1083,9 @@ mips_move_1word (operands, insn, unsignedp)
} }
else if (GP_REG_P (regno0)) else if (GP_REG_P (regno0))
ret = (INTVAL (op1) < 0) ? "li\t%0,%1\t\t\t# %X1" : "li\t%0,%X1\t\t# %1"; /* Don't use X format, because that will give out of range
numbers for 64 bit host and 32 bit target. */
ret = "li\t%0,%1\t\t\t# %X1";
} }
else if (code1 == CONST_DOUBLE && mode == SFmode) else if (code1 == CONST_DOUBLE && mode == SFmode)
...@@ -1463,11 +1472,17 @@ mips_move_2words (operands, insn) ...@@ -1463,11 +1472,17 @@ mips_move_2words (operands, insn)
a number that the assembler won't accept. */ a number that the assembler won't accept. */
ret = "dli\t%0,%X1\t\t# %1"; ret = "dli\t%0,%X1\t\t# %1";
} }
else else if (HOST_BITS_PER_WIDE_INT < 64)
{ {
operands[2] = GEN_INT (INTVAL (operands[1]) >= 0 ? 0 : -1); operands[2] = GEN_INT (INTVAL (operands[1]) >= 0 ? 0 : -1);
ret = "li\t%M0,%2\n\tli\t%L0,%1"; ret = "li\t%M0,%2\n\tli\t%L0,%1";
} }
else
{
operands[2] = GEN_INT (INTVAL (operands[1]) >> 32);
operands[1] = GEN_INT (INTVAL (operands[1]) << 32 >> 32);
ret = "li\t%M0,%2\n\tli\t%L0,%1";
}
} }
else if (code1 == MEM) else if (code1 == MEM)
...@@ -2877,7 +2892,7 @@ function_arg (cum, mode, type, named) ...@@ -2877,7 +2892,7 @@ function_arg (cum, mode, type, named)
switch (mode) switch (mode)
{ {
case SFmode: case SFmode:
if (! ABI_64BIT || mips_isa < 3) if (mips_abi == ABI_32)
{ {
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;
...@@ -2897,7 +2912,7 @@ function_arg (cum, mode, type, named) ...@@ -2897,7 +2912,7 @@ function_arg (cum, mode, type, named)
case DFmode: case DFmode:
if (! TARGET_64BIT) if (! TARGET_64BIT)
cum->arg_words += (cum->arg_words & 1); cum->arg_words += (cum->arg_words & 1);
if (! ABI_64BIT || mips_isa < 3) if (mips_abi == ABI_32)
regbase = ((cum->gp_reg_found regbase = ((cum->gp_reg_found
|| TARGET_SOFT_FLOAT || TARGET_SOFT_FLOAT
|| TARGET_SINGLE_FLOAT || TARGET_SINGLE_FLOAT
...@@ -3114,6 +3129,57 @@ override_options () ...@@ -3114,6 +3129,57 @@ override_options ()
mips_isa = 1; mips_isa = 1;
} }
#ifdef MIPS_ABI_DEFAULT
/* Get the ABI to use. Currently this code is only used for Irix 6. */
if (mips_abi_string == (char *) 0)
mips_abi = MIPS_ABI_DEFAULT;
else if (! strcmp (mips_abi_string, "32"))
mips_abi = ABI_32;
else if (! strcmp (mips_abi_string, "n32"))
mips_abi = ABI_N32;
else if (! strcmp (mips_abi_string, "64"))
mips_abi = ABI_64;
else
error ("bad value (%s) for -mabi= switch", mips_abi_string);
/* A specified ISA defaults the ABI if it was not specified. */
if (mips_abi_string == 0 && mips_isa_string)
{
if (mips_isa <= 2)
mips_abi = ABI_32;
else
mips_abi = ABI_64;
}
/* A specified ABI defaults the ISA if it was not specified. */
else if (mips_isa_string == 0 && mips_abi_string)
{
if (mips_abi == ABI_32)
mips_isa = 1;
else if (mips_abi == ABI_N32)
mips_isa = 3;
else
mips_isa = 4;
}
/* If both ABI and ISA were specified, check for conflicts. */
else if (mips_isa_string && mips_abi_string)
{
if ((mips_isa <= 2 && (mips_abi == ABI_N32 || mips_abi == ABI_64))
|| (mips_isa >= 3 && mips_abi == ABI_32))
error ("-mabi=%s does not support -mips%d", mips_abi_string, mips_isa);
}
/* Override TARGET_DEFAULT if necessary. */
if (mips_abi == ABI_32)
target_flags &= ~ (MASK_FLOAT64|MASK_64BIT);
/* ??? This doesn't work yet, so don't let people try to use it. */
if (mips_abi == ABI_32)
error ("The -mabi=32 support does not work yet.");
#else
if (mips_abi_string)
error ("This target does not support the -mabi switch.");
#endif
#ifdef MIPS_CPU_STRING_DEFAULT #ifdef MIPS_CPU_STRING_DEFAULT
/* ??? There is a minor inconsistency here. If the user specifies an ISA /* ??? There is a minor inconsistency here. If the user specifies an ISA
greater than that supported by the default processor, then the user gets greater than that supported by the default processor, then the user gets
...@@ -3232,7 +3298,7 @@ override_options () ...@@ -3232,7 +3298,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 (ABI_64BIT && mips_isa >= 3) if (mips_abi != ABI_32)
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. */
...@@ -4100,7 +4166,7 @@ mips_asm_file_start (stream) ...@@ -4100,7 +4166,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 (ABI_64BIT && mips_isa >= 3) if (mips_abi != ABI_32)
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
...@@ -4447,7 +4513,7 @@ compute_frame_size (size) ...@@ -4447,7 +4513,7 @@ compute_frame_size (size)
for leaf routines (total_size == extra_size) to save the gp reg. for leaf routines (total_size == extra_size) to save the gp reg.
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. */ save the gp reg. */
if (total_size == extra_size && ! (ABI_64BIT && mips_isa >= 3)) if (total_size == extra_size && mips_abi == ABI_32)
total_size = extra_size = 0; total_size = extra_size = 0;
else if (TARGET_ABICALLS) else if (TARGET_ABICALLS)
{ {
...@@ -4461,7 +4527,7 @@ compute_frame_size (size) ...@@ -4461,7 +4527,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 (ABI_64BIT && mips_isa >= 3) if (mips_abi != ABI_32)
total_size += MIPS_STACK_ALIGN (current_function_pretend_args_size); total_size += MIPS_STACK_ALIGN (current_function_pretend_args_size);
/* Save other computed information. */ /* Save other computed information. */
...@@ -4624,13 +4690,13 @@ save_restore_insns (store_p, large_reg, large_offset, file) ...@@ -4624,13 +4690,13 @@ save_restore_insns (store_p, large_reg, large_offset, file)
if (store_p) if (store_p)
emit_move_insn (mem_rtx, reg_rtx); emit_move_insn (mem_rtx, reg_rtx);
else if (!TARGET_ABICALLS || (ABI_64BIT && mips_isa >= 3) else if (!TARGET_ABICALLS || mips_abi != ABI_32
|| 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);
} }
else else
{ {
if (store_p || !TARGET_ABICALLS || (ABI_64BIT && mips_isa >= 3) if (store_p || !TARGET_ABICALLS || mips_abi != ABI_32
|| regno != (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST)) || regno != (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST))
fprintf (file, "\t%s\t%s,%ld(%s)\n", fprintf (file, "\t%s\t%s,%ld(%s)\n",
(TARGET_64BIT (TARGET_64BIT
...@@ -4803,7 +4869,7 @@ function_prologue (file, size) ...@@ -4803,7 +4869,7 @@ function_prologue (file, size)
current_frame_info.fmask, current_frame_info.fmask,
current_frame_info.fp_save_offset); current_frame_info.fp_save_offset);
if (TARGET_ABICALLS && ! (ABI_64BIT && mips_isa >= 3)) if (TARGET_ABICALLS && mips_abi == ABI_32)
{ {
char *sp_str = reg_names[STACK_POINTER_REGNUM]; char *sp_str = reg_names[STACK_POINTER_REGNUM];
...@@ -4928,7 +4994,7 @@ mips_expand_prologue () ...@@ -4928,7 +4994,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 ((! ABI_64BIT || mips_isa < 3) if (mips_abi == ABI_32
&& ((TYPE_ARG_TYPES (fntype) != 0 && ((TYPE_ARG_TYPES (fntype) != 0
&& (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node)) && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
|| (arg_name != (char *)0 || (arg_name != (char *)0
...@@ -4939,7 +5005,7 @@ mips_expand_prologue () ...@@ -4939,7 +5005,7 @@ mips_expand_prologue ()
rtx ptr = stack_pointer_rtx; rtx ptr = stack_pointer_rtx;
/* If we are doing svr4-abi, sp has already been decremented by tsize. */ /* If we are doing svr4-abi, sp has already been decremented by tsize. */
if (TARGET_ABICALLS && ! (ABI_64BIT && mips_isa >= 3)) if (TARGET_ABICALLS)
offset += tsize; offset += tsize;
for (; regno <= GP_ARG_LAST; regno++) for (; regno <= GP_ARG_LAST; regno++)
...@@ -4957,7 +5023,7 @@ mips_expand_prologue () ...@@ -4957,7 +5023,7 @@ mips_expand_prologue ()
rtx tsize_rtx = GEN_INT (tsize); rtx tsize_rtx = GEN_INT (tsize);
/* If we are doing svr4-abi, sp move is done by function_prologue. */ /* If we are doing svr4-abi, sp move is done by function_prologue. */
if (!TARGET_ABICALLS || (ABI_64BIT && mips_isa >= 3)) if (!TARGET_ABICALLS || mips_abi != ABI_32)
{ {
if (tsize > 32767) if (tsize > 32767)
{ {
...@@ -4984,7 +5050,7 @@ mips_expand_prologue () ...@@ -4984,7 +5050,7 @@ mips_expand_prologue ()
emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx)); emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
} }
if (TARGET_ABICALLS && (ABI_64BIT && mips_isa >= 3)) if (TARGET_ABICALLS && mips_abi != ABI_32)
emit_insn (gen_loadgp (XEXP (DECL_RTL (current_function_decl), 0))); emit_insn (gen_loadgp (XEXP (DECL_RTL (current_function_decl), 0)));
} }
...@@ -5107,7 +5173,7 @@ function_epilogue (file, size) ...@@ -5107,7 +5173,7 @@ function_epilogue (file, size)
save_restore_insns (FALSE, tmp_rtx, tsize, file); save_restore_insns (FALSE, tmp_rtx, tsize, file);
load_only_r31 = (((current_frame_info.mask load_only_r31 = (((current_frame_info.mask
& ~ (TARGET_ABICALLS && ! (ABI_64BIT && mips_isa >= 3) & ~ (TARGET_ABICALLS && mips_abi == ABI_32
? PIC_OFFSET_TABLE_MASK : 0)) ? PIC_OFFSET_TABLE_MASK : 0))
== RA_MASK) == RA_MASK)
&& current_frame_info.fmask == 0); && current_frame_info.fmask == 0);
...@@ -5428,7 +5494,7 @@ mips_select_section (decl, reloc) ...@@ -5428,7 +5494,7 @@ mips_select_section (decl, reloc)
} }
} }
#if ABI_64BIT #ifdef MIPS_ABI_DEFAULT
/* Support functions for the 64 bit ABI. */ /* Support functions for the 64 bit ABI. */
/* Return the register to be used for word INDEX of a variable with type TYPE /* Return the register to be used for word INDEX of a variable with type TYPE
...@@ -5483,7 +5549,7 @@ mips_function_value (valtype, func) ...@@ -5483,7 +5549,7 @@ mips_function_value (valtype, func)
if (mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT) if (mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT)
reg = FP_RETURN; reg = FP_RETURN;
else if (TREE_CODE (valtype) == RECORD_TYPE && mips_isa >= 3) else if (TREE_CODE (valtype) == RECORD_TYPE && mips_abi != ABI_32)
{ {
/* 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. */
......
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