From d74ea775af55782e3b0d5b10fa7602f8822a2f72 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Fri, 22 Apr 2011 23:38:06 +0000 Subject: [PATCH] Teach FastISel to deal with instructions that have two immediate operands. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130033 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/FastISel.h | 7 ++++- lib/CodeGen/SelectionDAG/FastISel.cpp | 37 +++++++++++++++++++-------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h index 76eb5942e66..fa6594c01ee 100644 --- a/include/llvm/CodeGen/FastISel.h +++ b/include/llvm/CodeGen/FastISel.h @@ -288,7 +288,12 @@ protected: unsigned FastEmitInst_i(unsigned MachineInstrOpcode, const TargetRegisterClass *RC, uint64_t Imm); - + + /// FastEmitInst_ii - Emit a MachineInstr with a two immediate operands. + unsigned FastEmitInst_ii(unsigned MachineInstrOpcode, + const TargetRegisterClass *RC, + uint64_t Imm1, uint64_t Imm2); + /// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg /// from a specified index of a superregister to a specified type. unsigned FastEmitInst_extractsubreg(MVT RetVT, diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp index 83894cd4a00..e8dfed395c0 100644 --- a/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -338,18 +338,18 @@ bool FastISel::SelectBinaryOp(const User *I, unsigned ISDOpcode) { if (Op1 == 0) return false; bool Op1IsKill = hasTrivialKill(I->getOperand(1)); - + unsigned ResultReg = FastEmit_ri_(VT.getSimpleVT(), ISDOpcode, Op1, Op1IsKill, CI->getZExtValue(), VT.getSimpleVT()); if (ResultReg == 0) return false; - + // We successfully emitted code for the given LLVM Instruction. UpdateValueMap(I, ResultReg); return true; } - - + + unsigned Op0 = getRegForValue(I->getOperand(0)); if (Op0 == 0) // Unhandled operand. Halt "fast" selection and bail. return false; @@ -359,7 +359,7 @@ bool FastISel::SelectBinaryOp(const User *I, unsigned ISDOpcode) { // Check if the second operand is a constant and handle it appropriately. if (ConstantInt *CI = dyn_cast(I->getOperand(1))) { uint64_t Imm = CI->getZExtValue(); - + // Transform "sdiv exact X, 8" -> "sra X, 3". if (ISDOpcode == ISD::SDIV && isa(I) && cast(I)->isExact() && @@ -367,11 +367,11 @@ bool FastISel::SelectBinaryOp(const User *I, unsigned ISDOpcode) { Imm = Log2_64(Imm); ISDOpcode = ISD::SRA; } - + unsigned ResultReg = FastEmit_ri_(VT.getSimpleVT(), ISDOpcode, Op0, Op0IsKill, Imm, VT.getSimpleVT()); if (ResultReg == 0) return false; - + // We successfully emitted code for the given LLVM Instruction. UpdateValueMap(I, ResultReg); return true; @@ -553,7 +553,7 @@ bool FastISel::SelectCall(const User *I) { EVT VT = TLI.getValueType(I->getType()); if (TLI.getOperationAction(ISD::EXCEPTIONADDR, VT)!=TargetLowering::Expand) break; - + assert(FuncInfo.MBB->isLandingPad() && "Call to eh.exception not in landing pad!"); unsigned Reg = TLI.getExceptionAddressRegister(); @@ -995,13 +995,13 @@ unsigned FastISel::FastEmit_ri_(MVT VT, unsigned Opcode, Opcode = ISD::SRL; Imm = Log2_64(Imm); } - + // Horrible hack (to be removed), check to make sure shift amounts are // in-range. if ((Opcode == ISD::SHL || Opcode == ISD::SRA || Opcode == ISD::SRL) && Imm >= VT.getSizeInBits()) return 0; - + // First check if immediate type is legal. If not, we can't use the ri form. unsigned ResultReg = FastEmit_ri(VT, VT, Opcode, Op0, Op0IsKill, Imm); if (ResultReg != 0) @@ -1219,6 +1219,23 @@ unsigned FastISel::FastEmitInst_i(unsigned MachineInstOpcode, return ResultReg; } +unsigned FastISel::FastEmitInst_ii(unsigned MachineInstOpcode, + const TargetRegisterClass *RC, + uint64_t Imm1, uint64_t Imm2) { + unsigned ResultReg = createResultReg(RC); + const TargetInstrDesc &II = TII.get(MachineInstOpcode); + + if (II.getNumDefs() >= 1) + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) + .addImm(Imm1).addImm(Imm2); + else { + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II).addImm(Imm1).addImm(Imm2); + BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(TargetOpcode::COPY), + ResultReg).addReg(II.ImplicitDefs[0]); + } + return ResultReg; +} + unsigned FastISel::FastEmitInst_extractsubreg(MVT RetVT, unsigned Op0, bool Op0IsKill, uint32_t Idx) {