diff --git a/js/src/nanojit/NativeSparc.h b/js/src/nanojit/NativeSparc.h
index 2a69caa..462ffc8 100644
--- a/js/src/nanojit/NativeSparc.h
+++ b/js/src/nanojit/NativeSparc.h
@@ -71,7 +71,7 @@
 {
     const int NJ_MAX_REGISTERS = 30; // L0 - L7, I0 - I5, F2 - F14
 
-    const int LARGEST_UNDERRUN_PROT = 32;  // largest value passed to underrunProtect
+    const int LARGEST_UNDERRUN_PROT = 72;  // largest value passed to underrunProtect
 
 #define NJ_MAX_STACK_ENTRY              8192
 #define NJ_MAX_PARAMETERS               1
@@ -203,16 +203,18 @@
 #define DECLARE_PLATFORM_REGALLOC()
 
 #define DECLARE_PLATFORM_ASSEMBLER()    \
+     friend class SafeUnderrunProtect; \
      const static Register argRegs[6], retRegs[1]; \
      void nativePageReset(); \
      void nativePageSetup(); \
      void underrunProtect(int bytes); \
      bool hardenNopInsertion(const Config& /*c*/) { return false; } \
      void asm_align_code(); \
-     void asm_cmp(LIns *cond); \
-     void asm_cmpd(LIns *cond); \
+     void asm_cmp(LIns* cond); \
+     void asm_cmpd(LIns* cond); \
      NIns* asm_branchd(bool, LIns*, NIns*); \
      void IMM32(int32_t i) { \
+         underrunProtect(4); \
          --_nIns; \
          *((int32_t*)_nIns) = i; \
      } \
@@ -294,16 +296,16 @@
     void Format_4_5(Register rd, int32_t op3, int32_t cond, int32_t opf_cc, int32_t opf_low, Register rs2) { \
         Format_3A(2, rd, op3, (cond & 0xF) << 14 | (opf_cc & 0x7) << 11 | (opf_low & 0x3F) << 5 | _reg_(rs2)); \
     } \
-    void IntegerOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char *opcode); \
-    void IntegerOperationI(Register rs1, int32_t simm13, Register rd, int32_t op3, const char *opcode); \
-    void FloatOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char *opcode); \
-    void Bicc(int32_t a, int32_t dsp22, int32_t cond, const char *opcode); \
-    void FBfcc(int32_t a, int32_t dsp22, int32_t cond, const char *opcode); \
+    void IntegerOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode); \
+    void IntegerOperationI(Register rs1, int32_t simm13, Register rd, int32_t op3, const char* opcode); \
+    void FloatOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode); \
+    void Bicc(int32_t a, int32_t dsp22, int32_t cond, const char* opcode); \
+    void FBfcc(int32_t a, int32_t dsp22, int32_t cond, const char* opcode); \
     void LoadOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode); \
     void LoadOperationI(Register rs1, int32_t simm13, Register rd, int32_t op3, const char* opcode); \
-    void MOVcc(Register rs, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char *opcode); \
-    void MOVccI(int32_t simm11, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char *opcode); \
-    void FMOVDcc(Register rs, int32_t opt_cc, Register rd, int32_t cond, const char *opcode); \
+    void MOVcc(Register rs, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char* opcode); \
+    void MOVccI(int32_t simm11, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char* opcode); \
+    void FMOVDcc(Register rs, int32_t opt_cc, Register rd, int32_t cond, const char* opcode); \
     void ShiftOperation(Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode); \
     void ShiftOperationI(Register rs1, int32_t shcnt32, Register rd, int32_t op3, const char* opcode); \
     void Store(Register rd, Register rs1, Register rs2, int32_t op3, const char* opcode); \
@@ -442,14 +444,13 @@
     void STB(Register rd, Register rs1, Register rs2); \
     void STBI(Register rd, int32_t simm13, Register rs1); \
     void STB32(Register rd, int32_t immI, Register rs1); \
-    bool isIMM13(int32_t imm) { return (imm) <= 0xfff && (imm) >= -0x1000; } \
-    bool isIMM19(int32_t imm) { return (imm) <= 0x3ffff && (imm) >= -0x40000; } \
-    bool isIMM22(int32_t imm) { return (imm) <= 0x1fffff && (imm) >= -0x200000; } \
-    void JMP_long_nocheck(int32_t t); \
+    static bool isIMM13(int32_t imm) { return (imm) <= 0xfff && (imm) >= -0x1000; } \
+    static bool isIMM19(int32_t imm) { return (imm) <= 0x3ffff && (imm) >= -0x40000; } \
+    static bool isIMM22(int32_t imm) { return (imm) <= 0x1fffff && (imm) >= -0x200000; } \
     void JMP_long(int32_t t); \
     void JMP_long_placeholder(); \
-    int32_t JCC(void *t); \
-    void JMP(void *t); \
+    int32_t JCC(void* t); \
+    void JMP(void* t); \
     void MR(Register rd, Register rs);
 }
 #endif // __nanojit_NativeSparc__
