Revert "Adds word-size store instructions to x64 assembler"
Esse commit está contido em:
@@ -5147,13 +5147,13 @@ void CodeGenerator::cgContPreNext(IRInstruction* inst) {
|
||||
static_assert((doneOffset + 1) == c_Continuation::runningOffset(),
|
||||
"done should immediately precede running");
|
||||
// Check done and running at the same time
|
||||
m_as.testw(0x0101, contReg[doneOffset]);
|
||||
m_as.test_imm16_disp_reg16(0x0101, doneOffset, contReg);
|
||||
emitFwdJcc(CC_NZ, inst->taken());
|
||||
|
||||
// ++m_index
|
||||
m_as.addq(0x1, contReg[CONTOFF(m_index)]);
|
||||
m_as.add_imm64_disp_reg64(0x1, CONTOFF(m_index), contReg);
|
||||
// running = true
|
||||
m_as.storeb(0x1, contReg[c_Continuation::runningOffset()]);
|
||||
m_as.store_imm8_disp_reg(0x1, c_Continuation::runningOffset(), contReg);
|
||||
}
|
||||
|
||||
void CodeGenerator::cgContStartedCheck(IRInstruction* inst) {
|
||||
|
||||
+22
-130
@@ -65,8 +65,6 @@ const int kNumGPRegs = 16;
|
||||
const int kNumXMMRegs = 16;
|
||||
const int kNumRegs = kNumGPRegs + kNumXMMRegs;
|
||||
|
||||
const uint8_t kOpsizePrefix = 0x66;
|
||||
|
||||
/*
|
||||
* Type for register numbers, independent of the size we're going to
|
||||
* be using it as. Also, the same register number may mean different
|
||||
@@ -118,7 +116,6 @@ private:
|
||||
}
|
||||
|
||||
SIMPLE_REGTYPE(Reg32);
|
||||
SIMPLE_REGTYPE(Reg16);
|
||||
SIMPLE_REGTYPE(Reg8);
|
||||
SIMPLE_REGTYPE(RegXMM);
|
||||
|
||||
@@ -133,10 +130,7 @@ struct RegRIP {
|
||||
|
||||
inline Reg8 rbyte(Reg32 r) { return Reg8(int(r)); }
|
||||
inline Reg8 rbyte(RegNumber r) { return Reg8(int(r)); }
|
||||
inline Reg16 r16(Reg8 r) { return Reg16(int(r)); }
|
||||
inline Reg16 r16(RegNumber r) { return Reg16(int(r)); }
|
||||
inline Reg32 r32(Reg8 r) { return Reg32(int(r)); }
|
||||
inline Reg32 r32(Reg16 r) { return Reg32(int(r)); }
|
||||
inline Reg32 r32(Reg32 r) { return r; }
|
||||
inline Reg32 r32(RegNumber r) { return Reg32(int(r)); }
|
||||
inline Reg64 r64(RegNumber r) { return Reg64(int(r)); }
|
||||
@@ -376,23 +370,6 @@ namespace reg {
|
||||
constexpr Reg32 r14d(14);
|
||||
constexpr Reg32 r15d(15);
|
||||
|
||||
constexpr Reg16 ax (0);
|
||||
constexpr Reg16 cx (1);
|
||||
constexpr Reg16 dx (2);
|
||||
constexpr Reg16 bx (3);
|
||||
constexpr Reg16 sp (4);
|
||||
constexpr Reg16 bp (5);
|
||||
constexpr Reg16 si (6);
|
||||
constexpr Reg16 di (7);
|
||||
constexpr Reg16 r8w (8);
|
||||
constexpr Reg16 r9w (9);
|
||||
constexpr Reg16 r10w(10);
|
||||
constexpr Reg16 r11w(11);
|
||||
constexpr Reg16 r12w(12);
|
||||
constexpr Reg16 r13w(13);
|
||||
constexpr Reg16 r14w(14);
|
||||
constexpr Reg16 r15w(15);
|
||||
|
||||
constexpr Reg8 al (0);
|
||||
constexpr Reg8 cl (1);
|
||||
constexpr Reg8 dl (2);
|
||||
@@ -449,11 +426,6 @@ namespace reg {
|
||||
X(r8d); X(r9d); X(r10d); X(r11d); X(r12d); X(r13d); X(r14d); X(r15d);
|
||||
return nullptr;
|
||||
}
|
||||
inline const char* regname(Reg16 r) {
|
||||
X(ax); X(cx); X(dx); X(bx); X(sp); X(bp); X(si); X(di);
|
||||
X(r8w); X(r9w); X(r10w); X(r11w); X(r12w); X(r13w); X(r14w); X(r15w);
|
||||
return nullptr;
|
||||
}
|
||||
inline const char* regname(Reg8 r) {
|
||||
X(al); X(cl); X(dl); X(bl); X(spl); X(bpl); X(sil); X(dil);
|
||||
X(r8b); X(r9b); X(r10b); X(r11b); X(r12b); X(r13b); X(r14b); X(r15b);
|
||||
@@ -941,27 +913,21 @@ struct X64Assembler {
|
||||
#define LOAD_OP(name, instr) \
|
||||
void name##q(MemoryRef m, Reg64 r) { instrMR(instr, m, r); } \
|
||||
void name##l(MemoryRef m, Reg32 r) { instrMR(instr, m, r); } \
|
||||
void name##w(MemoryRef m, Reg16 r) { instrMR(instr, m, r); } \
|
||||
void name##q(IndexedMemoryRef m, Reg64 r) { instrMR(instr, m, r); } \
|
||||
void name##l(IndexedMemoryRef m, Reg32 r) { instrMR(instr, m, r); } \
|
||||
void name##w(IndexedMemoryRef m, Reg16 r) { instrMR(instr, m, r); } \
|
||||
BYTE_LOAD_OP(name, instr##b)
|
||||
|
||||
#define BYTE_STORE_OP(name, instr) \
|
||||
#define BYTE_STORE_OP(name, instr) \
|
||||
void name##b(Reg8 r, MemoryRef m) { instrRM(instr, r, m); } \
|
||||
void name##b(Reg8 r, IndexedMemoryRef m) { instrRM(instr, r, m); } \
|
||||
void name##b(Immed i, MemoryRef m) { instrIM8(instr, i, m); } \
|
||||
void name##b(Immed i, IndexedMemoryRef m){ instrIM8(instr, i, m); }
|
||||
|
||||
#define STORE_OP(name, instr) \
|
||||
void name##w(Immed i, MemoryRef m) { instrIM16(instr, i, m); } \
|
||||
void name##l(Immed i, MemoryRef m) { instrIM32(instr, i, m); } \
|
||||
void name##w(Reg16 r, MemoryRef m) { instrRM(instr, r, m); } \
|
||||
void name##l(Reg32 r, MemoryRef m) { instrRM(instr, r, m); } \
|
||||
void name##q(Reg64 r, MemoryRef m) { instrRM(instr, r, m); } \
|
||||
void name##w(Immed i, IndexedMemoryRef m) { instrIM16(instr, i, m); } \
|
||||
void name##l(Immed i, IndexedMemoryRef m) { instrIM32(instr, i, m); } \
|
||||
void name##w(Reg16 r, IndexedMemoryRef m) { instrRM(instr, r, m); } \
|
||||
void name##l(Reg32 r, IndexedMemoryRef m) { instrRM(instr, r, m); } \
|
||||
void name##q(Reg64 r, IndexedMemoryRef m) { instrRM(instr, r, m); } \
|
||||
BYTE_STORE_OP(name, instr ## b)
|
||||
@@ -973,9 +939,7 @@ struct X64Assembler {
|
||||
#define REG_OP(name, instr) \
|
||||
void name##q(Reg64 r1, Reg64 r2) { instrRR(instr, r1, r2); } \
|
||||
void name##l(Reg32 r1, Reg32 r2) { instrRR(instr, r1, r2); } \
|
||||
void name##w(Reg16 r1, Reg16 r2) { instrRR(instr, r1, r2); } \
|
||||
void name##l(Immed i, Reg32 r) { instrIR(instr, i, r); } \
|
||||
void name##w(Immed i, Reg16 r) { instrIR(instr, i, r); } \
|
||||
void name##l(Immed i, Reg32 r) { instrIR(instr, i, r); } \
|
||||
BYTE_REG_OP(name, instr##b)
|
||||
|
||||
/*
|
||||
@@ -1088,10 +1052,8 @@ struct X64Assembler {
|
||||
void idiv(Reg64 r) { instrR(instr_idiv, r); }
|
||||
void incq(Reg64 r) { instrR(instr_inc, r); }
|
||||
void incl(Reg32 r) { instrR(instr_inc, r); }
|
||||
void incw(Reg16 r) { instrR(instr_inc, r); }
|
||||
void decq(Reg64 r) { instrR(instr_dec, r); }
|
||||
void decl(Reg32 r) { instrR(instr_dec, r); }
|
||||
void decw(Reg16 r) { instrR(instr_dec, r); }
|
||||
// decl(Reg32) cannot be encoded; it's REX.
|
||||
void notb(Reg8 r) { instrR(instr_notb, r); }
|
||||
void not(Reg64 r) { instrR(instr_not, r); }
|
||||
void neg(Reg64 r) { instrR(instr_neg, r); }
|
||||
@@ -1109,10 +1071,8 @@ struct X64Assembler {
|
||||
void pop (MemoryRef m) { instrM(instr_pop, m); }
|
||||
void incq(MemoryRef m) { instrM(instr_inc, m); }
|
||||
void incl(MemoryRef m) { instrM32(instr_inc, m); }
|
||||
void incw(MemoryRef m) { instrM16(instr_inc, m); }
|
||||
void decq(MemoryRef m) { instrM(instr_dec, m); }
|
||||
void decl(MemoryRef m) { instrM32(instr_dec, m); }
|
||||
void decw(MemoryRef m) { instrM16(instr_dec, m); }
|
||||
|
||||
void movdqu(RegXMM x, MemoryRef m) { instrRM(instr_movdqu, x, m); }
|
||||
void movdqu(RegXMM x, IndexedMemoryRef m) { instrRM(instr_movdqu, x, m); }
|
||||
@@ -1135,8 +1095,6 @@ struct X64Assembler {
|
||||
void shrq (Immed i, Reg64 r) { instrIR(instr_shr, i.b(), r); }
|
||||
void shll (Immed i, Reg32 r) { instrIR(instr_shl, i.b(), r); }
|
||||
void shrl (Immed i, Reg32 r) { instrIR(instr_shr, i.b(), r); }
|
||||
void shlw (Immed i, Reg16 r) { instrIR(instr_shl, i.b(), r); }
|
||||
void shrw (Immed i, Reg16 r) { instrIR(instr_shr, i.b(), r); }
|
||||
|
||||
/*
|
||||
* Control-flow directives. Primitive labeling/patching facilities
|
||||
@@ -1364,11 +1322,6 @@ struct X64Assembler {
|
||||
assert(regN != reg::noreg);
|
||||
int r = int(regN);
|
||||
|
||||
// Opsize prefix
|
||||
if (opSz == sz::word) {
|
||||
byte(kOpsizePrefix);
|
||||
}
|
||||
|
||||
// REX
|
||||
unsigned char rex = 0;
|
||||
bool highByteReg = false;
|
||||
@@ -1406,10 +1359,6 @@ struct X64Assembler {
|
||||
emitCR(op, 0, r, sz::dword);
|
||||
}
|
||||
|
||||
void emitR16(X64Instr op, RegNumber r) ALWAYS_INLINE {
|
||||
emitCR(op, 0, r, sz::word);
|
||||
}
|
||||
|
||||
// op %r2, %r1
|
||||
// -----------
|
||||
// Restrictions:
|
||||
@@ -1422,7 +1371,7 @@ struct X64Assembler {
|
||||
int r1 = int(rn1);
|
||||
int r2 = int(rn2);
|
||||
bool reverse = ((op.flags & IF_REVERSE) != 0);
|
||||
prefixBytes(op.flags, opSz);
|
||||
prefixBytes(op.flags);
|
||||
// The xchg instruction is special; we have compact encodings for
|
||||
// exchanging with rax or eax.
|
||||
if (op.flags & IF_XCHG) {
|
||||
@@ -1498,11 +1447,6 @@ struct X64Assembler {
|
||||
emitCRR(op, 0, r1, r2, sz::dword);
|
||||
}
|
||||
|
||||
void emitRR16(X64Instr op, RegNumber r1,
|
||||
RegNumber r2) ALWAYS_INLINE {
|
||||
emitCRR(op, 0, r1, r2, sz::word);
|
||||
}
|
||||
|
||||
void emitRR8(X64Instr op, RegNumber r1, RegNumber r2) {
|
||||
emitCRR(op, 0, r1, r2, sz::byte);
|
||||
}
|
||||
@@ -1516,15 +1460,13 @@ struct X64Assembler {
|
||||
ALWAYS_INLINE {
|
||||
assert(rname != reg::noreg);
|
||||
int r = int(rname);
|
||||
// Opsize prefix
|
||||
prefixBytes(0, opSz);
|
||||
// Determine the size of the immediate. This might change opSz so
|
||||
// do it first.
|
||||
int immSize;
|
||||
if ((op.flags & IF_MOV) && opSz == sz::qword) {
|
||||
immSize = computeImmediateSizeForMovRI64(op, imm, opSz);
|
||||
} else {
|
||||
immSize = computeImmediateSize(op, imm, opSz);
|
||||
immSize = computeImmediateSize(op, imm);
|
||||
}
|
||||
// REX
|
||||
unsigned char rex = 0;
|
||||
@@ -1576,11 +1518,6 @@ struct X64Assembler {
|
||||
emitIR(op, r, imm, sz::dword);
|
||||
}
|
||||
|
||||
void emitIR16(X64Instr op, RegNumber r, ssize_t imm)
|
||||
ALWAYS_INLINE {
|
||||
emitIR(op, r, safe_cast<int16_t>(imm), sz::word);
|
||||
}
|
||||
|
||||
void emitIR8(X64Instr op, RegNumber r, ssize_t imm) {
|
||||
emitIR(op, r, safe_cast<int8_t>(imm), sz::byte);
|
||||
}
|
||||
@@ -1597,8 +1534,6 @@ struct X64Assembler {
|
||||
int r1 = int(rn1);
|
||||
int r2 = int(rn2);
|
||||
bool reverse = ((op.flags & IF_REVERSE) != 0);
|
||||
// Opsize prefix
|
||||
prefixBytes(0, opSz);
|
||||
// REX
|
||||
unsigned char rex = 0;
|
||||
if ((op.flags & IF_NO_REXW) == 0 && opSz == sz::qword) rex |= 8;
|
||||
@@ -1606,7 +1541,7 @@ struct X64Assembler {
|
||||
if (r2 & 8) rex |= (reverse ? 4 : 1);
|
||||
if (rex) byte(0x40 | rex);
|
||||
// Determine the size of the immediate
|
||||
int immSize = computeImmediateSize(op, imm, opSz);
|
||||
int immSize = computeImmediateSize(op, imm);
|
||||
// Use 2-byte opcode for cmovcc, setcc, movsx, movzx, movsx8, movzx8
|
||||
// instructions
|
||||
if ((op.flags & IF_TWOBYTEOP) != 0) byte(0x0F);
|
||||
@@ -1623,14 +1558,12 @@ struct X64Assembler {
|
||||
|
||||
void emitCI(X64Instr op, int jcond, ssize_t imm, int opSz = sz::qword)
|
||||
ALWAYS_INLINE {
|
||||
// Opsize prefix
|
||||
prefixBytes(0, opSz);
|
||||
// REX
|
||||
if ((op.flags & IF_NO_REXW) == 0) {
|
||||
byte(0x48);
|
||||
}
|
||||
// Determine the size of the immediate
|
||||
int immSize = computeImmediateSize(op, imm, opSz);
|
||||
int immSize = computeImmediateSize(op, imm);
|
||||
// Emit opcode
|
||||
if ((op.flags & IF_JCC) != 0) {
|
||||
// jcc is weird so we handle it separately
|
||||
@@ -1723,16 +1656,14 @@ struct X64Assembler {
|
||||
int r = int(rName);
|
||||
int br = int(brName);
|
||||
|
||||
// The opsize prefix can be placed here, if the instruction
|
||||
// deals with words.
|
||||
// When an instruction has a manditory prefix, it goes before the
|
||||
// REX byte if we end up needing one.
|
||||
prefixBytes(op.flags, opSz);
|
||||
prefixBytes(op.flags);
|
||||
|
||||
// Determine immSize from the 'hasImmediate' flag
|
||||
int immSize = sz::nosize;
|
||||
if (hasImmediate) {
|
||||
immSize = computeImmediateSize(op, imm, opSz);
|
||||
immSize = computeImmediateSize(op, imm);
|
||||
}
|
||||
if ((op.flags & IF_REVERSE) != 0) reverse = !reverse;
|
||||
// Determine if we need to use a two byte opcode;
|
||||
@@ -1886,11 +1817,6 @@ struct X64Assembler {
|
||||
emitCMX(op, 0, br, ir, s, disp, r, false, 0, false, sz::dword);
|
||||
}
|
||||
|
||||
void emitRM16(X64Instr op, RegNumber br, RegNumber ir, int s,
|
||||
int disp, RegNumber r) ALWAYS_INLINE {
|
||||
emitCMX(op, 0, br, ir, s, disp, r, false, 0, false, sz::word);
|
||||
}
|
||||
|
||||
void emitRM8(X64Instr op, RegNumber br, RegNumber ir, int s,
|
||||
int disp, RegNumber r) {
|
||||
emitCMX(op, 0, br, ir, s, disp, r, false, 0, false, sz::byte);
|
||||
@@ -1913,11 +1839,6 @@ struct X64Assembler {
|
||||
emitCMX(op, 0, br, ir, s, disp, r, true, 0, false, sz::dword);
|
||||
}
|
||||
|
||||
void emitMR16(X64Instr op, RegNumber br, RegNumber ir,
|
||||
int s, int disp, RegNumber r) ALWAYS_INLINE {
|
||||
emitCMX(op, 0, br, ir, s, disp, r, true, 0, false, sz::word);
|
||||
}
|
||||
|
||||
void emitMR8(X64Instr op, RegNumber br, RegNumber ir,
|
||||
int s, int disp, RegNumber r) ALWAYS_INLINE {
|
||||
emitCMX(op, 0, br, ir, s, disp, r, true, 0, false, sz::byte);
|
||||
@@ -1946,12 +1867,6 @@ struct X64Assembler {
|
||||
sz::dword);
|
||||
}
|
||||
|
||||
void emitM16(X64Instr op, RegNumber br, RegNumber ir,
|
||||
int s, int disp) ALWAYS_INLINE {
|
||||
emitCMX(op, 0, br, ir, s, disp, reg::noreg, false, 0, false,
|
||||
sz::word);
|
||||
}
|
||||
|
||||
void emitCM(X64Instr op, int jcond, RegNumber br,
|
||||
RegNumber ir, int s, int disp, int opSz = sz::qword)
|
||||
ALWAYS_INLINE {
|
||||
@@ -2130,6 +2045,12 @@ public:
|
||||
inline void name ## _imm32_reg32(int64_t imm, RegNumber rdest) { \
|
||||
emitIR32(instr_ ## name, rdest, safe_cast<int32_t>(imm)); \
|
||||
} \
|
||||
/* op imm, disp(rdest) */ \
|
||||
inline void name ## _imm16_disp_reg16(int64_t imm, int disp, \
|
||||
RegNumber rdest) { \
|
||||
emitIM16(instr_ ## name, rdest, reg::noreg, \
|
||||
sz::byte, disp, safe_cast<int16_t>(imm)); \
|
||||
} \
|
||||
/* opl imm, disp(rdest) */ \
|
||||
inline void name ## _imm32_disp_reg32(int64_t imm, int disp, \
|
||||
RegNumber rdest) { \
|
||||
@@ -2297,13 +2218,10 @@ private:
|
||||
" anything requiring a REX prefix");
|
||||
}
|
||||
|
||||
int computeImmediateSize(X64Instr op,
|
||||
ssize_t imm,
|
||||
int opsize = sz::dword) {
|
||||
// Most instructions take a 32-bit or 16-bit immediate,
|
||||
// depending on the presence of the opsize prefix (0x66).
|
||||
int immSize = opsize == sz::word ? sz::word : sz::dword;
|
||||
// ret always takes a 16-bit immediate.
|
||||
int computeImmediateSize(X64Instr op, ssize_t imm) {
|
||||
// Most instructions take a 32-bit immediate, except
|
||||
// for ret which takes a 16-bit immediate
|
||||
int immSize = sz::dword;
|
||||
if (op.flags & IF_RET) {
|
||||
immSize = sz::word;
|
||||
}
|
||||
@@ -2360,8 +2278,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void prefixBytes(unsigned long flags, int opSz) {
|
||||
if (opSz == sz::word) byte(kOpsizePrefix);
|
||||
void prefixBytes(unsigned long flags) {
|
||||
if (flags & IF_66PREFIXED) byte(0x66);
|
||||
if (flags & IF_F2PREFIXED) byte(0xF2);
|
||||
if (flags & IF_F3PREFIXED) byte(0xF3);
|
||||
@@ -2369,7 +2286,6 @@ private:
|
||||
|
||||
private:
|
||||
RegNumber rn(Reg8 r) { return RegNumber(r); }
|
||||
RegNumber rn(Reg16 r) { return RegNumber(r); }
|
||||
RegNumber rn(Reg32 r) { return RegNumber(r); }
|
||||
RegNumber rn(Reg64 r) { return RegNumber(r); }
|
||||
RegNumber rn(RegXMM x) { return RegNumber(x); }
|
||||
@@ -2384,17 +2300,14 @@ private:
|
||||
|
||||
void instrR(X64Instr op, Reg64 r) { emitR(op, rn(r)); }
|
||||
void instrR(X64Instr op, Reg32 r) { emitR32(op, rn(r)); }
|
||||
void instrR(X64Instr op, Reg16 r) { emitR16(op, rn(r)); }
|
||||
void instrR(X64Instr op, Reg8 r) { emitR(op, rn(r), sz::byte); }
|
||||
void instrRR(X64Instr op, Reg64 x, Reg64 y) { emitRR(op, rn(x), rn(y)); }
|
||||
void instrRR(X64Instr op, Reg32 x, Reg32 y) { emitRR32(op, rn(x), rn(y)); }
|
||||
void instrRR(X64Instr op, Reg16 x, Reg16 y) { emitRR16(op, rn(x), rn(y)); }
|
||||
void instrRR(X64Instr op, Reg64 x, Reg64 y) { emitRR(op, rn(x), rn(y)); }
|
||||
void instrRR(X64Instr op, Reg32 x, Reg32 y) { emitRR32(op, rn(x), rn(y)); }
|
||||
void instrRR(X64Instr op, Reg8 x, Reg8 y) { emitRR8(op, rn(x), rn(y)); }
|
||||
void instrRR(X64Instr op, RegXMM x, RegXMM y) { emitRR(op, rn(x), rn(y)); }
|
||||
void instrM(X64Instr op, MemoryRef m) { emitM(op, UMR(m)); }
|
||||
void instrM(X64Instr op, IndexedMemoryRef m) { emitM(op, UIMR(m)); }
|
||||
void instrM32(X64Instr op, MemoryRef m) { emitM32(op, UMR(m)); }
|
||||
void instrM16(X64Instr op, MemoryRef m) { emitM16(op, UMR(m)); }
|
||||
|
||||
void instrRM(X64Instr op,
|
||||
Reg64 r,
|
||||
@@ -2402,9 +2315,6 @@ private:
|
||||
void instrRM(X64Instr op,
|
||||
Reg32 r,
|
||||
MemoryRef m) { emitRM32(op, UMR(m), rn(r)); }
|
||||
void instrRM(X64Instr op,
|
||||
Reg16 r,
|
||||
MemoryRef m) { emitRM16(op, UMR(m), rn(r)); }
|
||||
void instrRM(X64Instr op,
|
||||
Reg8 r,
|
||||
MemoryRef m) { emitRM8(op, UMR(m), rn(r)); }
|
||||
@@ -2414,9 +2324,6 @@ private:
|
||||
void instrRM(X64Instr op,
|
||||
Reg32 r,
|
||||
IndexedMemoryRef m) { emitRM32(op, UIMR(m), rn(r)); }
|
||||
void instrRM(X64Instr op,
|
||||
Reg16 r,
|
||||
IndexedMemoryRef m) { emitRM16(op, UIMR(m), rn(r)); }
|
||||
void instrRM(X64Instr op,
|
||||
Reg8 r,
|
||||
IndexedMemoryRef m) { emitRM8(op, UIMR(m), rn(r)); }
|
||||
@@ -2433,9 +2340,6 @@ private:
|
||||
void instrMR(X64Instr op,
|
||||
MemoryRef m,
|
||||
Reg32 r) { emitMR32(op, UMR(m), rn(r)); }
|
||||
void instrMR(X64Instr op,
|
||||
MemoryRef m,
|
||||
Reg16 r) { emitMR16(op, UMR(m), rn(r)); }
|
||||
void instrMR(X64Instr op,
|
||||
MemoryRef m,
|
||||
Reg8 r) { emitMR8(op, UMR(m), rn(r)); }
|
||||
@@ -2445,9 +2349,6 @@ private:
|
||||
void instrMR(X64Instr op,
|
||||
IndexedMemoryRef m,
|
||||
Reg32 r) { emitMR32(op, UIMR(m), rn(r)); }
|
||||
void instrMR(X64Instr op,
|
||||
IndexedMemoryRef m,
|
||||
Reg16 r) { emitMR16(op, UIMR(m), rn(r)); }
|
||||
void instrMR(X64Instr op,
|
||||
IndexedMemoryRef m,
|
||||
Reg8 r) { emitMR8(op, UIMR(m), rn(r)); }
|
||||
@@ -2468,9 +2369,6 @@ private:
|
||||
void instrIR(X64Instr op, Immed i, Reg32 r) {
|
||||
emitIR32(op, rn(r), i.l());
|
||||
}
|
||||
void instrIR(X64Instr op, Immed i, Reg16 r) {
|
||||
emitIR16(op, rn(r), i.w());
|
||||
}
|
||||
void instrIR(X64Instr op, Immed i, Reg8 r) {
|
||||
emitIR8(op, rn(r), i.b());
|
||||
}
|
||||
@@ -2481,9 +2379,6 @@ private:
|
||||
void instrIM32(X64Instr op, Immed i, MemoryRef m) {
|
||||
emitIM32(op, UMR(m), i.l());
|
||||
}
|
||||
void instrIM16(X64Instr op, Immed i, MemoryRef m) {
|
||||
emitIM16(op, UMR(m), i.w());
|
||||
}
|
||||
void instrIM8(X64Instr op, Immed i, MemoryRef m) {
|
||||
emitIM8(op, UMR(m), i.b());
|
||||
}
|
||||
@@ -2494,9 +2389,6 @@ private:
|
||||
void instrIM32(X64Instr op, Immed i, IndexedMemoryRef m) {
|
||||
emitIM32(op, UIMR(m), i.l());
|
||||
}
|
||||
void instrIM16(X64Instr op, Immed i, IndexedMemoryRef m) {
|
||||
emitIM16(op, UIMR(m), i.w());
|
||||
}
|
||||
void instrIM8(X64Instr op, Immed i, IndexedMemoryRef m) {
|
||||
emitIM8(op, UIMR(m), i.b());
|
||||
}
|
||||
|
||||
@@ -351,10 +351,8 @@ typedef void (Asm::*OpIR32)(Immed, Reg32);
|
||||
typedef void (Asm::*OpIR8)(Immed, Reg8);
|
||||
typedef void (Asm::*OpIM64)(Immed, MemoryRef);
|
||||
typedef void (Asm::*OpIM32)(Immed, MemoryRef);
|
||||
typedef void (Asm::*OpIM16)(Immed, MemoryRef);
|
||||
typedef void (Asm::*OpISM64)(Immed, IndexedMemoryRef);
|
||||
typedef void (Asm::*OpISM32)(Immed, IndexedMemoryRef);
|
||||
typedef void (Asm::*OpISM16)(Immed, IndexedMemoryRef);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -460,83 +458,6 @@ TEST(Asm, General) {
|
||||
doingByteOpcodes = false;
|
||||
}
|
||||
|
||||
TEST(Asm, WordSizeInstructions) {
|
||||
Asm a;
|
||||
a.init(10 << 24);
|
||||
|
||||
// single register operations
|
||||
a. incw (ax);
|
||||
// single memory operations
|
||||
a. decw (*r8);
|
||||
// register-register operations
|
||||
a. addw (ax, bx);
|
||||
a. xorw (r10w, r11w);
|
||||
a. movw (cx, si);
|
||||
// register-memory operations
|
||||
a. storew (ax, *rbx);
|
||||
a. testw (r10w, rsi[0x10]);
|
||||
// memory-register operations
|
||||
a. subw (*rcx, ax);
|
||||
a. orw (r11[0x100], dx);
|
||||
// immediate-register operations
|
||||
a. shlw (0x3, di);
|
||||
a. andw (0x5555, r12w);
|
||||
// immediate-memory operations
|
||||
a. storew (0x1, *r9);
|
||||
a. storew (0x1, rax[0x100]);
|
||||
|
||||
expect_asm(a, R"(
|
||||
inc %ax
|
||||
decw (%r8)
|
||||
add %ax,%bx
|
||||
xor %r10w,%r11w
|
||||
mov %cx,%si
|
||||
mov %ax,(%rbx)
|
||||
test %r10w,0x10(%rsi)
|
||||
sub (%rcx),%ax
|
||||
or 0x100(%r11),%dx
|
||||
shl $0x3,%di
|
||||
and $0x5555,%r12w
|
||||
movw $0x1,(%r9)
|
||||
movw $0x1,0x100(%rax)
|
||||
)");
|
||||
}
|
||||
|
||||
TEST(Asm, IncDecRegs) {
|
||||
Asm a;
|
||||
a.init(10 << 24);
|
||||
|
||||
// incq, incl, incw
|
||||
a. incq(rax);
|
||||
a. incl(eax);
|
||||
a. incw(ax);
|
||||
a. incq(r15);
|
||||
a. incl(r15d);
|
||||
a. incw(r15w);
|
||||
// decq, decl, decw
|
||||
a. decq(rax);
|
||||
a. decl(eax);
|
||||
a. decw(ax);
|
||||
a. decq(r15);
|
||||
a. decl(r15d);
|
||||
a. decw(r15w);
|
||||
|
||||
expect_asm(a, R"(
|
||||
inc %rax
|
||||
inc %eax
|
||||
inc %ax
|
||||
inc %r15
|
||||
inc %r15d
|
||||
inc %r15w
|
||||
dec %rax
|
||||
dec %eax
|
||||
dec %ax
|
||||
dec %r15
|
||||
dec %r15d
|
||||
dec %r15w
|
||||
)");
|
||||
}
|
||||
|
||||
TEST(Asm, HighByteReg) {
|
||||
Asm a;
|
||||
a.init(10 << 24);
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário