This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
custom ARM processor toolchain port
- From: Claudio Favi <claudio dot favi at epfl dot ch>
- To: ecos-discuss at ecos dot sourceware dot org
- Date: Wed, 26 Oct 2005 12:03:16 +0200
- Subject: [ECOS] custom ARM processor toolchain port
I know this isn't closely related to ecos but i'm trying to modify gcc
3.2.1 to work around some hardware bug and eventually port ecos to my
platform. If anyone who tweaked in gcc could help it would be
appreciated. My hardware is a custom made ARM7TDM "compliant" processor
but unfortunately I have some instructions that are broken. More
specifically one of the broken instructions are the LDM/STM with
decreasing addressing. To work around this bug i'd like to use the
increasing LDM/STM counterpart for eg:
ldmda R0, {R1,...,Rn} <= is broken
would need to be replaced by:
sub R0, R0, #n*4
ldmib R0!, {R1,...,Rn}
or
sub R0, R0, #n*4
ldmib R0, {R1,...,Rn}
add R0, R0, #n*4
I went through gcc source code and i think the only files I need to
modify are the following:
gcc/config/arm/arm.md
gcc/config/arm/arm.c
gcc/config/arm/arm.h (didn't touch this file so far)
now i replaced any occurrence of ldmd? and ldm?a in arm.md with the
corresponding workaround. for e.g. in insn "*arith_adjacentmem" around
line 8050:
if (val1 < val2)
output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm);
else
output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
was replaced by
if (val1 < val2)
{
output_asm_insn (\"sub%?\\t%0 , %0, #4\" , ldm );
output_asm_insn (\"ldm%?ib\\t%0, {%1, %2}\", ldm);
output_asm_insn (\"add%?\\t%0, %0, #4\" , ldm );
}
else
output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm);
In arm.c i'm trying to modify everywhere i see incorrect ldm/stm in
some similar way by using asm_fprintf(...) or output_asm_insn(...) but
could never get gcc to compile. More specifically in
output_return_instruction() i changed:
if (frame_pointer_needed) {
ldmfix = TRUE;
sprintf (instr, "ldm%sfd\t%%|fp!, {", conditional);
/* sprintf (instr, "ldm%sea\t%%|fp, {", conditional);*/
} ...
if(ldmfix) {
sprintf(ldmfixstr, "sub%s\t%%|fp, %%|fp, #%d", conditional,
4*(regscount+1));
output_asm_insn (ldmfixstr, & operand);
}
output_asm_insn (instr, & operand);
when compiling I get loads of warnings for
gcc/arm-elf/xscale/libiberty/regex.c and when assembling it complains :
/tmp/ccUf6qho.s: Assembler messages:
/tmp/ccUf6qho.s:2545: Error: bad immediate value for offset (4100)
i compiled regex.c with -S and there error doesn't seem directly
related to a "patched" ldm instruction.
Can anyone give me a hint on how this can be done ? What am i doing
wrong here ?
thank you.
Claudio
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss