Changeset 58562 in webkit for trunk/JavaScriptCore/jit/JITArithmetic32_64.cpp
- Timestamp:
- Apr 30, 2010, 12:56:38 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/jit/JITArithmetic32_64.cpp
r58555 r58562 315 315 } 316 316 317 // RightShift (>>) 318 319 void JIT::emit _op_rshift(Instruction* currentInstruction)317 // RightShift (>>) and UnsignedRightShift (>>>) helper 318 319 void JIT::emitRightShift(Instruction* currentInstruction, bool isUnsigned) 320 320 { 321 321 unsigned dst = currentInstruction[1].u.operand; … … 328 328 emitLoad(op1, regT1, regT0); 329 329 addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); 330 rshift32(Imm32(getConstantOperand(op2).asInt32()), regT0); 330 int shift = getConstantOperand(op2).asInt32(); 331 if (isUnsigned) { 332 if (shift) 333 urshift32(Imm32(shift & 0x1f), regT0); 334 // unsigned shift < 0 or shift = k*2^32 may result in (essentially) 335 // a toUint conversion, which can result in a value we can represent 336 // as an immediate int. 337 if (shift < 0 || !(shift & 31)) 338 addSlowCase(branch32(LessThan, regT0, Imm32(0))); 339 } else if (shift) { // signed right shift by zero is simply toInt conversion 340 rshift32(Imm32(shift & 0x1f), regT0); 341 } 331 342 emitStoreInt32(dst, regT0, dst == op1); 332 343 return; … … 337 348 addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag))); 338 349 addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag))); 339 rshift32(regT2, regT0); 350 if (isUnsigned) { 351 urshift32(regT2, regT0); 352 addSlowCase(branch32(LessThan, regT0, Imm32(0))); 353 } else 354 rshift32(regT2, regT0); 340 355 emitStoreInt32(dst, regT0, dst == op1 || dst == op2); 341 356 } 342 357 343 void JIT::emit Slow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)358 void JIT::emitRightShiftSlowCase(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool isUnsigned) 344 359 { 345 360 unsigned dst = currentInstruction[1].u.operand; … … 347 362 unsigned op2 = currentInstruction[3].u.operand; 348 363 if (isOperandConstantImmediateInt(op2)) { 364 int shift = getConstantOperand(op2).asInt32(); 349 365 // op1 = regT1:regT0 350 366 linkSlowCase(iter); // int32 check 351 367 if (supportsFloatingPointTruncate()) { 352 Jump notDouble = branch32(AboveOrEqual, regT1, Imm32(JSValue::LowestTag)); 368 JumpList failures; 369 failures.append(branch32(AboveOrEqual, regT1, Imm32(JSValue::LowestTag))); 353 370 emitLoadDouble(op1, fpRegT0); 354 Jump truncationFailed = branchTruncateDoubleToInt32(fpRegT0, regT0); 355 rshift32(Imm32(getConstantOperand(op2).asInt32()), regT0); 371 failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0)); 372 if (isUnsigned) { 373 if (shift) 374 urshift32(Imm32(shift & 0x1f), regT0); 375 if (shift < 0 || !(shift & 31)) 376 failures.append(branch32(LessThan, regT0, Imm32(0))); 377 } else if (shift) 378 rshift32(Imm32(shift & 0x1f), regT0); 356 379 emitStoreInt32(dst, regT0, dst == op1 || dst == op2); 357 380 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift)); 358 notDouble.link(this); 359 truncationFailed.link(this); 381 failures.link(this); 360 382 } 383 if (isUnsigned && (shift < 0 || !(shift & 31))) 384 linkSlowCase(iter); // failed to box in hot path 361 385 } else { 362 386 // op1 = regT1:regT0 … … 369 393 Jump notInt = branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)); // op2 is not an int 370 394 Jump cantTruncate = branchTruncateDoubleToInt32(fpRegT0, regT0); 371 rshift32(regT2, regT0); 395 if (isUnsigned) 396 urshift32(regT2, regT0); 397 else 398 rshift32(regT2, regT0); 372 399 emitStoreInt32(dst, regT0, dst == op1 || dst == op2); 373 400 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift)); … … 379 406 380 407 linkSlowCase(iter); // int32 check - op2 is not an int 381 } 382 383 JITStubCall stubCall(this, cti_op_rshift); 384 stubCall.addArgument(op1); 385 stubCall.addArgument(op2); 386 stubCall.call(dst); 408 if (isUnsigned) 409 linkSlowCase(iter); // Can't represent unsigned result as an immediate 410 } 411 412 JITStubCall stubCall(this, isUnsigned ? cti_op_urshift : cti_op_rshift); 413 stubCall.addArgument(op1); 414 stubCall.addArgument(op2); 415 stubCall.call(dst); 416 } 417 418 // RightShift (>>) 419 420 void JIT::emit_op_rshift(Instruction* currentInstruction) 421 { 422 emitRightShift(currentInstruction, false); 423 } 424 425 void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 426 { 427 emitRightShiftSlowCase(currentInstruction, iter, false); 428 } 429 430 // UnsignedRightShift (>>>) 431 432 void JIT::emit_op_urshift(Instruction* currentInstruction) 433 { 434 emitRightShift(currentInstruction, true); 435 } 436 437 void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 438 { 439 emitRightShiftSlowCase(currentInstruction, iter, true); 387 440 } 388 441
Note:
See TracChangeset
for help on using the changeset viewer.