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:
Paul Brook 2008-11-13 15:19:02 +00:00 committed by Paul Brook
parent 255e5b0481
commit 5fd424238b
4 changed files with 74 additions and 24 deletions

View file

@ -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

View file

@ -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
{

View file

@ -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.

View file

@ -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