Ignore:
Timestamp:
Nov 14, 2013, 8:52:48 AM (12 years ago)
Author:
[email protected]
Message:

REGRESSION (r159276): Fix lots of crashes for sh4 architecture.
https://bugs.webkit.org/show_bug.cgi?id=124347

Patch by Julien Brianceau <[email protected]> on 2013-11-14
Reviewed by Michael Saboff.

Since r159276, we have (t4 == a0 == r4) and (t5 == a1 == r5) in LLINT for sh4.
This leads to argument register trampling in cCallX macros, especially with cCall2
macro when arg1 == t4.

  • llint/LowLevelInterpreter32_64.asm: Use a new "setargs" pseudo-op to setup arguments for sh4.
  • offlineasm/instructions.rb:
  • offlineasm/sh4.rb: Lower "setargs" pseudo-op to setup argument registers and prevent register trampling issues.
File:
1 edited

Legend:

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

    r159283 r159288  
    564564
    565565
     566#
     567# Lowering of argument setup for SH4.
     568# This phase avoids argument register trampling. For example, if a0 == t4:
     569#
     570# setargs t1, t4
     571#
     572# becomes:
     573#
     574# move t4, a1
     575# move t1, a0
     576#
     577
     578def sh4LowerArgumentSetup(list)
     579    a0 = RegisterID.forName(codeOrigin, "a0")
     580    a1 = RegisterID.forName(codeOrigin, "a1")
     581    a2 = RegisterID.forName(codeOrigin, "a2")
     582    a3 = RegisterID.forName(codeOrigin, "a3")
     583    newList = []
     584    list.each {
     585        | node |
     586        if node.is_a? Instruction
     587            case node.opcode
     588            when "setargs"
     589                if node.operands.size == 2
     590                    if node.operands[1].sh4Operand != a0.sh4Operand
     591                        newList << Instruction.new(codeOrigin, "move", [node.operands[0], a0])
     592                        newList << Instruction.new(codeOrigin, "move", [node.operands[1], a1])
     593                    elsif node.operands[0].sh4Operand != a1.sh4Operand
     594                        newList << Instruction.new(codeOrigin, "move", [node.operands[1], a1])
     595                        newList << Instruction.new(codeOrigin, "move", [node.operands[0], a0])
     596                    else
     597                        # As (operands[0] == a1) and (operands[1] == a0), we just need to swap a0 and a1.
     598                        newList << Instruction.new(codeOrigin, "xori", [a0, a1])
     599                        newList << Instruction.new(codeOrigin, "xori", [a1, a0])
     600                        newList << Instruction.new(codeOrigin, "xori", [a0, a1])
     601                    end
     602                elsif node.operands.size == 4
     603                    # FIXME: We just raise an error if something is likely to go wrong for now.
     604                    # It would be better to implement a recovering algorithm.
     605                    if (node.operands[0].sh4Operand == a1.sh4Operand) or
     606                        (node.operands[0].sh4Operand == a2.sh4Operand) or
     607                        (node.operands[0].sh4Operand == a3.sh4Operand) or
     608                        (node.operands[1].sh4Operand == a0.sh4Operand) or
     609                        (node.operands[1].sh4Operand == a2.sh4Operand) or
     610                        (node.operands[1].sh4Operand == a3.sh4Operand) or
     611                        (node.operands[2].sh4Operand == a0.sh4Operand) or
     612                        (node.operands[2].sh4Operand == a1.sh4Operand) or
     613                        (node.operands[2].sh4Operand == a3.sh4Operand) or
     614                        (node.operands[3].sh4Operand == a0.sh4Operand) or
     615                        (node.operands[3].sh4Operand == a1.sh4Operand) or
     616                        (node.operands[3].sh4Operand == a2.sh4Operand)
     617                        raise "Potential argument register trampling detected."
     618                    end
     619
     620                    newList << Instruction.new(codeOrigin, "move", [node.operands[0], a0])
     621                    newList << Instruction.new(codeOrigin, "move", [node.operands[1], a1])
     622                    newList << Instruction.new(codeOrigin, "move", [node.operands[2], a2])
     623                    newList << Instruction.new(codeOrigin, "move", [node.operands[3], a3])
     624                else
     625                    raise "Invalid operands number (#{node.operands.size}) for setargs"
     626                end
     627            else
     628                newList << node
     629            end
     630        else
     631            newList << node
     632        end
     633    }
     634    newList
     635end
     636
     637
    566638class Sequence
    567639    def getModifiedListSH4
     
    614686
    615687        result = sh4LowerConstPool(result)
     688        result = sh4LowerArgumentSetup(result)
    616689
    617690        return result
     
    884957                    $asm.puts "mov.l #{operands[0].labelref.asmLabel}, #{operands[1].sh4Operand}"
    885958                end
    886             else
     959            elsif operands[0].sh4Operand != operands[1].sh4Operand
    887960                $asm.puts "mov #{sh4Operands(operands)}"
    888961            end
Note: See TracChangeset for help on using the changeset viewer.