зеркало из https://github.com/mozilla/pjs.git
Bug 607225 - nanojit: add MODRM() and SIB() to Nativei386.cpp, plus other clean-ups. r=rreitmai.
--HG-- extra : convert_revision : 5012f8eb917c654d4756025fd90f1f98a1f07626
This commit is contained in:
Родитель
e597faeb24
Коммит
1fc09caf80
|
@ -79,48 +79,44 @@ namespace nanojit
|
|||
typedef Register R;
|
||||
typedef int32_t I32;
|
||||
|
||||
// XXX rearrange NanoAssert() expression to workaround apparent gcc 4.3 bug:
|
||||
// XXX "error: logical && with non-zero constant will always evaluate as true"
|
||||
// underrunProtect(6) is necessary for worst-case
|
||||
// Length: 2--6 bytes.
|
||||
inline void Assembler::MODRMsib(I32 r, R b, R i, I32 s, I32 d) {
|
||||
NanoAssert(REGNUM(i) < 8 && REGNUM(b) < 8 && unsigned(r) < 8);
|
||||
if (d == 0 && b != rEBP) {
|
||||
*(--_nIns) = uint8_t(s << 6 | REGNUM(i) << 3 | REGNUM(b));
|
||||
*(--_nIns) = uint8_t(0 << 6 | r << 3 | 4);
|
||||
SIB(s, REGNUM(i), REGNUM(b));
|
||||
MODRM(0, r, 4); // amode == (b + i<<s)
|
||||
} else if (isS8(d)) {
|
||||
*(--_nIns) = uint8_t(d);
|
||||
*(--_nIns) = uint8_t(s << 6 | REGNUM(i) << 3 | REGNUM(b));
|
||||
*(--_nIns) = uint8_t(1 << 6 | r << 3 | 4);
|
||||
SIB(s, REGNUM(i), REGNUM(b));
|
||||
MODRM(1, r, 4); // amode == d8(b + i<<s)
|
||||
} else {
|
||||
IMM32(d);
|
||||
*(--_nIns) = uint8_t(s << 6 | REGNUM(i) << 3 | REGNUM(b));
|
||||
*(--_nIns) = uint8_t(2 << 6 | r << 3 | 4);
|
||||
SIB(s, REGNUM(i), REGNUM(b));
|
||||
MODRM(2, r, 4); // amode == d32(b + i<<s)
|
||||
}
|
||||
}
|
||||
|
||||
// underrunProtect(6) is necessary for worst-case
|
||||
// Length: 1--6 bytes.
|
||||
inline void Assembler::MODRMm(I32 r, I32 d, R b) {
|
||||
NanoAssert(unsigned(r) < 8 && (b == UnspecifiedReg || REGNUM(b) < 8));
|
||||
if (b == UnspecifiedReg) {
|
||||
IMM32(d);
|
||||
*(--_nIns) = uint8_t(0 << 6 | r << 3 | 5);
|
||||
MODRM(0, r, 5); // amode == (d32)
|
||||
} else if (b == rESP) {
|
||||
MODRMsib(r, b, rESP, 0, d);
|
||||
MODRMsib(r, b, rESP, 0, d); // amode == d(b)
|
||||
} else if (d == 0 && b != rEBP) {
|
||||
*(--_nIns) = uint8_t(0 << 6 | r << 3 | REGNUM(b));
|
||||
MODRM(0, r, REGNUM(b)); // amode == (r)
|
||||
} else if (isS8(d)) {
|
||||
*(--_nIns) = uint8_t(d);
|
||||
*(--_nIns) = uint8_t(1 << 6 | r << 3 | REGNUM(b));
|
||||
MODRM(1, r, REGNUM(b)); // amode == d8(b)
|
||||
} else {
|
||||
IMM32(d);
|
||||
*(--_nIns) = uint8_t(2 << 6 | r << 3 | REGNUM(b));
|
||||
MODRM(2, r, REGNUM(b)); // amode == d32(b)
|
||||
}
|
||||
}
|
||||
|
||||
// Length: 5 bytes.
|
||||
inline void Assembler::MODRMdm(I32 r, I32 addr) {
|
||||
NanoAssert(unsigned(r) < 8);
|
||||
IMM32(addr);
|
||||
*(--_nIns) = uint8_t(r << 3 | 5);
|
||||
MODRM(0, r, 5); // amode == d32(r)
|
||||
}
|
||||
|
||||
inline void Assembler::ALU0(I32 o) {
|
||||
|
@ -186,14 +182,14 @@ namespace nanojit
|
|||
NanoAssert(REGNUM(r) < 8);
|
||||
if (isS8(i)) {
|
||||
*(--_nIns) = uint8_t(i);
|
||||
MODRM(c>>3, REGNUM(r));
|
||||
MODRMr(c>>3, REGNUM(r));
|
||||
*(--_nIns) = uint8_t(0x83);
|
||||
} else {
|
||||
IMM32(i);
|
||||
if ( r == rEAX) {
|
||||
*(--_nIns) = uint8_t(c);
|
||||
} else {
|
||||
MODRM(c >> 3, REGNUM(r));
|
||||
MODRMr(c >> 3, REGNUM(r));
|
||||
*(--_nIns) = uint8_t(0x81);
|
||||
}
|
||||
}
|
||||
|
@ -215,7 +211,7 @@ namespace nanojit
|
|||
|
||||
inline void Assembler::ALU2(I32 c, R d, R s) {
|
||||
underrunProtect(3);
|
||||
MODRM(REGNUM(d), REGNUM(s));
|
||||
MODRMr(REGNUM(d), REGNUM(s));
|
||||
*(--_nIns) = uint8_t(c);
|
||||
*(--_nIns) = uint8_t(c>>8);
|
||||
}
|
||||
|
@ -261,7 +257,7 @@ namespace nanojit
|
|||
inline void Assembler::SHIFT(I32 c, R r, I32 i) {
|
||||
underrunProtect(3);
|
||||
*--_nIns = uint8_t(i);
|
||||
MODRM(c, REGNUM(r));
|
||||
MODRMr(c, REGNUM(r));
|
||||
*--_nIns = 0xc1;
|
||||
}
|
||||
|
||||
|
@ -284,13 +280,12 @@ namespace nanojit
|
|||
inline void Assembler::CMPi(R r, I32 i) { count_alu(); ALUi(0x3d, r, i); asm_output("cmp %s,%d", gpn(r), i); }
|
||||
|
||||
inline void Assembler::LEA(R r, I32 d, R b) { count_alu(); ALUm(0x8d, REGNUM(r), d, b); asm_output("lea %s,%d(%s)", gpn(r), d, gpn(b)); }
|
||||
// lea %r, d(%i*4)
|
||||
// This addressing mode is not supported by the MODRMsib function.
|
||||
inline void Assembler::LEAmi4(R r, I32 d, R i) {
|
||||
count_alu();
|
||||
IMM32(int32_t(d));
|
||||
*(--_nIns) = uint8_t(2 << 6 | REGNUM(i) << 3 | 5);
|
||||
*(--_nIns) = uint8_t(0 << 6 | REGNUM(r) << 3 | 4);
|
||||
SIB(2, REGNUM(i), 5);
|
||||
MODRM(0, REGNUM(r), 4); // amode == d(i*4)
|
||||
*(--_nIns) = 0x8d;
|
||||
asm_output("lea %s, %p(%s*4)", gpn(r), (void*)d, gpn(i));
|
||||
}
|
||||
|
@ -557,18 +552,13 @@ namespace nanojit
|
|||
*(--_nIns) = 0x6a;
|
||||
asm_output("push %d", i);
|
||||
} else {
|
||||
PUSHi32(i);
|
||||
underrunProtect(5);
|
||||
IMM32(i);
|
||||
*(--_nIns) = 0x68;
|
||||
asm_output("push %d", i);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Assembler::PUSHi32(I32 i) {
|
||||
count_push();
|
||||
underrunProtect(5);
|
||||
IMM32(i);
|
||||
*(--_nIns) = 0x68;
|
||||
asm_output("push %d", i);
|
||||
}
|
||||
|
||||
inline void Assembler::PUSHr(R r) {
|
||||
count_push();
|
||||
underrunProtect(1);
|
||||
|
@ -627,10 +617,10 @@ namespace nanojit
|
|||
|
||||
inline void Assembler::JMP_indexed(Register x, I32 ss, NIns** addr) {
|
||||
underrunProtect(7);
|
||||
IMM32(int32_t(addr));
|
||||
*(--_nIns) = uint8_t(ss << 6 | REGNUM(x) << 3 | 5); /* sib: x<<ss + table */
|
||||
*(--_nIns) = uint8_t(0 << 6 | 4 << 3 | 4); /* modrm: base=sib + disp32 */
|
||||
*(--_nIns) = uint8_t(0xff); /* jmp */
|
||||
IMM32(int32_t(addr));
|
||||
SIB(ss, REGNUM(x), 5);
|
||||
MODRM(0, 4, 4); // amode == addr(table + x<<ss)
|
||||
*(--_nIns) = uint8_t(0xff); // jmp
|
||||
asm_output("jmp *(%s*%d+%p)", gpn(x), 1 << ss, (void*)addr);
|
||||
}
|
||||
|
||||
|
@ -665,7 +655,7 @@ namespace nanojit
|
|||
// sse instructions
|
||||
inline void Assembler::SSE(I32 c, R d, R s) {
|
||||
underrunProtect(9);
|
||||
MODRM(REGNUM(d)&7, REGNUM(s)&7);
|
||||
MODRMr(REGNUM(d)&7, REGNUM(s)&7);
|
||||
*(--_nIns) = uint8_t(c & 0xff);
|
||||
*(--_nIns) = uint8_t((c >> 8) & 0xff);
|
||||
*(--_nIns) = uint8_t((c >> 16) & 0xff);
|
||||
|
@ -691,10 +681,11 @@ namespace nanojit
|
|||
count_ldq();
|
||||
underrunProtect(8);
|
||||
IMM32(int32_t(addr));
|
||||
*(--_nIns) = uint8_t((REGNUM(r) & 7) << 3 | 5);
|
||||
MODRM(0, REGNUM(r) & 7, 5); // amode == addr(r)
|
||||
*(--_nIns) = 0x10;
|
||||
*(--_nIns) = 0x0f;
|
||||
*(--_nIns) = 0xf2;
|
||||
// *addr is a constant, so we can print it here.
|
||||
asm_output("movsd %s,(%p) // =%f", gpn(r), (void*)addr, *addr);
|
||||
}
|
||||
|
||||
|
@ -705,14 +696,14 @@ namespace nanojit
|
|||
{
|
||||
count_ldq();
|
||||
SSEsib(0xf30f7e, rr, d, rb, ri, scale);
|
||||
asm_output("movq %s,%d(%s+%s*%d)", gpn(rr), d, gpn(rb), gpn(ri), SIBIDX(scale));
|
||||
asm_output("movq %s,%d(%s+%s*%c)", gpn(rr), d, gpn(rb), gpn(ri), SIBIDX(scale));
|
||||
}
|
||||
|
||||
inline void Assembler::SSE_LDSSsib(R rr, I32 d, R rb, R ri, I32 scale)
|
||||
{
|
||||
count_ld();
|
||||
SSEsib(0xf30f10, rr, d, rb, ri, scale);
|
||||
asm_output("movss %s,%d(%s+%s*%d)", gpn(rr), d, gpn(rb), gpn(ri), SIBIDX(scale));
|
||||
asm_output("movss %s,%d(%s+%s*%c)", gpn(rr), d, gpn(rb), gpn(ri), SIBIDX(scale));
|
||||
}
|
||||
|
||||
inline void Assembler::SSE_STSD(I32 d, R b, R r) { count_stq(); SSEm(0xf20f11, r, d, b); asm_output("movsd %d(%s),%s", d, gpn(b), gpn(r)); }
|
||||
|
@ -722,7 +713,7 @@ namespace nanojit
|
|||
inline void Assembler::SSE_STQsib(I32 d, R rb, R ri, I32 scale, R rv) {
|
||||
count_stq();
|
||||
SSEsib(0x660fd6, rv, d, rb, ri, scale);
|
||||
asm_output("movq %d(%s+%s*%d),%s", d, gpn(rb), gpn(ri), scale, gpn(rv));
|
||||
asm_output("movq %d(%s+%s*%c),%s", d, gpn(rb), gpn(ri), SIBIDX(scale), gpn(rv));
|
||||
}
|
||||
|
||||
inline void Assembler::SSE_CVTSI2SD(R xr, R gr) { count_fpu(); SSE(0xf20f2a, xr, gr); asm_output("cvtsi2sd %s,%s", gpn(xr), gpn(gr)); }
|
||||
|
@ -765,11 +756,12 @@ namespace nanojit
|
|||
NanoAssert(IsXmmReg(r));
|
||||
const double* daddr = addr;
|
||||
IMM32(int32_t(daddr));
|
||||
*(--_nIns) = uint8_t((REGNUM(r) & 7) << 3 | 5);
|
||||
MODRM(0, REGNUM(r) & 7, 5); // amode == daddr(r)
|
||||
*(--_nIns) = 0x58;
|
||||
*(--_nIns) = 0x0f;
|
||||
*(--_nIns) = 0xf2;
|
||||
asm_output("addsd %s,%p // =%f", gpn(r), (void*)daddr, *daddr);
|
||||
// *daddr is a constant, so we can print it here.
|
||||
asm_output("addsd %s,(%p) // =%f", gpn(r), (void*)daddr, *daddr);
|
||||
}
|
||||
|
||||
inline void Assembler::SSE_SUBSD(R rd, R rs) {
|
||||
|
@ -804,11 +796,11 @@ namespace nanojit
|
|||
count_fpuld();
|
||||
underrunProtect(8);
|
||||
IMM32(int32_t(maskaddr));
|
||||
*(--_nIns) = uint8_t((REGNUM(r) & 7) << 3 | 5);
|
||||
MODRM(0, REGNUM(r) & 7, 5); // amode == maskaddr(r)
|
||||
*(--_nIns) = 0x57;
|
||||
*(--_nIns) = 0x0f;
|
||||
*(--_nIns) = 0x66;
|
||||
asm_output("xorpd %s,[%p]", gpn(r), (void*)maskaddr);
|
||||
asm_output("xorpd %s,(%p)", gpn(r), (void*)maskaddr);
|
||||
}
|
||||
|
||||
inline void Assembler::SSE_XORPDr(R rd, R rs) {
|
||||
|
|
|
@ -204,26 +204,37 @@ namespace nanojit
|
|||
void asm_div_mod(LIns *cond); \
|
||||
void asm_load(int d, Register r); \
|
||||
void asm_immd(Register r, uint64_t q, double d, bool canClobberCCs); \
|
||||
void IMM8(int32_t i) { \
|
||||
\
|
||||
/* These function generate fragments of instructions. */ \
|
||||
void IMM8(int32_t i) { /* Length: 1 byte. */ \
|
||||
_nIns -= 1; \
|
||||
*((int8_t*)_nIns) = int8_t(i); \
|
||||
}; \
|
||||
void IMM16(int32_t i) { \
|
||||
void IMM16(int32_t i) { /* Length: 2 bytes. */ \
|
||||
_nIns -= 2; \
|
||||
*((int16_t*)_nIns) = int16_t(i); \
|
||||
}; \
|
||||
void IMM32(int32_t i) { \
|
||||
void IMM32(int32_t i) { /* Length: 4 bytes. */ \
|
||||
_nIns -= 4; \
|
||||
*((int32_t*)_nIns) = int32_t(i); \
|
||||
}; \
|
||||
void MODRM(int32_t mod, int32_t ro, int32_t rm) { /* Length: 1 byte. */ \
|
||||
NanoAssert(unsigned(mod) < 4 && unsigned(ro) < 8 && unsigned(rm) < 8); \
|
||||
*(--_nIns) = uint8_t(mod << 6 | ro << 3 | rm); \
|
||||
} \
|
||||
void SIB(int32_t s, int32_t i, int32_t b) { /* Length: 1 byte. */ \
|
||||
NanoAssert(unsigned(s) < 4 && unsigned(i) < 8 && unsigned(b) < 8); \
|
||||
*(--_nIns) = uint8_t(s << 6 | i << 3 | b); \
|
||||
} \
|
||||
void MODRMr(int32_t d, int32_t s) { /* Length: 1 byte. */ \
|
||||
NanoAssert(unsigned(d) < 8 && unsigned(s) < 8); \
|
||||
MODRM(3, d, s); \
|
||||
}; \
|
||||
void MODRMm(int32_t r, int32_t d, Register b); \
|
||||
void MODRMsib(int32_t r, Register b, Register i, int32_t s, int32_t d); \
|
||||
void MODRMdm(int32_t r, int32_t addr); \
|
||||
/* d may be a register number or something else */ \
|
||||
void MODRM(int32_t d, int32_t s) { \
|
||||
NanoAssert(unsigned(d) < 8 && unsigned(s) < 8); \
|
||||
*(--_nIns) = uint8_t(3 << 6 | d << 3 | s); \
|
||||
}; \
|
||||
\
|
||||
/* These functions generate entire instructions. */ \
|
||||
void ALU0(int32_t o); \
|
||||
void ALUm(int32_t c, int32_t r, int32_t d, Register b); \
|
||||
void ALUdm(int32_t c, Register r, int32_t addr); \
|
||||
|
@ -233,10 +244,9 @@ namespace nanojit
|
|||
void ALU2dm(int32_t c, Register r, int32_t addr); \
|
||||
void ALU2m(int32_t c, Register r, int32_t d, Register b); \
|
||||
void ALU2sib(int32_t c, Register r, Register base, Register index, int32_t scale, int32_t disp); \
|
||||
/* d may be a register number or something else */ \
|
||||
void ALU(int32_t c, int32_t d, Register s) { \
|
||||
underrunProtect(2); \
|
||||
MODRM(d, REGNUM(s)); \
|
||||
MODRMr(d, REGNUM(s)); \
|
||||
*(--_nIns) = uint8_t(c); \
|
||||
}; \
|
||||
void ALUi(int32_t c, Register r, int32_t i); \
|
||||
|
@ -334,7 +344,6 @@ namespace nanojit
|
|||
void NOP(); \
|
||||
void INT3(); \
|
||||
void PUSHi(int32_t i); \
|
||||
void PUSHi32(int32_t i); \
|
||||
void PUSHr(Register r); \
|
||||
void PUSHm(int32_t d, Register b); \
|
||||
void POPr(Register r); \
|
||||
|
|
Загрузка…
Ссылка в новой задаче