Ignore:
Timestamp:
Jan 14, 2019, 1:34:47 PM (6 years ago)
Author:
[email protected]
Message:

Fix all CLoop JSC test failures (including some LLInt bugs due to recent bytecode format change).
https://bugs.webkit.org/show_bug.cgi?id=193402
<rdar://problem/46012309>

Reviewed by Keith Miller.

JSTests:

  • stress/regexp-compile-oom.js:
  • Skip this test for !$jitTests because it is tuned for stack usage when the JIT is enabled. As a result, it will fail on cloop builds though there is no bug.

Source/JavaScriptCore:

The CLoop builds via build-jsc were previously completely disabled after our
change to enable ASM LLInt build without the JIT. As a result, JSC tests have
regressed on CLoop builds. The CLoop builds and tests will be re-enabled when
the fix for https://bugs.webkit.org/show_bug.cgi?id=192955 lands. This patch
fixes all the regressions (and some old bugs) so that the CLoop test bots won't
be red when CLoop build gets re-enabled.

In this patch, we do the following:

  1. Change CLoopStack::grow() to set the new CLoop stack top at the maximum allocated capacity (after discounting the reserved zone) as opposed to setting it only at the level that the client requested.

This fixes a small performance bug that I happened to noticed when I was
debugging a stack issue. It does not affect correctness.

  1. In LowLevelInterpreter32_64.asm:
  1. Fix loadConstantOrVariableTag() to use subi for computing the constant index because the VirtualRegister offset and FirstConstantRegisterIndex values it is operating on are both signed ints. This is just to be pedantic. The previous use of subu will still produce a correct value.
  1. Fix llintOpWithReturn() to use getu (instead of get) for reading OpIsCellWithType::type because it is of type JSType, which is a uint8_t.
  1. Fix llintOpWithMetadata() to use loadis for loading OpGetById::Metadata::modeMetadata.protoLoadMode.cachedOffset[t5] because it is of type PropertyOffset, which is a signed int.
  1. Fix commonCallOp() to use getu for loading fields argv and argc because they are of type unsigned for OpCall, OpConstruct, and OpTailCall, which are the clients of commonCallOp.
  1. Fix llintOpWithMetadata() and getClosureVar() to use loadp for loading OpGetFromScope::Metadata::operand because it is of type uintptr_t.
  1. In LowLevelInterpreter64.asm:
  1. Fix llintOpWithReturn() to use getu for reading OpIsCellWithType::type because it is of type JSType, which is a uint8_t.
  1. Fix llintOpWithMetadata() to use loadi for loading OpGetById::Metadata::modeMetadata.protoLoadMode.structure[t2] because it is of type StructureID, which is a uint32_t.

Fix llintOpWithMetadata() to use loadis for loading
OpGetById::Metadata::modeMetadata.protoLoadMode.cachedOffset[t2] because it
is of type PropertyOffset, which is a signed int.

  1. commonOp() should reload the metadataTable for op_catch because unlike for the ASM LLInt, the exception unwinding code is not able to restore "callee saved registers" for the CLoop interpreter because the CLoop uses pseudo-registers (see the CLoopRegister class).

This was the source of many exotic Cloop failures after the bytecode format
change (which introduced the metadataTable callee saved register). Hence,
we fix it by reloading metadataTable's value on re-entry via op_catch for
exception handling. We already take care of restoring it in op_ret.

  1. Fix llintOpWithMetadata() and getClosureVar() to use loadp for loading OpGetFromScope::Metadata::operand because it is of type uintptr_t.
  1. In LowLevelInterpreter.asm:

Fix metadata() to use loadi for loading metadataTable offsets because they are
of type unsigned. This was also a source of many exotic CLoop test failures.

  1. Change CLoopRegister into a class with a uintptr_t as its storage element. Previously, we were using a union to convert between various value types that we would store in this pseudo-register. This method of type conversion is undefined behavior according to the C++ spec. As a result, the C++ compiler may choose to elide some CLoop statements, thereby resulting in some exotic bugs.

