Changeset 239940 in webkit for trunk/Source/JavaScriptCore/offlineasm/cloop.rb
- Timestamp:
- Jan 14, 2019, 1:34:47 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/offlineasm/cloop.rb
r238543 r239940 34 34 def cloopMapType(type) 35 35 case type 36 when :int; ".i "37 when :uint; ".u "38 when :int32; ".i32 "39 when :uint32; ".u32 "40 when :int64; ".i64 "41 when :uint64; ".u64 "42 when :int8; ".i8 "43 when :uint8; ".u8 "44 when :int8Ptr; ".i8p "45 when :voidPtr; ".vp "46 when :nativeFunc; ".nativeFunc "47 when :double; ".d "48 when : castToDouble; ".castToDouble"49 when : castToInt64; ".castToInt64"50 when :opcode; ".opcode "36 when :int; ".i()" 37 when :uint; ".u()" 38 when :int32; ".i32()" 39 when :uint32; ".u32()" 40 when :int64; ".i64()" 41 when :uint64; ".u64()" 42 when :int8; ".i8()" 43 when :uint8; ".u8()" 44 when :int8Ptr; ".i8p()" 45 when :voidPtr; ".vp()" 46 when :nativeFunc; ".nativeFunc()" 47 when :double; ".d()" 48 when :bitsAsDouble; ".bitsAsDouble()" 49 when :bitsAsInt64; ".bitsAsInt64()" 50 when :opcode; ".opcode()" 51 51 else; 52 52 raise "Unsupported type" … … 56 56 57 57 class SpecialRegister < NoChildren 58 def clLValue(type=:int) 59 clDump 60 end 58 61 def clDump 59 62 @name … … 101 104 end 102 105 end 106 def clLValue(type=:int) 107 clDump 108 end 103 109 def clValue(type=:int) 104 110 clDump + cloopMapType(type) … … 125 131 end 126 132 end 133 def clLValue(type=:int) 134 clDump 135 end 127 136 def clValue(type=:int) 128 137 clDump + cloopMapType(type) … … 133 142 def clDump 134 143 "#{value}" 144 end 145 def clLValue(type=:int) 146 raise "Immediate cannot be used as an LValue" 135 147 end 136 148 def clValue(type=:int) … … 165 177 def clDump 166 178 "[#{base.clDump}, #{offset.value}]" 179 end 180 def clLValue(type=:int) 181 clValue(type) 167 182 end 168 183 def clValue(type=:int) … … 236 251 "[#{base.clDump}, #{offset.clDump}, #{index.clDump} << #{scaleShift}]" 237 252 end 253 def clLValue(type=:int) 254 clValue(type) 255 end 238 256 def clValue(type=:int) 239 257 case type … … 300 318 "#{codeOriginString}" 301 319 end 320 def clLValue(type=:int) 321 clValue(type) 322 end 302 323 def clValue 303 324 clDump … … 310 331 end 311 332 def cloopEmitLea(destination, type) 312 $asm.putc "#{destination.cl Value(:voidPtr)} = CAST<void*>(&#{cLabel});"333 $asm.putc "#{destination.clLValue(:voidPtr)} = CAST<void*>(&#{cLabel});" 313 334 end 314 335 end … … 322 343 def cloopEmitLea(destination, type) 323 344 if destination == base 324 $asm.putc "#{destination.cl Value(:int8Ptr)} += #{offset.clValue(type)};"345 $asm.putc "#{destination.clLValue(:int8Ptr)} += #{offset.clValue(type)};" 325 346 else 326 $asm.putc "#{destination.cl Value(:int8Ptr)} = #{base.clValue(:int8Ptr)} + #{offset.clValue(type)};"347 $asm.putc "#{destination.clLValue(:int8Ptr)} = #{base.clValue(:int8Ptr)} + #{offset.clValue(type)};" 327 348 end 328 349 end … … 332 353 def cloopEmitLea(destination, type) 333 354 raise "Malformed BaseIndex, offset should be zero at #{codeOriginString}" unless offset.value == 0 334 $asm.putc "#{destination.cl Value(:int8Ptr)} = #{base.clValue(:int8Ptr)} + (#{index.clValue} << #{scaleShift});"355 $asm.putc "#{destination.clLValue(:int8Ptr)} = #{base.clValue(:int8Ptr)} + (#{index.clValue} << #{scaleShift});" 335 356 end 336 357 end … … 368 389 type == :int64 || type == :uint64 || type == :double 369 390 if operands.size == 3 370 $asm.putc "#{operands[2].clValue(type)} = #{operands[0].clValue(type)} #{operator} #{operands[1].clValue(type)};" 371 if operands[2].is_a? RegisterID and (type == :int32 or type == :uint32) 372 $asm.putc "#{operands[2].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port. 373 end 391 op1 = operands[0] 392 op2 = operands[1] 393 dst = operands[2] 374 394 else 375 395 raise unless operands.size == 2 376 raise unless not operands[1].is_a? Immediate 377 $asm.putc "#{operands[1].clValue(type)} = #{operands[1].clValue(type)} #{operator} #{operands[0].clValue(type)};" 378 if operands[1].is_a? RegisterID and (type == :int32 or type == :uint32) 379 $asm.putc "#{operands[1].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port. 380 end 381 end 396 op1 = operands[1] 397 op2 = operands[0] 398 dst = operands[1] 399 end 400 raise unless not dst.is_a? Immediate 401 if dst.is_a? RegisterID and (type == :int32 or type == :uint32) 402 truncationHeader = "(uint32_t)(" 403 truncationFooter = ")" 404 else 405 truncationHeader = "" 406 truncationFooter = "" 407 end 408 $asm.putc "#{dst.clLValue(type)} = #{truncationHeader}#{op1.clValue(type)} #{operator} #{op2.clValue(type)}#{truncationFooter};" 382 409 end 383 410 … … 385 412 raise unless type == :int || type == :uint || type == :int32 || type == :uint32 || type == :int64 || type == :uint64 386 413 if operands.size == 3 387 $asm.putc "#{operands[2].clValue(type)} = #{operands[1].clValue(type)} #{operator} (#{operands[0].clValue(:int)} & 0x1f);" 388 if operands[2].is_a? RegisterID and (type == :int32 or type == :uint32) 389 $asm.putc "#{operands[2].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port. 390 end 414 op1 = operands[0] 415 op2 = operands[1] 416 dst = operands[2] 391 417 else 392 raise unless operands.size == 2 393 raise unless not operands[1].is_a? Immediate 394 $asm.putc "#{operands[1].clValue(type)} = #{operands[1].clValue(type)} #{operator} (#{operands[0].clValue(:int)} & 0x1f);" 395 if operands[1].is_a? RegisterID and (type == :int32 or type == :uint32) 396 $asm.putc "#{operands[1].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port. 397 end 398 end 418 op1 = operands[1] 419 op2 = operands[0] 420 dst = operands[1] 421 end 422 if dst.is_a? RegisterID and (type == :int32 or type == :uint32) 423 truncationHeader = "(uint32_t)(" 424 truncationFooter = ")" 425 else 426 truncationHeader = "" 427 truncationFooter = "" 428 end 429 $asm.putc "#{dst.clLValue(type)} = #{truncationHeader}#{operands[1].clValue(type)} #{operator} (#{operands[0].clValue(:int)} & 0x1f)#{truncationFooter};" 399 430 end 400 431 … … 403 434 raise unless operands.size == 1 404 435 raise unless not operands[0].is_a? Immediate 405 $asm.putc "#{operands[0].clValue(type)} = #{operator}#{operands[0].clValue(type)};" 406 if operands[0].is_a? RegisterID and (type == :int32 or type == :uint32) 407 $asm.putc "#{operands[0].clDump}.clearHighWord();" # Just clear it. It does nothing on the 32-bit port. 408 end 436 op = operands[0] 437 dst = operands[0] 438 if dst.is_a? RegisterID and (type == :int32 or type == :uint32) 439 truncationHeader = "(uint32_t)(" 440 truncationFooter = ")" 441 else 442 truncationHeader = "" 443 truncationFooter = "" 444 end 445 $asm.putc "#{dst.clLValue(type)} = #{truncationHeader}#{operator}#{op.clValue(type)}#{truncationFooter};" 409 446 end 410 447 … … 419 456 # The result is a boolean. Hence, it doesn't need to be based on the type 420 457 # of the arguments being compared. 421 $asm.putc "#{operands[2].cl Value} = (#{operands[0].clValue(type)} #{comparator} #{operands[1].clValue(type)});"458 $asm.putc "#{operands[2].clLValue(type)} = (#{operands[0].clValue(type)} #{comparator} #{operands[1].clValue(type)});" 422 459 end 423 460 … … 460 497 # the condition test. 461 498 conditionExpr = cloopGenerateConditionExpression(operands, type, conditionTest) 462 $asm.putc "#{operands[-1].cl Value} = (#{conditionExpr});"499 $asm.putc "#{operands[-1].clLValue} = (#{conditionExpr});" 463 500 end 464 501 … … 472 509 end 473 510 474 op1 = operands[0].clValue(type)475 op2 = operands[1].clValue(type)476 477 511 $asm.putc "{" 478 $asm.putc " #{tempType} temp = #{op 2} #{operator} #{op1};"479 $asm.putc " #{op 2} = temp;"512 $asm.putc " #{tempType} temp = #{operands[1].clValue(type)} #{operator} #{operands[0].clValue(type)};" 513 $asm.putc " #{operands[1].clLValue(type)} = temp;" 480 514 $asm.putc " if (temp #{conditionTest})" 481 515 $asm.putc " goto #{operands[2].cLabel};" … … 487 521 when :int32 488 522 tempType = "int32_t" 523 truncationHeader = "(uint32_t)(" 524 truncationFooter = ")" 489 525 else 490 526 raise "Unimplemented type" … … 502 538 end 503 539 504 $asm.putc " if (!WTF::ArithmeticOperations<#{tempType}, #{tempType}, #{tempType}>::#{operation}(#{operands[1].clValue(type)}, #{operands[0].clValue(type)}, #{operands[1].clValue(type)}))" 540 $asm.putc " #{tempType} result;" 541 $asm.putc " bool success = WTF::ArithmeticOperations<#{tempType}, #{tempType}, #{tempType}>::#{operation}(#{operands[1].clValue(type)}, #{operands[0].clValue(type)}, result);" 542 $asm.putc " #{operands[1].clLValue(type)} = #{truncationHeader}result#{truncationFooter};" 543 $asm.putc " if (!success)" 505 544 $asm.putc " goto #{operands[2].cLabel};" 506 545 $asm.putc "}" … … 510 549 def cloopEmitCallSlowPath(operands) 511 550 $asm.putc "{" 512 $asm.putc " cloopStack.setCurrentStackPointer(sp.vp );"551 $asm.putc " cloopStack.setCurrentStackPointer(sp.vp());" 513 552 $asm.putc " SlowPathReturnType result = #{operands[0].cLabel}(#{operands[1].clDump}, #{operands[2].clDump});" 514 $asm.putc " decodeResult(result, t0 .cvp, t1.cvp);"553 $asm.putc " decodeResult(result, t0, t1);" 515 554 $asm.putc "}" 516 555 end 517 556 518 557 def cloopEmitCallSlowPathVoid(operands) 519 $asm.putc "cloopStack.setCurrentStackPointer(sp.vp );"558 $asm.putc "cloopStack.setCurrentStackPointer(sp.vp());" 520 559 $asm.putc "#{operands[0].cLabel}(#{operands[1].clDump}, #{operands[2].clDump});" 521 560 end … … 598 637 599 638 when "loadi" 600 $asm.putc "#{operands[1].cl Value(:uint)} = #{operands[0].uint32MemRef};"639 $asm.putc "#{operands[1].clLValue(:uint32)} = #{operands[0].uint32MemRef};" 601 640 # There's no need to call clearHighWord() here because the above will 602 641 # automatically take care of 0 extension. 603 642 when "loadis" 604 $asm.putc "#{operands[1].cl Value(:int)} = #{operands[0].int32MemRef};"643 $asm.putc "#{operands[1].clLValue(:int32)} = #{operands[0].int32MemRef};" 605 644 when "loadq" 606 $asm.putc "#{operands[1].cl Value(:int64)} = #{operands[0].int64MemRef};"645 $asm.putc "#{operands[1].clLValue(:int64)} = #{operands[0].int64MemRef};" 607 646 when "loadp" 608 $asm.putc "#{operands[1].cl Value(:int)} = #{operands[0].intMemRef};"647 $asm.putc "#{operands[1].clLValue} = #{operands[0].intMemRef};" 609 648 when "storei" 610 649 $asm.putc "#{operands[1].int32MemRef} = #{operands[0].clValue(:int32)};" … … 614 653 $asm.putc "#{operands[1].intMemRef} = #{operands[0].clValue(:int)};" 615 654 when "loadb" 616 $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].uint8MemRef};" 617 when "loadbs", "loadbsp" 618 $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].int8MemRef};" 655 $asm.putc "#{operands[1].clLValue(:int)} = #{operands[0].uint8MemRef};" 656 when "loadbs" 657 $asm.putc "#{operands[1].clLValue(:int)} = (uint32_t)(#{operands[0].int8MemRef});" 658 when "loadbsp" 659 $asm.putc "#{operands[1].clLValue(:int)} = #{operands[0].int8MemRef};" 619 660 when "storeb" 620 661 $asm.putc "#{operands[1].uint8MemRef} = #{operands[0].clValue(:int8)};" 621 662 when "loadh" 622 $asm.putc "#{operands[1].cl Value(:int)} = #{operands[0].uint16MemRef};"663 $asm.putc "#{operands[1].clLValue(:int)} = #{operands[0].uint16MemRef};" 623 664 when "loadhs" 624 $asm.putc "#{operands[1].cl Value(:int)} = #{operands[0].int16MemRef};"665 $asm.putc "#{operands[1].clLValue(:int)} = (uint32_t)(#{operands[0].int16MemRef});" 625 666 when "storeh" 626 667 $asm.putc "*#{operands[1].uint16MemRef} = #{operands[0].clValue(:int16)};" 627 668 when "loadd" 628 $asm.putc "#{operands[1].cl Value(:double)} = #{operands[0].dblMemRef};"669 $asm.putc "#{operands[1].clLValue(:double)} = #{operands[0].dblMemRef};" 629 670 when "stored" 630 671 $asm.putc "#{operands[1].dblMemRef} = #{operands[0].clValue(:double)};" … … 641 682 # Convert an int value to its double equivalent, and store it in a double register. 642 683 when "ci2d" 643 $asm.putc "#{operands[1].cl Value(:double)} = #{operands[0].clValue(:int32)};"644 684 $asm.putc "#{operands[1].clLValue(:double)} = (double)#{operands[0].clValue(:int32)}; // ci2d" 685 645 686 when "bdeq" 646 687 cloopEmitCompareAndBranch(operands, :double, "==") … … 670 711 671 712 when "td2i" 672 $asm.putc "#{operands[1].clValue(:int)} = #{operands[0].clValue(:double)};" 673 $asm.putc "#{operands[1].clDump}.clearHighWord();" 713 $asm.putc "#{operands[1].clLValue(:int)} = (uint32_t)(intptr_t)#{operands[0].clValue(:double)}; // td2i" 674 714 675 715 when "bcd2i" # operands: srcDbl dstInt slowPath 676 $asm.putc "{ "716 $asm.putc "{ // bcd2i" 677 717 $asm.putc " double d = #{operands[0].clValue(:double)};" 678 718 $asm.putc " const int32_t asInt32 = int32_t(d);" 679 719 $asm.putc " if (asInt32 != d || (!asInt32 && std::signbit(d))) // true for -0.0" 680 720 $asm.putc " goto #{operands[2].cLabel};" 681 $asm.putc " #{operands[1].clValue} = asInt32;" 682 $asm.putc " #{operands[1].clDump}.clearHighWord();" 721 $asm.putc " #{operands[1].clLValue} = (uint32_t)asInt32;" 683 722 $asm.putc "}" 684 723 685 724 when "move" 686 $asm.putc "#{operands[1].cl Value(:int)} = #{operands[0].clValue(:int)};"725 $asm.putc "#{operands[1].clLValue(:int)} = #{operands[0].clValue(:int)};" 687 726 when "sxi2q" 688 $asm.putc "#{operands[1].cl Value(:int64)} = #{operands[0].clValue(:int32)};"727 $asm.putc "#{operands[1].clLValue(:int64)} = #{operands[0].clValue(:int32)};" 689 728 when "zxi2q" 690 $asm.putc "#{operands[1].cl Value(:uint64)} = #{operands[0].clValue(:uint32)};"729 $asm.putc "#{operands[1].clLValue(:uint64)} = #{operands[0].clValue(:uint32)};" 691 730 when "nop" 692 731 $asm.putc "// nop" … … 832 871 $asm.putc "CRASH(); // break instruction not implemented." 833 872 when "ret" 834 $asm.putc "opcode = lr.opcode ;"873 $asm.putc "opcode = lr.opcode();" 835 874 $asm.putc "DISPATCH_OPCODE();" 836 875 … … 956 995 # the lower 32 bits of t1. Leave the upper 32 bits of t0 and t1 unchanged. 957 996 when "cdqi" 958 $asm.putc "{" 959 $asm.putc " int64_t temp = t0.i32; // sign extend the low 32bit" 960 $asm.putc " t0.i32 = temp; // low word" 961 $asm.putc " t0.clearHighWord();" 962 $asm.putc " t1.i32 = uint64_t(temp) >> 32; // high word" 963 $asm.putc " t1.clearHighWord();" 997 $asm.putc "{ // cdqi" 998 $asm.putc " int64_t temp = t0.i32(); // sign extend the low 32bit" 999 $asm.putc " t0 = (uint32_t)temp; // low word" 1000 $asm.putc " t1 = (uint32_t)(temp >> 32); // high word" 964 1001 $asm.putc "}" 965 1002 … … 977 1014 # Divide t1,t0 (EDX,EAX) by the specified arg, and store the remainder in t1, 978 1015 # and quotient in t0: 979 $asm.putc "{ "980 $asm.putc " int64_t dividend = (int64_t(t1.u32 ) << 32) | t0.u32;"1016 $asm.putc "{ // idivi" 1017 $asm.putc " int64_t dividend = (int64_t(t1.u32()) << 32) | t0.u32();" 981 1018 $asm.putc " int64_t divisor = #{operands[0].clValue(:int)};" 982 $asm.putc " t1.i32 = dividend % divisor; // remainder" 983 $asm.putc " t1.clearHighWord();" 984 $asm.putc " t0.i32 = dividend / divisor; // quotient" 985 $asm.putc " t0.clearHighWord();" 1019 $asm.putc " t1 = (uint32_t)(dividend % divisor); // remainder" 1020 $asm.putc " t0 = (uint32_t)(dividend / divisor); // quotient" 986 1021 $asm.putc "}" 987 1022 … … 989 1024 # Decode 2 32-bit ints (low and high) into a 64-bit double. 990 1025 when "fii2d" 991 $asm.putc "#{operands[2].cl Value(:double)} = Ints2Double(#{operands[0].clValue(:uint32)}, #{operands[1].clValue(:uint32)});"1026 $asm.putc "#{operands[2].clLValue(:double)} = ints2Double(#{operands[0].clValue(:uint32)}, #{operands[1].clValue(:uint32)}); // fii2d" 992 1027 993 1028 # 32-bit instruction: f2dii dblOp int32LoOp int32HiOp (based on ARMv7) 994 1029 # Encode a 64-bit double into 2 32-bit ints (low and high). 995 1030 when "fd2ii" 996 $asm.putc " Double2Ints(#{operands[0].clValue(:double)}, #{operands[1].clValue(:uint32)}, #{operands[2].clValue(:uint32)});"1031 $asm.putc "double2Ints(#{operands[0].clValue(:double)}, #{operands[1].clDump}, #{operands[2].clDump}); // fd2ii" 997 1032 998 1033 # 64-bit instruction: fq2d int64Op dblOp (based on X64) 999 1034 # Copy a bit-encoded double in a 64-bit int register to a double register. 1000 1035 when "fq2d" 1001 $asm.putc "#{operands[1].cl Value(:double)} = #{operands[0].clValue(:castToDouble)};"1036 $asm.putc "#{operands[1].clLValue(:double)} = #{operands[0].clValue(:bitsAsDouble)}; // fq2d" 1002 1037 1003 1038 # 64-bit instruction: fd2q dblOp int64Op (based on X64 instruction set) 1004 1039 # Copy a double as a bit-encoded double into a 64-bit int register. 1005 1040 when "fd2q" 1006 $asm.putc "#{operands[1].cl Value(:int64)} = #{operands[0].clValue(:castToInt64)};"1041 $asm.putc "#{operands[1].clLValue(:int64)} = #{operands[0].clValue(:bitsAsInt64)}; // fd2q" 1007 1042 1008 1043 when "leai" … … 1080 1115 when "cloopCallJSFunction" 1081 1116 uid = $asm.newUID 1082 $asm.putc "lr .opcode= getOpcode(llint_cloop_did_return_from_js_#{uid});"1117 $asm.putc "lr = getOpcode(llint_cloop_did_return_from_js_#{uid});" 1083 1118 $asm.putc "opcode = #{operands[0].clValue(:opcode)};" 1084 1119 $asm.putc "DISPATCH_OPCODE();" … … 1089 1124 # have a fixed prototype of 1 args: the passed ExecState. 1090 1125 when "cloopCallNative" 1091 $asm.putc "cloopStack.setCurrentStackPointer(sp.vp );"1126 $asm.putc "cloopStack.setCurrentStackPointer(sp.vp());" 1092 1127 $asm.putc "nativeFunc = #{operands[0].clValue(:nativeFunc)};" 1093 $asm.putc "functionReturnValue = JSValue::decode(nativeFunc(t0.execState ));"1128 $asm.putc "functionReturnValue = JSValue::decode(nativeFunc(t0.execState()));" 1094 1129 $asm.putc "#if USE(JSVALUE32_64)" 1095 $asm.putc " t1 .i= functionReturnValue.tag();"1096 $asm.putc " t0 .i= functionReturnValue.payload();"1130 $asm.putc " t1 = functionReturnValue.tag();" 1131 $asm.putc " t0 = functionReturnValue.payload();" 1097 1132 $asm.putc "#else // USE_JSVALUE64)" 1098 $asm.putc " t0 .encodedJSValue= JSValue::encode(functionReturnValue);"1099 $asm.putc "#endif // USE_JSVALUE64)" 1133 $asm.putc " t0 = JSValue::encode(functionReturnValue);" 1134 $asm.putc "#endif // USE_JSVALUE64)" 1100 1135 1101 1136 # We can't do generic function calls with an arbitrary set of args, but
Note:
See TracChangeset
for help on using the changeset viewer.