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) ...@@ -175,7 +175,6 @@ SB_LDFLAGS := $(LINKOPTLEVEL) $(LD_EXTRA)
SRCS = \ SRCS = \
IceAssembler.cpp \ IceAssembler.cpp \
IceAssemblerX8632.cpp \
IceAssemblerX8664.cpp \ IceAssemblerX8664.cpp \
IceBrowserCompileServer.cpp \ IceBrowserCompileServer.cpp \
IceCfg.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 @@ ...@@ -19,28 +19,27 @@
namespace Ice { namespace Ice {
namespace CondX8664 { class CondX8664 {
// An enum of condition codes used for branches and cmov. The enum value // An enum of condition codes used for branches and cmov. The enum value
// should match the value used to encode operands in binary instructions. // should match the value used to encode operands in binary instructions.
enum BrCond { enum BrCond {
#define X(tag, encode, opp, dump, emit) tag encode, #define X(tag, encode, opp, dump, emit) tag encode,
ICEINSTX8664BR_TABLE ICEINSTX8664BR_TABLE
#undef X #undef X
Br_None Br_None
}; };
// An enum of condition codes relevant to the CMPPS instruction. The enum // An enum of condition codes relevant to the CMPPS instruction. The enum
// value should match the value used to encode operands in binary // value should match the value used to encode operands in binary
// instructions. // instructions.
enum CmppsCond { enum CmppsCond {
#define X(tag, emit) tag, #define X(tag, emit) tag,
ICEINSTX8664CMPPS_TABLE ICEINSTX8664CMPPS_TABLE
#undef X #undef X
Cmpps_Invalid Cmpps_Invalid
};
}; };
} // end of namespace CondX8664
} // end of namespace Ice } // end of namespace Ice
#endif // SUBZERO_SRC_ICECONDITIONCODESX8664_H #endif // SUBZERO_SRC_ICECONDITIONCODESX8664_H
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "IceInst.h" #include "IceInst.h"
#include "IceInstX8632.def" #include "IceInstX8632.def"
#include "IceOperand.h" #include "IceOperand.h"
#include "IceTargetLoweringX8632Traits.h"
namespace Ice { namespace Ice {
...@@ -76,7 +77,7 @@ public: ...@@ -76,7 +77,7 @@ public:
uint16_t getShift() const { return Shift; } uint16_t getShift() const { return Shift; }
SegmentRegisters getSegmentRegister() const { return SegmentReg; } SegmentRegisters getSegmentRegister() const { return SegmentReg; }
void emitSegmentOverride(X8632::AssemblerX8632 *Asm) const; 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; void emit(const Cfg *Func) const override;
using OperandX8632::dump; using OperandX8632::dump;
void dump(const Cfg *Func, Ostream &Str) const override; void dump(const Cfg *Func, Ostream &Str) const override;
...@@ -122,7 +123,7 @@ public: ...@@ -122,7 +123,7 @@ public:
} }
int32_t getOffset() const { return Part == High ? 4 : 0; } 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; void emit(const Cfg *Func) const override;
using OperandX8632::dump; using OperandX8632::dump;
void dump(const Cfg *Func, Ostream &Str) const override; void dump(const Cfg *Func, Ostream &Str) const override;
...@@ -279,7 +280,8 @@ public: ...@@ -279,7 +280,8 @@ public:
static const char *getWidthString(Type Ty); static const char *getWidthString(Type Ty);
static const char *getFldString(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; void dump(const Cfg *Func) const override;
// Shared emit routines for common forms of instructions. // Shared emit routines for common forms of instructions.
...@@ -428,8 +430,9 @@ class InstX8632Br : public InstX8632 { ...@@ -428,8 +430,9 @@ class InstX8632Br : public InstX8632 {
public: public:
// Create a conditional branch to a node. // Create a conditional branch to a node.
static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue, static InstX8632Br *create(Cfg *Func, CfgNode *TargetTrue,
CfgNode *TargetFalse, CondX86::BrCond Condition) { CfgNode *TargetFalse,
assert(Condition != CondX86::Br_None); X8632::Traits::Cond::BrCond Condition) {
assert(Condition != X8632::Traits::Cond::Br_None);
const InstX8632Label *NoLabel = nullptr; const InstX8632Label *NoLabel = nullptr;
return new (Func->allocate<InstX8632Br>()) return new (Func->allocate<InstX8632Br>())
InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition); InstX8632Br(Func, TargetTrue, TargetFalse, NoLabel, Condition);
...@@ -438,15 +441,15 @@ public: ...@@ -438,15 +441,15 @@ public:
static InstX8632Br *create(Cfg *Func, CfgNode *Target) { static InstX8632Br *create(Cfg *Func, CfgNode *Target) {
const CfgNode *NoCondTarget = nullptr; const CfgNode *NoCondTarget = nullptr;
const InstX8632Label *NoLabel = nullptr; const InstX8632Label *NoLabel = nullptr;
return new (Func->allocate<InstX8632Br>()) return new (Func->allocate<InstX8632Br>()) InstX8632Br(
InstX8632Br(Func, NoCondTarget, Target, NoLabel, CondX86::Br_None); Func, NoCondTarget, Target, NoLabel, X8632::Traits::Cond::Br_None);
} }
// Create a non-terminator conditional branch to a node, with a // Create a non-terminator conditional branch to a node, with a
// fallthrough to the next instruction in the current node. This is // fallthrough to the next instruction in the current node. This is
// used for switch lowering. // used for switch lowering.
static InstX8632Br *create(Cfg *Func, CfgNode *Target, static InstX8632Br *create(Cfg *Func, CfgNode *Target,
CondX86::BrCond Condition) { X8632::Traits::Cond::BrCond Condition) {
assert(Condition != CondX86::Br_None); assert(Condition != X8632::Traits::Cond::Br_None);
const CfgNode *NoUncondTarget = nullptr; const CfgNode *NoUncondTarget = nullptr;
const InstX8632Label *NoLabel = nullptr; const InstX8632Label *NoLabel = nullptr;
return new (Func->allocate<InstX8632Br>()) return new (Func->allocate<InstX8632Br>())
...@@ -455,7 +458,7 @@ public: ...@@ -455,7 +458,7 @@ public:
// Create a conditional intra-block branch (or unconditional, if // Create a conditional intra-block branch (or unconditional, if
// Condition==Br_None) to a label in the current block. // Condition==Br_None) to a label in the current block.
static InstX8632Br *create(Cfg *Func, InstX8632Label *Label, static InstX8632Br *create(Cfg *Func, InstX8632Label *Label,
CondX86::BrCond Condition) { X8632::Traits::Cond::BrCond Condition) {
const CfgNode *NoCondTarget = nullptr; const CfgNode *NoCondTarget = nullptr;
const CfgNode *NoUncondTarget = nullptr; const CfgNode *NoUncondTarget = nullptr;
return new (Func->allocate<InstX8632Br>()) return new (Func->allocate<InstX8632Br>())
...@@ -475,7 +478,7 @@ public: ...@@ -475,7 +478,7 @@ public:
return Sum; return Sum;
} }
bool isUnconditionalBranch() const override { 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; bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
void emit(const Cfg *Func) const override; void emit(const Cfg *Func) const override;
...@@ -485,9 +488,10 @@ public: ...@@ -485,9 +488,10 @@ public:
private: private:
InstX8632Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, 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 *TargetTrue;
const CfgNode *TargetFalse; const CfgNode *TargetFalse;
const InstX8632Label *Label; // Intra-block branch target const InstX8632Label *Label; // Intra-block branch target
...@@ -1256,7 +1260,7 @@ class InstX8632Cmov : public InstX8632 { ...@@ -1256,7 +1260,7 @@ class InstX8632Cmov : public InstX8632 {
public: public:
static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source, static InstX8632Cmov *create(Cfg *Func, Variable *Dest, Operand *Source,
CondX86::BrCond Cond) { X8632::Traits::Cond::BrCond Cond) {
return new (Func->allocate<InstX8632Cmov>()) return new (Func->allocate<InstX8632Cmov>())
InstX8632Cmov(Func, Dest, Source, Cond); InstX8632Cmov(Func, Dest, Source, Cond);
} }
...@@ -1267,9 +1271,9 @@ public: ...@@ -1267,9 +1271,9 @@ public:
private: private:
InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, 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 // Cmpps instruction - compare packed singled-precision floating point
...@@ -1281,7 +1285,7 @@ class InstX8632Cmpps : public InstX8632 { ...@@ -1281,7 +1285,7 @@ class InstX8632Cmpps : public InstX8632 {
public: public:
static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source, static InstX8632Cmpps *create(Cfg *Func, Variable *Dest, Operand *Source,
CondX86::CmppsCond Condition) { X8632::Traits::Cond::CmppsCond Condition) {
return new (Func->allocate<InstX8632Cmpps>()) return new (Func->allocate<InstX8632Cmpps>())
InstX8632Cmpps(Func, Dest, Source, Condition); InstX8632Cmpps(Func, Dest, Source, Condition);
} }
...@@ -1292,9 +1296,9 @@ public: ...@@ -1292,9 +1296,9 @@ public:
private: private:
InstX8632Cmpps(Cfg *Func, Variable *Dest, Operand *Source, 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> // Cmpxchg instruction - cmpxchg <dest>, <desired> will compare if <dest>
...@@ -1670,7 +1674,7 @@ class InstX8632Setcc : public InstX8632 { ...@@ -1670,7 +1674,7 @@ class InstX8632Setcc : public InstX8632 {
public: public:
static InstX8632Setcc *create(Cfg *Func, Variable *Dest, static InstX8632Setcc *create(Cfg *Func, Variable *Dest,
CondX86::BrCond Cond) { X8632::Traits::Cond::BrCond Cond) {
return new (Func->allocate<InstX8632Setcc>()) return new (Func->allocate<InstX8632Setcc>())
InstX8632Setcc(Func, Dest, Cond); InstX8632Setcc(Func, Dest, Cond);
} }
...@@ -1680,9 +1684,9 @@ public: ...@@ -1680,9 +1684,9 @@ public:
static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); } static bool classof(const Inst *Inst) { return isClassof(Inst, Setcc); }
private: 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 // Exchanging Add instruction. Exchanges the first operand (destination
......
...@@ -20,93 +20,92 @@ ...@@ -20,93 +20,92 @@
namespace Ice { namespace Ice {
namespace RegX8632 { class RegX8632 {
public:
// An enum of every register. The enum value may not match the encoding // An enum of every register. The enum value may not match the encoding
// used to binary encode register operands in instructions. // used to binary encode register operands in instructions.
enum AllRegisters { enum AllRegisters {
#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
frameptr, isI8, isInt, isFP) \ frameptr, isI8, isInt, isFP) \
val, val,
REGX8632_TABLE REGX8632_TABLE
#undef X #undef X
Reg_NUM, Reg_NUM,
#define X(val, init) val init, #define X(val, init) val init,
REGX8632_TABLE_BOUNDS REGX8632_TABLE_BOUNDS
#undef X #undef X
}; };
// An enum of GPR Registers. The enum value does match the encoding used // An enum of GPR Registers. The enum value does match the encoding used
// to binary encode register operands in instructions. // to binary encode register operands in instructions.
enum GPRRegister { enum GPRRegister {
#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
frameptr, isI8, isInt, isFP) \ frameptr, isI8, isInt, isFP) \
Encoded_##val encode, Encoded_##val encode,
REGX8632_GPR_TABLE REGX8632_GPR_TABLE
#undef X #undef X
Encoded_Not_GPR = -1 Encoded_Not_GPR = -1
}; };
// An enum of XMM Registers. The enum value does match the encoding used // An enum of XMM Registers. The enum value does match the encoding used
// to binary encode register operands in instructions. // to binary encode register operands in instructions.
enum XmmRegister { enum XmmRegister {
#define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \ #define X(val, encode, name, name16, name8, scratch, preserved, stackptr, \
frameptr, isI8, isInt, isFP) \ frameptr, isI8, isInt, isFP) \
Encoded_##val encode, Encoded_##val encode,
REGX8632_XMM_TABLE REGX8632_XMM_TABLE
#undef X #undef X
Encoded_Not_Xmm = -1 Encoded_Not_Xmm = -1
}; };
// An enum of Byte Registers. The enum value does match the encoding used // An enum of Byte Registers. The enum value does match the encoding used
// to binary encode register operands in instructions. // to binary encode register operands in instructions.
enum ByteRegister { enum ByteRegister {
#define X(val, encode) Encoded_##val encode, #define X(val, encode) Encoded_##val encode,
REGX8632_BYTEREG_TABLE REGX8632_BYTEREG_TABLE
#undef X #undef X
Encoded_Not_ByteReg = -1 Encoded_Not_ByteReg = -1
}; };
// An enum of X87 Stack Registers. The enum value does match the encoding used // An enum of X87 Stack Registers. The enum value does match the encoding used
// to binary encode register operands in instructions. // to binary encode register operands in instructions.
enum X87STRegister { enum X87STRegister {
#define X(val, encode, name) Encoded_##val encode, #define X(val, encode, name) Encoded_##val encode,
X87ST_REGX8632_TABLE X87ST_REGX8632_TABLE
#undef X #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 } // end of namespace Ice
#endif // SUBZERO_SRC_ICEREGISTERSX8632_H #endif // SUBZERO_SRC_ICEREGISTERSX8632_H
...@@ -20,79 +20,78 @@ ...@@ -20,79 +20,78 @@
namespace Ice { namespace Ice {
namespace RegX8664 { class RegX8664 {
public:
// An enum of every register. The enum value may not match the encoding // An enum of every register. The enum value may not match the encoding
// used to binary encode register operands in instructions. // used to binary encode register operands in instructions.
enum AllRegisters { enum AllRegisters {
#define X(val, encode, name64, name, name16, name8, scratch, preserved, \ #define X(val, encode, name64, name, name16, name8, scratch, preserved, \
stackptr, frameptr, isInt, isFP) \ stackptr, frameptr, isInt, isFP) \
val, val,
REGX8664_TABLE REGX8664_TABLE
#undef X #undef X
Reg_NUM, Reg_NUM,
#define X(val, init) val init, #define X(val, init) val init,
REGX8664_TABLE_BOUNDS REGX8664_TABLE_BOUNDS
#undef X #undef X
}; };
// An enum of GPR Registers. The enum value does match the encoding used // An enum of GPR Registers. The enum value does match the encoding used
// to binary encode register operands in instructions. // to binary encode register operands in instructions.
enum GPRRegister { enum GPRRegister {
#define X(val, encode, name64, name, name16, name8, scratch, preserved, \ #define X(val, encode, name64, name, name16, name8, scratch, preserved, \
stackptr, frameptr, isInt, isFP) \ stackptr, frameptr, isInt, isFP) \
Encoded_##val encode, Encoded_##val encode,
REGX8664_GPR_TABLE REGX8664_GPR_TABLE
#undef X #undef X
Encoded_Not_GPR = -1 Encoded_Not_GPR = -1
}; };
// An enum of XMM Registers. The enum value does match the encoding used // An enum of XMM Registers. The enum value does match the encoding used
// to binary encode register operands in instructions. // to binary encode register operands in instructions.
enum XmmRegister { enum XmmRegister {
#define X(val, encode, name64, name, name16, name8, scratch, preserved, \ #define X(val, encode, name64, name, name16, name8, scratch, preserved, \
stackptr, frameptr, isInt, isFP) \ stackptr, frameptr, isInt, isFP) \
Encoded_##val encode, Encoded_##val encode,
REGX8664_XMM_TABLE REGX8664_XMM_TABLE
#undef X #undef X
Encoded_Not_Xmm = -1 Encoded_Not_Xmm = -1
}; };
// An enum of Byte Registers. The enum value does match the encoding used // An enum of Byte Registers. The enum value does match the encoding used
// to binary encode register operands in instructions. // to binary encode register operands in instructions.
enum ByteRegister { enum ByteRegister {
#define X(val, encode) Encoded_##val encode, #define X(val, encode) Encoded_##val encode,
REGX8664_BYTEREG_TABLE REGX8664_BYTEREG_TABLE
#undef X #undef X
Encoded_Not_ByteReg = -1 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);
}
static inline XmmRegister getEncodedXmm(int32_t RegNum) { static inline GPRRegister getEncodedGPR(int32_t RegNum) {
assert(Reg_XMM_First <= RegNum && RegNum <= Reg_XMM_Last); assert(Reg_GPR_First <= RegNum && RegNum <= Reg_GPR_Last);
return XmmRegister(RegNum - Reg_XMM_First); return GPRRegister(RegNum - Reg_GPR_First);
} }
static inline ByteRegister getEncodedByteReg(int32_t RegNum) { static inline XmmRegister getEncodedXmm(int32_t RegNum) {
// In x86-64, AH is not encodable when the REX prefix is used; the same assert(Reg_XMM_First <= RegNum && RegNum <= Reg_XMM_Last);
// encoding is used for spl. Therefore, ah needs special handling. return XmmRegister(RegNum - Reg_XMM_First);
if (RegNum == Reg_ah) }
return Encoded_Reg_spl;
return ByteRegister(RegNum - Reg_GPR_First);
}
static inline GPRRegister getEncodedByteRegOrGPR(Type Ty, int32_t RegNum) { static inline ByteRegister getEncodedByteReg(int32_t RegNum) {
if (isByteSizedType(Ty)) // In x86-64, AH is not encodable when the REX prefix is used; the same
return GPRRegister(getEncodedByteReg(RegNum)); // encoding is used for spl. Therefore, ah needs special handling.
else if (RegNum == Reg_ah)
return getEncodedGPR(RegNum); 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 } // end of namespace Ice
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
// //
// The Subzero Code Generator // 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 // This file implements the TargetLoweringX8632 class, which
...@@ -12,100 +15,19 @@ ...@@ -12,100 +15,19 @@
#include "IceTargetLoweringX8632.h" #include "IceTargetLoweringX8632.h"
#include "IceTargetLoweringX8632Traits.h"
#include "IceTargetLoweringX86Base.h" #include "IceTargetLoweringX86Base.h"
namespace Ice { 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 const MachineTraits<TargetX8632>::TableFcmpType
MachineTraits<TargetX8632>::TableFcmp[] = { MachineTraits<TargetX8632>::TableFcmp[] = {
#define X(val, dflt, swapS, C1, C2, swapV, pred) \ #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 FCMPX8632_TABLE
#undef X #undef X
...@@ -117,7 +39,7 @@ const size_t MachineTraits<TargetX8632>::TableFcmpSize = ...@@ -117,7 +39,7 @@ const size_t MachineTraits<TargetX8632>::TableFcmpSize =
const MachineTraits<TargetX8632>::TableIcmp32Type const MachineTraits<TargetX8632>::TableIcmp32Type
MachineTraits<TargetX8632>::TableIcmp32[] = { MachineTraits<TargetX8632>::TableIcmp32[] = {
#define X(val, C_32, C1_64, C2_64, C3_64) \ #define X(val, C_32, C1_64, C2_64, C3_64) \
{ CondX86::C_32 } \ { X8632::Traits::Cond::C_32 } \
, ,
ICMPX8632_TABLE ICMPX8632_TABLE
#undef X #undef X
...@@ -129,7 +51,10 @@ const size_t MachineTraits<TargetX8632>::TableIcmp32Size = ...@@ -129,7 +51,10 @@ const size_t MachineTraits<TargetX8632>::TableIcmp32Size =
const MachineTraits<TargetX8632>::TableIcmp64Type const MachineTraits<TargetX8632>::TableIcmp64Type
MachineTraits<TargetX8632>::TableIcmp64[] = { MachineTraits<TargetX8632>::TableIcmp64[] = {
#define X(val, C_32, C1_64, C2_64, C3_64) \ #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 ICMPX8632_TABLE
#undef X #undef X
...@@ -151,6 +76,7 @@ const size_t MachineTraits<TargetX8632>::TableTypeX8632AttributesSize = ...@@ -151,6 +76,7 @@ const size_t MachineTraits<TargetX8632>::TableTypeX8632AttributesSize =
llvm::array_lengthof(TableTypeX8632Attributes); llvm::array_lengthof(TableTypeX8632Attributes);
const uint32_t MachineTraits<TargetX8632>::X86_STACK_ALIGNMENT_BYTES = 16; const uint32_t MachineTraits<TargetX8632>::X86_STACK_ALIGNMENT_BYTES = 16;
} // end of namespace X86Internal } // end of namespace X86Internal
TargetX8632 *TargetX8632::create(Cfg *Func) { TargetX8632 *TargetX8632::create(Cfg *Func) {
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "IceInstX8632.h" #include "IceInstX8632.h"
#include "IceRegistersX8632.h" #include "IceRegistersX8632.h"
#include "IceTargetLowering.h" #include "IceTargetLowering.h"
#include "IceTargetLoweringX8632Traits.h"
namespace Ice { namespace Ice {
...@@ -30,16 +31,11 @@ class TargetX8632 : public TargetLowering { ...@@ -30,16 +31,11 @@ class TargetX8632 : public TargetLowering {
TargetX8632 &operator=(const TargetX8632 &) = delete; TargetX8632 &operator=(const TargetX8632 &) = delete;
public: public:
enum X86InstructionSet { using X86InstructionSet = X8632::Traits::InstructionSet;
Begin,
// SSE2 is the PNaCl baseline instruction set.
SSE2 = Begin,
SSE4_1,
End
};
static TargetX8632 *create(Cfg *Func); 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; virtual X86InstructionSet getInstructionSet() const = 0;
protected: protected:
......
...@@ -107,7 +107,9 @@ public: ...@@ -107,7 +107,9 @@ public:
void doLoadOpt(); void doLoadOpt();
bool doBranchOpt(Inst *I, const CfgNode *NextNode) override; 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; Variable *getPhysicalRegister(SizeT RegNum, Type Ty = IceType_void) override;
IceString getRegName(SizeT RegNum, Type Ty) const override; IceString getRegName(SizeT RegNum, Type Ty) const override;
llvm::SmallBitVector getRegisterSet(RegSetMask Include, llvm::SmallBitVector getRegisterSet(RegSetMask Include,
...@@ -117,7 +119,8 @@ public: ...@@ -117,7 +119,8 @@ public:
} }
bool hasFramePointer() const override { return IsEbpBasedFrame; } bool hasFramePointer() const override { return IsEbpBasedFrame; }
SizeT getFrameOrStackReg() const override { 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 { size_t typeWidthInBytesOnStack(Type Ty) const override {
// Round up to the next multiple of 4 bytes. In particular, i1, // Round up to the next multiple of 4 bytes. In particular, i1,
...@@ -148,7 +151,8 @@ public: ...@@ -148,7 +151,8 @@ public:
Operand *hiOperand(Operand *Operand); Operand *hiOperand(Operand *Operand);
void finishArgumentLowering(Variable *Arg, Variable *FramePtr, void finishArgumentLowering(Variable *Arg, Variable *FramePtr,
size_t BasicFrameOffset, size_t &InArgsSizeBytes); 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 { typename Traits::InstructionSet getInstructionSet() const final {
return InstructionSet; return InstructionSet;
...@@ -255,6 +259,7 @@ protected: ...@@ -255,6 +259,7 @@ protected:
llvm::SmallVectorImpl<int32_t> &Permutation, llvm::SmallVectorImpl<int32_t> &Permutation,
const llvm::SmallBitVector &ExcludeRegisters) const override; 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 // The following are helpers that insert lowered x86 instructions
// with minimal syntactic overhead, so that the lowering code can // with minimal syntactic overhead, so that the lowering code can
// look as close to assembly as practical. // look as close to assembly as practical.
...@@ -272,7 +277,7 @@ protected: ...@@ -272,7 +277,7 @@ protected:
} }
void _adjust_stack(int32_t Amount) { void _adjust_stack(int32_t Amount) {
Context.insert(InstX8632AdjustStack::create( Context.insert(InstX8632AdjustStack::create(
Func, Amount, getPhysicalRegister(RegX8632::Reg_esp))); Func, Amount, getPhysicalRegister(Traits::RegisterSet::Reg_esp)));
} }
void _addps(Variable *Dest, Operand *Src0) { void _addps(Variable *Dest, Operand *Src0) {
Context.insert(InstX8632Addps::create(Func, Dest, Src0)); Context.insert(InstX8632Addps::create(Func, Dest, Src0));
...@@ -289,7 +294,7 @@ protected: ...@@ -289,7 +294,7 @@ protected:
void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) { void _blendvps(Variable *Dest, Operand *Src0, Operand *Src1) {
Context.insert(InstX8632Blendvps::create(Func, Dest, Src0, 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) { CfgNode *TargetFalse) {
Context.insert( Context.insert(
InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition)); InstX8632Br::create(Func, TargetTrue, TargetFalse, Condition));
...@@ -297,10 +302,10 @@ protected: ...@@ -297,10 +302,10 @@ protected:
void _br(CfgNode *Target) { void _br(CfgNode *Target) {
Context.insert(InstX8632Br::create(Func, 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)); 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)); Context.insert(InstX8632Br::create(Func, Label, Condition));
} }
void _bsf(Variable *Dest, Operand *Src0) { void _bsf(Variable *Dest, Operand *Src0) {
...@@ -315,13 +320,15 @@ protected: ...@@ -315,13 +320,15 @@ protected:
void _cbwdq(Variable *Dest, Operand *Src0) { void _cbwdq(Variable *Dest, Operand *Src0) {
Context.insert(InstX8632Cbwdq::create(Func, Dest, 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)); Context.insert(InstX8632Cmov::create(Func, Dest, Src0, Condition));
} }
void _cmp(Operand *Src0, Operand *Src1) { void _cmp(Operand *Src0, Operand *Src1) {
Context.insert(InstX8632Icmp::create(Func, Src0, 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)); Context.insert(InstX8632Cmpps::create(Func, Dest, Src0, Condition));
} }
void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired, void _cmpxchg(Operand *DestOrAddr, Variable *Eax, Variable *Desired,
...@@ -503,7 +510,7 @@ protected: ...@@ -503,7 +510,7 @@ protected:
void _sbb_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) { void _sbb_rmw(OperandX8632Mem *DestSrc0, Operand *Src1) {
Context.insert(InstX8632SbbRMW::create(Func, DestSrc0, 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)); Context.insert(InstX8632Setcc::create(Func, Dest, Condition));
} }
void _shl(Variable *Dest, Operand *Src0) { 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