Changeset 90352 in webkit
- Timestamp:
- Jul 3, 2011 10:59:03 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r90349 r90352 1 2011-07-03 Gavin Barraclough <barraclough@apple.com> 2 3 https://bugs.webkit.org/show_bug.cgi?id=63879 4 Reduce code duplication for op_jless, op_jlesseq, op_jnless, op_jnlesseq. 5 6 Reviewed by Sam Weinig. 7 8 There is a lot of copy & paste code here; we can reduce duplication by making 9 a shared implementation. 10 11 * assembler/MacroAssembler.h: 12 (JSC::MacroAssembler::branch32): 13 (JSC::MacroAssembler::commute): 14 - Make these function platform agnostic. 15 * assembler/MacroAssemblerX86Common.h: 16 - Moved branch32/commute up to MacroAssembler. 17 * jit/JIT.h: 18 (JSC::JIT::emit_op_loop_if_lesseq): 19 (JSC::JIT::emitSlow_op_loop_if_lesseq): 20 - Add an implementation matching that for op_loop_if_less, which just calls op_jless. 21 * jit/JITArithmetic.cpp: 22 (JSC::JIT::emit_op_jless): 23 (JSC::JIT::emit_op_jlesseq): 24 (JSC::JIT::emit_op_jnless): 25 (JSC::JIT::emit_op_jnlesseq): 26 (JSC::JIT::emitSlow_op_jless): 27 (JSC::JIT::emitSlow_op_jlesseq): 28 (JSC::JIT::emitSlow_op_jnless): 29 (JSC::JIT::emitSlow_op_jnlesseq): 30 - Common implmentations of these methods for JSVALUE64 & JSVALUE32_64. 31 (JSC::JIT::emit_compareAndJump): 32 (JSC::JIT::emit_compareAndJumpSlow): 33 - Internal implmementation of jless etc for JSVALUE64. 34 * jit/JITArithmetic32_64.cpp: 35 (JSC::JIT::emit_compareAndJump): 36 (JSC::JIT::emit_compareAndJumpSlow): 37 - Internal implmementation of jless etc for JSVALUE32_64. 38 * jit/JITOpcodes.cpp: 39 * jit/JITOpcodes32_64.cpp: 40 * jit/JITStubs.cpp: 41 * jit/JITStubs.h: 42 - Remove old implementation of emit_op_loop_if_lesseq. 43 1 44 2011-07-03 Sheriff Bot <webkit.review.bot@gmail.com> 2 45 -
trunk/Source/JavaScriptCore/assembler/MacroAssembler.h
r86699 r90352 126 126 } 127 127 128 Jump branch32(RelationalCondition cond, TrustedImm32 left, RegisterID right) 129 { 130 return branch32(commute(cond), right, left); 131 } 132 128 133 void branch16(RelationalCondition cond, BaseIndex left, RegisterID right, Label target) 129 134 { … … 141 146 } 142 147 148 // Commute a relational condition, returns a new condition that will produce 149 // the same results given the same inputs but with their positions exchanged. 150 static RelationalCondition commute(RelationalCondition condition) 151 { 152 switch (condition) { 153 case Above: 154 return Below; 155 case AboveOrEqual: 156 return BelowOrEqual; 157 case Below: 158 return Above; 159 case BelowOrEqual: 160 return AboveOrEqual; 161 case GreaterThan: 162 return LessThan; 163 case GreaterThanOrEqual: 164 return LessThanOrEqual; 165 case LessThan: 166 return GreaterThan; 167 case LessThanOrEqual: 168 return GreaterThanOrEqual; 169 default: 170 break; 171 } 172 173 ASSERT(condition == Equal || condition == NotEqual); 174 return condition; 175 } 176 143 177 144 178 // Ptr methods -
trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
r90237 r90352 845 845 } 846 846 847 Jump branch32(RelationalCondition cond, TrustedImm32 left, RegisterID right)848 {849 if (((cond == Equal) || (cond == NotEqual)) && !left.m_value)850 m_assembler.testl_rr(right, right);851 else852 m_assembler.cmpl_ir(left.m_value, right);853 return Jump(m_assembler.jCC(x86Condition(commute(cond))));854 }855 856 847 Jump branch32(RelationalCondition cond, RegisterID left, Address right) 857 848 { … … 1202 1193 } 1203 1194 1204 // Commute a relational condition, returns a new condition that will produce1205 // the same results given the same inputs but with their positions exchanged.1206 static RelationalCondition commute(RelationalCondition cond)1207 {1208 // Equality is commutative!1209 if (cond == Equal || cond == NotEqual)1210 return cond;1211 1212 // Based on the values of x86 condition codes, remap > with < and >= with <=1213 if (cond >= LessThan) {1214 ASSERT(cond == LessThan || cond == LessThanOrEqual || cond == GreaterThan || cond == GreaterThanOrEqual);1215 return static_cast<RelationalCondition>(X86Assembler::ConditionL + X86Assembler::ConditionG - cond);1216 }1217 1218 // As above, for unsigned conditions.1219 ASSERT(cond == Below || cond == BelowOrEqual || cond == Above || cond == AboveOrEqual);1220 return static_cast<RelationalCondition>(X86Assembler::ConditionB + X86Assembler::ConditionA - cond);1221 }1222 1223 1195 void nop() 1224 1196 { -
trunk/Source/JavaScriptCore/jit/JIT.h
r90060 r90352 720 720 #define END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, dst) do { endUninterruptedSequence(); } while (false) 721 721 #endif 722 723 void emit_compareAndJump(OpcodeID, unsigned op1, unsigned op2, unsigned target, RelationalCondition); 724 void emit_compareAndJumpSlow(unsigned op1, unsigned op2, unsigned target, DoubleCondition, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION), bool invert, Vector<SlowCaseEntry>::iterator&); 722 725 723 726 void emit_op_add(Instruction*); … … 763 766 void emit_op_jnless(Instruction*); 764 767 void emit_op_jless(Instruction*); 765 void emit_op_jlesseq(Instruction* , bool invert = false);768 void emit_op_jlesseq(Instruction*); 766 769 void emit_op_jnlesseq(Instruction*); 767 770 void emit_op_jsr(Instruction*); … … 859 862 void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&); 860 863 void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&); 861 void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator& , bool invert = false);864 void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); 862 865 void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&); 863 866 void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&); … … 1041 1044 } 1042 1045 1046 inline void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction) 1047 { 1048 emitTimeoutCheck(); 1049 emit_op_jlesseq(currentInstruction); 1050 } 1051 1052 inline void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1053 { 1054 emitSlow_op_jlesseq(currentInstruction, iter); 1055 } 1056 1043 1057 } // namespace JSC 1044 1058 -
trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp
r85729 r90352 27 27 28 28 #if ENABLE(JIT) 29 #if USE(JSVALUE64)30 29 #include "JIT.h" 31 30 … … 47 46 48 47 namespace JSC { 48 49 void JIT::emit_op_jless(Instruction* currentInstruction) 50 { 51 unsigned op1 = currentInstruction[1].u.operand; 52 unsigned op2 = currentInstruction[2].u.operand; 53 unsigned target = currentInstruction[3].u.operand; 54 55 emit_compareAndJump(op_jless, op1, op2, target, LessThan); 56 } 57 58 void JIT::emit_op_jlesseq(Instruction* currentInstruction) 59 { 60 unsigned op1 = currentInstruction[1].u.operand; 61 unsigned op2 = currentInstruction[2].u.operand; 62 unsigned target = currentInstruction[3].u.operand; 63 64 emit_compareAndJump(op_jlesseq, op1, op2, target, LessThanOrEqual); 65 } 66 67 void JIT::emit_op_jnless(Instruction* currentInstruction) 68 { 69 unsigned op1 = currentInstruction[1].u.operand; 70 unsigned op2 = currentInstruction[2].u.operand; 71 unsigned target = currentInstruction[3].u.operand; 72 73 emit_compareAndJump(op_jnless, op1, op2, target, GreaterThanOrEqual); 74 } 75 76 void JIT::emit_op_jnlesseq(Instruction* currentInstruction) 77 { 78 unsigned op1 = currentInstruction[1].u.operand; 79 unsigned op2 = currentInstruction[2].u.operand; 80 unsigned target = currentInstruction[3].u.operand; 81 82 emit_compareAndJump(op_jnlesseq, op1, op2, target, GreaterThan); 83 } 84 85 void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 86 { 87 unsigned op1 = currentInstruction[1].u.operand; 88 unsigned op2 = currentInstruction[2].u.operand; 89 unsigned target = currentInstruction[3].u.operand; 90 91 emit_compareAndJumpSlow(op1, op2, target, DoubleLessThan, cti_op_jless, false, iter); 92 } 93 94 void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 95 { 96 unsigned op1 = currentInstruction[1].u.operand; 97 unsigned op2 = currentInstruction[2].u.operand; 98 unsigned target = currentInstruction[3].u.operand; 99 100 emit_compareAndJumpSlow(op1, op2, target, DoubleLessThanOrEqual, cti_op_jlesseq, false, iter); 101 } 102 103 void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 104 { 105 unsigned op1 = currentInstruction[1].u.operand; 106 unsigned op2 = currentInstruction[2].u.operand; 107 unsigned target = currentInstruction[3].u.operand; 108 109 emit_compareAndJumpSlow(op1, op2, target, DoubleGreaterThanOrEqualOrUnordered, cti_op_jless, true, iter); 110 } 111 112 void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 113 { 114 unsigned op1 = currentInstruction[1].u.operand; 115 unsigned op2 = currentInstruction[2].u.operand; 116 unsigned target = currentInstruction[3].u.operand; 117 118 emit_compareAndJumpSlow(op1, op2, target, DoubleGreaterThanOrUnordered, cti_op_jlesseq, true, iter); 119 } 120 121 #if USE(JSVALUE64) 49 122 50 123 void JIT::emit_op_lshift(Instruction* currentInstruction) … … 243 316 } 244 317 245 void JIT::emit_op_jnless(Instruction* currentInstruction) 246 { 247 unsigned op1 = currentInstruction[1].u.operand; 248 unsigned op2 = currentInstruction[2].u.operand; 249 unsigned target = currentInstruction[3].u.operand; 250 318 void JIT::emit_compareAndJump(OpcodeID, unsigned op1, unsigned op2, unsigned target, RelationalCondition condition) 319 { 251 320 // We generate inline code for the following cases in the fast path: 252 321 // - int immediate to constant int immediate … … 260 329 emitLoadCharacterString(regT0, regT0, failures); 261 330 addSlowCase(failures); 262 addJump(branch32( LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);331 addJump(branch32(commute(condition), regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target); 263 332 return; 264 333 } … … 269 338 emitLoadCharacterString(regT0, regT0, failures); 270 339 addSlowCase(failures); 271 addJump(branch32( GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);340 addJump(branch32(condition, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target); 272 341 return; 273 342 } … … 276 345 emitJumpSlowCaseIfNotImmediateInteger(regT0); 277 346 int32_t op2imm = getConstantOperandImmediateInt(op2); 278 addJump(branch32( GreaterThanOrEqual, regT0, Imm32(op2imm)), target);347 addJump(branch32(condition, regT0, Imm32(op2imm)), target); 279 348 } else if (isOperandConstantImmediateInt(op1)) { 280 349 emitGetVirtualRegister(op2, regT1); 281 350 emitJumpSlowCaseIfNotImmediateInteger(regT1); 282 351 int32_t op1imm = getConstantOperandImmediateInt(op1); 283 addJump(branch32( LessThanOrEqual, regT1, Imm32(op1imm)), target);352 addJump(branch32(commute(condition), regT1, Imm32(op1imm)), target); 284 353 } else { 285 354 emitGetVirtualRegisters(op1, regT0, op2, regT1); … … 287 356 emitJumpSlowCaseIfNotImmediateInteger(regT1); 288 357 289 addJump(branch32(GreaterThanOrEqual, regT0, regT1), target); 290 } 291 } 292 293 void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 294 { 295 unsigned op1 = currentInstruction[1].u.operand; 296 unsigned op2 = currentInstruction[2].u.operand; 297 unsigned target = currentInstruction[3].u.operand; 298 358 addJump(branch32(condition, regT0, regT1), target); 359 } 360 } 361 362 void JIT::emit_compareAndJumpSlow(unsigned op1, unsigned op2, unsigned target, DoubleCondition condition, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION), bool invert, Vector<SlowCaseEntry>::iterator& iter) 363 { 299 364 // We generate inline code for the following cases in the slow path: 300 365 // - floating-point number to constant int immediate … … 306 371 linkSlowCase(iter); 307 372 linkSlowCase(iter); 308 JITStubCall stubCall(this, cti_op_jless);373 JITStubCall stubCall(this, stub); 309 374 stubCall.addArgument(op1, regT0); 310 375 stubCall.addArgument(op2, regT1); 311 376 stubCall.call(); 312 emitJumpSlowToHot(branchTest32( Zero, regT0), target);377 emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target); 313 378 return; 314 379 } … … 322 387 movePtrToDouble(regT0, fpRegT0); 323 388 324 int32_t op2imm = getConstantOperand(op2).asInt32(); ;389 int32_t op2imm = getConstantOperand(op2).asInt32(); 325 390 326 391 move(Imm32(op2imm), regT1); 327 392 convertInt32ToDouble(regT1, fpRegT1); 328 393 329 emitJumpSlowToHot(branchDouble( DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);394 emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target); 330 395 331 396 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); … … 334 399 } 335 400 336 JITStubCall stubCall(this, cti_op_jless);401 JITStubCall stubCall(this, stub); 337 402 stubCall.addArgument(regT0); 338 403 stubCall.addArgument(op2, regT2); 339 404 stubCall.call(); 340 emitJumpSlowToHot(branchTest32( Zero, regT0), target);405 emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target); 341 406 342 407 } else if (isOperandConstantImmediateInt(op1)) { … … 348 413 movePtrToDouble(regT1, fpRegT1); 349 414 350 int32_t op1imm = getConstantOperand(op1).asInt32(); ;415 int32_t op1imm = getConstantOperand(op1).asInt32(); 351 416 352 417 move(Imm32(op1imm), regT0); 353 418 convertInt32ToDouble(regT0, fpRegT0); 354 419 355 emitJumpSlowToHot(branchDouble( DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);420 emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target); 356 421 357 422 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); … … 360 425 } 361 426 362 JITStubCall stubCall(this, cti_op_jless);427 JITStubCall stubCall(this, stub); 363 428 stubCall.addArgument(op1, regT2); 364 429 stubCall.addArgument(regT1); 365 430 stubCall.call(); 366 emitJumpSlowToHot(branchTest32( Zero, regT0), target);431 emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target); 367 432 368 433 } else { … … 378 443 movePtrToDouble(regT1, fpRegT1); 379 444 380 emitJumpSlowToHot(branchDouble( DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);445 emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target); 381 446 382 447 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); … … 388 453 389 454 linkSlowCase(iter); 390 JITStubCall stubCall(this, cti_op_jless); 391 stubCall.addArgument(regT0); 392 stubCall.addArgument(regT1); 393 stubCall.call(); 394 emitJumpSlowToHot(branchTest32(Zero, regT0), target); 395 } 396 } 397 398 void JIT::emit_op_jless(Instruction* currentInstruction) 399 { 400 unsigned op1 = currentInstruction[1].u.operand; 401 unsigned op2 = currentInstruction[2].u.operand; 402 unsigned target = currentInstruction[3].u.operand; 403 404 // We generate inline code for the following cases in the fast path: 405 // - int immediate to constant int immediate 406 // - constant int immediate to int immediate 407 // - int immediate to int immediate 408 409 if (isOperandConstantImmediateChar(op1)) { 410 emitGetVirtualRegister(op2, regT0); 411 addSlowCase(emitJumpIfNotJSCell(regT0)); 412 JumpList failures; 413 emitLoadCharacterString(regT0, regT0, failures); 414 addSlowCase(failures); 415 addJump(branch32(GreaterThan, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target); 416 return; 417 } 418 if (isOperandConstantImmediateChar(op2)) { 419 emitGetVirtualRegister(op1, regT0); 420 addSlowCase(emitJumpIfNotJSCell(regT0)); 421 JumpList failures; 422 emitLoadCharacterString(regT0, regT0, failures); 423 addSlowCase(failures); 424 addJump(branch32(LessThan, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target); 425 return; 426 } 427 if (isOperandConstantImmediateInt(op2)) { 428 emitGetVirtualRegister(op1, regT0); 429 emitJumpSlowCaseIfNotImmediateInteger(regT0); 430 int32_t op2imm = getConstantOperandImmediateInt(op2); 431 addJump(branch32(LessThan, regT0, Imm32(op2imm)), target); 432 } else if (isOperandConstantImmediateInt(op1)) { 433 emitGetVirtualRegister(op2, regT1); 434 emitJumpSlowCaseIfNotImmediateInteger(regT1); 435 int32_t op1imm = getConstantOperandImmediateInt(op1); 436 addJump(branch32(GreaterThan, regT1, Imm32(op1imm)), target); 437 } else { 438 emitGetVirtualRegisters(op1, regT0, op2, regT1); 439 emitJumpSlowCaseIfNotImmediateInteger(regT0); 440 emitJumpSlowCaseIfNotImmediateInteger(regT1); 441 442 addJump(branch32(LessThan, regT0, regT1), target); 443 } 444 } 445 446 void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 447 { 448 unsigned op1 = currentInstruction[1].u.operand; 449 unsigned op2 = currentInstruction[2].u.operand; 450 unsigned target = currentInstruction[3].u.operand; 451 452 // We generate inline code for the following cases in the slow path: 453 // - floating-point number to constant int immediate 454 // - constant int immediate to floating-point number 455 // - floating-point number to floating-point number. 456 if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) { 457 linkSlowCase(iter); 458 linkSlowCase(iter); 459 linkSlowCase(iter); 460 linkSlowCase(iter); 461 JITStubCall stubCall(this, cti_op_jless); 462 stubCall.addArgument(op1, regT0); 463 stubCall.addArgument(op2, regT1); 464 stubCall.call(); 465 emitJumpSlowToHot(branchTest32(NonZero, regT0), target); 466 return; 467 } 468 469 if (isOperandConstantImmediateInt(op2)) { 470 linkSlowCase(iter); 471 472 if (supportsFloatingPoint()) { 473 Jump fail1 = emitJumpIfNotImmediateNumber(regT0); 474 addPtr(tagTypeNumberRegister, regT0); 475 movePtrToDouble(regT0, fpRegT0); 476 477 int32_t op2imm = getConstantOperand(op2).asInt32(); 478 479 move(Imm32(op2imm), regT1); 480 convertInt32ToDouble(regT1, fpRegT1); 481 482 emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target); 483 484 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); 485 486 fail1.link(this); 487 } 488 489 JITStubCall stubCall(this, cti_op_jless); 490 stubCall.addArgument(regT0); 491 stubCall.addArgument(op2, regT2); 492 stubCall.call(); 493 emitJumpSlowToHot(branchTest32(NonZero, regT0), target); 494 495 } else if (isOperandConstantImmediateInt(op1)) { 496 linkSlowCase(iter); 497 498 if (supportsFloatingPoint()) { 499 Jump fail1 = emitJumpIfNotImmediateNumber(regT1); 500 addPtr(tagTypeNumberRegister, regT1); 501 movePtrToDouble(regT1, fpRegT1); 502 503 int32_t op1imm = getConstantOperand(op1).asInt32(); 504 505 move(Imm32(op1imm), regT0); 506 convertInt32ToDouble(regT0, fpRegT0); 507 508 emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target); 509 510 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); 511 512 fail1.link(this); 513 } 514 515 JITStubCall stubCall(this, cti_op_jless); 516 stubCall.addArgument(op1, regT2); 517 stubCall.addArgument(regT1); 518 stubCall.call(); 519 emitJumpSlowToHot(branchTest32(NonZero, regT0), target); 520 521 } else { 522 linkSlowCase(iter); 523 524 if (supportsFloatingPoint()) { 525 Jump fail1 = emitJumpIfNotImmediateNumber(regT0); 526 Jump fail2 = emitJumpIfNotImmediateNumber(regT1); 527 Jump fail3 = emitJumpIfImmediateInteger(regT1); 528 addPtr(tagTypeNumberRegister, regT0); 529 addPtr(tagTypeNumberRegister, regT1); 530 movePtrToDouble(regT0, fpRegT0); 531 movePtrToDouble(regT1, fpRegT1); 532 533 emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target); 534 535 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless)); 536 537 fail1.link(this); 538 fail2.link(this); 539 fail3.link(this); 540 } 541 542 linkSlowCase(iter); 543 JITStubCall stubCall(this, cti_op_jless); 544 stubCall.addArgument(regT0); 545 stubCall.addArgument(regT1); 546 stubCall.call(); 547 emitJumpSlowToHot(branchTest32(NonZero, regT0), target); 548 } 549 } 550 551 void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert) 552 { 553 unsigned op1 = currentInstruction[1].u.operand; 554 unsigned op2 = currentInstruction[2].u.operand; 555 unsigned target = currentInstruction[3].u.operand; 556 557 // We generate inline code for the following cases in the fast path: 558 // - int immediate to constant int immediate 559 // - constant int immediate to int immediate 560 // - int immediate to int immediate 561 562 if (isOperandConstantImmediateChar(op1)) { 563 emitGetVirtualRegister(op2, regT0); 564 addSlowCase(emitJumpIfNotJSCell(regT0)); 565 JumpList failures; 566 emitLoadCharacterString(regT0, regT0, failures); 567 addSlowCase(failures); 568 addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target); 569 return; 570 } 571 if (isOperandConstantImmediateChar(op2)) { 572 emitGetVirtualRegister(op1, regT0); 573 addSlowCase(emitJumpIfNotJSCell(regT0)); 574 JumpList failures; 575 emitLoadCharacterString(regT0, regT0, failures); 576 addSlowCase(failures); 577 addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target); 578 return; 579 } 580 if (isOperandConstantImmediateInt(op2)) { 581 emitGetVirtualRegister(op1, regT0); 582 emitJumpSlowCaseIfNotImmediateInteger(regT0); 583 int32_t op2imm = getConstantOperandImmediateInt(op2); 584 addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(op2imm)), target); 585 } else if (isOperandConstantImmediateInt(op1)) { 586 emitGetVirtualRegister(op2, regT1); 587 emitJumpSlowCaseIfNotImmediateInteger(regT1); 588 int32_t op1imm = getConstantOperandImmediateInt(op1); 589 addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT1, Imm32(op1imm)), target); 590 } else { 591 emitGetVirtualRegisters(op1, regT0, op2, regT1); 592 emitJumpSlowCaseIfNotImmediateInteger(regT0); 593 emitJumpSlowCaseIfNotImmediateInteger(regT1); 594 595 addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, regT1), target); 596 } 597 } 598 599 void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool invert) 600 { 601 unsigned op1 = currentInstruction[1].u.operand; 602 unsigned op2 = currentInstruction[2].u.operand; 603 unsigned target = currentInstruction[3].u.operand; 604 605 // We generate inline code for the following cases in the slow path: 606 // - floating-point number to constant int immediate 607 // - constant int immediate to floating-point number 608 // - floating-point number to floating-point number. 609 610 if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) { 611 linkSlowCase(iter); 612 linkSlowCase(iter); 613 linkSlowCase(iter); 614 linkSlowCase(iter); 615 JITStubCall stubCall(this, cti_op_jlesseq); 616 stubCall.addArgument(op1, regT0); 617 stubCall.addArgument(op2, regT1); 618 stubCall.call(); 619 emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target); 620 return; 621 } 622 623 if (isOperandConstantImmediateInt(op2)) { 624 linkSlowCase(iter); 625 626 if (supportsFloatingPoint()) { 627 Jump fail1 = emitJumpIfNotImmediateNumber(regT0); 628 addPtr(tagTypeNumberRegister, regT0); 629 movePtrToDouble(regT0, fpRegT0); 630 631 int32_t op2imm = getConstantOperand(op2).asInt32();; 632 633 move(Imm32(op2imm), regT1); 634 convertInt32ToDouble(regT1, fpRegT1); 635 636 emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target); 637 638 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); 639 640 fail1.link(this); 641 } 642 643 JITStubCall stubCall(this, cti_op_jlesseq); 644 stubCall.addArgument(regT0); 645 stubCall.addArgument(op2, regT2); 646 stubCall.call(); 647 emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target); 648 649 } else if (isOperandConstantImmediateInt(op1)) { 650 linkSlowCase(iter); 651 652 if (supportsFloatingPoint()) { 653 Jump fail1 = emitJumpIfNotImmediateNumber(regT1); 654 addPtr(tagTypeNumberRegister, regT1); 655 movePtrToDouble(regT1, fpRegT1); 656 657 int32_t op1imm = getConstantOperand(op1).asInt32();; 658 659 move(Imm32(op1imm), regT0); 660 convertInt32ToDouble(regT0, fpRegT0); 661 662 emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target); 663 664 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); 665 666 fail1.link(this); 667 } 668 669 JITStubCall stubCall(this, cti_op_jlesseq); 670 stubCall.addArgument(op1, regT2); 671 stubCall.addArgument(regT1); 672 stubCall.call(); 673 emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target); 674 675 } else { 676 linkSlowCase(iter); 677 678 if (supportsFloatingPoint()) { 679 Jump fail1 = emitJumpIfNotImmediateNumber(regT0); 680 Jump fail2 = emitJumpIfNotImmediateNumber(regT1); 681 Jump fail3 = emitJumpIfImmediateInteger(regT1); 682 addPtr(tagTypeNumberRegister, regT0); 683 addPtr(tagTypeNumberRegister, regT1); 684 movePtrToDouble(regT0, fpRegT0); 685 movePtrToDouble(regT1, fpRegT1); 686 687 emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target); 688 689 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq)); 690 691 fail1.link(this); 692 fail2.link(this); 693 fail3.link(this); 694 } 695 696 linkSlowCase(iter); 697 JITStubCall stubCall(this, cti_op_jlesseq); 455 JITStubCall stubCall(this, stub); 698 456 stubCall.addArgument(regT0); 699 457 stubCall.addArgument(regT1); … … 701 459 emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target); 702 460 } 703 }704 705 void JIT::emit_op_jnlesseq(Instruction* currentInstruction)706 {707 emit_op_jlesseq(currentInstruction, true);708 }709 710 void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)711 {712 emitSlow_op_jlesseq(currentInstruction, iter, true);713 461 } 714 462 … … 1239 987 /* ------------------------------ END: OP_ADD, OP_SUB, OP_MUL ------------------------------ */ 1240 988 989 #endif // USE(JSVALUE64) 990 1241 991 } // namespace JSC 1242 992 1243 #endif // USE(JSVALUE64)1244 993 #endif // ENABLE(JIT) -
trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
r86968 r90352 85 85 } 86 86 87 void JIT::emit_op_jnless(Instruction* currentInstruction) 88 { 89 unsigned op1 = currentInstruction[1].u.operand; 90 unsigned op2 = currentInstruction[2].u.operand; 91 unsigned target = currentInstruction[3].u.operand; 92 87 void JIT::emit_compareAndJump(OpcodeID opcode, unsigned op1, unsigned op2, unsigned target, RelationalCondition condition) 88 { 93 89 JumpList notInt32Op1; 94 90 JumpList notInt32Op2; … … 101 97 emitLoadCharacterString(regT0, regT0, failures); 102 98 addSlowCase(failures); 103 addJump(branch32( LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);99 addJump(branch32(commute(condition), regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target); 104 100 return; 105 101 } … … 110 106 emitLoadCharacterString(regT0, regT0, failures); 111 107 addSlowCase(failures); 112 addJump(branch32( GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);113 return; 114 } 108 addJump(branch32(condition, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target); 109 return; 110 } 115 111 if (isOperandConstantImmediateInt(op1)) { 116 // Int32 less.117 112 emitLoad(op2, regT3, regT2); 118 113 notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 119 addJump(branch32( LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target);114 addJump(branch32(commute(condition), regT2, Imm32(getConstantOperand(op1).asInt32())), target); 120 115 } else if (isOperandConstantImmediateInt(op2)) { 121 116 emitLoad(op1, regT1, regT0); 122 117 notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 123 addJump(branch32( GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);118 addJump(branch32(condition, regT0, Imm32(getConstantOperand(op2).asInt32())), target); 124 119 } else { 125 120 emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 126 121 notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 127 122 notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 128 addJump(branch32( GreaterThanOrEqual, regT0, regT2), target);123 addJump(branch32(condition, regT0, regT2), target); 129 124 } 130 125 … … 137 132 138 133 // Double less. 139 emitBinaryDoubleOp(op _jnless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));134 emitBinaryDoubleOp(opcode, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)); 140 135 end.link(this); 141 136 } 142 137 143 void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 144 { 145 unsigned op1 = currentInstruction[1].u.operand; 146 unsigned op2 = currentInstruction[2].u.operand; 147 unsigned target = currentInstruction[3].u.operand; 148 138 void JIT::emit_compareAndJumpSlow(unsigned op1, unsigned op2, unsigned target, DoubleCondition, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION), bool invert, Vector<SlowCaseEntry>::iterator& iter) 139 { 149 140 if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) { 150 141 linkSlowCase(iter); … … 166 157 } 167 158 } 168 169 JITStubCall stubCall(this, cti_op_jless); 170 stubCall.addArgument(op1); 171 stubCall.addArgument(op2); 172 stubCall.call(); 173 emitJumpSlowToHot(branchTest32(Zero, regT0), target); 174 } 175 176 void JIT::emit_op_jless(Instruction* currentInstruction) 177 { 178 unsigned op1 = currentInstruction[1].u.operand; 179 unsigned op2 = currentInstruction[2].u.operand; 180 unsigned target = currentInstruction[3].u.operand; 181 182 JumpList notInt32Op1; 183 JumpList notInt32Op2; 184 185 // Character less. 186 if (isOperandConstantImmediateChar(op1)) { 187 emitLoad(op2, regT1, regT0); 188 addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag))); 189 JumpList failures; 190 emitLoadCharacterString(regT0, regT0, failures); 191 addSlowCase(failures); 192 addJump(branch32(GreaterThan, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target); 193 return; 194 } 195 if (isOperandConstantImmediateChar(op2)) { 196 emitLoad(op1, regT1, regT0); 197 addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag))); 198 JumpList failures; 199 emitLoadCharacterString(regT0, regT0, failures); 200 addSlowCase(failures); 201 addJump(branch32(LessThan, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target); 202 return; 203 } 204 if (isOperandConstantImmediateInt(op1)) { 205 emitLoad(op2, regT3, regT2); 206 notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 207 addJump(branch32(GreaterThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target); 208 } else if (isOperandConstantImmediateInt(op2)) { 209 emitLoad(op1, regT1, regT0); 210 notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 211 addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target); 212 } else { 213 emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 214 notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 215 notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 216 addJump(branch32(LessThan, regT0, regT2), target); 217 } 218 219 if (!supportsFloatingPoint()) { 220 addSlowCase(notInt32Op1); 221 addSlowCase(notInt32Op2); 222 return; 223 } 224 Jump end = jump(); 225 226 // Double less. 227 emitBinaryDoubleOp(op_jless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)); 228 end.link(this); 229 } 230 231 void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 232 { 233 unsigned op1 = currentInstruction[1].u.operand; 234 unsigned op2 = currentInstruction[2].u.operand; 235 unsigned target = currentInstruction[3].u.operand; 236 237 if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) { 238 linkSlowCase(iter); 239 linkSlowCase(iter); 240 linkSlowCase(iter); 241 linkSlowCase(iter); 242 } else { 243 if (!supportsFloatingPoint()) { 244 if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) 245 linkSlowCase(iter); // int32 check 246 linkSlowCase(iter); // int32 check 247 } else { 248 if (!isOperandConstantImmediateInt(op1)) { 249 linkSlowCase(iter); // double check 250 linkSlowCase(iter); // int32 check 251 } 252 if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)) 253 linkSlowCase(iter); // double check 254 } 255 } 256 JITStubCall stubCall(this, cti_op_jless); 257 stubCall.addArgument(op1); 258 stubCall.addArgument(op2); 259 stubCall.call(); 260 emitJumpSlowToHot(branchTest32(NonZero, regT0), target); 261 } 262 263 void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert) 264 { 265 unsigned op1 = currentInstruction[1].u.operand; 266 unsigned op2 = currentInstruction[2].u.operand; 267 unsigned target = currentInstruction[3].u.operand; 268 269 JumpList notInt32Op1; 270 JumpList notInt32Op2; 271 272 // Character less. 273 if (isOperandConstantImmediateChar(op1)) { 274 emitLoad(op2, regT1, regT0); 275 addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag))); 276 JumpList failures; 277 emitLoadCharacterString(regT0, regT0, failures); 278 addSlowCase(failures); 279 addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target); 280 return; 281 } 282 if (isOperandConstantImmediateChar(op2)) { 283 emitLoad(op1, regT1, regT0); 284 addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag))); 285 JumpList failures; 286 emitLoadCharacterString(regT0, regT0, failures); 287 addSlowCase(failures); 288 addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target); 289 return; 290 } 291 if (isOperandConstantImmediateInt(op1)) { 292 emitLoad(op2, regT3, regT2); 293 notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 294 addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target); 295 } else if (isOperandConstantImmediateInt(op2)) { 296 emitLoad(op1, regT1, regT0); 297 notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 298 addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target); 299 } else { 300 emitLoad2(op1, regT1, regT0, op2, regT3, regT2); 301 notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag))); 302 notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag))); 303 addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, regT2), target); 304 } 305 306 if (!supportsFloatingPoint()) { 307 addSlowCase(notInt32Op1); 308 addSlowCase(notInt32Op2); 309 return; 310 } 311 Jump end = jump(); 312 313 // Double less. 314 emitBinaryDoubleOp(invert ? op_jnlesseq : op_jlesseq, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)); 315 end.link(this); 316 } 317 318 void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool invert) 319 { 320 unsigned op1 = currentInstruction[1].u.operand; 321 unsigned op2 = currentInstruction[2].u.operand; 322 unsigned target = currentInstruction[3].u.operand; 323 324 if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) { 325 linkSlowCase(iter); 326 linkSlowCase(iter); 327 linkSlowCase(iter); 328 linkSlowCase(iter); 329 } else { 330 if (!supportsFloatingPoint()) { 331 if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2)) 332 linkSlowCase(iter); // int32 check 333 linkSlowCase(iter); // int32 check 334 } else { 335 if (!isOperandConstantImmediateInt(op1)) { 336 linkSlowCase(iter); // double check 337 linkSlowCase(iter); // int32 check 338 } 339 if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2)) 340 linkSlowCase(iter); // double check 341 } 342 } 343 344 JITStubCall stubCall(this, cti_op_jlesseq); 159 JITStubCall stubCall(this, stub); 345 160 stubCall.addArgument(op1); 346 161 stubCall.addArgument(op2); 347 162 stubCall.call(); 348 163 emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target); 349 }350 351 void JIT::emit_op_jnlesseq(Instruction* currentInstruction)352 {353 emit_op_jlesseq(currentInstruction, true);354 }355 356 void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)357 {358 emitSlow_op_jlesseq(currentInstruction, iter, true);359 164 } 360 165 -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r89171 r90352 329 329 } 330 330 331 void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)332 {333 emitTimeoutCheck();334 335 unsigned op1 = currentInstruction[1].u.operand;336 unsigned op2 = currentInstruction[2].u.operand;337 unsigned target = currentInstruction[3].u.operand;338 if (isOperandConstantImmediateInt(op2)) {339 emitGetVirtualRegister(op1, regT0);340 emitJumpSlowCaseIfNotImmediateInteger(regT0);341 int32_t op2imm = getConstantOperandImmediateInt(op2);342 addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target);343 } else {344 emitGetVirtualRegisters(op1, regT0, op2, regT1);345 emitJumpSlowCaseIfNotImmediateInteger(regT0);346 emitJumpSlowCaseIfNotImmediateInteger(regT1);347 addJump(branch32(LessThanOrEqual, regT0, regT1), target);348 }349 }350 351 331 void JIT::emit_op_new_object(Instruction* currentInstruction) 352 332 { … … 1242 1222 stubCall.addArgument(regT0); 1243 1223 stubCall.call(currentInstruction[1].u.operand); 1244 }1245 1246 void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)1247 {1248 unsigned op2 = currentInstruction[2].u.operand;1249 unsigned target = currentInstruction[3].u.operand;1250 if (isOperandConstantImmediateInt(op2)) {1251 linkSlowCase(iter);1252 JITStubCall stubCall(this, cti_op_loop_if_lesseq);1253 stubCall.addArgument(regT0);1254 stubCall.addArgument(currentInstruction[2].u.operand, regT2);1255 stubCall.call();1256 emitJumpSlowToHot(branchTest32(NonZero, regT0), target);1257 } else {1258 linkSlowCase(iter);1259 linkSlowCase(iter);1260 JITStubCall stubCall(this, cti_op_loop_if_lesseq);1261 stubCall.addArgument(regT0);1262 stubCall.addArgument(regT1);1263 stubCall.call();1264 emitJumpSlowToHot(branchTest32(NonZero, regT0), target);1265 }1266 1224 } 1267 1225 -
trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
r90232 r90352 484 484 } 485 485 486 void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)487 {488 unsigned op1 = currentInstruction[1].u.operand;489 unsigned op2 = currentInstruction[2].u.operand;490 unsigned target = currentInstruction[3].u.operand;491 492 emitTimeoutCheck();493 494 if (isOperandConstantImmediateInt(op1)) {495 emitLoad(op2, regT1, regT0);496 addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));497 addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target);498 return;499 }500 501 if (isOperandConstantImmediateInt(op2)) {502 emitLoad(op1, regT1, regT0);503 addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));504 addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);505 return;506 }507 508 emitLoad2(op1, regT1, regT0, op2, regT3, regT2);509 addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));510 addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));511 addJump(branch32(LessThanOrEqual, regT0, regT2), target);512 }513 514 void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)515 {516 unsigned op1 = currentInstruction[1].u.operand;517 unsigned op2 = currentInstruction[2].u.operand;518 unsigned target = currentInstruction[3].u.operand;519 520 if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))521 linkSlowCase(iter); // int32 check522 linkSlowCase(iter); // int32 check523 524 JITStubCall stubCall(this, cti_op_loop_if_lesseq);525 stubCall.addArgument(op1);526 stubCall.addArgument(op2);527 stubCall.call();528 emitJumpSlowToHot(branchTest32(NonZero, regT0), target);529 }530 531 486 void JIT::emit_op_new_object(Instruction* currentInstruction) 532 487 { -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r89954 r90352 1369 1369 1370 1370 return callFrame; 1371 }1372 1373 DEFINE_STUB_FUNCTION(int, op_loop_if_lesseq)1374 {1375 STUB_INIT_STACK_FRAME(stackFrame);1376 1377 JSValue src1 = stackFrame.args[0].jsValue();1378 JSValue src2 = stackFrame.args[1].jsValue();1379 CallFrame* callFrame = stackFrame.callFrame;1380 1381 bool result = jsLessEq(callFrame, src1, src2);1382 CHECK_FOR_EXCEPTION_AT_END();1383 return result;1384 1371 } 1385 1372 -
trunk/Source/JavaScriptCore/jit/JITStubs.h
r88873 r90352 397 397 int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION); 398 398 int JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION); 399 int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS_DECLARATION);400 399 int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION); 401 400 int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION);
Note: See TracChangeset
for help on using the changeset viewer.