This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC 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]

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


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]);
		}
          }
        }
)

;;Load patterns

(define_insn "*load_word"
        [(set (match_operand:HI 0 "register_operand" "=r")
              (mem:HI (match_operand:HI 1 "address_operand" "p")))]
        ""
        "lw \\t%0, %a1"
)

;;Store patterns

(define_insn "*store_word"
        [(set (mem:HI (match_operand:HI 0 "address_operand" "p"))
              (match_operand:HI 1 "register_operand" "r"))]
        ""
        "sw \\t%1, %a0"
)
-------------------------------





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