Changeset 50595 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Nov 6, 2009, 1:35:03 AM (16 years ago)
Author:
[email protected]
Message:

Tidy up the shift methods on the macro-assembler interface.

Patch by Gavin Barraclough <[email protected]> on 2009-11-06
Reviewed by Oliver Hunt.

Currently behaviour of shifts of a magnitude > 0x1f is undefined.
Instead defined that all shifts are masked to this range. This makes a lot of
practical sense, both since having undefined behaviour is not particularly
desirable, and because this behaviour is commonly required (particularly since
it is required bt ECMA-262 for shifts).

Update the ARM assemblers to provide this behaviour. Remove (now) redundant
masks from JITArithmetic, and remove rshiftPtr (this was used in case that
could be rewritten in a simpler form using rshift32, only optimized JSVALUE32
on x86-64, which uses JSVALUE64!)

  • assembler/MacroAssembler.h:
  • assembler/MacroAssemblerARM.h:

(JSC::MacroAssemblerARM::lshift32):
(JSC::MacroAssemblerARM::rshift32):

  • assembler/MacroAssemblerARMv7.h:

(JSC::MacroAssemblerARMv7::lshift32):
(JSC::MacroAssemblerARMv7::rshift32):

  • assembler/MacroAssemblerX86_64.h:
  • jit/JITArithmetic.cpp:

(JSC::JIT::emit_op_lshift):
(JSC::JIT::emit_op_rshift):

