[llvm-commits] [llvm] r40566 - in /llvm/trunk/lib/Target/X86: X86CallingConv.td X86CodeEmitter.cpp X86CodeEmitter.h X86ISelLowering.cpp X86ISelLowering.h

Duncan Sands baldrick at free.fr
Fri Jul 27 13:02:49 PDT 2007


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);
   };
 }
 





More information about the llvm-commits mailing list