Changeset 131989 in webkit
- Timestamp:
- Oct 20, 2012 1:06:39 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r131982 r131989 1 2012-10-20 Filip Pizlo <fpizlo@apple.com> 2 3 LLInt backends of non-ARM RISC platforms should be able to share code with the existing ARMv7 backend 4 https://bugs.webkit.org/show_bug.cgi?id=99745 5 6 Reviewed by Geoffrey Garen. 7 8 This moves all of the things in armv7.rb that I thought are generally useful out 9 into risc.rb. It also separates some phases (branch ops is separated into one 10 phase that does sensible things, and another that does things that are painfully 11 ARM-specific), and removes ARM assumptions from others by using a callback to 12 drive exactly what lowering must happen. The goal here is to minimize the future 13 maintenance burden of LLInt by ensuring that the various platforms share as much 14 lowering code as possible. 15 16 * offlineasm/armv7.rb: 17 * offlineasm/risc.rb: Added. 18 1 19 2012-10-19 Filip Pizlo <fpizlo@apple.com> 2 20 -
trunk/Source/JavaScriptCore/offlineasm/armv7.rb
r130826 r131989 1 # Copyright (C) 2011 Apple Inc. All rights reserved.1 # Copyright (C) 2011, 2012 Apple Inc. All rights reserved. 2 2 # 3 3 # Redistribution and use in source and binary forms, with or without … … 25 25 require "ast" 26 26 require "opt" 27 require "risc" 27 28 28 29 class Node … … 34 35 end 35 36 36 class SpecialRegister < NoChildren37 class SpecialRegister 37 38 def armV7Operand 38 39 @name … … 134 135 135 136 # 136 # Lowering of branch ops. For example:137 #138 # baddiz foo, bar, baz139 #140 # will become:141 #142 # addi foo, bar143 # bz baz144 #145 146 def armV7LowerBranchOps(list)147 newList = []148 list.each {149 | node |150 if node.is_a? Instruction151 annotation = node.annotation152 case node.opcode153 when /^b(addi|subi|ori|addp)/154 op = $1155 branch = "b" + $~.post_match156 157 case op158 when "addi", "addp"159 op = "addis"160 when "subi"161 op = "subis"162 when "ori"163 op = "oris"164 end165 166 newList << Instruction.new(node.codeOrigin, op, node.operands[0..-2], annotation)167 newList << Instruction.new(node.codeOrigin, branch, [node.operands[-1]])168 when "bmulio"169 tmp1 = Tmp.new(node.codeOrigin, :gpr)170 tmp2 = Tmp.new(node.codeOrigin, :gpr)171 newList << Instruction.new(node.codeOrigin, "smulli", [node.operands[0], node.operands[1], node.operands[1], tmp1], annotation)172 newList << Instruction.new(node.codeOrigin, "rshifti", [node.operands[-2], Immediate.new(node.codeOrigin, 31), tmp2])173 newList << Instruction.new(node.codeOrigin, "bineq", [tmp1, tmp2, node.operands[-1]])174 when /^bmuli/175 condition = $~.post_match176 newList << Instruction.new(node.codeOrigin, "muli", node.operands[0..-2], annotation)177 newList << Instruction.new(node.codeOrigin, "bti" + condition, [node.operands[-2], node.operands[-1]])178 else179 newList << node180 end181 else182 newList << node183 end184 }185 newList186 end187 188 #189 # Lowering of shift ops. For example:190 #191 # lshifti foo, bar192 #193 # will become:194 #195 # andi foo, 31, tmp196 # lshifti tmp, bar197 #198 199 def armV7SanitizeShift(operand, list)200 return operand if operand.immediate?201 202 tmp = Tmp.new(operand.codeOrigin, :gpr)203 list << Instruction.new(operand.codeOrigin, "andi", [operand, Immediate.new(operand.codeOrigin, 31), tmp])204 tmp205 end206 207 def armV7LowerShiftOps(list)208 newList = []209 list.each {210 | node |211 if node.is_a? Instruction212 case node.opcode213 when "lshifti", "rshifti", "urshifti", "lshiftp", "rshiftp", "urshiftp"214 if node.operands.size == 2215 newList << Instruction.new(node.codeOrigin, node.opcode, [armV7SanitizeShift(node.operands[0], newList), node.operands[1]], node.annotation)216 else217 newList << Instruction.new(node.codeOrigin, node.opcode, [node.operands[0], armV7SanitizeShift(node.operands[1], newList), node.operands[2]], node.annotation)218 raise "Wrong number of operands for shift at #{node.codeOriginString}" unless node.operands.size == 3219 end220 else221 newList << node222 end223 else224 newList << node225 end226 }227 newList228 end229 230 #231 # Lowering of malformed addresses. For example:232 #233 # loadp 10000[foo], bar234 #235 # will become:236 #237 # move 10000, tmp238 # addp foo, tmp239 # loadp 0[tmp], bar240 #241 242 class Node243 def armV7LowerMalformedAddressesRecurse(list)244 mapChildren {245 | node |246 node.armV7LowerMalformedAddressesRecurse(list)247 }248 end249 end250 251 class Address252 def armV7LowerMalformedAddressesRecurse(list)253 if offset.value < -0xff or offset.value > 0xfff254 tmp = Tmp.new(codeOrigin, :gpr)255 list << Instruction.new(codeOrigin, "move", [offset, tmp])256 list << Instruction.new(codeOrigin, "addp", [base, tmp])257 Address.new(codeOrigin, tmp, Immediate.new(codeOrigin, 0))258 else259 self260 end261 end262 end263 264 class BaseIndex265 def armV7LowerMalformedAddressesRecurse(list)266 if offset.value != 0267 tmp = Tmp.new(codeOrigin, :gpr)268 list << Instruction.new(codeOrigin, "move", [offset, tmp])269 list << Instruction.new(codeOrigin, "addp", [base, tmp])270 BaseIndex.new(codeOrigin, tmp, index, scale, Immediate.new(codeOrigin, 0))271 else272 self273 end274 end275 end276 277 class AbsoluteAddress278 def armV7LowerMalformedAddressesRecurse(list)279 tmp = Tmp.new(codeOrigin, :gpr)280 list << Instruction.new(codeOrigin, "move", [address, tmp])281 Address.new(codeOrigin, tmp, Immediate.new(codeOrigin, 0))282 end283 end284 285 def armV7LowerMalformedAddresses(list)286 newList = []287 list.each {288 | node |289 newList << node.armV7LowerMalformedAddressesRecurse(newList)290 }291 newList292 end293 294 #295 # Lowering of malformed addresses in double loads and stores. For example:296 #297 # loadd [foo, bar, 8], baz298 #299 # becomes:300 #301 # leap [foo, bar, 8], tmp302 # loadd [tmp], baz303 #304 305 class Node306 def armV7DoubleAddress(list)307 self308 end309 end310 311 class BaseIndex312 def armV7DoubleAddress(list)313 tmp = Tmp.new(codeOrigin, :gpr)314 list << Instruction.new(codeOrigin, "leap", [self, tmp])315 Address.new(codeOrigin, tmp, Immediate.new(codeOrigin, 0))316 end317 end318 319 def armV7LowerMalformedAddressesDouble(list)320 newList = []321 list.each {322 | node |323 if node.is_a? Instruction324 case node.opcode325 when "loadd"326 newList << Instruction.new(node.codeOrigin, "loadd", [node.operands[0].armV7DoubleAddress(newList), node.operands[1]], node.annotation)327 when "stored"328 newList << Instruction.new(node.codeOrigin, "stored", [node.operands[0], node.operands[1].armV7DoubleAddress(newList)], node.annotation)329 else330 newList << node331 end332 else333 newList << node334 end335 }336 newList337 end338 339 #340 # Lowering of misplaced immediates. For example:341 #342 # storei 0, [foo]343 #344 # will become:345 #346 # move 0, tmp347 # storei tmp, [foo]348 #349 350 def armV7LowerMisplacedImmediates(list)351 newList = []352 list.each {353 | node |354 if node.is_a? Instruction355 case node.opcode356 when "storeb", "storei", "storep"357 operands = node.operands358 newOperands = []359 operands.each {360 | operand |361 if operand.is_a? Immediate362 tmp = Tmp.new(operand.codeOrigin, :gpr)363 newList << Instruction.new(operand.codeOrigin, "move", [operand, tmp])364 newOperands << tmp365 else366 newOperands << operand367 end368 }369 newList << Instruction.new(node.codeOrigin, node.opcode, newOperands, node.annotation)370 else371 newList << node372 end373 else374 newList << node375 end376 }377 newList378 end379 380 #381 # Lowering of malformed immediates except when used in a "move" instruction.382 # For example:383 #384 # addp 642641, foo385 #386 # will become:387 #388 # move 642641, tmp389 # addp tmp, foo390 #391 392 class Node393 def armV7LowerMalformedImmediatesRecurse(list)394 mapChildren {395 | node |396 node.armV7LowerMalformedImmediatesRecurse(list)397 }398 end399 end400 401 class Address402 def armV7LowerMalformedImmediatesRecurse(list)403 self404 end405 end406 407 class BaseIndex408 def armV7LowerMalformedImmediatesRecurse(list)409 self410 end411 end412 413 class AbsoluteAddress414 def armV7LowerMalformedImmediatesRecurse(list)415 self416 end417 end418 419 class Immediate420 def armV7LowerMalformedImmediatesRecurse(list)421 if value < 0 or value > 255422 tmp = Tmp.new(codeOrigin, :gpr)423 list << Instruction.new(codeOrigin, "move", [self, tmp])424 tmp425 else426 self427 end428 end429 end430 431 def armV7LowerMalformedImmediates(list)432 newList = []433 list.each {434 | node |435 if node.is_a? Instruction436 annotation = node.annotation437 case node.opcode438 when "move"439 newList << node440 when "addi", "addp", "addis", "subi", "subp", "subis"441 if node.operands[0].is_a? Immediate and442 node.operands[0].value < 0 and443 node.operands[0].value >= 255 and444 node.operands.size == 2445 if node.opcode =~ /add/446 newOpcode = "sub" + node.opcode[-1..-1]447 else448 newOpcode = "add" + node.opcode[-1..-1]449 end450 newList << Instruction.new(node.codeOrigin, newOpcode,451 [Immediate.new(-node.operands[0].value)] + node.operands[1..-1],452 annotation)453 else454 newList << node.armV7LowerMalformedImmediatesRecurse(newList)455 end456 when "muli", "mulp"457 if node.operands[0].is_a? Immediate458 tmp = Tmp.new(codeOrigin, :gpr)459 newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp], annotation)460 newList << Instruction.new(node.codeOrigin, "muli", [tmp] + node.operands[1..-1])461 else462 newList << node.armV7LowerMalformedImmediatesRecurse(newList)463 end464 else465 newList << node.armV7LowerMalformedImmediatesRecurse(newList)466 end467 else468 newList << node469 end470 }471 newList472 end473 474 #475 # Lowering of misplaced addresses. For example:476 #477 # addi foo, [bar]478 #479 # will become:480 #481 # loadi [bar], tmp482 # addi foo, tmp483 # storei tmp, [bar]484 #485 # Another example:486 #487 # addi [foo], bar488 #489 # will become:490 #491 # loadi [foo], tmp492 # addi tmp, bar493 #494 495 def armV7AsRegister(preList, postList, operand, suffix, needStore)496 return operand unless operand.address?497 498 tmp = Tmp.new(operand.codeOrigin, if suffix == "d" then :fpr else :gpr end)499 preList << Instruction.new(operand.codeOrigin, "load" + suffix, [operand, tmp])500 if needStore501 postList << Instruction.new(operand.codeOrigin, "store" + suffix, [tmp, operand])502 end503 tmp504 end505 506 def armV7AsRegisters(preList, postList, operands, suffix)507 newOperands = []508 operands.each_with_index {509 | operand, index |510 newOperands << armV7AsRegister(preList, postList, operand, suffix, index == operands.size - 1)511 }512 newOperands513 end514 515 def armV7LowerMisplacedAddresses(list)516 newList = []517 list.each {518 | node |519 if node.is_a? Instruction520 postInstructions = []521 annotation = node.annotation522 case node.opcode523 when "addi", "addp", "addis", "andi", "andp", "lshifti", "lshiftp", "muli", "mulp", "negi",524 "negp", "noti", "ori", "oris", "orp", "rshifti", "urshifti", "rshiftp", "urshiftp", "subi",525 "subp", "subis", "xori", "xorp", /^bi/, /^bp/, /^bti/, /^btp/, /^ci/, /^cp/, /^ti/526 newList << Instruction.new(node.codeOrigin,527 node.opcode,528 armV7AsRegisters(newList, postInstructions, node.operands, "i"),529 annotation)530 when "bbeq", "bbneq", "bba", "bbaeq", "bbb", "bbbeq", "btbz", "btbnz", "tbz", "tbnz",531 "cbeq", "cbneq", "cba", "cbaeq", "cbb", "cbbeq"532 newList << Instruction.new(node.codeOrigin,533 node.opcode,534 armV7AsRegisters(newList, postInstructions, node.operands, "b"),535 annotation)536 when "bbgt", "bbgteq", "bblt", "bblteq", "btbs", "tbs", "cbgt", "cbgteq", "cblt", "cblteq"537 newList << Instruction.new(node.codeOrigin,538 node.opcode,539 armV7AsRegisters(newList, postInstructions, node.operands, "bs"),540 annotation)541 when "addd", "divd", "subd", "muld", "sqrtd", /^bd/542 newList << Instruction.new(node.codeOrigin,543 node.opcode,544 armV7AsRegisters(newList, postInstructions, node.operands, "d"),545 annotation)546 when "jmp", "call"547 newList << Instruction.new(node.codeOrigin,548 node.opcode,549 [armV7AsRegister(newList, postInstructions, node.operands[0], "p", false)],550 annotation)551 else552 newList << node553 end554 newList += postInstructions555 else556 newList << node557 end558 }559 newList560 end561 562 #563 # Lowering of register reuse in compare instructions. For example:564 #565 # cieq t0, t1, t0566 #567 # will become:568 #569 # mov tmp, t0570 # cieq tmp, t1, t0571 #572 573 def armV7LowerRegisterReuse(list)574 newList = []575 list.each {576 | node |577 if node.is_a? Instruction578 annotation = node.annotation579 case node.opcode580 when "cieq", "cineq", "cia", "ciaeq", "cib", "cibeq", "cigt", "cigteq", "cilt", "cilteq",581 "cpeq", "cpneq", "cpa", "cpaeq", "cpb", "cpbeq", "cpgt", "cpgteq", "cplt", "cplteq",582 "tis", "tiz", "tinz", "tbs", "tbz", "tbnz", "tps", "tpz", "tpnz", "cbeq", "cbneq",583 "cba", "cbaeq", "cbb", "cbbeq", "cbgt", "cbgteq", "cblt", "cblteq"584 if node.operands.size == 2585 if node.operands[0] == node.operands[1]586 tmp = Tmp.new(node.codeOrigin, :gpr)587 newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp], annotation)588 newList << Instruction.new(node.codeOrigin, node.opcode, [tmp, node.operands[1]])589 else590 newList << node591 end592 else593 raise "Wrong number of arguments at #{node.codeOriginString}" unless node.operands.size == 3594 if node.operands[0] == node.operands[2]595 tmp = Tmp.new(node.codeOrigin, :gpr)596 newList << Instruction.new(node.codeOrigin, "move", [node.operands[0], tmp], annotation)597 newList << Instruction.new(node.codeOrigin, node.opcode, [tmp, node.operands[1], node.operands[2]])598 elsif node.operands[1] == node.operands[2]599 tmp = Tmp.new(node.codeOrigin, :gpr)600 newList << Instruction.new(node.codeOrigin, "move", [node.operands[1], tmp], annotation)601 newList << Instruction.new(node.codeOrigin, node.opcode, [node.operands[0], tmp, node.operands[2]])602 else603 newList << node604 end605 end606 else607 newList << node608 end609 else610 newList << node611 end612 }613 newList614 end615 616 #617 137 # Lea support. 618 138 # … … 643 163 class Sequence 644 164 def getModifiedListARMv7 645 myList = @list 646 647 # Verify that we will only see instructions and labels. 648 myList.each { 649 | node | 650 unless node.is_a? Instruction or 651 node.is_a? Label or 652 node.is_a? LocalLabel or 653 node.is_a? Skip 654 raise "Unexpected #{node.inspect} at #{node.codeOrigin}" 165 result = @list 166 result = riscLowerSimpleBranchOps(result) 167 result = riscLowerHardBranchOps(result) 168 result = riscLowerShiftOps(result) 169 result = riscLowerMalformedAddresses(result) { 170 | node, address | 171 if address.is_a? BaseIndex 172 address.offset.value == 0 173 elsif address.is_a? Address 174 (-0xff..0xfff).include? address.offset.value 175 else 176 false 655 177 end 656 178 } 657 658 myList = armV7LowerBranchOps(myList) 659 myList = armV7LowerShiftOps(myList) 660 myList = armV7LowerMalformedAddresses(myList) 661 myList = armV7LowerMalformedAddressesDouble(myList) 662 myList = armV7LowerMisplacedImmediates(myList) 663 myList = armV7LowerMalformedImmediates(myList) 664 myList = armV7LowerMisplacedAddresses(myList) 665 myList = armV7LowerRegisterReuse(myList) 666 myList = assignRegistersToTemporaries(myList, :gpr, ARMv7_EXTRA_GPRS) 667 myList = assignRegistersToTemporaries(myList, :fpr, ARMv7_EXTRA_FPRS) 668 669 return myList 179 result = riscLowerMalformedAddressesDouble(result) 180 result = riscLowerMisplacedImmediates(result) 181 result = riscLowerMalformedImmediates(result, 0..0xff) 182 result = riscLowerMisplacedAddresses(result) 183 result = riscLowerRegisterReuse(result) 184 result = assignRegistersToTemporaries(result, :gpr, ARMv7_EXTRA_GPRS) 185 result = assignRegistersToTemporaries(result, :fpr, ARMv7_EXTRA_FPRS) 186 return result 670 187 end 671 188 end … … 748 265 749 266 case opcode 750 when "addi", "addp", "addis" 751 if opcode == "addis" 267 when "addi", "addp", "addis", "addps" 268 if opcode == "addis" or opcode == "addps" 752 269 suffix = "s" 753 270 else … … 838 355 $asm.puts "vmrs apsr_nzcv, fpscr" 839 356 isUnordered = LocalLabel.unique("bdneq") 840 $asm.puts "bvs #{L abelReference.new(codeOrigin, isUnordered).asmLabel}"357 $asm.puts "bvs #{LocalLabelReference.new(codeOrigin, isUnordered).asmLabel}" 841 358 $asm.puts "bne #{operands[2].asmLabel}" 842 359 isUnordered.lower("ARMv7")
Note: See TracChangeset
for help on using the changeset viewer.