Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Unified Diff: src/IceAssemblerX86Base.h

Issue 1224173006: Adds the x86-64 assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: make format Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceAssemblerX86Base.h
diff --git a/src/IceAssemblerX86Base.h b/src/IceAssemblerX86Base.h
index 1db270ab20af84ff7d7f07670930fb124b280e37..36de87a324b511af47d2a802aa7887cefc39c99a 100644
--- a/src/IceAssemblerX86Base.h
+++ b/src/IceAssemblerX86Base.h
@@ -314,7 +314,7 @@ public:
*/
void call(typename Traits::GPRRegister reg);
void call(const typename Traits::Address &address);
- void call(const ConstantRelocatable *label);
+ void call(const ConstantRelocatable *label); // not testable.
void call(const Immediate &abs_address);
static const intptr_t kCallExternalLabelSize = 5;
@@ -324,7 +324,11 @@ public:
void popl(typename Traits::GPRRegister reg);
void popl(const typename Traits::Address &address);
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::HasPusha>::type>
void pushal();
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::HasPopa>::type>
void popal();
void setcc(typename Traits::Cond::BrCond condition,
@@ -332,7 +336,6 @@ public:
void setcc(typename Traits::Cond::BrCond condition,
const typename Traits::Address &address);
- // All mov() overloads are tested.
void mov(Type Ty, typename Traits::GPRRegister dst, const Immediate &src);
void mov(Type Ty, typename Traits::GPRRegister dst,
typename Traits::GPRRegister src);
@@ -342,6 +345,8 @@ public:
typename Traits::GPRRegister src);
void mov(Type Ty, const typename Traits::Address &dst, const Immediate &imm);
+ void movFromAh(const typename Traits::GPRRegister dst);
+
void movzx(Type Ty, typename Traits::GPRRegister dst,
typename Traits::GPRRegister src);
void movzx(Type Ty, typename Traits::GPRRegister dst,
@@ -503,6 +508,7 @@ public:
void sqrtps(typename Traits::XmmRegister dst);
void rsqrtps(typename Traits::XmmRegister dst);
void reciprocalps(typename Traits::XmmRegister dst);
+
void movhlps(typename Traits::XmmRegister dst,
typename Traits::XmmRegister src);
void movlhps(typename Traits::XmmRegister dst,
@@ -518,14 +524,13 @@ public:
void set1ps(typename Traits::XmmRegister dst,
typename Traits::GPRRegister tmp, const Immediate &imm);
- void shufps(typename Traits::XmmRegister dst,
- typename Traits::XmmRegister src, const Immediate &mask);
void minpd(typename Traits::XmmRegister dst,
typename Traits::XmmRegister src);
void maxpd(typename Traits::XmmRegister dst,
typename Traits::XmmRegister src);
void sqrtpd(typename Traits::XmmRegister dst);
+
void shufpd(typename Traits::XmmRegister dst,
typename Traits::XmmRegister src, const Immediate &mask);
@@ -533,6 +538,8 @@ public:
typename Traits::XmmRegister src, const Immediate &mask);
void pshufd(Type Ty, typename Traits::XmmRegister dst,
const typename Traits::Address &src, const Immediate &mask);
+ void shufps(typename Traits::XmmRegister dst,
+ typename Traits::XmmRegister src, const Immediate &mask);
void shufps(Type Ty, typename Traits::XmmRegister dst,
typename Traits::XmmRegister src, const Immediate &mask);
void shufps(Type Ty, typename Traits::XmmRegister dst,
@@ -606,6 +613,7 @@ public:
void pextr(Type Ty, typename Traits::GPRRegister dst,
typename Traits::XmmRegister src, const Immediate &imm);
+ // The following overload is not implemented.
void pextr(Type Ty, typename Traits::GPRRegister dst,
const typename Traits::Address &src, const Immediate &imm);
@@ -630,19 +638,49 @@ public:
void roundsd(typename Traits::XmmRegister dst,
typename Traits::XmmRegister src, RoundingMode mode);
- void fld(Type Ty, const typename Traits::Address &src);
- void fstp(Type Ty, const typename Traits::Address &dst);
- void fstp(typename Traits::X87STRegister st);
-
- void fnstcw(const typename Traits::Address &dst);
- void fldcw(const typename Traits::Address &src);
-
- void fistpl(const typename Traits::Address &dst);
- void fistps(const typename Traits::Address &dst);
- void fildl(const typename Traits::Address &src);
- void filds(const typename Traits::Address &src);
-
+ //----------------------------------------------------------------------------
+ //
+ // Begin: X87 instructions. Only available when Traits::UsesX87.
+ //
+ //----------------------------------------------------------------------------
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::UsesX87>::type>
+ void fld(Type Ty, const typename T::Address &src);
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::UsesX87>::type>
+ void fstp(Type Ty, const typename T::Address &dst);
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::UsesX87>::type>
+ void fstp(typename T::X87STRegister st);
+
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::UsesX87>::type>
+ void fnstcw(const typename T::Address &dst);
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::UsesX87>::type>
+ void fldcw(const typename T::Address &src);
+
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::UsesX87>::type>
+ void fistpl(const typename T::Address &dst);
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::UsesX87>::type>
+ void fistps(const typename T::Address &dst);
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::UsesX87>::type>
+ void fildl(const typename T::Address &src);
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::UsesX87>::type>
+ void filds(const typename T::Address &src);
+
+ template <typename T = Traits,
+ typename = typename std::enable_if<T::UsesX87>::type>
void fincstp();
+ //----------------------------------------------------------------------------
+ //
+ // End: X87 instructions.
+ //
+ //----------------------------------------------------------------------------
void cmp(Type Ty, typename Traits::GPRRegister reg0,
typename Traits::GPRRegister reg1);
@@ -754,9 +792,13 @@ public:
void mul(Type Ty, typename Traits::GPRRegister reg);
void mul(Type Ty, const typename Traits::Address &address);
+ template <class T = Traits,
+ typename = typename std::enable_if<!T::Is64Bit>::type>
void incl(typename Traits::GPRRegister reg);
void incl(const typename Traits::Address &address);
+ template <class T = Traits,
+ typename = typename std::enable_if<!T::Is64Bit>::type>
void decl(typename Traits::GPRRegister reg);
void decl(const typename Traits::Address &address);
@@ -825,16 +867,14 @@ public:
void ud2();
// j(Label) is fully tested.
- // j(ConstantRelocatable) is not tested as the test can not easily create such
- // an argument.
void j(typename Traits::Cond::BrCond condition, Label *label,
bool near = kFarJump);
void j(typename Traits::Cond::BrCond condition,
- const ConstantRelocatable *label);
+ const ConstantRelocatable *label); // not testable.
void jmp(typename Traits::GPRRegister reg);
void jmp(Label *label, bool near = kFarJump);
- void jmp(const ConstantRelocatable *label);
+ void jmp(const ConstantRelocatable *label); // not testable.
void mfence();
@@ -855,12 +895,15 @@ public:
intptr_t CodeSize() const { return Buffer.size(); }
-private:
+protected:
inline void emitUint8(uint8_t value);
+
+private:
inline void emitInt16(int16_t value);
inline void emitInt32(int32_t value);
inline void emitRegisterOperand(int rm, int reg);
- inline void emitXmmRegisterOperand(int rm, typename Traits::XmmRegister reg);
+ template <typename RegType, typename RmType>
+ inline void emitXmmRegisterOperand(RegType reg, RmType rm);
inline void emitFixup(AssemblerFixup *fixup);
inline void emitOperandSizeOverride();
@@ -910,6 +953,76 @@ private:
template <uint32_t Tag>
void arith_int(Type Ty, const typename Traits::Address &address,
const Immediate &imm);
+
+ // gprEncoding returns Reg encoding for operand emission. For x86-64 we mask
+ // out the 4th bit as it is encoded in the REX.[RXB] bits. No other bits are
+ // touched because we don't want to mask errors.
+ template <typename RegType, typename T = Traits>
+ typename std::enable_if<T::Is64Bit, typename T::GPRRegister>::type
+ gprEncoding(const RegType Reg) {
+ static_assert(
+ &AssemblerX86Base<Machine>::gprEncoding<RegType> !=
+ &T::Assembler::template gprEncoding<RegType>,
+ "You need to define the gprEncoding() template in your assembler.");
+ return static_cast<typename T::Assembler *>(this)->gprEncoding(Reg);
+ }
+
+ template <typename RegType, typename T = Traits>
+ typename std::enable_if<!T::Is64Bit, typename T::GPRRegister>::type
+ gprEncoding(const RegType Reg) {
+ return static_cast<typename T::GPRRegister>(Reg);
+ }
+
+ // emitRex is used for emitting a Rex prefix for an address and a GPR. The
Jim Stichnoth 2015/07/26 15:31:11 Did you swap the description of emitRex and emitRe
John 2015/07/27 20:35:58 Yes I did. Done. On a related note, I changed thi
+ // address may contain zero, one, or two registers.
+ template <typename RegType, typename RmType, typename T = Traits>
+ typename std::enable_if<T::Is64Bit, void>::type
+ emitRexRB(const Type Ty, const RegType Reg, const RmType Rm) {
+ static_assert(
+ &AssemblerX86Base<Machine>::emitRexRB<RegType, RmType> !=
+ &T::Assembler::template emitRexRB<RegType, RmType>,
+ "You need to define the emitRexRB() template in your assembler.");
+ static_cast<typename T::Assembler *>(this)->emitRexRB(Ty, Reg, Rm);
+ }
+
+ template <typename RegType, typename RmType, typename T = Traits>
+ typename std::enable_if<!T::Is64Bit, void>::type
+ emitRexRB(const Type, const RegType, const RmType) {}
+
+ // emitRexB is used for emitting a Rex prefix if one is needed on encoding the
+ // Reg field in an x86 instruction. It is invoked by the template when Reg is
+ // the single register operand in the instruction (e.g., push Reg.)
+ template <typename RmType, typename T = Traits>
+ typename std::enable_if<T::Is64Bit, void>::type emitRexB(const Type Ty,
+ const RmType Rm) {
+ static_assert(
+ &AssemblerX86Base<Machine>::emitRexB<RmType> !=
+ &T::Assembler::template emitRexB<RmType>,
+ "You need to define the emitRexB() template in your assembler.");
+ static_cast<typename T::Assembler *>(this)->emitRexB(Ty, Rm);
+ }
+
+ template <typename RmType, typename T = Traits>
+ typename std::enable_if<!T::Is64Bit, void>::type emitRexB(const Type,
+ const RmType) {}
+
+ // emitRexRB is used for emitting a Rex prefix instructions with two explicit
+ // register operands in its mod-rm byte.
+ template <typename RegType, typename T = Traits>
+ typename std::enable_if<T::Is64Bit, void>::type
+ emitRex(const Type Ty, const typename Traits::Address &Addr,
+ const RegType Reg) {
+ static_assert(
+ &AssemblerX86Base<Machine>::emitRex<RegType> !=
+ &T::Assembler::template emitRex<RegType>,
+ "You need to define the emitRex() template in your assembler.");
+ static_cast<typename T::Assembler *>(this)
+ ->emitRex(Ty, Addr, static_cast<typename Traits::GPRRegister>(Reg));
+ }
+
+ template <typename RegType, typename T = Traits>
+ typename std::enable_if<!T::Is64Bit, void>::type
+ emitRex(const Type, const typename Traits::Address &, const RegType) {}
};
template <class Machine>
@@ -928,15 +1041,17 @@ inline void AssemblerX86Base<Machine>::emitInt32(int32_t value) {
}
template <class Machine>
-inline void AssemblerX86Base<Machine>::emitRegisterOperand(int rm, int reg) {
+inline void AssemblerX86Base<Machine>::emitRegisterOperand(int reg, int rm) {
+ assert(reg >= 0 && reg < 8);
assert(rm >= 0 && rm < 8);
- Buffer.emit<uint8_t>(0xC0 + (rm << 3) + reg);
+ Buffer.emit<uint8_t>(0xC0 + (reg << 3) + rm);
}
template <class Machine>
-inline void AssemblerX86Base<Machine>::emitXmmRegisterOperand(
- int rm, typename Traits::XmmRegister reg) {
- emitRegisterOperand(rm, static_cast<typename Traits::GPRRegister>(reg));
+template <typename RegType, typename RmType>
+inline void AssemblerX86Base<Machine>::emitXmmRegisterOperand(RegType reg,
+ RmType rm) {
+ emitRegisterOperand(gprEncoding(reg), gprEncoding(rm));
}
template <class Machine>

Powered by Google App Engine
This is Rietveld 408576698