Nicolas Geoffray
2007-Jan-12 12:22 UTC
[LLVMdev] Inserting an assembly instruction in the calling sequence of the powerpc target
Hi all, I'm currently implementing a linux/ppc target in llvm. The abis between Darwin/ppc and linux/ppc are different and I'm running into problems with vararg calls. Before a variadic method is called, an extra instruction must be executed (which is creqv 6, 6, 6). This instruction is not necessary in Darwin/ppc. I looked into the PowerPC target implementation and the code generation uses Dags (lib/Target/PowerPC/PPCISelLowering.cpp, LowerCALL). I need some help on how to insert the creqv instruction in the calling sequence. After this is implemented, I will be able to send a patch for linux/ppc support. I also need to know what is your preference for a linux/ppc target implementation? I can either 1) Use macros (#ifdef __MACH__ for darwin or #ifdef __PPC__ for linux) 2) Test the target in the code when needed if (os == linux && ppc32) then... else if (os == linux && ppc64) then ... else if (os == darwin && ppc32) then ... else if (os == darwin && ppc64) then ... 3) Create a new subtarget (but does it worth it? considering that the difference between the 2 abis is minor) Thx for your help. Cheers, Nicolas
Chris Lattner
2007-Jan-14 19:06 UTC
[LLVMdev] Inserting an assembly instruction in the calling sequence of the powerpc target
On Fri, 12 Jan 2007, Nicolas Geoffray wrote:> I'm currently implementing a linux/ppc target in llvm. The abis betweencool> Darwin/ppc and linux/ppc are different and I'm running into problems > with vararg calls.ok> Before a variadic method is called, an extra instruction must be > executed (which is creqv 6, 6, 6). This instruction is not necessary in > Darwin/ppc. > I looked into the PowerPC target implementation and the code generation uses > Dags (lib/Target/PowerPC/PPCISelLowering.cpp, LowerCALL).right.> I need some help on how to insert the creqv instruction in the calling > sequence.The basic approach you want to take: 1. Introduce a new target-specific dag node to represent "SETCR", which takes a single register operand (in this case, CR6). 2. At call lowering time, flag this into the call sequence. 3. At ISel time, turn this into creq reg,reg,reg> After this is implemented, I will be able to send a patch for linux/ppc > support.Nice. This will also resolve http://llvm.org/PR1064> I also need to know what is your preference for a linux/ppc target > implementation? I can either > 1) Use macros (#ifdef __MACH__ for darwin or #ifdef __PPC__ for linux)This won't work for cross compiles.> 2) Test the target in the code when needed > if (os == linux && ppc32) then... > else if (os == linux && ppc64) then ... > else if (os == darwin && ppc32) then ... > else if (os == darwin && ppc64) then ...This is inefficient :)> 3) Create a new subtarget (but does it worth it? considering that the > difference between the 2 abis is minor)There is already a subtarget. In the call lowering code, just do something like: if (!PPCSubTarget->isDarwin()) ... insert creq here ... -Chris -- http://nondot.org/sabre/ http://llvm.org/
Nicolas Geoffray
2007-Jan-16 16:37 UTC
[LLVMdev] Inserting an assembly instruction in the calling sequence of the powerpc target
Hi Crhis, Chris Lattner wrote:> The basic approach you want to take: > 1. Introduce a new target-specific dag node to represent "SETCR", which > takes a single register operand (in this case, CR6). >That I did. I introduced the creqv instruction in PPCInstrInfo.td and inserted a SETCR in the PPCISD::NodeType enum, file PPCSelLowering.h.> 2. At call lowering time, flag this into the call sequence. >I'm still confused on how flags operate into the call sequence. I tried to do : if (isVarArg) { InFlag = DAG.getNode(PPCISD::SETCR, MVT::i32, DAG.getRegister(PPC::CR6, MVT::i32)); } in PPCISelLowering.cpp after the copy-to-reg sequence (line 1462 in llvm-cvs), but it does not work (I always get wrong assertions)> 3. At ISel time, turn this into creq reg,reg,reg > >If I understand correctly, all I have to do for this is to add in PPCISelDagToDag.cpp::Select a switch case where: case PPCISD::SETCR : { SDOperand InFlag = N->getOperand(0); return CurDAG->getTargetNode(PPC::CREQV, MVT::i32, InFlag, InFlag); }>> 2) Test the target in the code when needed >> if (os == linux && ppc32) then... >> else if (os == linux && ppc64) then ... >> else if (os == darwin && ppc32) then ... >> else if (os == darwin && ppc64) then ... >> > > This is inefficient :) > > > There is already a subtarget. In the call lowering code, just do > something like: > > if (!PPCSubTarget->isDarwin()) > ... insert creq here ... > >OK, that's what I meant with my second proposition.> -Chris > >Thx, Nicolas