Support arithmetic with branch on overflow on MIPS -- bug 560926 (r=rreitmai+)
authorWilliam Maddox <wmaddox@adobe.com>
Thu, 27 May 2010 18:00:45 -0700
changeset 43274 7e5432180193e89a1338254bb6a4c4581b3dd21b
parent 43273 e2405f332a7bc270a2e5c755906cff1cf2070f10
child 43275 da5bf2ad82ed2aeeb9100b273df0604e2e6823dd
push idunknown
push userunknown
push dateunknown
reviewersrreitmai
bugs560926
milestone1.9.3a5pre
Support arithmetic with branch on overflow on MIPS -- bug 560926 (r=rreitmai+) Adds support for MIPS target lacking in earlier patch. Bug 560926 - Add support for arithmetic with branch on overflow We simply extend the existing logic for exit-on-overflow in the manner done for other targets. There appear to other issues with oveflow detection in general that are not dealt with here.
js/src/nanojit/NativeMIPS.cpp
--- a/js/src/nanojit/NativeMIPS.cpp
+++ b/js/src/nanojit/NativeMIPS.cpp
@@ -949,36 +949,39 @@ namespace nanojit
         allow &= ~rmask(ra);
 
         if (rhs->isImmI()) {
             int32_t rhsc = rhs->immI();
             if (isS16(rhsc)) {
                 // MIPS arith immediate ops sign-extend the imm16 value
                 switch (op) {
                 case LIR_addxovi:
+                case LIR_addjovi:
                     SLT(AT, rr, ra);
                     ADDIU(rr, ra, rhsc);
                     goto done;
                 case LIR_addi:
                     ADDIU(rr, ra, rhsc);
                     goto done;
                 case LIR_subxovi:
+                case LIR_subjovi:
                     if (isS16(-rhsc)) {
                         SLT(AT, ra, rr);
                         ADDIU(rr, ra, -rhsc);
                         goto done;
                     }
                     break;
                 case LIR_subi:
                     if (isS16(-rhsc)) {
                         ADDIU(rr, ra, -rhsc);
                         goto done;
                     }
                     break;
                 case LIR_mulxovi:
+                case LIR_muljovi:
                 case LIR_muli:
                     // FIXME: optimise constant multiply by 2^n
                     // if ((rhsc & (rhsc-1)) == 0)
                     //    SLL(rr, ra, ffs(rhsc)-1);
                     //goto done;
                     break;
                 default:
                     break;
@@ -1019,32 +1022,34 @@ namespace nanojit
 
         // general case, put rhs in register
         rb = (rhs == lhs) ? ra : findRegFor(rhs, allow);
         NanoAssert(deprecated_isKnownReg(rb));
         allow &= ~rmask(rb);
 
         switch (op) {
             case LIR_addxovi:
+            case LIR_addjovi:
                 SLT(AT, rr, ra);
                 ADDU(rr, ra, rb);
                 break;
             case LIR_addi:
                 ADDU(rr, ra, rb);
                 break;
             case LIR_andi:
                 AND(rr, ra, rb);
                 break;
             case LIR_ori:
                 OR(rr, ra, rb);
                 break;
             case LIR_xori:
                 XOR(rr, ra, rb);
                 break;
             case LIR_subxovi:
+            case LIR_subjovi:
                 SLT(AT,ra,rr);
                 SUBU(rr, ra, rb);
                 break;
             case LIR_subi:
                 SUBU(rr, ra, rb);
                 break;
             case LIR_lshi:
                 SLLV(rr, ra, rb);
@@ -1054,16 +1059,17 @@ namespace nanojit
                 SRAV(rr, ra, rb);
                 ANDI(rb, rb, 31);
                 break;
             case LIR_rshui:
                 SRLV(rr, ra, rb);
                 ANDI(rb, rb, 31);
                 break;
             case LIR_mulxovi:
+            case LIR_muljovi:
                 t = registerAllocTmp(allow);
                 // Overflow indication required
                 // Do a 32x32 signed multiply generating a 64 bit result
                 // Compare bit31 of the result with the high order bits
                 // mult $ra,$rb
                 // mflo $rr             # result to $rr
                 // sra  $t,$rr,31       # $t = 0x00000000 or 0xffffffff
                 // mfhi $at
@@ -1476,24 +1482,25 @@ namespace nanojit
                 BADOPCODE(condop);
             }
         }
         TAG("asm_bxx(branchOnFalse=%d, condop=%s, ra=%s rb=%s targ=%p)",
             branchOnFalse, lirNames[condop], gpn(ra), gpn(rb), targ);
         return patch;
     }
 
-    void Assembler::asm_branch_ov(LOpcode op, NIns* target)
+    NIns* Assembler::asm_branch_ov(LOpcode op, NIns* target)
     {
         USE(op);
         NanoAssert(target != NULL);
 
-        (void) asm_bxx(true, LIR_eqi, AT, ZERO, target);
+        NIns* patch = asm_bxx(true, LIR_eqi, AT, ZERO, target);
 
         TAG("asm_branch_ov(op=%s, target=%p)", lirNames[op], target);
+        return patch;
     }
 
     NIns* Assembler::asm_branch(bool branchOnFalse, LIns *cond, NIns * const targ)
     {
         NanoAssert(cond->isCmp());
         LOpcode condop = cond->opcode();
         RegisterMask allow = isCmpDOpcode(condop) ? FpRegs : GpRegs;
         LIns *a = cond->oprnd1();