Author: baldrick Date: Fri Jul 27 15:02:49 2007 New Revision: 40566 URL: http://llvm.org/viewvc/llvm-project?rev=40566&view=rev Log: Trampoline codegen support for X86-32.
Added: llvm/trunk/lib/Target/X86/X86CodeEmitter.h Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.h Modified: llvm/trunk/lib/Target/X86/X86CallingConv.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CallingConv.td?rev=40566&r1=40565&r2=40566&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CallingConv.td (original) +++ llvm/trunk/lib/Target/X86/X86CallingConv.td Fri Jul 27 15:02:49 2007 @@ -108,6 +108,9 @@ CCIfType<[v8i8, v4i16, v2i32, v1i64], CCAssignToReg<[RDI, RSI, RDX, RCX, R8 , R9 ]>>, + // The 'nest' parameter, if any, is passed in R10. + CCIfNest<CCAssignToReg<[R10]>>, + // Integer/FP values get stored in stack slots that are 8 bytes in size and // 8-byte aligned if there are no more registers to hold them. CCIfType<[i32, i64, f32, f64], CCAssignToStack<8, 8>>, @@ -150,11 +153,14 @@ def CC_X86_32_C : CallingConv<[ // Promote i8/i16 arguments to i32. CCIfType<[i8, i16], CCPromoteToType<i32>>, - + + // The 'nest' parameter, if any, is passed in ECX. + CCIfNest<CCAssignToReg<[ECX]>>, + // The first 3 integer arguments, if marked 'inreg' and if the call is not // a vararg call, are passed in integer registers. CCIfNotVarArg<CCIfInReg<CCIfType<[i32], CCAssignToReg<[EAX, EDX, ECX]>>>>, - + // Otherwise, same as everything else. CCDelegateTo<CC_X86_32_Common> ]>; @@ -163,10 +169,13 @@ def CC_X86_32_FastCall : CallingConv<[ // Promote i8/i16 arguments to i32. CCIfType<[i8, i16], CCPromoteToType<i32>>, - + + // The 'nest' parameter, if any, is passed in EAX. + CCIfNest<CCAssignToReg<[EAX]>>, + // The first 2 integer arguments are passed in ECX/EDX CCIfType<[i32], CCAssignToReg<[ECX, EDX]>>, - + // Otherwise, same as everything else. CCDelegateTo<CC_X86_32_Common> ]>; Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=40566&r1=40565&r2=40566&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Fri Jul 27 15:02:49 2007 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "x86-emitter" +#include "X86CodeEmitter.h" #include "X86InstrInfo.h" #include "X86Subtarget.h" #include "X86TargetMachine.h" @@ -192,14 +193,6 @@ MCE.emitWordLE(0); // The relocated value will be added to the displacement } -/// N86 namespace - Native X86 Register numbers... used by X86 backend. -/// -namespace N86 { - enum { - EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7 - }; -} - // getX86RegNum - This function maps LLVM register identifiers to their X86 // specific numbering, which is used in various places encoding instructions. // Added: llvm/trunk/lib/Target/X86/X86CodeEmitter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.h?rev=40566&view=auto ============================================================================== --- llvm/trunk/lib/Target/X86/X86CodeEmitter.h (added) +++ llvm/trunk/lib/Target/X86/X86CodeEmitter.h Fri Jul 27 15:02:49 2007 @@ -0,0 +1,25 @@ +//===-- X86CodeEmitter.h - X86 DAG Lowering Interface -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Duncan Sands and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines utilities for X86 code emission. +// +//===----------------------------------------------------------------------===// + +#ifndef X86CODEEMITTER_H +#define X86CODEEMITTER_H + +/// N86 namespace - Native X86 Register numbers... used by X86 backend. +/// +namespace N86 { + enum { + EAX = 0, ECX = 1, EDX = 2, EBX = 3, ESP = 4, EBP = 5, ESI = 6, EDI = 7 + }; +} + +#endif // X86CODEEMITTER_H Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=40566&r1=40565&r2=40566&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Jul 27 15:02:49 2007 @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "X86.h" +#include "X86CodeEmitter.h" #include "X86InstrBuilder.h" #include "X86ISelLowering.h" #include "X86MachineFunctionInfo.h" @@ -34,6 +35,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ParameterAttributes.h" using namespace llvm; X86TargetLowering::X86TargetLowering(TargetMachine &TM) @@ -244,6 +246,10 @@ setExceptionSelectorRegister(X86::EDX); } + setOperationAction(ISD::ADJUST_TRAMP, MVT::i32, Expand); + setOperationAction(ISD::ADJUST_TRAMP, MVT::i64, Expand); + setOperationAction(ISD::TRAMPOLINE, MVT::Other, Custom); + // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VASTART , MVT::Other, Custom); setOperationAction(ISD::VAARG , MVT::Other, Expand); @@ -4265,6 +4271,89 @@ Chain, DAG.getRegister(X86::ECX, getPointerTy())); } +SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op, + SelectionDAG &DAG) { + SDOperand Root = Op.getOperand(0); + SDOperand Trmp = Op.getOperand(1); // trampoline + SDOperand FPtr = Op.getOperand(2); // nested function + SDOperand Nest = Op.getOperand(3); // 'nest' parameter value + + SrcValueSDNode *TrmpSV = cast<SrcValueSDNode>(Op.getOperand(4)); + + if (Subtarget->is64Bit()) { + return SDOperand(); // not yet supported + } else { + Function *Func = (Function *) + cast<Function>(cast<SrcValueSDNode>(Op.getOperand(5))->getValue()); + unsigned CC = Func->getCallingConv(); + unsigned char NestReg; + + switch (CC) { + default: + assert(0 && "Unsupported calling convention"); + case CallingConv::C: + case CallingConv::Fast: + case CallingConv::X86_StdCall: { + // Pass 'nest' parameter in ECX. + // Must be kept in sync with X86CallingConv.td + NestReg = N86::ECX; + + // Check that ECX wasn't needed by an 'inreg' parameter. + const FunctionType *FTy = Func->getFunctionType(); + const ParamAttrsList *Attrs = FTy->getParamAttrs(); + + if (Attrs && !Func->isVarArg()) { + unsigned InRegCount = 0; + unsigned Idx = 1; + + for (FunctionType::param_iterator I = FTy->param_begin(), + E = FTy->param_end(); I != E; ++I, ++Idx) + if (Attrs->paramHasAttr(Idx, ParamAttr::InReg)) + // FIXME: should only count parameters that are lowered to integers. + InRegCount += (getTargetData()->getTypeSizeInBits(*I) + 31) / 32; + + if (InRegCount > 2) { + cerr << "Nest register in use - reduce number of inreg parameters!\n"; + abort(); + } + } + break; + } + case CallingConv::X86_FastCall: + // Pass 'nest' parameter in EAX. + // Must be kept in sync with X86CallingConv.td + NestReg = N86::EAX; + break; + } + + SDOperand OutChains[4]; + SDOperand Addr, Disp; + + Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(10, MVT::i32)); + Disp = DAG.getNode(ISD::SUB, MVT::i32, FPtr, Addr); + + const unsigned char MOV32ri = 0xB8; + const unsigned char JMP = 0xE9; + + OutChains[0] = DAG.getStore(Root, DAG.getConstant(MOV32ri|NestReg, MVT::i8), + Trmp, TrmpSV->getValue(), TrmpSV->getOffset()); + + Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(1, MVT::i32)); + OutChains[1] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(), + TrmpSV->getOffset() + 1, false, 1); + + Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(5, MVT::i32)); + OutChains[2] = DAG.getStore(Root, DAG.getConstant(JMP, MVT::i8), Addr, + TrmpSV->getValue() + 5, TrmpSV->getOffset()); + + Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(6, MVT::i32)); + OutChains[3] = DAG.getStore(Root, Disp, Addr, TrmpSV->getValue(), + TrmpSV->getOffset() + 6, false, 1); + + return DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains, 4); + } +} + /// LowerOperation - Provide custom lowering hooks for some operations. /// SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { @@ -4306,6 +4395,7 @@ return LowerFRAME_TO_ARGS_OFFSET(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG); + case ISD::TRAMPOLINE: return LowerTRAMPOLINE(Op, DAG); } return SDOperand(); } Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=40566&r1=40565&r2=40566&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Fri Jul 27 15:02:49 2007 @@ -423,6 +423,7 @@ SDOperand LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFRAME_TO_ARGS_OFFSET(SDOperand Op, SelectionDAG &DAG); SDOperand LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerTRAMPOLINE(SDOperand Op, SelectionDAG &DAG); }; } _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits