Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 // Input values must be either smi or heap number objects (fp values). | 218 // Input values must be either smi or heap number objects (fp values). |
| 219 // Requirements: | 219 // Requirements: |
| 220 // Register version: operands in registers lhs and rhs. | 220 // Register version: operands in registers lhs and rhs. |
| 221 // Stack version: operands on TOS+1 and TOS+2. | 221 // Stack version: operands on TOS+1 and TOS+2. |
| 222 // Returns operands as floating point numbers on fp stack. | 222 // Returns operands as floating point numbers on fp stack. |
| 223 static void LoadFloatOperands(MacroAssembler* masm); | 223 static void LoadFloatOperands(MacroAssembler* masm); |
| 224 static void LoadFloatOperands(MacroAssembler* masm, | 224 static void LoadFloatOperands(MacroAssembler* masm, |
| 225 Register lhs, | 225 Register lhs, |
| 226 Register rhs); | 226 Register rhs); |
| 227 | 227 |
| 228 // Code pattern for loading a floating point value and converting it | 228 // Code pattern for loading a floating point argument and converting it |
| 229 // to a 32 bit integer. Input value must be either a smi or a heap number | 229 // to a 32 bit integer by truncating. Input value must be either a smi or |
| 230 // object. | 230 // a heap number object, otherwise the on_non_number label is jumped to. |
| 231 // Returns operands as 32-bit sign extended integers in a general purpose | 231 // Expects arguments in register src, and returns result in register dst. |
| 232 // registers. | 232 // Uses rcx and rax (src may not be either of these). |
| 233 static void LoadInt32Operand(MacroAssembler* masm, | 233 static void LoadInt32OperandSSE3(MacroAssembler* masm, |
| 234 const Operand& src, | 234 Register dst, |
| 235 Register dst); | 235 Register src, |
| 236 Label* on_non_number); | |
| 237 static void LoadInt32OperandFPU(MacroAssembler* masm, | |
| 238 Register dst, | |
| 239 Register src, | |
| 240 Label* on_non_number); | |
| 236 | 241 |
| 237 // Test if operands are smi or number objects (fp). Requirements: | 242 // Test if operands are smi or number objects (fp). Requirements: |
| 238 // operand_1 in rax, operand_2 in rdx; falls through on float or smi | 243 // operand_1 in rax, operand_2 in rdx; falls through on float or smi |
| 239 // operands, jumps to the non_float label otherwise. | 244 // operands, jumps to the non_float label otherwise. |
| 240 static void CheckFloatOperands(MacroAssembler* masm, | 245 static void CheckFloatOperands(MacroAssembler* masm, |
| 241 Label* non_float); | 246 Label* non_float); |
| 242 | 247 |
| 243 // Allocate a heap number in new space with undefined value. | 248 // Allocate a heap number in new space with undefined value. |
| 244 // Returns tagged pointer in result, or jumps to need_gc if new space is full. | 249 // Returns tagged pointer in result, or jumps to need_gc if new space is full. |
| 245 static void AllocateHeapNumber(MacroAssembler* masm, | 250 static void AllocateHeapNumber(MacroAssembler* masm, |
| (...skipping 7001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7247 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm, | 7252 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm, |
| 7248 XMMRegister dst1, | 7253 XMMRegister dst1, |
| 7249 XMMRegister dst2) { | 7254 XMMRegister dst2) { |
| 7250 __ movq(kScratchRegister, Operand(rsp, 2 * kPointerSize)); | 7255 __ movq(kScratchRegister, Operand(rsp, 2 * kPointerSize)); |
| 7251 LoadFloatOperand(masm, kScratchRegister, dst1); | 7256 LoadFloatOperand(masm, kScratchRegister, dst1); |
| 7252 __ movq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); | 7257 __ movq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); |
| 7253 LoadFloatOperand(masm, kScratchRegister, dst2); | 7258 LoadFloatOperand(masm, kScratchRegister, dst2); |
| 7254 } | 7259 } |
| 7255 | 7260 |
| 7256 | 7261 |
| 7257 void FloatingPointHelper::LoadInt32Operand(MacroAssembler* masm, | 7262 void FloatingPointHelper::LoadInt32OperandSSE3(MacroAssembler* masm, |
| 7258 const Operand& src, | 7263 Register dst, |
| 7259 Register dst) { | 7264 Register src, |
| 7260 // TODO(X64): Convert number operands to int32 values. | 7265 Label* on_non_number) { |
| 7261 // Don't convert a Smi to a double first. | 7266 ASSERT(!src.is(rax)); |
| 7262 UNIMPLEMENTED(); | 7267 ASSERT(!src.is(rcx)); |
| 7268 | |
| 7269 CpuFeatures::Scope scope(CpuFeatures::SSE3); | |
| 7270 | |
| 7271 Label non_smi; | |
| 7272 Label done; | |
| 7273 Label non_smi_value; | |
| 7274 | |
| 7275 __ JumpIfNotSmi(src, &non_smi); | |
| 7276 __ SmiToInteger32(dst, src); | |
| 7277 __ jmp(&done); | |
| 7278 | |
| 7279 // Do a full conversion by operating on the double bits. | |
| 7280 __ bind(&non_smi_value); | |
| 7281 __ addq(rsp, Immediate(kPointerSize)); | |
| 7282 __ fnclex(); | |
| 7283 __ movq(src, FieldOperand(src, HeapNumber::kValueOffset)); | |
| 7284 __ DoubleToInteger32(dst, src, rax); | |
| 7285 __ jmp(&done); | |
| 7286 | |
| 7287 __ bind(&non_smi); | |
| 7288 // Check that we have a HeapNumber. | |
| 7289 __ CompareRoot(FieldOperand(src, HeapObject::kMapOffset), | |
| 7290 Heap::kHeapNumberMapRootIndex); | |
| 7291 __ j(not_equal, on_non_number); | |
| 7292 | |
| 7293 // Try quick conversion, if the double holds a valid smi value. | |
| 7294 | |
| 7295 __ fld_d(FieldOperand(src, HeapNumber::kValueOffset)); | |
| 7296 __ subq(rsp, Immediate(kPointerSize)); | |
| 7297 __ fisttp_s(Operand(rsp, 0 * kPointerSize)); | |
| 7298 __ fnstsw_ax(); | |
| 7299 __ testl(rax, Immediate(1)); | |
| 7300 __ j(not_zero, &non_smi_value); | |
| 7301 __ pop(dst); | |
| 7302 | |
| 7303 __ bind(&done); | |
| 7263 } | 7304 } |
| 7264 | 7305 |
| 7265 | 7306 |
| 7307 void FloatingPointHelper::LoadInt32OperandFPU(MacroAssembler* masm, | |
| 7308 Register dst, | |
| 7309 Register src, | |
| 7310 Label* on_non_number) { | |
| 7311 ASSERT(!src.is(rax)); | |
| 7312 ASSERT(!src.is(rcx)); | |
| 7313 | |
| 7314 Label non_smi; | |
| 7315 Label done; | |
| 7316 Label non_smi_value; | |
| 7317 | |
| 7318 __ JumpIfNotSmi(src, &non_smi); | |
| 7319 __ SmiToInteger32(dst, src); | |
| 7320 __ jmp(&done); | |
| 7321 | |
| 7322 // Do a full conversion by operating on the double bits. | |
| 7323 __ bind(&non_smi_value); | |
| 7324 __ addq(rsp, Immediate(kPointerSize)); | |
| 7325 __ movq(src, FieldOperand(src, HeapNumber::kValueOffset)); | |
| 7326 __ DoubleToInteger32(dst, src, rax); | |
| 7327 __ jmp(&done); | |
| 7328 | |
| 7329 __ bind(&non_smi); | |
| 7330 // Check that we have a HeapNumber. | |
| 7331 __ CompareRoot(FieldOperand(src, HeapObject::kMapOffset), | |
| 7332 Heap::kHeapNumberMapRootIndex); | |
| 7333 __ j(not_equal, on_non_number); | |
| 7334 | |
| 7335 // Try quick conversion, if the double holds a valid smi value. | |
| 7336 | |
| 7337 __ fld_d(FieldOperand(src, HeapNumber::kValueOffset)); | |
| 7338 __ subq(rsp, Immediate(kPointerSize)); | |
| 7339 __ fist_s(Operand(rsp, 0 * kPointerSize)); | |
| 7340 __ fild_s(Operand(rsp, 0 * kPointerSize)); | |
| 7341 __ fucompp(); | |
| 7342 __ fnstsw_ax(); | |
| 7343 if (CpuFeatures::IsSupported(CpuFeatures::SAHF)) { | |
| 7344 __ sahf(); | |
| 7345 __ j(not_zero, &non_smi_value); | |
| 7346 __ j(parity_even, &non_smi_value); | |
| 7347 } else { | |
| 7348 __ and_(rax, Immediate(0x4400)); | |
| 7349 __ cmpl(rax, Immediate(0x4000)); | |
| 7350 __ j(not_equal, &non_smi_value); | |
| 7351 } | |
| 7352 __ pop(dst); | |
| 7353 | |
| 7354 __ bind(&done); | |
| 7355 } | |
| 7356 | |
| 7357 | |
| 7358 | |
| 7266 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm) { | 7359 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm) { |
| 7267 Label load_smi_1, load_smi_2, done_load_1, done; | 7360 Label load_smi_1, load_smi_2, done_load_1, done; |
| 7268 __ movq(kScratchRegister, Operand(rsp, 2 * kPointerSize)); | 7361 __ movq(kScratchRegister, Operand(rsp, 2 * kPointerSize)); |
| 7269 __ JumpIfSmi(kScratchRegister, &load_smi_1); | 7362 __ JumpIfSmi(kScratchRegister, &load_smi_1); |
| 7270 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); | 7363 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); |
| 7271 __ bind(&done_load_1); | 7364 __ bind(&done_load_1); |
| 7272 | 7365 |
| 7273 __ movq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); | 7366 __ movq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); |
| 7274 __ JumpIfSmi(kScratchRegister, &load_smi_2); | 7367 __ JumpIfSmi(kScratchRegister, &load_smi_2); |
| 7275 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); | 7368 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7395 __ SmiAnd(rax, rax, rbx); | 7488 __ SmiAnd(rax, rax, rbx); |
| 7396 break; | 7489 break; |
| 7397 | 7490 |
| 7398 case Token::BIT_XOR: | 7491 case Token::BIT_XOR: |
| 7399 __ SmiXor(rax, rax, rbx); | 7492 __ SmiXor(rax, rax, rbx); |
| 7400 break; | 7493 break; |
| 7401 | 7494 |
| 7402 case Token::SHL: | 7495 case Token::SHL: |
| 7403 case Token::SHR: | 7496 case Token::SHR: |
| 7404 case Token::SAR: | 7497 case Token::SAR: |
| 7405 // Move the second operand into register ecx. | |
| 7406 __ movl(rcx, rbx); | |
| 7407 // Perform the operation. | 7498 // Perform the operation. |
| 7408 switch (op_) { | 7499 switch (op_) { |
| 7409 case Token::SAR: | 7500 case Token::SAR: |
| 7410 __ SmiShiftArithmeticRight(rax, rax, rbx); | 7501 __ SmiShiftArithmeticRight(rax, rax, rbx); |
| 7411 break; | 7502 break; |
| 7412 case Token::SHR: | 7503 case Token::SHR: |
| 7413 __ SmiShiftLogicalRight(rax, rax, rbx, slow); | 7504 __ SmiShiftLogicalRight(rax, rax, rbx, slow); |
| 7414 break; | 7505 break; |
| 7415 case Token::SHL: | 7506 case Token::SHL: |
| 7416 __ SmiShiftLeft(rax, rax, rbx, slow); | 7507 __ SmiShiftLeft(rax, rax, rbx, slow); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7492 case Token::MOD: { | 7583 case Token::MOD: { |
| 7493 // For MOD we go directly to runtime in the non-smi case. | 7584 // For MOD we go directly to runtime in the non-smi case. |
| 7494 break; | 7585 break; |
| 7495 } | 7586 } |
| 7496 case Token::BIT_OR: | 7587 case Token::BIT_OR: |
| 7497 case Token::BIT_AND: | 7588 case Token::BIT_AND: |
| 7498 case Token::BIT_XOR: | 7589 case Token::BIT_XOR: |
| 7499 case Token::SAR: | 7590 case Token::SAR: |
| 7500 case Token::SHL: | 7591 case Token::SHL: |
| 7501 case Token::SHR: { | 7592 case Token::SHR: { |
| 7502 FloatingPointHelper::CheckFloatOperands(masm, &call_runtime); | 7593 Label skip_allocation, non_smi_result, operand_conversion_failure; |
|
Lasse Reichstein
2009/10/07 16:54:24
I'm considering using CheckFloatOperands first, to
| |
| 7503 // TODO(X64): Don't convert a Smi to float and then back to int32 | 7594 // Arguments in rax/rsp[1] and rdx/rsp[0]. |
| 7504 // afterwards. | 7595 // Move rhs to rbx, since conversion uses rax to read FPU status word. |
| 7505 FloatingPointHelper::LoadFloatOperands(masm); | 7596 __ movq(rbx, rax); |
| 7597 if (use_sse3_) { | |
| 7598 FloatingPointHelper::LoadInt32OperandSSE3(masm, | |
| 7599 rdx, | |
| 7600 rdx, | |
| 7601 &operand_conversion_failure); | |
| 7602 FloatingPointHelper::LoadInt32OperandSSE3(masm, | |
| 7603 rcx, | |
| 7604 rbx, | |
| 7605 &operand_conversion_failure); | |
| 7606 } else { | |
| 7607 FloatingPointHelper::LoadInt32OperandFPU(masm, | |
| 7608 rdx, | |
| 7609 rdx, | |
| 7610 &operand_conversion_failure); | |
| 7611 FloatingPointHelper::LoadInt32OperandFPU(masm, | |
| 7612 rcx, | |
| 7613 rbx, | |
| 7614 &operand_conversion_failure); | |
| 7615 } | |
| 7616 // 32-bit values in rbx, rcx. | |
| 7506 | 7617 |
| 7507 Label skip_allocation, non_smi_result, operand_conversion_failure; | |
| 7508 | |
| 7509 // Reserve space for converted numbers. | |
| 7510 __ subq(rsp, Immediate(2 * kPointerSize)); | |
| 7511 | |
| 7512 if (use_sse3_) { | |
| 7513 // Truncate the operands to 32-bit integers and check for | |
| 7514 // exceptions in doing so. | |
| 7515 CpuFeatures::Scope scope(CpuFeatures::SSE3); | |
| 7516 __ fisttp_s(Operand(rsp, 0 * kPointerSize)); | |
| 7517 __ fisttp_s(Operand(rsp, 1 * kPointerSize)); | |
| 7518 __ fnstsw_ax(); | |
| 7519 __ testl(rax, Immediate(1)); | |
| 7520 __ j(not_zero, &operand_conversion_failure); | |
| 7521 } else { | |
| 7522 // Check if right operand is int32. | |
| 7523 __ fist_s(Operand(rsp, 0 * kPointerSize)); | |
| 7524 __ fild_s(Operand(rsp, 0 * kPointerSize)); | |
| 7525 __ fucompp(); | |
| 7526 __ fnstsw_ax(); | |
| 7527 if (CpuFeatures::IsSupported(CpuFeatures::SAHF)) { | |
| 7528 __ sahf(); | |
| 7529 __ j(not_zero, &operand_conversion_failure); | |
| 7530 __ j(parity_even, &operand_conversion_failure); | |
| 7531 } else { | |
| 7532 __ and_(rax, Immediate(0x4400)); | |
| 7533 __ cmpl(rax, Immediate(0x4000)); | |
| 7534 __ j(not_zero, &operand_conversion_failure); | |
| 7535 } | |
| 7536 // Check if left operand is int32. | |
| 7537 __ fist_s(Operand(rsp, 1 * kPointerSize)); | |
| 7538 __ fild_s(Operand(rsp, 1 * kPointerSize)); | |
| 7539 __ fucompp(); | |
| 7540 __ fnstsw_ax(); | |
| 7541 if (CpuFeatures::IsSupported(CpuFeatures::SAHF)) { | |
| 7542 __ sahf(); | |
| 7543 __ j(not_zero, &operand_conversion_failure); | |
| 7544 __ j(parity_even, &operand_conversion_failure); | |
| 7545 } else { | |
| 7546 __ and_(rax, Immediate(0x4400)); | |
| 7547 __ cmpl(rax, Immediate(0x4000)); | |
| 7548 __ j(not_zero, &operand_conversion_failure); | |
| 7549 } | |
| 7550 } | |
| 7551 | |
| 7552 // Get int32 operands and perform bitop. | |
| 7553 __ pop(rcx); | |
| 7554 __ pop(rax); | |
| 7555 switch (op_) { | 7618 switch (op_) { |
| 7556 case Token::BIT_OR: __ or_(rax, rcx); break; | 7619 case Token::BIT_OR: __ orl(rdx, rcx); break; |
| 7557 case Token::BIT_AND: __ and_(rax, rcx); break; | 7620 case Token::BIT_AND: __ andl(rdx, rcx); break; |
| 7558 case Token::BIT_XOR: __ xor_(rax, rcx); break; | 7621 case Token::BIT_XOR: __ xorl(rdx, rcx); break; |
| 7559 case Token::SAR: __ sarl(rax); break; | 7622 case Token::SAR: __ sarl(rdx); break; |
| 7560 case Token::SHL: __ shll(rax); break; | 7623 case Token::SHL: __ shll(rdx); break; |
| 7561 case Token::SHR: __ shrl(rax); break; | 7624 case Token::SHR: __ shrl(rdx); break; |
| 7562 default: UNREACHABLE(); | 7625 default: UNREACHABLE(); |
| 7563 } | 7626 } |
| 7564 if (op_ == Token::SHR) { | 7627 if (op_ == Token::SHR) { |
| 7565 // Check if result is non-negative and fits in a smi. | 7628 // Check if result is non-negative and fits in a smi. |
| 7566 __ testl(rax, Immediate(0xc0000000)); | 7629 __ testl(rdx, Immediate(0xc0000000)); |
| 7567 __ j(not_zero, &non_smi_result); | 7630 __ j(not_zero, &non_smi_result); |
| 7568 } else { | 7631 } else { |
| 7569 // Check if result fits in a smi. | 7632 // Check if result fits in a smi. |
| 7570 __ cmpl(rax, Immediate(0xc0000000)); | 7633 __ cmpl(rdx, Immediate(0xc0000000)); |
| 7571 __ j(negative, &non_smi_result); | 7634 __ j(negative, &non_smi_result); |
| 7572 } | 7635 } |
| 7573 // Tag smi result and return. | 7636 // Tag smi result and return. |
| 7574 __ Integer32ToSmi(rax, rax); | 7637 __ Integer32ToSmi(rax, rdx); |
| 7575 __ ret(2 * kPointerSize); | 7638 __ ret(2 * kPointerSize); |
| 7576 | 7639 |
| 7577 // All ops except SHR return a signed int32 that we load in a HeapNumber. | 7640 // All ops except SHR return a signed int32 that we load in a HeapNumber. |
| 7578 if (op_ != Token::SHR) { | 7641 if (op_ != Token::SHR) { |
| 7579 __ bind(&non_smi_result); | 7642 __ bind(&non_smi_result); |
| 7580 // Allocate a heap number if needed. | 7643 // Allocate a heap number if needed. |
| 7581 __ movsxlq(rbx, rax); // rbx: sign extended 32-bit result | 7644 __ movsxlq(rbx, rdx); // rbx: sign extended 32-bit result |
| 7582 switch (mode_) { | 7645 switch (mode_) { |
| 7583 case OVERWRITE_LEFT: | 7646 case OVERWRITE_LEFT: |
| 7584 case OVERWRITE_RIGHT: | 7647 case OVERWRITE_RIGHT: |
| 7585 // If the operand was an object, we skip the | 7648 // If the operand was an object, we skip the |
| 7586 // allocation of a heap number. | 7649 // allocation of a heap number. |
| 7587 __ movq(rax, Operand(rsp, mode_ == OVERWRITE_RIGHT ? | 7650 __ movq(rax, Operand(rsp, mode_ == OVERWRITE_RIGHT ? |
| 7588 1 * kPointerSize : 2 * kPointerSize)); | 7651 1 * kPointerSize : 2 * kPointerSize)); |
| 7589 __ JumpIfNotSmi(rax, &skip_allocation); | 7652 __ JumpIfNotSmi(rax, &skip_allocation); |
| 7590 // Fall through! | 7653 // Fall through! |
| 7591 case NO_OVERWRITE: | 7654 case NO_OVERWRITE: |
| 7592 FloatingPointHelper::AllocateHeapNumber(masm, &call_runtime, | 7655 FloatingPointHelper::AllocateHeapNumber(masm, &call_runtime, |
| 7593 rcx, rax); | 7656 rcx, rax); |
| 7594 __ bind(&skip_allocation); | 7657 __ bind(&skip_allocation); |
| 7595 break; | 7658 break; |
| 7596 default: UNREACHABLE(); | 7659 default: UNREACHABLE(); |
| 7597 } | 7660 } |
| 7598 // Store the result in the HeapNumber and return. | 7661 // Store the result in the HeapNumber and return. |
| 7599 __ movq(Operand(rsp, 1 * kPointerSize), rbx); | 7662 __ movq(Operand(rsp, 1 * kPointerSize), rbx); |
| 7600 __ fild_s(Operand(rsp, 1 * kPointerSize)); | 7663 __ fild_s(Operand(rsp, 1 * kPointerSize)); |
| 7601 __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); | 7664 __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); |
| 7602 __ ret(2 * kPointerSize); | 7665 __ ret(2 * kPointerSize); |
| 7603 } | 7666 } |
| 7604 | 7667 |
| 7605 // Clear the FPU exception flag and reset the stack before calling | 7668 // Fast-case operation failed, so call the runtime to perform the operatio n. |
| 7606 // the runtime system. | |
| 7607 __ bind(&operand_conversion_failure); | 7669 __ bind(&operand_conversion_failure); |
| 7608 __ addq(rsp, Immediate(2 * kPointerSize)); | |
| 7609 if (use_sse3_) { | |
| 7610 // If we've used the SSE3 instructions for truncating the | |
| 7611 // floating point values to integers and it failed, we have a | |
| 7612 // pending #IA exception. Clear it. | |
| 7613 __ fnclex(); | |
| 7614 } else { | |
| 7615 // The non-SSE3 variant does early bailout if the right | |
| 7616 // operand isn't a 32-bit integer, so we may have a single | |
| 7617 // value on the FPU stack we need to get rid of. | |
| 7618 __ ffree(0); | |
| 7619 } | |
| 7620 | 7670 |
| 7621 // SHR should return uint32 - go to runtime for non-smi/negative result. | 7671 // SHR should return uint32 - go to runtime for non-smi/negative result. |
| 7622 if (op_ == Token::SHR) { | 7672 if (op_ == Token::SHR) { |
| 7623 __ bind(&non_smi_result); | 7673 __ bind(&non_smi_result); |
| 7624 } | 7674 } |
| 7625 __ movq(rax, Operand(rsp, 1 * kPointerSize)); | 7675 __ movq(rax, Operand(rsp, 1 * kPointerSize)); |
| 7626 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | 7676 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); |
| 7627 break; | 7677 break; |
| 7628 } | 7678 } |
| 7629 default: UNREACHABLE(); break; | 7679 default: UNREACHABLE(); break; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7675 int CompareStub::MinorKey() { | 7725 int CompareStub::MinorKey() { |
| 7676 // Encode the two parameters in a unique 16 bit value. | 7726 // Encode the two parameters in a unique 16 bit value. |
| 7677 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 7727 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
| 7678 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 7728 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
| 7679 } | 7729 } |
| 7680 | 7730 |
| 7681 | 7731 |
| 7682 #undef __ | 7732 #undef __ |
| 7683 | 7733 |
| 7684 } } // namespace v8::internal | 7734 } } // namespace v8::internal |
| OLD | NEW |