porting GCC to a micro with a very limited addressing mode --- what to write in LEGITIMATE_ADDRESS, LEGITIMIZE_ADDRESS and micro.md ?!

2010-01-25 Thread Sergio Ruocco

Hi everyone,

I am porting GCC to a custom 16-bit microcontroller with very limited
addressing modes. Basically, it can only load/store using a (general
purpose) register as the address, without any offset:

LOAD (R2) R1; load R1 from memory at address (R2)
STORE R1 (R2)   ; store R1 to memory at address (R2)

As far as I can understand, this is more limited than the current
architectures supported by GCC that I found in the current gcc/config/*.

Since for my port I started modifying a MIPS target (from the tutorials
by IIT Bombay http://www.cse.iitb.ac.in/grc/ - great work guys!), the
GCC still generates code like:

sw  R15, 0(R13)
sw  R13, -2(R13)
sw  R14, -4(R13)
...
lw  R14, -4(R13)
lw  R15, 0(R13)

Now, in order to restrict the addressing mode, I want to force GCC to
compute the address and store it in a register, then generate the
instructions above to LOAD/STORE in memory. Thus I tried to fiddle with
LEGITIMATE_ADDRESS() and LEGITIMIZE_ADDRESS(), but the compilation of a
simple C program like:

void foobar(int par1, int par2, int parN)
{
int a, b, c;

a = -1;
b = -65535;
c = 0xabcd;
}

fails with

foobar7.c:11: internal compiler error: in change_address_1, at
emit-rtl.c:1800
Please submit a full bug report,

The same program gets compiled with the lw/sw above if I replace 0 with
1 in legitimate_address() below, at the comment /* reject/accept*/.

What should I do? How the addressing mode(s) are managed in the md files
and the LEGITxxx_ADDRESS() macros ? The GCC manual is not very clear on
this... Is there any other architecture/documentation I should look at ?

Thanks,

Sergio

===




Here follows a fragment of my micro.c with the C implementations of the
LEGITIMATE_ADDRESS() and LEGITIMIZE_ADDRESS() macros:

-

int
legitimate_address2(enum machine_mode MODE,rtx X)
{
rtx op1,op2;

if(CONSTANT_ADDRESS_P(X))
{
return 1;
}
if(GET_CODE(X)==REG && non_strict_base_reg(REGNO(X)))
{
return 1;
}
if(GET_CODE(X)==PLUS) /* is it offset+(Rx) ?! */
{
puts ("GET_CODE(X)==PLUS ");
op1=XEXP(X,0);
op2=XEXP(X,1);
if(GET_CODE(op1)==REG && CONSTANT_ADDRESS_P(op2) &&
non_strict_base_reg(REGNO(op1)))
{
return 0; /* reject / accept */
}
if(GET_CODE(op2)==REG && CONSTANT_ADDRESS_P(op1) &&
non_strict_base_reg(REGNO(op2)))
{
return 0; /* reject / accept */
}
}
/*  reject all other cases, too */
puts ("legitimate_address2() - end - ret 0/NO");
return 0;
}


rtx
legitimize_address(rtx X,rtx OLDX, enum machine_mode MODE)
{
rtx op1,op2,op;
op=NULL;

if(memory_address_p(MODE,X))
   return X;
if(GET_CODE(X)==MEM && !no_new_pseudos)
op = force_reg(MODE,X);

else if ( GET_CODE(X)==PLUS && !no_new_pseudos)
{
puts("GET_CODE(X)==PLUS && !no_new_pseudos !");

op1=XEXP(X,0);
op2=XEXP(X,1);
if(GET_CODE(op1)==REG && !CONSTANT_ADDRESS_P(op2))
{
op=force_reg(MODE,X);
}
else if(GET_CODE(op2)==REG && !CONSTANT_ADDRESS_P(op1))
{
op=force_reg(MODE,X);
}
else /* HACK */
{
op=force_reg(MODE,X);
}
-
/* Here is another HACK attempt, now disabled (commented), inspired by
http://gcc.gnu.org/ml/gcc/2001-07/msg01513.html, but this is not
working, either */

   else if ( (GET_CODE (op1)== REG) && (GET_CODE (op2) ==
CONST_INT) )
   {
op1 = force_reg (MODE, op1);
op = force_reg (MODE, gen_rtx_PLUS (MODE, op1, op2));
   }
-

}

if(op!=NULL && memory_address_p(MODE,op))
{
return op; /* if we rewrote the expression */
}
return X; /* otherwise original */
}
-



