mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
Make X86 call and return instructions non-variadic.
Function argument and return value registers aren't part of the encoding, so they should be implicit operands. llvm-svn: 159728
This commit is contained in:
parent
e8399d2b3a
commit
6edf66ffe8
@ -1838,21 +1838,21 @@ bool X86FastISel::DoSelectCall(const Instruction *I, const char *MemIntName) {
|
|||||||
MIB.addGlobalAddress(GV, 0, OpFlags);
|
MIB.addGlobalAddress(GV, 0, OpFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an implicit use GOT pointer in EBX.
|
|
||||||
if (Subtarget->isPICStyleGOT())
|
|
||||||
MIB.addReg(X86::EBX);
|
|
||||||
|
|
||||||
if (Subtarget->is64Bit() && isVarArg && !Subtarget->isTargetWin64())
|
|
||||||
MIB.addReg(X86::AL);
|
|
||||||
|
|
||||||
// Add implicit physical register uses to the call.
|
|
||||||
for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
|
|
||||||
MIB.addReg(RegArgs[i]);
|
|
||||||
|
|
||||||
// Add a register mask with the call-preserved registers.
|
// Add a register mask with the call-preserved registers.
|
||||||
// Proper defs for return values will be added by setPhysRegsDeadExcept().
|
// Proper defs for return values will be added by setPhysRegsDeadExcept().
|
||||||
MIB.addRegMask(TRI.getCallPreservedMask(CS.getCallingConv()));
|
MIB.addRegMask(TRI.getCallPreservedMask(CS.getCallingConv()));
|
||||||
|
|
||||||
|
// Add an implicit use GOT pointer in EBX.
|
||||||
|
if (Subtarget->isPICStyleGOT())
|
||||||
|
MIB.addReg(X86::EBX, RegState::Implicit);
|
||||||
|
|
||||||
|
if (Subtarget->is64Bit() && isVarArg && !Subtarget->isTargetWin64())
|
||||||
|
MIB.addReg(X86::AL, RegState::Implicit);
|
||||||
|
|
||||||
|
// Add implicit physical register uses to the call.
|
||||||
|
for (unsigned i = 0, e = RegArgs.size(); i != e; ++i)
|
||||||
|
MIB.addReg(RegArgs[i], RegState::Implicit);
|
||||||
|
|
||||||
// Issue CALLSEQ_END
|
// Issue CALLSEQ_END
|
||||||
unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
|
unsigned AdjStackUp = TII.getCallFrameDestroyOpcode();
|
||||||
unsigned NumBytesCallee = 0;
|
unsigned NumBytesCallee = 0;
|
||||||
|
@ -1124,8 +1124,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
|
|||||||
}
|
}
|
||||||
|
|
||||||
MachineInstr *NewMI = prior(MBBI);
|
MachineInstr *NewMI = prior(MBBI);
|
||||||
for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i)
|
NewMI->copyImplicitOps(MBBI);
|
||||||
NewMI->addOperand(MBBI->getOperand(i));
|
|
||||||
|
|
||||||
// Delete the pseudo instruction TCRETURN.
|
// Delete the pseudo instruction TCRETURN.
|
||||||
MBB.erase(MBBI);
|
MBB.erase(MBBI);
|
||||||
|
@ -12344,8 +12344,9 @@ X86TargetLowering::EmitLoweredSegAlloca(MachineInstr *MI, MachineBasicBlock *BB,
|
|||||||
BuildMI(mallocMBB, DL, TII->get(X86::MOV64rr), X86::RDI)
|
BuildMI(mallocMBB, DL, TII->get(X86::MOV64rr), X86::RDI)
|
||||||
.addReg(sizeVReg);
|
.addReg(sizeVReg);
|
||||||
BuildMI(mallocMBB, DL, TII->get(X86::CALL64pcrel32))
|
BuildMI(mallocMBB, DL, TII->get(X86::CALL64pcrel32))
|
||||||
.addExternalSymbol("__morestack_allocate_stack_space").addReg(X86::RDI)
|
.addExternalSymbol("__morestack_allocate_stack_space")
|
||||||
.addRegMask(RegMask)
|
.addRegMask(RegMask)
|
||||||
|
.addReg(X86::RDI, RegState::Implicit)
|
||||||
.addReg(X86::RAX, RegState::ImplicitDefine);
|
.addReg(X86::RAX, RegState::ImplicitDefine);
|
||||||
} else {
|
} else {
|
||||||
BuildMI(mallocMBB, DL, TII->get(X86::SUB32ri), physSPReg).addReg(physSPReg)
|
BuildMI(mallocMBB, DL, TII->get(X86::SUB32ri), physSPReg).addReg(physSPReg)
|
||||||
|
@ -18,16 +18,16 @@
|
|||||||
// Return instructions.
|
// Return instructions.
|
||||||
let isTerminator = 1, isReturn = 1, isBarrier = 1,
|
let isTerminator = 1, isReturn = 1, isBarrier = 1,
|
||||||
hasCtrlDep = 1, FPForm = SpecialFP in {
|
hasCtrlDep = 1, FPForm = SpecialFP in {
|
||||||
def RET : I <0xC3, RawFrm, (outs), (ins variable_ops),
|
def RET : I <0xC3, RawFrm, (outs), (ins),
|
||||||
"ret",
|
"ret",
|
||||||
[(X86retflag 0)], IIC_RET>;
|
[(X86retflag 0)], IIC_RET>;
|
||||||
def RETW : I <0xC3, RawFrm, (outs), (ins variable_ops),
|
def RETW : I <0xC3, RawFrm, (outs), (ins),
|
||||||
"ret{w}",
|
"ret{w}",
|
||||||
[], IIC_RET>, OpSize;
|
[], IIC_RET>, OpSize;
|
||||||
def RETI : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),
|
def RETI : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt),
|
||||||
"ret\t$amt",
|
"ret\t$amt",
|
||||||
[(X86retflag timm:$amt)], IIC_RET_IMM>;
|
[(X86retflag timm:$amt)], IIC_RET_IMM>;
|
||||||
def RETIW : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt, variable_ops),
|
def RETIW : Ii16<0xC2, RawFrm, (outs), (ins i16imm:$amt),
|
||||||
"ret{w}\t$amt",
|
"ret{w}\t$amt",
|
||||||
[], IIC_RET_IMM>, OpSize;
|
[], IIC_RET_IMM>, OpSize;
|
||||||
def LRETL : I <0xCB, RawFrm, (outs), (ins),
|
def LRETL : I <0xCB, RawFrm, (outs), (ins),
|
||||||
@ -148,12 +148,12 @@ let isCall = 1 in
|
|||||||
// registers are added manually.
|
// registers are added manually.
|
||||||
let Uses = [ESP] in {
|
let Uses = [ESP] in {
|
||||||
def CALLpcrel32 : Ii32PCRel<0xE8, RawFrm,
|
def CALLpcrel32 : Ii32PCRel<0xE8, RawFrm,
|
||||||
(outs), (ins i32imm_pcrel:$dst,variable_ops),
|
(outs), (ins i32imm_pcrel:$dst),
|
||||||
"call{l}\t$dst", [], IIC_CALL_RI>, Requires<[In32BitMode]>;
|
"call{l}\t$dst", [], IIC_CALL_RI>, Requires<[In32BitMode]>;
|
||||||
def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst, variable_ops),
|
def CALL32r : I<0xFF, MRM2r, (outs), (ins GR32:$dst),
|
||||||
"call{l}\t{*}$dst", [(X86call GR32:$dst)], IIC_CALL_RI>,
|
"call{l}\t{*}$dst", [(X86call GR32:$dst)], IIC_CALL_RI>,
|
||||||
Requires<[In32BitMode]>;
|
Requires<[In32BitMode]>;
|
||||||
def CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst, variable_ops),
|
def CALL32m : I<0xFF, MRM2m, (outs), (ins i32mem:$dst),
|
||||||
"call{l}\t{*}$dst", [(X86call (loadi32 addr:$dst))], IIC_CALL_MEM>,
|
"call{l}\t{*}$dst", [(X86call (loadi32 addr:$dst))], IIC_CALL_MEM>,
|
||||||
Requires<[In32BitMode]>;
|
Requires<[In32BitMode]>;
|
||||||
|
|
||||||
@ -174,7 +174,7 @@ let isCall = 1 in
|
|||||||
// callw for 16 bit code for the assembler.
|
// callw for 16 bit code for the assembler.
|
||||||
let isAsmParserOnly = 1 in
|
let isAsmParserOnly = 1 in
|
||||||
def CALLpcrel16 : Ii16PCRel<0xE8, RawFrm,
|
def CALLpcrel16 : Ii16PCRel<0xE8, RawFrm,
|
||||||
(outs), (ins i16imm_pcrel:$dst, variable_ops),
|
(outs), (ins i16imm_pcrel:$dst),
|
||||||
"callw\t$dst", []>, OpSize;
|
"callw\t$dst", []>, OpSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,23 +185,23 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
|
|||||||
isCodeGenOnly = 1 in
|
isCodeGenOnly = 1 in
|
||||||
let Uses = [ESP] in {
|
let Uses = [ESP] in {
|
||||||
def TCRETURNdi : PseudoI<(outs),
|
def TCRETURNdi : PseudoI<(outs),
|
||||||
(ins i32imm_pcrel:$dst, i32imm:$offset, variable_ops), []>;
|
(ins i32imm_pcrel:$dst, i32imm:$offset), []>;
|
||||||
def TCRETURNri : PseudoI<(outs),
|
def TCRETURNri : PseudoI<(outs),
|
||||||
(ins ptr_rc_tailcall:$dst, i32imm:$offset, variable_ops), []>;
|
(ins ptr_rc_tailcall:$dst, i32imm:$offset), []>;
|
||||||
let mayLoad = 1 in
|
let mayLoad = 1 in
|
||||||
def TCRETURNmi : PseudoI<(outs),
|
def TCRETURNmi : PseudoI<(outs),
|
||||||
(ins i32mem_TC:$dst, i32imm:$offset, variable_ops), []>;
|
(ins i32mem_TC:$dst, i32imm:$offset), []>;
|
||||||
|
|
||||||
// FIXME: The should be pseudo instructions that are lowered when going to
|
// FIXME: The should be pseudo instructions that are lowered when going to
|
||||||
// mcinst.
|
// mcinst.
|
||||||
def TAILJMPd : Ii32PCRel<0xE9, RawFrm, (outs),
|
def TAILJMPd : Ii32PCRel<0xE9, RawFrm, (outs),
|
||||||
(ins i32imm_pcrel:$dst, variable_ops),
|
(ins i32imm_pcrel:$dst),
|
||||||
"jmp\t$dst # TAILCALL",
|
"jmp\t$dst # TAILCALL",
|
||||||
[], IIC_JMP_REL>;
|
[], IIC_JMP_REL>;
|
||||||
def TAILJMPr : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst, variable_ops),
|
def TAILJMPr : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst),
|
||||||
"", [], IIC_JMP_REG>; // FIXME: Remove encoding when JIT is dead.
|
"", [], IIC_JMP_REG>; // FIXME: Remove encoding when JIT is dead.
|
||||||
let mayLoad = 1 in
|
let mayLoad = 1 in
|
||||||
def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem_TC:$dst, variable_ops),
|
def TAILJMPm : I<0xFF, MRM4m, (outs), (ins i32mem_TC:$dst),
|
||||||
"jmp{l}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>;
|
"jmp{l}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,14 +218,14 @@ let isCall = 1, Uses = [RSP] in {
|
|||||||
// that the offset between an arbitrary immediate and the call will fit in
|
// that the offset between an arbitrary immediate and the call will fit in
|
||||||
// the 32-bit pcrel field that we have.
|
// the 32-bit pcrel field that we have.
|
||||||
def CALL64pcrel32 : Ii32PCRel<0xE8, RawFrm,
|
def CALL64pcrel32 : Ii32PCRel<0xE8, RawFrm,
|
||||||
(outs), (ins i64i32imm_pcrel:$dst, variable_ops),
|
(outs), (ins i64i32imm_pcrel:$dst),
|
||||||
"call{q}\t$dst", [], IIC_CALL_RI>,
|
"call{q}\t$dst", [], IIC_CALL_RI>,
|
||||||
Requires<[In64BitMode]>;
|
Requires<[In64BitMode]>;
|
||||||
def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst, variable_ops),
|
def CALL64r : I<0xFF, MRM2r, (outs), (ins GR64:$dst),
|
||||||
"call{q}\t{*}$dst", [(X86call GR64:$dst)],
|
"call{q}\t{*}$dst", [(X86call GR64:$dst)],
|
||||||
IIC_CALL_RI>,
|
IIC_CALL_RI>,
|
||||||
Requires<[In64BitMode]>;
|
Requires<[In64BitMode]>;
|
||||||
def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst, variable_ops),
|
def CALL64m : I<0xFF, MRM2m, (outs), (ins i64mem:$dst),
|
||||||
"call{q}\t{*}$dst", [(X86call (loadi64 addr:$dst))],
|
"call{q}\t{*}$dst", [(X86call (loadi64 addr:$dst))],
|
||||||
IIC_CALL_MEM>,
|
IIC_CALL_MEM>,
|
||||||
Requires<[In64BitMode]>;
|
Requires<[In64BitMode]>;
|
||||||
@ -240,7 +240,7 @@ let isCall = 1, isCodeGenOnly = 1 in
|
|||||||
let Defs = [RAX, R10, R11, RSP, EFLAGS],
|
let Defs = [RAX, R10, R11, RSP, EFLAGS],
|
||||||
Uses = [RSP] in {
|
Uses = [RSP] in {
|
||||||
def W64ALLOCA : Ii32PCRel<0xE8, RawFrm,
|
def W64ALLOCA : Ii32PCRel<0xE8, RawFrm,
|
||||||
(outs), (ins i64i32imm_pcrel:$dst, variable_ops),
|
(outs), (ins i64i32imm_pcrel:$dst),
|
||||||
"call{q}\t$dst", [], IIC_CALL_RI>,
|
"call{q}\t$dst", [], IIC_CALL_RI>,
|
||||||
Requires<[IsWin64]>;
|
Requires<[IsWin64]>;
|
||||||
}
|
}
|
||||||
@ -250,21 +250,21 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1,
|
|||||||
let Uses = [RSP],
|
let Uses = [RSP],
|
||||||
usesCustomInserter = 1 in {
|
usesCustomInserter = 1 in {
|
||||||
def TCRETURNdi64 : PseudoI<(outs),
|
def TCRETURNdi64 : PseudoI<(outs),
|
||||||
(ins i64i32imm_pcrel:$dst, i32imm:$offset, variable_ops),
|
(ins i64i32imm_pcrel:$dst, i32imm:$offset),
|
||||||
[]>;
|
[]>;
|
||||||
def TCRETURNri64 : PseudoI<(outs),
|
def TCRETURNri64 : PseudoI<(outs),
|
||||||
(ins ptr_rc_tailcall:$dst, i32imm:$offset, variable_ops), []>;
|
(ins ptr_rc_tailcall:$dst, i32imm:$offset), []>;
|
||||||
let mayLoad = 1 in
|
let mayLoad = 1 in
|
||||||
def TCRETURNmi64 : PseudoI<(outs),
|
def TCRETURNmi64 : PseudoI<(outs),
|
||||||
(ins i64mem_TC:$dst, i32imm:$offset, variable_ops), []>;
|
(ins i64mem_TC:$dst, i32imm:$offset), []>;
|
||||||
|
|
||||||
def TAILJMPd64 : Ii32PCRel<0xE9, RawFrm, (outs),
|
def TAILJMPd64 : Ii32PCRel<0xE9, RawFrm, (outs),
|
||||||
(ins i64i32imm_pcrel:$dst, variable_ops),
|
(ins i64i32imm_pcrel:$dst),
|
||||||
"jmp\t$dst # TAILCALL", [], IIC_JMP_REL>;
|
"jmp\t$dst # TAILCALL", [], IIC_JMP_REL>;
|
||||||
def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst, variable_ops),
|
def TAILJMPr64 : I<0xFF, MRM4r, (outs), (ins ptr_rc_tailcall:$dst),
|
||||||
"jmp{q}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>;
|
"jmp{q}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>;
|
||||||
|
|
||||||
let mayLoad = 1 in
|
let mayLoad = 1 in
|
||||||
def TAILJMPm64 : I<0xFF, MRM4m, (outs), (ins i64mem_TC:$dst, variable_ops),
|
def TAILJMPm64 : I<0xFF, MRM4m, (outs), (ins i64mem_TC:$dst),
|
||||||
"jmp{q}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>;
|
"jmp{q}\t{*}$dst # TAILCALL", [], IIC_JMP_MEM>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user