Bug 1183060 - wrong code generated for x86 word operations. r=sunfish

This commit is contained in:
Lars T Hansen 2015-08-05 09:20:28 +02:00
parent 8a8be84533
commit bb47fb0015
3 changed files with 521 additions and 10 deletions

View File

@ -0,0 +1,55 @@
if (!this.SharedArrayBuffer)
quit(0);
function loadModule_uint16(stdlib, foreign, heap) {
"use asm";
var atomic_add = stdlib.Atomics.add;
var atomic_sub = stdlib.Atomics.sub;
var atomic_and = stdlib.Atomics.and;
var atomic_or = stdlib.Atomics.or;
var atomic_xor = stdlib.Atomics.xor;
var i16a = new stdlib.SharedUint16Array(heap);
function do_add_i(i) {
i = i|0;
var v = 0;
v = atomic_add(i16a, i>>1, 0x3333)|0;
}
function do_sub_i(i) {
i = i|0;
var v = 0;
v = atomic_sub(i16a, i>>1, 0x3333)|0;
}
function do_and_i(i) {
i = i|0;
var v = 0;
v = atomic_and(i16a, i>>1, 0x3333)|0;
}
function do_or_i(i) {
i = i|0;
var v = 0;
v = atomic_or(i16a, i>>1, 0x3333)|0;
}
function do_xor_i(i) {
i = i|0;
var v = 0;
v = atomic_xor(i16a, i>>1, 0x3333)|0;
}
return { add_i: do_add_i,
sub_i: do_sub_i,
and_i: do_and_i,
or_i: do_or_i,
xor_i: do_xor_i };
}
function test_uint16(heap) {
var i16m = loadModule_uint16(this, {}, heap);
var size = SharedUint16Array.BYTES_PER_ELEMENT;
i16m.add_i(size*40)
i16m.sub_i(size*40)
i16m.and_i(size*40)
i16m.or_i(size*40)
i16m.xor_i(size*40)
}
var heap = new SharedArrayBuffer(65536);
test_uint16(heap);

View File

