Help math RTL patterns...
Hi All, I am porting gcc for an internal processor and I am having some issues with math instructions. Our processor uses two operands for math instructions which are usually of the form OP0 = OP0 + OP1. The RTL pattern (for addm3) in gcc uses the form OP0 = OP1 + OP2. I understand that gcc supposedly supports the two operand flavor, but I have not been able to convince it to do that for me. I tried the following RTL pattern with no success: (define_insn "addhi3_op1_is_op0" [(set (match_operand:HI 0 "register_operand""=a") (plus:HI (match_dup 0) (match_operand:HI 1 "general_operand" "aim")))] "" { output_asm_insn("//Start of addhi3_op1_is_op0 %0 = %1 + %2", operands); output_asm_insn("//End of addhi3_op1_is_op0", operands); return(""); } ) So I used the three operand form and fixed things up in the code: (define_insn "addhi3_regtarget" [(set (match_operand:HI 0 "register_operand""=a") (plus:HI (match_operand:HI 1 "general_operand" "aim") (match_operand:HI 2 "general_operand" "aim")))] "" { output_asm_insn("//Start of addhi3_regtarget %0 = %1 + %2", operands); snap_do_basic_math_op_hi(operands, MATH_OP_PLUS); output_asm_insn("//End of addhi3_regtarget", operands); return(""); } ) Of course this does not work for all cases since my fixup cannot detect if the operands are the same memory location for OP0 and either OP1 or OP2. So I am back to trying to find the right RTL magic to do this right. I have looked over a number of machine descriptions but have not been able to find the precise pattern for this. Any help is greatly appreciated. Steve Silva (Broadcom)
Re: Help math RTL patterns...
Hi Nathan, Thanks for your advice. I retooled the addhi3 sequence to look like this: (define_expand "addhi3" [(set (match_operand:HI 0 "snap_mem_or_reg""+a,m") (plus:HI (match_operand:HI 1 "snap_mem_or_reg" "%0,0") (match_operand:HI 2 "general_operand" "aim,aim")))] "" "" ) (define_insn "addhi3_regtarget" [(set (match_operand:HI 0 "register_operand" "+a") (plus:HI (match_operand:HI 1 "register_operand" "%0") (match_operand:HI 2 "general_operand" "aim")))] "" { output_asm_insn("//Start of addhi3_regtarget %0 = %1 + %2", operands); snap_do_basic_math_op_hi(operands, MATH_OP_PLUS); output_asm_insn("//End of addhi3_regtarget", operands); return(""); } ) (define_insn "addhi3_memtarget" [(set (match_operand:HI 0 "memory_operand""+m") (plus:HI (match_operand:HI 1 "memory_operand" "%0") (match_operand:HI 2 "general_operand" "aim")))] "" { output_asm_insn("//Start of addhi3_memtarget %0 = %1 + %2", operands); snap_do_basic_math_op_hi(operands, MATH_OP_PLUS); output_asm_insn("//End of addhi3_memtarget", operands); return(""); } ) I compile a simple program with this: void addit() { int a, b, c; a = -10; b = 2; c = a + b; } And the compiler fails out with the following message: addit.c: In function 'addit': addit.c:12:1: internal compiler error: in find_reloads, at reload.c:4085 } ^ 0x8f5953 find_reloads(rtx_insn*, int, int, int, short*) ../../gcc-6.2.0/gcc/reload.c:4085 0x90327b calculate_needs_all_insns ../../gcc-6.2.0/gcc/reload1.c:1484 0x90327b reload(rtx_insn*, int) ../../gcc-6.2.0/gcc/reload1.c:995 0x7e8f11 do_reload ../../gcc-6.2.0/gcc/ira.c:5437 0x7e8f11 execute ../../gcc-6.2.0/gcc/ira.c:5609 It would seem that the constraints are somehow not right, but I am not familiar with the particular way the compiler does this step. Any insights or pointers? Thanks, Steve S On Tuesday, January 17, 2017 12:45 PM, Nathan Sidwell wrote: On 01/17/2017 12:19 PM, Steve Silva via gcc wrote: > Hi All, > > > I am porting gcc for an internal processor and I am having some issues with > math instructions. Our processor uses two operands for math instructions > which are usually of the form OP0 = OP0 + OP1. The RTL pattern (for addm3) > in gcc uses the form OP0 = OP1 + OP2. I understand that gcc supposedly > supports the two operand flavor, but I have not been able to convince it to > do that for me. I tried the following RTL pattern with no success: > So I used the three operand form and fixed things up in the code: That's nearly right. Use register constraints with the 3 op pattern: (define_insn "addhi3" [(set (match_operand:HI 0 "register_operand" "+a") (plus:HI (match_operand:HI 1 "register_operand" "0") (match_operand:HI 2 "general_operand" "aim")))] The sh port may be instructive, IIRC it has a bunch of 2-op insns. nathan -- Nathan Sidwell
Re: Help math RTL patterns...
Hi All, I just wanted to thank you for your help; I was able to fix the problem with the following RTL (define_expand "addhi3" [(set (match_operand:HI 0 "nonimmediate_operand") (plus:HI (match_operand:HI 1 "nonimmediate_operand") (match_operand:HI 2 "general_operand")))] "" { if((GET_CODE(operands[2]) == CONST_INT) && ((INTVAL(operands[2]) > 4095) || (INTVAL(operands[2]) < -2048))) { emit_insn(gen_addhi3_mem_or_reg(operands[0], operands[1], force_reg(HImode, operands[2]))); DONE; } }) ;;* ;;** This pattern is for any register or memory target. This pattern cannot** ;;** accept immediate values over 12 bits hence the expand above. ** ;;* (define_insn "addhi3_mem_or_reg" [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m") (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") (match_operand:HI 2 "general_operand" "aim,aim")))] "" { output_asm_insn("//Start of addhi3_mem_or_reg %0 = %1 + %2", operands); snap_do_basic_math_op_hi(operands, MATH_OP_PLUS); output_asm_insn("//End of addhi3_mem_or_reg", operands); return(""); } ) Nathan and Johann if you are even in Fort Collins, CO I will buy you a beer. :) Steve On Wednesday, January 18, 2017 8:47 AM, Georg-Johann Lay wrote: On 17.01.2017 21:41, Steve Silva via gcc wrote: > Hi Nathan, > > Thanks for your advice. I retooled the addhi3 sequence to look like this: > > (define_expand "addhi3" > [(set (match_operand:HI 0 "snap_mem_or_reg""+a,m") > (plus:HI (match_operand:HI 1 "snap_mem_or_reg" "%0,0") > (match_operand:HI 2 "general_operand" "aim,aim")))] Expanders don't take constraints; you should get a warning here. > "" > "" > ) You can omit trailing elements if they are empty: (define_expand "addhi3" [(set (match_operand:HI 0 "snap_mem_or_reg") (plus:HI (match_operand:HI 1 "snap_mem_or_reg") (match_operand:HI 2 "general_operand")))]) If you are allowing MEM here the generated insn might come with a memory operand. Disallowing it in the insn predicate might lead to "unrecognizable insn" ICE, e.g. if op 1 is a MEM and op 0 is a REG. > (define_insn "addhi3_regtarget" > [(set (match_operand:HI 0 "register_operand" "+a") operands[0] is not an input here, it's only an output. Hence "=a" is the right constraint, not "+a". > (plus:HI (match_operand:HI 1 "register_operand" "%0") > (match_operand:HI 2 "general_operand" "aim")))] > "" > { > output_asm_insn("//Start of addhi3_regtarget %0 = %1 + %2", operands); > snap_do_basic_math_op_hi(operands, MATH_OP_PLUS); > output_asm_insn("//End of addhi3_regtarget", operands); > return(""); > } > ) > > > (define_insn "addhi3_memtarget" > [(set (match_operand:HI 0 "memory_operand""+m") > (plus:HI (match_operand:HI 1 "memory_operand" "%0") > (match_operand:HI 2 "general_operand" "aim")))] You might consider one insn with several alternatives like: (define_insn "*addhi3_insn" [(set (match_operand:HI 0 "nonimmediate_operand" "=a ,m") (plus:HI (match_operand:HI 1 "register_operand" "%0 ,0") (match_operand:HI 2 "general_operand" "aim,aim")))] "" { // Output depending on which_alternative. return ""; }) Johann > "" > { > output_asm_insn("//Start of addhi3_memtarget %0 = %1 + %2", operands); > snap_do_basic_math_op_hi(operands, MATH_OP_PLUS); > output_asm_insn("//End of addhi3_memtarget", operands); > return(""); > } > ) > > I compile a simple program with this: > > void addit() > { > int a, b, c; > > a = -10; > b = 2; > c = a + b; > } > > > And the compiler fails out with the following message: > > addit.c: In function 'addit': > addit.c:12:1: internal compiler error: in find_reloads, at reload.c:4085 > } > ^ > 0x8f5953 find_reloads(rtx_insn*, int, int, int, short*) > ../../gcc-6.2.0/gcc/reload.c:4085 > 0x90327b calculate_needs_all_insns > ../../gcc-6.2.0/gcc/reload1.c:1484 > 0x90327b reload(rtx_insn*, int) > ../../gcc-6.2.0/gcc/reload1.c:995 > 0x7e8f11 do_reload > ../../gcc-6.2.0/gcc/ira.c:5437 > 0x7e8f11 execute > ../../gcc-6.2.0/gcc/ira.c:5609 > > It would seem that the constraints are somehow not right, but I am not > familiar with the particular way the compiler does this step. Any insights > or pointers? > > > Thanks, > > Steve S [snipped TOFU]
GCC function calling: Parameter passing on stack...
Hi All, I am doing a port of GCC for a small internal processor and I have a question about function parameter passing. I am allocating space for function parameters on the frame (via crtl->outgoing_args_size) and want gcc to use this space via frame pointer manipulation, not stack pointer manipulation. So far, I cannot get gcc to use the frame pointer for the args, it manipulates the stack pointer directly (this is a problem since the stack pointer is not directly accessible). I have the following configurations set: #define ACCUMULATE_OUTGOING_ARGS (1) #define REG_PARM_STACK_SPACE(x) (0) //NOT USED #define INCOMING_REG_PARM_STACK_SPACE #define OUTGOING_REG_PARM_STACK_SPACE(x) (1) #define STACK_PARMS_IN_REG_PARM_AREA (1) but these do not seem to help. The compiler uses the frame pointer correctly for all the local variables, so I know it is aware of it. Any suggestions are appreciated. Steve (Broadcom)