mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-18 05:40:23 +08:00
Fix various problems; Add -m{,no-}fused-madd, -m{,no-}no-update switches; Allow add/and/ior/xor of 32 bit constants
From-SVN: r14361
This commit is contained in:
parent
8b0c969eb1
commit
38c1f2d7e6
@ -104,6 +104,14 @@ enum rs6000_abi rs6000_current_abi;
|
||||
int rs6000_fpmem_offset;
|
||||
int rs6000_fpmem_size;
|
||||
|
||||
/* Debug flags */
|
||||
char *rs6000_debug_name;
|
||||
int rs6000_debug_stack; /* debug stack applications */
|
||||
int rs6000_debug_arg; /* debug argument handling */
|
||||
|
||||
/* Flag to say the TOC is initialized */
|
||||
int toc_initialized;
|
||||
|
||||
|
||||
/* Default register names. */
|
||||
char rs6000_reg_names[][8] =
|
||||
@ -297,6 +305,19 @@ rs6000_override_options (default_cpu)
|
||||
}
|
||||
}
|
||||
|
||||
/* Set debug flags */
|
||||
if (rs6000_debug_name)
|
||||
{
|
||||
if (!strcmp (rs6000_debug_name, "all"))
|
||||
rs6000_debug_stack = rs6000_debug_arg = 1;
|
||||
else if (!strcmp (rs6000_debug_name, "stack"))
|
||||
rs6000_debug_stack = 1;
|
||||
else if (!strcmp (rs6000_debug_name, "arg"))
|
||||
rs6000_debug_arg = 1;
|
||||
else
|
||||
error ("Unknown -mdebug-%s switch", rs6000_debug_name);
|
||||
}
|
||||
|
||||
#ifdef TARGET_REGNAMES
|
||||
/* If the user desires alternate register names, copy in the alternate names
|
||||
now. */
|
||||
@ -416,7 +437,8 @@ any_operand (op, mode)
|
||||
}
|
||||
|
||||
/* Returns 1 if op is the count register */
|
||||
int count_register_operand(op, mode)
|
||||
int
|
||||
count_register_operand(op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
@ -434,7 +456,8 @@ int count_register_operand(op, mode)
|
||||
|
||||
/* Returns 1 if op is memory location for float/int conversions that masquerades
|
||||
as a register. */
|
||||
int fpmem_operand(op, mode)
|
||||
int
|
||||
fpmem_operand(op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
@ -576,6 +599,17 @@ got_operand (op, mode)
|
||||
|| GET_CODE (op) == LABEL_REF);
|
||||
}
|
||||
|
||||
/* Return 1 if the operand is a simple references that can be loaded via
|
||||
the GOT (labels involving addition aren't allowed). */
|
||||
|
||||
int
|
||||
got_no_const_operand (op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
|
||||
}
|
||||
|
||||
/* Return the number of instructions it takes to form a constant in an
|
||||
integer register. */
|
||||
|
||||
@ -869,8 +903,7 @@ and_operand (op, mode)
|
||||
register rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
return (reg_or_short_operand (op, mode)
|
||||
|| logical_operand (op, mode)
|
||||
return (logical_operand (op, mode)
|
||||
|| mask_operand (op, mode));
|
||||
}
|
||||
|
||||
@ -1009,7 +1042,7 @@ small_data_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
#ifdef TARGET_SDATA
|
||||
#if TARGET_ELF
|
||||
rtx sym_ref, const_part;
|
||||
|
||||
if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
|
||||
@ -2168,6 +2201,7 @@ rs6000_finalize_pic ()
|
||||
rtx insn = get_insns ();
|
||||
rtx reg = NULL_RTX;
|
||||
rtx first_insn;
|
||||
rtx last_insn = NULL_RTX;
|
||||
|
||||
if (GET_CODE (insn) == NOTE)
|
||||
insn = next_nonnote_insn (insn);
|
||||
@ -2186,12 +2220,17 @@ rs6000_finalize_pic ()
|
||||
GOT_TOC_REGNUM,
|
||||
®);
|
||||
}
|
||||
|
||||
if (GET_CODE (insn) != NOTE)
|
||||
last_insn = insn;
|
||||
}
|
||||
|
||||
if (reg)
|
||||
{
|
||||
rtx init = gen_init_v4_pic (reg);
|
||||
emit_insn_before (init, first_insn);
|
||||
if (!optimize && last_insn)
|
||||
emit_insn_after (gen_rtx (USE, VOIDmode, reg), last_insn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2274,7 +2313,7 @@ rs6000_init_expanders ()
|
||||
|
||||
/* Print an operand. Recognize special options, documented below. */
|
||||
|
||||
#ifdef TARGET_SDATA
|
||||
#if TARGET_ELF
|
||||
#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
|
||||
#else
|
||||
#define SMALL_DATA_RELOC "sda21"
|
||||
@ -2875,8 +2914,10 @@ rs6000_makes_calls ()
|
||||
{
|
||||
rtx insn;
|
||||
|
||||
/* If we are profiling, we will be making a call to __mcount. */
|
||||
if (profile_flag)
|
||||
/* If we are profiling, we will be making a call to __mcount.
|
||||
Under the System V ABI's, we store the LR directly, so
|
||||
we don't need to do it here. */
|
||||
if (DEFAULT_ABI == ABI_AIX && profile_flag)
|
||||
return 1;
|
||||
|
||||
for (insn = get_insns (); insn; insn = next_insn (insn))
|
||||
@ -3066,7 +3107,8 @@ rs6000_stack_info ()
|
||||
|
||||
|
||||
/* Determine if we need to save the link register */
|
||||
if (regs_ever_live[65] || profile_flag
|
||||
if (regs_ever_live[65]
|
||||
|| (DEFAULT_ABI == ABI_AIX && profile_flag)
|
||||
#ifdef TARGET_RELOCATABLE
|
||||
|| (TARGET_RELOCATABLE && (get_pool_size () != 0))
|
||||
#endif
|
||||
@ -3336,8 +3378,9 @@ debug_stack_info (info)
|
||||
a constant pool. */
|
||||
|
||||
void
|
||||
rs6000_output_load_toc_table (file)
|
||||
rs6000_output_load_toc_table (file, reg)
|
||||
FILE *file;
|
||||
int reg;
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
@ -3349,8 +3392,45 @@ rs6000_output_load_toc_table (file)
|
||||
assemble_name (file, buf);
|
||||
fprintf (file, "\n");
|
||||
|
||||
/* possibly create the toc section */
|
||||
if (!toc_initialized)
|
||||
{
|
||||
toc_section ();
|
||||
function_section (current_function_decl);
|
||||
}
|
||||
|
||||
/* If not first call in this function, we need to put the
|
||||
different between .LCTOC1 and the address we get to right
|
||||
after the bl. It will mess up disassembling the instructions
|
||||
but that can't be helped. We will later need to bias the
|
||||
address before loading. */
|
||||
if (rs6000_pic_func_labelno != rs6000_pic_labelno)
|
||||
{
|
||||
char *init_ptr = (TARGET_64BIT) ? ".quad" : ".long";
|
||||
char *buf_ptr;
|
||||
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LCL", rs6000_pic_labelno);
|
||||
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
|
||||
STRIP_NAME_ENCODING (buf_ptr, buf);
|
||||
fprintf (file, "\t%s %s-", init_ptr, buf_ptr);
|
||||
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
|
||||
fprintf (file, "%s\n", buf_ptr);
|
||||
}
|
||||
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LCF", rs6000_pic_labelno);
|
||||
fprintf (file, "\tmflr %s\n", reg_names[30]);
|
||||
fprintf (file, "\tmflr %s\n", reg_names[reg]);
|
||||
|
||||
if (rs6000_pic_func_labelno != rs6000_pic_labelno)
|
||||
{
|
||||
if (TARGET_POWERPC64)
|
||||
fprintf (file, "\taddi %s,%s,8\n", reg_names[reg], reg_names[reg]);
|
||||
else if (TARGET_NEW_MNEMONICS)
|
||||
fprintf (file, "\taddi %s,%s,4\n", reg_names[reg], reg_names[reg]);
|
||||
else
|
||||
fprintf (file, "\tcal %s,4(%s)\n", reg_names[reg], reg_names[reg]);
|
||||
}
|
||||
|
||||
if (TARGET_POWERPC64)
|
||||
fprintf (file, "\tld");
|
||||
@ -3360,33 +3440,33 @@ rs6000_output_load_toc_table (file)
|
||||
fprintf (file, "\tl");
|
||||
|
||||
fprintf (file, " %s,(", reg_names[0]);
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_func_labelno);
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
|
||||
assemble_name (file, buf);
|
||||
fprintf (file, "-");
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
|
||||
assemble_name (file, buf);
|
||||
fprintf (file, ")(%s)\n", reg_names[30]);
|
||||
fprintf (file, ")(%s)\n", reg_names[reg]);
|
||||
asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
|
||||
reg_names[30], reg_names[0], reg_names[30]);
|
||||
reg_names[reg], reg_names[0], reg_names[reg]);
|
||||
rs6000_pic_labelno++;
|
||||
}
|
||||
else if (!TARGET_64BIT)
|
||||
{
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
|
||||
asm_fprintf (file, "\t{cau|addis} %s,%s,", reg_names[30], reg_names[0]);
|
||||
asm_fprintf (file, "\t{cau|addis} %s,%s,", reg_names[reg], reg_names[0]);
|
||||
assemble_name (file, buf);
|
||||
asm_fprintf (file, "@ha\n");
|
||||
if (TARGET_NEW_MNEMONICS)
|
||||
{
|
||||
asm_fprintf (file, "\taddi %s,%s,", reg_names[30], reg_names[30]);
|
||||
asm_fprintf (file, "\taddi %s,%s,", reg_names[reg], reg_names[reg]);
|
||||
assemble_name (file, buf);
|
||||
asm_fprintf (file, "@l\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
asm_fprintf (file, "\tcal %s,", reg_names[30]);
|
||||
asm_fprintf (file, "\tcal %s,", reg_names[reg]);
|
||||
assemble_name (file, buf);
|
||||
asm_fprintf (file, "@l(%s)\n", reg_names[30]);
|
||||
asm_fprintf (file, "@l(%s)\n", reg_names[reg]);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -3394,12 +3474,68 @@ rs6000_output_load_toc_table (file)
|
||||
|
||||
#else /* !USING_SVR4_H */
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 0);
|
||||
asm_fprintf (file, "\t{l|lwz} %s,", reg_names[30]);
|
||||
asm_fprintf (file, "\t{l|lwz} %s,", reg_names[reg]);
|
||||
assemble_name (file, buf);
|
||||
asm_fprintf (file, "(%s)\n", reg_names[2]);
|
||||
#endif /* USING_SVR4_H */
|
||||
}
|
||||
|
||||
|
||||
/* Emit the correct code for allocating stack space. If COPY_R12, make sure a copy
|
||||
of the old frame is left in r12. */
|
||||
|
||||
void
|
||||
rs6000_allocate_stack_space (file, size, copy_r12)
|
||||
FILE *file;
|
||||
int size;
|
||||
int copy_r12;
|
||||
{
|
||||
int neg_size = -size;
|
||||
if (TARGET_UPDATE)
|
||||
{
|
||||
if (size < 32767)
|
||||
asm_fprintf (file,
|
||||
(TARGET_32BIT) ? "\t{stu|stwu} %s,%d(%s)\n" : "\tstdu %s,%d(%s)\n",
|
||||
reg_names[1], neg_size, reg_names[1]);
|
||||
else
|
||||
{
|
||||
if (copy_r12)
|
||||
fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]);
|
||||
|
||||
asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n",
|
||||
reg_names[0], (neg_size >> 16) & 0xffff,
|
||||
reg_names[0], reg_names[0], neg_size & 0xffff);
|
||||
asm_fprintf (file,
|
||||
(TARGET_32BIT) ? "\t{stux|stwux} %s,%s,%s\n" : "\tstdux %s,%s,%s\n",
|
||||
reg_names[1], reg_names[1], reg_names[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]);
|
||||
if (size < 32767)
|
||||
{
|
||||
if (TARGET_NEW_MNEMONICS)
|
||||
fprintf (file, "\taddi %s,%s,%d\n", reg_names[1], reg_names[1], neg_size);
|
||||
else
|
||||
fprintf (file, "\tcal %s,%d(%s)\n", reg_names[1], neg_size, reg_names[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n",
|
||||
reg_names[0], (neg_size >> 16) & 0xffff,
|
||||
reg_names[0], reg_names[0], neg_size & 0xffff);
|
||||
asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", reg_names[1],
|
||||
reg_names[0], reg_names[1]);
|
||||
}
|
||||
|
||||
asm_fprintf (file,
|
||||
(TARGET_32BIT) ? "\t{st|stw} %s,0(%s)\n" : "\tstd %s,0(%s)\n",
|
||||
reg_names[12], reg_names[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Write function prologue. */
|
||||
void
|
||||
output_prolog (file, size)
|
||||
@ -3458,24 +3594,10 @@ output_prolog (file, size)
|
||||
if (info->push_p && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
|
||||
{
|
||||
if (info->total_size < 32767)
|
||||
{
|
||||
asm_fprintf (file,
|
||||
(TARGET_32BIT) ? "\t{stu|stwu} %s,%d(%s)\n" : "\tstdu %s,%d(%s)\n",
|
||||
reg_names[1], - info->total_size, reg_names[1]);
|
||||
sp_offset = info->total_size;
|
||||
}
|
||||
sp_offset = info->total_size;
|
||||
else
|
||||
{
|
||||
int neg_size = - info->total_size;
|
||||
sp_reg = 12;
|
||||
asm_fprintf (file, "\tmr %s,%s\n", reg_names[12], reg_names[1]);
|
||||
asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n",
|
||||
reg_names[0], (neg_size >> 16) & 0xffff,
|
||||
reg_names[0], reg_names[0], neg_size & 0xffff);
|
||||
asm_fprintf (file,
|
||||
(TARGET_32BIT) ? "\t{stux|stwux} %s,%s,%s\n" : "\tstdux %s,%s,%s\n",
|
||||
reg_names[1], reg_names[1], reg_names[0]);
|
||||
}
|
||||
sp_reg = 12;
|
||||
rs6000_allocate_stack_space (file, info->total_size, sp_reg == 12);
|
||||
}
|
||||
|
||||
/* If we use the link register, get it into r0. */
|
||||
@ -3589,24 +3711,9 @@ output_prolog (file, size)
|
||||
}
|
||||
}
|
||||
|
||||
/* Update stack and set back pointer and we have already done so for V.4. */
|
||||
/* Update stack and set back pointer unless this is V.4, which was done previously */
|
||||
if (info->push_p && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
|
||||
{
|
||||
if (info->total_size < 32767)
|
||||
asm_fprintf (file,
|
||||
(TARGET_32BIT) ? "\t{stu|stwu} %s,%d(%s)\n" : "\tstdu %s,%d(%s)\n",
|
||||
reg_names[1], - info->total_size, reg_names[1]);
|
||||
else
|
||||
{
|
||||
int neg_size = - info->total_size;
|
||||
asm_fprintf (file, "\t{liu|lis} %s,%d\n\t{oril|ori} %s,%s,%d\n",
|
||||
reg_names[0], (neg_size >> 16) & 0xffff,
|
||||
reg_names[0], reg_names[0], neg_size & 0xffff);
|
||||
asm_fprintf (file,
|
||||
(TARGET_32BIT) ? "\t{stux|stwux} %s,%s,%s\n" : "\tstdux %s,%s,%s\n",
|
||||
reg_names[1], reg_names[1], reg_names[0]);
|
||||
}
|
||||
}
|
||||
rs6000_allocate_stack_space (file, info->total_size, FALSE);
|
||||
|
||||
/* Set frame pointer, if needed. */
|
||||
if (frame_pointer_needed)
|
||||
@ -3671,9 +3778,10 @@ output_prolog (file, size)
|
||||
if (TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
|
||||
{
|
||||
#ifdef USING_SVR4_H
|
||||
rs6000_pic_func_labelno = rs6000_pic_labelno;
|
||||
if (!profile_flag)
|
||||
rs6000_pic_func_labelno = rs6000_pic_labelno;
|
||||
#endif
|
||||
rs6000_output_load_toc_table (file);
|
||||
rs6000_output_load_toc_table (file, 30);
|
||||
}
|
||||
|
||||
if (DEFAULT_ABI == ABI_NT)
|
||||
@ -4287,55 +4395,115 @@ output_function_profiler (file, labelno)
|
||||
int i, j;
|
||||
char buf[100];
|
||||
|
||||
if (DEFAULT_ABI != ABI_AIX)
|
||||
abort ();
|
||||
|
||||
/* Set up a TOC entry for the profiler label. */
|
||||
toc_section ();
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LPC", labelno);
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
switch (DEFAULT_ABI)
|
||||
{
|
||||
fputs ("\t.long ", file);
|
||||
assemble_name (file, buf);
|
||||
putc ('\n', file);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs ("\t.tc\t", file);
|
||||
assemble_name (file, buf);
|
||||
fputs ("[TC],", file);
|
||||
assemble_name (file, buf);
|
||||
putc ('\n', file);
|
||||
}
|
||||
text_section ();
|
||||
default:
|
||||
abort ();
|
||||
|
||||
case ABI_V4:
|
||||
case ABI_SOLARIS:
|
||||
case ABI_AIX_NODESC:
|
||||
fprintf (file, "\tmflr %s\n", reg_names[0]);
|
||||
if (flag_pic == 1)
|
||||
{
|
||||
fprintf (file, "\tbl _GLOBAL_OFFSET_TABLE_@local-4\n");
|
||||
fprintf (file, "\tmflr %s\n", reg_names[11]);
|
||||
fprintf (file, "\t%s %s,", (TARGET_NEW_MNEMONICS) ? "lwz" : "l",
|
||||
reg_names[11]);
|
||||
assemble_name (file, buf);
|
||||
fprintf (file, "@got(%s)\n", reg_names[11]);
|
||||
}
|
||||
#if TARGET_ELF
|
||||
else if (flag_pic > 1 || TARGET_RELOCATABLE)
|
||||
{
|
||||
fprintf (file, "\tstw %s,4(%s)\n", reg_names[0], reg_names[1]);
|
||||
fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
|
||||
assemble_name (file, buf);
|
||||
fprintf (file, "X = .-.LCTOC1\n");
|
||||
fprintf (file, "\t.long ");
|
||||
assemble_name (file, buf);
|
||||
fputs ("\n\t.previous\n", file);
|
||||
rs6000_pic_func_labelno = rs6000_pic_labelno;
|
||||
rs6000_output_load_toc_table (file, 11);
|
||||
fprintf (file, "\t%s %s,", (TARGET_NEW_MNEMONICS) ? "lwz" : "l",
|
||||
reg_names[11]);
|
||||
assemble_name (file, buf);
|
||||
fprintf (file, "X(%s)\n", reg_names[11]);
|
||||
}
|
||||
#endif
|
||||
else if (TARGET_NEW_MNEMONICS)
|
||||
{
|
||||
fprintf (file, "\taddis %s,%s,", reg_names[11], reg_names[11]);
|
||||
assemble_name (file, buf);
|
||||
fprintf (file, "@ha\n");
|
||||
fprintf (file, "\tstw %s,4(%s)\n", reg_names[0], reg_names[1]);
|
||||
fprintf (file, "\taddi %s,%s,", reg_names[11], reg_names[11]);
|
||||
assemble_name (file, buf);
|
||||
fputs ("@l\n", file);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (file, "\tcau %s,%s,", reg_names[11], reg_names[11]);
|
||||
assemble_name (file, buf);
|
||||
fprintf (file, "@ha\n");
|
||||
fprintf (file, "\tst %s,4(%s)\n", reg_names[0], reg_names[1]);
|
||||
fprintf (file, "\tcal %s,", reg_names[11]);
|
||||
assemble_name (file, buf);
|
||||
fprintf (file, "@l(%s)\n", reg_names[11]);
|
||||
}
|
||||
|
||||
fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
|
||||
break;
|
||||
|
||||
case ABI_AIX:
|
||||
/* Set up a TOC entry for the profiler label. */
|
||||
toc_section ();
|
||||
ASM_OUTPUT_INTERNAL_LABEL (file, "LPC", labelno);
|
||||
if (TARGET_MINIMAL_TOC)
|
||||
{
|
||||
fputs ("\t.long ", file);
|
||||
assemble_name (file, buf);
|
||||
putc ('\n', file);
|
||||
}
|
||||
else
|
||||
{
|
||||
fputs ("\t.tc\t", file);
|
||||
assemble_name (file, buf);
|
||||
fputs ("[TC],", file);
|
||||
assemble_name (file, buf);
|
||||
putc ('\n', file);
|
||||
}
|
||||
text_section ();
|
||||
|
||||
/* Figure out last used parameter register. The proper thing to do is
|
||||
to walk incoming args of the function. A function might have live
|
||||
parameter registers even if it has no incoming args. */
|
||||
|
||||
for (last_parm_reg = 10;
|
||||
last_parm_reg > 2 && ! regs_ever_live [last_parm_reg];
|
||||
last_parm_reg--)
|
||||
;
|
||||
for (last_parm_reg = 10;
|
||||
last_parm_reg > 2 && ! regs_ever_live [last_parm_reg];
|
||||
last_parm_reg--)
|
||||
;
|
||||
|
||||
/* Save parameter registers in regs 23-30. Don't overwrite reg 31, since
|
||||
it might be set up as the frame pointer. */
|
||||
|
||||
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
|
||||
asm_fprintf (file, "\tmr %d,%d\n", j, i);
|
||||
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
|
||||
asm_fprintf (file, "\tmr %d,%d\n", j, i);
|
||||
|
||||
/* Load location address into r3, and call mcount. */
|
||||
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LPC", labelno);
|
||||
asm_fprintf (file, "\t{l|lwz} %s,", reg_names[3]);
|
||||
assemble_name (file, buf);
|
||||
asm_fprintf (file, "(%s)\n\tbl %s\n", reg_names[2], RS6000_MCOUNT);
|
||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LPC", labelno);
|
||||
asm_fprintf (file, "\t{l|lwz} %s,", reg_names[3]);
|
||||
assemble_name (file, buf);
|
||||
asm_fprintf (file, "(%s)\n\tbl %s\n", reg_names[2], RS6000_MCOUNT);
|
||||
|
||||
/* Restore parameter registers. */
|
||||
|
||||
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
|
||||
asm_fprintf (file, "\tmr %d,%d\n", i, j);
|
||||
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
|
||||
asm_fprintf (file, "\tmr %d,%d\n", i, j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust the cost of a scheduling dependency. Return the new cost of
|
||||
|
@ -208,33 +208,33 @@ Boston, MA 02111-1307, USA. */
|
||||
extern int target_flags;
|
||||
|
||||
/* Use POWER architecture instructions and MQ register. */
|
||||
#define MASK_POWER 0x01
|
||||
#define MASK_POWER 0x00000001
|
||||
|
||||
/* Use POWER2 extensions to POWER architecture. */
|
||||
#define MASK_POWER2 0x02
|
||||
#define MASK_POWER2 0x00000002
|
||||
|
||||
/* Use PowerPC architecture instructions. */
|
||||
#define MASK_POWERPC 0x04
|
||||
#define MASK_POWERPC 0x00000004
|
||||
|
||||
/* Use PowerPC General Purpose group optional instructions, e.g. fsqrt. */
|
||||
#define MASK_PPC_GPOPT 0x08
|
||||
#define MASK_PPC_GPOPT 0x00000008
|
||||
|
||||
/* Use PowerPC Graphics group optional instructions, e.g. fsel. */
|
||||
#define MASK_PPC_GFXOPT 0x10
|
||||
#define MASK_PPC_GFXOPT 0x00000010
|
||||
|
||||
/* Use PowerPC-64 architecture instructions. */
|
||||
#define MASK_POWERPC64 0x20
|
||||
#define MASK_POWERPC64 0x00000020
|
||||
|
||||
/* Use revised mnemonic names defined for PowerPC architecture. */
|
||||
#define MASK_NEW_MNEMONICS 0x40
|
||||
#define MASK_NEW_MNEMONICS 0x00000040
|
||||
|
||||
/* Disable placing fp constants in the TOC; can be turned on when the
|
||||
TOC overflows. */
|
||||
#define MASK_NO_FP_IN_TOC 0x80
|
||||
#define MASK_NO_FP_IN_TOC 0x00000080
|
||||
|
||||
/* Disable placing symbol+offset constants in the TOC; can be turned on when
|
||||
the TOC overflows. */
|
||||
#define MASK_NO_SUM_IN_TOC 0x100
|
||||
#define MASK_NO_SUM_IN_TOC 0x00000100
|
||||
|
||||
/* Output only one TOC entry per module. Normally linking fails if
|
||||
there are more than 16K unique variables/constants in an executable. With
|
||||
@ -243,25 +243,27 @@ extern int target_flags;
|
||||
|
||||
This is at the cost of having 2 extra loads and one extra store per
|
||||
function, and one less allocatable register. */
|
||||
#define MASK_MINIMAL_TOC 0x200
|
||||
#define MASK_MINIMAL_TOC 0x00000200
|
||||
|
||||
/* Nonzero for the 64bit model: ints, longs, and pointers are 64 bits. */
|
||||
#define MASK_64BIT 0x400
|
||||
#define MASK_64BIT 0x00000400
|
||||
|
||||
/* Disable use of FPRs. */
|
||||
#define MASK_SOFT_FLOAT 0x800
|
||||
#define MASK_SOFT_FLOAT 0x00000800
|
||||
|
||||
/* Enable load/store multiple, even on powerpc */
|
||||
#define MASK_MULTIPLE 0x1000
|
||||
#define MASK_MULTIPLE_SET 0x2000
|
||||
#define MASK_MULTIPLE 0x00001000
|
||||
#define MASK_MULTIPLE_SET 0x00002000
|
||||
|
||||
/* Use string instructions for block moves */
|
||||
#define MASK_STRING 0x4000
|
||||
#define MASK_STRING_SET 0x8000
|
||||
#define MASK_STRING 0x00004000
|
||||
#define MASK_STRING_SET 0x00008000
|
||||
|
||||
/* Temporary debug switches */
|
||||
#define MASK_DEBUG_STACK 0x10000
|
||||
#define MASK_DEBUG_ARG 0x20000
|
||||
/* Disable update form of load/store */
|
||||
#define MASK_NO_UPDATE 0x00010000
|
||||
|
||||
/* Disable fused multiply/add operations */
|
||||
#define MASK_NO_FUSED_MADD 0x00020000
|
||||
|
||||
#define TARGET_POWER (target_flags & MASK_POWER)
|
||||
#define TARGET_POWER2 (target_flags & MASK_POWER2)
|
||||
@ -279,11 +281,13 @@ extern int target_flags;
|
||||
#define TARGET_MULTIPLE_SET (target_flags & MASK_MULTIPLE_SET)
|
||||
#define TARGET_STRING (target_flags & MASK_STRING)
|
||||
#define TARGET_STRING_SET (target_flags & MASK_STRING_SET)
|
||||
#define TARGET_DEBUG_STACK (target_flags & MASK_DEBUG_STACK)
|
||||
#define TARGET_DEBUG_ARG (target_flags & MASK_DEBUG_ARG)
|
||||
#define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE)
|
||||
#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
|
||||
|
||||
#define TARGET_32BIT (! TARGET_64BIT)
|
||||
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
|
||||
#define TARGET_UPDATE (! TARGET_NO_UPDATE)
|
||||
#define TARGET_FUSED_MADD (! TARGET_NO_FUSED_MADD)
|
||||
|
||||
/* Pseudo target to indicate whether the object format is ELF
|
||||
(to get around not having conditional compilation in the md file) */
|
||||
@ -366,8 +370,10 @@ extern int target_flags;
|
||||
{"string", MASK_STRING | MASK_STRING_SET}, \
|
||||
{"no-string", - MASK_STRING}, \
|
||||
{"no-string", MASK_STRING_SET}, \
|
||||
{"debug-stack", MASK_DEBUG_STACK}, \
|
||||
{"debug-arg", MASK_DEBUG_ARG}, \
|
||||
{"update", - MASK_NO_UPDATE}, \
|
||||
{"no-update", MASK_NO_UPDATE}, \
|
||||
{"fused-madd", - MASK_NO_FUSED_MADD}, \
|
||||
{"no-fused-madd", MASK_NO_FUSED_MADD}, \
|
||||
SUBTARGET_SWITCHES \
|
||||
{"", TARGET_DEFAULT}}
|
||||
|
||||
@ -427,6 +433,8 @@ extern enum processor_type rs6000_cpu;
|
||||
{ \
|
||||
{"cpu=", &rs6000_select[1].string}, \
|
||||
{"tune=", &rs6000_select[2].string}, \
|
||||
{"debug-", &rs6000_debug_name}, \
|
||||
{"debug=", &rs6000_debug_name}, \
|
||||
SUBTARGET_OPTIONS \
|
||||
}
|
||||
|
||||
@ -441,6 +449,14 @@ struct rs6000_cpu_select
|
||||
|
||||
extern struct rs6000_cpu_select rs6000_select[];
|
||||
|
||||
/* Debug support */
|
||||
extern char *rs6000_debug_name; /* Name for -mdebug-xxxx option */
|
||||
extern int rs6000_debug_stack; /* debug stack applications */
|
||||
extern int rs6000_debug_arg; /* debug argument handling */
|
||||
|
||||
#define TARGET_DEBUG_STACK rs6000_debug_stack
|
||||
#define TARGET_DEBUG_ARG rs6000_debug_arg
|
||||
|
||||
/* Sometimes certain combinations of command options do not make sense
|
||||
on a particular target machine. You can define a macro
|
||||
`OVERRIDE_OPTIONS' to take account of this. This macro, if
|
||||
@ -1811,6 +1827,7 @@ typedef struct rs6000_args
|
||||
{ if (LEGITIMATE_INDIRECT_ADDRESS_P (X)) \
|
||||
goto ADDR; \
|
||||
if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
|
||||
&& TARGET_UPDATE \
|
||||
&& LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0))) \
|
||||
goto ADDR; \
|
||||
if (LEGITIMATE_SMALL_DATA_P (MODE, X)) \
|
||||
@ -1904,9 +1921,9 @@ typedef struct rs6000_args
|
||||
&& ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), \
|
||||
(TARGET_32BIT ? 4 : 8))) \
|
||||
goto LABEL; \
|
||||
if (GET_CODE (ADDR) == PRE_INC) \
|
||||
if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_INC) \
|
||||
goto LABEL; \
|
||||
if (GET_CODE (ADDR) == PRE_DEC) \
|
||||
if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_DEC) \
|
||||
goto LABEL; \
|
||||
if (GET_CODE (ADDR) == LO_SUM) \
|
||||
goto LABEL; \
|
||||
@ -2096,59 +2113,74 @@ typedef struct rs6000_args
|
||||
/* Provide the costs of a rtl expression. This is in the body of a
|
||||
switch on CODE. */
|
||||
|
||||
#define RTX_COSTS(X,CODE,OUTER_CODE) \
|
||||
case MULT: \
|
||||
switch (rs6000_cpu) \
|
||||
{ \
|
||||
case PROCESSOR_RIOS1: \
|
||||
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
|
||||
? COSTS_N_INSNS (5) \
|
||||
: INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
|
||||
? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
|
||||
case PROCESSOR_RIOS2: \
|
||||
case PROCESSOR_MPCCORE: \
|
||||
return COSTS_N_INSNS (2); \
|
||||
case PROCESSOR_PPC601: \
|
||||
return COSTS_N_INSNS (5); \
|
||||
case PROCESSOR_PPC603: \
|
||||
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
|
||||
? COSTS_N_INSNS (5) \
|
||||
: INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
|
||||
? COSTS_N_INSNS (2) : COSTS_N_INSNS (3)); \
|
||||
case PROCESSOR_PPC403: \
|
||||
case PROCESSOR_PPC604: \
|
||||
case PROCESSOR_PPC620: \
|
||||
return COSTS_N_INSNS (4); \
|
||||
} \
|
||||
case DIV: \
|
||||
case MOD: \
|
||||
if (GET_CODE (XEXP (X, 1)) == CONST_INT \
|
||||
&& exact_log2 (INTVAL (XEXP (X, 1))) >= 0) \
|
||||
return COSTS_N_INSNS (2); \
|
||||
/* otherwise fall through to normal divide. */ \
|
||||
case UDIV: \
|
||||
case UMOD: \
|
||||
switch (rs6000_cpu) \
|
||||
{ \
|
||||
case PROCESSOR_RIOS1: \
|
||||
return COSTS_N_INSNS (19); \
|
||||
case PROCESSOR_RIOS2: \
|
||||
return COSTS_N_INSNS (13); \
|
||||
case PROCESSOR_MPCCORE: \
|
||||
return COSTS_N_INSNS (6); \
|
||||
case PROCESSOR_PPC403: \
|
||||
return COSTS_N_INSNS (33); \
|
||||
case PROCESSOR_PPC601: \
|
||||
return COSTS_N_INSNS (36); \
|
||||
case PROCESSOR_PPC603: \
|
||||
return COSTS_N_INSNS (37); \
|
||||
case PROCESSOR_PPC604: \
|
||||
case PROCESSOR_PPC620: \
|
||||
return COSTS_N_INSNS (20); \
|
||||
} \
|
||||
case FFS: \
|
||||
return COSTS_N_INSNS (4); \
|
||||
case MEM: \
|
||||
#define RTX_COSTS(X,CODE,OUTER_CODE) \
|
||||
case PLUS: \
|
||||
return ((GET_CODE (XEXP (X, 1)) == CONST_INT \
|
||||
&& (unsigned HOST_WIDE_INT) ((INTVAL (XEXP (X, 1)) \
|
||||
+ 0x8000) >= 0x10000)) \
|
||||
? COSTS_N_INSNS (2) \
|
||||
: COSTS_N_INSNS (1)); \
|
||||
case AND: \
|
||||
return ((non_and_cint_operand (XEXP (X, 1), SImode)) \
|
||||
? COSTS_N_INSNS (2) \
|
||||
: COSTS_N_INSNS (1)); \
|
||||
case IOR: \
|
||||
case XOR: \
|
||||
return ((non_logical_cint_operand (XEXP (X, 1), SImode)) \
|
||||
? COSTS_N_INSNS (2) \
|
||||
: COSTS_N_INSNS (1)); \
|
||||
case MULT: \
|
||||
switch (rs6000_cpu) \
|
||||
{ \
|
||||
case PROCESSOR_RIOS1: \
|
||||
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
|
||||
? COSTS_N_INSNS (5) \
|
||||
: INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
|
||||
? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
|
||||
case PROCESSOR_RIOS2: \
|
||||
case PROCESSOR_MPCCORE: \
|
||||
return COSTS_N_INSNS (2); \
|
||||
case PROCESSOR_PPC601: \
|
||||
return COSTS_N_INSNS (5); \
|
||||
case PROCESSOR_PPC603: \
|
||||
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
|
||||
? COSTS_N_INSNS (5) \
|
||||
: INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
|
||||
? COSTS_N_INSNS (2) : COSTS_N_INSNS (3)); \
|
||||
case PROCESSOR_PPC403: \
|
||||
case PROCESSOR_PPC604: \
|
||||
case PROCESSOR_PPC620: \
|
||||
return COSTS_N_INSNS (4); \
|
||||
} \
|
||||
case DIV: \
|
||||
case MOD: \
|
||||
if (GET_CODE (XEXP (X, 1)) == CONST_INT \
|
||||
&& exact_log2 (INTVAL (XEXP (X, 1))) >= 0) \
|
||||
return COSTS_N_INSNS (2); \
|
||||
/* otherwise fall through to normal divide. */ \
|
||||
case UDIV: \
|
||||
case UMOD: \
|
||||
switch (rs6000_cpu) \
|
||||
{ \
|
||||
case PROCESSOR_RIOS1: \
|
||||
return COSTS_N_INSNS (19); \
|
||||
case PROCESSOR_RIOS2: \
|
||||
return COSTS_N_INSNS (13); \
|
||||
case PROCESSOR_MPCCORE: \
|
||||
return COSTS_N_INSNS (6); \
|
||||
case PROCESSOR_PPC403: \
|
||||
return COSTS_N_INSNS (33); \
|
||||
case PROCESSOR_PPC601: \
|
||||
return COSTS_N_INSNS (36); \
|
||||
case PROCESSOR_PPC603: \
|
||||
return COSTS_N_INSNS (37); \
|
||||
case PROCESSOR_PPC604: \
|
||||
case PROCESSOR_PPC620: \
|
||||
return COSTS_N_INSNS (20); \
|
||||
} \
|
||||
case FFS: \
|
||||
return COSTS_N_INSNS (4); \
|
||||
case MEM: \
|
||||
/* MEM should be slightly more expensive than (plus (reg) (const)) */ \
|
||||
return 5;
|
||||
|
||||
@ -2373,8 +2405,6 @@ toc_section () \
|
||||
{ \
|
||||
if (TARGET_MINIMAL_TOC) \
|
||||
{ \
|
||||
static int toc_initialized = 0; \
|
||||
\
|
||||
/* toc_section is always called at least once from ASM_FILE_START, \
|
||||
so this is guaranteed to always be defined once and only once \
|
||||
in each file. */ \
|
||||
@ -2396,6 +2426,9 @@ toc_section () \
|
||||
in_section = toc; \
|
||||
}
|
||||
|
||||
/* Flag to say the TOC is initialized */
|
||||
extern int toc_initialized;
|
||||
|
||||
/* This macro produces the initial definition of a function name.
|
||||
On the RS/6000, we need to place an extra '.' in the function name and
|
||||
output the function descriptor.
|
||||
@ -2998,6 +3031,7 @@ do { \
|
||||
{"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
|
||||
{"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
|
||||
{"got_no_const_operand", {SYMBOL_REF, LABEL_REF}}, \
|
||||
{"easy_fp_constant", {CONST_DOUBLE}}, \
|
||||
{"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
|
||||
{"lwa_operand", {SUBREG, MEM, REG}}, \
|
||||
@ -3058,6 +3092,7 @@ extern int reg_or_neg_short_operand ();
|
||||
extern int reg_or_u_short_operand ();
|
||||
extern int reg_or_cint_operand ();
|
||||
extern int got_operand ();
|
||||
extern int got_no_const_operand ();
|
||||
extern int num_insns_constant ();
|
||||
extern int easy_fp_constant ();
|
||||
extern int volatile_mem_operand ();
|
||||
|
@ -859,15 +859,17 @@
|
||||
;; Discourage ai/addic because of carry but provide it in an alternative
|
||||
;; allowing register zero as source.
|
||||
(define_insn "addsi3"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r")
|
||||
(plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b")
|
||||
(match_operand:SI 2 "add_operand" "r,I,I,J")))]
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r,r")
|
||||
(plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b,b")
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "r,I,I,J,n")))]
|
||||
""
|
||||
"@
|
||||
{cax|add} %0,%1,%2
|
||||
{cal %0,%2(%1)|addi %0,%1,%2}
|
||||
{ai|addic} %0,%1,%2
|
||||
{cau|addis} %0,%1,%v2")
|
||||
{cau|addis} %0,%1,%v2
|
||||
#"
|
||||
[(set_attr "length" "4,4,4,4,8")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
|
||||
@ -1646,16 +1648,18 @@
|
||||
[(set_attr "type" "idiv")])
|
||||
|
||||
(define_insn "andsi3"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
|
||||
(and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
|
||||
(match_operand:SI 2 "and_operand" "?r,L,K,J")))
|
||||
(clobber (match_scratch:CC 3 "=X,X,x,x"))]
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
|
||||
(and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "?r,L,K,J,n")))
|
||||
(clobber (match_scratch:CC 3 "=X,X,x,x,x"))]
|
||||
""
|
||||
"@
|
||||
and %0,%1,%2
|
||||
{rlinm|rlwinm} %0,%1,0,%m2,%M2
|
||||
{andil.|andi.} %0,%1,%b2
|
||||
{andiu.|andis.} %0,%1,%u2")
|
||||
{andiu.|andis.} %0,%1,%u2
|
||||
#"
|
||||
[(set_attr "length" "4,4,4,4,8")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
|
||||
@ -1687,54 +1691,37 @@
|
||||
[(set_attr "type" "compare,compare,compare,delayed_compare")])
|
||||
|
||||
;; Take a AND with a constant that cannot be done in a single insn and try to
|
||||
;; split it into two insns. This does not verify that the insns are valid
|
||||
;; since this need not be done as combine will do it.
|
||||
;; split it into two insns.
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
(and:SI (match_operand:SI 1 "gpc_reg_operand" "")
|
||||
(match_operand:SI 2 "non_and_cint_operand" "")))]
|
||||
""
|
||||
[(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))
|
||||
(set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))]
|
||||
(match_operand:SI 2 "non_and_cint_operand" "")))
|
||||
(clobber (match_scratch:CC 3 ""))]
|
||||
"reload_completed"
|
||||
[(parallel [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 4))) (clobber (match_dup 6))])
|
||||
(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 5))) (clobber (match_dup 7))])]
|
||||
"
|
||||
{
|
||||
int maskval = INTVAL (operands[2]);
|
||||
int i, transitions, last_bit_value;
|
||||
int orig = maskval, first_c = maskval, second_c;
|
||||
|
||||
/* We know that MASKVAL must have more than 2 bit-transitions. Start at
|
||||
the low-order bit and count for the third transition. When we get there,
|
||||
make a first mask that has everything to the left of that position
|
||||
a one. Then make the second mask to turn off whatever else is needed. */
|
||||
|
||||
for (i = 1, transitions = 0, last_bit_value = maskval & 1; i < 32; i++)
|
||||
{
|
||||
if (((maskval >>= 1) & 1) != last_bit_value)
|
||||
last_bit_value ^= 1, transitions++;
|
||||
|
||||
if (transitions > 2)
|
||||
{
|
||||
first_c |= (~0) << i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
second_c = orig | ~ first_c;
|
||||
|
||||
operands[3] = gen_rtx (CONST_INT, VOIDmode, first_c);
|
||||
operands[4] = gen_rtx (CONST_INT, VOIDmode, second_c);
|
||||
operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff0000);
|
||||
operands[5] = GEN_INT (INTVAL (operands[2]) & 0x0000ffff);
|
||||
operands[6] = ((mask_constant (INTVAL (operands[4])))
|
||||
? gen_rtx (SCRATCH, CCmode)
|
||||
: operands[3]);
|
||||
operands[7] = operands[3];
|
||||
}")
|
||||
|
||||
(define_insn "iorsi3"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
|
||||
(ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
|
||||
(match_operand:SI 2 "logical_operand" "r,K,J")))]
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
|
||||
(ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "r,K,J,n")))]
|
||||
""
|
||||
"@
|
||||
or %0,%1,%2
|
||||
{oril|ori} %0,%1,%b2
|
||||
{oriu|oris} %0,%1,%u2")
|
||||
{oriu|oris} %0,%1,%u2
|
||||
#"
|
||||
[(set_attr "length" "4,4,4,8")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:CC 0 "cc_reg_operand" "=x")
|
||||
@ -1758,7 +1745,7 @@
|
||||
[(set_attr "type" "compare")])
|
||||
|
||||
;; Split an IOR that we can't do in one insn into two insns, each of which
|
||||
;; does one 16-bit part. This is used by combine.
|
||||
;; does one 16-bit part.
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
@ -1769,20 +1756,21 @@
|
||||
(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]
|
||||
"
|
||||
{
|
||||
operands[3] = gen_rtx (CONST_INT, VOIDmode,
|
||||
INTVAL (operands[2]) & 0xffff0000);
|
||||
operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
|
||||
operands[3] = GEN_INT (INTVAL (operands[2]) & 0xffff0000);
|
||||
operands[4] = GEN_INT (INTVAL (operands[2]) & 0x0000ffff);
|
||||
}")
|
||||
|
||||
(define_insn "xorsi3"
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
|
||||
(xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
|
||||
(match_operand:SI 2 "logical_operand" "r,K,J")))]
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
|
||||
(xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
|
||||
(match_operand:SI 2 "reg_or_cint_operand" "r,K,J,n")))]
|
||||
""
|
||||
"@
|
||||
xor %0,%1,%2
|
||||
{xoril|xori} %0,%1,%b2
|
||||
{xoriu|xoris} %0,%1,%u2")
|
||||
{xoriu|xoris} %0,%1,%u2
|
||||
#"
|
||||
[(set_attr "length" "4,4,4,8")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:CC 0 "cc_reg_operand" "=x")
|
||||
@ -1806,7 +1794,7 @@
|
||||
[(set_attr "type" "compare")])
|
||||
|
||||
;; Split an XOR that we can't do in one insn into two insns, each of which
|
||||
;; does one 16-bit part. This is used by combine.
|
||||
;; does one 16-bit part.
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||
@ -1817,9 +1805,8 @@
|
||||
(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]
|
||||
"
|
||||
{
|
||||
operands[3] = gen_rtx (CONST_INT, VOIDmode,
|
||||
INTVAL (operands[2]) & 0xffff0000);
|
||||
operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
|
||||
operands[3] = GEN_INT (INTVAL (operands[2]) & 0xffff0000);
|
||||
operands[4] = GEN_INT (INTVAL (operands[2]) & 0x0000ffff);
|
||||
}")
|
||||
|
||||
(define_insn ""
|
||||
@ -3058,7 +3045,7 @@
|
||||
(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||
(match_operand:SF 3 "gpc_reg_operand" "f")))]
|
||||
"TARGET_POWERPC && TARGET_HARD_FLOAT"
|
||||
"TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
|
||||
"fmadds %0,%1,%2,%3"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
@ -3067,7 +3054,7 @@
|
||||
(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||
(match_operand:SF 3 "gpc_reg_operand" "f")))]
|
||||
"! TARGET_POWERPC && TARGET_HARD_FLOAT"
|
||||
"! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
|
||||
"{fma|fmadd} %0,%1,%2,%3"
|
||||
[(set_attr "type" "dmul")])
|
||||
|
||||
@ -3076,7 +3063,7 @@
|
||||
(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||
(match_operand:SF 3 "gpc_reg_operand" "f")))]
|
||||
"TARGET_POWERPC && TARGET_HARD_FLOAT"
|
||||
"TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
|
||||
"fmsubs %0,%1,%2,%3"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
@ -3085,7 +3072,7 @@
|
||||
(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||
(match_operand:SF 3 "gpc_reg_operand" "f")))]
|
||||
"! TARGET_POWERPC && TARGET_HARD_FLOAT"
|
||||
"! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
|
||||
"{fms|fmsub} %0,%1,%2,%3"
|
||||
[(set_attr "type" "dmul")])
|
||||
|
||||
@ -3094,7 +3081,7 @@
|
||||
(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||
(match_operand:SF 3 "gpc_reg_operand" "f"))))]
|
||||
"TARGET_POWERPC && TARGET_HARD_FLOAT"
|
||||
"TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
|
||||
"fnmadds %0,%1,%2,%3"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
@ -3103,7 +3090,7 @@
|
||||
(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||
(match_operand:SF 3 "gpc_reg_operand" "f"))))]
|
||||
"! TARGET_POWERPC && TARGET_HARD_FLOAT"
|
||||
"! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
|
||||
"{fnma|fnmadd} %0,%1,%2,%3"
|
||||
[(set_attr "type" "dmul")])
|
||||
|
||||
@ -3112,7 +3099,7 @@
|
||||
(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||
(match_operand:SF 3 "gpc_reg_operand" "f"))))]
|
||||
"TARGET_POWERPC && TARGET_HARD_FLOAT"
|
||||
"TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
|
||||
"fnmsubs %0,%1,%2,%3"
|
||||
[(set_attr "type" "fp")])
|
||||
|
||||
@ -3121,7 +3108,7 @@
|
||||
(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||
(match_operand:SF 3 "gpc_reg_operand" "f"))))]
|
||||
"! TARGET_POWERPC && TARGET_HARD_FLOAT"
|
||||
"! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
|
||||
"{fnms|fnmsub} %0,%1,%2,%3"
|
||||
[(set_attr "type" "dmul")])
|
||||
|
||||
@ -5039,12 +5026,30 @@
|
||||
"(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
|
||||
"
|
||||
{
|
||||
if (GET_CODE (operands[1]) == CONST)
|
||||
{
|
||||
rtx offset = const0_rtx;
|
||||
HOST_WIDE_INT value;
|
||||
|
||||
operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
|
||||
value = INTVAL (offset);
|
||||
if (value != 0)
|
||||
{
|
||||
rtx tmp = ((reload_in_progress || reload_completed)
|
||||
? operands[0]
|
||||
: gen_reg_rtx (Pmode));
|
||||
emit_insn (gen_movsi_got (tmp, operands[1]));
|
||||
emit_insn (gen_addsi3 (operands[0], tmp, offset));
|
||||
DONE;
|
||||
}
|
||||
}
|
||||
|
||||
operands[2] = rs6000_got_register (operands[1]);
|
||||
}")
|
||||
|
||||
(define_insn "*movsi_got_internal"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(unspec [(match_operand:SI 1 "got_operand" "")
|
||||
(unspec [(match_operand:SI 1 "got_no_const_operand" "")
|
||||
(match_operand:SI 2 "register_operand" "b")] 8))]
|
||||
"(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
|
||||
"{l|lwz} %0,%a1@got(%2)"
|
||||
@ -5132,24 +5137,7 @@
|
||||
|
||||
emit_insn (gen_movsi (tmp1, sym));
|
||||
if (INTVAL (const_term) != 0)
|
||||
{
|
||||
if (value + 0x8000 < 0x10000)
|
||||
emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
|
||||
|
||||
else
|
||||
{
|
||||
HOST_WIDE_INT high_int = value & (~ (HOST_WIDE_INT) 0xffff);
|
||||
HOST_WIDE_INT low_int = value & 0xffff;
|
||||
rtx tmp2 = (!new_reg_p || !low_int) ? operands[0] : gen_reg_rtx (Pmode);
|
||||
|
||||
if (low_int & 0x8000)
|
||||
high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;
|
||||
|
||||
emit_insn (gen_addsi3 (tmp2, tmp1, GEN_INT (high_int)));
|
||||
if (low_int)
|
||||
emit_insn (gen_addsi3 (operands[0], tmp2, GEN_INT (low_int)));
|
||||
}
|
||||
}
|
||||
emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
|
||||
DONE;
|
||||
}
|
||||
else
|
||||
@ -6745,19 +6733,19 @@
|
||||
;; tie and these are the pair most likely to be tieable (and the ones
|
||||
;; that will benefit the most).
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movdi_update1"
|
||||
[(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
|
||||
(mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:DI 2 "reg_or_short_operand" "r,I"))))
|
||||
(set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:DI (match_dup 1) (match_dup 2)))]
|
||||
"TARGET_POWERPC64"
|
||||
"TARGET_POWERPC64 && TARGET_UPDATE"
|
||||
"@
|
||||
ldux %3,%0,%2
|
||||
ldu %3,%2(%0)"
|
||||
[(set_attr "type" "load")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movdi_update2"
|
||||
[(set (match_operand:DI 3 "gpc_reg_operand" "=r")
|
||||
(sign_extend:DI
|
||||
(mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
|
||||
@ -6774,13 +6762,13 @@
|
||||
(match_operand:DI 3 "gpc_reg_operand" "r,r"))
|
||||
(set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:DI (match_dup 1) (match_dup 2)))]
|
||||
"TARGET_POWERPC64"
|
||||
"TARGET_POWERPC64 && TARGET_UPDATE"
|
||||
"@
|
||||
stdux %3,%0,%2
|
||||
stdu %3,%2(%0)"
|
||||
[(set_attr "type" "store")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movsi_update1"
|
||||
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
||||
(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
|
||||
@ -6798,142 +6786,166 @@
|
||||
(match_operand:SI 3 "gpc_reg_operand" "r,r"))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"TARGET_UPDATE"
|
||||
"@
|
||||
{stux|stwux} %3,%0,%2
|
||||
{stu|stwu} %3,%2(%0)"
|
||||
[(set_attr "type" "store")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movhi_update"
|
||||
[(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
|
||||
(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"TARGET_UPDATE"
|
||||
"@
|
||||
lhzux %3,%0,%2
|
||||
lhzu %3,%2(%0)"
|
||||
[(set_attr "type" "load")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movhi_update2"
|
||||
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
||||
(zero_extend:SI
|
||||
(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I")))))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"TARGET_UPDATE"
|
||||
"@
|
||||
lhzux %3,%0,%2
|
||||
lhzu %3,%2(%0)"
|
||||
[(set_attr "type" "load")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movhi_update3"
|
||||
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
||||
(sign_extend:SI
|
||||
(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I")))))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"TARGET_UPDATE"
|
||||
"@
|
||||
lhaux %3,%0,%2
|
||||
lhau %3,%2(%0)"
|
||||
[(set_attr "type" "load")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movhi_update4"
|
||||
[(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I")))
|
||||
(match_operand:HI 3 "gpc_reg_operand" "r,r"))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"TARGET_UPDATE"
|
||||
"@
|
||||
sthux %3,%0,%2
|
||||
sthu %3,%2(%0)"
|
||||
[(set_attr "type" "store")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movqi_update1"
|
||||
[(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
|
||||
(mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"TARGET_UPDATE"
|
||||
"@
|
||||
lbzux %3,%0,%2
|
||||
lbzu %3,%2(%0)"
|
||||
[(set_attr "type" "load")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movqi_update2"
|
||||
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
||||
(zero_extend:SI
|
||||
(mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I")))))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"TARGET_UPDATE"
|
||||
"@
|
||||
lbzux %3,%0,%2
|
||||
lbzu %3,%2(%0)"
|
||||
[(set_attr "type" "load")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movqi_update3"
|
||||
[(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I")))
|
||||
(match_operand:QI 3 "gpc_reg_operand" "r,r"))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"TARGET_UPDATE"
|
||||
"@
|
||||
stbux %3,%0,%2
|
||||
stbu %3,%2(%0)"
|
||||
[(set_attr "type" "store")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movsf_update1"
|
||||
[(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
|
||||
(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
"TARGET_HARD_FLOAT"
|
||||
"TARGET_HARD_FLOAT && TARGET_UPDATE"
|
||||
"@
|
||||
lfsux %3,%0,%2
|
||||
lfsu %3,%2(%0)"
|
||||
[(set_attr "type" "fpload")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movsf_update2"
|
||||
[(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I")))
|
||||
(match_operand:SF 3 "gpc_reg_operand" "f,f"))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
"TARGET_HARD_FLOAT"
|
||||
"TARGET_HARD_FLOAT && TARGET_UPDATE"
|
||||
"@
|
||||
stfsux %3,%0,%2
|
||||
stfsu %3,%2(%0)"
|
||||
[(set_attr "type" "fpstore")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movsf_update3"
|
||||
[(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
|
||||
(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
"TARGET_SOFT_FLOAT && TARGET_UPDATE"
|
||||
"@
|
||||
{lux|lwzux} %3,%0,%2
|
||||
{lu|lwzu} %3,%2(%0)"
|
||||
[(set_attr "type" "load")])
|
||||
|
||||
(define_insn "*movsf_update4"
|
||||
[(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I")))
|
||||
(match_operand:SF 3 "gpc_reg_operand" "r,r"))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
"TARGET_SOFT_FLOAT && TARGET_UPDATE"
|
||||
"@
|
||||
{stux|stwux} %3,%0,%2
|
||||
{stu|stwu} %3,%2(%0)"
|
||||
[(set_attr "type" "store")])
|
||||
|
||||
(define_insn "*movdf_update1"
|
||||
[(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
|
||||
(mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
"TARGET_HARD_FLOAT"
|
||||
"TARGET_HARD_FLOAT && TARGET_UPDATE"
|
||||
"@
|
||||
lfdux %3,%0,%2
|
||||
lfdu %3,%2(%0)"
|
||||
[(set_attr "type" "fpload")])
|
||||
|
||||
(define_insn ""
|
||||
(define_insn "*movdf_update2"
|
||||
[(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||
(match_operand:SI 2 "reg_or_short_operand" "r,I")))
|
||||
(match_operand:DF 3 "gpc_reg_operand" "f,f"))
|
||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
"TARGET_HARD_FLOAT"
|
||||
"TARGET_HARD_FLOAT && TARGET_UPDATE"
|
||||
"@
|
||||
stfdux %3,%0,%2
|
||||
stfdu %3,%2(%0)"
|
||||
@ -7007,11 +7019,18 @@
|
||||
else
|
||||
neg_op0 = GEN_INT (- INTVAL (operands[0]));
|
||||
|
||||
if (TARGET_32BIT)
|
||||
emit_insn (gen_movsi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
|
||||
else
|
||||
emit_insn (gen_movdi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
|
||||
if (TARGET_UPDATE)
|
||||
emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update : gen_movdi_update))
|
||||
(stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
|
||||
|
||||
else
|
||||
{
|
||||
emit_insn ((* ((TARGET_32BIT) ? gen_addsi3 : gen_adddi3))
|
||||
(stack_pointer_rtx, stack_pointer_rtx, neg_op0));
|
||||
emit_move_insn (gen_rtx (MEM, (TARGET_32BIT) ? SImode : DImode,
|
||||
stack_pointer_rtx),
|
||||
chain);
|
||||
}
|
||||
DONE;
|
||||
}")
|
||||
|
||||
@ -7089,7 +7108,7 @@
|
||||
"TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0"
|
||||
"*
|
||||
{
|
||||
rs6000_output_load_toc_table (asm_out_file);
|
||||
rs6000_output_load_toc_table (asm_out_file, 30);
|
||||
return \"\";
|
||||
}"
|
||||
[(set_attr "type" "load")])
|
||||
|
@ -33,20 +33,18 @@ extern enum rs6000_sdata_type rs6000_sdata;
|
||||
#define MASK_NO_BITFIELD_TYPE 0x40000000 /* Set PCC_BITFIELD_TYPE_MATTERS to 0 */
|
||||
#define MASK_STRICT_ALIGN 0x20000000 /* Set STRICT_ALIGNMENT to 1. */
|
||||
#define MASK_RELOCATABLE 0x10000000 /* GOT pointers are PC relative */
|
||||
#define MASK_SDATA 0x08000000 /* use small data areas */
|
||||
#define MASK_EABI 0x08000000 /* Adhere to eabi, not System V spec */
|
||||
#define MASK_LITTLE_ENDIAN 0x04000000 /* target is little endian */
|
||||
#define MASK_REGNAMES 0x02000000 /* use alternate register names. */
|
||||
#define MASK_PROTOTYPE 0x01000000 /* Only prototyped fcns pass variable args */
|
||||
#define MASK_EABI 0x00800000 /* Adhere to eabi, not System V spec */
|
||||
|
||||
#define TARGET_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE)
|
||||
#define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN)
|
||||
#define TARGET_RELOCATABLE (target_flags & MASK_RELOCATABLE)
|
||||
#define TARGET_SDATA (target_flags & MASK_SDATA)
|
||||
#define TARGET_EABI (target_flags & MASK_EABI)
|
||||
#define TARGET_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN)
|
||||
#define TARGET_REGNAMES (target_flags & MASK_REGNAMES)
|
||||
#define TARGET_PROTOTYPE (target_flags & MASK_PROTOTYPE)
|
||||
#define TARGET_EABI (target_flags & MASK_EABI)
|
||||
#define TARGET_TOC ((target_flags & MASK_64BIT) \
|
||||
|| ((target_flags & (MASK_RELOCATABLE \
|
||||
| MASK_MINIMAL_TOC)) \
|
||||
@ -73,13 +71,9 @@ extern enum rs6000_sdata_type rs6000_sdata;
|
||||
{ "strict-align", MASK_STRICT_ALIGN }, \
|
||||
{ "no-strict-align", -MASK_STRICT_ALIGN }, \
|
||||
{ "relocatable", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
|
||||
{ "relocatable", -MASK_SDATA }, \
|
||||
{ "no-relocatable", -MASK_RELOCATABLE }, \
|
||||
{ "relocatable-lib", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
|
||||
{ "relocatable-lib", -MASK_SDATA }, \
|
||||
{ "no-relocatable-lib", -MASK_RELOCATABLE }, \
|
||||
{ "sdata", MASK_SDATA }, \
|
||||
{ "no-sdata", -MASK_SDATA }, \
|
||||
{ "little-endian", MASK_LITTLE_ENDIAN }, \
|
||||
{ "little", MASK_LITTLE_ENDIAN }, \
|
||||
{ "big-endian", -MASK_LITTLE_ENDIAN }, \
|
||||
@ -94,6 +88,8 @@ extern enum rs6000_sdata_type rs6000_sdata;
|
||||
{ "no-eabi", -MASK_EABI }, \
|
||||
{ "regnames", MASK_REGNAMES }, \
|
||||
{ "no-regnames", -MASK_REGNAMES }, \
|
||||
{ "sdata", 0 }, \
|
||||
{ "no-sdata", 0 }, \
|
||||
{ "sim", 0 }, \
|
||||
{ "mvme", 0 }, \
|
||||
{ "emb", 0 }, \
|
||||
@ -169,12 +165,8 @@ do { \
|
||||
\
|
||||
if (rs6000_sdata_name) \
|
||||
{ \
|
||||
target_flags |= MASK_SDATA; \
|
||||
if (!strcmp (rs6000_sdata_name, "none")) \
|
||||
{ \
|
||||
rs6000_sdata = SDATA_NONE; \
|
||||
target_flags &= ~MASK_SDATA; \
|
||||
} \
|
||||
rs6000_sdata = SDATA_NONE; \
|
||||
else if (!strcmp (rs6000_sdata_name, "data")) \
|
||||
rs6000_sdata = SDATA_DATA; \
|
||||
else if (!strcmp (rs6000_sdata_name, "default")) \
|
||||
@ -186,21 +178,10 @@ do { \
|
||||
else \
|
||||
error ("Bad value for -msdata=%s", rs6000_sdata_name); \
|
||||
} \
|
||||
else if (TARGET_SDATA && TARGET_EABI) \
|
||||
{ \
|
||||
rs6000_sdata = SDATA_EABI; \
|
||||
rs6000_sdata_name = "eabi"; \
|
||||
} \
|
||||
else if (TARGET_SDATA) \
|
||||
{ \
|
||||
rs6000_sdata = SDATA_SYSV; \
|
||||
rs6000_sdata_name = "sysv"; \
|
||||
} \
|
||||
else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \
|
||||
{ \
|
||||
rs6000_sdata = SDATA_DATA; \
|
||||
rs6000_sdata_name = "data"; \
|
||||
target_flags |= MASK_SDATA; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
@ -225,10 +206,12 @@ do { \
|
||||
rs6000_sdata_name); \
|
||||
} \
|
||||
\
|
||||
if (TARGET_SDATA && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS) \
|
||||
if (rs6000_sdata != SDATA_NONE && DEFAULT_ABI != ABI_V4 \
|
||||
&& DEFAULT_ABI != ABI_SOLARIS) \
|
||||
{ \
|
||||
target_flags &= ~MASK_SDATA; \
|
||||
error ("-msdata and -mcall-%s are incompatible.", rs6000_abi_name); \
|
||||
rs6000_sdata = SDATA_NONE; \
|
||||
error ("-msdata=%s and -mcall-%s are incompatible.", \
|
||||
rs6000_sdata_name, rs6000_abi_name); \
|
||||
} \
|
||||
\
|
||||
if (TARGET_RELOCATABLE && !TARGET_MINIMAL_TOC) \
|
||||
@ -467,8 +450,6 @@ extern void sbss_section ();
|
||||
void \
|
||||
toc_section () \
|
||||
{ \
|
||||
static int toc_initialized = 0; \
|
||||
\
|
||||
if (in_section != in_toc) \
|
||||
{ \
|
||||
in_section = in_toc; \
|
||||
@ -628,7 +609,7 @@ extern int rs6000_pic_labelno;
|
||||
char *init_ptr = (TARGET_64BIT) ? ".quad" : ".long"; \
|
||||
STRIP_NAME_ENCODING (orig_name, NAME); \
|
||||
\
|
||||
if (TARGET_RELOCATABLE && get_pool_size () != 0) \
|
||||
if (TARGET_RELOCATABLE && (get_pool_size () != 0 || profile_flag)) \
|
||||
{ \
|
||||
char buf[256], *buf_ptr; \
|
||||
\
|
||||
@ -701,7 +682,8 @@ extern int rs6000_pic_labelno;
|
||||
#undef ASM_OUTPUT_ALIGNED_LOCAL
|
||||
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
|
||||
do { \
|
||||
if (TARGET_SDATA && (SIZE) > 0 && (SIZE) <= g_switch_value) \
|
||||
if (rs6000_sdata != SDATA_NONE && (SIZE) > 0 \
|
||||
&& (SIZE) <= g_switch_value) \
|
||||
{ \
|
||||
sdata_section (); \
|
||||
ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \
|
||||
@ -961,7 +943,8 @@ do { \
|
||||
|
||||
/* Pass various options to the assembler */
|
||||
#undef ASM_SPEC
|
||||
#define ASM_SPEC "%(asm_cpu) %{mregnames} %{mno-regnames} \
|
||||
#define ASM_SPEC "%(asm_cpu) \
|
||||
%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
|
||||
%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
|
||||
%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
|
||||
%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
|
||||
@ -983,7 +966,9 @@ do { \
|
||||
%{!meabi: %{!mno-eabi: \
|
||||
%{mrelocatable: -meabi } \
|
||||
%{mcall-solaris: -mno-eabi } \
|
||||
%{mcall-linux: -mno-eabi }}}"
|
||||
%{mcall-linux: -mno-eabi }}} \
|
||||
%{msdata: -msdata=default} \
|
||||
%{mno-sdata: -msdata=none}"
|
||||
|
||||
/* Don't put -Y P,<path> for cross compilers */
|
||||
#undef LINK_PATH_SPEC
|
||||
@ -1357,3 +1342,12 @@ do { \
|
||||
|
||||
#undef MULTILIB_DEFAULTS
|
||||
#define MULTILIB_DEFAULTS { "mbig", "mcall-sysv" }
|
||||
|
||||
/* Define this macro if the code for function profiling should come
|
||||
before the function prologue. Normally, the profiling code comes
|
||||
after. */
|
||||
#define PROFILE_BEFORE_PROLOGUE 1
|
||||
|
||||
/* Function name to call to do profiling. */
|
||||
#undef RS6000_MCOUNT
|
||||
#define RS6000_MCOUNT "_mcount"
|
||||
|
Loading…
x
Reference in New Issue
Block a user