We fix this by now always using accessor methods and assignment operators to
ensure that we use bitwise_cast to do the type conversions. Since bitwise_cast
uses a memcpy, this ensures that there's no undefined behavior, and that CLoop
statements won't get elided willy-nilly by the compiler.

Ditto for the CloopDobleRegisters.

Similarly, use bitwise_cast for ints2Double() and double2Ints() utility
functions.

Also use bitwise_cast (instead of reinterpret_cast) for the CLoop CAST macro.

  1. Fix cloop.rb to use the new CLoopRegister and CLoopDoubleRegister classes.

Add a clLValue accessor for offlineasm operand types to distinguish
LValue use of the operands from RValue uses.

Replace the use of clearHighWord() with simply casting to uint32_t. This is
more efficient for the C++ compiler (and help speed up debug build runs).

Also fix 32-bit arithmetic operations to only set the lower 32-bit value of
the pseudo registers. This fixes some CLoop JSC test failures.

This patch has been manually tested with the JSC tests on the following builds:
64bit X86 ASM LLLint (without JIT), 64bit and 32bit X86 CLoop, and ARMv7 Cloop.

  • interpreter/CLoopStack.cpp:

(JSC::CLoopStack::grow):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter.cpp:

(JSC::CLoopRegister::i const):
(JSC::CLoopRegister::u const):
(JSC::CLoopRegister::i32 const):
(JSC::CLoopRegister::u32 const):
(JSC::CLoopRegister::i8 const):
(JSC::CLoopRegister::u8 const):
(JSC::CLoopRegister::ip const):
(JSC::CLoopRegister::i8p const):
(JSC::CLoopRegister::vp const):
(JSC::CLoopRegister::cvp const):
(JSC::CLoopRegister::callFrame const):
(JSC::CLoopRegister::execState const):
(JSC::CLoopRegister::instruction const):
(JSC::CLoopRegister::vm const):
(JSC::CLoopRegister::cell const):
(JSC::CLoopRegister::protoCallFrame const):
(JSC::CLoopRegister::nativeFunc const):
(JSC::CLoopRegister::i64 const):
(JSC::CLoopRegister::u64 const):
(JSC::CLoopRegister::encodedJSValue const):
(JSC::CLoopRegister::opcode const):
(JSC::CLoopRegister::operator ExecState*):
(JSC::CLoopRegister::operator const Instruction*):
(JSC::CLoopRegister::operator JSCell*):
(JSC::CLoopRegister::operator ProtoCallFrame*):
(JSC::CLoopRegister::operator Register*):
(JSC::CLoopRegister::operator VM*):
(JSC::CLoopRegister::operator=):
(JSC::CLoopRegister::bitsAsDouble const):
(JSC::CLoopRegister::bitsAsInt64 const):
(JSC::CLoopDoubleRegister::operator T const):
(JSC::CLoopDoubleRegister::d const):
(JSC::CLoopDoubleRegister::bitsAsInt64 const):
(JSC::CLoopDoubleRegister::operator=):
(JSC::LLInt::ints2Double):
(JSC::LLInt::double2Ints):
(JSC::LLInt::decodeResult):
(JSC::CLoop::execute):
(JSC::LLInt::Ints2Double): Deleted.
(JSC::LLInt::Double2Ints): Deleted.
(JSC::CLoopRegister::CLoopRegister): Deleted.
(JSC::CLoopRegister::clearHighWord): Deleted.

  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
  • offlineasm/cloop.rb:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/offlineasm/cloop.rb

    r238543 r239940  
    3434def cloopMapType(type)
    3535    case type
    36     when :int;            ".i"
    37     when :uint;           ".u"
    38     when :int32;          ".i32"
    39     when :uint32;         ".u32"
    40     when :int64;          ".i64"
    41     when :uint64;         ".u64"
    42     when :int8;           ".i8"
    43     when :uint8;          ".u8"
    44     when :int8Ptr;        ".i8p"
    45     when :voidPtr;        ".vp"
    46     when :nativeFunc;     ".nativeFunc"
    47     when :double;         ".d"
    48     when :castToDouble;   ".castToDouble"
    49     when :castToInt64;    ".castToInt64"
    50     when :opcode;         ".opcode"
     36    when :int;            ".i()"
     37    when :uint;           ".u()"
     38    when :int32;          ".i32()"
     39    when :uint32;         ".u32()"
     40    when :int64;          ".i64()"
     41    when :uint64;         ".u64()"
     42    when :int8;           ".i8()"
     43    when :uint8;          ".u8()"
     44    when :int8Ptr;        ".i8p()"
     45    when :voidPtr;        ".vp()"
     46    when :nativeFunc;     ".nativeFunc()"
     47    when :double;         ".d()"
     48    when :bitsAsDouble;   ".bitsAsDouble()"
     49    when :bitsAsInt64;    ".bitsAsInt64()"
     50    when :opcode;         ".opcode()"
    5151    else;
    5252        raise "Unsupported type"
     
    5656
    5757class SpecialRegister < NoChildren
     58    def clLValue(type=:int)
     59        clDump
     60    end
    5861    def clDump
    5962        @name
     
    101104        end
    102105    end
     106    def clLValue(type=:int)
     107        clDump
     108    end
    103109    def clValue(type=:int)
    104110        clDump + cloopMapType(type)
     
    125131        end
    126132    end
     133    def clLValue(type=:int)
     134        clDump
     135    end
    127136    def clValue(type=:int)
    128137        clDump + cloopMapType(type)
     
    133142    def clDump
    134143        "#{value}"
     144    end
     145    def clLValue(type=:int)
     146        raise "Immediate cannot be used as an LValue"
    135147    end
    136148    def clValue(type=:int)
     
    165177    def clDump
    166178        "[#{base.clDump}, #{offset.value}]"
     179    end
     180    def clLValue(type=:int)
     181        clValue(type)
    167182    end
    168183    def clValue(type=:int)
     
    236251        "[#{base.clDump}, #{offset.clDump}, #{index.clDump} << #{scaleShift}]"
    237252    end
     253    def clLValue(type=:int)
     254        clValue(type)
     255    end
    238256    def clValue(type=:int)
    239257        case type
     
    300318        "#{codeOriginString}"
    301319    end
     320    def clLValue(type=:int)
     321        clValue(type)
     322    end
    302323    def clValue
    303324        clDump
     
    310331    end
    311332    def cloopEmitLea(destination, type)
    312         $asm.putc "#{destination.clValue(:voidPtr)} = CAST<void*>(&#{cLabel});"
     333        $asm.putc "#{destination.clLValue(:voidPtr)} = CAST<void*>(&#{cLabel});"
    313334    end
    314335end
     
    322343    def cloopEmitLea(destination, type)
    323344        if destination == base
    324             $asm.putc "#{destination.clValue(:int8Ptr)} += #{offset.clValue(type)};"
     345            $asm.putc "#{destination.clLValue(:int8Ptr)} += #{offset.clValue(type)};"
    325346        else
    326             $asm.putc "#{destination.clValue(:int8Ptr)} = #{base.clValue(:int8Ptr)} + #{offset.clValue(type)};"
     347            $asm.putc "#{destination.clLValue(:int8Ptr)} = #{base.clValue(:int8Ptr)} + #{offset.clValue(type)};"
    327348        end
    328349    end
     
    332353    def cloopEmitLea(destination, type)
    333354        raise "Malformed BaseIndex, offset should be zero at #{codeOriginString}" unless offset.value == 0
    334         $asm.putc "#{destination.clValue(:int8Ptr)} = #{base.clValue(:int8Ptr)} + (#{index.clValue} << #{scaleShift});"
     355        $asm.putc "#{destination.clLValue(:int8Ptr)} = #{base.clValue(:int8Ptr)} + (#{index.clValue} << #{scaleShift});"
    335356    end
    336357end
     
    368389        type == :int64 || type == :uint64 || type == :double
    369390    if operands.size == 3
    370         $asm.putc "#{operands[2].clValue(type)} = #{operands[0].clValue(type)} #{operator} #{operands[1].clValue(type)};"
    371         if operands[2].is_a? RegisterID and (type == :int32 or type == :uint32)
    372             $asm.putc "#{operands[2].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
    373         end
     391        op1 = operands[0]
     392        op2 = operands[1]
     393        dst = operands[2]
    374394    else
    375395        raise unless operands.size == 2
    376         raise unless not operands[1].is_a? Immediate
    377         $asm.putc "#{operands[1].clValue(type)} = #{operands[1].clValue(type)} #{operator} #{operands[0].clValue(type)};"
    378         if operands[1].is_a? RegisterID and (type == :int32 or type == :uint32)
    379             $asm.putc "#{operands[1].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
    380         end
    381     end
     396        op1 = operands[1]
     397        op2 = operands[0]
     398        dst = operands[1]
     399    end
     400    raise unless not dst.is_a? Immediate
     401    if dst.is_a? RegisterID and (type == :int32 or type == :uint32)
     402        truncationHeader = "(uint32_t)("
     403        truncationFooter = ")"
     404    else
     405        truncationHeader = ""
     406        truncationFooter = ""
     407    end
     408    $asm.putc "#{dst.clLValue(type)} = #{truncationHeader}#{op1.clValue(type)} #{operator} #{op2.clValue(type)}#{truncationFooter};"
    382409end
    383410
     
    385412    raise unless type == :int || type == :uint || type == :int32 || type == :uint32 || type == :int64 || type == :uint64
    386413    if operands.size == 3
    387         $asm.putc "#{operands[2].clValue(type)} = #{operands[1].clValue(type)} #{operator} (#{operands[0].clValue(:int)} & 0x1f);"
    388         if operands[2].is_a? RegisterID and (type == :int32 or type == :uint32)
    389             $asm.putc "#{operands[2].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
    390         end
     414        op1 = operands[0]
     415        op2 = operands[1]
     416        dst = operands[2]
    391417    else
    392         raise unless operands.size == 2
    393         raise unless not operands[1].is_a? Immediate
    394         $asm.putc "#{operands[1].clValue(type)} = #{operands[1].clValue(type)} #{operator} (#{operands[0].clValue(:int)} & 0x1f);"
    395         if operands[1].is_a? RegisterID and (type == :int32 or type == :uint32)
    396             $asm.putc "#{operands[1].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
    397         end
    398     end
     418        op1 = operands[1]
     419        op2 = operands[0]
     420        dst = operands[1]
     421    end
     422    if dst.is_a? RegisterID and (type == :int32 or type == :uint32)
     423        truncationHeader = "(uint32_t)("
     424        truncationFooter = ")"
     425    else
     426        truncationHeader = ""
     427        truncationFooter = ""
     428    end
     429    $asm.putc "#{dst.clLValue(type)} = #{truncationHeader}#{operands[1].clValue(type)} #{operator} (#{operands[0].clValue(:int)} & 0x1f)#{truncationFooter};"
    399430end
    400431
     
    403434    raise unless operands.size == 1
    404435    raise unless not operands[0].is_a? Immediate
    405     $asm.putc "#{operands[0].clValue(type)} = #{operator}#{operands[0].clValue(type)};"
    406     if operands[0].is_a? RegisterID and (type == :int32 or type == :uint32)
    407         $asm.putc "#{operands[0].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port.
    408     end
     436    op = operands[0]
     437    dst = operands[0]
     438    if dst.is_a? RegisterID and (type == :int32 or type == :uint32)
     439        truncationHeader = "(uint32_t)("
     440        truncationFooter = ")"
     441    else
     442        truncationHeader = ""
     443        truncationFooter = ""
     444    end
     445    $asm.putc "#{dst.clLValue(type)} = #{truncationHeader}#{operator}#{op.clValue(type)}#{truncationFooter};"
    409446end
    410447
     
    419456    # The result is a boolean.  Hence, it doesn't need to be based on the type
    420457    # of the arguments being compared.
    421     $asm.putc "#{operands[2].clValue} = (#{operands[0].clValue(type)} #{comparator} #{operands[1].clValue(type)});"
     458    $asm.putc "#{operands[2].clLValue(type)} = (#{operands[0].clValue(type)} #{comparator} #{operands[1].clValue(type)});"
    422459end
    423460
     
    460497    # the condition test.
    461498    conditionExpr = cloopGenerateConditionExpression(operands, type, conditionTest)
    462     $asm.putc "#{operands[-1].clValue} = (#{conditionExpr});"
     499    $asm.putc "#{operands[-1].clLValue} = (#{conditionExpr});"
    463500end
    464501
     
    472509    end
    473510
    474     op1 = operands[0].clValue(type)
    475     op2 = operands[1].clValue(type)
    476 
    477511    $asm.putc "{"
    478     $asm.putc "    #{tempType} temp = #{op2} #{operator} #{op1};"
    479     $asm.putc "    #{op2} = temp;"
     512    $asm.putc "    #{tempType} temp = #{operands[1].clValue(type)} #{operator} #{operands[0].clValue(type)};"
     513    $asm.putc "    #{operands[1].clLValue(type)} = temp;"
    480514    $asm.putc "    if (temp #{conditionTest})"
    481515    $asm.putc "        goto  #{operands[2].cLabel};"
     
    487521    when :int32
    488522        tempType = "int32_t"
     523        truncationHeader = "(uint32_t)("
     524        truncationFooter = ")"
    489525    else
    490526        raise "Unimplemented type"
     
    502538    end
    503539
    504     $asm.putc "    if (!WTF::ArithmeticOperations<#{tempType}, #{tempType}, #{tempType}>::#{operation}(#{operands[1].clValue(type)}, #{operands[0].clValue(type)}, #{operands[1].clValue(type)}))"
     540    $asm.putc "    #{tempType} result;"
     541    $asm.putc "    bool success = WTF::ArithmeticOperations<#{tempType}, #{tempType}, #{tempType}>::#{operation}(#{operands[1].clValue(type)}, #{operands[0].clValue(type)}, result);"
     542    $asm.putc "    #{operands[1].clLValue(type)} = #{truncationHeader}result#{truncationFooter};"
     543    $asm.putc "    if (!success)"
    505544    $asm.putc "        goto #{operands[2].cLabel};"
    506545    $asm.putc "}"
     
    510549def cloopEmitCallSlowPath(operands)
    511550    $asm.putc "{"
    512     $asm.putc "    cloopStack.setCurrentStackPointer(sp.vp);"
     551    $asm.putc "    cloopStack.setCurrentStackPointer(sp.vp());"
    513552    $asm.putc "    SlowPathReturnType result = #{operands[0].cLabel}(#{operands[1].clDump}, #{operands[2].clDump});"
    514     $asm.putc "    decodeResult(result, t0.cvp, t1.cvp);"
     553    $asm.putc "    decodeResult(result, t0, t1);"
    515554    $asm.putc "}"
    516555end
    517556
    518557def cloopEmitCallSlowPathVoid(operands)
    519     $asm.putc "cloopStack.setCurrentStackPointer(sp.vp);"
     558    $asm.putc "cloopStack.setCurrentStackPointer(sp.vp());"
    520559    $asm.putc "#{operands[0].cLabel}(#{operands[1].clDump}, #{operands[2].clDump});"
    521560end
     
    598637
    599638        when "loadi"
    600             $asm.putc "#{operands[1].clValue(:uint)} = #{operands[0].uint32MemRef};"
     639            $asm.putc "#{operands[1].clLValue(:uint32)} = #{operands[0].uint32MemRef};"
    601640            # There's no need to call clearHighWord() here because the above will
    602641            # automatically take care of 0 extension.
    603642        when "loadis"
    604             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].int32MemRef};"
     643            $asm.putc "#{operands[1].clLValue(:int32)} = #{operands[0].int32MemRef};"
    605644        when "loadq"
    606             $asm.putc "#{operands[1].clValue(:int64)} = #{operands[0].int64MemRef};"
     645            $asm.putc "#{operands[1].clLValue(:int64)} = #{operands[0].int64MemRef};"
    607646        when "loadp"
    608             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].intMemRef};"
     647            $asm.putc "#{operands[1].clLValue} = #{operands[0].intMemRef};"
    609648        when "storei"
    610649            $asm.putc "#{operands[1].int32MemRef} = #{operands[0].clValue(:int32)};"
     
    614653            $asm.putc "#{operands[1].intMemRef} = #{operands[0].clValue(:int)};"
    615654        when "loadb"
    616             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].uint8MemRef};"
    617         when "loadbs", "loadbsp"
    618             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].int8MemRef};"
     655            $asm.putc "#{operands[1].clLValue(:int)} = #{operands[0].uint8MemRef};"
     656        when "loadbs"
     657            $asm.putc "#{operands[1].clLValue(:int)} = (uint32_t)(#{operands[0].int8MemRef});"
     658        when "loadbsp"
     659            $asm.putc "#{operands[1].clLValue(:int)} = #{operands[0].int8MemRef};"
    619660        when "storeb"
    620661            $asm.putc "#{operands[1].uint8MemRef} = #{operands[0].clValue(:int8)};"
    621662        when "loadh"
    622             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].uint16MemRef};"
     663            $asm.putc "#{operands[1].clLValue(:int)} = #{operands[0].uint16MemRef};"
    623664        when "loadhs"
    624             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].int16MemRef};"
     665            $asm.putc "#{operands[1].clLValue(:int)} = (uint32_t)(#{operands[0].int16MemRef});"
    625666        when "storeh"
    626667            $asm.putc "*#{operands[1].uint16MemRef} = #{operands[0].clValue(:int16)};"
    627668        when "loadd"
    628             $asm.putc "#{operands[1].clValue(:double)} = #{operands[0].dblMemRef};"
     669            $asm.putc "#{operands[1].clLValue(:double)} = #{operands[0].dblMemRef};"
    629670        when "stored"
    630671            $asm.putc "#{operands[1].dblMemRef} = #{operands[0].clValue(:double)};"
     
    641682        # Convert an int value to its double equivalent, and store it in a double register.
    642683        when "ci2d"
    643             $asm.putc "#{operands[1].clValue(:double)} = #{operands[0].clValue(:int32)};"
    644            
     684            $asm.putc "#{operands[1].clLValue(:double)} = (double)#{operands[0].clValue(:int32)}; // ci2d"
     685
    645686        when "bdeq"
    646687            cloopEmitCompareAndBranch(operands, :double, "==")
     
    670711
    671712        when "td2i"
    672             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].clValue(:double)};"
    673             $asm.putc "#{operands[1].clDump}.clearHighWord();"
     713            $asm.putc "#{operands[1].clLValue(:int)} = (uint32_t)(intptr_t)#{operands[0].clValue(:double)}; // td2i"
    674714
    675715        when "bcd2i"  # operands: srcDbl dstInt slowPath
    676             $asm.putc "{"
     716            $asm.putc "{ // bcd2i"
    677717            $asm.putc "    double d = #{operands[0].clValue(:double)};"
    678718            $asm.putc "    const int32_t asInt32 = int32_t(d);"
    679719            $asm.putc "    if (asInt32 != d || (!asInt32 && std::signbit(d))) // true for -0.0"
    680720            $asm.putc "        goto  #{operands[2].cLabel};"
    681             $asm.putc "    #{operands[1].clValue} = asInt32;"           
    682             $asm.putc "    #{operands[1].clDump}.clearHighWord();"
     721            $asm.putc "    #{operands[1].clLValue} = (uint32_t)asInt32;"
    683722            $asm.putc "}"
    684723
    685724        when "move"
    686             $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].clValue(:int)};"
     725            $asm.putc "#{operands[1].clLValue(:int)} = #{operands[0].clValue(:int)};"
    687726        when "sxi2q"
    688             $asm.putc "#{operands[1].clValue(:int64)} = #{operands[0].clValue(:int32)};"
     727            $asm.putc "#{operands[1].clLValue(:int64)} = #{operands[0].clValue(:int32)};"
    689728        when "zxi2q"
    690             $asm.putc "#{operands[1].clValue(:uint64)} = #{operands[0].clValue(:uint32)};"
     729            $asm.putc "#{operands[1].clLValue(:uint64)} = #{operands[0].clValue(:uint32)};"
    691730        when "nop"
    692731            $asm.putc "// nop"
     
    832871            $asm.putc "CRASH(); // break instruction not implemented."
    833872        when "ret"
    834             $asm.putc "opcode = lr.opcode;"
     873            $asm.putc "opcode = lr.opcode();"
    835874            $asm.putc "DISPATCH_OPCODE();"
    836875
     
    956995        # the lower 32 bits of t1. Leave the upper 32 bits of t0 and t1 unchanged.
    957996        when "cdqi"
    958             $asm.putc "{"
    959             $asm.putc "    int64_t temp = t0.i32; // sign extend the low 32bit"
    960             $asm.putc "    t0.i32 = temp; // low word"
    961             $asm.putc "    t0.clearHighWord();"
    962             $asm.putc "    t1.i32 = uint64_t(temp) >> 32; // high word"
    963             $asm.putc "    t1.clearHighWord();"
     997            $asm.putc "{ // cdqi"
     998            $asm.putc "    int64_t temp = t0.i32(); // sign extend the low 32bit"
     999            $asm.putc "    t0 = (uint32_t)temp; // low word"
     1000            $asm.putc "    t1 = (uint32_t)(temp >> 32); // high word"
    9641001            $asm.putc "}"
    9651002
     
    9771014            # Divide t1,t0 (EDX,EAX) by the specified arg, and store the remainder in t1,
    9781015            # and quotient in t0:
    979             $asm.putc "{"
    980             $asm.putc "    int64_t dividend = (int64_t(t1.u32) << 32) | t0.u32;"
     1016            $asm.putc "{ // idivi"
     1017            $asm.putc "    int64_t dividend = (int64_t(t1.u32()) << 32) | t0.u32();"
    9811018            $asm.putc "    int64_t divisor = #{operands[0].clValue(:int)};"
    982             $asm.putc "    t1.i32 = dividend % divisor; // remainder"
    983             $asm.putc "    t1.clearHighWord();"
    984             $asm.putc "    t0.i32 = dividend / divisor; // quotient"
    985             $asm.putc "    t0.clearHighWord();"
     1019            $asm.putc "    t1 = (uint32_t)(dividend % divisor); // remainder"
     1020            $asm.putc "    t0 = (uint32_t)(dividend / divisor); // quotient"
    9861021            $asm.putc "}"
    9871022
     
    9891024        # Decode 2 32-bit ints (low and high) into a 64-bit double.
    9901025        when "fii2d"
    991             $asm.putc "#{operands[2].clValue(:double)} = Ints2Double(#{operands[0].clValue(:uint32)}, #{operands[1].clValue(:uint32)});"
     1026            $asm.putc "#{operands[2].clLValue(:double)} = ints2Double(#{operands[0].clValue(:uint32)}, #{operands[1].clValue(:uint32)}); // fii2d"
    9921027
    9931028        # 32-bit instruction: f2dii dblOp int32LoOp int32HiOp (based on ARMv7)
    9941029        # Encode a 64-bit double into 2 32-bit ints (low and high).
    9951030        when "fd2ii"
    996             $asm.putc "Double2Ints(#{operands[0].clValue(:double)}, #{operands[1].clValue(:uint32)}, #{operands[2].clValue(:uint32)});"
     1031            $asm.putc "double2Ints(#{operands[0].clValue(:double)}, #{operands[1].clDump}, #{operands[2].clDump}); // fd2ii"
    9971032
    9981033        # 64-bit instruction: fq2d int64Op dblOp (based on X64)
    9991034        # Copy a bit-encoded double in a 64-bit int register to a double register.
    10001035        when "fq2d"
    1001             $asm.putc "#{operands[1].clValue(:double)} = #{operands[0].clValue(:castToDouble)};"
     1036            $asm.putc "#{operands[1].clLValue(:double)} = #{operands[0].clValue(:bitsAsDouble)}; // fq2d"
    10021037
    10031038        # 64-bit instruction: fd2q dblOp int64Op (based on X64 instruction set)
    10041039        # Copy a double as a bit-encoded double into a 64-bit int register.
    10051040        when "fd2q"
    1006             $asm.putc "#{operands[1].clValue(:int64)} = #{operands[0].clValue(:castToInt64)};"
     1041            $asm.putc "#{operands[1].clLValue(:int64)} = #{operands[0].clValue(:bitsAsInt64)}; // fd2q"
    10071042
    10081043        when "leai"
     
    10801115        when "cloopCallJSFunction"
    10811116            uid = $asm.newUID
    1082             $asm.putc "lr.opcode = getOpcode(llint_cloop_did_return_from_js_#{uid});"
     1117            $asm.putc "lr = getOpcode(llint_cloop_did_return_from_js_#{uid});"
    10831118            $asm.putc "opcode = #{operands[0].clValue(:opcode)};"
    10841119            $asm.putc "DISPATCH_OPCODE();"
     
    10891124        # have a fixed prototype of 1 args: the passed ExecState.
    10901125        when "cloopCallNative"
    1091             $asm.putc "cloopStack.setCurrentStackPointer(sp.vp);"
     1126            $asm.putc "cloopStack.setCurrentStackPointer(sp.vp());"
    10921127            $asm.putc "nativeFunc = #{operands[0].clValue(:nativeFunc)};"
    1093             $asm.putc "functionReturnValue = JSValue::decode(nativeFunc(t0.execState));"
     1128            $asm.putc "functionReturnValue = JSValue::decode(nativeFunc(t0.execState()));"
    10941129            $asm.putc "#if USE(JSVALUE32_64)"
    1095             $asm.putc "    t1.i = functionReturnValue.tag();"
    1096             $asm.putc "    t0.i = functionReturnValue.payload();"
     1130            $asm.putc "    t1 = functionReturnValue.tag();"
     1131            $asm.putc "    t0 = functionReturnValue.payload();"
    10971132            $asm.putc "#else // USE_JSVALUE64)"
    1098             $asm.putc "    t0.encodedJSValue = JSValue::encode(functionReturnValue);"
    1099             $asm.putc "#endif // USE_JSVALUE64)"           
     1133            $asm.putc "    t0 = JSValue::encode(functionReturnValue);"
     1134            $asm.putc "#endif // USE_JSVALUE64)"
    11001135
    11011136        # We can't do generic function calls with an arbitrary set of args, but
Note: See TracChangeset for help on using the changeset viewer.