Changes in directory llvm/lib/Target/X86:
X86ISelLowering.cpp updated: 1.26 -> 1.27 X86ISelLowering.h updated: 1.12 -> 1.13 X86InstrInfo.td updated: 1.194 -> 1.195 --- Log message: SSE cmov support. --- Diffs of the changes: (+121 -17) X86ISelLowering.cpp | 109 ++++++++++++++++++++++++++++++++++++++++++++-------- X86ISelLowering.h | 3 + X86InstrInfo.td | 26 +++++++++++- 3 files changed, 121 insertions(+), 17 deletions(-) Index: llvm/lib/Target/X86/X86ISelLowering.cpp diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.26 llvm/lib/Target/X86/X86ISelLowering.cpp:1.27 --- llvm/lib/Target/X86/X86ISelLowering.cpp:1.26 Tue Jan 10 14:26:56 2006 +++ llvm/lib/Target/X86/X86ISelLowering.cpp Tue Jan 10 18:33:36 2006 @@ -17,8 +17,9 @@ #include "X86TargetMachine.h" #include "llvm/CallingConv.h" #include "llvm/Function.h" -#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/TargetOptions.h" @@ -1140,14 +1141,34 @@ return std::make_pair(Result, Chain); } -//===----------------------------------------------------------------------===// -// X86 Custom Lowering Hooks -//===----------------------------------------------------------------------===// +/// getCondBrOpcodeForX86CC - Returns the X86 conditional branch opcode +/// which corresponds to the condition code. +static unsigned getCondBrOpcodeForX86CC(unsigned X86CC) { + switch (X86CC) { + default: assert(0 && "Unknown X86 conditional code!"); + case X86ISD::COND_A: return X86::JA; + case X86ISD::COND_AE: return X86::JAE; + case X86ISD::COND_B: return X86::JB; + case X86ISD::COND_BE: return X86::JBE; + case X86ISD::COND_E: return X86::JE; + case X86ISD::COND_G: return X86::JG; + case X86ISD::COND_GE: return X86::JGE; + case X86ISD::COND_L: return X86::JL; + case X86ISD::COND_LE: return X86::JLE; + case X86ISD::COND_NE: return X86::JNE; + case X86ISD::COND_NO: return X86::JNO; + case X86ISD::COND_NP: return X86::JNP; + case X86ISD::COND_NS: return X86::JNS; + case X86ISD::COND_O: return X86::JO; + case X86ISD::COND_P: return X86::JP; + case X86ISD::COND_S: return X86::JS; + } +} -/// SetCCToX86CondCode - do a one to one translation of a ISD::CondCode to -/// X86 specific CondCode. It returns a X86ISD::COND_INVALID if it cannot +/// getX86CC - do a one to one translation of a ISD::CondCode to the X86 +/// specific condition code. It returns a X86ISD::COND_INVALID if it cannot /// do a direct translation. -static unsigned CCToX86CondCode(SDOperand CC, bool isFP) { +static unsigned getX86CC(SDOperand CC, bool isFP) { ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get(); unsigned X86CC = X86ISD::COND_INVALID; if (!isFP) { @@ -1192,11 +1213,10 @@ return X86CC; } -/// SupportedByFPCMOV - is there a floating point cmov for the specific -/// X86 condition code. -/// Current x86 isa includes the following FP cmov instructions: +/// hasFPCMov - is there a floating point cmov for the specific X86 condition +/// code. Current x86 isa includes the following FP cmov instructions: /// fcmovb, fcomvbe, fcomve, fcmovu, fcmovae, fcmova, fcmovne, fcmovnu. -static bool SupportedByFPCMOV(unsigned X86CC) { +static bool hasFPCMov(unsigned X86CC) { switch (X86CC) { default: return false; @@ -1212,6 +1232,64 @@ } } +MachineBasicBlock * +X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, + MachineBasicBlock *BB) { + assert((MI->getOpcode() == X86::CMOV_FR32 || + MI->getOpcode() == X86::CMOV_FR64) && + "Unexpected instr type to insert"); + + // To "insert" a SELECT_CC instruction, we actually have to insert the diamond + // control-flow pattern. The incoming instruction knows the destination vreg + // to set, the condition code register to branch on, the true/false values to + // select between, and a branch opcode to use. + const BasicBlock *LLVM_BB = BB->getBasicBlock(); + ilist<MachineBasicBlock>::iterator It = BB; + ++It; + + // thisMBB: + // ... + // TrueVal = ... + // cmpTY ccX, r1, r2 + // bCC copy1MBB + // fallthrough --> copy0MBB + MachineBasicBlock *thisMBB = BB; + MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); + MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); + unsigned Opc = getCondBrOpcodeForX86CC(MI->getOperand(3).getImmedValue()); + BuildMI(BB, Opc, 1).addMBB(sinkMBB); + MachineFunction *F = BB->getParent(); + F->getBasicBlockList().insert(It, copy0MBB); + F->getBasicBlockList().insert(It, sinkMBB); + // Update machine-CFG edges + BB->addSuccessor(copy0MBB); + BB->addSuccessor(sinkMBB); + + // copy0MBB: + // %FalseValue = ... + // # fallthrough to sinkMBB + BB = copy0MBB; + + // Update machine-CFG edges + BB->addSuccessor(sinkMBB); + + // sinkMBB: + // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] + // ... + BB = sinkMBB; + BuildMI(BB, X86::PHI, 4, MI->getOperand(0).getReg()) + .addReg(MI->getOperand(1).getReg()).addMBB(copy0MBB) + .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB); + + delete MI; // The pseudo instruction is gone now. + return BB; +} + + +//===----------------------------------------------------------------------===// +// X86 Custom Lowering Hooks +//===----------------------------------------------------------------------===// + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -1383,7 +1461,7 @@ Op.getOperand(0), Op.getOperand(1)); ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get(); bool isFP = MVT::isFloatingPoint(Op.getOperand(1).getValueType()); - unsigned X86CC = CCToX86CondCode(CC, isFP); + unsigned X86CC = getX86CC(CC, isFP); if (X86CC != X86ISD::COND_INVALID) { return DAG.getNode(X86ISD::SETCC, MVT::i8, DAG.getConstant(X86CC, MVT::i8), Cond); @@ -1475,12 +1553,11 @@ CC = Op0.getOperand(0); Cond = Op0.getOperand(1); isValid = - !(isFPStack && - !SupportedByFPCMOV(cast<ConstantSDNode>(CC)->getSignExtended())); + !(isFPStack && !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended())); } else if (Op0.getOpcode() == ISD::SETCC) { CC = Op0.getOperand(2); bool isFP = MVT::isFloatingPoint(Op0.getOperand(1).getValueType()); - unsigned X86CC = CCToX86CondCode(CC, isFP); + unsigned X86CC = getX86CC(CC, isFP); CC = DAG.getConstant(X86CC, MVT::i8); Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Op0.getOperand(0), Op0.getOperand(1)); @@ -1513,7 +1590,7 @@ } else if (Cond.getOpcode() == ISD::SETCC) { CC = Cond.getOperand(2); bool isFP = MVT::isFloatingPoint(Cond.getOperand(1).getValueType()); - unsigned X86CC = CCToX86CondCode(CC, isFP); + unsigned X86CC = getX86CC(CC, isFP); CC = DAG.getConstant(X86CC, MVT::i8); Cond = DAG.getNode(X86ISD::CMP, MVT::Flag, Cond.getOperand(0), Cond.getOperand(1)); Index: llvm/lib/Target/X86/X86ISelLowering.h diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.12 llvm/lib/Target/X86/X86ISelLowering.h:1.13 --- llvm/lib/Target/X86/X86ISelLowering.h:1.12 Mon Jan 9 12:33:28 2006 +++ llvm/lib/Target/X86/X86ISelLowering.h Tue Jan 10 18:33:36 2006 @@ -199,6 +199,9 @@ LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, SelectionDAG &DAG); + virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, + MachineBasicBlock *MBB); + /// getTargetNodeName - This method returns the name of a target specific /// DAG node. virtual const char *getTargetNodeName(unsigned Opcode) const; Index: llvm/lib/Target/X86/X86InstrInfo.td diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.194 llvm/lib/Target/X86/X86InstrInfo.td:1.195 --- llvm/lib/Target/X86/X86InstrInfo.td:1.194 Tue Jan 10 16:22:02 2006 +++ llvm/lib/Target/X86/X86InstrInfo.td Tue Jan 10 18:33:36 2006 @@ -361,8 +361,8 @@ // Instruction list... // +// Pseudo-instructions: def PHI : I<0, Pseudo, (ops variable_ops), "PHINODE", []>; // PHI node. -def NOOP : I<0x90, RawFrm, (ops), "nop", []>; // nop def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN", [(X86callseq_start imm:$amt)]>; @@ -388,10 +388,29 @@ [(set FR64:$dst, (undef))]>, Requires<[HasSSE2]>; +// CMOV* - Used to implement the SSE SELECT DAG operation. Expanded by the +// scheduler into a branch sequence. +let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler. + def CMOV_FR32 : I<0, Pseudo, + (ops FR32:$dst, FR32:$t, FR32:$f, i8imm:$cond), + "#CMOV PSEUDO!", + [(set FR32:$dst, (X86cmov FR32:$t, FR32:$f, imm:$cond, + STATUS))]>; + def CMOV_FR64 : I<0, Pseudo, + (ops FR64:$dst, FR64:$t, FR64:$f, i8imm:$cond), + "#CMOV PSEUDO!", + [(set FR64:$dst, (X86cmov FR64:$t, FR64:$f, imm:$cond, + STATUS))]>; +} + let isTerminator = 1 in let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in def FP_REG_KILL : I<0, Pseudo, (ops), "#FP_REG_KILL", []>; + +// Nop +def NOOP : I<0x90, RawFrm, (ops), "nop", []>; + //===----------------------------------------------------------------------===// // Control Flow Instructions... // @@ -409,6 +428,7 @@ class IBr<bits<8> opcode, dag ops, string asm, list<dag> pattern> : I<opcode, RawFrm, ops, asm, pattern>; +// Conditional branches let isBarrier = 1 in def JMP : IBr<0xE9, (ops brtarget:$dst), "jmp $dst", [(br bb:$dst)]>; @@ -442,6 +462,10 @@ [(X86brcond bb:$dst, X86_COND_P, STATUS)]>, Imp<[STATUS],[]>, TB; def JNP : IBr<0x8B, (ops brtarget:$dst), "jnp $dst", [(X86brcond bb:$dst, X86_COND_NP, STATUS)]>, Imp<[STATUS],[]>, TB; +def JO : IBr<0x80, (ops brtarget:$dst), "jo $dst", + [(X86brcond bb:$dst, X86_COND_O, STATUS)]>, Imp<[STATUS],[]>, TB; +def JNO : IBr<0x81, (ops brtarget:$dst), "jno $dst", + [(X86brcond bb:$dst, X86_COND_NO, STATUS)]>, Imp<[STATUS],[]>, TB; //===----------------------------------------------------------------------===// // Call Instructions... _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits