Help math RTL patterns...

2017-01-17 Thread Steve Silva via gcc
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...

2017-01-17 Thread Steve Silva via gcc
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...

2017-01-18 Thread Steve Silva via gcc
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...

2017-01-23 Thread Steve Silva via gcc
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)