mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
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
This commit is contained in:
parent
81a39bb7ba
commit
78e448d8b4
@ -4802,8 +4802,59 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
|
||||
|
||||
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 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
|
||||
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 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
|
||||
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());
|
||||
|
14
test/CodeGen/X86/2008-01-16-Trampoline.ll
Normal file
14
test/CodeGen/X86/2008-01-16-Trampoline.ll
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user