Ignore:
Timestamp:
Sep 3, 2014, 2:50:46 PM (11 years ago)
Author:
[email protected]
Message:

[MIPS] Wrong register usage in LLInt op_catch.
https://bugs.webkit.org/show_bug.cgi?id=125168

Patch by Balazs Kilvady <[email protected]> on 2014-09-03
Reviewed by Geoffrey Garen.

Fix register usage and add PIC header to all the ops in LLInt.

  • offlineasm/instructions.rb:
  • offlineasm/mips.rb:
File:
1 edited

Legend:

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

    r172429 r173232  
    6363MIPS_GP_REG = SpecialRegister.new("$gp")
    6464MIPS_GPSAVE_REG = SpecialRegister.new("$s4")
    65 MIPS_JUMP_REG = SpecialRegister.new("$ra")
    6665MIPS_CALL_REG = SpecialRegister.new("$t9")
    6766MIPS_TEMP_FPRS = [SpecialRegister.new("$f16")]
     
    160159        raise "Unconverted absolute address at #{codeOriginString}"
    161160    end
     161end
     162
     163#
     164# Negate condition of branches to labels.
     165#
     166
     167class Instruction
     168    def mipsNegateCondition(list)
     169        /^(b(add|sub|or|mul|t)?)([ipb])/.match(opcode)
     170        case $~.post_match
     171        when "eq"
     172            op = "neq"
     173        when "neq"
     174            op = "eq"
     175        when "z"
     176            op = "nz"
     177        when "nz"
     178            op = "z"
     179        when "gt"
     180            op = "lteq"
     181        when "gteq"
     182            op = "lt"
     183        when "lt"
     184            op = "gteq"
     185        when "lteq"
     186            op = "gt"
     187        when "a"
     188            op = "beq"
     189        when "b"
     190            op = "aeq"
     191        when "aeq"
     192            op = "b"
     193        when "beq"
     194            op = "a"
     195        else
     196            raise "Can't negate #{opcode} branch."
     197        end
     198        noBranch = LocalLabel.unique("nobranch")
     199        noBranchRef = LocalLabelReference.new(codeOrigin, noBranch)
     200        toRef = operands[-1]
     201        list << Instruction.new(codeOrigin, "#{$1}#{$3}#{op}", operands[0..-2].push(noBranchRef), annotation)
     202        list << Instruction.new(codeOrigin, "la", [toRef, MIPS_CALL_REG])
     203        list << Instruction.new(codeOrigin, "jmp", [MIPS_CALL_REG])
     204        list << noBranch
     205    end
     206end
     207
     208def mipsLowerFarBranchOps(list)
     209    newList = []
     210    list.each {
     211        | node |
     212        if node.is_a? Instruction
     213            annotation = node.annotation
     214            case node.opcode
     215            when /^b(add|sub|or|mul|t)?([ipb])/
     216                if node.operands[-1].is_a? LabelReference
     217                    node.mipsNegateCondition(newList)
     218                    next
     219                end
     220            end
     221        end
     222        newList << node
     223    }
     224    newList
    162225end
    163226
     
    446509#
    447510
     511class LocalLabelReference
     512    def register?
     513        false
     514    end
     515end
     516
     517def mipsAsRegister(preList, postList, operand, needRestore)
     518    tmp = MIPS_CALL_REG
     519    if operand.address?
     520        preList << Instruction.new(operand.codeOrigin, "loadp", [operand, MIPS_CALL_REG])
     521    elsif operand.is_a? LabelReference
     522        preList << Instruction.new(operand.codeOrigin, "la", [operand, MIPS_CALL_REG])
     523    elsif operand.register? and operand != MIPS_CALL_REG
     524        preList << Instruction.new(operand.codeOrigin, "move", [operand, MIPS_CALL_REG])
     525    else
     526        needRestore = false
     527        tmp = operand
     528    end
     529    if needRestore
     530        postList << Instruction.new(operand.codeOrigin, "move", [MIPS_GPSAVE_REG, MIPS_GP_REG])
     531    end
     532    tmp
     533end
     534
    448535def mipsLowerMisplacedAddresses(list)
    449536    newList = []
     
    455542            case node.opcode
    456543            when "jmp"
    457                 if node.operands[0].address?
    458                     newList << Instruction.new(node.operands[0].codeOrigin, "loadi", [node.operands[0], MIPS_JUMP_REG])
    459                     newList << Instruction.new(node.codeOrigin, node.opcode, [MIPS_JUMP_REG])
    460                 else
    461                     newList << Instruction.new(node.codeOrigin,
    462                                                node.opcode,
    463                                                [riscAsRegister(newList, postInstructions, node.operands[0], "p", false)])
    464                 end
     544                newList << Instruction.new(node.codeOrigin,
     545                                           node.opcode,
     546                                           [mipsAsRegister(newList, [], node.operands[0], false)])
    465547            when "call"
    466                 restoreGP = false;
    467                 tmp = MIPS_CALL_REG
    468                 if node.operands[0].address?
    469                     newList << Instruction.new(node.operands[0].codeOrigin, "loadp", [node.operands[0], MIPS_CALL_REG])
    470                     restoreGP = true;
    471                 elsif node.operands[0].is_a? LabelReference
    472                     tmp = node.operands[0]
    473                     restoreGP = true;
    474                 elsif node.operands[0].register?
    475                     newList << Instruction.new(node.operands[0].codeOrigin, "move", [node.operands[0], MIPS_CALL_REG])
    476                     restoreGP = true;
    477                 else
    478                     tmp = node.operands[0]
    479                 end
    480                 newList << Instruction.new(node.codeOrigin, node.opcode, [tmp])
    481                 if restoreGP
    482                     newList << Instruction.new(node.codeOrigin, "move", [MIPS_GPSAVE_REG, MIPS_GP_REG])
    483                 end
     548                newList << Instruction.new(node.codeOrigin,
     549                                           node.opcode,
     550                                           [mipsAsRegister(newList, postInstructions, node.operands[0], true)])
    484551            when "slt", "sltu"
    485552                newList << Instruction.new(node.codeOrigin,
     
    566633
    567634#
    568 # Add PIC compatible header code to prologue/entry rutins.
     635# Add PIC compatible header code to all the LLInt rutins.
    569636#
    570637
     
    575642        myList << node
    576643        if node.is_a? Label
    577             if /_prologue$/.match(node.name) || /^_llint_function_/.match(node.name)
    578                 # Functions called from trampoline/JIT codes.
    579                 myList << Instruction.new(node.codeOrigin, "pichdr", [])
    580             elsif /_llint_op_catch/.match(node.name)
    581                 # Exception cactcher entry point function.
    582                 myList << Instruction.new(node.codeOrigin, "pichdrra", [])
    583             end
     644            myList << Instruction.new(node.codeOrigin, "pichdr", [])
    584645        end
    585646    }
     
    607668
    608669        result = mipsAddPICCode(result)
     670        result = mipsLowerFarBranchOps(result)
    609671        result = mipsLowerSimpleBranchOps(result)
    610672        result = riscLowerSimpleBranchOps(result)
     
    712774    else
    713775        $asm.puts "bc1f #{operands[2].asmLabel}"
     776    end
     777end
     778
     779def emitMIPSJumpOrCall(opcode, operand)
     780    if operand.label?
     781        raise "Direct call/jump to a not local label." unless operand.is_a? LocalLabelReference
     782        $asm.puts "#{opcode} #{operand.asmLabel}"
     783    else
     784        raise "Invalid call/jump register." unless operand == MIPS_CALL_REG
     785        $asm.puts "#{opcode}r #{MIPS_CALL_REG.mipsOperand}"
    714786    end
    715787end
     
    785857        when "stored"
    786858            $asm.puts "sdc1 #{mipsOperands(operands)}"
     859        when "la"
     860            $asm.puts "la #{operands[1].mipsOperand}, #{operands[0].asmLabel}"
    787861        when "addd"
    788862            emitMIPS("add.d", operands)
     
    872946            $asm.puts "ble #{mipsOperands(operands[0..1])}, #{operands[2].asmLabel}"
    873947        when "jmp"
    874             if operands[0].label?
    875                 $asm.puts "j #{operands[0].asmLabel}"
    876             else
    877                 $asm.puts "jr #{operands[0].mipsOperand}"
    878             end
     948            emitMIPSJumpOrCall("j", operands[0])
    879949        when "call"
    880             if operands[0].label?
    881                 $asm.puts "jal #{operands[0].asmLabel}"
    882             else
    883                 $asm.puts "jalr #{operands[0].mipsOperand}"
    884             end
     950            emitMIPSJumpOrCall("jal", operands[0])
    885951        when "break"
    886952            $asm.puts "break"
     
    9411007            $asm.puts "sltu #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}"
    9421008        when "pichdr"
    943             $asm.putStr("OFFLINE_ASM_CPLOAD($25)")
    944             $asm.puts "move $s4, $gp"
    945         when "pichdrra"
    946             $asm.putStr("OFFLINE_ASM_CPLOAD($31)")
    947             $asm.puts "move $s4, $gp"
     1009            $asm.putStr("OFFLINE_ASM_CPLOAD(#{MIPS_CALL_REG.mipsOperand})")
     1010            $asm.puts "move #{MIPS_GPSAVE_REG.mipsOperand}, #{MIPS_GP_REG.mipsOperand}"
    9481011        when "memfence"
    9491012            $asm.puts "sync"
Note: See TracChangeset for help on using the changeset viewer.