Implement NotI and NotD. (bug 732952, r=jbramley)
authorMarty Rosenberg <mrosenberg@mozilla.com>
Tue, 06 Mar 2012 02:05:51 -0800
changeset 112237 d72074514c6fa4aec75323b18f135b0e720f3e7a
parent 112236 bd6f0d8274571f8d08a88934a4157f438a8621ad
child 112240 9c866973398c487baf4771af084ffc1c9cfd29f2
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjbramley
bugs732952
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Implement NotI and NotD. (bug 732952, r=jbramley)
js/src/ion/arm/CodeGenerator-arm.cpp
js/src/ion/arm/CodeGenerator-arm.h
js/src/ion/arm/MacroAssembler-arm.cpp
--- a/js/src/ion/arm/CodeGenerator-arm.cpp
+++ b/js/src/ion/arm/CodeGenerator-arm.cpp
@@ -1131,16 +1131,60 @@ CodeGeneratorARM::visitCompareDAndBranch
     Assembler::Condition cond = masm.compareDoubles(comp->jsop(), lhs, rhs);
     // TODO: we don't handle anything that has an undefined in it.
     emitBranch(cond, comp->ifTrue(), comp->ifFalse());
     //    Assembler::Condition cond = masm.compareDoubles(comp->jsop(), lhs, rhs);
 
     return true;
 }
 
+bool
+CodeGeneratorARM::visitNotI(LNotI *ins)
+{
+    // It is hard to optimize !x, so just do it the basic way for now.
+    masm.ma_cmp(ToRegister(ins->input()), Imm32(0));
+    emitSet(Assembler::Equal, ToRegister(ins->output()));
+    return true;
+}
+
+bool
+CodeGeneratorARM::visitNotD(LNotD *ins)
+{
+    // Since this operation is not, we want to set a bit if
+    // the double is falsey, which means 0.0, -0.0 or NaN.
+    // when comparing with 0, an input of 0 will set the Z bit (30)
+    // and NaN will set the V bit (28) of the APSR.
+    FloatRegister opd = ToFloatRegister(ins->input());
+    Register dest = ToRegister(ins->output());
+
+    // Do the compare
+    masm.ma_vcmpz(opd);
+    bool nocond = true;
+    if (nocond) {
+        // Load the value into the dest register
+        masm.as_vmrs(dest);
+        masm.ma_lsr(Imm32(28), dest, dest);
+        masm.ma_alu(dest, lsr(dest, 2), dest, op_orr); // 28 + 2 = 30
+        masm.ma_and(Imm32(1), dest);
+    } else {
+        masm.as_vmrs(pc);
+        masm.ma_mov(Imm32(0), dest);
+        masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal);
+        masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow);
+#if 0
+        masm.as_vmrs(ToRegister(dest));
+        // Mask out just the two bits we care about.  If neither bit is set,
+        // the dest is already zero
+        masm.ma_and(Imm32(0x50000000), dest, dest, Assembler::SetCond);
+        // If it is non-zero, then force it to be 1.
+        masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::NotEqual);
+#endif
+    }
+    return true;
+}
 
 bool
 CodeGeneratorARM::visitLoadSlotV(LLoadSlotV *load)
 {
     const ValueOperand out = ToOutValue(load);
     Register base = ToRegister(load->input());
     int32 offset = load->mir()->slot() * sizeof(js::Value);
 
--- a/js/src/ion/arm/CodeGenerator-arm.h
+++ b/js/src/ion/arm/CodeGenerator-arm.h
@@ -114,16 +114,18 @@ class CodeGeneratorARM : public CodeGene
     virtual bool visitShiftOp(LShiftOp *ins);
 
     virtual bool visitTestIAndBranch(LTestIAndBranch *test);
     virtual bool visitCompare(LCompare *comp);
     virtual bool visitCompareAndBranch(LCompareAndBranch *comp);
     virtual bool visitTestDAndBranch(LTestDAndBranch *test);
     virtual bool visitCompareD(LCompareD *comp);
     virtual bool visitCompareDAndBranch(LCompareDAndBranch *comp);
+    virtual bool visitNotI(LNotI *ins);
+    virtual bool visitNotD(LNotD *ins);
 
     virtual bool visitMathD(LMathD *math);
     virtual bool visitRound(LRound *lir);
     virtual bool visitTableSwitch(LTableSwitch *ins);
 
 
     // Out of line visitors.
     bool visitOutOfLineBailout(OutOfLineBailout *ool);
--- a/js/src/ion/arm/MacroAssembler-arm.cpp
+++ b/js/src/ion/arm/MacroAssembler-arm.cpp
@@ -1391,17 +1391,20 @@ MacroAssemblerARMCompat::addPtr(Imm32 im
 {
     ma_add(imm, dest);
 }
 
 // higher level tag testing code
 Assembler::Condition
 MacroAssemblerARMCompat::compareDoubles(JSOp compare, FloatRegister lhs, FloatRegister rhs)
 {
-    ma_vcmp(lhs, rhs);
+    if (rhs == InvalidFloatReg)
+        ma_vcmpz(lhs);
+    else
+        ma_vcmp(lhs, rhs);
     as_vmrs(pc);
     switch (compare) {
       case JSOP_STRICTNE:
       case JSOP_NE:
         return Assembler::VFP_NotEqualOrUnordered;
       case JSOP_STRICTEQ:
       case JSOP_EQ:
         return Assembler::VFP_Equal;