diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/offlineasm/mips.rb | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/offlineasm/mips.rb')
-rw-r--r-- | Source/JavaScriptCore/offlineasm/mips.rb | 243 |
1 files changed, 165 insertions, 78 deletions
diff --git a/Source/JavaScriptCore/offlineasm/mips.rb b/Source/JavaScriptCore/offlineasm/mips.rb index 686f58f16..53bb9c143 100644 --- a/Source/JavaScriptCore/offlineasm/mips.rb +++ b/Source/JavaScriptCore/offlineasm/mips.rb @@ -24,6 +24,43 @@ require 'risc' +# GPR conventions, to match the baseline JIT +# +# $a0 => a0 +# $a1 => a1 +# $a2 => a2 +# $a3 => a3 +# $v0 => t0, r0 +# $v1 => t1, r1 +# $t0 => (scratch) +# $t1 => (scratch) +# $t2 => t2 +# $t3 => t3 +# $t4 => t4 +# $t5 => t5 +# $t6 => t6 +# $t7 => (scratch) +# $t8 => (scratch) +# $t9 => (stores the callee of a call opcode) +# $gp => (globals) +# $s4 => (callee-save used to preserve $gp across calls) +# $ra => lr +# $sp => sp +# $fp => cfr +# +# FPR conventions, to match the baseline JIT +# We don't have fa2 or fa3! +# $f0 => ft0, fr +# $f2 => ft1 +# $f4 => ft2 +# $f6 => ft3 +# $f8 => ft4 +# $f10 => ft5 +# $f12 => fa0 +# $f14 => fa1 +# $f16 => (scratch) +# $f18 => (scratch) + class Assembler def putStr(str) @outp.puts str @@ -57,12 +94,10 @@ class SpecialRegister < NoChildren end end -MIPS_TEMP_GPRS = [SpecialRegister.new("$t5"), SpecialRegister.new("$t6"), SpecialRegister.new("$t7"), - SpecialRegister.new("$t8")] +MIPS_TEMP_GPRS = [SpecialRegister.new("$t0"), SpecialRegister.new("$t1"), SpecialRegister.new("$t7"), SpecialRegister.new("$t8")] MIPS_ZERO_REG = SpecialRegister.new("$zero") MIPS_GP_REG = SpecialRegister.new("$gp") MIPS_GPSAVE_REG = SpecialRegister.new("$s4") -MIPS_JUMP_REG = SpecialRegister.new("$ra") MIPS_CALL_REG = SpecialRegister.new("$t9") MIPS_TEMP_FPRS = [SpecialRegister.new("$f16")] MIPS_SCRATCH_FPR = SpecialRegister.new("$f18") @@ -86,24 +121,18 @@ class RegisterID "$a2" when "a3" "$a3" - when "r0", "t0" + when "t0", "r0" "$v0" - when "r1", "t1" + when "t1", "r1" "$v1" when "t2" "$t2" when "t3" - "$s3" - when "t4" # PC reg in llint - "$s2" + "$t3" + when "t4" + "$t4" when "t5" "$t5" - when "t6" - "$t6" - when "t7" - "$t7" - when "t8" - "$t8" when "cfr" "$fp" when "lr" @@ -162,6 +191,70 @@ class AbsoluteAddress end # +# Negate condition of branches to labels. +# + +class Instruction + def mipsNegateCondition(list) + /^(b(add|sub|or|mul|t)?)([ipb])/.match(opcode) + case $~.post_match + when "eq" + op = "neq" + when "neq" + op = "eq" + when "z" + op = "nz" + when "nz" + op = "z" + when "gt" + op = "lteq" + when "gteq" + op = "lt" + when "lt" + op = "gteq" + when "lteq" + op = "gt" + when "a" + op = "beq" + when "b" + op = "aeq" + when "aeq" + op = "b" + when "beq" + op = "a" + else + raise "Can't negate #{opcode} branch." + end + noBranch = LocalLabel.unique("nobranch") + noBranchRef = LocalLabelReference.new(codeOrigin, noBranch) + toRef = operands[-1] + list << Instruction.new(codeOrigin, "#{$1}#{$3}#{op}", operands[0..-2].push(noBranchRef), annotation) + list << Instruction.new(codeOrigin, "la", [toRef, MIPS_CALL_REG]) + list << Instruction.new(codeOrigin, "jmp", [MIPS_CALL_REG]) + list << noBranch + end +end + +def mipsLowerFarBranchOps(list) + newList = [] + list.each { + | node | + if node.is_a? Instruction + annotation = node.annotation + case node.opcode + when /^b(add|sub|or|mul|t)?([ipb])/ + if node.operands[-1].is_a? LabelReference + node.mipsNegateCondition(newList) + next + end + end + end + newList << node + } + newList +end + +# # Lower 'and' masked branches # @@ -172,9 +265,10 @@ def lowerMIPSCondBranch(list, condOp, node) [node.operands[0], MIPS_ZERO_REG, node.operands[-1]], node.annotation) elsif node.operands.size == 3 + tl = condOp[-1, 1] tmp = Tmp.new(node.codeOrigin, :gpr) list << Instruction.new(node.codeOrigin, - "andi", + "and" + tl, [node.operands[0], node.operands[1], tmp], node.annotation) list << Instruction.new(node.codeOrigin, @@ -431,6 +525,8 @@ def mipsLowerMisplacedImmediates(list) end when /^(addi|subi)/ newList << node.riscLowerMalformedImmediatesRecurse(newList, -0x7fff..0x7fff) + when "andi", "andp", "ori", "orp", "xori", "xorp" + newList << node.riscLowerMalformedImmediatesRecurse(newList, 0..0xffff) else newList << node end @@ -445,6 +541,30 @@ end # Specialization of lowering of misplaced addresses. # +class LocalLabelReference + def register? + false + end +end + +def mipsAsRegister(preList, postList, operand, needRestore) + tmp = MIPS_CALL_REG + if operand.address? + preList << Instruction.new(operand.codeOrigin, "loadp", [operand, MIPS_CALL_REG]) + elsif operand.is_a? LabelReference + preList << Instruction.new(operand.codeOrigin, "la", [operand, MIPS_CALL_REG]) + elsif operand.register? and operand != MIPS_CALL_REG + preList << Instruction.new(operand.codeOrigin, "move", [operand, MIPS_CALL_REG]) + else + needRestore = false + tmp = operand + end + if needRestore + postList << Instruction.new(operand.codeOrigin, "move", [MIPS_GPSAVE_REG, MIPS_GP_REG]) + end + tmp +end + def mipsLowerMisplacedAddresses(list) newList = [] list.each { @@ -454,33 +574,13 @@ def mipsLowerMisplacedAddresses(list) annotation = node.annotation case node.opcode when "jmp" - if node.operands[0].address? - newList << Instruction.new(node.operands[0].codeOrigin, "loadi", [node.operands[0], MIPS_JUMP_REG]) - newList << Instruction.new(node.codeOrigin, node.opcode, [MIPS_JUMP_REG]) - else - newList << Instruction.new(node.codeOrigin, - node.opcode, - [riscAsRegister(newList, postInstructions, node.operands[0], "p", false)]) - end + newList << Instruction.new(node.codeOrigin, + node.opcode, + [mipsAsRegister(newList, [], node.operands[0], false)]) when "call" - restoreGP = false; - tmp = MIPS_CALL_REG - if node.operands[0].address? - newList << Instruction.new(node.operands[0].codeOrigin, "loadp", [node.operands[0], MIPS_CALL_REG]) - restoreGP = true; - elsif node.operands[0].is_a? LabelReference - tmp = node.operands[0] - restoreGP = true; - elsif node.operands[0].register? - newList << Instruction.new(node.operands[0].codeOrigin, "move", [node.operands[0], MIPS_CALL_REG]) - restoreGP = true; - else - tmp = node.operands[0] - end - newList << Instruction.new(node.codeOrigin, node.opcode, [tmp]) - if restoreGP - newList << Instruction.new(node.codeOrigin, "move", [MIPS_GPSAVE_REG, MIPS_GP_REG]) - end + newList << Instruction.new(node.codeOrigin, + node.opcode, + [mipsAsRegister(newList, postInstructions, node.operands[0], true)]) when "slt", "sltu" newList << Instruction.new(node.codeOrigin, node.opcode, @@ -489,6 +589,10 @@ def mipsLowerMisplacedAddresses(list) newList << Instruction.new(node.codeOrigin, node.opcode, riscAsRegisters(newList, [], node.operands, "b")) + when "andb" + newList << Instruction.new(node.codeOrigin, + "andi", + riscAsRegisters(newList, [], node.operands, "b")) when /^(bz|bnz|bs|bo)/ tl = $~.post_match == "" ? "i" : $~.post_match newList << Instruction.new(node.codeOrigin, @@ -565,7 +669,7 @@ class Address end # -# Add PIC compatible header code to prologue/entry rutins. +# Add PIC compatible header code to all the LLInt rutins. # def mipsAddPICCode(list) @@ -574,13 +678,7 @@ def mipsAddPICCode(list) | node | myList << node if node.is_a? Label - if /_prologue$/.match(node.name) || /^_llint_function_/.match(node.name) - # Functions called from trampoline/JIT codes. - myList << Instruction.new(node.codeOrigin, "pichdr", []) - elsif /_llint_op_catch/.match(node.name) - # Exception cactcher entry point function. - myList << Instruction.new(node.codeOrigin, "pichdrra", []) - end + myList << Instruction.new(node.codeOrigin, "pichdr", []) end } myList @@ -606,6 +704,7 @@ class Sequence } result = mipsAddPICCode(result) + result = mipsLowerFarBranchOps(result) result = mipsLowerSimpleBranchOps(result) result = riscLowerSimpleBranchOps(result) result = riscLowerHardBranchOps(result) @@ -714,6 +813,16 @@ def emitMIPSDoubleBranch(branchOpcode, neg, operands) end end +def emitMIPSJumpOrCall(opcode, operand) + if operand.label? + raise "Direct call/jump to a not local label." unless operand.is_a? LocalLabelReference + $asm.puts "#{opcode} #{operand.asmLabel}" + else + raise "Invalid call/jump register." unless operand == MIPS_CALL_REG + $asm.puts "#{opcode}r #{MIPS_CALL_REG.mipsOperand}" + end +end + class Instruction def lowerMIPS $asm.comment codeOriginString @@ -784,6 +893,8 @@ class Instruction $asm.puts "ldc1 #{mipsFlippedOperands(operands)}" when "stored" $asm.puts "sdc1 #{mipsOperands(operands)}" + when "la" + $asm.puts "la #{operands[1].mipsOperand}, #{operands[0].asmLabel}" when "addd" emitMIPS("add.d", operands) when "divd" @@ -850,20 +961,6 @@ class Instruction $asm.puts "addiu $sp, $sp, -4" $asm.puts "sw #{op.mipsOperand}, 0($sp)" } - when "popCalleeSaves" - $asm.puts "lw $16, 0($sp)" - $asm.puts "lw $17, 4($sp)" - $asm.puts "lw $18, 8($sp)" - $asm.puts "lw $19, 12($sp)" - $asm.puts "lw $20, 16($sp)" - $asm.puts "addiu $sp, $sp, 20" - when "pushCalleeSaves" - $asm.puts "addiu $sp, $sp, -20" - $asm.puts "sw $20, 16($sp)" - $asm.puts "sw $19, 12($sp)" - $asm.puts "sw $18, 8($sp)" - $asm.puts "sw $17, 4($sp)" - $asm.puts "sw $16, 0($sp)" when "move", "sxi2p", "zxi2p" if operands[0].is_a? Immediate mipsMoveImmediate(operands[0].value, operands[1]) @@ -885,17 +982,9 @@ class Instruction when "bilteq", "bplteq", "bblteq" $asm.puts "ble #{mipsOperands(operands[0..1])}, #{operands[2].asmLabel}" when "jmp" - if operands[0].label? - $asm.puts "j #{operands[0].asmLabel}" - else - $asm.puts "jr #{operands[0].mipsOperand}" - end + emitMIPSJumpOrCall("j", operands[0]) when "call" - if operands[0].label? - $asm.puts "jal #{operands[0].asmLabel}" - else - $asm.puts "jalr #{operands[0].mipsOperand}" - end + emitMIPSJumpOrCall("jal", operands[0]) when "break" $asm.puts "break" when "ret" @@ -949,16 +1038,14 @@ class Instruction $asm.puts "movz #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}" when "movn" $asm.puts "movn #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}" + when "setcallreg" + $asm.puts "move #{MIPS_CALL_REG.mipsOperand}, #{operands[0].mipsOperand}" when "slt", "sltb" $asm.puts "slt #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}" when "sltu", "sltub" $asm.puts "sltu #{operands[0].mipsOperand}, #{operands[1].mipsOperand}, #{operands[2].mipsOperand}" when "pichdr" - $asm.putStr("OFFLINE_ASM_CPLOAD($25)") - $asm.puts "move $s4, $gp" - when "pichdrra" - $asm.putStr("OFFLINE_ASM_CPLOAD($31)") - $asm.puts "move $s4, $gp" + $asm.putStr("OFFLINE_ASM_CPLOAD(#{MIPS_CALL_REG.mipsOperand})") when "memfence" $asm.puts "sync" else |