Skip to content

Commit 32b0ff6

Browse files
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! llvm-svn: 46098
1 parent a14396d commit 32b0ff6

File tree

2 files changed

+70
-7
lines changed

2 files changed

+70
-7
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4802,8 +4802,59 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
48024802

48034803
SrcValueSDNode *TrmpSV = cast<SrcValueSDNode>(Op.getOperand(4));
48044804

4805+
const X86InstrInfo *TII =
4806+
((X86TargetMachine&)getTargetMachine()).getInstrInfo();
4807+
48054808
if (Subtarget->is64Bit()) {
4806-
return SDOperand(); // not yet supported
4809+
SDOperand OutChains[6];
4810+
4811+
// Large code-model.
4812+
4813+
const unsigned char JMP64r = TII->getBaseOpcodeFor(X86::JMP64r);
4814+
const unsigned char MOV64ri = TII->getBaseOpcodeFor(X86::MOV64ri);
4815+
4816+
const unsigned char N86R10 =
4817+
((X86RegisterInfo*)RegInfo)->getX86RegNum(X86::R10);
4818+
const unsigned char N86R11 =
4819+
((X86RegisterInfo*)RegInfo)->getX86RegNum(X86::R11);
4820+
4821+
const unsigned char REX_WB = 0x40 | 0x08 | 0x01; // REX prefix
4822+
4823+
// Load the pointer to the nested function into R11.
4824+
unsigned OpCode = ((MOV64ri | N86R11) << 8) | REX_WB; // movabsq r11
4825+
SDOperand Addr = Trmp;
4826+
OutChains[0] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
4827+
TrmpSV->getValue(), TrmpSV->getOffset());
4828+
4829+
Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(2, MVT::i64));
4830+
OutChains[1] = DAG.getStore(Root, FPtr, Addr, TrmpSV->getValue(),
4831+
TrmpSV->getOffset() + 2, false, 2);
4832+
4833+
// Load the 'nest' parameter value into R10.
4834+
// R10 is specified in X86CallingConv.td
4835+
OpCode = ((MOV64ri | N86R10) << 8) | REX_WB; // movabsq r10
4836+
Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(10, MVT::i64));
4837+
OutChains[2] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
4838+
TrmpSV->getValue(), TrmpSV->getOffset() + 10);
4839+
4840+
Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(12, MVT::i64));
4841+
OutChains[3] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
4842+
TrmpSV->getOffset() + 12, false, 2);
4843+
4844+
// Jump to the nested function.
4845+
OpCode = (JMP64r << 8) | REX_WB; // jmpq *...
4846+
Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(20, MVT::i64));
4847+
OutChains[4] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
4848+
TrmpSV->getValue(), TrmpSV->getOffset() + 20);
4849+
4850+
unsigned char ModRM = N86R11 | (4 << 3) | (3 << 6); // ...r11
4851+
Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(22, MVT::i64));
4852+
OutChains[5] = DAG.getStore(Root, DAG.getConstant(ModRM, MVT::i8), Addr,
4853+
TrmpSV->getValue(), TrmpSV->getOffset() + 22);
4854+
4855+
SDOperand Ops[] =
4856+
{ Trmp, DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains, 6) };
4857+
return DAG.getNode(ISD::MERGE_VALUES, Op.Val->getVTList(), Ops, 2);
48074858
} else {
48084859
Function *Func = (Function *)
48094860
cast<Function>(cast<SrcValueSDNode>(Op.getOperand(5))->getValue());
@@ -4847,25 +4898,23 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
48474898
break;
48484899
}
48494900

4850-
const X86InstrInfo *TII =
4851-
((X86TargetMachine&)getTargetMachine()).getInstrInfo();
4852-
48534901
SDOperand OutChains[4];
48544902
SDOperand Addr, Disp;
48554903

48564904
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(10, MVT::i32));
48574905
Disp = DAG.getNode(ISD::SUB, MVT::i32, FPtr, Addr);
48584906

4859-
unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
4860-
unsigned char N86Reg = ((X86RegisterInfo*)RegInfo)->getX86RegNum(NestReg);
4907+
const unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
4908+
const unsigned char N86Reg =
4909+
((X86RegisterInfo*)RegInfo)->getX86RegNum(NestReg);
48614910
OutChains[0] = DAG.getStore(Root, DAG.getConstant(MOV32ri|N86Reg, MVT::i8),
48624911
Trmp, TrmpSV->getValue(), TrmpSV->getOffset());
48634912

48644913
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(1, MVT::i32));
48654914
OutChains[1] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
48664915
TrmpSV->getOffset() + 1, false, 1);
48674916

4868-
unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
4917+
const unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
48694918
Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(5, MVT::i32));
48704919
OutChains[2] = DAG.getStore(Root, DAG.getConstant(JMP, MVT::i8), Addr,
48714920
TrmpSV->getValue() + 5, TrmpSV->getOffset());
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; RUN: llvm-as < %s | llc -march=x86
2+
; RUN: llvm-as < %s | llc -march=x86-64
3+
4+
%struct.FRAME.gnat__perfect_hash_generators__select_char_position__build_identical_keys_sets = type { i32, i32, void (i32, i32)*, i8 (i32, i32)* }
5+
6+
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) {
7+
entry:
8+
%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]
9+
unreachable
10+
}
11+
12+
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
13+
14+
declare i8* @llvm.init.trampoline(i8*, i8*, i8*) nounwind

0 commit comments

Comments
 (0)