Commit 5d0acff3 by John Porto

Move X8632-specific Assembler stuff to Machine Traits.

As part of the refactoring moves the MachineTraits<TargetX8632> to a separate header. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4077 R=jvoung@chromium.org Review URL: https://codereview.chromium.org/1216033004.
parent 7b60eb77
......@@ -175,7 +175,6 @@ SB_LDFLAGS := $(LINKOPTLEVEL) $(LD_EXTRA)
SRCS = \
IceAssembler.cpp \
IceAssemblerX8632.cpp \
IceAssemblerX8664.cpp \
IceBrowserCompileServer.cpp \
IceCfg.cpp \
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -19,28 +19,27 @@
namespace Ice {
namespace CondX8664 {
// An enum of condition codes used for branches and cmov. The enum value
// should match the value used to encode operands in binary instructions.
enum BrCond {
class CondX8664 {
// An enum of condition codes used for branches and cmov. The enum value
// should match the value used to encode operands in binary instructions.
enum BrCond {
#define X(tag, encode, opp, dump, emit) tag encode,
ICEINSTX8664BR_TABLE
ICEINSTX8664BR_TABLE
#undef X
Br_None
};
Br_None
};
// An enum of condition codes relevant to the CMPPS instruction. The enum
// value should match the value used to encode operands in binary
// instructions.
enum CmppsCond {
// An enum of condition codes relevant to the CMPPS instruction. The enum
// value should match the value used to encode operands in binary
// instructions.
enum CmppsCond {
#define X(tag, emit) tag,
ICEINSTX8664CMPPS_TABLE
ICEINSTX8664CMPPS_TABLE
#undef X
Cmpps_Invalid
Cmpps_Invalid
};
};
} // end of namespace CondX8664
} // end of namespace Ice
#endif // SUBZERO_SRC_ICECONDITIONCODESX8664_H
......@@ -22,6 +22,7 @@
#include "IceInst.h"
#include "IceInstX8632.def"
#include "IceOperand.h"
#include "IceTargetLoweringX8632Traits.h"
namespace Ice {
......@@ -76,7 +77,7 @@ public:
uint16_t getShift() const { return Shift; }
SegmentRegisters getSegmentRegister() const { return SegmentReg; }
void emitSegmentOverride(X8632::AssemblerX8632 *Asm) const;
X8632::Address toAsmAddress(Assembler *Asm) const;
X8632::Traits::Address toAsmAddress(Assembler *Asm) const;
void emit(const Cfg *Func) const override;
using OperandX8632::dump;
void dump(const Cfg *Func, Ostream &Str) const override;
......@@ -122,7 +123,7 @@ public:
}
int32_t getOffset() const { return Part == High ? 4 : 0; }
X8632::Address toAsmAddress(const Cfg *Func) const;
X8632::Traits::Address toAsmAddress(const Cfg *Func) const;
void emit(const Cfg *Func) const override;
using OperandX8632::dump;
void dump(const Cfg *Func, Ostream &Str) const override;
......@@ -279,7 +280,8 @@ public:
static const char *getWidthString(Type Ty);
static const char *getFldString(Type Ty);
static CondX86::BrCond getOppositeCondition(CondX86::BrCond Cond);
static X8632::Traits::Cond::BrCond
getOppositeCondition(X8632::Traits::Cond::BrCond Cond);
void dump(const Cfg *Func) const override;
// Shared emit routines for common forms of instructions.
......@@ -428,8 +430,9 @@ class InstX8632Br : public InstX8632 {
public:
// Create a conditional branch to a node.
static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
CfgNode *TargetFalse, CondX86::BrCond Condition) {
assert(Condition != CondX86::Br_None);
CfgNode *TargetFalse,
X8632::Traits::Cond::BrCond Condition) {
assert(Condition != X8632::Traits::Cond::Br_None);
const InstX8632Label *NoLabel = nullptr;
return new (Func->allocate<InstX8632Br>())
InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
......@@ -438,15 +441,15 @@ public:
static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
const CfgNode *NoCondTarget = nullptr;
const InstX8632Label *NoLabel = nullptr;
return new (Func->allocate<InstX8632Br>())
InstX8632Br(Func, NoCondTarget, Target, NoLabel, CondX86::Br_None);
return new (Func->allocate<InstX8632Br>()) InstX8632Br(
Func, NoCondTarget, Target, NoLabel, X8632::Traits::Cond::Br_None);
}
// Create a non-terminator conditional branch to a node, with a
// fallthrough to the next instruction in the current node. This is
// used for switch lowering.
static InstX8632Br *create(Cfg *Func, CfgNode *Target,
CondX86::BrCond Condition) {
assert(Condition != CondX86::Br_None);
X8632::Traits::Cond::BrCond Condition) {
assert(Condition != X8632::Traits::Cond::Br_None);
const CfgNode *NoUncondTarget = nullptr;
const InstX8632Label *NoLabel = nullptr;
return new (Func->allocate<InstX8632Br>())
......@@ -455,7 +458,7 @@ public:
// Create a conditional intra-block branch (or unconditional, if
// Condition==Br_None) to a label in the current block.
static InstX8632Br *create(Cfg *Func, InstX8632Label *Label,
CondX86::BrCond Condition) {
X8632::Traits::Cond::BrCond Condition) {
const CfgNode *NoCondTarget = nullptr;
const CfgNode *NoUncondTarget = nullptr;
return new (Func->allocate<InstX8632Br>())
......@@ -475,7 +478,7 @@ public:
return Sum;
}
bool isUnconditionalBranch() const override {
return !Label && Condition == CondX86::Br_None;
return !Label && Condition == X8632::Traits::Cond::Br_None;
}
bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
void emit(const Cfg *Func) const override;
......@@ -485,9 +488,10 @@ public:
private:
InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
const InstX8632Label *Label, CondX86::BrCond Condition);
const InstX8632Label *Label,
X8632::Traits::Cond::BrCond Condition);
CondX86::BrCond Condition;
X8632::Traits::Cond::BrCond Condition;
const CfgNode *TargetTrue;
const CfgNode *TargetFalse;
const InstX8632Label *Label; // Intra-block branch target
......@@ -1256,7 +1260,7 @@ class InstX8632Cmov : public InstX8632 {
public:
static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
CondX86::BrCond Cond) {
X8632::Traits::Cond::BrCond Cond) {
return new (Func->allocate<InstX8632Cmov>())
InstX8632Cmov(Func, Dest, Source, Cond);
}
......@@ -1267,9 +1271,9 @@ public:
private:
InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source,
CondX86::BrCond Cond);
X8632::Traits::Cond::BrCond Cond);
CondX86::BrCond Condition;
X8632::Traits::Cond::BrCond Condition;
};
// Cmpps instruction - compare packed singled-precision floating point
......@@ -1281,7 +1285,7 @@ class InstX8632Cmpps : public InstX8632 {
public:
static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
CondX86::CmppsCond Condition) {
X8632::Traits::Cond::CmppsCond Condition) {
return new (Func->allocate<InstX8632Cmpps>())
InstX8632Cmpps(Func, Dest, Source, Condition);
}
......@@ -1292,9 +1296,9 @@ public:
private:
InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source,
CondX86::CmppsCond Cond);
X8632::Traits::Cond::CmppsCond Cond);
CondX86::CmppsCond Condition;
X8632::Traits::Cond::CmppsCond Condition;
};
// Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
......@@ -1670,7 +1674,7 @@ class InstX8632Setcc : public InstX8632 {
public:
static InstX8632Setcc *create(Cfg *Func, Variable *Dest,
CondX86::BrCond Cond) {
X8632::Traits::Cond::BrCond Cond) {
return new (Func->allocate<InstX8632Setcc>())
InstX8632Setcc(Func, Dest, Cond);
}
......@@ -1680,9 +1684,9 @@ public:
static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); }
private:
InstX8632Setcc(Cfg *Func, Variable *Dest, CondX86::BrCond Cond);
InstX8632Setcc(Cfg *Func, Variable *Dest, X8632::Traits::Cond::BrCond Cond);
const CondX86::BrCond Condition;
const X8632::Traits::Cond::BrCond Condition;
};
// Exchanging Add instruction. Exchanges the first operand (destination
......
......@@ -20,93 +20,92 @@
namespace Ice {
namespace RegX8632 {
// An enum of every register. The enum value may not match the encoding
// used to binary encode register operands in instructions.
enum AllRegisters {
class RegX8632 {
public:
// An enum of every register. The enum value may not match the encoding
// used to binary encode register operands in instructions.
enum AllRegisters {
#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
frameptr, isI8, isInt, isFP) \
val,
REGX8632_TABLE
REGX8632_TABLE
#undef X
Reg_NUM,
Reg_NUM,
#define X(val, init) val init,
REGX8632_TABLE_BOUNDS
REGX8632_TABLE_BOUNDS
#undef X
};
};
// An enum of GPR Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum GPRRegister {
// An enum of GPR Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum GPRRegister {
#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
frameptr, isI8, isInt, isFP) \
Encoded_##val encode,
REGX8632_GPR_TABLE
REGX8632_GPR_TABLE
#undef X
Encoded_Not_GPR = -1
};
Encoded_Not_GPR = -1
};
// An enum of XMM Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum XmmRegister {
// An enum of XMM Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum XmmRegister {
#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
frameptr, isI8, isInt, isFP) \
Encoded_##val encode,
REGX8632_XMM_TABLE
REGX8632_XMM_TABLE
#undef X
Encoded_Not_Xmm = -1
};
Encoded_Not_Xmm = -1
};
// An enum of Byte Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum ByteRegister {
// An enum of Byte Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum ByteRegister {
#define X(val, encode) Encoded_##val encode,
REGX8632_BYTEREG_TABLE
REGX8632_BYTEREG_TABLE
#undef X
Encoded_Not_ByteReg = -1
};
Encoded_Not_ByteReg = -1
};
// An enum of X87 Stack Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum X87STRegister {
// An enum of X87 Stack Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum X87STRegister {
#define X(val, encode, name) Encoded_##val encode,
X87ST_REGX8632_TABLE
X87ST_REGX8632_TABLE
#undef X
Encoded_Not_X87STReg = -1
Encoded_Not_X87STReg = -1
};
static inline GPRRegister getEncodedGPR(int32_t RegNum) {
assert(Reg_GPR_First <= RegNum && RegNum <= Reg_GPR_Last);
return GPRRegister(RegNum - Reg_GPR_First);
}
static inline XmmRegister getEncodedXmm(int32_t RegNum) {
assert(Reg_XMM_First <= RegNum && RegNum <= Reg_XMM_Last);
return XmmRegister(RegNum - Reg_XMM_First);
}
static inline ByteRegister getEncodedByteReg(int32_t RegNum) {
assert(RegNum == Reg_ah || (Reg_GPR_First <= RegNum && RegNum <= Reg_ebx));
if (RegNum == Reg_ah)
return Encoded_Reg_ah;
return ByteRegister(RegNum - Reg_GPR_First);
}
static inline GPRRegister getEncodedByteRegOrGPR(Type Ty, int32_t RegNum) {
if (isByteSizedType(Ty))
return GPRRegister(getEncodedByteReg(RegNum));
else
return getEncodedGPR(RegNum);
}
static inline X87STRegister getEncodedSTReg(int32_t RegNum) {
assert(Encoded_X87ST_First <= RegNum && RegNum <= Encoded_X87ST_Last);
return X87STRegister(RegNum);
}
};
static inline GPRRegister getEncodedGPR(int32_t RegNum) {
assert(Reg_GPR_First <= RegNum && RegNum <= Reg_GPR_Last);
return GPRRegister(RegNum - Reg_GPR_First);
}
static inline XmmRegister getEncodedXmm(int32_t RegNum) {
assert(Reg_XMM_First <= RegNum && RegNum <= Reg_XMM_Last);
return XmmRegister(RegNum - Reg_XMM_First);
}
static inline ByteRegister getEncodedByteReg(int32_t RegNum) {
assert(RegNum == Reg_ah || (Reg_GPR_First <= RegNum && RegNum <= Reg_ebx));
if (RegNum == Reg_ah)
return Encoded_Reg_ah;
return ByteRegister(RegNum - Reg_GPR_First);
}
static inline GPRRegister getEncodedByteRegOrGPR(Type Ty, int32_t RegNum) {
if (isByteSizedType(Ty))
return GPRRegister(getEncodedByteReg(RegNum));
else
return getEncodedGPR(RegNum);
}
static inline X87STRegister getEncodedSTReg(int32_t RegNum) {
assert(Encoded_X87ST_First <= RegNum && RegNum <= Encoded_X87ST_Last);
return X87STRegister(RegNum);
}
} // end of namespace RegX8632
} // end of namespace Ice
#endif // SUBZERO_SRC_ICEREGISTERSX8632_H
......@@ -20,79 +20,78 @@
namespace Ice {
namespace RegX8664 {
// An enum of every register. The enum value may not match the encoding
// used to binary encode register operands in instructions.
enum AllRegisters {
class RegX8664 {
public:
// An enum of every register. The enum value may not match the encoding
// used to binary encode register operands in instructions.
enum AllRegisters {
#define X(val, encode, name64, name, name16, name8, scratch, preserved, \
stackptr, frameptr, isInt, isFP) \
val,
REGX8664_TABLE
REGX8664_TABLE
#undef X
Reg_NUM,
Reg_NUM,
#define X(val, init) val init,
REGX8664_TABLE_BOUNDS
REGX8664_TABLE_BOUNDS
#undef X
};
};
// An enum of GPR Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum GPRRegister {
// An enum of GPR Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum GPRRegister {
#define X(val, encode, name64, name, name16, name8, scratch, preserved, \
stackptr, frameptr, isInt, isFP) \
Encoded_##val encode,
REGX8664_GPR_TABLE
REGX8664_GPR_TABLE
#undef X
Encoded_Not_GPR = -1
};
Encoded_Not_GPR = -1
};
// An enum of XMM Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum XmmRegister {
// An enum of XMM Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum XmmRegister {
#define X(val, encode, name64, name, name16, name8, scratch, preserved, \
stackptr, frameptr, isInt, isFP) \
Encoded_##val encode,
REGX8664_XMM_TABLE
REGX8664_XMM_TABLE
#undef X
Encoded_Not_Xmm = -1
};
Encoded_Not_Xmm = -1
};
// An enum of Byte Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum ByteRegister {
// An enum of Byte Registers. The enum value does match the encoding used
// to binary encode register operands in instructions.
enum ByteRegister {
#define X(val, encode) Encoded_##val encode,
REGX8664_BYTEREG_TABLE
REGX8664_BYTEREG_TABLE
#undef X
Encoded_Not_ByteReg = -1
};
static inline GPRRegister getEncodedGPR(int32_t RegNum) {
assert(Reg_GPR_First <= RegNum && RegNum <= Reg_GPR_Last);
return GPRRegister(RegNum - Reg_GPR_First);
}
Encoded_Not_ByteReg = -1
};
static inline XmmRegister getEncodedXmm(int32_t RegNum) {
assert(Reg_XMM_First <= RegNum && RegNum <= Reg_XMM_Last);
return XmmRegister(RegNum - Reg_XMM_First);
}
static inline GPRRegister getEncodedGPR(int32_t RegNum) {
assert(Reg_GPR_First <= RegNum && RegNum <= Reg_GPR_Last);
return GPRRegister(RegNum - Reg_GPR_First);
}
static inline ByteRegister getEncodedByteReg(int32_t RegNum) {
// In x86-64, AH is not encodable when the REX prefix is used; the same
// encoding is used for spl. Therefore, ah needs special handling.
if (RegNum == Reg_ah)
return Encoded_Reg_spl;
return ByteRegister(RegNum - Reg_GPR_First);
}
static inline XmmRegister getEncodedXmm(int32_t RegNum) {
assert(Reg_XMM_First <= RegNum && RegNum <= Reg_XMM_Last);
return XmmRegister(RegNum - Reg_XMM_First);
}
static inline GPRRegister getEncodedByteRegOrGPR(Type Ty, int32_t RegNum) {
if (isByteSizedType(Ty))
return GPRRegister(getEncodedByteReg(RegNum));
else
return getEncodedGPR(RegNum);
}
static inline ByteRegister getEncodedByteReg(int32_t RegNum) {
// In x86-64, AH is not encodable when the REX prefix is used; the same
// encoding is used for spl. Therefore, ah needs special handling.
if (RegNum == Reg_ah)
return Encoded_Reg_spl;
return ByteRegister(RegNum - Reg_GPR_First);
}
} // end of namespace RegX8664
static inline GPRRegister getEncodedByteRegOrGPR(Type Ty, int32_t RegNum) {
if (isByteSizedType(Ty))
return GPRRegister(getEncodedByteReg(RegNum));
else
return getEncodedGPR(RegNum);
}
};
} // end of namespace Ice
......
......@@ -2,6 +2,9 @@
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the TargetLoweringX8632 class, which
......@@ -12,100 +15,19 @@
#include "IceTargetLoweringX8632.h"
#include "IceTargetLoweringX8632Traits.h"
#include "IceTargetLoweringX86Base.h"
namespace Ice {
namespace X86Internal {
template <> struct MachineTraits<TargetX8632> {
using InstructionSet = TargetX8632::X86InstructionSet;
// The following table summarizes the logic for lowering the fcmp
// instruction. There is one table entry for each of the 16 conditions.
//
// The first four columns describe the case when the operands are
// floating point scalar values. A comment in lowerFcmp() describes the
// lowering template. In the most general case, there is a compare
// followed by two conditional branches, because some fcmp conditions
// don't map to a single x86 conditional branch. However, in many cases
// it is possible to swap the operands in the comparison and have a
// single conditional branch. Since it's quite tedious to validate the
// table by hand, good execution tests are helpful.
//
// The last two columns describe the case when the operands are vectors
// of floating point values. For most fcmp conditions, there is a clear
// mapping to a single x86 cmpps instruction variant. Some fcmp
// conditions require special code to handle and these are marked in the
// table with a Cmpps_Invalid predicate.
static const struct TableFcmpType {
uint32_t Default;
bool SwapScalarOperands;
CondX86::BrCond C1, C2;
bool SwapVectorOperands;
CondX86::CmppsCond Predicate;
} TableFcmp[];
static const size_t TableFcmpSize;
// The following table summarizes the logic for lowering the icmp instruction
// for i32 and narrower types. Each icmp condition has a clear mapping to an
// x86 conditional branch instruction.
static const struct TableIcmp32Type {
CondX86::BrCond Mapping;
} TableIcmp32[];
static const size_t TableIcmp32Size;
// The following table summarizes the logic for lowering the icmp instruction
// for the i64 type. For Eq and Ne, two separate 32-bit comparisons and
// conditional branches are needed. For the other conditions, three separate
// conditional branches are needed.
static const struct TableIcmp64Type {
CondX86::BrCond C1, C2, C3;
} TableIcmp64[];
static const size_t TableIcmp64Size;
static CondX86::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) {
size_t Index = static_cast<size_t>(Cond);
assert(Index < TableIcmp32Size);
return TableIcmp32[Index].Mapping;
}
static const struct TableTypeX8632AttributesType {
Type InVectorElementType;
} TableTypeX8632Attributes[];
static const size_t TableTypeX8632AttributesSize;
// Return the type which the elements of the vector have in the X86
// representation of the vector.
static Type getInVectorElementType(Type Ty) {
assert(isVectorType(Ty));
size_t Index = static_cast<size_t>(Ty);
(void)Index;
assert(Index < TableTypeX8632AttributesSize);
return TableTypeX8632Attributes[Ty].InVectorElementType;
}
// The maximum number of arguments to pass in XMM registers
static const uint32_t X86_MAX_XMM_ARGS = 4;
// The number of bits in a byte
static const uint32_t X86_CHAR_BIT = 8;
// Stack alignment
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;
// The number of different NOP instructions
static const uint32_t X86_NUM_NOP_VARIANTS = 5;
// Value is in bytes. Return Value adjusted to the next highest multiple
// of the stack alignment.
static uint32_t applyStackAlignment(uint32_t Value) {
return Utils::applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES);
}
};
namespace X86Internal {
const MachineTraits<TargetX8632>::TableFcmpType
MachineTraits<TargetX8632>::TableFcmp[] = {
#define X(val, dflt, swapS, C1, C2, swapV, pred) \
{ dflt, swapS, CondX86::C1, CondX86::C2, swapV, CondX86::pred } \
{ \
dflt, swapS, X8632::Traits::Cond::C1, X8632::Traits::Cond::C2, swapV, \
X8632::Traits::Cond::pred \
} \
,
FCMPX8632_TABLE
#undef X
......@@ -117,7 +39,7 @@ const size_t MachineTraits<TargetX8632>::TableFcmpSize =
const MachineTraits<TargetX8632>::TableIcmp32Type
MachineTraits<TargetX8632>::TableIcmp32[] = {
#define X(val, C_32, C1_64, C2_64, C3_64) \
{ CondX86::C_32 } \
{ X8632::Traits::Cond::C_32 } \
,
ICMPX8632_TABLE
#undef X
......@@ -129,7 +51,10 @@ const size_t MachineTraits<TargetX8632>::TableIcmp32Size =
const MachineTraits<TargetX8632>::TableIcmp64Type
MachineTraits<TargetX8632>::TableIcmp64[] = {
#define X(val, C_32, C1_64, C2_64, C3_64) \
{ CondX86::C1_64, CondX86::C2_64, CondX86::C3_64 } \
{ \
X8632::Traits::Cond::C1_64, X8632::Traits::Cond::C2_64, \
X8632::Traits::Cond::C3_64 \
} \
,
ICMPX8632_TABLE
#undef X
......@@ -151,6 +76,7 @@ const size_t MachineTraits<TargetX8632>::TableTypeX8632AttributesSize =
llvm::array_lengthof(TableTypeX8632Attributes);
const uint32_t MachineTraits<TargetX8632>::X86_STACK_ALIGNMENT_BYTES = 16;
} // end of namespace X86Internal
TargetX8632 *TargetX8632::create(Cfg *Func) {
......
......@@ -21,6 +21,7 @@
#include "IceInstX8632.h"
#include "IceRegistersX8632.h"
#include "IceTargetLowering.h"
#include "IceTargetLoweringX8632Traits.h"
namespace Ice {
......@@ -30,16 +31,11 @@ class TargetX8632 : public TargetLowering {
TargetX8632 &operator=(const TargetX8632 &) = delete;
public:
enum X86InstructionSet {
Begin,
// SSE2 is the PNaCl baseline instruction set.
SSE2 = Begin,
SSE4_1,
End
};
using X86InstructionSet = X8632::Traits::InstructionSet;
static TargetX8632 *create(Cfg *Func);
virtual X8632::Address stackVarToAsmOperand(const Variable *Var) const = 0;
virtual X8632::Traits::Address
stackVarToAsmOperand(const Variable *Var) const = 0;
virtual X86InstructionSet getInstructionSet() const = 0;
protected:
......
......@@ -107,7 +107,9 @@ public:
void doLoadOpt();
bool doBranchOpt(Inst *I, const CfgNode *NextNode) override;
SizeT getNumRegisters() const override { return RegX8632::Reg_NUM; }
SizeT getNumRegisters() const override {
return Traits::RegisterSet::Reg_NUM;
}
Variable *getPhysicalRegister(SizeT RegNum, Type Ty = IceType_void) override;
IceString getRegName(SizeT RegNum, Type Ty) const override;
llvm::SmallBitVector getRegisterSet(RegSetMask Include,
......@@ -117,7 +119,8 @@ public:
}
bool hasFramePointer() const override { return IsEbpBasedFrame; }
SizeT getFrameOrStackReg() const override {
return IsEbpBasedFrame ? RegX8632::Reg_ebp : RegX8632::Reg_esp;
return IsEbpBasedFrame ? Traits::RegisterSet::Reg_ebp
: Traits::RegisterSet::Reg_esp;
}
size_t typeWidthInBytesOnStack(Type Ty) const override {
// Round up to the next multiple of 4 bytes. In particular, i1,
......@@ -148,7 +151,8 @@ public:
Operand *hiOperand(Operand *Operand);
void finishArgumentLowering(Variable *Arg, Variable *FramePtr,
size_t BasicFrameOffset, size_t &InArgsSizeBytes);
X8632::Address stackVarToAsmOperand(const Variable *Var) const final;
typename Traits::Address
stackVarToAsmOperand(const Variable *Var) const final;
typename Traits::InstructionSet getInstructionSet() const final {
return InstructionSet;
......@@ -255,6 +259,7 @@ protected:
llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters) const override;
// TODO(jpp): move the helper methods below to the MachineTraits.
// The following are helpers that insert lowered x86 instructions
// with minimal syntactic overhead, so that the lowering code can
// look as close to assembly as practical.
......@@ -272,7 +277,7 @@ protected:
}
void _adjust_stack(int32_t Amount) {
Context.insert(InstX8632AdjustStack::create(
Func, Amount, getPhysicalRegister(RegX8632::Reg_esp)));
Func, Amount, getPhysicalRegister(Traits::RegisterSet::Reg_esp)));
}
void _addps(Variable *Dest, Operand *Src0) {
Context.insert(InstX8632Addps::create(Func, Dest, Src0));
......@@ -289,7 +294,7 @@ protected:
void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, Src1));
}
void _br(CondX86::BrCond Condition, CfgNode *TargetTrue,
void _br(typename Traits::Cond::BrCond Condition, CfgNode *TargetTrue,
CfgNode *TargetFalse) {
Context.insert(
InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition));
......@@ -297,10 +302,10 @@ protected:
void _br(CfgNode *Target) {
Context.insert(InstX8632Br::create(Func, Target));
}
void _br(CondX86::BrCond Condition, CfgNode *Target) {
void _br(typename Traits::Cond::BrCond Condition, CfgNode *Target) {
Context.insert(InstX8632Br::create(Func, Target, Condition));
}
void _br(CondX86::BrCond Condition, InstX8632Label *Label) {
void _br(typename Traits::Cond::BrCond Condition, InstX8632Label *Label) {
Context.insert(InstX8632Br::create(Func, Label, Condition));
}
void _bsf(Variable *Dest, Operand *Src0) {
......@@ -315,13 +320,15 @@ protected:
void _cbwdq(Variable *Dest, Operand *Src0) {
Context.insert(InstX8632Cbwdq::create(Func, Dest, Src0));
}
void _cmov(Variable *Dest, Operand *Src0, CondX86::BrCond Condition) {
void _cmov(Variable *Dest, Operand *Src0,
typename Traits::Cond::BrCond Condition) {
Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition));
}
void _cmp(Operand *Src0, Operand *Src1) {
Context.insert(InstX8632Icmp::create(Func, Src0, Src1));
}
void _cmpps(Variable *Dest, Operand *Src0, CondX86::CmppsCond Condition) {
void _cmpps(Variable *Dest, Operand *Src0,
typename Traits::Cond::CmppsCond Condition) {
Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition));
}
void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired,
......@@ -503,7 +510,7 @@ protected:
void _sbb_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
Context.insert(InstX8632SbbRMW::create(Func, DestSrc0, Src1));
}
void _setcc(Variable *Dest, CondX86::BrCond Condition) {
void _setcc(Variable *Dest, typename Traits::Cond::BrCond Condition) {
Context.insert(InstX8632Setcc::create(Func, Dest, Condition));
}
void _shl(Variable *Dest, Operand *Src0) {
......
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