Here is a fragment of "micro.md" with the definitions of the "movXX",
load and store patterns:


(define_expand "movhi"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
  (match_operand:HI 1 "general_operand" "")
)]
""
{
if(GET_CODE(operands[0])==MEM && GET_CODE(operands[1])!=REG)
  {
if(!no_new_pseudos) {
operands[1]=force_reg(HImode,operands[1]);
}
  

Re: porting GCC to a micro with a very limited addressing mode --- what to write in LEGITIMATE_ADDRESS, LEGITIMIZE_ADDRESS and micro.md ?!

2010-01-25 Thread Sergio Ruocco
Gabriel Paubert wrote:
> On Mon, Jan 25, 2010 at 01:34:09PM +0100, Sergio Ruocco wrote:
>> Hi everyone,
>>
>> I am porting GCC to a custom 16-bit microcontroller with very limited
>> addressing modes. Basically, it can only load/store using a (general
>> purpose) register as the address, without any offset:
>>
>>  LOAD (R2) R1; load R1 from memory at address (R2)
>>  STORE R1 (R2)   ; store R1 to memory at address (R2)
>>
>> As far as I can understand, this is more limited than the current
>> architectures supported by GCC that I found in the current gcc/config/*.
> 
> The Itanium (ia64) has the same limited choice of addressing modes. 
> 
>   Gabriel

Thanks Gabriel.

I dived into the ia64 md, but it is still unclear to me how the various
parts (macros, define_expand and define_insn in MD etc.) work together
to force the computation of a source/dest address plus offset into a
register... can anyone help me with this ?

Thanks,

Sergio


Re: porting GCC to a micro with a very limited addressing mode --- what to write in LEGITIMATE_ADDRESS, LEGITIMIZE_ADDRESS and micro.md ?!

2010-01-28 Thread Sergio Ruocco


Now my GO_IF_LEGITIMATE_ADDRESS refuses anything that is not a REG
or a CONSTANT_ADDRESS:

int legitimate_address1(enum machine_mode MODE,rtx X)
{
if(CONSTANT_ADDRESS_P(X))
return 1;
if(GET_CODE(X)==REG && is_base_reg(REGNO(X)))
return 1;

return 0; /* fails everything else */

} /* this is the strict version, the non strict version is similar */

but GCC (4.0.2, just in case the version is relevant) still aborts the
compilation.


Then I found this wiki note about forcing complex addresses into
registers: http://gcc.gnu.org/wiki/WritingANewBackEnd

...
rtx copy_addr_to_reg (rtx x)
Equivalent to copy_to_mode_reg (Pmode, x). For example, this
function can be used to compute a complex address X in a register for an
instruction which supports only register indirect addressing. See also
replace_equiv_address() below.
...


Thus I changed in the .md file the movXX RTL expand macro to force any
MEM expression into a register:

(define_expand "movhi" /*  my micro is 16 bit... */
[(set (match_operand:HI 0 "nonimmediate_operand" "")
  (match_operand:HI 1 "general_operand" "")
)]
""
{
if(!no_new_pseudos && GET_CODE(operands[0])==MEM) {
if( /* addr in operands[0] == base reg + offset */ )
operands[0] = copy_addr_to_reg ( operands[0] );
}
)

The GCC still fails to generate the assembly code to do the arithmetic
computation of the baseReg+offset-->tempReg, and then use (tempReg) as
address.

Note that with the current MD GCC is able to generate simple sums like
R1 = R2 + R3 and R1 = R2 + IMM, thus the basic math to compute an
address is there.

Any suggestion on what I am doing wrong ?

Sergio


Michael Hope wrote:
> Hi Sergio.  My port has similar addressing modes - all memory must be
> accessed by one of two registers and can only be accessed indirectly,
> indirect with pre increment, and indirect with post increment.  The
> key is GO_IF_LEGITIMATE_ADDRESS and the legitimate address helper
> function.  Mine looks like this:
> 
> /* Return 1 if the address is OK, otherwise 0.
>Used by GO_IF_LEGITIMATE_ADDRESS.  */
> 
> bool
> tomi_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED,
>rtx x,
>bool strict_checking)
> {
>   /* (mem reg) */
>   if (REG_P (x)
>   && tomi_reg_ok (x, strict_checking)
>   )
> {
>   return 1;
> }
> 
>   if (GET_CODE(x) == PRE_DEC)
> {
> ...
> }
> 
>   if (GET_CODE(x) == POST_INC)
> {
> ...
> }
> 
>   return 0;
> }
> 
> tomi_reg_ok returns true if x is any register when strict checking is
> clear and true if x is one of my addressing registers when strict
> checking is set.
> 
> GCC will feed any memory accesses through this function to see if they
> are directly supported, and if not it will break them up into
> something smaller and try again.
> 
> Hope that helps,
> 
> -- Michael
> 
> 
> 2010/1/26 Sergio Ruocco :
>> Gabriel Paubert wrote:
>>> On Mon, Jan 25, 2010 at 01:34:09PM +0100, Sergio Ruocco wrote:
>>>> Hi everyone,
>>>>
>>>> I am porting GCC to a custom 16-bit microcontroller with very limited
>>>> addressing modes. Basically, it can only load/store using a (general
>>>> purpose) register as the address, without any offset:
>>>>
>>>>  LOAD (R2) R1; load R1 from memory at address (R2)
>>>>  STORE R1 (R2)   ; store R1 to memory at address (R2)
>>>>
>>>> As far as I can understand, this is more limited than the current
>>>> architectures supported by GCC that I found in the current gcc/config/*.
>>> The Itanium (ia64) has the same limited choice of addressing modes.
>>>
>>>   Gabriel
>> Thanks Gabriel.
>>
>> I dived into the ia64 md, but it is still unclear to me how the various
>> parts (macros, define_expand and define_insn in MD etc.) work together
>> to force the computation of a source/dest address plus offset into a
>> register... can anyone help me with this ?
>>
>> Thanks,
>>
>>Sergio
>>



Re: porting GCC to a micro with a very limited addressing mode --- success with LEGITIMATE / LEGITIMIZE_ADDRESS, stuck with ICE !

2010-02-09 Thread Sergio Ruocco
1792 addr = XEXP (memref, 0);
   1793   if (mode == GET_MODE (memref) && addr == XEXP (memref, 0)
   1794   && (!validate || memory_address_p (mode, addr)))
   1795 return memref;
   1796
   1797   if (validate)
   1798 {
   1799   if (reload_in_progress || reload_completed)
   1800 gcc_assert (memory_address_p (mode, addr));
   1801   else
   1802 addr = memory_address (mode, addr);
   1803 }
   1804
   1805   if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE
(memref))
   1806 return memref;
   1807
   1808   new = gen_rtx_MEM (mode, addr);
   1809   MEM_COPY_ATTRIBUTES (new, memref);
   1810   return new;
   1811 }


Could it be the REG+OFF which the LEGITIMATE_ADDRESS() rejects above?

But then why all the others before it get re-written by a call to
LEGITIMIZE_ ADDRESS() ?!

What is calling change_address_1() at the end of the compilation phase?

Thanks

Sergio

======






Sergio Ruocco wrote:
> 
> Now my GO_IF_LEGITIMATE_ADDRESS refuses anything that is not a REG
> or a CONSTANT_ADDRESS:
> 
> int legitimate_address1(enum machine_mode MODE,rtx X)
> {
>   if(CONSTANT_ADDRESS_P(X))
> return 1;
>   if(GET_CODE(X)==REG && is_base_reg(REGNO(X)))
> return 1;
> 
>   return 0; /* fails everything else */
> 
> } /* this is the strict version, the non strict version is similar */
> 
> but GCC (4.0.2, just in case the version is relevant) still aborts the
> compilation.
> 
> 
> Then I found this wiki note about forcing complex addresses into
> registers: http://gcc.gnu.org/wiki/WritingANewBackEnd
> 
> ...
> rtx copy_addr_to_reg (rtx x)
> Equivalent to copy_to_mode_reg (Pmode, x). For example, this
> function can be used to compute a complex address X in a register for an
> instruction which supports only register indirect addressing. See also
> replace_equiv_address() below.
> ...
> 
> 
> Thus I changed in the .md file the movXX RTL expand macro to force any
> MEM expression into a register:
> 
> (define_expand "movhi" /*  my micro is 16 bit... */
> [(set (match_operand:HI 0 "nonimmediate_operand" "")
>   (match_operand:HI 1 "general_operand" "")
> )]
> ""
>   {
>   if(!no_new_pseudos && GET_CODE(operands[0])==MEM) {
>   if( /* addr in operands[0] == base reg + offset */ )
>   operands[0] = copy_addr_to_reg ( operands[0] );
>   }
> )
> 
> The GCC still fails to generate the assembly code to do the arithmetic
> computation of the baseReg+offset-->tempReg, and then use (tempReg) as
> address.
> 
> Note that with the current MD GCC is able to generate simple sums like
> R1 = R2 + R3 and R1 = R2 + IMM, thus the basic math to compute an
> address is there.
> 
> Any suggestion on what I am doing wrong ?
> 
>   Sergio
> 
> 
> Michael Hope wrote:
>> Hi Sergio.  My port has similar addressing modes - all memory must be
>> accessed by one of two registers and can only be accessed indirectly,
>> indirect with pre increment, and indirect with post increment.  The
>> key is GO_IF_LEGITIMATE_ADDRESS and the legitimate address helper
>> function.  Mine looks like this:
>>
>> /* Return 1 if the address is OK, otherwise 0.
>>Used by GO_IF_LEGITIMATE_ADDRESS.  */
>>
>> bool
>> tomi_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED,
>>   rtx x,
>>   bool strict_checking)
>> {
>>   /* (mem reg) */
>>   if (REG_P (x)
>>   && tomi_reg_ok (x, strict_checking)
>>   )
>> {
>>   return 1;
>> }
>>
>>   if (GET_CODE(x) == PRE_DEC)
>> {
>> ...
>>     }
>>
>>   if (GET_CODE(x) == POST_INC)
>> {
>> ...
>> }
>>
>>   return 0;
>> }
>>
>> tomi_reg_ok returns true if x is any register when strict checking is
>> clear and true if x is one of my addressing registers when strict
>> checking is set.
>>
>> GCC will feed any memory accesses through this function to see if they
>> are directly supported, and if not it will break them up into
>> something smaller and try again.
>>
>> Hope that helps,
>>
>> -- Michael
>>
>>
>> 2010/1/26 Sergio Ruocco :
>>> Gabriel Paubert wrote:
>>>> On Mon, Jan 25, 2010 at 01:34:09PM +0100, Sergio Ruocco wrote:
>>>>> Hi everyone,
>>>>>
>>>>> 

Re: porting GCC to a micro with a very limited addressing mode --- enforcing a 'register indirect memory operand' through a constraint in md

2010-02-10 Thread Sergio Ruocco


Thanks Micheal for your code, I will try it... however, I think the
problem that crashes my compiler may not lie in my LEGITIMATE/LEGITIMIZE
ADDRESS macros, which are equivalent to many others (yours included),
but in the GCC which - in some corner cases - does not like being told
that an register+offset is an invalid address.

While investigating this hypothesis, I found this tutorial

http://spindazzle.org/ggx/

which discusses a GCC port with the same constraints I am battling with,
but solved in a different way.

In this port, the register indirect addressing is enforced through a
custom constraint in the MD (details below).

What do you think of this approach?

Sergio

(from the patch to the MD)

-
;; Constraints
;; -
(define_constraint "W"
  "A register indirect memory operand."
  (and (match_code "mem")
   (match_test "REG_P (XEXP (op, 0))
&& REGNO_OK_FOR_BASE_P (REGNO (XEXP (op, 0)))")))


which is then specified by the define_insn

 (define_insn "*movsi"
   [(set (match_operand:SI 0 "general_operand" "=r,r,W,m,r,r")
(match_operand:SI 1 "ggx_general_movsrc_operand" "r,i,r,r,W,m"))]
   "register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)"
   "@
mov%0, %1
ldi.l  %0, %1
st.l   %0, %1
sta.l  %0, %1
ld.l   %0, %1
lda.l  %0, %1")

http://spindazzle.org/ggx/gcc/add-load-store.patch.txt


The GO_IF_LEGITIMATE_ADDRESS() macro is plain and simple:

/* A C compound statement with a conditional `goto LABEL;' executed
   if X (an RTX) is a legitimate memory address on the target machine
   for a memory operand of mode MODE.  */
#define GO_IF_LEGITIMATE_ADDRESS(MODE,X,LABEL)  \
  do {  \
if (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))   \
  goto LABEL;   \
if (GET_CODE (X) == SYMBOL_REF  \
|| GET_CODE (X) == LABEL_REF\
|| GET_CODE (X) == CONST)   \
  goto LABEL;   \
  } while (0)

http://spindazzle.org/ggx/gcc/add-ggx-config.patch.txt




Michael Hope wrote:
> Hi Sergio.  Here's the interesting parts from my port.  The code's a
> bit funny looking as I've edited it for this post.
> 
> In .h:
> 
> #define BASE_REG_CLASS  ADDR_REGS
> #define INDEX_REG_CLASS NO_REGS
> 
> #ifdef REG_OK_STRICT
> # define _REG_OK_STRICT 1
> #else
> # define _REG_OK_STRICT 0
> #endif
> 
> #define REGNO_OK_FOR_BASE_P(r) _regno_ok_for_base_p(r,
> _REG_OK_STRICT)
> #define REGNO_OK_FOR_INDEX_P(r) 0
> 
> In .c:
> 
> static bool
> _reg_ok(rtx reg, bool strict)
> {
>   int regno = REGNO(reg);
> 
>   bool is_addr = _is_addr_regno(regno);
>   bool ok_strict = is_addr;
>   bool special = regno == ARG_POINTER_REGNUM
> || regno == TREG_S
> ;
> 
>   if (strict)
> {
>   return ok_strict || special;
> }
>   else
> {
>   return ok_strict || special
>   || regno >= FIRST_PSEUDO_REGISTER
>   ;
> }
> }
> 
> bool
> _legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED,
>rtx x,
>bool strict_checking)
> {
>   /* (mem reg) */
>   if (REG_P (x)
>   && _reg_ok (x, strict_checking)
>   )
> {
>   return 1;
> }
> 
>   return 0;
> }
> 
> Note that this ISA only has indirect addressing and has no indirect +
> offset or indirect + register modes.  GCC
> handles this just fine by splitting up any other type that fails
> legitimate_address into smaller components.
> 
> -- Michael
> 
> On 10 February 2010 09:02, Sergio Ruocco  wrote:
>> Michael Hope wrote:
>>> Hi Sergio.  Any luck so far?
>> Micheal, thanks for your inquiry. I made some progress, in fact.
>>
>> I got the GO_IF_LEGITIMATE_ADDRESS() macro to detect correctly REG+IMM
>> addresses, and then the LEGITIMIZE_ADDRESS() macro to force them to be
>> pre-computed in a register.
>>
>> However, now the compiler freaks out with an ICE.. :-/ I put some
>> details below. Thanks for any clue that you or others can give me.
>>
>> Cheers,
>>
>>Sergio
>>
>> ==
>>
>>
>> This is a fragment of my LEGITIMIZE_ADDRESS():
>> -

Re: porting GCC to a micro with a very limited addressing mode --- enforcing a 'register indirect memory operand' through a constraint in md

2010-02-10 Thread Sergio Ruocco

I found the source of my problems!

The prologue()/epilogue() functions (*) I took from the tutorial written
for SPIM/MIPS emit a number of move insn to/from "invalid" memory
addresses (reg+off) that do not go through LEGITIMIZE_ADDRESS(), and
this freaks out GCC, so I have to rewrite these in some ways...

It seems that prologue()/epilogue() are called quite late in the
compiling process, thus new registers cannot be created (no_new_pseudos
assert fires) and/or emit_move_insn() does not go through
LEGITIMIZE_ADDRESS()... will work on this tomorrow...

Thanks for the support so far!

Sergio

(*)
void
spim_prologue(void)
{
int i,j;

emit_move_insn(gen_rtx_MEM(HImode,plus_constant(stack_pointer_rtx,0)),return_addr_rtx);
emit_move_insn(gen_rtx_MEM(HImode,plus_constant(stack_pointer_rtx,-2)),stack_pointer_rtx);
emit_move_insn(gen_rtx_MEM(HImode,plus_constant(stack_pointer_rtx,-4)),hard_frame_pointer_rtx);


...

}



Sergio Ruocco wrote:
> 
> Thanks Micheal for your code, I will try it... however, I think the
> problem that crashes my compiler may not lie in my LEGITIMATE/LEGITIMIZE
> ADDRESS macros, which are equivalent to many others (yours included),
> but in the GCC which - in some corner cases - does not like being told
> that an register+offset is an invalid address.
> 
> While investigating this hypothesis, I found this tutorial
> 
> http://spindazzle.org/ggx/
> 
> which discusses a GCC port with the same constraints I am battling with,
> but solved in a different way.
> 
> In this port, the register indirect addressing is enforced through a
> custom constraint in the MD (details below).
> 
> What do you think of this approach?
> 
>   Sergio
> 
> (from the patch to the MD)
> 
> -
> ;; Constraints
> ;; -
> (define_constraint "W"
>   "A register indirect memory operand."
>   (and (match_code "mem")
>(match_test "REG_P (XEXP (op, 0))
>   && REGNO_OK_FOR_BASE_P (REGNO (XEXP (op, 0)))")))
> 
> 
> which is then specified by the define_insn
> 
>  (define_insn "*movsi"
>[(set (match_operand:SI 0 "general_operand" "=r,r,W,m,r,r")
>   (match_operand:SI 1 "ggx_general_movsrc_operand" "r,i,r,r,W,m"))]
>"register_operand (operands[0], SImode)
> || register_operand (operands[1], SImode)"
>"@
> mov%0, %1
> ldi.l  %0, %1
> st.l   %0, %1
> sta.l  %0, %1
> ld.l   %0, %1
> lda.l  %0, %1")
> 
> http://spindazzle.org/ggx/gcc/add-load-store.patch.txt
> 
> 
> The GO_IF_LEGITIMATE_ADDRESS() macro is plain and simple:
> 
> /* A C compound statement with a conditional `goto LABEL;' executed
>if X (an RTX) is a legitimate memory address on the target machine
>for a memory operand of mode MODE.  */
> #define GO_IF_LEGITIMATE_ADDRESS(MODE,X,LABEL)\
>   do {  \
> if (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X))) \
>   goto LABEL; \
> if (GET_CODE (X) == SYMBOL_REF\
>   || GET_CODE (X) == LABEL_REF\
>   || GET_CODE (X) == CONST)   \
>   goto LABEL; \
>   } while (0)
> 
> http://spindazzle.org/ggx/gcc/add-ggx-config.patch.txt
> 
> 
> 
> 
> Michael Hope wrote:
>> Hi Sergio.  Here's the interesting parts from my port.  The code's a
>> bit funny looking as I've edited it for this post.
>>
>> In .h:
>>
>> #define BASE_REG_CLASS  ADDR_REGS
>> #define INDEX_REG_CLASS NO_REGS
>>
>> #ifdef REG_OK_STRICT
>> # define _REG_OK_STRICT 1
>> #else
>> # define _REG_OK_STRICT 0
>> #endif
>>
>> #define REGNO_OK_FOR_BASE_P(r) _regno_ok_for_base_p(r,
>> _REG_OK_STRICT)
>> #define REGNO_OK_FOR_INDEX_P(r) 0
>>
>> In .c:
>>
>> static bool
>> _reg_ok(rtx reg, bool strict)
>> {
>>   int regno = REGNO(reg);
>>
>>   bool is_addr = _is_addr_regno(regno);
>>   bool ok_strict = is_addr;
>>   bool special = regno == ARG_POINTER_REGNUM
>> || regno == TREG_S
>> ;
>>
>>   if (strict)
>> {
>>   return ok_strict || special;
>> }
>>   else
>> {
>>   return ok_strict || special
>>  || regno >= FIRST_PSEUDO_REGISTER
>>  ;
>>     }
>> }
>>
>&g

Re: GCC porting tutorials

2010-04-24 Thread Sergio Ruocco
Hi Radu,

Check both the GCC Wiki and the work done at IIT Bombay:
http://www.cse.iitb.ac.in/grc/reach.html
Activities->Workshops

They developed some tutorials on porting GCC and writing new backends, such as:
http://www.cse.iitb.ac.in/grc/gcc-workshop-09/
http://www.cse.iitb.ac.in/~uday/gcc-mini-workshop/


On 24 April 2010 10:53, Radu Hobincu  wrote:
> Hello,
>
> My name is Radu Hobincu, I am part of a team at "Politehnica" University
> of Bucharest that is developing a massive parallel computing architecture
> and currently my job is to port the GCC compiler to this new machine.
>
> I've been looking over the GCC official site at http://gcc.gnu.org/ but I
> couldn't find an official porting tutorial. Is there such a thing? And
> maybe a small example for a lightweight architecture?
>
> Regards,
> Radu
>


Trouble with MDs: "const" RTL object stops recognition of RTL expressions by insn patterns

2010-05-25 Thread Sergio Ruocco

Dear All,

I am porting GCC to a 16 bit micro (with 16 bit bytes, thus
BITS_PER_UNIT=16, 16 bit ints become "QI"s etc).

The port compiles is nearly done and simple C programs, but now chokes
on a trivial line such as:

yyy(&array[4], &e, &p);

with this error:

xxx.c: In function ‘yyy’:
xxx.c:193: error: unrecognizable insn:
(insn 183 181 184 4 (set (reg/f:QI 37 [ D.1127 ])
(const:QI (plus:QI (symbol_ref:QI ("digest") [flags 0x2]
)
(const_int 8 [0x8] -1 (nil)
(nil))
sha1_16_struct2.c:193: internal compiler error: in extract_insn, at
recog.c:2020
Please submit a full bug report,
with preprocessed source if appropriate.
See http://gcc.gnu.org/bugs.html> for instructions.

I determined that the problem is triggered by the computation of array
address+const (4/8 in this case).


My MD contains:

(define_insn "addqi3"
[(set (match_operand:QI 0 "register_operand" "=r,r")
  (plus:QI (match_operand:QI 1 "register_operand" "0,0")
   (match_operand:QI 2 "nonmemory_operand" "r,K"))
 )]
""
"@
 ADD  \\t%2 %0
 ADDI \\t%h2 %0"
)

which correctly compiles ordinary arithmetic expressions: x = 5+y etc.

However, when a symbol is involved, the addqi3 isns pattern cannot
recognise the RTL: Symbol+Int.


Is maybe the surrounding  (const:QI...) the reason why addqi3 does not
match?!  Grepping the GCC source I found in rtl.h that CONST is defined as:


/* This is used to encapsulate an expression whose value is constant
(such as the sum of a SYMBOL_REF and a CONST_INT) so that it will be
recognized as a constant operand rather than by arithmetic instructions.  */
DEF_RTL_EXPR(CONST, "const", "e", RTX_CONST_OBJ)


So, what is my port missing to make it compile such RTL expressions?

I feel that it must be something really trivial which I am overlooking..

Thanks for your help,

Sergio