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 5240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5251 } | 5251 } |
5252 operand->Unuse(); | 5252 operand->Unuse(); |
5253 ASSERT(kSmiTag == 0); | 5253 ASSERT(kSmiTag == 0); |
5254 ASSERT(kSmiTagSize == 1); | 5254 ASSERT(kSmiTagSize == 1); |
5255 __ addl(answer.reg(), answer.reg()); | 5255 __ addl(answer.reg(), answer.reg()); |
5256 deferred->BindExit(); | 5256 deferred->BindExit(); |
5257 frame_->Push(&answer); | 5257 frame_->Push(&answer); |
5258 } | 5258 } |
5259 break; | 5259 break; |
5260 | 5260 |
| 5261 case Token::SHL: |
| 5262 if (reversed) { |
| 5263 Result constant_operand(value); |
| 5264 LikelySmiBinaryOperation(op, &constant_operand, operand, |
| 5265 overwrite_mode); |
| 5266 } else { |
| 5267 // Only the least significant 5 bits of the shift value are used. |
| 5268 // In the slow case, this masking is done inside the runtime call. |
| 5269 int shift_value = int_value & 0x1f; |
| 5270 operand->ToRegister(); |
| 5271 if (shift_value == 0) { |
| 5272 // Spill operand so it can be overwritten in the slow case. |
| 5273 frame_->Spill(operand->reg()); |
| 5274 DeferredInlineSmiOperation* deferred = |
| 5275 new DeferredInlineSmiOperation(op, |
| 5276 operand->reg(), |
| 5277 operand->reg(), |
| 5278 smi_value, |
| 5279 overwrite_mode); |
| 5280 __ testl(operand->reg(), Immediate(kSmiTagMask)); |
| 5281 deferred->Branch(not_zero); |
| 5282 deferred->BindExit(); |
| 5283 frame_->Push(operand); |
| 5284 } else { |
| 5285 // Use a fresh temporary for nonzero shift values. |
| 5286 Result answer = allocator()->Allocate(); |
| 5287 ASSERT(answer.is_valid()); |
| 5288 DeferredInlineSmiOperation* deferred = |
| 5289 new DeferredInlineSmiOperation(op, |
| 5290 answer.reg(), |
| 5291 operand->reg(), |
| 5292 smi_value, |
| 5293 overwrite_mode); |
| 5294 __ testl(operand->reg(), Immediate(kSmiTagMask)); |
| 5295 deferred->Branch(not_zero); |
| 5296 __ movl(answer.reg(), operand->reg()); |
| 5297 ASSERT(kSmiTag == 0); // adjust code if not the case |
| 5298 // We do no shifts, only the Smi conversion, if shift_value is 1. |
| 5299 if (shift_value > 1) { |
| 5300 __ shll(answer.reg(), Immediate(shift_value - 1)); |
| 5301 } |
| 5302 // Convert int result to Smi, checking that it is in int range. |
| 5303 ASSERT(kSmiTagSize == 1); // adjust code if not the case |
| 5304 __ addl(answer.reg(), answer.reg()); |
| 5305 deferred->Branch(overflow); |
| 5306 deferred->BindExit(); |
| 5307 operand->Unuse(); |
| 5308 frame_->Push(&answer); |
| 5309 } |
| 5310 } |
| 5311 break; |
| 5312 |
5261 case Token::BIT_OR: | 5313 case Token::BIT_OR: |
5262 case Token::BIT_XOR: | 5314 case Token::BIT_XOR: |
5263 case Token::BIT_AND: { | 5315 case Token::BIT_AND: { |
5264 operand->ToRegister(); | 5316 operand->ToRegister(); |
5265 frame_->Spill(operand->reg()); | 5317 frame_->Spill(operand->reg()); |
5266 if (reversed) { | 5318 if (reversed) { |
5267 // Bit operations with a constant smi are commutative. | 5319 // Bit operations with a constant smi are commutative. |
5268 // We can swap left and right operands with no problem. | 5320 // We can swap left and right operands with no problem. |
5269 // Swap left and right overwrite modes. 0->0, 1->2, 2->1. | 5321 // Swap left and right overwrite modes. 0->0, 1->2, 2->1. |
5270 overwrite_mode = static_cast<OverwriteMode>((2 * overwrite_mode) % 3); | 5322 overwrite_mode = static_cast<OverwriteMode>((2 * overwrite_mode) % 3); |
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6006 // We can skip the write barrier for smis and constants. | 6058 // We can skip the write barrier for smis and constants. |
6007 if (!value_is_constant) { | 6059 if (!value_is_constant) { |
6008 __ testl(value.reg(), Immediate(kSmiTagMask)); | 6060 __ testl(value.reg(), Immediate(kSmiTagMask)); |
6009 deferred->Branch(not_zero); | 6061 deferred->Branch(not_zero); |
6010 } | 6062 } |
6011 | 6063 |
6012 // Check that the key is a non-negative smi. | 6064 // Check that the key is a non-negative smi. |
6013 __ testl(key.reg(), | 6065 __ testl(key.reg(), |
6014 Immediate(static_cast<uint32_t>(kSmiTagMask | 0x80000000U))); | 6066 Immediate(static_cast<uint32_t>(kSmiTagMask | 0x80000000U))); |
6015 deferred->Branch(not_zero); | 6067 deferred->Branch(not_zero); |
| 6068 // Ensure that the smi is zero-extended. This is not guaranteed. |
| 6069 __ movl(key.reg(), key.reg()); |
6016 | 6070 |
6017 // Check that the receiver is not a smi. | 6071 // Check that the receiver is not a smi. |
6018 __ testl(receiver.reg(), Immediate(kSmiTagMask)); | 6072 __ testl(receiver.reg(), Immediate(kSmiTagMask)); |
6019 deferred->Branch(zero); | 6073 deferred->Branch(zero); |
6020 | 6074 |
6021 // Check that the receiver is a JSArray. | 6075 // Check that the receiver is a JSArray. |
6022 __ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, kScratchRegister); | 6076 __ CmpObjectType(receiver.reg(), JS_ARRAY_TYPE, kScratchRegister); |
6023 deferred->Branch(not_equal); | 6077 deferred->Branch(not_equal); |
6024 | 6078 |
6025 // Check that the key is within bounds. Both the key and the | 6079 // Check that the key is within bounds. Both the key and the |
(...skipping 1139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7165 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); | 7219 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); |
7166 __ bind(&done_load_1); | 7220 __ bind(&done_load_1); |
7167 | 7221 |
7168 __ movq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); | 7222 __ movq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); |
7169 __ testl(kScratchRegister, Immediate(kSmiTagMask)); | 7223 __ testl(kScratchRegister, Immediate(kSmiTagMask)); |
7170 __ j(zero, &load_smi_2); | 7224 __ j(zero, &load_smi_2); |
7171 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); | 7225 __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); |
7172 __ jmp(&done); | 7226 __ jmp(&done); |
7173 | 7227 |
7174 __ bind(&load_smi_1); | 7228 __ bind(&load_smi_1); |
7175 __ sar(kScratchRegister, Immediate(kSmiTagSize)); | 7229 __ sarl(kScratchRegister, Immediate(kSmiTagSize)); |
7176 __ push(kScratchRegister); | 7230 __ push(kScratchRegister); |
7177 __ fild_s(Operand(rsp, 0)); | 7231 __ fild_s(Operand(rsp, 0)); |
7178 __ pop(kScratchRegister); | 7232 __ pop(kScratchRegister); |
7179 __ jmp(&done_load_1); | 7233 __ jmp(&done_load_1); |
7180 | 7234 |
7181 __ bind(&load_smi_2); | 7235 __ bind(&load_smi_2); |
7182 __ sar(kScratchRegister, Immediate(kSmiTagSize)); | 7236 __ sarl(kScratchRegister, Immediate(kSmiTagSize)); |
7183 __ push(kScratchRegister); | 7237 __ push(kScratchRegister); |
7184 __ fild_s(Operand(rsp, 0)); | 7238 __ fild_s(Operand(rsp, 0)); |
7185 __ pop(kScratchRegister); | 7239 __ pop(kScratchRegister); |
7186 | 7240 |
7187 __ bind(&done); | 7241 __ bind(&done); |
7188 } | 7242 } |
7189 | 7243 |
7190 | 7244 |
7191 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm, | 7245 void FloatingPointHelper::LoadFloatOperands(MacroAssembler* masm, |
7192 Register lhs, | 7246 Register lhs, |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7527 if (op_ == Token::SHR) { | 7581 if (op_ == Token::SHR) { |
7528 // Check if result is non-negative and fits in a smi. | 7582 // Check if result is non-negative and fits in a smi. |
7529 __ testl(rax, Immediate(0xc0000000)); | 7583 __ testl(rax, Immediate(0xc0000000)); |
7530 __ j(not_zero, &non_smi_result); | 7584 __ j(not_zero, &non_smi_result); |
7531 } else { | 7585 } else { |
7532 // Check if result fits in a smi. | 7586 // Check if result fits in a smi. |
7533 __ cmpl(rax, Immediate(0xc0000000)); | 7587 __ cmpl(rax, Immediate(0xc0000000)); |
7534 __ j(negative, &non_smi_result); | 7588 __ j(negative, &non_smi_result); |
7535 } | 7589 } |
7536 // Tag smi result and return. | 7590 // Tag smi result and return. |
7537 ASSERT(kSmiTagSize == times_2); // adjust code if not the case | 7591 ASSERT(kSmiTagSize == 1); // adjust code if not the case |
7538 __ lea(rax, Operand(rax, rax, times_1, kSmiTag)); | 7592 __ lea(rax, Operand(rax, rax, times_1, kSmiTag)); |
7539 __ ret(2 * kPointerSize); | 7593 __ ret(2 * kPointerSize); |
7540 | 7594 |
7541 // All ops except SHR return a signed int32 that we load in a HeapNumber. | 7595 // All ops except SHR return a signed int32 that we load in a HeapNumber. |
7542 if (op_ != Token::SHR) { | 7596 if (op_ != Token::SHR) { |
7543 __ bind(&non_smi_result); | 7597 __ bind(&non_smi_result); |
7544 // Allocate a heap number if needed. | 7598 // Allocate a heap number if needed. |
7545 __ movsxlq(rbx, rax); // rbx: sign extended 32-bit result | 7599 __ movsxlq(rbx, rax); // rbx: sign extended 32-bit result |
7546 switch (mode_) { | 7600 switch (mode_) { |
7547 case OVERWRITE_LEFT: | 7601 case OVERWRITE_LEFT: |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7640 int CompareStub::MinorKey() { | 7694 int CompareStub::MinorKey() { |
7641 // Encode the two parameters in a unique 16 bit value. | 7695 // Encode the two parameters in a unique 16 bit value. |
7642 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 7696 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
7643 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 7697 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
7644 } | 7698 } |
7645 | 7699 |
7646 | 7700 |
7647 #undef __ | 7701 #undef __ |
7648 | 7702 |
7649 } } // namespace v8::internal | 7703 } } // namespace v8::internal |
OLD | NEW |