@ -1129,6 +1129,24 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_CRASH("unexpected operand kind");
}
}
void addw(Imm32 imm, const Operand& op) {
switch (op.kind()) {
case Operand::REG:
masm.addw_ir(imm.value, op.reg());
break;
case Operand::MEM_REG_DISP:
masm.addw_im(imm.value, op.disp(), op.base());
break;
case Operand::MEM_ADDRESS32:
masm.addw_im(imm.value, op.address());
break;
case Operand::MEM_SCALE:
masm.addw_im(imm.value, op.disp(), op.base(), op.index(), op.scale());
break;
default:
MOZ_CRASH("unexpected operand kind");
}
}
void subl(Imm32 imm, Register dest) {
masm.subl_ir(imm.value, dest.encoding());
}
@ -1147,6 +1165,21 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_CRASH("unexpected operand kind");
}
}
void subw(Imm32 imm, const Operand& op) {
switch (op.kind()) {
case Operand::REG:
masm.subw_ir(imm.value, op.reg());
break;
case Operand::MEM_REG_DISP:
masm.subw_im(imm.value, op.disp(), op.base());
break;
case Operand::MEM_SCALE:
masm.subw_im(imm.value, op.disp(), op.base(), op.index(), op.scale());
break;
default:
MOZ_CRASH("unexpected operand kind");
}
}
void addl(Register src, Register dest) {
masm.addl_rr(src.encoding(), dest.encoding());
}
@ -1165,6 +1198,21 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_CRASH("unexpected operand kind");
}
}
void addw(Register src, const Operand& dest) {
switch (dest.kind()) {
case Operand::REG:
masm.addw_rr(src.encoding(), dest.reg());
break;
case Operand::MEM_REG_DISP:
masm.addw_rm(src.encoding(), dest.disp(), dest.base());
break;
case Operand::MEM_SCALE:
masm.addw_rm(src.encoding(), dest.disp(), dest.base(), dest.index(), dest.scale());
break;
default:
MOZ_CRASH("unexpected operand kind");
}
}
void subl(Register src, Register dest) {
masm.subl_rr(src.encoding(), dest.encoding());
}
@ -1195,6 +1243,21 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_CRASH("unexpected operand kind");
}
}
void subw(Register src, const Operand& dest) {
switch (dest.kind()) {
case Operand::REG:
masm.subw_rr(src.encoding(), dest.reg());
break;
case Operand::MEM_REG_DISP:
masm.subw_rm(src.encoding(), dest.disp(), dest.base());
break;
case Operand::MEM_SCALE:
masm.subw_rm(src.encoding(), dest.disp(), dest.base(), dest.index(), dest.scale());
break;
default:
MOZ_CRASH("unexpected operand kind");
}
}
void orl(Register reg, Register dest) {
masm.orl_rr(reg.encoding(), dest.encoding());
}
@ -1213,6 +1276,21 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_CRASH("unexpected operand kind");
}
}
void orw(Register src, const Operand& dest) {
switch (dest.kind()) {
case Operand::REG:
masm.orw_rr(src.encoding(), dest.reg());
break;
case Operand::MEM_REG_DISP:
masm.orw_rm(src.encoding(), dest.disp(), dest.base());
break;
case Operand::MEM_SCALE:
masm.orw_rm(src.encoding(), dest.disp(), dest.base(), dest.index(), dest.scale());
break;
default:
MOZ_CRASH("unexpected operand kind");
}
}
void orl(Imm32 imm, Register reg) {
masm.orl_ir(imm.value, reg.encoding());
}
@ -1231,6 +1309,21 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_CRASH("unexpected operand kind");
}
}
void orw(Imm32 imm, const Operand& op) {
switch (op.kind()) {
case Operand::REG:
masm.orw_ir(imm.value, op.reg());
break;
case Operand::MEM_REG_DISP:
masm.orw_im(imm.value, op.disp(), op.base());
break;
case Operand::MEM_SCALE:
masm.orw_im(imm.value, op.disp(), op.base(), op.index(), op.scale());
break;
default:
MOZ_CRASH("unexpected operand kind");
}
}
void xorl(Register src, Register dest) {
masm.xorl_rr(src.encoding(), dest.encoding());
}
@ -1249,6 +1342,21 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_CRASH("unexpected operand kind");
}
}
void xorw(Register src, const Operand& dest) {
switch (dest.kind()) {
case Operand::REG:
masm.xorw_rr(src.encoding(), dest.reg());
break;
case Operand::MEM_REG_DISP:
masm.xorw_rm(src.encoding(), dest.disp(), dest.base());
break;
case Operand::MEM_SCALE:
masm.xorw_rm(src.encoding(), dest.disp(), dest.base(), dest.index(), dest.scale());
break;
default:
MOZ_CRASH("unexpected operand kind");
}
}
void xorl(Imm32 imm, Register reg) {
masm.xorl_ir(imm.value, reg.encoding());
}
@ -1267,6 +1375,21 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_CRASH("unexpected operand kind");
}
}
void xorw(Imm32 imm, const Operand& op) {
switch (op.kind()) {
case Operand::REG:
masm.xorw_ir(imm.value, op.reg());
break;
case Operand::MEM_REG_DISP:
masm.xorw_im(imm.value, op.disp(), op.base());
break;
case Operand::MEM_SCALE:
masm.xorw_im(imm.value, op.disp(), op.base(), op.index(), op.scale());
break;
default:
MOZ_CRASH("unexpected operand kind");
}
}
void andl(Register src, Register dest) {
masm.andl_rr(src.encoding(), dest.encoding());
}
@ -1285,6 +1408,21 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_CRASH("unexpected operand kind");
}
}
void andw(Register src, const Operand& dest) {
switch (dest.kind()) {
case Operand::REG:
masm.andw_rr(src.encoding(), dest.reg());
break;
case Operand::MEM_REG_DISP:
masm.andw_rm(src.encoding(), dest.disp(), dest.base());
break;
case Operand::MEM_SCALE:
masm.andw_rm(src.encoding(), dest.disp(), dest.base(), dest.index(), dest.scale());
break;
default:
MOZ_CRASH("unexpected operand kind");
}
}
void andl(Imm32 imm, Register dest) {
masm.andl_ir(imm.value, dest.encoding());
}
@ -1303,6 +1441,21 @@ class AssemblerX86Shared : public AssemblerShared
MOZ_CRASH("unexpected operand kind");
}
}
void andw(Imm32 imm, const Operand& op) {
switch (op.kind()) {
case Operand::REG:
masm.andw_ir(imm.value, op.reg());
break;
case Operand::MEM_REG_DISP:
masm.andw_im(imm.value, op.disp(), op.base());
break;
case Operand::MEM_SCALE:
masm.andw_im(imm.value, op.disp(), op.base(), op.index(), op.scale());
break;
default:
MOZ_CRASH("unexpected operand kind");
}
}
void addl(const Operand& src, Register dest) {
switch (src.kind()) {
case Operand::REG:
@ -1622,32 +1775,27 @@ class AssemblerX86Shared : public AssemblerShared
template<typename T>
void lock_addw(T src, const Operand& op) {
masm.prefix_lock();
masm.prefix_16_for_32();
addl(src, op);
addw(src, op);
}
template<typename T>
void lock_subw(T src, const Operand& op) {
masm.prefix_lock();
masm.prefix_16_for_32();
subl(src, op);
subw(src, op);
}
template<typename T>
void lock_andw(T src, const Operand& op) {
masm.prefix_lock();
masm.prefix_16_for_32();
andl(src, op);
andw(src, op);
}
template<typename T>
void lock_orw(T src, const Operand& op) {
masm.prefix_lock();
masm.prefix_16_for_32();
orl(src, op);
orw(src, op);
}
template<typename T>
void lock_xorw(T src, const Operand& op) {
masm.prefix_lock();
masm.prefix_16_for_32();
xorl(src, op);
xorw(src, op);
}
// Note, lock_addl(imm, op) is used for a memory barrier on non-SSE2 systems,

View File

@ -276,6 +276,13 @@ public:
m_formatter.oneByteOp(OP_ADD_GvEv, src, dst);
}
void addw_rr(RegisterID src, RegisterID dst)
{
spew("addw %s, %s", GPReg16Name(src), GPReg16Name(dst));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_ADD_GvEv, src, dst);
}
void addl_mr(int32_t offset, RegisterID base, RegisterID dst)
{
spew("addl " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
@ -308,6 +315,15 @@ public:
m_formatter.immediate32(imm);
}
}
void addw_ir(int32_t imm, RegisterID dst)
{
spew("addw $%d, %s", int16_t(imm), GPReg16Name(dst));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_ADD);
m_formatter.immediate16(imm);
}
void addl_i32r(int32_t imm, RegisterID dst)
{
// 32-bit immediate always, for patching.
@ -412,6 +428,46 @@ public:
m_formatter.immediate32(imm);
}
}
void addw_im(int32_t imm, const void* addr)
{
spew("addw $%d, %p", int16_t(imm), addr);
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, addr, GROUP1_OP_ADD);
m_formatter.immediate8s(imm);
} else {
m_formatter.oneByteOp(OP_GROUP1_EvIz, addr, GROUP1_OP_ADD);
m_formatter.immediate16(imm);
}
}
void addw_im(int32_t imm, int32_t offset, RegisterID base) {
spew("addw $%d, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_ADD);
m_formatter.immediate16(imm);
}
void addw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("addw $%d, " MEM_obs, int16_t(imm), ADDR_obs(offset, base, index, scale));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_ADD);
m_formatter.immediate16(imm);
}
void addw_rm(RegisterID src, int32_t offset, RegisterID base) {
spew("addw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, src);
}
void addw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("addw %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_ADD_EvGv, offset, base, index, scale, src);
}
void addb_im(int32_t imm, int32_t offset, RegisterID base) {
spew("addb $%d, " MEM_ob, int8_t(imm), ADDR_ob(offset, base));
@ -693,6 +749,13 @@ public:
m_formatter.oneByteOp(OP_AND_GvEv, src, dst);
}
void andw_rr(RegisterID src, RegisterID dst)
{
spew("andw %s, %s", GPReg16Name(src), GPReg16Name(dst));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_AND_GvEv, src, dst);
}
void andl_mr(int32_t offset, RegisterID base, RegisterID dst)
{
spew("andl " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
@ -705,12 +768,26 @@ public:
m_formatter.oneByteOp(OP_AND_EvGv, offset, base, src);
}
void andw_rm(RegisterID src, int32_t offset, RegisterID base)
{
spew("andw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_AND_EvGv, offset, base, src);
}
void andl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("andl %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
m_formatter.oneByteOp(OP_AND_EvGv, offset, base, index, scale, src);
}
void andw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("andw %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_AND_EvGv, offset, base, index, scale, src);
}
void andl_ir(int32_t imm, RegisterID dst)
{
spew("andl $0x%x, %s", imm, GPReg32Name(dst));
@ -726,6 +803,22 @@ public:
}
}
void andw_ir(int32_t imm, RegisterID dst)
{
spew("andw $0x%x, %s", int16_t(imm), GPReg16Name(dst));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_AND);
m_formatter.immediate8s(imm);
} else {
if (dst == rax)
m_formatter.oneByteOp(OP_AND_EAXIv);
else
m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_AND);
m_formatter.immediate16(imm);
}
}
void andl_im(int32_t imm, int32_t offset, RegisterID base)
{
spew("andl $0x%x, " MEM_ob, imm, ADDR_ob(offset, base));
@ -738,6 +831,19 @@ public:
}
}
void andw_im(int32_t imm, int32_t offset, RegisterID base)
{
spew("andw $0x%x, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_AND);
m_formatter.immediate8s(imm);
} else {
m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_AND);
m_formatter.immediate16(imm);
}
}
void andl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("andl $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
@ -750,6 +856,19 @@ public:
}
}
void andw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("andw $%d, " MEM_obs, int16_t(imm), ADDR_obs(offset, base, index, scale));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_AND);
m_formatter.immediate8s(imm);
} else {
m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_AND);
m_formatter.immediate16(imm);
}
}
#ifdef JS_CODEGEN_X64
void andq_rr(RegisterID src, RegisterID dst)
{
@ -871,6 +990,13 @@ public:
m_formatter.oneByteOp(OP_OR_GvEv, src, dst);
}
void orw_rr(RegisterID src, RegisterID dst)
{
spew("orw %s, %s", GPReg16Name(src), GPReg16Name(dst));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_OR_GvEv, src, dst);
}
void orl_mr(int32_t offset, RegisterID base, RegisterID dst)
{
spew("orl " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
@ -883,12 +1009,26 @@ public:
m_formatter.oneByteOp(OP_OR_EvGv, offset, base, src);
}
void orw_rm(RegisterID src, int32_t offset, RegisterID base)
{
spew("orw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_OR_EvGv, offset, base, src);
}
void orl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("orl %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
m_formatter.oneByteOp(OP_OR_EvGv, offset, base, index, scale, src);
}
void orw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("orw %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_OR_EvGv, offset, base, index, scale, src);
}
void orl_ir(int32_t imm, RegisterID dst)
{
spew("orl $0x%x, %s", imm, GPReg32Name(dst));
@ -904,6 +1044,22 @@ public:
}
}
void orw_ir(int32_t imm, RegisterID dst)
{
spew("orw $0x%x, %s", int16_t(imm), GPReg16Name(dst));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_OR);
m_formatter.immediate8s(imm);
} else {
if (dst == rax)
m_formatter.oneByteOp(OP_OR_EAXIv);
else
m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_OR);
m_formatter.immediate16(imm);
}
}
void orl_im(int32_t imm, int32_t offset, RegisterID base)
{
spew("orl $0x%x, " MEM_ob, imm, ADDR_ob(offset, base));
@ -916,6 +1072,19 @@ public:
}
}
void orw_im(int32_t imm, int32_t offset, RegisterID base)
{
spew("orw $0x%x, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_OR);
m_formatter.immediate8s(imm);
} else {
m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_OR);
m_formatter.immediate16(imm);
}
}
void orl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("orl $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
@ -928,6 +1097,19 @@ public:
}
}
void orw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("orw $%d, " MEM_obs, int16_t(imm), ADDR_obs(offset, base, index, scale));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_OR);
m_formatter.immediate8s(imm);
} else {
m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_OR);
m_formatter.immediate16(imm);
}
}
#ifdef JS_CODEGEN_X64
void negq_r(RegisterID dst)
{
@ -981,6 +1163,13 @@ public:
m_formatter.oneByteOp(OP_SUB_GvEv, src, dst);
}
void subw_rr(RegisterID src, RegisterID dst)
{
spew("subw %s, %s", GPReg16Name(src), GPReg16Name(dst));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_SUB_GvEv, src, dst);
}
void subl_mr(int32_t offset, RegisterID base, RegisterID dst)
{
spew("subl " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
@ -993,12 +1182,26 @@ public:
m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, src);
}
void subw_rm(RegisterID src, int32_t offset, RegisterID base)
{
spew("subw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, src);
}
void subl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("subl %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, index, scale, src);
}
void subw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("subw %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_SUB_EvGv, offset, base, index, scale, src);
}
void subl_ir(int32_t imm, RegisterID dst)
{
spew("subl $%d, %s", imm, GPReg32Name(dst));
@ -1014,6 +1217,22 @@ public:
}
}
void subw_ir(int32_t imm, RegisterID dst)
{
spew("subw $%d, %s", int16_t(imm), GPReg16Name(dst));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_SUB);
m_formatter.immediate8s(imm);
} else {
if (dst == rax)
m_formatter.oneByteOp(OP_SUB_EAXIv);
else
m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_SUB);
m_formatter.immediate16(imm);
}
}
void subl_im(int32_t imm, int32_t offset, RegisterID base)
{
spew("subl $%d, " MEM_ob, imm, ADDR_ob(offset, base));
@ -1026,6 +1245,19 @@ public:
}
}
void subw_im(int32_t imm, int32_t offset, RegisterID base)
{
spew("subw $%d, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_SUB);
m_formatter.immediate8s(imm);
} else {
m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_SUB);
m_formatter.immediate16(imm);
}
}
void subl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("subl $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
@ -1038,6 +1270,19 @@ public:
}
}
void subw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("subw $%d, " MEM_obs, int16_t(imm), ADDR_obs(offset, base, index, scale));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_SUB);
m_formatter.immediate8s(imm);
} else {
m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_SUB);
m_formatter.immediate16(imm);
}
}
#ifdef JS_CODEGEN_X64
void subq_rr(RegisterID src, RegisterID dst)
{
@ -1097,6 +1342,13 @@ public:
m_formatter.oneByteOp(OP_XOR_GvEv, src, dst);
}
void xorw_rr(RegisterID src, RegisterID dst)
{
spew("xorw %s, %s", GPReg16Name(src), GPReg16Name(dst));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_XOR_GvEv, src, dst);
}
void xorl_mr(int32_t offset, RegisterID base, RegisterID dst)
{
spew("xorl " MEM_ob ", %s", ADDR_ob(offset, base), GPReg32Name(dst));
@ -1109,12 +1361,26 @@ public:
m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, src);
}
void xorw_rm(RegisterID src, int32_t offset, RegisterID base)
{
spew("xorw %s, " MEM_ob, GPReg16Name(src), ADDR_ob(offset, base));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, src);
}
void xorl_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("xorl %s, " MEM_obs, GPReg32Name(src), ADDR_obs(offset, base, index, scale));
m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, index, scale, src);
}
void xorw_rm(RegisterID src, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("xorw %s, " MEM_obs, GPReg16Name(src), ADDR_obs(offset, base, index, scale));
m_formatter.prefix(PRE_OPERAND_SIZE);
m_formatter.oneByteOp(OP_XOR_EvGv, offset, base, index, scale, src);
}
void xorl_im(int32_t imm, int32_t offset, RegisterID base)
{
spew("xorl $0x%x, " MEM_ob, imm, ADDR_ob(offset, base));
@ -1127,6 +1393,19 @@ public:
}
}
void xorw_im(int32_t imm, int32_t offset, RegisterID base)
{
spew("xorw $0x%x, " MEM_ob, int16_t(imm), ADDR_ob(offset, base));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, GROUP1_OP_XOR);
m_formatter.immediate8s(imm);
} else {
m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, GROUP1_OP_XOR);
m_formatter.immediate16(imm);
}
}
void xorl_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("xorl $%d, " MEM_obs, imm, ADDR_obs(offset, base, index, scale));
@ -1139,6 +1418,19 @@ public:
}
}
void xorw_im(int32_t imm, int32_t offset, RegisterID base, RegisterID index, int scale)
{
spew("xorw $%d, " MEM_obs, int16_t(imm), ADDR_obs(offset, base, index, scale));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, offset, base, index, scale, GROUP1_OP_XOR);
m_formatter.immediate8s(imm);
} else {
m_formatter.oneByteOp(OP_GROUP1_EvIz, offset, base, index, scale, GROUP1_OP_XOR);
m_formatter.immediate16(imm);
}
}
void xorl_ir(int32_t imm, RegisterID dst)
{
spew("xorl $%d, %s", imm, GPReg32Name(dst));
@ -1154,6 +1446,22 @@ public:
}
}
void xorw_ir(int32_t imm, RegisterID dst)
{
spew("xorw $%d, %s", int16_t(imm), GPReg16Name(dst));
m_formatter.prefix(PRE_OPERAND_SIZE);
if (CAN_SIGN_EXTEND_8_32(imm)) {
m_formatter.oneByteOp(OP_GROUP1_EvIb, dst, GROUP1_OP_XOR);
m_formatter.immediate8s(imm);
} else {
if (dst == rax)
m_formatter.oneByteOp(OP_XOR_EAXIv);
else
m_formatter.oneByteOp(OP_GROUP1_EvIz, dst, GROUP1_OP_XOR);
m_formatter.immediate16(imm);
}
}
#ifdef JS_CODEGEN_X64
void xorq_rr(RegisterID src, RegisterID dst)
{