[llvm-commits] [llvm] r46098 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/2008-01-16-Trampoline.ll

Duncan Sands baldrick at free.fr
Wed Jan 16 14:55:25 PST 2008


Author: baldrick
Date: Wed Jan 16 16:55:25 2008
New Revision: 46098

URL: http://llvm.org/viewvc/llvm-project?rev=46098&view=rev
Log:
Trampoline support for x86-64.  This looks like
it should work, but I have no machine to test
it on.  Committed because it will at least
cause no harm, and maybe someone can test it
for me!

Added:
    llvm/trunk/test/CodeGen/X86/2008-01-16-Trampoline.ll
Modified:
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=46098&r1=46097&r2=46098&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Jan 16 16:55:25 2008
@@ -4802,8 +4802,59 @@
 
   SrcValueSDNode *TrmpSV = cast<SrcValueSDNode>(Op.getOperand(4));
 
+  const X86InstrInfo *TII =
+    ((X86TargetMachine&)getTargetMachine()).getInstrInfo();
+
   if (Subtarget->is64Bit()) {
-    return SDOperand(); // not yet supported
+    SDOperand OutChains[6];
+
+    // Large code-model.
+
+    const unsigned char JMP64r  = TII->getBaseOpcodeFor(X86::JMP64r);
+    const unsigned char MOV64ri = TII->getBaseOpcodeFor(X86::MOV64ri);
+
+    const unsigned char N86R10 =
+      ((X86RegisterInfo*)RegInfo)->getX86RegNum(X86::R10);
+    const unsigned char N86R11 =
+      ((X86RegisterInfo*)RegInfo)->getX86RegNum(X86::R11);
+
+    const unsigned char REX_WB = 0x40 | 0x08 | 0x01; // REX prefix
+
+    // Load the pointer to the nested function into R11.
+    unsigned OpCode = ((MOV64ri | N86R11) << 8) | REX_WB; // movabsq r11
+    SDOperand Addr = Trmp;
+    OutChains[0] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
+                                TrmpSV->getValue(), TrmpSV->getOffset());
+
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(2, MVT::i64));
+    OutChains[1] = DAG.getStore(Root, FPtr, Addr, TrmpSV->getValue(),
+                                TrmpSV->getOffset() + 2, false, 2);
+
+    // Load the 'nest' parameter value into R10.
+    // R10 is specified in X86CallingConv.td
+    OpCode = ((MOV64ri | N86R10) << 8) | REX_WB; // movabsq r10
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(10, MVT::i64));
+    OutChains[2] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
+                                TrmpSV->getValue(), TrmpSV->getOffset() + 10);
+
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(12, MVT::i64));
+    OutChains[3] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
+                                TrmpSV->getOffset() + 12, false, 2);
+
+    // Jump to the nested function.
+    OpCode = (JMP64r << 8) | REX_WB; // jmpq *...
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(20, MVT::i64));
+    OutChains[4] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
+                                TrmpSV->getValue(), TrmpSV->getOffset() + 20);
+
+    unsigned char ModRM = N86R11 | (4 << 3) | (3 << 6); // ...r11
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(22, MVT::i64));
+    OutChains[5] = DAG.getStore(Root, DAG.getConstant(ModRM, MVT::i8), Addr,
+                                TrmpSV->getValue(), TrmpSV->getOffset() + 22);
+
+    SDOperand Ops[] =
+      { Trmp, DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains, 6) };
+    return DAG.getNode(ISD::MERGE_VALUES, Op.Val->getVTList(), Ops, 2);
   } else {
     Function *Func = (Function *)
       cast<Function>(cast<SrcValueSDNode>(Op.getOperand(5))->getValue());
@@ -4847,17 +4898,15 @@
       break;
     }
 
-    const X86InstrInfo *TII =
-      ((X86TargetMachine&)getTargetMachine()).getInstrInfo();
-
     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);
 
-    unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
-    unsigned char N86Reg  = ((X86RegisterInfo*)RegInfo)->getX86RegNum(NestReg);
+    const unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
+    const unsigned char N86Reg =
+      ((X86RegisterInfo*)RegInfo)->getX86RegNum(NestReg);
     OutChains[0] = DAG.getStore(Root, DAG.getConstant(MOV32ri|N86Reg, MVT::i8),
                                 Trmp, TrmpSV->getValue(), TrmpSV->getOffset());
 
@@ -4865,7 +4914,7 @@
     OutChains[1] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
                                 TrmpSV->getOffset() + 1, false, 1);
 
-    unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
+    const unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
     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());

Added: llvm/trunk/test/CodeGen/X86/2008-01-16-Trampoline.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/2008-01-16-Trampoline.ll?rev=46098&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/X86/2008-01-16-Trampoline.ll (added)
+++ llvm/trunk/test/CodeGen/X86/2008-01-16-Trampoline.ll Wed Jan 16 16:55:25 2008
@@ -0,0 +1,14 @@
+; RUN: llvm-as < %s | llc -march=x86
+; RUN: llvm-as < %s | llc -march=x86-64
+
+	%struct.FRAME.gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets = type { i32, i32, void (i32, i32)*, i8 (i32, i32)* }
+
+define fastcc i32 @gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets.5146(i64 %table.0.0, i64 %table.0.1, i32 %last, i32 %pos) {
+entry:
+	%tramp22 = call i8* @llvm.init.trampoline( i8* null, i8* bitcast (void (%struct.FRAME.gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets*, i32, i32)* @gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets__move.5177 to i8*), i8* null )		; <i8*> [#uses=0]
+	unreachable
+}
+
+declare void @gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets__move.5177(%struct.FRAME.gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets* nest , i32, i32) nounwind 
+
+declare i8* @llvm.init.trampoline(i8*, i8*, i8*) nounwind 





More information about the llvm-commits mailing list