public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* divmod pattern question
@ 2018-06-20  5:16 Paul Koning
  2018-06-20  5:31 ` Jeff Law
  2018-06-20  8:24 ` Andreas Schwab
  0 siblings, 2 replies; 4+ messages in thread
From: Paul Koning @ 2018-06-20  5:16 UTC (permalink / raw)
  To: GCC Development

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: divmod pattern question
  2018-06-20  5:16 divmod pattern question Paul Koning
@ 2018-06-20  5:31 ` Jeff Law
  2018-06-20 13:05   ` Paul Koning
  2018-06-20  8:24 ` Andreas Schwab
  1 sibling, 1 reply; 4+ messages in thread
From: Jeff Law @ 2018-06-20  5:31 UTC (permalink / raw)
  To: Paul Koning, GCC Development

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, ewwwww.

> 
> 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

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: divmod pattern question
  2018-06-20  5:16 divmod pattern question Paul Koning
  2018-06-20  5:31 ` Jeff Law
@ 2018-06-20  8:24 ` Andreas Schwab
  1 sibling, 0 replies; 4+ messages in thread
From: Andreas Schwab @ 2018-06-20  8:24 UTC (permalink / raw)
  To: Paul Koning; +Cc: GCC Development

On Jun 19 2018, Paul Koning <paulkoning@comcast.net> 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, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: divmod pattern question
  2018-06-20  5:31 ` Jeff Law
@ 2018-06-20 13:05   ` Paul Koning
  0 siblings, 0 replies; 4+ messages in thread
From: Paul Koning @ 2018-06-20 13:05 UTC (permalink / raw)
  To: Jeff Law, Andreas Schwab; +Cc: GCC Development



> On Jun 20, 2018, at 1:16 AM, Jeff Law <law@redhat.com> 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, ewwwww.
> 
>> 
>> 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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-06-20 12:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-20  5:16 divmod pattern question Paul Koning
2018-06-20  5:31 ` Jeff Law
2018-06-20 13:05   ` Paul Koning
2018-06-20  8:24 ` Andreas Schwab

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).