--- a/js/src/jsapi.cpp	2011-06-22 22:05:28.108252350 +0800
+++ b/js/src/jsapi.cpp	2011-06-22 22:06:13.458823300 +0800
@@ -2763,6 +2763,12 @@
 JS_PUBLIC_API(void)
 JS_SetNativeStackQuota(JSContext *cx, size_t stackSize)
 {
+#ifdef JS_CPU_SPARC
+    stackSize = stackSize * 8; // more stack is required on SPARC
+#else
+    // stackSize = stackSize * 2; // PGO needs more stack, why?
+#endif
+
 #ifdef JS_THREADSAFE
     JS_ASSERT(cx->thread());
 #endif
diff --git a/js/src/nanojit/NativeSparc.cpp b/js/src/nanojit/NativeSparc.cpp
index 029a22a..a73be3d 100644
--- a/js/src/nanojit/NativeSparc.cpp
+++ b/js/src/nanojit/NativeSparc.cpp
@@ -47,9 +47,33 @@
 namespace nanojit
 {
 #ifdef FEATURE_NANOJIT
+    class SafeUnderrunProtect
+    {
+        public:
+            SafeUnderrunProtect(Assembler* assembler, int n)
+            {
+                _nprotect = n;
+                _assembler = assembler;
+                _assembler->underrunProtect(n);
+                _priorIns = _assembler->_nIns;
+                _priorStart = _assembler->codeStart;
+            };
 
+            ~SafeUnderrunProtect()
+            {
+                NanoAssert(_priorStart == _assembler->codeStart);
+                NanoAssert((intptr_t)_priorIns - (intptr_t)_assembler->_nIns <= _nprotect);
+            };
+
+        private:
+            int _nprotect;
+            Assembler* _assembler;
+            NIns* _priorIns;
+            NIns* _priorStart;
+    };
+
 #ifdef NJ_VERBOSE
-    const char *regNames[] = {
+    const char* regNames[] = {
         "%g0", "%g1", "%g2", "%g3", "%g4", "%g5", "%g6", "%g7",
         "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%sp", "%o7",
         "%l0", "%l1", "%l2", "%l3", "%l4", "%l5", "%l6", "%l7",
@@ -79,13 +103,13 @@
     }
 
     inline void Assembler::IntegerOperation
-        (Register rs1, Register rs2, Register rd, int32_t op3, const char *opcode) {
+        (Register rs1, Register rs2, Register rd, int32_t op3, const char* opcode) {
         Format_3_1(2, rd, op3, rs1, 0, rs2);
         asm_output("%s %s, %s, %s", opcode, gpn(rs1), gpn(rs2), gpn(rd));
     }
 
     inline void Assembler::IntegerOperationI
-        (Register rs1, int32_t simm13, Register rd, int32_t op3, const char *opcode) {
+        (Register rs1, int32_t simm13, Register rd, int32_t op3, const char* opcode) {
         Format_3_1I(2, rd, op3, rs1, simm13);
         asm_output("%s %s, %d, %s", opcode, gpn(rs1), simm13, gpn(rd));
     }
@@ -127,9 +151,9 @@
         IntegerOperation(rs1, rs2, rd, 0x3, "xor");
     }
 
-    inline void Assembler::Bicc(int32_t a, int32_t dsp22, int32_t cond, const char *opcode) {
+    inline void Assembler::Bicc(int32_t a, int32_t dsp22, int32_t cond, const char* opcode) {
         Format_2_2(a, cond, 0x2, dsp22);
-        asm_output("%s 0x%x", opcode, _nIns + dsp22 - 1);
+        asm_output("%s 0x%x", opcode, _nIns + dsp22);
     }
 
     inline void Assembler::BA  (int32_t a, int32_t dsp22) { Bicc(a, dsp22, 0x8, "ba");   }
@@ -156,7 +180,7 @@
         asm_output("faddd %s, %s, %s", gpn(rs1), gpn(rs2), gpn(rd));
     }
 
-    inline void Assembler::FBfcc(int32_t a, int32_t dsp22, int32_t cond, const char *opcode) {
+    inline void Assembler::FBfcc(int32_t a, int32_t dsp22, int32_t cond, const char* opcode) {
         Format_2_2(a, cond, 0x6, dsp22);
         asm_output("%s 0x%x", opcode, _nIns + dsp22 - 1);
     }
@@ -179,7 +203,7 @@
     }
 
     inline void Assembler::FloatOperation
-        (Register rs1, Register rs2, Register rd, int32_t opf, const char *opcode) {
+        (Register rs1, Register rs2, Register rd, int32_t opf, const char* opcode) {
         Format_3_8(2, rd, 0x34, rs1, opf, rs2);
         if (rs1 != G0) {
           asm_output("%s %s, %s, %s", opcode, gpn(rs1), gpn(rs2), gpn(rd));
@@ -347,13 +371,13 @@
     }
 
     inline void Assembler::MOVcc
-        (Register rs, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char *opcode) {
+        (Register rs, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char* opcode) {
         Format_4_2(rd, 0x2c, cc2, cond, cc1, cc0, rs);
         asm_output("%s %s, %s", opcode, gpn(rs), gpn(rd));
     }
 
     inline void Assembler::MOVccI
-        (int32_t simm11, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char *opcode) {
+        (int32_t simm11, int32_t cc2, int32_t cc1, int32_t cc0, Register rd, int32_t cond, const char* opcode) {
         Format_4_2I(rd, 0x2c, cc2, cond, cc1, cc0, simm11);
         asm_output("%s 0x%x, %s", opcode, simm11, gpn(rd));
     }
@@ -386,7 +410,7 @@
     inline void Assembler::MOVFGI (int32_t simm11, Register rd) { MOVccI(simm11, 0, 0, 0, rd, 0x6, "movfg");  }
     inline void Assembler::MOVFGEI(int32_t simm11, Register rd) { MOVccI(simm11, 0, 0, 0, rd, 0xb, "movfge"); }
 
-    inline void Assembler::FMOVDcc(Register rs, int32_t opt_cc, Register rd, int32_t cond, const char *opcode) {
+    inline void Assembler::FMOVDcc(Register rs, int32_t opt_cc, Register rd, int32_t cond, const char* opcode) {
         Format_4_5(rd, 0x35, cond, opt_cc, 0x2, rs);
         asm_output("%s %s, %s", opcode, gpn(rs), gpn(rd));
     }
@@ -556,7 +580,19 @@
     }
 
     // general Assemble
-    inline void Assembler::JMP_long_nocheck(int32_t t) {
+    inline void Assembler::JMP_long(int32_t t) {
+        SafeUnderrunProtect protect(this, 16);
+    /*    if (t) {
+            int32_t tt = ((intptr_t)t - (intptr_t)_nIns + 16) >> 2;
+            if (isIMM22(tt)) {
+                NOP();
+                NOP();
+                NOP();
+                BA(0,tt);
+                return;
+            }
+        }
+*/
         NOP();
         JMPL(G0, G2, G0);
         ORI(G2, t & 0x3FF, G2);
@@ -563,17 +599,12 @@
         SETHI(t, G2);
     }
 
-    inline void Assembler::JMP_long(int32_t t) {
-        underrunProtect(16);
-        JMP_long_nocheck(t);
-    }
-
     inline void Assembler::JMP_long_placeholder() {
         JMP_long(0);
     }
 
-    inline int32_t Assembler::JCC(void *t) {
-        underrunProtect(32);
+    inline int32_t Assembler::JCC(void* t) {
+        SafeUnderrunProtect protect(this, 32);
         int32_t tt = ((intptr_t)t - (intptr_t)_nIns + 8) >> 2;
         if( !(isIMM22(tt)) ) {
             NOP();
@@ -587,7 +618,7 @@
         return tt;
     }
 
-    void Assembler::JMP(void *t) {
+    void Assembler::JMP(void* t) {
         if (!t) {
             JMP_long_placeholder();
         } else {
@@ -597,7 +628,6 @@
     }
 
     void Assembler::MR(Register rd, Register rs) {
-        underrunProtect(4);
         ORI(rs, 0, rd);
     }
 
@@ -612,7 +642,7 @@
         /**
          * Prologue
          */
-        underrunProtect(16);
+        SafeUnderrunProtect protect(this, 28);
         uint32_t stackNeeded = STACK_GRANULARITY * _activation.stackSlotsNeeded();
         uint32_t frameSize = stackNeeded + kcalleeAreaSize + kLinkageAreaSize;
         frameSize = BIT_ROUND_UP(frameSize, 8);
@@ -630,7 +660,7 @@
             outputf("        0x%x:",_nIns);
             outputf("        patch entry:");
         })
-        NIns *patchEntry = _nIns;
+        NIns* patchEntry = _nIns;
 
         // The frame size in SAVE is faked. We will still re-caculate SP later.
         // We can use 0 here but it is not good for debuggers.
@@ -642,7 +672,8 @@
         return patchEntry;
     }
 
-    void Assembler::asm_align_code() {
+    void Assembler::asm_align_code()
+    {
         while(uintptr_t(_nIns) & 15) {
             NOP();
         }
@@ -651,30 +682,27 @@
     void Assembler::nFragExit(LIns* guard)
     {
         SideExit* exit = guard->record()->exit;
-        Fragment *frag = exit->target;
-        GuardRecord *lr;
-        if (frag && frag->fragEntry)
-            {
-                JMP(frag->fragEntry);
-                lr = 0;
-            }
-        else
-            {
-                // Target doesn't exit yet. Emit jump to epilog, and set up to patch later.
-                if (!_epilogue)
-                    _epilogue = genEpilogue();
-                lr = guard->record();
-                JMP_long((intptr_t)_epilogue);
-                lr->jmp = _nIns;
-            }
+        Fragment* frag = exit->target;
+        GuardRecord* lr;
+        if (frag && frag->fragEntry) {
+            JMP(frag->fragEntry);
+            lr = 0;
+        } else {
+            // Target doesn't exit yet. Emit jump to epilog, and set up to patch later.
+            if (!_epilogue)
+                _epilogue = genEpilogue();
+            lr = guard->record();
+            JMP_long((intptr_t)_epilogue);
+            lr->jmp = _nIns;
+        }
 
         // return value is GuardRecord*
         SET32(int(lr), O0);
     }
 
-    NIns *Assembler::genEpilogue()
+    NIns* Assembler::genEpilogue()
     {
-        underrunProtect(12);
+        SafeUnderrunProtect protect(this, 12);
         RESTORE(G0, G0, G0); //restore
         JMPLI(I7, 8, G0); //ret
         ORI(O0, 0, I0);
@@ -684,19 +712,15 @@
     void Assembler::asm_call(LIns* ins)
     {
         if (!ins->isop(LIR_callv)) {
-            Register retReg = ( ins->isop(LIR_calld) ? F0 : retRegs[0] );
-            deprecated_prepResultReg(ins, rmask(retReg));
+            Register retReg = (ins->isop(LIR_calld) ? F0 : retRegs[0]);
+            prepareResultReg(ins, rmask(retReg));
+            evictScratchRegsExcept(rmask(retReg));
+        } else {
+            evictScratchRegsExcept(0);
         }
 
-        // Do this after we've handled the call result, so we don't
-        // force the call result to be spilled unnecessarily.
-        evictScratchRegsExcept(0);
-
         const CallInfo* ci = ins->callInfo();
 
-        underrunProtect(8);
-        NOP();
-
         ArgType argTypes[MAXARGS];
         uint32_t argc = ci->getArgTypes(argTypes);
 
@@ -704,53 +728,59 @@
                    ins->isop(LIR_calld));
         verbose_only(if (_logc->lcbits & LC_Native)
                      outputf("        0x%x:", _nIns);
-                     )
+                    )
         bool indirect = ci->isIndirect();
-        if (!indirect) {
-            CALL(ci);
+
+        {
+            SafeUnderrunProtect protect(this, 8);
+            NOP();
+            if (!indirect) {
+                CALL(ci);
+            }
+            else {
+                argc--;
+                Register r = findSpecificRegFor(ins->arg(argc), I0);
+                JMPL(G0, I0, O7);
+            }
         }
-        else {
-            argc--;
-            Register r = findSpecificRegFor(ins->arg(argc), I0);
-            JMPL(G0, I0, O7);
-        }
 
+        freeResourcesOf(ins);
+
         Register GPRIndex = O0;
         uint32_t offset = kLinkageAreaSize; // start of parameters stack postion.
 
-        for(int i=0; i<argc; i++)
-            {
-                uint32_t j = argc-i-1;
-                ArgType ty = argTypes[j];
-                if (ty == ARGTYPE_D) {
-                    Register r = findRegFor(ins->arg(j), FpRegs);
+        for (int i = 0; i < argc; i++) {
+            uint32_t j = argc-i-1;
+            ArgType ty = argTypes[j];
+            if (ty == ARGTYPE_D) {
+                Register r = findRegFor(ins->arg(j), FpRegs);
 
-                    underrunProtect(48);
-                    // We might be calling a varargs function.
-                    // So, make sure the GPR's are also loaded with
-                    // the value, or the stack contains it.
-                    if (GPRIndex <= O5) {
-                        LDSW32(SP, offset, GPRIndex);
-                    }
-                    GPRIndex = GPRIndex + 1;
-                    if (GPRIndex <= O5) {
-                        LDSW32(SP, offset+4, GPRIndex);
-                    }
-                    GPRIndex = GPRIndex + 1;
-                    STDF32(r, offset, SP);
-                    offset += 8;
+                SafeUnderrunProtect protect(this, 48);
+                // We might be calling a varargs function.
+                // So, make sure the GPR's are also loaded with
+                // the value, or the stack contains it.
+                if (GPRIndex <= O5) {
+                    LDSW32(SP, offset, GPRIndex);
+                }
+                GPRIndex = GPRIndex + 1;
+                if (GPRIndex <= O5) {
+                    LDSW32(SP, offset+4, GPRIndex);
+                }
+                GPRIndex = GPRIndex + 1;
+                STDF32(r, offset, SP);
+                offset += 8;
+            } else {
+                if (GPRIndex > O5) {
+                    SafeUnderrunProtect protect(this, 12);
+                    Register r = findRegFor(ins->arg(j), GpRegs);
+                    STW32(r, offset, SP);
                 } else {
-                    if (GPRIndex > O5) {
-                        underrunProtect(12);
-                        Register r = findRegFor(ins->arg(j), GpRegs);
-                        STW32(r, offset, SP);
-                    } else {
-                        Register r = findSpecificRegFor(ins->arg(j), GPRIndex);
-                    }
-                    GPRIndex = GPRIndex + 1;
-                    offset += 4;
+                    Register r = findSpecificRegFor(ins->arg(j), GPRIndex);
                 }
+                GPRIndex = GPRIndex + 1;
+                offset += 4;
             }
+        }
     }
 
     Register Assembler::nRegisterAllocFromSet(RegisterMask set)
@@ -771,10 +801,16 @@
 
     void Assembler::nPatchBranch(NIns* branch, NIns* location)
     {
-        *(uint32_t*)&branch[0] &= 0xFFC00000;
-        *(uint32_t*)&branch[0] |= ((intptr_t)location >> 10) & 0x3FFFFF;
-        *(uint32_t*)&branch[1] &= 0xFFFFFC00;
-        *(uint32_t*)&branch[1] |= (intptr_t)location & 0x3FF;
+        intptr_t addr_diff = ((intptr_t)location - (intptr_t)branch) >> 2;
+        if ( !isIMM22(addr_diff)) {
+            *(uint32_t*)&branch[0] = 0x05000000 | ((intptr_t)location >> 10) & 0x3FFFFF; // sethi ..., %g2
+            *(uint32_t*)&branch[1] = 0x8410a000 | (intptr_t)location & 0x3FF; // bset ..., %g2
+            *(uint32_t*)&branch[2] = 0x81c00002; // jmp %g2
+        } else {
+            *(uint32_t*)&branch[0] = 0x10800000 | (addr_diff & 0x3FFFFF); // ba
+            *(uint32_t*)&branch[1] = 0x01000000; // nop
+            *(uint32_t*)&branch[2] = 0x01000000; // nop
+        }
     }
 
     RegisterMask Assembler::nHint(LIns* ins)
@@ -791,10 +827,10 @@
 
     void Assembler::asm_restore(LIns* i, Register r)
     {
-        underrunProtect(24);
+        SafeUnderrunProtect protect(this, 24);
         if (i->isop(LIR_allocp)) {
             ADD(FP, L2, r);
-            int32_t d = deprecated_disp(i);
+            int32_t d = arDisp(i);
             SET32(d, L2);
         }
         else if (i->isImmI()) {
@@ -810,7 +846,7 @@
         }
     }
 
-    void Assembler::asm_store32(LOpcode op, LIns *value, int dr, LIns *base)
+    void Assembler::asm_store32(LOpcode op, LIns* value, int dr, LIns* base)
     {
         switch (op) {
             case LIR_sti:
@@ -823,53 +859,38 @@
                 return;
         }
 
-        underrunProtect(20);
-        if (value->isImmI())
-            {
-                Register rb = getBaseReg(base, dr, GpRegs);
-                int c = value->immI();
-                switch (op) {
-                case LIR_sti:
-                    STW32(L2, dr, rb);
-                    break;
-                case LIR_sti2c:
-                    STB32(L2, dr, rb);
-                    break;
-                case LIR_sti2s:
-                    STH32(L2, dr, rb);
-                    break;
-                }
-                SET32(c, L2);
+        SafeUnderrunProtect protect(this, 20);
+        if (value->isImmI()) {
+            Register rb = getBaseReg(base, dr, GpRegs);
+            int c = value->immI();
+            switch (op) {
+                case LIR_sti:   STW32(L2, dr, rb); break;
+                case LIR_sti2c: STB32(L2, dr, rb); break;
+                case LIR_sti2s: STH32(L2, dr, rb); break;
             }
-        else
-            {
-                // make sure what is in a register
-                Register ra, rb;
-                if (base->isImmI()) {
-                    // absolute address
-                    dr += base->immI();
-                    ra = findRegFor(value, GpRegs);
-                    rb = G0;
-                } else {
-                    getBaseReg2(GpRegs, value, ra, GpRegs, base, rb, dr);
-                }
-                switch (op) {
-                case LIR_sti:
-                    STW32(ra, dr, rb);
-                    break;
-                case LIR_sti2c:
-                    STB32(ra, dr, rb);
-                    break;
-                case LIR_sti2s:
-                    STH32(ra, dr, rb);
-                    break;
-                }
+            SET32(c, L2);
+        } else {
+            // make sure what is in a register
+            Register ra, rb;
+            if (base->isImmI()) {
+                // absolute address
+                dr += base->immI();
+                ra = findRegFor(value, GpRegs);
+                rb = G0;
+            } else {
+                getBaseReg2(GpRegs, value, ra, GpRegs, base, rb, dr);
             }
+            switch (op) {
+                case LIR_sti:   STW32(ra, dr, rb); break;
+                case LIR_sti2c: STB32(ra, dr, rb); break;
+                case LIR_sti2s: STH32(ra, dr, rb); break;
+            }
+        }
     }
 
     void Assembler::asm_spill(Register rr, int d, bool quad)
     {
-        underrunProtect(24);
+        SafeUnderrunProtect protect(this, 24);
         (void)quad;
         NanoAssert(d);
         if (rmask(rr) & FpRegs) {
@@ -891,7 +912,7 @@
                 return;
         }
 
-        underrunProtect(48);
+        SafeUnderrunProtect protect(this, 48);
         LIns* base = ins->oprnd1();
         int db = ins->disp();
         Register rb = getBaseReg(base, db, GpRegs);
@@ -936,7 +957,7 @@
                 return;
         }
 
-        underrunProtect(48);
+        SafeUnderrunProtect protect(this, 48);
         Register rb = getBaseReg(base, dr, GpRegs);
         if (op == LIR_std2f) {
             Register rv = ( !value->isInReg()
@@ -948,32 +969,30 @@
             return;
         }
 
-        if (value->isImmD())
-            {
-                // if a constant 64-bit value just store it now rather than
-                // generating a pointless store/load/store sequence
-                STW32(L2, dr+4, rb);
-                SET32(value->immDlo(), L2);
-                STW32(L2, dr, rb);
-                SET32(value->immDhi(), L2);
-                return;
-            }
+        if (value->isImmD()) {
+            // if a constant 64-bit value just store it now rather than
+            // generating a pointless store/load/store sequence
+            STW32(L2, dr+4, rb);
+            SET32(value->immDlo(), L2);
+            STW32(L2, dr, rb);
+            SET32(value->immDhi(), L2);
+            return;
+        }
 
-        if (value->isop(LIR_ldd))
-            {
-                // value is 64bit struct or int64_t, or maybe a double.
-                // it may be live in an FPU reg.  Either way, don't
-                // put it in an FPU reg just to load & store it.
+        if (value->isop(LIR_ldd)) {
+            // value is 64bit struct or int64_t, or maybe a double.
+            // it may be live in an FPU reg.  Either way, don't
+            // put it in an FPU reg just to load & store it.
 
-                // a) if we know it's not a double, this is right.
-                // b) if we guarded that its a double, this store could be on
-                // the side exit, copying a non-double.
-                // c) maybe its a double just being stored.  oh well.
+            // a) if we know it's not a double, this is right.
+            // b) if we guarded that its a double, this store could be on
+            // the side exit, copying a non-double.
+            // c) maybe its a double just being stored.  oh well.
 
-                int da = findMemFor(value);
-                asm_mmq(rb, dr, FP, da);
-                return;
-            }
+            int da = findMemFor(value);
+             asm_mmq(rb, dr, FP, da);
+             return;
+        }
 
         // if value already in a reg, use that, otherwise
         // get it into FPU regs.
@@ -1004,66 +1023,56 @@
         NIns* at = 0;
         LOpcode condop = cond->opcode();
         NanoAssert(cond->isCmp());
-        if (isCmpDOpcode(condop))
-            {
-                return Branches(asm_branchd(branchOnFalse, cond, targ));
-            }
+        if (isCmpDOpcode(condop)) {
+            return Branches(asm_branchd(branchOnFalse, cond, targ));
+        }
 
-        underrunProtect(32);
-        intptr_t tt = ((intptr_t)targ - (intptr_t)_nIns + 8) >> 2;
-        // !targ means that it needs patch.
-        if( !(isIMM22((int32_t)tt)) || !targ ) {
-            JMP_long_nocheck((intptr_t)targ);
-            at = _nIns;
+        {
+            SafeUnderrunProtect protect(this, 32);
+            intptr_t tt = ((intptr_t)targ - (intptr_t)_nIns + 8) >> 2;
+            // !targ means that it needs patch.
+            if( !(isIMM22((int32_t)tt)) || !targ ) {
+                JMP_long((intptr_t)targ);
+                at = _nIns;
+                NOP();
+                BA(0, 5);
+                tt = 4;
+            }
             NOP();
-            BA(0, 5);
-            tt = 4;
-        }
-        NOP();
 
-        // produce the branch
-        if (branchOnFalse)
-            {
-                if (condop == LIR_eqi)
-                    BNE(0, tt);
-                else if (condop == LIR_lti)
-                    BGE(0, tt);
-                else if (condop == LIR_lei)
-                    BG(0, tt);
-                else if (condop == LIR_gti)
-                    BLE(0, tt);
-                else if (condop == LIR_gei)
-                    BL(0, tt);
-                else if (condop == LIR_ltui)
-                    BCC(0, tt);
-                else if (condop == LIR_leui)
-                    BGU(0, tt);
-                else if (condop == LIR_gtui)
-                    BLEU(0, tt);
-                else //if (condop == LIR_geui)
-                    BCS(0, tt);
+            // produce the branch
+            if (branchOnFalse) {
+                switch (condop) {
+                    case LIR_eqi : BNE (0, tt); break;
+                    case LIR_lti : BGE (0, tt); break;
+                    case LIR_lei : BG  (0, tt); break;
+                    case LIR_gti : BLE (0, tt); break;
+                    case LIR_gei : BL  (0, tt); break;
+                    case LIR_ltui: BCC (0, tt); break;
+                    case LIR_leui: BGU (0, tt); break;
+                    case LIR_gtui: BLEU(0, tt); break;
+                    case LIR_geui: BCS (0, tt); break;
+                    default:
+                        NanoAssertMsg(0, "asm_branch should never receive this cond opcode");
+                        return;
+                }
+            } else {// op == LIR_xt
+                switch (condop) {
+                    case LIR_eqi : BE  (0, tt); break;
+                    case LIR_lti : BL  (0, tt); break;
+                    case LIR_lei : BLE (0, tt); break;
+                    case LIR_gti : BG  (0, tt); break;
+                    case LIR_gei : BGE (0, tt); break;
+                    case LIR_ltui: BCS (0, tt); break;
+                    case LIR_leui: BLEU(0, tt); break;
+                    case LIR_gtui: BGU (0, tt); break;
+                    case LIR_geui: BCC (0, tt); break;
+                    default:
+                        NanoAssertMsg(0, "asm_branch should never receive this cond opcode");
+                        return;
+                }
             }
-        else // op == LIR_xt
-            {
-                if (condop == LIR_eqi)
-                    BE(0, tt);
-                else if (condop == LIR_lti)
-                    BL(0, tt);
-                else if (condop == LIR_lei)
-                    BLE(0, tt);
-                else if (condop == LIR_gti)
-                    BG(0, tt);
-                else if (condop == LIR_gei)
-                    BGE(0, tt);
-                else if (condop == LIR_ltui)
-                    BCS(0, tt);
-                else if (condop == LIR_leui)
-                    BLEU(0, tt);
-                else if (condop == LIR_gtui)
-                    BGU(0, tt);
-                else //if (condop == LIR_geui)
-                    BCC(0, tt);
-            }
+        }
         asm_cmp(cond);
         return Branches(at);
     }
@@ -1071,11 +1080,11 @@
     NIns* Assembler::asm_branch_ov(LOpcode op, NIns* targ)
     {
         NIns* at = 0;
-        underrunProtect(32);
+        SafeUnderrunProtect protect(this, 32);
         intptr_t tt = ((intptr_t)targ - (intptr_t)_nIns + 8) >> 2;
         // !targ means that it needs patch.
-        if( !(isIMM22((int32_t)tt)) || !targ ) {
-            JMP_long_nocheck((intptr_t)targ);
+        if (!(isIMM22((int32_t)tt)) || !targ) {
+            JMP_long((intptr_t)targ);
             at = _nIns;
             NOP();
             BA(0, 5);
@@ -1083,7 +1092,7 @@
         }
         NOP();
 
-        if( op == LIR_mulxovi || op == LIR_muljovi )
+        if (op == LIR_mulxovi || op == LIR_muljovi)
             BNE(0, tt);
         else
             BVS(0, tt);
@@ -1090,10 +1099,8 @@
         return at;
     }
 
-    void Assembler::asm_cmp(LIns *cond)
+    void Assembler::asm_cmp(LIns* cond)
     {
-        underrunProtect(12);
-
         LIns* lhs = cond->oprnd1();
         LIns* rhs = cond->oprnd2();
 
@@ -1100,182 +1107,205 @@
         NanoAssert(lhs->isI() && rhs->isI());
 
         // ready to issue the compare
-        if (rhs->isImmI())
-            {
-                int c = rhs->immI();
-                Register r = findRegFor(lhs, GpRegs);
-                if (c == 0 && cond->isop(LIR_eqi)) {
-                    ANDCC(r, r, G0);
-                }
-                else {
-                    SUBCC(r, L2, G0);
-                    SET32(c, L2);
-                }
+        if (rhs->isImmI()) {
+            int c = rhs->immI();
+            Register r = findRegFor(lhs, GpRegs);
+            SafeUnderrunProtect protect(this, 12);
+            if (c == 0 && cond->isop(LIR_eqi)) {
+                ANDCC(r, r, G0);
+            } else {
+                SUBCC(r, L2, G0);
+                SET32(c, L2);
             }
-        else
-            {
-                Register ra, rb;
-                findRegFor2(GpRegs, lhs, ra, GpRegs, rhs, rb);
-                SUBCC(ra, rb, G0);
-            }
+        } else {
+            Register ra, rb;
+            findRegFor2(GpRegs, lhs, ra, GpRegs, rhs, rb);
+            SUBCC(ra, rb, G0);
+        }
     }
 
     void Assembler::asm_condd(LIns* ins)
     {
         // only want certain regs
-        Register r = deprecated_prepResultReg(ins, AllowableFlagRegs);
-        underrunProtect(8);
+        Register r = prepareResultReg(ins, AllowableFlagRegs);
+        SafeUnderrunProtect protect(this, 12);
         LOpcode condop = ins->opcode();
         NanoAssert(isCmpDOpcode(condop));
-        if (condop == LIR_eqd)
-            MOVFEI(1, r);
-        else if (condop == LIR_led)
-            MOVFLEI(1, r);
-        else if (condop == LIR_ltd)
-            MOVFLI(1, r);
-        else if (condop == LIR_ged)
-            MOVFGEI(1, r);
-        else // if (condop == LIR_gtd)
-            MOVFGI(1, r);
+        switch (condop) {
+            case LIR_eqd: MOVFEI (1, r); break;
+            case LIR_led: MOVFLEI(1, r); break;
+            case LIR_ltd: MOVFLI (1, r); break;
+            case LIR_ged: MOVFGEI(1, r); break;
+            case LIR_gtd: MOVFGI (1, r); break;
+            default:
+                NanoAssertMsg(0, "asm_condd should never receive this cond opcode");
+                return;
+        }
         ORI(G0, 0, r);
+        freeResourcesOf(ins);
         asm_cmpd(ins);
     }
 
     void Assembler::asm_cond(LIns* ins)
     {
-        underrunProtect(8);
         // only want certain regs
-        LOpcode op = ins->opcode();
-        Register r = deprecated_prepResultReg(ins, AllowableFlagRegs);
+        LOpcode condop = ins->opcode();
+        Register r = prepareResultReg(ins, AllowableFlagRegs);
+        SafeUnderrunProtect protect(this, 20);
 
-        if (op == LIR_eqi)
-            MOVEI(1, r);
-        else if (op == LIR_lti)
-            MOVLI(1, r);
-        else if (op == LIR_lei)
-            MOVLEI(1, r);
-        else if (op == LIR_gti)
-            MOVGI(1, r);
-        else if (op == LIR_gei)
-            MOVGEI(1, r);
-        else if (op == LIR_ltui)
-            MOVCSI(1, r);
-        else if (op == LIR_leui)
-            MOVLEUI(1, r);
-        else if (op == LIR_gtui)
-            MOVGUI(1, r);
-        else // if (op == LIR_geui)
-            MOVCCI(1, r);
+        switch (condop) {
+            case LIR_eqi : MOVEI  (1, r); break;
+            case LIR_lti : MOVLI  (1, r); break;
+            case LIR_lei : MOVLEI (1, r); break;
+            case LIR_gti : MOVGI  (1, r); break;
+            case LIR_gei : MOVGEI (1, r); break;
+            case LIR_ltui: MOVCSI (1, r); break;
+            case LIR_leui: MOVLEUI(1, r); break;
+            case LIR_gtui: MOVGUI (1, r); break;
+            case LIR_geui: MOVCCI (1, r); break;
+            default:
+                NanoAssertMsg(0, "asm_cond should never receive this cond opcode");
+                return;
+        }
         ORI(G0, 0, r);
+        freeResourcesOf(ins);
         asm_cmp(ins);
     }
 
     void Assembler::asm_arith(LIns* ins)
     {
-        underrunProtect(28);
+        SafeUnderrunProtect protect(this, 28);
         LOpcode op = ins->opcode();
         LIns* lhs = ins->oprnd1();
         LIns* rhs = ins->oprnd2();
 
-        Register rb = deprecated_UnknownReg;
+        Register rb;
         RegisterMask allow = GpRegs;
         bool forceReg = (op == LIR_muli || op == LIR_mulxovi || op == LIR_muljovi || !rhs->isImmI());
 
-        if (lhs != rhs && forceReg)
-            {
-                if ((rb = asm_binop_rhs_reg(ins)) == deprecated_UnknownReg) {
-                    rb = findRegFor(rhs, allow);
-                }
-                allow &= ~rmask(rb);
-            }
-        else if ((op == LIR_addi || op == LIR_addxovi || op == LIR_addjovi) && lhs->isop(LIR_allocp) && rhs->isImmI()) {
+        if (lhs != rhs && forceReg) {
+            rb = findRegFor(rhs, allow);
+            allow &= ~rmask(rb);
+        } else if ((op == LIR_addi || op == LIR_addxovi || op == LIR_addjovi) && lhs->isop(LIR_allocp) && rhs->isImmI()) {
             // add alloc+const, use lea
-            Register rr = deprecated_prepResultReg(ins, allow);
+            Register rr = prepareResultReg(ins, allow);
             int d = findMemFor(lhs) + rhs->immI();
+            SafeUnderrunProtect protect(this, 12);
             ADD(FP, L2, rr);
             SET32(d, L2);
+            freeResourcesOf(ins);
             return;
         }
 
-        Register rr = deprecated_prepResultReg(ins, allow);
-        // if this is last use of lhs in reg, we can re-use result reg
-        // else, lhs already has a register assigned.
-        Register ra = ( !lhs->isInReg()
-                      ? findSpecificRegFor(lhs, rr)
-                      : lhs->deprecated_getReg() );
+        Register rr = prepareResultReg(ins, allow);
 
-        if (forceReg)
-            {
-                if (lhs == rhs)
-                    rb = ra;
+        // If 'lhs' isn't in a register, it can be clobbered by 'ins'.
+        Register ra = lhs->isInReg() ? lhs->getReg() : rr;
 
-                if (op == LIR_addi || op == LIR_addxovi || op == LIR_addjovi)
+        if (forceReg) {
+            if (lhs == rhs)
+                rb = ra;
+
+            switch (op) {
+                case LIR_addi:
+                case LIR_addxovi:
+                case LIR_addjovi:
                     ADDCC(rr, rb, rr);
-                else if (op == LIR_subi || op == LIR_subxovi || op == LIR_subjovi)
+                    break;
+                case LIR_subi:
+                case LIR_subxovi:
+                case LIR_subjovi:
                     SUBCC(rr, rb, rr);
-                else if (op == LIR_muli)
+                    break;
+                case LIR_muli:
                     SMULCC(rr, rb, rr);
-                else if (op == LIR_mulxovi || op == LIR_muljovi) {
+                    break;
+                case LIR_mulxovi:
+                case LIR_muljovi:
                     SUBCC(L4, L6, L4);
                     SRAI(rr, 31, L6);
                     RDY(L4);
                     SMULCC(rr, rb, rr);
-                }
-                else if (op == LIR_andi)
+                    break;
+                case LIR_andi:
                     AND(rr, rb, rr);
-                else if (op == LIR_ori)
+                    break;
+                case LIR_ori:
                     OR(rr, rb, rr);
-                else if (op == LIR_xori)
+                    break;
+                case LIR_xori:
                     XOR(rr, rb, rr);
-                else if (op == LIR_lshi)
+                    break;
+                case LIR_lshi:
                     SLL(rr, rb, rr);
-                else if (op == LIR_rshi)
+                    break;
+                case LIR_rshi:
                     SRA(rr, rb, rr);
-                else if (op == LIR_rshui)
+                    break;
+                case LIR_rshui:
                     SRL(rr, rb, rr);
-                else
+                    break;
+                default:
                     NanoAssertMsg(0, "Unsupported");
+                    return;
             }
-        else
-            {
-                int c = rhs->immI();
-                if (op == LIR_addi || op == LIR_addxovi || op == LIR_addjovi)
+        } else {
+            int c = rhs->immI();
+            switch (op) {
+                case LIR_addi:
+                case LIR_addxovi:
+                case LIR_addjovi:
                     ADDCC(rr, L2, rr);
-                else if (op == LIR_subi || op == LIR_subxovi || op == LIR_subjovi)
+                    break;
+                case LIR_subi:
+                case LIR_subxovi:
+                case LIR_subjovi:
                     SUBCC(rr, L2, rr);
-                else if (op == LIR_andi)
+                    break;
+                case LIR_andi:
                     AND(rr, L2, rr);
-                else if (op == LIR_ori)
+                    break;
+                case LIR_ori:
                     OR(rr, L2, rr);
-                else if (op == LIR_xori)
+                    break;
+                case LIR_xori:
                     XOR(rr, L2, rr);
-                else if (op == LIR_lshi)
+                    break;
+                case LIR_lshi:
                     SLL(rr, L2, rr);
-                else if (op == LIR_rshi)
+                    break;
+                case LIR_rshi:
                     SRA(rr, L2, rr);
-                else if (op == LIR_rshui)
+                    break;
+                case LIR_rshui:
                     SRL(rr, L2, rr);
-                else
+                    break;
+                default:
                     NanoAssertMsg(0, "Unsupported");
-                SET32(c, L2);
+                    return;
             }
+            SET32(c, L2);
+        }
 
-        if ( rr != ra )
+        if (rr != ra)
             ORI(ra, 0, rr);
+
+        freeResourcesOf(ins);
+        if (!lhs->isInReg()) {
+            NanoAssert(ra == rr);
+            findSpecificRegForUnallocated(lhs, ra);
+        }
     }
 
     void Assembler::asm_neg_not(LIns* ins)
     {
-        underrunProtect(8);
         LOpcode op = ins->opcode();
-        Register rr = deprecated_prepResultReg(ins, GpRegs);
+        Register rr = prepareResultReg(ins, GpRegs);
 
+        SafeUnderrunProtect protect(this, 16);
         LIns* lhs = ins->oprnd1();
-        // if this is last use of lhs in reg, we can re-use result reg
-        // else, lhs already has a register assigned.
-        Register ra = ( !lhs->isInReg()
-                      ? findSpecificRegFor(lhs, rr)
-                      : lhs->deprecated_getReg() );
+        // If 'lhs' isn't in a register, it can be clobbered by 'ins'.
+        Register ra = lhs->isInReg() ? lhs->getReg() : rr;
 
         if (op == LIR_noti)
             ORN(G0, rr, rr);
@@ -1282,43 +1312,44 @@
         else
             SUB(G0, rr, rr);
 
-        if ( rr != ra )
+        if (rr != ra)
             ORI(ra, 0, rr);
+
+        freeResourcesOf(ins);
+        if (!lhs->isInReg()) {
+            NanoAssert(ra == rr);
+            findSpecificRegForUnallocated(lhs, ra);
+        }
     }
 
     void Assembler::asm_load32(LIns* ins)
     {
-        underrunProtect(12);
         LOpcode op = ins->opcode();
         LIns* base = ins->oprnd1();
         int d = ins->disp();
-        Register rr = deprecated_prepResultReg(ins, GpRegs);
+        Register rr = prepareResultReg(ins, GpRegs);
         Register ra = getBaseReg(base, d, GpRegs);
+
+        SafeUnderrunProtect protect(this, 12);
         switch(op) {
-            case LIR_lduc2ui:
-                LDUB32(ra, d, rr);
-                break;
-            case LIR_ldus2ui:
-                LDUH32(ra, d, rr);
-                break;
-            case LIR_ldi:
-                LDSW32(ra, d, rr);
-                break;
-            case LIR_ldc2i:
-                LDSB32(ra, d, rr);
-                break;
-            case LIR_lds2i:
-                LDSH32(ra, d, rr);
-                break;
+            case LIR_lduc2ui: LDUB32(ra, d, rr); break;
+            case LIR_ldus2ui: LDUH32(ra, d, rr); break;
+            case LIR_ldi    : LDSW32(ra, d, rr); break;
+            case LIR_ldc2i  : LDSB32(ra, d, rr); break;
+            case LIR_lds2i  : LDSH32(ra, d, rr); break;
             default:
                 NanoAssertMsg(0, "asm_load32 should never receive this LIR opcode");
                 return;
         }
+        freeResourcesOf(ins);
+        if (!base->isop(LIR_allocp) && !base->isInReg()) {
+            NanoAssert(ra == rr);
+            findSpecificRegForUnallocated(base, ra);
+        }
     }
 
     void Assembler::asm_cmov(LIns* ins)
     {
-        underrunProtect(4);
         LOpcode op = ins->opcode();
         LIns* condval = ins->oprnd1();
         LIns* iftrue  = ins->oprnd2();
@@ -1329,7 +1360,7 @@
                   (op == LIR_cmovd && iftrue->isD() && iffalse->isD()));
 
         RegisterMask rm = (op == LIR_cmovi) ? GpRegs : FpRegs;
-        const Register rr = deprecated_prepResultReg(ins, rm);
+        const Register rr = prepareResultReg(ins, rm);
         const Register iffalsereg = findRegFor(iffalse, rm & ~rmask(rr));
         bool isIcc = true;
 
@@ -1345,7 +1376,9 @@
                 case LIR_leui: MOVGU (iffalsereg, rr); break;
                 case LIR_gtui: MOVLEU(iffalsereg, rr); break;
                 case LIR_geui: MOVCS (iffalsereg, rr); break;
-                debug_only( default: NanoAssert(0); break; )
+                default:
+                    NanoAssertMsg(0, "asm_comv should never receive this cond opcode");
+                    return;
             }
         } else {
             switch (condval->opcode()) {
@@ -1364,10 +1397,13 @@
                 case LIR_ltd:  FMOVDFUGE(iffalsereg, rr); isIcc = false; break;
                 case LIR_ged:  FMOVDFUL (iffalsereg, rr); isIcc = false; break;
                 case LIR_gtd:  FMOVDFULE(iffalsereg, rr); isIcc = false; break;
-                debug_only( default: NanoAssert(0); break; )
+                default:
+                    NanoAssertMsg(0, "asm_comv should never receive this cond opcode");
+                    return;
             }
         }
 
+        freeResourcesOf(ins);
         /*const Register iftruereg =*/ findSpecificRegFor(iftrue, rr);
         if (isIcc)
             asm_cmp(condval);
@@ -1378,16 +1414,16 @@
 
     void Assembler::asm_param(LIns* ins)
     {
-        underrunProtect(12);
         uint32_t a = ins->paramArg();
         NanoAssertMsg(ins->paramKind() == 0, "savedRegs are not used on SPARC");
 
-        if (a < sizeof(argRegs)/sizeof(argRegs[0])) { // i0 - i5
+        if (a < sizeof(argRegs) / sizeof(argRegs[0])) { // i0 - i5
             prepareResultReg(ins, rmask(argRegs[a]));
         } else {
             // Incoming arg is on stack
             Register r = prepareResultReg(ins, GpRegs);
             int32_t d = a * sizeof (intptr_t) + kLinkageAreaSize;
+            SafeUnderrunProtect protect(this, 12);
             LDSW32(FP, d, r);
         }
         freeResourcesOf(ins);
@@ -1395,100 +1431,102 @@
 
     void Assembler::asm_immi(LIns* ins)
     {
-        underrunProtect(8);
-        Register rr = deprecated_prepResultReg(ins, GpRegs);
+        Register rr = prepareResultReg(ins, GpRegs);
+        SafeUnderrunProtect protect(this, 12);
         int32_t val = ins->immI();
         if (val == 0)
             XOR(rr, rr, rr);
         else
             SET32(val, rr);
+        freeResourcesOf(ins);
     }
 
     void Assembler::asm_immd(LIns* ins)
     {
-        underrunProtect(64);
-        Register rr = ins->deprecated_getReg();
-        if (rr != deprecated_UnknownReg)
-            {
-                // @todo -- add special-cases for 0 and 1
-                _allocator.retire(rr);
-                ins->clearReg();
-                NanoAssert((rmask(rr) & FpRegs) != 0);
-                findMemFor(ins);
-                int d = deprecated_disp(ins);
-                LDDF32(FP, d, rr);
-            }
+        SafeUnderrunProtect protect(this, 64);
+        if (ins->isInReg()) {
+            Register rr = ins->getReg();
+            // @todo -- add special-cases for 0 and 1
+            _allocator.retire(rr);
+            ins->clearReg();
+            NanoAssert((rmask(rr) & FpRegs) != 0);
+            findMemFor(ins);
+            int d = arDisp(ins);
+            LDDF32(FP, d, rr);
+        }
 
         // @todo, if we used xor, ldsd, fldz, etc above, we don't need mem here
-        int d = deprecated_disp(ins);
-        deprecated_freeRsrcOf(ins);
-        if (d)
-            {
-                STW32(L2, d+4, FP);
-                SET32(ins->immDlo(), L2);
-                STW32(L2, d, FP);
-                SET32(ins->immDhi(), L2);
-            }
+        int d = arDisp(ins);
+        if (d) {
+            STW32(L2, d+4, FP);
+            SET32(ins->immDlo(), L2);
+            STW32(L2, d, FP);
+            SET32(ins->immDhi(), L2);
+        }
+        freeResourcesOf(ins);
     }
 
     void Assembler::asm_fneg(LIns* ins)
     {
-        underrunProtect(4);
-        Register rr = deprecated_prepResultReg(ins, FpRegs);
+        Register rr = prepareResultReg(ins, FpRegs);
         LIns* lhs = ins->oprnd1();
 
-        // lhs into reg, prefer same reg as result
-        // if this is last use of lhs in reg, we can re-use result reg
-        // else, lhs already has a different reg assigned
-        Register ra = ( !lhs->isInReg()
-                      ? findSpecificRegFor(lhs, rr)
-                      : findRegFor(lhs, FpRegs) );
+        // If 'lhs' isn't in a register, it can be clobbered by 'ins'.
+        Register ra = lhs->isInReg() ? lhs->getReg() : rr;
 
         FNEGD(ra, rr);
+
+        freeResourcesOf(ins);
+        if (!lhs->isInReg()) {
+            NanoAssert(ra == rr);
+            findSpecificRegForUnallocated(lhs, ra);
+        }
     }
 
     void Assembler::asm_fop(LIns* ins)
     {
-        underrunProtect(4);
         LOpcode op = ins->opcode();
-        LIns *lhs = ins->oprnd1();
-        LIns *rhs = ins->oprnd2();
+        LIns* lhs = ins->oprnd1();
+        LIns* rhs = ins->oprnd2();
 
         RegisterMask allow = FpRegs;
         Register ra, rb;
         findRegFor2(allow, lhs, ra, allow, rhs, rb);
-        Register rr = deprecated_prepResultReg(ins, allow);
+        Register rr = prepareResultReg(ins, allow);
 
-        if (op == LIR_addd)
-            FADDD(ra, rb, rr);
-        else if (op == LIR_subd)
-            FSUBD(ra, rb, rr);
-        else if (op == LIR_muld)
-            FMULD(ra, rb, rr);
-        else //if (op == LIR_divd)
-            FDIVD(ra, rb, rr);
+        switch (op) {
+            case LIR_addd: FADDD(ra, rb, rr); break;
+            case LIR_subd: FSUBD(ra, rb, rr); break;
+            case LIR_muld: FMULD(ra, rb, rr); break;
+            case LIR_divd: FDIVD(ra, rb, rr); break;
+            default:
+                NanoAssertMsg(0, "asm_fop should never receive this opcode");
+                return;
+        }
 
+        freeResourcesOf(ins);
     }
 
     void Assembler::asm_i2d(LIns* ins)
     {
-        underrunProtect(32);
         // where our result goes
-        Register rr = deprecated_prepResultReg(ins, FpRegs);
+        Register rr = prepareResultReg(ins, FpRegs);
+        SafeUnderrunProtect protect(this, 32);
         int d = findMemFor(ins->oprnd1());
         FITOD(rr, rr);
         LDDF32(FP, d, rr);
+        freeResourcesOf(ins);
     }
 
     void Assembler::asm_ui2d(LIns* ins)
     {
-        underrunProtect(72);
         // where our result goes
-        Register rr = deprecated_prepResultReg(ins, FpRegs);
+        Register rr = prepareResultReg(ins, FpRegs);
         Register rt = registerAllocTmp(FpRegs & ~(rmask(rr)));
         Register gr = findRegFor(ins->oprnd1(), GpRegs);
         int disp = -8;
 
+        SafeUnderrunProtect protect(this, 72);
         FABSS(rr, rr);
         FSUBD(rt, rr, rr);
         LDDF32(SP, disp, rr);
@@ -1497,37 +1535,37 @@
         STWI(gr, disp+4, SP);
         STWI(G1, disp, SP);
         SETHI(0x43300000, G1);
+        freeResourcesOf(ins);
     }
 
     void Assembler::asm_d2i(LIns* ins) {
-        underrunProtect(28);
-        LIns *lhs = ins->oprnd1();
+        LIns* lhs = ins->oprnd1();
         Register rr = prepareResultReg(ins, GpRegs);
         Register ra = findRegFor(lhs, FpRegs);
         int d = findMemFor(ins);
+        SafeUnderrunProtect protect(this, 28);
         LDSW32(FP, d, rr);
-        STF32(ra, d, FP);
-        FDTOI(ra, ra);
+        STF32(F28, d, FP);
+        FDTOI(ra, F28);
         freeResourcesOf(ins);
     }
 
     void Assembler::asm_nongp_copy(Register r, Register s)
     {
-        underrunProtect(4);
         NanoAssert((rmask(r) & FpRegs) && (rmask(s) & FpRegs));
         FMOVD(s, r);
     }
 
-    NIns * Assembler::asm_branchd(bool branchOnFalse, LIns *cond, NIns *targ)
+    NIns* Assembler::asm_branchd(bool branchOnFalse, LIns* cond, NIns* targ)
     {
-        NIns *at = 0;
+        NIns* at = 0;
         LOpcode condop = cond->opcode();
         NanoAssert(isCmpDOpcode(condop));
-        underrunProtect(32);
+        SafeUnderrunProtect protect(this, 32);
         intptr_t tt = ((intptr_t)targ - (intptr_t)_nIns + 8) >> 2;
         // !targ means that it needs patch.
         if( !(isIMM22((int32_t)tt)) || !targ ) {
-            JMP_long_nocheck((intptr_t)targ);
+            JMP_long((intptr_t)targ);
             at = _nIns;
             NOP();
             BA(0, 5);
@@ -1536,39 +1574,35 @@
         NOP();
 
         // produce the branch
-        if (branchOnFalse)
-            {
-                if (condop == LIR_eqd)
-                    FBNE(0, tt);
-                else if (condop == LIR_led)
-                    FBUG(0, tt);
-                else if (condop == LIR_ltd)
-                    FBUGE(0, tt);
-                else if (condop == LIR_ged)
-                    FBUL(0, tt);
-                else //if (condop == LIR_gtd)
-                    FBULE(0, tt);
+        if (branchOnFalse) {
+            switch (condop) {
+                case LIR_eqd: FBNE (0, tt); break;
+                case LIR_led: FBUG (0, tt); break;
+                case LIR_ltd: FBUGE(0, tt); break;
+                case LIR_ged: FBUL (0, tt); break;
+                case LIR_gtd: FBULE(0, tt); break;
+                default:
+                    NanoAssertMsg(0, "asm_branchd should never receive this cond opcode");
+                    return;
             }
-        else // op == LIR_xt
-            {
-                if (condop == LIR_eqd)
-                    FBE(0, tt);
-                else if (condop == LIR_led)
-                    FBLE(0, tt);
-                else if (condop == LIR_ltd)
-                    FBL(0, tt);
-                else if (condop == LIR_ged)
-                    FBGE(0, tt);
-                else //if (condop == LIR_gtd)
-                    FBG(0, tt);
+        } else { // op == LIR_xt
+            switch (condop) {
+                case LIR_eqd: FBE (0, tt); break;
+                case LIR_led: FBLE(0, tt); break;
+                case LIR_ltd: FBL (0, tt); break;
+                case LIR_ged: FBGE(0, tt); break;
+                case LIR_gtd: FBG (0, tt); break;
+                default:
+                    NanoAssertMsg(0, "asm_branchd should never receive this cond opcode");
+                    return;
             }
+        }
         asm_cmpd(cond);
         return at;
     }
 
-    void Assembler::asm_cmpd(LIns *cond)
+    void Assembler::asm_cmpd(LIns* cond)
     {
-        underrunProtect(4);
         LIns* lhs = cond->oprnd1();
         LIns* rhs = cond->oprnd2();
 
@@ -1582,11 +1616,6 @@
     {
     }
 
-    Register Assembler::asm_binop_rhs_reg(LIns* ins)
-    {
-        return deprecated_UnknownReg;
-    }
-
     void Assembler::nativePageSetup()
     {
         NanoAssert(!_inExit);
@@ -1606,11 +1635,12 @@
     void
     Assembler::underrunProtect(int n)
     {
-        NIns *eip = _nIns;
+        NIns* eip = _nIns;
+        NanoAssertMsg(n <= LARGEST_UNDERRUN_PROT, "constant LARGEST_UNDERRUN_PROT is too small %d");
         // This may be in a normal code chunk or an exit code chunk.
-        if (eip - n < codeStart) {
+        if ((intptr_t)eip - n < (intptr_t)codeStart) {
             codeAlloc(codeStart, codeEnd, _nIns verbose_only(, codeBytes));
-            JMP_long_nocheck((intptr_t)eip);
+            JMP_long((intptr_t)eip);
         }
     }
 
@@ -1619,7 +1649,7 @@
         genEpilogue();
         releaseRegisters();
         assignSavedRegs();
-        LIns *val = ins->oprnd1();
+        LIns* val = ins->oprnd1();
         if (ins->isop(LIR_reti)) {
             findSpecificRegFor(val, retRegs[0]);
         } else {