Location:
trunk/JavaScriptCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r50594 r50595  
     12009-11-06  Gavin Barraclough  <[email protected]>
     2
     3        Reviewed by Oliver Hunt.
     4
     5        Tidy up the shift methods on the macro-assembler interface.
     6
     7        Currently behaviour of shifts of a magnitude > 0x1f is undefined.
     8        Instead defined that all shifts are masked to this range.  This makes a lot of
     9        practical sense, both since having undefined behaviour is not particularly
     10        desirable, and because this behaviour is commonly required (particularly since
     11        it is required bt ECMA-262 for shifts).
     12
     13        Update the ARM assemblers to provide this behaviour.  Remove (now) redundant
     14        masks from JITArithmetic, and remove rshiftPtr (this was used in case that
     15        could be rewritten in a simpler form using rshift32, only optimized JSVALUE32
     16        on x86-64, which uses JSVALUE64!)
     17
     18        * assembler/MacroAssembler.h:
     19        * assembler/MacroAssemblerARM.h:
     20        (JSC::MacroAssemblerARM::lshift32):
     21        (JSC::MacroAssemblerARM::rshift32):
     22        * assembler/MacroAssemblerARMv7.h:
     23        (JSC::MacroAssemblerARMv7::lshift32):
     24        (JSC::MacroAssemblerARMv7::rshift32):
     25        * assembler/MacroAssemblerX86_64.h:
     26        * jit/JITArithmetic.cpp:
     27        (JSC::JIT::emit_op_lshift):
     28        (JSC::JIT::emit_op_rshift):
     29
    1302009-11-05  Gavin Barraclough  <[email protected]>
    231
  • trunk/JavaScriptCore/assembler/MacroAssembler.h

    r48525 r50595  
    180180    }
    181181
    182     void rshiftPtr(RegisterID shift_amount, RegisterID dest)
    183     {
    184         rshift32(shift_amount, dest);
    185     }
    186 
    187     void rshiftPtr(Imm32 imm, RegisterID dest)
    188     {
    189         rshift32(imm, dest);
    190     }
    191 
    192182    void subPtr(RegisterID src, RegisterID dest)
    193183    {
  • trunk/JavaScriptCore/assembler/MacroAssemblerARM.h

    r50593 r50595  
    119119    }
    120120
     121    void lshift32(RegisterID shift_amount, RegisterID dest)
     122    {
     123        ARMWord w = m_assembler.getImm(0x1f, ARMRegisters::S0, true);
     124        ASSERT(!(w & ARMAssembler::OP2_INV_IMM));
     125        m_assembler.ands_r(ARMRegisters::S0, shift_amount, w);
     126
     127        m_assembler.movs_r(dest, m_assembler.lsl_r(dest, ARMRegisters::S0));
     128    }
     129
    121130    void lshift32(Imm32 imm, RegisterID dest)
    122131    {
    123132        m_assembler.movs_r(dest, m_assembler.lsl(dest, imm.m_value & 0x1f));
    124     }
    125 
    126     void lshift32(RegisterID shift_amount, RegisterID dest)
    127     {
    128         m_assembler.movs_r(dest, m_assembler.lsl_r(dest, shift_amount));
    129133    }
    130134
     
    161165    void rshift32(RegisterID shift_amount, RegisterID dest)
    162166    {
    163         m_assembler.movs_r(dest, m_assembler.asr_r(dest, shift_amount));
     167        ARMWord w = m_assembler.getImm(0x1f, ARMRegisters::S0, true);
     168        ASSERT(!(w & ARMAssembler::OP2_INV_IMM));
     169        m_assembler.ands_r(ARMRegisters::S0, shift_amount, w);
     170
     171        m_assembler.movs_r(dest, m_assembler.asr_r(dest, ARMRegisters::S0));
    164172    }
    165173
  • trunk/JavaScriptCore/assembler/MacroAssemblerARMv7.h

    r50541 r50595  
    198198    }
    199199
     200    void lshift32(RegisterID shift_amount, RegisterID dest)
     201    {
     202        // Clamp the shift to the range 0..31
     203        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f);
     204        ASSERT(armImm.isValid());
     205        m_assembler.ARM_and(dataTempRegister, shift_amount, armImm);
     206
     207        m_assembler.lsl(dest, dest, dataTempRegister);
     208    }
     209
    200210    void lshift32(Imm32 imm, RegisterID dest)
    201211    {
    202         m_assembler.lsl(dest, dest, imm.m_value);
    203     }
    204 
    205     void lshift32(RegisterID shift_amount, RegisterID dest)
    206     {
    207         m_assembler.lsl(dest, dest, shift_amount);
     212        m_assembler.lsl(dest, dest, imm.m_value & 0x1f);
    208213    }
    209214
     
    242247    void rshift32(RegisterID shift_amount, RegisterID dest)
    243248    {
    244         m_assembler.asr(dest, dest, shift_amount);
     249        // Clamp the shift to the range 0..31
     250        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f);
     251        ASSERT(armImm.isValid());
     252        m_assembler.ARM_and(dataTempRegister, shift_amount, armImm);
     253
     254        m_assembler.asr(dest, dest, dataTempRegister);
    245255    }
    246256
    247257    void rshift32(Imm32 imm, RegisterID dest)
    248258    {
    249         m_assembler.asr(dest, dest, imm.m_value);
     259        m_assembler.asr(dest, dest, imm.m_value & 0x1f);
    250260    }
    251261
  • trunk/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r50531 r50595  
    559559    void swap(RegisterID reg1, RegisterID reg2)
    560560    {
    561         m_assembler.xchgq_rr(reg1, reg2);
     561        if (reg1 != reg2)
     562            m_assembler.xchgq_rr(reg1, reg2);
    562563    }
    563564
  • trunk/JavaScriptCore/assembler/MacroAssemblerX86_64.h

    r47802 r50595  
    193193    }
    194194
    195     void rshiftPtr(RegisterID shift_amount, RegisterID dest)
    196     {
    197         // On x86 we can only shift by ecx; if asked to shift by another register we'll
    198         // need rejig the shift amount into ecx first, and restore the registers afterwards.
    199         if (shift_amount != X86Registers::ecx) {
    200             swap(shift_amount, X86Registers::ecx);
    201 
    202             // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
    203             if (dest == shift_amount)
    204                 m_assembler.sarq_CLr(X86Registers::ecx);
    205             // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
    206             else if (dest == X86Registers::ecx)
    207                 m_assembler.sarq_CLr(shift_amount);
    208             // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
    209             else
    210                 m_assembler.sarq_CLr(dest);
    211        
    212             swap(shift_amount, X86Registers::ecx);
    213         } else
    214             m_assembler.sarq_CLr(dest);
    215     }
    216 
    217     void rshiftPtr(Imm32 imm, RegisterID dest)
    218     {
    219         m_assembler.sarq_i8r(imm.m_value, dest);
    220     }
    221 
    222195    void subPtr(RegisterID src, RegisterID dest)
    223196    {
  • trunk/JavaScriptCore/jit/JITArithmetic.cpp

    r50531 r50595  
    11441144    emitFastArithImmToInt(regT0);
    11451145    emitFastArithImmToInt(regT2);
    1146 #if !PLATFORM(X86)
    1147     // Mask with 0x1f as per ecma-262 11.7.2 step 7.
    1148     // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
    1149     and32(Imm32(0x1f), regT2);
    1150 #endif
    11511146    lshift32(regT2, regT0);
    1152 #if !USE(JSVALUE64)
     1147#if USE(JSVALUE32)
    11531148    addSlowCase(branchAdd32(Overflow, regT0, regT0));
    11541149    signExtend32ToPtr(regT0, regT0);
     
    12261221        }
    12271222        emitFastArithImmToInt(regT2);
    1228 #if !PLATFORM(X86)
    1229         // Mask with 0x1f as per ecma-262 11.7.2 step 7.
    1230         // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
    1231         and32(Imm32(0x1f), regT2);
    1232 #endif
    1233 #if USE(JSVALUE64)
    12341223        rshift32(regT2, regT0);
    1235 #else
    1236         rshiftPtr(regT2, regT0);
     1224#if USE(JSVALUE32)
     1225        signExtend32ToPtr(regT0, regT0);
    12371226#endif
    12381227    }
Note: See TracChangeset for help on using the changeset viewer.