Re: divmod pattern question

2018-06-20 Thread Paul Koning



> On Jun 20, 2018, at 1:16 AM, Jeff Law  wrote:
> 
> On 06/19/2018 12:55 PM, Paul Koning wrote:
>> Gentlepeople,
>> 
>> I have a two-operand divide instruction that takes a double length dividend 
>> in a register pair, and produces the quotient in the first register and 
>> remainder in the second.
>> 
>> How do I write a divmod pattern for that?  The quotient is easy enough, I 
>> write a match_operand for that register and a matching constraint ("0") for 
>> the input dividend.  But what about the remainder?  The remainder appears in 
>> a register that isn't explicitly mentioned in the RTL (it's the regnum one 
>> higher than the quotient, or if you like, the second subreg of the input 
>> (dividend) register.
> You can generally allocate double-sized registers with appropriate
> constraints and the like.  And you could use matching constraints,
> perhaps with subregs, but in the end, ew.
> 
>> 
>> I can make it a define_expand that adds a move from the remainder register 
>> into a new register which is the output operand, and count on the optimizer 
>> to optimize away that move.  Is that the best answer?  The current "mod" 
>> pattern does that, and I could keep that approach.
> But this would generally be better I think.  I'd expect the move to be
> optimized away the vast majority of the time.

Thanks.  I looked at some others, like M68k, the difference there is that the 
mod result goes to an explicitly named register in the machine instruction.

Here's what I ended up with; it seems to work even though it doesn't match 
precisely what the documentation seems to call for.

(define_expand "divmodhi4"
  [(parallel
[(set (subreg:HI (match_dup 1) 0)
(div:HI (match_operand:SI 1 "register_operand" "0")
(match_operand:HI 2 "general_operand" "g")))
 (set (subreg:HI (match_dup 1) 2)
(mod:HI (match_dup 1) (match_dup 2)))])
   (set (match_operand:HI 0 "register_operand" "=r")
(subreg:HI (match_dup 1) 0))
   (set (match_operand:HI 3 "register_operand" "=r")
(subreg:HI (match_dup 1) 2))]
  "TARGET_40_PLUS"
  "")

; and then the actual final instruction:
(define_insn "divmodhi4_nocc"
  [(set (subreg:HI (match_operand:SI 0 "register_operand" "=r,r") 0)
(div:HI (match_operand:SI 1 "register_operand" "0,0")
 (match_operand:HI 2 "general_operand" "rR,Qi")))
   (set (subreg:HI (match_dup 1) 2)
(mod:HI (match_dup 1) (match_dup 2)))
   (clobber (reg:CC CC_REGNUM))]
  "TARGET_40_PLUS"
   "div %2,%0"
  [(set_attr "length" "2,4")])

paul



Re: divmod pattern question

2018-06-20 Thread Andreas Schwab
On Jun 19 2018, Paul Koning  wrote:

> I have a two-operand divide instruction that takes a double length dividend 
> in a register pair, and produces the quotient in the first register and 
> remainder in the second.

That's looks like the m68k div insn.

Andreas.

-- 
Andreas Schwab, SUSE Labs, sch...@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."


Re: divmod pattern question

2018-06-19 Thread Jeff Law
On 06/19/2018 12:55 PM, Paul Koning wrote:
> Gentlepeople,
> 
> I have a two-operand divide instruction that takes a double length dividend 
> in a register pair, and produces the quotient in the first register and 
> remainder in the second.
> 
> How do I write a divmod pattern for that?  The quotient is easy enough, I 
> write a match_operand for that register and a matching constraint ("0") for 
> the input dividend.  But what about the remainder?  The remainder appears in 
> a register that isn't explicitly mentioned in the RTL (it's the regnum one 
> higher than the quotient, or if you like, the second subreg of the input 
> (dividend) register.
You can generally allocate double-sized registers with appropriate
constraints and the like.  And you could use matching constraints,
perhaps with subregs, but in the end, ew.

> 
> I can make it a define_expand that adds a move from the remainder register 
> into a new register which is the output operand, and count on the optimizer 
> to optimize away that move.  Is that the best answer?  The current "mod" 
> pattern does that, and I could keep that approach.
But this would generally be better I think.  I'd expect the move to be
optimized away the vast majority of the time.

jeff


divmod pattern question

2018-06-19 Thread Paul Koning
Gentlepeople,

I have a two-operand divide instruction that takes a double length dividend in 
a register pair, and produces the quotient in the first register and remainder 
in the second.

How do I write a divmod pattern for that?  The quotient is easy enough, I write 
a match_operand for that register and a matching constraint ("0") for the input 
dividend.  But what about the remainder?  The remainder appears in a register 
that isn't explicitly mentioned in the RTL (it's the regnum one higher than the 
quotient, or if you like, the second subreg of the input (dividend) register.

I can make it a define_expand that adds a move from the remainder register into 
a new register which is the output operand, and count on the optimizer to 
optimize away that move.  Is that the best answer?  The current "mod" pattern 
does that, and I could keep that approach.

paul