Re: divmod pattern question
> 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
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
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
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