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_offset;
|
||||||
int rs6000_fpmem_size;
|
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. */
|
/* Default register names. */
|
||||||
char rs6000_reg_names[][8] =
|
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
|
#ifdef TARGET_REGNAMES
|
||||||
/* If the user desires alternate register names, copy in the alternate names
|
/* If the user desires alternate register names, copy in the alternate names
|
||||||
now. */
|
now. */
|
||||||
|
@ -416,7 +437,8 @@ any_operand (op, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns 1 if op is the count register */
|
/* Returns 1 if op is the count register */
|
||||||
int count_register_operand(op, mode)
|
int
|
||||||
|
count_register_operand(op, mode)
|
||||||
register rtx op;
|
register rtx op;
|
||||||
enum machine_mode mode;
|
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
|
/* Returns 1 if op is memory location for float/int conversions that masquerades
|
||||||
as a register. */
|
as a register. */
|
||||||
int fpmem_operand(op, mode)
|
int
|
||||||
|
fpmem_operand(op, mode)
|
||||||
register rtx op;
|
register rtx op;
|
||||||
enum machine_mode mode;
|
enum machine_mode mode;
|
||||||
{
|
{
|
||||||
|
@ -576,6 +599,17 @@ got_operand (op, mode)
|
||||||
|| GET_CODE (op) == LABEL_REF);
|
|| 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
|
/* Return the number of instructions it takes to form a constant in an
|
||||||
integer register. */
|
integer register. */
|
||||||
|
|
||||||
|
@ -869,8 +903,7 @@ and_operand (op, mode)
|
||||||
register rtx op;
|
register rtx op;
|
||||||
enum machine_mode mode;
|
enum machine_mode mode;
|
||||||
{
|
{
|
||||||
return (reg_or_short_operand (op, mode)
|
return (logical_operand (op, mode)
|
||||||
|| logical_operand (op, mode)
|
|
||||||
|| mask_operand (op, mode));
|
|| mask_operand (op, mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,7 +1042,7 @@ small_data_operand (op, mode)
|
||||||
rtx op;
|
rtx op;
|
||||||
enum machine_mode mode;
|
enum machine_mode mode;
|
||||||
{
|
{
|
||||||
#ifdef TARGET_SDATA
|
#if TARGET_ELF
|
||||||
rtx sym_ref, const_part;
|
rtx sym_ref, const_part;
|
||||||
|
|
||||||
if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
|
if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
|
||||||
|
@ -2168,6 +2201,7 @@ rs6000_finalize_pic ()
|
||||||
rtx insn = get_insns ();
|
rtx insn = get_insns ();
|
||||||
rtx reg = NULL_RTX;
|
rtx reg = NULL_RTX;
|
||||||
rtx first_insn;
|
rtx first_insn;
|
||||||
|
rtx last_insn = NULL_RTX;
|
||||||
|
|
||||||
if (GET_CODE (insn) == NOTE)
|
if (GET_CODE (insn) == NOTE)
|
||||||
insn = next_nonnote_insn (insn);
|
insn = next_nonnote_insn (insn);
|
||||||
|
@ -2186,12 +2220,17 @@ rs6000_finalize_pic ()
|
||||||
GOT_TOC_REGNUM,
|
GOT_TOC_REGNUM,
|
||||||
®);
|
®);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GET_CODE (insn) != NOTE)
|
||||||
|
last_insn = insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reg)
|
if (reg)
|
||||||
{
|
{
|
||||||
rtx init = gen_init_v4_pic (reg);
|
rtx init = gen_init_v4_pic (reg);
|
||||||
emit_insn_before (init, first_insn);
|
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. */
|
/* Print an operand. Recognize special options, documented below. */
|
||||||
|
|
||||||
#ifdef TARGET_SDATA
|
#if TARGET_ELF
|
||||||
#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
|
#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
|
||||||
#else
|
#else
|
||||||
#define SMALL_DATA_RELOC "sda21"
|
#define SMALL_DATA_RELOC "sda21"
|
||||||
|
@ -2875,8 +2914,10 @@ rs6000_makes_calls ()
|
||||||
{
|
{
|
||||||
rtx insn;
|
rtx insn;
|
||||||
|
|
||||||
/* If we are profiling, we will be making a call to __mcount. */
|
/* If we are profiling, we will be making a call to __mcount.
|
||||||
if (profile_flag)
|
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;
|
return 1;
|
||||||
|
|
||||||
for (insn = get_insns (); insn; insn = next_insn (insn))
|
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 */
|
/* 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
|
#ifdef TARGET_RELOCATABLE
|
||||||
|| (TARGET_RELOCATABLE && (get_pool_size () != 0))
|
|| (TARGET_RELOCATABLE && (get_pool_size () != 0))
|
||||||
#endif
|
#endif
|
||||||
|
@ -3336,8 +3378,9 @@ debug_stack_info (info)
|
||||||
a constant pool. */
|
a constant pool. */
|
||||||
|
|
||||||
void
|
void
|
||||||
rs6000_output_load_toc_table (file)
|
rs6000_output_load_toc_table (file, reg)
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
int reg;
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
|
@ -3349,8 +3392,45 @@ rs6000_output_load_toc_table (file)
|
||||||
assemble_name (file, buf);
|
assemble_name (file, buf);
|
||||||
fprintf (file, "\n");
|
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);
|
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)
|
if (TARGET_POWERPC64)
|
||||||
fprintf (file, "\tld");
|
fprintf (file, "\tld");
|
||||||
|
@ -3360,33 +3440,33 @@ rs6000_output_load_toc_table (file)
|
||||||
fprintf (file, "\tl");
|
fprintf (file, "\tl");
|
||||||
|
|
||||||
fprintf (file, " %s,(", reg_names[0]);
|
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);
|
assemble_name (file, buf);
|
||||||
fprintf (file, "-");
|
fprintf (file, "-");
|
||||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
|
ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
|
||||||
assemble_name (file, buf);
|
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",
|
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++;
|
rs6000_pic_labelno++;
|
||||||
}
|
}
|
||||||
else if (!TARGET_64BIT)
|
else if (!TARGET_64BIT)
|
||||||
{
|
{
|
||||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
|
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);
|
assemble_name (file, buf);
|
||||||
asm_fprintf (file, "@ha\n");
|
asm_fprintf (file, "@ha\n");
|
||||||
if (TARGET_NEW_MNEMONICS)
|
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);
|
assemble_name (file, buf);
|
||||||
asm_fprintf (file, "@l\n");
|
asm_fprintf (file, "@l\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
asm_fprintf (file, "\tcal %s,", reg_names[30]);
|
asm_fprintf (file, "\tcal %s,", reg_names[reg]);
|
||||||
assemble_name (file, buf);
|
assemble_name (file, buf);
|
||||||
asm_fprintf (file, "@l(%s)\n", reg_names[30]);
|
asm_fprintf (file, "@l(%s)\n", reg_names[reg]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3394,12 +3474,68 @@ rs6000_output_load_toc_table (file)
|
||||||
|
|
||||||
#else /* !USING_SVR4_H */
|
#else /* !USING_SVR4_H */
|
||||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 0);
|
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);
|
assemble_name (file, buf);
|
||||||
asm_fprintf (file, "(%s)\n", reg_names[2]);
|
asm_fprintf (file, "(%s)\n", reg_names[2]);
|
||||||
#endif /* USING_SVR4_H */
|
#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. */
|
/* Write function prologue. */
|
||||||
void
|
void
|
||||||
output_prolog (file, size)
|
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->push_p && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
|
||||||
{
|
{
|
||||||
if (info->total_size < 32767)
|
if (info->total_size < 32767)
|
||||||
{
|
sp_offset = info->total_size;
|
||||||
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;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
sp_reg = 12;
|
||||||
int neg_size = - info->total_size;
|
rs6000_allocate_stack_space (file, info->total_size, sp_reg == 12);
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we use the link register, get it into r0. */
|
/* 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->push_p && DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_SOLARIS)
|
||||||
{
|
rs6000_allocate_stack_space (file, info->total_size, FALSE);
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set frame pointer, if needed. */
|
/* Set frame pointer, if needed. */
|
||||||
if (frame_pointer_needed)
|
if (frame_pointer_needed)
|
||||||
|
@ -3671,9 +3778,10 @@ output_prolog (file, size)
|
||||||
if (TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
|
if (TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
|
||||||
{
|
{
|
||||||
#ifdef USING_SVR4_H
|
#ifdef USING_SVR4_H
|
||||||
rs6000_pic_func_labelno = rs6000_pic_labelno;
|
if (!profile_flag)
|
||||||
|
rs6000_pic_func_labelno = rs6000_pic_labelno;
|
||||||
#endif
|
#endif
|
||||||
rs6000_output_load_toc_table (file);
|
rs6000_output_load_toc_table (file, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DEFAULT_ABI == ABI_NT)
|
if (DEFAULT_ABI == ABI_NT)
|
||||||
|
@ -4287,55 +4395,115 @@ output_function_profiler (file, labelno)
|
||||||
int i, j;
|
int i, j;
|
||||||
char buf[100];
|
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);
|
ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
|
||||||
if (TARGET_MINIMAL_TOC)
|
switch (DEFAULT_ABI)
|
||||||
{
|
{
|
||||||
fputs ("\t.long ", file);
|
default:
|
||||||
assemble_name (file, buf);
|
abort ();
|
||||||
putc ('\n', file);
|
|
||||||
}
|
case ABI_V4:
|
||||||
else
|
case ABI_SOLARIS:
|
||||||
{
|
case ABI_AIX_NODESC:
|
||||||
fputs ("\t.tc\t", file);
|
fprintf (file, "\tmflr %s\n", reg_names[0]);
|
||||||
assemble_name (file, buf);
|
if (flag_pic == 1)
|
||||||
fputs ("[TC],", file);
|
{
|
||||||
assemble_name (file, buf);
|
fprintf (file, "\tbl _GLOBAL_OFFSET_TABLE_@local-4\n");
|
||||||
putc ('\n', file);
|
fprintf (file, "\tmflr %s\n", reg_names[11]);
|
||||||
}
|
fprintf (file, "\t%s %s,", (TARGET_NEW_MNEMONICS) ? "lwz" : "l",
|
||||||
text_section ();
|
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
|
/* Figure out last used parameter register. The proper thing to do is
|
||||||
to walk incoming args of the function. A function might have live
|
to walk incoming args of the function. A function might have live
|
||||||
parameter registers even if it has no incoming args. */
|
parameter registers even if it has no incoming args. */
|
||||||
|
|
||||||
for (last_parm_reg = 10;
|
for (last_parm_reg = 10;
|
||||||
last_parm_reg > 2 && ! regs_ever_live [last_parm_reg];
|
last_parm_reg > 2 && ! regs_ever_live [last_parm_reg];
|
||||||
last_parm_reg--)
|
last_parm_reg--)
|
||||||
;
|
;
|
||||||
|
|
||||||
/* Save parameter registers in regs 23-30. Don't overwrite reg 31, since
|
/* Save parameter registers in regs 23-30. Don't overwrite reg 31, since
|
||||||
it might be set up as the frame pointer. */
|
it might be set up as the frame pointer. */
|
||||||
|
|
||||||
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
|
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
|
||||||
asm_fprintf (file, "\tmr %d,%d\n", j, i);
|
asm_fprintf (file, "\tmr %d,%d\n", j, i);
|
||||||
|
|
||||||
/* Load location address into r3, and call mcount. */
|
/* Load location address into r3, and call mcount. */
|
||||||
|
|
||||||
ASM_GENERATE_INTERNAL_LABEL (buf, "LPC", labelno);
|
ASM_GENERATE_INTERNAL_LABEL (buf, "LPC", labelno);
|
||||||
asm_fprintf (file, "\t{l|lwz} %s,", reg_names[3]);
|
asm_fprintf (file, "\t{l|lwz} %s,", reg_names[3]);
|
||||||
assemble_name (file, buf);
|
assemble_name (file, buf);
|
||||||
asm_fprintf (file, "(%s)\n\tbl %s\n", reg_names[2], RS6000_MCOUNT);
|
asm_fprintf (file, "(%s)\n\tbl %s\n", reg_names[2], RS6000_MCOUNT);
|
||||||
|
|
||||||
/* Restore parameter registers. */
|
/* Restore parameter registers. */
|
||||||
|
|
||||||
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
|
for (i = 3, j = 30; i <= last_parm_reg; i++, j--)
|
||||||
asm_fprintf (file, "\tmr %d,%d\n", i, j);
|
asm_fprintf (file, "\tmr %d,%d\n", i, j);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust the cost of a scheduling dependency. Return the new cost of
|
/* 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;
|
extern int target_flags;
|
||||||
|
|
||||||
/* Use POWER architecture instructions and MQ register. */
|
/* Use POWER architecture instructions and MQ register. */
|
||||||
#define MASK_POWER 0x01
|
#define MASK_POWER 0x00000001
|
||||||
|
|
||||||
/* Use POWER2 extensions to POWER architecture. */
|
/* Use POWER2 extensions to POWER architecture. */
|
||||||
#define MASK_POWER2 0x02
|
#define MASK_POWER2 0x00000002
|
||||||
|
|
||||||
/* Use PowerPC architecture instructions. */
|
/* Use PowerPC architecture instructions. */
|
||||||
#define MASK_POWERPC 0x04
|
#define MASK_POWERPC 0x00000004
|
||||||
|
|
||||||
/* Use PowerPC General Purpose group optional instructions, e.g. fsqrt. */
|
/* 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. */
|
/* Use PowerPC Graphics group optional instructions, e.g. fsel. */
|
||||||
#define MASK_PPC_GFXOPT 0x10
|
#define MASK_PPC_GFXOPT 0x00000010
|
||||||
|
|
||||||
/* Use PowerPC-64 architecture instructions. */
|
/* Use PowerPC-64 architecture instructions. */
|
||||||
#define MASK_POWERPC64 0x20
|
#define MASK_POWERPC64 0x00000020
|
||||||
|
|
||||||
/* Use revised mnemonic names defined for PowerPC architecture. */
|
/* 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
|
/* Disable placing fp constants in the TOC; can be turned on when the
|
||||||
TOC overflows. */
|
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
|
/* Disable placing symbol+offset constants in the TOC; can be turned on when
|
||||||
the TOC overflows. */
|
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
|
/* Output only one TOC entry per module. Normally linking fails if
|
||||||
there are more than 16K unique variables/constants in an executable. With
|
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
|
This is at the cost of having 2 extra loads and one extra store per
|
||||||
function, and one less allocatable register. */
|
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. */
|
/* Nonzero for the 64bit model: ints, longs, and pointers are 64 bits. */
|
||||||
#define MASK_64BIT 0x400
|
#define MASK_64BIT 0x00000400
|
||||||
|
|
||||||
/* Disable use of FPRs. */
|
/* Disable use of FPRs. */
|
||||||
#define MASK_SOFT_FLOAT 0x800
|
#define MASK_SOFT_FLOAT 0x00000800
|
||||||
|
|
||||||
/* Enable load/store multiple, even on powerpc */
|
/* Enable load/store multiple, even on powerpc */
|
||||||
#define MASK_MULTIPLE 0x1000
|
#define MASK_MULTIPLE 0x00001000
|
||||||
#define MASK_MULTIPLE_SET 0x2000
|
#define MASK_MULTIPLE_SET 0x00002000
|
||||||
|
|
||||||
/* Use string instructions for block moves */
|
/* Use string instructions for block moves */
|
||||||
#define MASK_STRING 0x4000
|
#define MASK_STRING 0x00004000
|
||||||
#define MASK_STRING_SET 0x8000
|
#define MASK_STRING_SET 0x00008000
|
||||||
|
|
||||||
/* Temporary debug switches */
|
/* Disable update form of load/store */
|
||||||
#define MASK_DEBUG_STACK 0x10000
|
#define MASK_NO_UPDATE 0x00010000
|
||||||
#define MASK_DEBUG_ARG 0x20000
|
|
||||||
|
/* Disable fused multiply/add operations */
|
||||||
|
#define MASK_NO_FUSED_MADD 0x00020000
|
||||||
|
|
||||||
#define TARGET_POWER (target_flags & MASK_POWER)
|
#define TARGET_POWER (target_flags & MASK_POWER)
|
||||||
#define TARGET_POWER2 (target_flags & MASK_POWER2)
|
#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_MULTIPLE_SET (target_flags & MASK_MULTIPLE_SET)
|
||||||
#define TARGET_STRING (target_flags & MASK_STRING)
|
#define TARGET_STRING (target_flags & MASK_STRING)
|
||||||
#define TARGET_STRING_SET (target_flags & MASK_STRING_SET)
|
#define TARGET_STRING_SET (target_flags & MASK_STRING_SET)
|
||||||
#define TARGET_DEBUG_STACK (target_flags & MASK_DEBUG_STACK)
|
#define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE)
|
||||||
#define TARGET_DEBUG_ARG (target_flags & MASK_DEBUG_ARG)
|
#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
|
||||||
|
|
||||||
#define TARGET_32BIT (! TARGET_64BIT)
|
#define TARGET_32BIT (! TARGET_64BIT)
|
||||||
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
|
#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
|
/* Pseudo target to indicate whether the object format is ELF
|
||||||
(to get around not having conditional compilation in the md file) */
|
(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}, \
|
{"string", MASK_STRING | MASK_STRING_SET}, \
|
||||||
{"no-string", - MASK_STRING}, \
|
{"no-string", - MASK_STRING}, \
|
||||||
{"no-string", MASK_STRING_SET}, \
|
{"no-string", MASK_STRING_SET}, \
|
||||||
{"debug-stack", MASK_DEBUG_STACK}, \
|
{"update", - MASK_NO_UPDATE}, \
|
||||||
{"debug-arg", MASK_DEBUG_ARG}, \
|
{"no-update", MASK_NO_UPDATE}, \
|
||||||
|
{"fused-madd", - MASK_NO_FUSED_MADD}, \
|
||||||
|
{"no-fused-madd", MASK_NO_FUSED_MADD}, \
|
||||||
SUBTARGET_SWITCHES \
|
SUBTARGET_SWITCHES \
|
||||||
{"", TARGET_DEFAULT}}
|
{"", TARGET_DEFAULT}}
|
||||||
|
|
||||||
|
@ -427,6 +433,8 @@ extern enum processor_type rs6000_cpu;
|
||||||
{ \
|
{ \
|
||||||
{"cpu=", &rs6000_select[1].string}, \
|
{"cpu=", &rs6000_select[1].string}, \
|
||||||
{"tune=", &rs6000_select[2].string}, \
|
{"tune=", &rs6000_select[2].string}, \
|
||||||
|
{"debug-", &rs6000_debug_name}, \
|
||||||
|
{"debug=", &rs6000_debug_name}, \
|
||||||
SUBTARGET_OPTIONS \
|
SUBTARGET_OPTIONS \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,6 +449,14 @@ struct rs6000_cpu_select
|
||||||
|
|
||||||
extern struct rs6000_cpu_select rs6000_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
|
/* Sometimes certain combinations of command options do not make sense
|
||||||
on a particular target machine. You can define a macro
|
on a particular target machine. You can define a macro
|
||||||
`OVERRIDE_OPTIONS' to take account of this. This macro, if
|
`OVERRIDE_OPTIONS' to take account of this. This macro, if
|
||||||
|
@ -1811,6 +1827,7 @@ typedef struct rs6000_args
|
||||||
{ if (LEGITIMATE_INDIRECT_ADDRESS_P (X)) \
|
{ if (LEGITIMATE_INDIRECT_ADDRESS_P (X)) \
|
||||||
goto ADDR; \
|
goto ADDR; \
|
||||||
if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
|
if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
|
||||||
|
&& TARGET_UPDATE \
|
||||||
&& LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0))) \
|
&& LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0))) \
|
||||||
goto ADDR; \
|
goto ADDR; \
|
||||||
if (LEGITIMATE_SMALL_DATA_P (MODE, X)) \
|
if (LEGITIMATE_SMALL_DATA_P (MODE, X)) \
|
||||||
|
@ -1904,9 +1921,9 @@ typedef struct rs6000_args
|
||||||
&& ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), \
|
&& ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), \
|
||||||
(TARGET_32BIT ? 4 : 8))) \
|
(TARGET_32BIT ? 4 : 8))) \
|
||||||
goto LABEL; \
|
goto LABEL; \
|
||||||
if (GET_CODE (ADDR) == PRE_INC) \
|
if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_INC) \
|
||||||
goto LABEL; \
|
goto LABEL; \
|
||||||
if (GET_CODE (ADDR) == PRE_DEC) \
|
if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_DEC) \
|
||||||
goto LABEL; \
|
goto LABEL; \
|
||||||
if (GET_CODE (ADDR) == LO_SUM) \
|
if (GET_CODE (ADDR) == LO_SUM) \
|
||||||
goto LABEL; \
|
goto LABEL; \
|
||||||
|
@ -2096,59 +2113,74 @@ typedef struct rs6000_args
|
||||||
/* Provide the costs of a rtl expression. This is in the body of a
|
/* Provide the costs of a rtl expression. This is in the body of a
|
||||||
switch on CODE. */
|
switch on CODE. */
|
||||||
|
|
||||||
#define RTX_COSTS(X,CODE,OUTER_CODE) \
|
#define RTX_COSTS(X,CODE,OUTER_CODE) \
|
||||||
case MULT: \
|
case PLUS: \
|
||||||
switch (rs6000_cpu) \
|
return ((GET_CODE (XEXP (X, 1)) == CONST_INT \
|
||||||
{ \
|
&& (unsigned HOST_WIDE_INT) ((INTVAL (XEXP (X, 1)) \
|
||||||
case PROCESSOR_RIOS1: \
|
+ 0x8000) >= 0x10000)) \
|
||||||
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
|
? COSTS_N_INSNS (2) \
|
||||||
? COSTS_N_INSNS (5) \
|
: COSTS_N_INSNS (1)); \
|
||||||
: INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
|
case AND: \
|
||||||
? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
|
return ((non_and_cint_operand (XEXP (X, 1), SImode)) \
|
||||||
case PROCESSOR_RIOS2: \
|
? COSTS_N_INSNS (2) \
|
||||||
case PROCESSOR_MPCCORE: \
|
: COSTS_N_INSNS (1)); \
|
||||||
return COSTS_N_INSNS (2); \
|
case IOR: \
|
||||||
case PROCESSOR_PPC601: \
|
case XOR: \
|
||||||
return COSTS_N_INSNS (5); \
|
return ((non_logical_cint_operand (XEXP (X, 1), SImode)) \
|
||||||
case PROCESSOR_PPC603: \
|
? COSTS_N_INSNS (2) \
|
||||||
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
|
: COSTS_N_INSNS (1)); \
|
||||||
? COSTS_N_INSNS (5) \
|
case MULT: \
|
||||||
: INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
|
switch (rs6000_cpu) \
|
||||||
? COSTS_N_INSNS (2) : COSTS_N_INSNS (3)); \
|
{ \
|
||||||
case PROCESSOR_PPC403: \
|
case PROCESSOR_RIOS1: \
|
||||||
case PROCESSOR_PPC604: \
|
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
|
||||||
case PROCESSOR_PPC620: \
|
? COSTS_N_INSNS (5) \
|
||||||
return COSTS_N_INSNS (4); \
|
: INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
|
||||||
} \
|
? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
|
||||||
case DIV: \
|
case PROCESSOR_RIOS2: \
|
||||||
case MOD: \
|
case PROCESSOR_MPCCORE: \
|
||||||
if (GET_CODE (XEXP (X, 1)) == CONST_INT \
|
return COSTS_N_INSNS (2); \
|
||||||
&& exact_log2 (INTVAL (XEXP (X, 1))) >= 0) \
|
case PROCESSOR_PPC601: \
|
||||||
return COSTS_N_INSNS (2); \
|
return COSTS_N_INSNS (5); \
|
||||||
/* otherwise fall through to normal divide. */ \
|
case PROCESSOR_PPC603: \
|
||||||
case UDIV: \
|
return (GET_CODE (XEXP (X, 1)) != CONST_INT \
|
||||||
case UMOD: \
|
? COSTS_N_INSNS (5) \
|
||||||
switch (rs6000_cpu) \
|
: INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
|
||||||
{ \
|
? COSTS_N_INSNS (2) : COSTS_N_INSNS (3)); \
|
||||||
case PROCESSOR_RIOS1: \
|
case PROCESSOR_PPC403: \
|
||||||
return COSTS_N_INSNS (19); \
|
case PROCESSOR_PPC604: \
|
||||||
case PROCESSOR_RIOS2: \
|
case PROCESSOR_PPC620: \
|
||||||
return COSTS_N_INSNS (13); \
|
return COSTS_N_INSNS (4); \
|
||||||
case PROCESSOR_MPCCORE: \
|
} \
|
||||||
return COSTS_N_INSNS (6); \
|
case DIV: \
|
||||||
case PROCESSOR_PPC403: \
|
case MOD: \
|
||||||
return COSTS_N_INSNS (33); \
|
if (GET_CODE (XEXP (X, 1)) == CONST_INT \
|
||||||
case PROCESSOR_PPC601: \
|
&& exact_log2 (INTVAL (XEXP (X, 1))) >= 0) \
|
||||||
return COSTS_N_INSNS (36); \
|
return COSTS_N_INSNS (2); \
|
||||||
case PROCESSOR_PPC603: \
|
/* otherwise fall through to normal divide. */ \
|
||||||
return COSTS_N_INSNS (37); \
|
case UDIV: \
|
||||||
case PROCESSOR_PPC604: \
|
case UMOD: \
|
||||||
case PROCESSOR_PPC620: \
|
switch (rs6000_cpu) \
|
||||||
return COSTS_N_INSNS (20); \
|
{ \
|
||||||
} \
|
case PROCESSOR_RIOS1: \
|
||||||
case FFS: \
|
return COSTS_N_INSNS (19); \
|
||||||
return COSTS_N_INSNS (4); \
|
case PROCESSOR_RIOS2: \
|
||||||
case MEM: \
|
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)) */ \
|
/* MEM should be slightly more expensive than (plus (reg) (const)) */ \
|
||||||
return 5;
|
return 5;
|
||||||
|
|
||||||
|
@ -2373,8 +2405,6 @@ toc_section () \
|
||||||
{ \
|
{ \
|
||||||
if (TARGET_MINIMAL_TOC) \
|
if (TARGET_MINIMAL_TOC) \
|
||||||
{ \
|
{ \
|
||||||
static int toc_initialized = 0; \
|
|
||||||
\
|
|
||||||
/* toc_section is always called at least once from ASM_FILE_START, \
|
/* toc_section is always called at least once from ASM_FILE_START, \
|
||||||
so this is guaranteed to always be defined once and only once \
|
so this is guaranteed to always be defined once and only once \
|
||||||
in each file. */ \
|
in each file. */ \
|
||||||
|
@ -2396,6 +2426,9 @@ toc_section () \
|
||||||
in_section = toc; \
|
in_section = toc; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Flag to say the TOC is initialized */
|
||||||
|
extern int toc_initialized;
|
||||||
|
|
||||||
/* This macro produces the initial definition of a function name.
|
/* 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
|
On the RS/6000, we need to place an extra '.' in the function name and
|
||||||
output the function descriptor.
|
output the function descriptor.
|
||||||
|
@ -2998,6 +3031,7 @@ do { \
|
||||||
{"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
|
{"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
|
||||||
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
|
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
|
||||||
{"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
|
{"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
|
||||||
|
{"got_no_const_operand", {SYMBOL_REF, LABEL_REF}}, \
|
||||||
{"easy_fp_constant", {CONST_DOUBLE}}, \
|
{"easy_fp_constant", {CONST_DOUBLE}}, \
|
||||||
{"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
|
{"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
|
||||||
{"lwa_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_u_short_operand ();
|
||||||
extern int reg_or_cint_operand ();
|
extern int reg_or_cint_operand ();
|
||||||
extern int got_operand ();
|
extern int got_operand ();
|
||||||
|
extern int got_no_const_operand ();
|
||||||
extern int num_insns_constant ();
|
extern int num_insns_constant ();
|
||||||
extern int easy_fp_constant ();
|
extern int easy_fp_constant ();
|
||||||
extern int volatile_mem_operand ();
|
extern int volatile_mem_operand ();
|
||||||
|
|
|
@ -859,15 +859,17 @@
|
||||||
;; Discourage ai/addic because of carry but provide it in an alternative
|
;; Discourage ai/addic because of carry but provide it in an alternative
|
||||||
;; allowing register zero as source.
|
;; allowing register zero as source.
|
||||||
(define_insn "addsi3"
|
(define_insn "addsi3"
|
||||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,?r,r")
|
[(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")
|
(plus:SI (match_operand:SI 1 "gpc_reg_operand" "%r,b,r,b,b")
|
||||||
(match_operand:SI 2 "add_operand" "r,I,I,J")))]
|
(match_operand:SI 2 "reg_or_cint_operand" "r,I,I,J,n")))]
|
||||||
""
|
""
|
||||||
"@
|
"@
|
||||||
{cax|add} %0,%1,%2
|
{cax|add} %0,%1,%2
|
||||||
{cal %0,%2(%1)|addi %0,%1,%2}
|
{cal %0,%2(%1)|addi %0,%1,%2}
|
||||||
{ai|addic} %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 ""
|
(define_insn ""
|
||||||
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
|
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x")
|
||||||
|
@ -1646,16 +1648,18 @@
|
||||||
[(set_attr "type" "idiv")])
|
[(set_attr "type" "idiv")])
|
||||||
|
|
||||||
(define_insn "andsi3"
|
(define_insn "andsi3"
|
||||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
|
[(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")
|
(and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
|
||||||
(match_operand:SI 2 "and_operand" "?r,L,K,J")))
|
(match_operand:SI 2 "reg_or_cint_operand" "?r,L,K,J,n")))
|
||||||
(clobber (match_scratch:CC 3 "=X,X,x,x"))]
|
(clobber (match_scratch:CC 3 "=X,X,x,x,x"))]
|
||||||
""
|
""
|
||||||
"@
|
"@
|
||||||
and %0,%1,%2
|
and %0,%1,%2
|
||||||
{rlinm|rlwinm} %0,%1,0,%m2,%M2
|
{rlinm|rlwinm} %0,%1,0,%m2,%M2
|
||||||
{andil.|andi.} %0,%1,%b2
|
{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 ""
|
(define_insn ""
|
||||||
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
|
[(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x")
|
||||||
|
@ -1687,54 +1691,37 @@
|
||||||
[(set_attr "type" "compare,compare,compare,delayed_compare")])
|
[(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
|
;; 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
|
;; split it into two insns.
|
||||||
;; since this need not be done as combine will do it.
|
|
||||||
|
|
||||||
(define_split
|
(define_split
|
||||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||||
(and:SI (match_operand:SI 1 "gpc_reg_operand" "")
|
(and:SI (match_operand:SI 1 "gpc_reg_operand" "")
|
||||||
(match_operand:SI 2 "non_and_cint_operand" "")))]
|
(match_operand:SI 2 "non_and_cint_operand" "")))
|
||||||
""
|
(clobber (match_scratch:CC 3 ""))]
|
||||||
[(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))
|
"reload_completed"
|
||||||
(set (match_dup 0) (and:SI (match_dup 0) (match_dup 4)))]
|
[(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]);
|
operands[4] = GEN_INT (INTVAL (operands[2]) & 0xffff0000);
|
||||||
int i, transitions, last_bit_value;
|
operands[5] = GEN_INT (INTVAL (operands[2]) & 0x0000ffff);
|
||||||
int orig = maskval, first_c = maskval, second_c;
|
operands[6] = ((mask_constant (INTVAL (operands[4])))
|
||||||
|
? gen_rtx (SCRATCH, CCmode)
|
||||||
/* We know that MASKVAL must have more than 2 bit-transitions. Start at
|
: operands[3]);
|
||||||
the low-order bit and count for the third transition. When we get there,
|
operands[7] = operands[3];
|
||||||
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);
|
|
||||||
}")
|
}")
|
||||||
|
|
||||||
(define_insn "iorsi3"
|
(define_insn "iorsi3"
|
||||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
|
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
|
||||||
(ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
|
(ior:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
|
||||||
(match_operand:SI 2 "logical_operand" "r,K,J")))]
|
(match_operand:SI 2 "reg_or_cint_operand" "r,K,J,n")))]
|
||||||
""
|
""
|
||||||
"@
|
"@
|
||||||
or %0,%1,%2
|
or %0,%1,%2
|
||||||
{oril|ori} %0,%1,%b2
|
{oril|ori} %0,%1,%b2
|
||||||
{oriu|oris} %0,%1,%u2")
|
{oriu|oris} %0,%1,%u2
|
||||||
|
#"
|
||||||
|
[(set_attr "length" "4,4,4,8")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn ""
|
||||||
[(set (match_operand:CC 0 "cc_reg_operand" "=x")
|
[(set (match_operand:CC 0 "cc_reg_operand" "=x")
|
||||||
|
@ -1758,7 +1745,7 @@
|
||||||
[(set_attr "type" "compare")])
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
;; Split an IOR that we can't do in one insn into two insns, each of which
|
;; 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
|
(define_split
|
||||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||||
|
@ -1769,20 +1756,21 @@
|
||||||
(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]
|
(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 4)))]
|
||||||
"
|
"
|
||||||
{
|
{
|
||||||
operands[3] = gen_rtx (CONST_INT, VOIDmode,
|
operands[3] = GEN_INT (INTVAL (operands[2]) & 0xffff0000);
|
||||||
INTVAL (operands[2]) & 0xffff0000);
|
operands[4] = GEN_INT (INTVAL (operands[2]) & 0x0000ffff);
|
||||||
operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
|
|
||||||
}")
|
}")
|
||||||
|
|
||||||
(define_insn "xorsi3"
|
(define_insn "xorsi3"
|
||||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
|
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
|
||||||
(xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
|
(xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
|
||||||
(match_operand:SI 2 "logical_operand" "r,K,J")))]
|
(match_operand:SI 2 "reg_or_cint_operand" "r,K,J,n")))]
|
||||||
""
|
""
|
||||||
"@
|
"@
|
||||||
xor %0,%1,%2
|
xor %0,%1,%2
|
||||||
{xoril|xori} %0,%1,%b2
|
{xoril|xori} %0,%1,%b2
|
||||||
{xoriu|xoris} %0,%1,%u2")
|
{xoriu|xoris} %0,%1,%u2
|
||||||
|
#"
|
||||||
|
[(set_attr "length" "4,4,4,8")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn ""
|
||||||
[(set (match_operand:CC 0 "cc_reg_operand" "=x")
|
[(set (match_operand:CC 0 "cc_reg_operand" "=x")
|
||||||
|
@ -1806,7 +1794,7 @@
|
||||||
[(set_attr "type" "compare")])
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
;; Split an XOR that we can't do in one insn into two insns, each of which
|
;; 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
|
(define_split
|
||||||
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
[(set (match_operand:SI 0 "gpc_reg_operand" "")
|
||||||
|
@ -1817,9 +1805,8 @@
|
||||||
(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]
|
(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))]
|
||||||
"
|
"
|
||||||
{
|
{
|
||||||
operands[3] = gen_rtx (CONST_INT, VOIDmode,
|
operands[3] = GEN_INT (INTVAL (operands[2]) & 0xffff0000);
|
||||||
INTVAL (operands[2]) & 0xffff0000);
|
operands[4] = GEN_INT (INTVAL (operands[2]) & 0x0000ffff);
|
||||||
operands[4] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) & 0xffff);
|
|
||||||
}")
|
}")
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn ""
|
||||||
|
@ -3058,7 +3045,7 @@
|
||||||
(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||||
(match_operand:SF 3 "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"
|
"fmadds %0,%1,%2,%3"
|
||||||
[(set_attr "type" "fp")])
|
[(set_attr "type" "fp")])
|
||||||
|
|
||||||
|
@ -3067,7 +3054,7 @@
|
||||||
(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||||
(match_operand:SF 3 "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"
|
"{fma|fmadd} %0,%1,%2,%3"
|
||||||
[(set_attr "type" "dmul")])
|
[(set_attr "type" "dmul")])
|
||||||
|
|
||||||
|
@ -3076,7 +3063,7 @@
|
||||||
(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||||
(match_operand:SF 3 "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"
|
"fmsubs %0,%1,%2,%3"
|
||||||
[(set_attr "type" "fp")])
|
[(set_attr "type" "fp")])
|
||||||
|
|
||||||
|
@ -3085,7 +3072,7 @@
|
||||||
(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
||||||
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
(match_operand:SF 2 "gpc_reg_operand" "f"))
|
||||||
(match_operand:SF 3 "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"
|
"{fms|fmsub} %0,%1,%2,%3"
|
||||||
[(set_attr "type" "dmul")])
|
[(set_attr "type" "dmul")])
|
||||||
|
|
||||||
|
@ -3094,7 +3081,7 @@
|
||||||
(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
(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 2 "gpc_reg_operand" "f"))
|
||||||
(match_operand:SF 3 "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"
|
"fnmadds %0,%1,%2,%3"
|
||||||
[(set_attr "type" "fp")])
|
[(set_attr "type" "fp")])
|
||||||
|
|
||||||
|
@ -3103,7 +3090,7 @@
|
||||||
(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
(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 2 "gpc_reg_operand" "f"))
|
||||||
(match_operand:SF 3 "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"
|
"{fnma|fnmadd} %0,%1,%2,%3"
|
||||||
[(set_attr "type" "dmul")])
|
[(set_attr "type" "dmul")])
|
||||||
|
|
||||||
|
@ -3112,7 +3099,7 @@
|
||||||
(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
(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 2 "gpc_reg_operand" "f"))
|
||||||
(match_operand:SF 3 "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"
|
"fnmsubs %0,%1,%2,%3"
|
||||||
[(set_attr "type" "fp")])
|
[(set_attr "type" "fp")])
|
||||||
|
|
||||||
|
@ -3121,7 +3108,7 @@
|
||||||
(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
|
(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 2 "gpc_reg_operand" "f"))
|
||||||
(match_operand:SF 3 "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"
|
"{fnms|fnmsub} %0,%1,%2,%3"
|
||||||
[(set_attr "type" "dmul")])
|
[(set_attr "type" "dmul")])
|
||||||
|
|
||||||
|
@ -5039,12 +5026,30 @@
|
||||||
"(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
|
"(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]);
|
operands[2] = rs6000_got_register (operands[1]);
|
||||||
}")
|
}")
|
||||||
|
|
||||||
(define_insn "*movsi_got_internal"
|
(define_insn "*movsi_got_internal"
|
||||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(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))]
|
(match_operand:SI 2 "register_operand" "b")] 8))]
|
||||||
"(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
|
"(DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) && flag_pic == 1"
|
||||||
"{l|lwz} %0,%a1@got(%2)"
|
"{l|lwz} %0,%a1@got(%2)"
|
||||||
|
@ -5132,24 +5137,7 @@
|
||||||
|
|
||||||
emit_insn (gen_movsi (tmp1, sym));
|
emit_insn (gen_movsi (tmp1, sym));
|
||||||
if (INTVAL (const_term) != 0)
|
if (INTVAL (const_term) != 0)
|
||||||
{
|
emit_insn (gen_addsi3 (operands[0], tmp1, GEN_INT (value)));
|
||||||
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)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DONE;
|
DONE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -6745,19 +6733,19 @@
|
||||||
;; tie and these are the pair most likely to be tieable (and the ones
|
;; tie and these are the pair most likely to be tieable (and the ones
|
||||||
;; that will benefit the most).
|
;; that will benefit the most).
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movdi_update1"
|
||||||
[(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
|
[(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
|
||||||
(mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
|
(mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
|
||||||
(match_operand:DI 2 "reg_or_short_operand" "r,I"))))
|
(match_operand:DI 2 "reg_or_short_operand" "r,I"))))
|
||||||
(set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:DI (match_dup 1) (match_dup 2)))]
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
||||||
"TARGET_POWERPC64"
|
"TARGET_POWERPC64 && TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
ldux %3,%0,%2
|
ldux %3,%0,%2
|
||||||
ldu %3,%2(%0)"
|
ldu %3,%2(%0)"
|
||||||
[(set_attr "type" "load")])
|
[(set_attr "type" "load")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movdi_update2"
|
||||||
[(set (match_operand:DI 3 "gpc_reg_operand" "=r")
|
[(set (match_operand:DI 3 "gpc_reg_operand" "=r")
|
||||||
(sign_extend:DI
|
(sign_extend:DI
|
||||||
(mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
|
(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"))
|
(match_operand:DI 3 "gpc_reg_operand" "r,r"))
|
||||||
(set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:DI (match_dup 1) (match_dup 2)))]
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
||||||
"TARGET_POWERPC64"
|
"TARGET_POWERPC64 && TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
stdux %3,%0,%2
|
stdux %3,%0,%2
|
||||||
stdu %3,%2(%0)"
|
stdu %3,%2(%0)"
|
||||||
[(set_attr "type" "store")])
|
[(set_attr "type" "store")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movsi_update1"
|
||||||
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
||||||
(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
||||||
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
|
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
|
||||||
|
@ -6798,142 +6786,166 @@
|
||||||
(match_operand:SI 3 "gpc_reg_operand" "r,r"))
|
(match_operand:SI 3 "gpc_reg_operand" "r,r"))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
""
|
"TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
{stux|stwux} %3,%0,%2
|
{stux|stwux} %3,%0,%2
|
||||||
{stu|stwu} %3,%2(%0)"
|
{stu|stwu} %3,%2(%0)"
|
||||||
[(set_attr "type" "store")])
|
[(set_attr "type" "store")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movhi_update"
|
||||||
[(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
|
[(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
|
||||||
(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
(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:SI 2 "reg_or_short_operand" "r,I"))))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
""
|
"TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
lhzux %3,%0,%2
|
lhzux %3,%0,%2
|
||||||
lhzu %3,%2(%0)"
|
lhzu %3,%2(%0)"
|
||||||
[(set_attr "type" "load")])
|
[(set_attr "type" "load")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movhi_update2"
|
||||||
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
||||||
(zero_extend:SI
|
(zero_extend:SI
|
||||||
(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
(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:SI 2 "reg_or_short_operand" "r,I")))))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
""
|
"TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
lhzux %3,%0,%2
|
lhzux %3,%0,%2
|
||||||
lhzu %3,%2(%0)"
|
lhzu %3,%2(%0)"
|
||||||
[(set_attr "type" "load")])
|
[(set_attr "type" "load")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movhi_update3"
|
||||||
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
||||||
(sign_extend:SI
|
(sign_extend:SI
|
||||||
(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
(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:SI 2 "reg_or_short_operand" "r,I")))))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
""
|
"TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
lhaux %3,%0,%2
|
lhaux %3,%0,%2
|
||||||
lhau %3,%2(%0)"
|
lhau %3,%2(%0)"
|
||||||
[(set_attr "type" "load")])
|
[(set_attr "type" "load")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movhi_update4"
|
||||||
[(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
[(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:SI 2 "reg_or_short_operand" "r,I")))
|
||||||
(match_operand:HI 3 "gpc_reg_operand" "r,r"))
|
(match_operand:HI 3 "gpc_reg_operand" "r,r"))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
""
|
"TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
sthux %3,%0,%2
|
sthux %3,%0,%2
|
||||||
sthu %3,%2(%0)"
|
sthu %3,%2(%0)"
|
||||||
[(set_attr "type" "store")])
|
[(set_attr "type" "store")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movqi_update1"
|
||||||
[(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
|
[(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
|
||||||
(mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
(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:SI 2 "reg_or_short_operand" "r,I"))))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
""
|
"TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
lbzux %3,%0,%2
|
lbzux %3,%0,%2
|
||||||
lbzu %3,%2(%0)"
|
lbzu %3,%2(%0)"
|
||||||
[(set_attr "type" "load")])
|
[(set_attr "type" "load")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movqi_update2"
|
||||||
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
|
||||||
(zero_extend:SI
|
(zero_extend:SI
|
||||||
(mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
(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:SI 2 "reg_or_short_operand" "r,I")))))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
""
|
"TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
lbzux %3,%0,%2
|
lbzux %3,%0,%2
|
||||||
lbzu %3,%2(%0)"
|
lbzu %3,%2(%0)"
|
||||||
[(set_attr "type" "load")])
|
[(set_attr "type" "load")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movqi_update3"
|
||||||
[(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
[(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:SI 2 "reg_or_short_operand" "r,I")))
|
||||||
(match_operand:QI 3 "gpc_reg_operand" "r,r"))
|
(match_operand:QI 3 "gpc_reg_operand" "r,r"))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
""
|
"TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
stbux %3,%0,%2
|
stbux %3,%0,%2
|
||||||
stbu %3,%2(%0)"
|
stbu %3,%2(%0)"
|
||||||
[(set_attr "type" "store")])
|
[(set_attr "type" "store")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movsf_update1"
|
||||||
[(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
|
[(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
|
||||||
(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
(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:SI 2 "reg_or_short_operand" "r,I"))))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT && TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
lfsux %3,%0,%2
|
lfsux %3,%0,%2
|
||||||
lfsu %3,%2(%0)"
|
lfsu %3,%2(%0)"
|
||||||
[(set_attr "type" "fpload")])
|
[(set_attr "type" "fpload")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movsf_update2"
|
||||||
[(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
[(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:SI 2 "reg_or_short_operand" "r,I")))
|
||||||
(match_operand:SF 3 "gpc_reg_operand" "f,f"))
|
(match_operand:SF 3 "gpc_reg_operand" "f,f"))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT && TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
stfsux %3,%0,%2
|
stfsux %3,%0,%2
|
||||||
stfsu %3,%2(%0)"
|
stfsu %3,%2(%0)"
|
||||||
[(set_attr "type" "fpstore")])
|
[(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")
|
[(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
|
||||||
(mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
(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:SI 2 "reg_or_short_operand" "r,I"))))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT && TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
lfdux %3,%0,%2
|
lfdux %3,%0,%2
|
||||||
lfdu %3,%2(%0)"
|
lfdu %3,%2(%0)"
|
||||||
[(set_attr "type" "fpload")])
|
[(set_attr "type" "fpload")])
|
||||||
|
|
||||||
(define_insn ""
|
(define_insn "*movdf_update2"
|
||||||
[(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
|
[(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:SI 2 "reg_or_short_operand" "r,I")))
|
||||||
(match_operand:DF 3 "gpc_reg_operand" "f,f"))
|
(match_operand:DF 3 "gpc_reg_operand" "f,f"))
|
||||||
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
|
||||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_HARD_FLOAT && TARGET_UPDATE"
|
||||||
"@
|
"@
|
||||||
stfdux %3,%0,%2
|
stfdux %3,%0,%2
|
||||||
stfdu %3,%2(%0)"
|
stfdu %3,%2(%0)"
|
||||||
|
@ -7007,11 +7019,18 @@
|
||||||
else
|
else
|
||||||
neg_op0 = GEN_INT (- INTVAL (operands[0]));
|
neg_op0 = GEN_INT (- INTVAL (operands[0]));
|
||||||
|
|
||||||
if (TARGET_32BIT)
|
if (TARGET_UPDATE)
|
||||||
emit_insn (gen_movsi_update (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
|
emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update : gen_movdi_update))
|
||||||
else
|
(stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
|
||||||
emit_insn (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;
|
DONE;
|
||||||
}")
|
}")
|
||||||
|
|
||||||
|
@ -7089,7 +7108,7 @@
|
||||||
"TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0"
|
"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 \"\";
|
return \"\";
|
||||||
}"
|
}"
|
||||||
[(set_attr "type" "load")])
|
[(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_NO_BITFIELD_TYPE 0x40000000 /* Set PCC_BITFIELD_TYPE_MATTERS to 0 */
|
||||||
#define MASK_STRICT_ALIGN 0x20000000 /* Set STRICT_ALIGNMENT to 1. */
|
#define MASK_STRICT_ALIGN 0x20000000 /* Set STRICT_ALIGNMENT to 1. */
|
||||||
#define MASK_RELOCATABLE 0x10000000 /* GOT pointers are PC relative */
|
#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_LITTLE_ENDIAN 0x04000000 /* target is little endian */
|
||||||
#define MASK_REGNAMES 0x02000000 /* use alternate register names. */
|
#define MASK_REGNAMES 0x02000000 /* use alternate register names. */
|
||||||
#define MASK_PROTOTYPE 0x01000000 /* Only prototyped fcns pass variable args */
|
#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_NO_BITFIELD_TYPE (target_flags & MASK_NO_BITFIELD_TYPE)
|
||||||
#define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN)
|
#define TARGET_STRICT_ALIGN (target_flags & MASK_STRICT_ALIGN)
|
||||||
#define TARGET_RELOCATABLE (target_flags & MASK_RELOCATABLE)
|
#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_LITTLE_ENDIAN (target_flags & MASK_LITTLE_ENDIAN)
|
||||||
#define TARGET_REGNAMES (target_flags & MASK_REGNAMES)
|
#define TARGET_REGNAMES (target_flags & MASK_REGNAMES)
|
||||||
#define TARGET_PROTOTYPE (target_flags & MASK_PROTOTYPE)
|
#define TARGET_PROTOTYPE (target_flags & MASK_PROTOTYPE)
|
||||||
#define TARGET_EABI (target_flags & MASK_EABI)
|
|
||||||
#define TARGET_TOC ((target_flags & MASK_64BIT) \
|
#define TARGET_TOC ((target_flags & MASK_64BIT) \
|
||||||
|| ((target_flags & (MASK_RELOCATABLE \
|
|| ((target_flags & (MASK_RELOCATABLE \
|
||||||
| MASK_MINIMAL_TOC)) \
|
| MASK_MINIMAL_TOC)) \
|
||||||
|
@ -73,13 +71,9 @@ extern enum rs6000_sdata_type rs6000_sdata;
|
||||||
{ "strict-align", MASK_STRICT_ALIGN }, \
|
{ "strict-align", MASK_STRICT_ALIGN }, \
|
||||||
{ "no-strict-align", -MASK_STRICT_ALIGN }, \
|
{ "no-strict-align", -MASK_STRICT_ALIGN }, \
|
||||||
{ "relocatable", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
|
{ "relocatable", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
|
||||||
{ "relocatable", -MASK_SDATA }, \
|
|
||||||
{ "no-relocatable", -MASK_RELOCATABLE }, \
|
{ "no-relocatable", -MASK_RELOCATABLE }, \
|
||||||
{ "relocatable-lib", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
|
{ "relocatable-lib", MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC }, \
|
||||||
{ "relocatable-lib", -MASK_SDATA }, \
|
|
||||||
{ "no-relocatable-lib", -MASK_RELOCATABLE }, \
|
{ "no-relocatable-lib", -MASK_RELOCATABLE }, \
|
||||||
{ "sdata", MASK_SDATA }, \
|
|
||||||
{ "no-sdata", -MASK_SDATA }, \
|
|
||||||
{ "little-endian", MASK_LITTLE_ENDIAN }, \
|
{ "little-endian", MASK_LITTLE_ENDIAN }, \
|
||||||
{ "little", MASK_LITTLE_ENDIAN }, \
|
{ "little", MASK_LITTLE_ENDIAN }, \
|
||||||
{ "big-endian", -MASK_LITTLE_ENDIAN }, \
|
{ "big-endian", -MASK_LITTLE_ENDIAN }, \
|
||||||
|
@ -94,6 +88,8 @@ extern enum rs6000_sdata_type rs6000_sdata;
|
||||||
{ "no-eabi", -MASK_EABI }, \
|
{ "no-eabi", -MASK_EABI }, \
|
||||||
{ "regnames", MASK_REGNAMES }, \
|
{ "regnames", MASK_REGNAMES }, \
|
||||||
{ "no-regnames", -MASK_REGNAMES }, \
|
{ "no-regnames", -MASK_REGNAMES }, \
|
||||||
|
{ "sdata", 0 }, \
|
||||||
|
{ "no-sdata", 0 }, \
|
||||||
{ "sim", 0 }, \
|
{ "sim", 0 }, \
|
||||||
{ "mvme", 0 }, \
|
{ "mvme", 0 }, \
|
||||||
{ "emb", 0 }, \
|
{ "emb", 0 }, \
|
||||||
|
@ -169,12 +165,8 @@ do { \
|
||||||
\
|
\
|
||||||
if (rs6000_sdata_name) \
|
if (rs6000_sdata_name) \
|
||||||
{ \
|
{ \
|
||||||
target_flags |= MASK_SDATA; \
|
|
||||||
if (!strcmp (rs6000_sdata_name, "none")) \
|
if (!strcmp (rs6000_sdata_name, "none")) \
|
||||||
{ \
|
rs6000_sdata = SDATA_NONE; \
|
||||||
rs6000_sdata = SDATA_NONE; \
|
|
||||||
target_flags &= ~MASK_SDATA; \
|
|
||||||
} \
|
|
||||||
else if (!strcmp (rs6000_sdata_name, "data")) \
|
else if (!strcmp (rs6000_sdata_name, "data")) \
|
||||||
rs6000_sdata = SDATA_DATA; \
|
rs6000_sdata = SDATA_DATA; \
|
||||||
else if (!strcmp (rs6000_sdata_name, "default")) \
|
else if (!strcmp (rs6000_sdata_name, "default")) \
|
||||||
|
@ -186,21 +178,10 @@ do { \
|
||||||
else \
|
else \
|
||||||
error ("Bad value for -msdata=%s", rs6000_sdata_name); \
|
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) \
|
else if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS) \
|
||||||
{ \
|
{ \
|
||||||
rs6000_sdata = SDATA_DATA; \
|
rs6000_sdata = SDATA_DATA; \
|
||||||
rs6000_sdata_name = "data"; \
|
rs6000_sdata_name = "data"; \
|
||||||
target_flags |= MASK_SDATA; \
|
|
||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
|
@ -225,10 +206,12 @@ do { \
|
||||||
rs6000_sdata_name); \
|
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; \
|
rs6000_sdata = SDATA_NONE; \
|
||||||
error ("-msdata and -mcall-%s are incompatible.", rs6000_abi_name); \
|
error ("-msdata=%s and -mcall-%s are incompatible.", \
|
||||||
|
rs6000_sdata_name, rs6000_abi_name); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
if (TARGET_RELOCATABLE && !TARGET_MINIMAL_TOC) \
|
if (TARGET_RELOCATABLE && !TARGET_MINIMAL_TOC) \
|
||||||
|
@ -467,8 +450,6 @@ extern void sbss_section ();
|
||||||
void \
|
void \
|
||||||
toc_section () \
|
toc_section () \
|
||||||
{ \
|
{ \
|
||||||
static int toc_initialized = 0; \
|
|
||||||
\
|
|
||||||
if (in_section != in_toc) \
|
if (in_section != in_toc) \
|
||||||
{ \
|
{ \
|
||||||
in_section = in_toc; \
|
in_section = in_toc; \
|
||||||
|
@ -628,7 +609,7 @@ extern int rs6000_pic_labelno;
|
||||||
char *init_ptr = (TARGET_64BIT) ? ".quad" : ".long"; \
|
char *init_ptr = (TARGET_64BIT) ? ".quad" : ".long"; \
|
||||||
STRIP_NAME_ENCODING (orig_name, NAME); \
|
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; \
|
char buf[256], *buf_ptr; \
|
||||||
\
|
\
|
||||||
|
@ -701,7 +682,8 @@ extern int rs6000_pic_labelno;
|
||||||
#undef ASM_OUTPUT_ALIGNED_LOCAL
|
#undef ASM_OUTPUT_ALIGNED_LOCAL
|
||||||
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
|
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
|
||||||
do { \
|
do { \
|
||||||
if (TARGET_SDATA && (SIZE) > 0 && (SIZE) <= g_switch_value) \
|
if (rs6000_sdata != SDATA_NONE && (SIZE) > 0 \
|
||||||
|
&& (SIZE) <= g_switch_value) \
|
||||||
{ \
|
{ \
|
||||||
sdata_section (); \
|
sdata_section (); \
|
||||||
ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \
|
ASM_OUTPUT_ALIGN (FILE, exact_log2 (ALIGN / BITS_PER_UNIT)); \
|
||||||
|
@ -961,7 +943,8 @@ do { \
|
||||||
|
|
||||||
/* Pass various options to the assembler */
|
/* Pass various options to the assembler */
|
||||||
#undef ASM_SPEC
|
#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,*:%*} \
|
%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
|
||||||
%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
|
%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
|
||||||
%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
|
%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
|
||||||
|
@ -983,7 +966,9 @@ do { \
|
||||||
%{!meabi: %{!mno-eabi: \
|
%{!meabi: %{!mno-eabi: \
|
||||||
%{mrelocatable: -meabi } \
|
%{mrelocatable: -meabi } \
|
||||||
%{mcall-solaris: -mno-eabi } \
|
%{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 */
|
/* Don't put -Y P,<path> for cross compilers */
|
||||||
#undef LINK_PATH_SPEC
|
#undef LINK_PATH_SPEC
|
||||||
|
@ -1357,3 +1342,12 @@ do { \
|
||||||
|
|
||||||
#undef MULTILIB_DEFAULTS
|
#undef MULTILIB_DEFAULTS
|
||||||
#define MULTILIB_DEFAULTS { "mbig", "mcall-sysv" }
|
#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…
Reference in New Issue