invoke.texi: Document --fix-cortex-m3.
2008-11-13 Paul Brook <paul@codesourcery.com> gcc/ * doc/invoke.texi: Document --fix-cortex-m3. * config/arm/arm.c (arm_override_options): Set fix_cm3_ldrd if Cortex-M3 cpu is selected. (output_move_double): Avoid overlapping base register and first destination register when fix_cm3_ldrd. * config/arm/arm.opt: Add mfix-cortex-m3-ldrd. From-SVN: r141822
This commit is contained in:
parent
255e5b0481
commit
5fd424238b
4 changed files with 74 additions and 24 deletions
|
@ -1,3 +1,12 @@
|
|||
2008-11-13 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* doc/invoke.texi: Document --fix-cortex-m3.
|
||||
* config/arm/arm.c (arm_override_options): Set fix_cm3_ldrd if
|
||||
Cortex-M3 cpu is selected.
|
||||
(output_move_double): Avoid overlapping base register and first
|
||||
destination register when fix_cm3_ldrd.
|
||||
* config/arm/arm.opt: Add mfix-cortex-m3-ldrd.
|
||||
|
||||
2008-11-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR bootstrap/38100
|
||||
|
|
|
@ -1037,6 +1037,7 @@ arm_override_options (void)
|
|||
{
|
||||
unsigned i;
|
||||
enum processor_type target_arch_cpu = arm_none;
|
||||
enum processor_type selected_cpu = arm_none;
|
||||
|
||||
/* Set up the flags based on the cpu/architecture selected by the user. */
|
||||
for (i = ARRAY_SIZE (arm_select); i--;)
|
||||
|
@ -1069,6 +1070,9 @@ arm_override_options (void)
|
|||
if (i == ARM_OPT_SET_ARCH)
|
||||
target_arch_cpu = sel->core;
|
||||
|
||||
if (i == ARM_OPT_SET_CPU)
|
||||
selected_cpu = (enum processor_type) (sel - ptr->processors);
|
||||
|
||||
if (i != ARM_OPT_SET_TUNE)
|
||||
{
|
||||
/* If we have been given an architecture and a processor
|
||||
|
@ -1099,21 +1103,20 @@ arm_override_options (void)
|
|||
{
|
||||
const struct processors * sel;
|
||||
unsigned int sought;
|
||||
enum processor_type cpu;
|
||||
|
||||
cpu = TARGET_CPU_DEFAULT;
|
||||
if (cpu == arm_none)
|
||||
selected_cpu = TARGET_CPU_DEFAULT;
|
||||
if (selected_cpu == arm_none)
|
||||
{
|
||||
#ifdef SUBTARGET_CPU_DEFAULT
|
||||
/* Use the subtarget default CPU if none was specified by
|
||||
configure. */
|
||||
cpu = SUBTARGET_CPU_DEFAULT;
|
||||
selected_cpu = SUBTARGET_CPU_DEFAULT;
|
||||
#endif
|
||||
/* Default to ARM6. */
|
||||
if (cpu == arm_none)
|
||||
cpu = arm6;
|
||||
if (selected_cpu == arm_none)
|
||||
selected_cpu = arm6;
|
||||
}
|
||||
sel = &all_cores[cpu];
|
||||
sel = &all_cores[selected_cpu];
|
||||
|
||||
insn_flags = sel->flags;
|
||||
|
||||
|
@ -1505,6 +1508,15 @@ arm_override_options (void)
|
|||
arm_pic_register = pic_register;
|
||||
}
|
||||
|
||||
/* Enable -mfix-cortex-m3-ldrd by default for Cortex-M3 cores. */
|
||||
if (fix_cm3_ldrd == 2)
|
||||
{
|
||||
if (selected_cpu == cortexm3)
|
||||
fix_cm3_ldrd = 1;
|
||||
else
|
||||
fix_cm3_ldrd = 0;
|
||||
}
|
||||
|
||||
/* ??? We might want scheduling for thumb2. */
|
||||
if (TARGET_THUMB && flag_schedule_insns)
|
||||
{
|
||||
|
@ -9978,7 +9990,8 @@ output_move_double (rtx *operands)
|
|||
switch (GET_CODE (XEXP (operands[1], 0)))
|
||||
{
|
||||
case REG:
|
||||
if (TARGET_LDRD)
|
||||
if (TARGET_LDRD
|
||||
&& !(fix_cm3_ldrd && reg0 == REGNO(XEXP (operands[1], 0))))
|
||||
output_asm_insn ("ldr%(d%)\t%0, [%m1]", operands);
|
||||
else
|
||||
output_asm_insn ("ldm%(ia%)\t%m1, %M0", operands);
|
||||
|
@ -10010,6 +10023,10 @@ output_move_double (rtx *operands)
|
|||
|
||||
case PRE_MODIFY:
|
||||
case POST_MODIFY:
|
||||
/* Autoicrement addressing modes should never have overlapping
|
||||
base and destination registers, and overlapping index registers
|
||||
are already prohibited, so this doesn't need to worry about
|
||||
fix_cm3_ldrd. */
|
||||
otherops[0] = operands[0];
|
||||
otherops[1] = XEXP (XEXP (XEXP (operands[1], 0), 1), 0);
|
||||
otherops[2] = XEXP (XEXP (XEXP (operands[1], 0), 1), 1);
|
||||
|
@ -10062,11 +10079,15 @@ output_move_double (rtx *operands)
|
|||
/* We might be able to use ldrd %0, %1 here. However the range is
|
||||
different to ldr/adr, and it is broken on some ARMv7-M
|
||||
implementations. */
|
||||
output_asm_insn ("adr%?\t%0, %1", operands);
|
||||
/* Use the second register of the pair to avoid problematic
|
||||
overlap. */
|
||||
otherops[1] = operands[1];
|
||||
output_asm_insn ("adr%?\t%0, %1", otherops);
|
||||
operands[1] = otherops[0];
|
||||
if (TARGET_LDRD)
|
||||
output_asm_insn ("ldr%(d%)\t%0, [%0]", operands);
|
||||
output_asm_insn ("ldr%(d%)\t%0, [%1]", operands);
|
||||
else
|
||||
output_asm_insn ("ldm%(ia%)\t%0, %M0", operands);
|
||||
output_asm_insn ("ldm%(ia%)\t%1, %M0", operands);
|
||||
break;
|
||||
|
||||
/* ??? This needs checking for thumb2. */
|
||||
|
@ -10099,30 +10120,37 @@ output_move_double (rtx *operands)
|
|||
return "";
|
||||
}
|
||||
}
|
||||
otherops[0] = gen_rtx_REG(SImode, REGNO(operands[0]) + 1);
|
||||
operands[1] = otherops[0];
|
||||
if (TARGET_LDRD
|
||||
&& (GET_CODE (otherops[2]) == REG
|
||||
|| (GET_CODE (otherops[2]) == CONST_INT
|
||||
&& INTVAL (otherops[2]) > -256
|
||||
&& INTVAL (otherops[2]) < 256)))
|
||||
{
|
||||
if (reg_overlap_mentioned_p (otherops[0],
|
||||
if (reg_overlap_mentioned_p (operands[0],
|
||||
otherops[2]))
|
||||
{
|
||||
rtx tmp;
|
||||
/* Swap base and index registers over to
|
||||
avoid a conflict. */
|
||||
otherops[1] = XEXP (XEXP (operands[1], 0), 1);
|
||||
otherops[2] = XEXP (XEXP (operands[1], 0), 0);
|
||||
tmp = otherops[1];
|
||||
otherops[1] = otherops[2];
|
||||
otherops[2] = tmp;
|
||||
}
|
||||
/* If both registers conflict, it will usually
|
||||
have been fixed by a splitter. */
|
||||
if (reg_overlap_mentioned_p (otherops[0], otherops[2]))
|
||||
if (reg_overlap_mentioned_p (operands[0], otherops[2])
|
||||
|| (fix_cm3_ldrd && reg0 == REGNO (otherops[1])))
|
||||
{
|
||||
output_asm_insn ("add%?\t%1, %1, %2", otherops);
|
||||
output_asm_insn ("ldr%(d%)\t%0, [%1]",
|
||||
otherops);
|
||||
output_asm_insn ("add%?\t%0, %1, %2", otherops);
|
||||
output_asm_insn ("ldr%(d%)\t%0, [%1]", operands);
|
||||
}
|
||||
else
|
||||
output_asm_insn ("ldr%(d%)\t%0, [%1, %2]", otherops);
|
||||
{
|
||||
otherops[0] = operands[0];
|
||||
output_asm_insn ("ldr%(d%)\t%0, [%1, %2]", otherops);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -10140,9 +10168,9 @@ output_move_double (rtx *operands)
|
|||
output_asm_insn ("sub%?\t%0, %1, %2", otherops);
|
||||
|
||||
if (TARGET_LDRD)
|
||||
return "ldr%(d%)\t%0, [%0]";
|
||||
return "ldr%(d%)\t%0, [%1]";
|
||||
|
||||
return "ldm%(ia%)\t%0, %M0";
|
||||
return "ldm%(ia%)\t%1, %M0";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -159,4 +159,9 @@ Use Neon quad-word (rather than double-word) registers for vectorization
|
|||
|
||||
mword-relocations
|
||||
Target Report Var(target_word_relocations) Init(TARGET_DEFAULT_WORD_RELOCATIONS)
|
||||
+Only generate absolute relocations on word sized values.
|
||||
Only generate absolute relocations on word sized values.
|
||||
|
||||
mfix-cortex-m3-ldrd
|
||||
Target Report Var(fix_cm3_ldrd) Init(2)
|
||||
Avoid overlapping destination and address registers on LDRD instructions
|
||||
that may trigger Cortex-M3 errata.
|
||||
|
|
|
@ -452,8 +452,9 @@ Objective-C and Objective-C++ Dialects}.
|
|||
-mthumb -marm @gol
|
||||
-mtpcs-frame -mtpcs-leaf-frame @gol
|
||||
-mcaller-super-interworking -mcallee-super-interworking @gol
|
||||
-mtp=@var{name}
|
||||
-mword-relocations}
|
||||
-mtp=@var{name} @gol
|
||||
-mword-relocations @gol
|
||||
-mfix-cortex-m3-ldrd}
|
||||
|
||||
@emph{AVR Options}
|
||||
@gccoptlist{-mmcu=@var{mcu} -msize -minit-stack=@var{n} -mno-interrupts @gol
|
||||
|
@ -8708,6 +8709,13 @@ Put functions, data, and readonly data in @var{text-section},
|
|||
by default. This can be overridden with the @code{section} attribute.
|
||||
@xref{Variable Attributes}.
|
||||
|
||||
@item -mfix-cortex-m3-ldrd
|
||||
@opindex mfix-cortex-m3-ldrd
|
||||
Some Cortex-M3 cores can cause data corruption when @code{ldrd} instructions
|
||||
with overlapping destination and base registers are used. This option avoids
|
||||
generating these instructions. This option is enabled by default when
|
||||
@option{-mcpu=cortex-m3} is specified.
|
||||
|
||||
@end table
|
||||
|
||||
@node ARM Options
|
||||
|
|
Loading…
Add table
Reference in a new issue