Test only low 8 bits for bool return values (
bug 733248, r=pierron).
--- a/js/src/assembler/assembler/X86Assembler.h
+++ b/js/src/assembler/assembler/X86Assembler.h
@@ -221,16 +221,17 @@ private:
#endif
PRE_OPERAND_SIZE = 0x66,
PRE_SSE_66 = 0x66,
OP_PUSH_Iz = 0x68,
OP_IMUL_GvEvIz = 0x69,
OP_GROUP1_EbIb = 0x80,
OP_GROUP1_EvIz = 0x81,
OP_GROUP1_EvIb = 0x83,
+ OP_TEST_EbGb = 0x84,
OP_TEST_EvGv = 0x85,
OP_XCHG_EvGv = 0x87,
OP_MOV_EbGv = 0x88,
OP_MOV_EvGv = 0x89,
OP_MOV_GvEv = 0x8B,
OP_LEA = 0x8D,
OP_GROUP1A_Ev = 0x8F,
OP_NOP = 0x90,
@@ -1266,16 +1267,24 @@ public:
void testl_rr(RegisterID src, RegisterID dst)
{
js::JaegerSpew(js::JSpew_Insns,
IPFX "testl %s, %s\n", MAYBE_PAD,
nameIReg(4,src), nameIReg(4,dst));
m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
}
+
+ void testb_rr(RegisterID src, RegisterID dst)
+ {
+ js::JaegerSpew(js::JSpew_Insns,
+ IPFX "testb %s, %s\n", MAYBE_PAD,
+ nameIReg(1,src), nameIReg(1,dst));
+ m_formatter.oneByteOp(OP_TEST_EbGb, src, dst);
+ }
void testl_i32r(int imm, RegisterID dst)
{
js::JaegerSpew(js::JSpew_Insns,
IPFX "testl $0x%x, %s\n", MAYBE_PAD,
imm, nameIReg(dst));
m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
m_formatter.immediate32(imm);
--- a/js/src/ion/shared/Assembler-x86-shared.h
+++ b/js/src/ion/shared/Assembler-x86-shared.h
@@ -496,16 +496,21 @@ class AssemblerX86Shared
break;
default:
JS_NOT_REACHED("unexpected operand kind");
}
}
void setCC(Condition cond, const Register &r) {
masm.setCC_r(static_cast<JSC::X86Assembler::Condition>(cond), r.code());
}
+ void testb(const Register &lhs, const Register &rhs) {
+ JS_ASSERT(GeneralRegisterSet(Registers::SingleByteRegs).has(lhs));
+ JS_ASSERT(GeneralRegisterSet(Registers::SingleByteRegs).has(rhs));
+ masm.testb_rr(rhs.code(), lhs.code());
+ }
void testl(const Register &lhs, const Register &rhs) {
masm.testl_rr(rhs.code(), lhs.code());
}
void testl(const Register &lhs, Imm32 rhs) {
masm.testl_i32r(rhs.value, lhs.code());
}
void testl(const Operand &lhs, Imm32 rhs) {
switch (lhs.kind()) {
--- a/js/src/ion/x64/Trampoline-x64.cpp
+++ b/js/src/ion/x64/Trampoline-x64.cpp
@@ -564,17 +564,18 @@ IonCompartment::generateVMWrapper(JSCont
// Test for failure.
Label exception;
switch (f.failType()) {
case Type_Object:
masm.testq(rax, rax);
masm.j(Assembler::Zero, &exception);
break;
case Type_Bool:
- masm.branchTest32(Assembler::Zero, eax, eax, &exception);
+ masm.testb(rax, rax);
+ masm.j(Assembler::Zero, &exception);
break;
default:
JS_NOT_REACHED("unknown failure kind");
break;
}
// Load the outparam and free any allocated stack.
switch (f.outParam) {
--- a/js/src/ion/x86/Trampoline-x86.cpp
+++ b/js/src/ion/x86/Trampoline-x86.cpp
@@ -583,17 +583,29 @@ IonCompartment::generateVMWrapper(JSCont
// Copy the implicit outparam, if any.
if (outReg != InvalidReg)
masm.passABIArg(outReg);
masm.callWithABI(f.wrapped);
// Test for failure.
Label exception;
- masm.branchTest32(Assembler::Zero, eax, eax, &exception);
+ switch (f.failType()) {
+ case Type_Object:
+ masm.testl(eax, eax);
+ masm.j(Assembler::Zero, &exception);
+ break;
+ case Type_Bool:
+ masm.testb(eax, eax);
+ masm.j(Assembler::Zero, &exception);
+ break;
+ default:
+ JS_NOT_REACHED("unknown failure kind");
+ break;
+ }
// Load the outparam and free any allocated stack.
switch (f.outParam) {
case Type_Value:
masm.loadValue(Address(esp, 0), JSReturnOperand);
masm.freeStack(sizeof(Value));
break;