Ignore:
Timestamp:
May 30, 2013, 4:21:17 PM (12 years ago)
Author:
[email protected]
Message:

[sh4] Optimize NaN checks in LLINT for floating point comparisons.
https://bugs.webkit.org/show_bug.cgi?id=117049

Patch by Julien Brianceau <[email protected]> on 2013-05-30
Reviewed by Oliver Hunt.

Use the fcmp/eq opcode in sh4 LLINT to test if a double is NaN.
This is more efficient, doesn't require two tmp registers and requires
less code than current implementation (which converts double to float,
then checks 'E = Emax + 1' and 'f != 0').

  • offlineasm/sh4.rb:
File:
1 edited

Legend:

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

    r150644 r150992  
    321321            when "bdltun", "bdgtun"
    322322                # Handle specific floating point unordered opcodes.
    323                 tmp1 = Tmp.new(codeOrigin, :gpr)
    324                 tmp2 = Tmp.new(codeOrigin, :gpr)
    325                 newList << Instruction.new(codeOrigin, "bdnan", [node.operands[0], node.operands[2], tmp1, tmp2])
    326                 newList << Instruction.new(codeOrigin, "bdnan", [node.operands[1], node.operands[2], tmp1, tmp2])
     323                newList << Instruction.new(codeOrigin, "bdnan", [node.operands[0], node.operands[2]])
     324                newList << Instruction.new(codeOrigin, "bdnan", [node.operands[1], node.operands[2]])
    327325                newList << Instruction.new(codeOrigin, node.opcode[0..-3], node.operands)
    328326            when "bdnequn", "bdgtequn", "bdltequn"
     
    330328            when "bdneq", "bdgteq", "bdlteq"
    331329                # Handle specific floating point ordered opcodes.
    332                 tmp1 = Tmp.new(codeOrigin, :gpr)
    333                 tmp2 = Tmp.new(codeOrigin, :gpr)
    334330                outlabel = LocalLabel.unique("out_#{node.opcode}")
    335331                outref = LocalLabelReference.new(codeOrigin, outlabel)
    336                 newList << Instruction.new(codeOrigin, "bdnan", [node.operands[0], outref, tmp1, tmp2])
    337                 newList << Instruction.new(codeOrigin, "bdnan", [node.operands[1], outref, tmp1, tmp2])
     332                newList << Instruction.new(codeOrigin, "bdnan", [node.operands[0], outref])
     333                newList << Instruction.new(codeOrigin, "bdnan", [node.operands[1], outref])
    338334                newList << Instruction.new(codeOrigin, node.opcode, node.operands)
    339335                newList << outlabel
     
    545541
    546542def emitSH4BranchIfNaN(operands)
    547     raise "Invalid operands number (#{operands.size})" unless operands.size == 4
    548     dblop = operands[0]
    549     labelop = operands[1]
    550     scrmask = operands[2]
    551     scrint = operands[3]
    552 
    553     notNaNlabel = LocalLabel.unique("notnan")
    554     notNaNref = LocalLabelReference.new(codeOrigin, notNaNlabel)
    555     constlabel1 = LocalLabel.unique("notnanConst1")
    556     constlabel2 = LocalLabel.unique("notnanConst2")
    557 
    558     # If we don't have "E = Emax + 1", it's not a NaN.
    559     $asm.puts "fcnvds #{dblop.sh4Operand}, fpul"
    560     $asm.puts "sts fpul, #{scrint.sh4Operand}"
    561     $asm.puts "mov.l #{LocalLabelReference.new(codeOrigin, constlabel1).asmLabel}, #{scrmask.sh4Operand}"
    562     $asm.puts "and #{sh4Operands([scrmask, scrint])}"
    563     $asm.puts "cmp/eq #{sh4Operands([scrmask, scrint])}"
    564     $asm.puts "bf #{notNaNref.asmLabel}"
    565 
    566     # If we have "E = Emax + 1" and "f != 0", then it's a NaN.
    567     $asm.puts "sts fpul, #{scrint.sh4Operand}"
    568     $asm.puts "mov.l #{LocalLabelReference.new(codeOrigin, constlabel2).asmLabel}, #{scrmask.sh4Operand}"
    569     $asm.puts "tst #{sh4Operands([scrmask, scrint])}"
    570     $asm.puts "bt #{notNaNref.asmLabel}"
    571     $asm.puts "bra #{labelop.asmLabel}"
    572     $asm.puts "nop"
    573 
    574     $asm.puts ".balign 4"
    575     constlabel1.lower("SH4")
    576     $asm.puts ".long 0x7f800000"
    577     constlabel2.lower("SH4")
    578     $asm.puts ".long 0x003fffff"
    579 
    580     notNaNlabel.lower("SH4")
     543    raise "Invalid operands number (#{operands.size})" unless operands.size == 2
     544    $asm.puts "fcmp/eq #{sh4Operands([operands[0], operands[0]])}"
     545    $asm.puts "bf #{operands[1].asmLabel}"
    581546end
    582547
Note: See TracChangeset for help on using the changeset viewer.