From 60c07e1aeadd332c5e000449df2a487831209fa8 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 5 Jul 2006 22:17:51 +0000 Subject: [PATCH] Reorg. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28999 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 378 +++++++++++++++-------------- 1 file changed, 195 insertions(+), 183 deletions(-) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 1b0be8acc80..674c38fb0a9 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1394,139 +1394,6 @@ static bool hasFPCMov(unsigned X86CC) { } } -MachineBasicBlock * -X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, - MachineBasicBlock *BB) { - switch (MI->getOpcode()) { - default: assert(false && "Unexpected instr type to insert"); - case X86::CMOV_FR32: - case X86::CMOV_FR64: - case X86::CMOV_V4F32: - case X86::CMOV_V2F64: - case X86::CMOV_V2I64: { - // 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::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 by first adding all successors of the current - // block to the new block which will contain the Phi node for the select. - for(MachineBasicBlock::succ_iterator i = BB->succ_begin(), - e = BB->succ_end(); i != e; ++i) - sinkMBB->addSuccessor(*i); - // Next, remove all successors of the current block, and add the true - // and fallthrough blocks as its successors. - while(!BB->succ_empty()) - BB->removeSuccessor(BB->succ_begin()); - 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; - } - - case X86::FP_TO_INT16_IN_MEM: - case X86::FP_TO_INT32_IN_MEM: - case X86::FP_TO_INT64_IN_MEM: { - // Change the floating point control register to use "round towards zero" - // mode when truncating to an integer value. - MachineFunction *F = BB->getParent(); - int CWFrameIdx = F->getFrameInfo()->CreateStackObject(2, 2); - addFrameReference(BuildMI(BB, X86::FNSTCW16m, 4), CWFrameIdx); - - // Load the old value of the high byte of the control word... - unsigned OldCW = - F->getSSARegMap()->createVirtualRegister(X86::GR16RegisterClass); - addFrameReference(BuildMI(BB, X86::MOV16rm, 4, OldCW), CWFrameIdx); - - // Set the high part to be round to zero... - addFrameReference(BuildMI(BB, X86::MOV16mi, 5), CWFrameIdx).addImm(0xC7F); - - // Reload the modified control word now... - addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx); - - // Restore the memory image of control word to original value - addFrameReference(BuildMI(BB, X86::MOV16mr, 5), CWFrameIdx).addReg(OldCW); - - // Get the X86 opcode to use. - unsigned Opc; - switch (MI->getOpcode()) { - default: assert(0 && "illegal opcode!"); - case X86::FP_TO_INT16_IN_MEM: Opc = X86::FpIST16m; break; - case X86::FP_TO_INT32_IN_MEM: Opc = X86::FpIST32m; break; - case X86::FP_TO_INT64_IN_MEM: Opc = X86::FpIST64m; break; - } - - X86AddressMode AM; - MachineOperand &Op = MI->getOperand(0); - if (Op.isRegister()) { - AM.BaseType = X86AddressMode::RegBase; - AM.Base.Reg = Op.getReg(); - } else { - AM.BaseType = X86AddressMode::FrameIndexBase; - AM.Base.FrameIndex = Op.getFrameIndex(); - } - Op = MI->getOperand(1); - if (Op.isImmediate()) - AM.Scale = Op.getImmedValue(); - Op = MI->getOperand(2); - if (Op.isImmediate()) - AM.IndexReg = Op.getImmedValue(); - Op = MI->getOperand(3); - if (Op.isGlobalAddress()) { - AM.GV = Op.getGlobal(); - } else { - AM.Disp = Op.getImmedValue(); - } - addFullAddress(BuildMI(BB, Opc, 5), AM).addReg(MI->getOperand(4).getReg()); - - // Reload the original control word now. - addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx); - - delete MI; // The pseudo instruction is gone now. - return BB; - } - } -} - - -//===----------------------------------------------------------------------===// -// X86 Custom Lowering Hooks -//===----------------------------------------------------------------------===// - /// DarwinGVRequiresExtraLoad - true if accessing the GV requires an extra /// load. For Darwin, external and weak symbols are indirect, loading the value /// at address GV rather then the value of GV itself. This means that the @@ -3892,6 +3759,197 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const { } } +/// isLegalAddressImmediate - Return true if the integer value or +/// GlobalValue can be used as the offset of the target addressing mode. +bool X86TargetLowering::isLegalAddressImmediate(int64_t V) const { + // X86 allows a sign-extended 32-bit immediate field. + return (V > -(1LL << 32) && V < (1LL << 32)-1); +} + +bool X86TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { + // GV is 64-bit but displacement field is 32-bit unless we are in small code + // model. Mac OS X happens to support only small PIC code model. + // FIXME: better support for other OS's. + if (Subtarget->is64Bit() && !Subtarget->isTargetDarwin()) + return false; + if (Subtarget->isTargetDarwin()) { + Reloc::Model RModel = getTargetMachine().getRelocationModel(); + if (RModel == Reloc::Static) + return true; + else if (RModel == Reloc::DynamicNoPIC) + return !DarwinGVRequiresExtraLoad(GV); + else + return false; + } else + return true; +} + +/// isShuffleMaskLegal - Targets can use this to indicate that they only +/// support *some* VECTOR_SHUFFLE operations, those with specific masks. +/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values +/// are assumed to be legal. +bool +X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const { + // Only do shuffles on 128-bit vector types for now. + if (MVT::getSizeInBits(VT) == 64) return false; + return (Mask.Val->getNumOperands() <= 4 || + isSplatMask(Mask.Val) || + isPSHUFHW_PSHUFLWMask(Mask.Val) || + X86::isUNPCKLMask(Mask.Val) || + X86::isUNPCKL_v_undef_Mask(Mask.Val) || + X86::isUNPCKHMask(Mask.Val)); +} + +bool X86TargetLowering::isVectorClearMaskLegal(std::vector &BVOps, + MVT::ValueType EVT, + SelectionDAG &DAG) const { + unsigned NumElts = BVOps.size(); + // Only do shuffles on 128-bit vector types for now. + if (MVT::getSizeInBits(EVT) * NumElts == 64) return false; + if (NumElts == 2) return true; + if (NumElts == 4) { + return (isMOVLMask(BVOps) || isCommutedMOVL(BVOps, true) || + isSHUFPMask(BVOps) || isCommutedSHUFP(BVOps)); + } + return false; +} + +//===----------------------------------------------------------------------===// +// X86 Scheduler Hooks +//===----------------------------------------------------------------------===// + +MachineBasicBlock * +X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, + MachineBasicBlock *BB) { + switch (MI->getOpcode()) { + default: assert(false && "Unexpected instr type to insert"); + case X86::CMOV_FR32: + case X86::CMOV_FR64: + case X86::CMOV_V4F32: + case X86::CMOV_V2F64: + case X86::CMOV_V2I64: { + // 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::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 by first adding all successors of the current + // block to the new block which will contain the Phi node for the select. + for(MachineBasicBlock::succ_iterator i = BB->succ_begin(), + e = BB->succ_end(); i != e; ++i) + sinkMBB->addSuccessor(*i); + // Next, remove all successors of the current block, and add the true + // and fallthrough blocks as its successors. + while(!BB->succ_empty()) + BB->removeSuccessor(BB->succ_begin()); + 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; + } + + case X86::FP_TO_INT16_IN_MEM: + case X86::FP_TO_INT32_IN_MEM: + case X86::FP_TO_INT64_IN_MEM: { + // Change the floating point control register to use "round towards zero" + // mode when truncating to an integer value. + MachineFunction *F = BB->getParent(); + int CWFrameIdx = F->getFrameInfo()->CreateStackObject(2, 2); + addFrameReference(BuildMI(BB, X86::FNSTCW16m, 4), CWFrameIdx); + + // Load the old value of the high byte of the control word... + unsigned OldCW = + F->getSSARegMap()->createVirtualRegister(X86::GR16RegisterClass); + addFrameReference(BuildMI(BB, X86::MOV16rm, 4, OldCW), CWFrameIdx); + + // Set the high part to be round to zero... + addFrameReference(BuildMI(BB, X86::MOV16mi, 5), CWFrameIdx).addImm(0xC7F); + + // Reload the modified control word now... + addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx); + + // Restore the memory image of control word to original value + addFrameReference(BuildMI(BB, X86::MOV16mr, 5), CWFrameIdx).addReg(OldCW); + + // Get the X86 opcode to use. + unsigned Opc; + switch (MI->getOpcode()) { + default: assert(0 && "illegal opcode!"); + case X86::FP_TO_INT16_IN_MEM: Opc = X86::FpIST16m; break; + case X86::FP_TO_INT32_IN_MEM: Opc = X86::FpIST32m; break; + case X86::FP_TO_INT64_IN_MEM: Opc = X86::FpIST64m; break; + } + + X86AddressMode AM; + MachineOperand &Op = MI->getOperand(0); + if (Op.isRegister()) { + AM.BaseType = X86AddressMode::RegBase; + AM.Base.Reg = Op.getReg(); + } else { + AM.BaseType = X86AddressMode::FrameIndexBase; + AM.Base.FrameIndex = Op.getFrameIndex(); + } + Op = MI->getOperand(1); + if (Op.isImmediate()) + AM.Scale = Op.getImmedValue(); + Op = MI->getOperand(2); + if (Op.isImmediate()) + AM.IndexReg = Op.getImmedValue(); + Op = MI->getOperand(3); + if (Op.isGlobalAddress()) { + AM.GV = Op.getGlobal(); + } else { + AM.Disp = Op.getImmedValue(); + } + addFullAddress(BuildMI(BB, Opc, 5), AM).addReg(MI->getOperand(4).getReg()); + + // Reload the original control word now. + addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx); + + delete MI; // The pseudo instruction is gone now. + return BB; + } + } +} + +//===----------------------------------------------------------------------===// +// X86 Optimization Hooks +//===----------------------------------------------------------------------===// + void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, uint64_t Mask, uint64_t &KnownZero, @@ -3914,6 +3972,10 @@ void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, } } +//===----------------------------------------------------------------------===// +// X86 Inline Assembly Support +//===----------------------------------------------------------------------===// + std::vector X86TargetLowering:: getRegClassForInlineAsmConstraint(const std::string &Constraint, MVT::ValueType VT) const { @@ -3969,53 +4031,3 @@ getRegClassForInlineAsmConstraint(const std::string &Constraint, return std::vector(); } - -/// isLegalAddressImmediate - Return true if the integer value or -/// GlobalValue can be used as the offset of the target addressing mode. -bool X86TargetLowering::isLegalAddressImmediate(int64_t V) const { - // X86 allows a sign-extended 32-bit immediate field. - return (V > -(1LL << 32) && V < (1LL << 32)-1); -} - -bool X86TargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { - if (Subtarget->isTargetDarwin()) { - Reloc::Model RModel = getTargetMachine().getRelocationModel(); - if (RModel == Reloc::Static) - return true; - else if (RModel == Reloc::DynamicNoPIC) - return !DarwinGVRequiresExtraLoad(GV); - else - return false; - } else - return true; -} - -/// isShuffleMaskLegal - Targets can use this to indicate that they only -/// support *some* VECTOR_SHUFFLE operations, those with specific masks. -/// By default, if a target supports the VECTOR_SHUFFLE node, all mask values -/// are assumed to be legal. -bool -X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const { - // Only do shuffles on 128-bit vector types for now. - if (MVT::getSizeInBits(VT) == 64) return false; - return (Mask.Val->getNumOperands() <= 4 || - isSplatMask(Mask.Val) || - isPSHUFHW_PSHUFLWMask(Mask.Val) || - X86::isUNPCKLMask(Mask.Val) || - X86::isUNPCKL_v_undef_Mask(Mask.Val) || - X86::isUNPCKHMask(Mask.Val)); -} - -bool X86TargetLowering::isVectorClearMaskLegal(std::vector &BVOps, - MVT::ValueType EVT, - SelectionDAG &DAG) const { - unsigned NumElts = BVOps.size(); - // Only do shuffles on 128-bit vector types for now. - if (MVT::getSizeInBits(EVT) * NumElts == 64) return false; - if (NumElts == 2) return true; - if (NumElts == 4) { - return (isMOVLMask(BVOps) || isCommutedMOVL(BVOps, true) || - isSHUFPMask(BVOps) || isCommutedSHUFP(BVOps)); - } - return false; -}