Commit 0c68bef8 by David Sehr

Merge lowerCall and lowerRet between x86 and x64

BUG= R=jpp@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/1592033002 .
parent 29d15fd6
......@@ -58,9 +58,8 @@ protected:
void initSandbox() {}
void lowerIndirectJump(Variable *JumpTarget);
void lowerCall(const InstCall *Instr) override;
void lowerArguments() override;
void lowerRet(const InstRet *Inst) override;
Inst *emitCallToTarget(Operand *CallTarget, Variable *ReturnReg) override;
Variable *moveReturnValueToRegister(Operand *Value, Type ReturnType) override;
void addProlog(CfgNode *Node) override;
void addEpilog(CfgNode *Node) override;
......
......@@ -68,10 +68,11 @@ struct TargetX8632Traits {
using Cond = ::Ice::CondX86;
using RegisterSet = ::Ice::RegX8632;
static const SizeT StackPtr = RegX8632::Reg_esp;
static const SizeT FramePtr = RegX8632::Reg_ebp;
static const GPRRegister Encoded_Reg_Accumulator = RegX8632::Encoded_Reg_eax;
static const GPRRegister Encoded_Reg_Counter = RegX8632::Encoded_Reg_ecx;
static constexpr SizeT StackPtr = RegX8632::Reg_esp;
static constexpr SizeT FramePtr = RegX8632::Reg_ebp;
static constexpr GPRRegister Encoded_Reg_Accumulator =
RegX8632::Encoded_Reg_eax;
static constexpr GPRRegister Encoded_Reg_Counter = RegX8632::Encoded_Reg_ecx;
static constexpr FixupKind FK_PcRel = llvm::ELF::R_386_PC32;
static constexpr FixupKind FK_Abs = llvm::ELF::R_386_32;
static constexpr FixupKind FK_Gotoff = llvm::ELF::R_386_GOTOFF;
......@@ -658,21 +659,50 @@ public:
llvm::report_fatal_error("no rdx in non-64-bit mode.");
}
// x86-32 calling convention:
//
// * The first four arguments of vector type, regardless of their position
// relative to the other arguments in the argument list, are placed in
// registers xmm0 - xmm3.
//
// This intends to match the section "IA-32 Function Calling Convention" of
// the document "OS X ABI Function Call Guide" by Apple.
/// The maximum number of arguments to pass in XMM registers
static const uint32_t X86_MAX_XMM_ARGS = 4;
static constexpr uint32_t X86_MAX_XMM_ARGS = 4;
/// The maximum number of arguments to pass in GPR registers
static const uint32_t X86_MAX_GPR_ARGS = 0;
static constexpr uint32_t X86_MAX_GPR_ARGS = 0;
/// Whether scalar floating point arguments are passed in XMM registers
static constexpr bool X86_PASS_SCALAR_FP_IN_XMM = false;
/// Get the register for a given argument slot in the XMM registers.
static int32_t getRegisterForXmmArgNum(uint32_t ArgNum) {
// TODO(sehr): Change to use the CCArg technique used in ARM32.
static_assert(RegisterSet::Reg_xmm0 + 1 == RegisterSet::Reg_xmm1,
"Inconsistency between XMM register numbers and ordinals");
if (ArgNum >= X86_MAX_XMM_ARGS) {
return Variable::NoRegister;
}
return static_cast<int32_t>(RegisterSet::Reg_xmm0 + ArgNum);
}
/// Get the register for a given argument slot in the GPRs.
static int32_t getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) {
assert(Ty == IceType_i64 || Ty == IceType_i32);
(void)Ty;
(void)ArgNum;
return Variable::NoRegister;
}
/// The number of bits in a byte
static const uint32_t X86_CHAR_BIT = 8;
static constexpr uint32_t X86_CHAR_BIT = 8;
/// Stack alignment. This is defined in IceTargetLoweringX8632.cpp because it
/// is used as an argument to std::max(), and the default std::less<T> has an
/// operator(T const&, T const&) which requires this member to have an
/// address.
static const uint32_t X86_STACK_ALIGNMENT_BYTES;
/// Size of the return address on the stack
static const uint32_t X86_RET_IP_SIZE_BYTES = 4;
static constexpr uint32_t X86_RET_IP_SIZE_BYTES = 4;
/// The number of different NOP instructions
static const uint32_t X86_NUM_NOP_VARIANTS = 5;
static constexpr uint32_t X86_NUM_NOP_VARIANTS = 5;
/// \name Limits for unrolling memory intrinsics.
/// @{
......
......@@ -60,9 +60,8 @@ protected:
void initSandbox();
void lowerIndirectJump(Variable *JumpTarget);
void lowerCall(const InstCall *Instr) override;
void lowerArguments() override;
void lowerRet(const InstRet *Inst) override;
Inst *emitCallToTarget(Operand *CallTarget, Variable *ReturnReg) override;
Variable *moveReturnValueToRegister(Operand *Value, Type ReturnType) override;
void addProlog(CfgNode *Node) override;
void addEpilog(CfgNode *Node) override;
......
......@@ -68,10 +68,11 @@ struct TargetX8664Traits {
using Cond = ::Ice::CondX8664;
using RegisterSet = ::Ice::RegX8664;
static const SizeT StackPtr = RegX8664::Reg_rsp;
static const SizeT FramePtr = RegX8664::Reg_rbp;
static const GPRRegister Encoded_Reg_Accumulator = RegX8664::Encoded_Reg_eax;
static const GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx;
static constexpr SizeT StackPtr = RegX8664::Reg_rsp;
static constexpr SizeT FramePtr = RegX8664::Reg_rbp;
static constexpr GPRRegister Encoded_Reg_Accumulator =
RegX8664::Encoded_Reg_eax;
static constexpr GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx;
static constexpr FixupKind FK_PcRel = llvm::ELF::R_X86_64_PC32;
static constexpr FixupKind FK_Abs = llvm::ELF::R_X86_64_32;
static constexpr FixupKind FK_Gotoff = llvm::ELF::R_X86_64_GOTOFF64;
......@@ -715,21 +716,61 @@ public:
static int32_t getRdxOrDie() { return RegisterSet::Reg_rdx; }
// x86-64 calling convention:
//
// * The first eight arguments of vector/fp type, regardless of their
// position relative to the other arguments in the argument list, are placed
// in registers %xmm0 - %xmm7.
//
// * The first six arguments of integer types, regardless of their position
// relative to the other arguments in the argument list, are placed in
// registers %rdi, %rsi, %rdx, %rcx, %r8, and %r9.
//
// This intends to match the section "Function Calling Sequence" of the
// document "System V Application Binary Interface."
/// The maximum number of arguments to pass in XMM registers
static const uint32_t X86_MAX_XMM_ARGS = 8;
static constexpr uint32_t X86_MAX_XMM_ARGS = 8;
/// The maximum number of arguments to pass in GPR registers
static const uint32_t X86_MAX_GPR_ARGS = 6;
static constexpr uint32_t X86_MAX_GPR_ARGS = 6;
/// Whether scalar floating point arguments are passed in XMM registers
static constexpr bool X86_PASS_SCALAR_FP_IN_XMM = true;
/// Get the register for a given argument slot in the XMM registers.
static int32_t getRegisterForXmmArgNum(uint32_t ArgNum) {
// TODO(sehr): Change to use the CCArg technique used in ARM32.
static_assert(RegisterSet::Reg_xmm0 + 1 == RegisterSet::Reg_xmm1,
"Inconsistency between XMM register numbers and ordinals");
if (ArgNum >= X86_MAX_XMM_ARGS) {
return Variable::NoRegister;
}
return static_cast<int32_t>(RegisterSet::Reg_xmm0 + ArgNum);
}
/// Get the register for a given argument slot in the GPRs.
static int32_t getRegisterForGprArgNum(Type Ty, uint32_t ArgNum) {
if (ArgNum >= X86_MAX_GPR_ARGS) {
return Variable::NoRegister;
}
static const RegisterSet::AllRegisters GprForArgNum[] = {
RegisterSet::Reg_rdi, RegisterSet::Reg_rsi, RegisterSet::Reg_rdx,
RegisterSet::Reg_rcx, RegisterSet::Reg_r8, RegisterSet::Reg_r9,
};
static_assert(llvm::array_lengthof(GprForArgNum) == X86_MAX_GPR_ARGS,
"Mismatch between MAX_GPR_ARGS and GprForArgNum.");
assert(Ty == IceType_i64 || Ty == IceType_i32);
return static_cast<int32_t>(getGprForType(Ty, GprForArgNum[ArgNum]));
}
/// The number of bits in a byte
static const uint32_t X86_CHAR_BIT = 8;
static constexpr uint32_t X86_CHAR_BIT = 8;
/// Stack alignment. This is defined in IceTargetLoweringX8664.cpp because it
/// is used as an argument to std::max(), and the default std::less<T> has an
/// operator(T const&, T const&) which requires this member to have an
/// address.
static const uint32_t X86_STACK_ALIGNMENT_BYTES;
/// Size of the return address on the stack
static const uint32_t X86_RET_IP_SIZE_BYTES = 8;
static constexpr uint32_t X86_RET_IP_SIZE_BYTES = 8;
/// The number of different NOP instructions
static const uint32_t X86_NUM_NOP_VARIANTS = 5;
static constexpr uint32_t X86_NUM_NOP_VARIANTS = 5;
/// \name Limits for unrolling memory intrinsics.
/// @{
......
......@@ -197,9 +197,11 @@ protected:
}
void lowerAlloca(const InstAlloca *Inst) override;
void lowerArguments() override;
void lowerArithmetic(const InstArithmetic *Inst) override;
void lowerAssign(const InstAssign *Inst) override;
void lowerBr(const InstBr *Inst) override;
void lowerCall(const InstCall *Inst) override;
void lowerCast(const InstCast *Inst) override;
void lowerExtractElement(const InstExtractElement *Inst) override;
void lowerFcmp(const InstFcmp *Inst) override;
......@@ -209,6 +211,7 @@ protected:
void lowerInsertElement(const InstInsertElement *Inst) override;
void lowerLoad(const InstLoad *Inst) override;
void lowerPhi(const InstPhi *Inst) override;
void lowerRet(const InstRet *Inst) override;
void lowerSelect(const InstSelect *Inst) override;
void lowerStore(const InstStore *Inst) override;
void lowerSwitch(const InstSwitch *Inst) override;
......@@ -279,6 +282,13 @@ protected:
void scalarizeArithmetic(InstArithmetic::OpKind K, Variable *Dest,
Operand *Src0, Operand *Src1);
/// Emit just the call instruction (without argument or return variable
/// processing), sandboxing if needed.
virtual Inst *emitCallToTarget(Operand *CallTarget, Variable *ReturnReg) = 0;
/// Materialize the moves needed to return a value of the specified type.
virtual Variable *moveReturnValueToRegister(Operand *Value,
Type ReturnType) = 0;
/// Emit a fake use of esp to make sure esp stays alive for the entire
/// function. Otherwise some esp adjustments get dead-code eliminated.
void keepEspLiveAtExit() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment