From 66ef6517ad445e5aaee7b15fd272ee0fd0053c9a Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 8 Sep 2008 06:35:17 +0000 Subject: [PATCH] Add support to extend call operands when needed. Enable x86 fastisel call support. llvm-svn: 55891 --- lib/Target/X86/X86FastISel.cpp | 57 ++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index 15c8f717090..b2e2532e569 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -70,6 +70,9 @@ private: bool X86FastEmitStore(MVT VT, unsigned Val, unsigned Ptr, unsigned Offset, Value *V); + + bool X86FastEmitExtend(ISD::NodeType Opc, MVT DstVT, unsigned Src, MVT SrcVT, + unsigned &ResultReg); bool X86SelectConstAddr(Value *V, unsigned &Op0, bool isCall = false); @@ -269,6 +272,16 @@ X86FastISel::X86FastEmitStore(MVT VT, unsigned Val, return true; } +/// X86FastEmitExtend - Emit a machine instruction to extend a value Src of +/// type SrcVT to type DstVT using the specified extension opcode Opc (e.g. +/// ISD::SIGN_EXTEND). +bool X86FastISel::X86FastEmitExtend(ISD::NodeType Opc, MVT DstVT, + unsigned Src, MVT SrcVT, + unsigned &ResultReg) { + ResultReg = FastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), Opc, Src); + return ResultReg != 0; +} + /// X86SelectConstAddr - Select and emit code to materialize constant address. /// bool X86FastISel::X86SelectConstAddr(Value *V, unsigned &Op0, bool isCall) { @@ -300,18 +313,8 @@ bool X86FastISel::X86SelectConstAddr(Value *V, unsigned &Op0, bool isCall) { /// X86SelectStore - Select and emit code to implement store instructions. bool X86FastISel::X86SelectStore(Instruction* I) { - MVT VT = MVT::getMVT(I->getOperand(0)->getType()); - if (VT == MVT::Other || !VT.isSimple()) - // Unhandled type. Halt "fast" selection and bail. - return false; - if (VT == MVT::iPTR) - // Use pointer type. - VT = TLI.getPointerTy(); - // We only handle legal types. For example, on x86-32 the instruction - // selector contains all of the 64-bit instructions from x86-64, - // under the assumption that i64 won't be used if the target doesn't - // support it. - if (!TLI.isTypeLegal(VT)) + MVT VT; + if (!isTypeLegal(I->getOperand(0)->getType(), TLI, VT)) return false; unsigned Val = getRegForValue(I->getOperand(0)); if (Val == 0) @@ -762,16 +765,28 @@ bool X86FastISel::X86SelectCall(Instruction *I) { switch (VA.getLocInfo()) { default: assert(0 && "Unknown loc info!"); case CCValAssign::Full: break; - case CCValAssign::SExt: - abort(); // FIXME + case CCValAssign::SExt: { + bool Emitted = X86FastEmitExtend(ISD::SIGN_EXTEND, VA.getLocVT(), + Arg, ArgVT, Arg); + assert(Emitted && "Failed to emit a sext!"); + ArgVT = VA.getLocVT(); break; - case CCValAssign::ZExt: - abort(); + } + case CCValAssign::ZExt: { + bool Emitted = X86FastEmitExtend(ISD::ZERO_EXTEND, VA.getLocVT(), + Arg, ArgVT, Arg); + assert(Emitted && "Failed to emit a zext!"); + ArgVT = VA.getLocVT(); break; - case CCValAssign::AExt: - abort(); + } + case CCValAssign::AExt: { + bool Emitted = X86FastEmitExtend(ISD::ANY_EXTEND, VA.getLocVT(), + Arg, ArgVT, Arg); + assert(Emitted && "Failed to emit a aext!"); + ArgVT = VA.getLocVT(); break; } + } if (VA.isRegLoc()) { TargetRegisterClass* RC = TLI.getRegClassFor(ArgVT); @@ -802,10 +817,6 @@ bool X86FastISel::X86SelectCall(Instruction *I) { BuildMI(MBB, TII.get(X86::ADJCALLSTACKUP)).addImm(NumBytes).addImm(0); // Now handle call return value (if any). -#if 0 // FIXME - bool isSExt = CS.paramHasAttr(0, ParamAttr::SExt); - bool isZExt = CS.paramHasAttr(0, ParamAttr::ZExt); -#endif if (RetVT.getSimpleVT() != MVT::isVoid) { SmallVector RVLocs; CCState CCInfo(CC, false, TM, RVLocs); @@ -870,10 +881,8 @@ X86FastISel::TargetSelectInstruction(Instruction *I) { return X86SelectZExt(I); case Instruction::Br: return X86SelectBranch(I); -#if 0 case Instruction::Call: return X86SelectCall(I); -#endif case Instruction::LShr: case Instruction::AShr: case Instruction::Shl: