This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: move patterns, emit_move_insn
> Meena, could you please give me advice about how to set up eliminating
> FP against SP ? In my target.h, these macros are NOT defined :
> ELIMINABLE_REGS
> CAN_ELIMINATE
> INITIAL_ELIMINATION_OFFSET
Before these macro definitions, please ensure that following registers should be defined:
#define STACK_POINTER_REGNUM
#define FRAME_POINTER_REGNUM
#define ARG_POINTER_REGNUM
Note:
If the target architecture does not supports frame pointer and argument pointer then you need to define fake registers.
> ELIMINABLE_REGS
> CAN_ELIMINATE
> INITIAL_ELIMINATION_OFFSET
You can check with the following macro definitions:
#define ELIMINABLE_REGS \
{{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM} \
}
#define CAN_ELIMINATE(FROM, TO) \
( (FROM == FRAME_POINTER_REGNUM && TO == STACK_POINTER_REGNUM ) \
|| (FROM == ARG_POINTER_REGNUM && TO == STACK_POINTER_REGNUM) \
)
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, VAR) \
(VAR) = initial_elimination_offset(FROM, TO)
Note:
Function initial_elimination_offset(FROM, TO) should be defined in target.c file.
int initial_elimination_offset(int from, int to)
{
HOST_WIDE_INT elimination_offset = 0;
HOST_WIDE_INT size_of_variables_in_stack = 0;
if(from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
{
elimination_offset = 0;
}
else if ((from == ARG_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
{
size_of_variables_in_stack = get_frame_size();
elimination_offset = size_of_variables_in_stack +
current_function_outgoing_args_size ;
}
else
{
gcc_unreachable ();
}
return elimination_offset;
}
Note:
Function definition you can modify later as per your requirement.
On Tue, 2009-03-03 at 14:35 +0100, Florent DEFAY wrote:
> Thank you very much for your attention.
>
> Meena, could you please give me advice about how to set up eliminating
> FP against SP ? In my target.h, these macros are NOT defined :
> ELIMINABLE_REGS
> CAN_ELIMINATE
> INITIAL_ELIMINATION_OFFSET
>
> I changed target.md :
> ________________________________________
> ;; movhi
> (define_expand "movhi"
> [(set (match_operand:HI 0 "nonimmediate_operand" "")
> (match_operand:HI 1 "general_operand" "")
> )]
> ""
> {
> /* First try */
> /*
> if (GET_CODE (operands[0]) == MEM
> && GET_CODE (operands[1]) != REG)
> {
> operands[1] = force_reg (HImode, operands[1]);
> }
> */
> /* Second try */
> if (!register_operand(operand0, HImode)
> && !register_operand(operand1, HImode))
> {
> operands[1] = copy_to_mode_reg(HImode, operand1);
> }
> }
> )
>
> ;; move.w r -> (r)
> (define_insn "movhi1"
> [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m,r,r")
> (match_operand:HI 1 "general_operand" "r,r,m,i")
> )]
> ""
> "@
> move.w\t%1,%0
> move.w\t%1,%0
> move.w\t%1,%0
> move.w\t%1,%0"
> )
> ______________________________
>
> First and second try (as commented in the code) are successful to
> force copying immediate into register and then register into memory.
> But then, with both of them, this error appears:
>
> e.c:7: error: unrecognizable insn:
> (insn 8 7 9 3 e.c:4 (set (mem/c/i:HI (reg/f:HI 14) [0 i+0 S2 A16])
> (reg:HI 15)) -1 (nil))
>
> I don't know why. Since the pattern movhi1 allows register to memory transfer.
>
> I still wonder how I can deal with access modes ?
> For example, to obtain such an ASM instruction
> ______________
> movew r1,8(r2) ;; move R1 to [R2 + 8]
> ______________
> How to do that ? How to check the access mode ? Where to catch the 8
> (in the example) ?
>
> Regards.
>
> Florent