Hi, In the PPC backend, there is a "helper" class used to define instructions that implicitly define a condition register: class isDOT { list<Register> Defs = [CR0]; bit RC = 1; } and this gets used on instructions such as: def ADDICo : DForm_2<13, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), "addic. $rD, $rA, $imm", IntGeneral, []>, isDOT; but there is a small problem. If these instructions are also part of a larger block which also defines registers, like this: let Defs = [CARRY] in def ADDICo : DForm_2<13, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), "addic. $rD, $rA, $imm", IntGeneral, []>, isDOT; then the fact that isDOT puts CR0 into Defs is lost (only CARRY ends up in the list of implicitly-defined registers). How can I modify things to make them work correctly? Thanks again, Hal -- Hal Finkel Postdoctoral Appointee Leadership Computing Facility Argonne National Laboratory
On Apr 12, 2013, at 2:06 AM, Hal Finkel <hfinkel at anl.gov> wrote:> In the PPC backend, there is a "helper" class used to define instructions that implicitly define a condition register: > > class isDOT { > list<Register> Defs = [CR0]; > bit RC = 1; > } > > and this gets used on instructions such as: > > def ADDICo : DForm_2<13, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), > "addic. $rD, $rA, $imm", IntGeneral, > []>, isDOT; > > but there is a small problem. If these instructions are also part of a larger block which also defines registers, like this: > > let Defs = [CARRY] in > def ADDICo : DForm_2<13, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), > "addic. $rD, $rA, $imm", IntGeneral, > []>, isDOT; > > then the fact that isDOT puts CR0 into Defs is lost (only CARRY ends up in the list of implicitly-defined registers). How can I modify things to make them work correctly?let Defs = [CARRY, CR0] in… I think it can already be tricky to figure out where TableGen instruction definitions get all their properties. If we add syntax that allows them to come from multiple places at once, it becomes even harder to figure out. For readability, just combine them explicitly. You may also want to look at ARM's use of optional defs for instructions that can optionally set the flags. /jakob
----- Original Message -----> From: "Jakob Stoklund Olesen" <stoklund at 2pi.dk> > To: "Hal Finkel" <hfinkel at anl.gov> > Cc: "LLVM Developers Mailing List" <llvmdev at cs.uiuc.edu> > Sent: Friday, April 12, 2013 11:36:49 AM > Subject: Re: [LLVMdev] TableGen list merging > > > On Apr 12, 2013, at 2:06 AM, Hal Finkel <hfinkel at anl.gov> wrote: > > > In the PPC backend, there is a "helper" class used to define > > instructions that implicitly define a condition register: > > > > class isDOT { > > list<Register> Defs = [CR0]; > > bit RC = 1; > > } > > > > and this gets used on instructions such as: > > > > def ADDICo : DForm_2<13, (outs GPRC:$rD), (ins GPRC:$rA, > > s16imm:$imm), > > "addic. $rD, $rA, $imm", IntGeneral, > > []>, isDOT; > > > > but there is a small problem. If these instructions are also part > > of a larger block which also defines registers, like this: > > > > let Defs = [CARRY] in > > def ADDICo : DForm_2<13, (outs GPRC:$rD), (ins GPRC:$rA, > > s16imm:$imm), > > "addic. $rD, $rA, $imm", IntGeneral, > > []>, isDOT; > > > > then the fact that isDOT puts CR0 into Defs is lost (only CARRY > > ends up in the list of implicitly-defined registers). How can I > > modify things to make them work correctly? > > let Defs = [CARRY, CR0] in… > > I think it can already be tricky to figure out where TableGen > instruction definitions get all their properties. If we add syntax > that allows them to come from multiple places at once, it becomes > even harder to figure out. > > For readability, just combine them explicitly.Okay, will do.> > You may also want to look at ARM's use of optional defs for > instructions that can optionally set the flags.As far as I can tell, this makes it the job of the C++ code to add the implicit register definition (as is done at the end of ARMBaseInstrInfo::optimizeCompareInstr). Is that right? Thanks again, Hal> > /jakob > >