Dr. ERDI Gergo via llvm-dev
2017-May-28 06:27 UTC
[llvm-dev] Pseudo-instruction that overwrites its input register
Hi, I'd like to define a pseudo-instruction whose expansion will, as a side-effect, overwrite an input register's value: the pseudo-instruction ldw r1:r2, P to load 2 bytes from memory address P is to be expaneded to ld r1, P+ ld r2, P where "ld _, P+" is an instruction that loads a single byte from P, and post-increments P by one. How can I represent this behaviour in LLVM? Currently, I have let Constraints = "@earlyclobber $reg" in def LDWRdPtr : Pseudo<(outs DREGS:$reg), (ins PTRREGS:$ptrreg), "ldw\t$reg, $ptrreg", [(set i16:$reg, (load i16:$ptrreg))]>, Requires<[HasSRAM]>; The problem, of course, is that with this definition I end up with code which assumes it is equivalent to save P before 'ldw r1:r2,P' or after. I tried adding "@earlyclobber $ptrreg" as a Constraint, but that just leads to an assertion failure during codegen (I assume because @earlyclobber is for output ports) void llvm::MachineOperand::setIsEarlyClobber(bool): Assertion `isReg() && IsDef && "Wrong MachineOperand accessor"' failed. Thanks, Gergo
David Chisnall via llvm-dev
2017-May-28 07:07 UTC
[llvm-dev] Pseudo-instruction that overwrites its input register
On 28 May 2017, at 07:27, Dr. ERDI Gergo via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > Hi, > > I'd like to define a pseudo-instruction whose expansion will, as a side-effect, overwrite an input register's value: the pseudo-instruction > > ldw r1:r2, P > > to load 2 bytes from memory address P is to be expaneded to > > ld r1, P+ > ld r2, P > > where "ld _, P+" is an instruction that loads a single byte from P, and post-increments P by one. > > How can I represent this behaviour in LLVM? Currently, I have > > let Constraints = "@earlyclobber $reg" in > def LDWRdPtr : Pseudo<(outs DREGS:$reg), > (ins PTRREGS:$ptrreg), > "ldw\t$reg, $ptrreg", > [(set i16:$reg, (load i16:$ptrreg))]>, > Requires<[HasSRAM]>; > > The problem, of course, is that with this definition I end up with code which assumes it is equivalent to save P before 'ldw r1:r2,P' or after. I tried adding "@earlyclobber $ptrreg" as a Constraint, but that just leads to an assertion failure during codegen (I assume because @earlyclobber is for output ports)You need to express the P as both an input and output operand and add a constraint that both must be the same register. David
Dr. ERDI Gergo via llvm-dev
2017-May-28 10:04 UTC
[llvm-dev] Pseudo-instruction that overwrites its input register
On Sun, 28 May 2017, David Chisnall wrote:>> let Constraints = "@earlyclobber $reg" in >> def LDWRdPtr : Pseudo<(outs DREGS:$reg), >> (ins PTRREGS:$ptrreg), >> "ldw\t$reg, $ptrreg", >> [(set i16:$reg, (load i16:$ptrreg))]>, >> Requires<[HasSRAM]>; >> >> The problem, of course, is that with this definition I end up with code which assumes it is equivalent to save P before 'ldw r1:r2,P' or after. I tried adding "@earlyclobber $ptrreg" as a Constraint, but that just leads to an assertion failure during codegen (I assume because @earlyclobber is for output ports) > > You need to express the P as both an input and output operand and add a constraint that both must be the same register.OK, but then the pattern will have to include that extra output operand somehow, right? What would the pattern need to be so that during ISel, this LDWRdPtr instruction with the extra output still matches?