This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]