| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 frame_->Pop(eax); | 1088 frame_->Pop(eax); |
| 1089 __ test(eax, Immediate(kSmiTagMask)); | 1089 __ test(eax, Immediate(kSmiTagMask)); |
| 1090 __ mov(ebx, Operand(eax)); | 1090 __ mov(ebx, Operand(eax)); |
| 1091 __ j(not_zero, deferred->enter(), not_taken); | 1091 __ j(not_zero, deferred->enter(), not_taken); |
| 1092 __ sar(ebx, kSmiTagSize); | 1092 __ sar(ebx, kSmiTagSize); |
| 1093 __ shr(ebx, shift_value); | 1093 __ shr(ebx, shift_value); |
| 1094 __ test(ebx, Immediate(0xc0000000)); | 1094 __ test(ebx, Immediate(0xc0000000)); |
| 1095 __ j(not_zero, deferred->enter(), not_taken); | 1095 __ j(not_zero, deferred->enter(), not_taken); |
| 1096 // tag result and store it in TOS (eax) | 1096 // tag result and store it in TOS (eax) |
| 1097 ASSERT(kSmiTagSize == times_2); // adjust code if not the case | 1097 ASSERT(kSmiTagSize == times_2); // adjust code if not the case |
| 1098 __ lea(eax, Operand(ebx, times_2, kSmiTag)); | 1098 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag)); |
| 1099 __ bind(deferred->exit()); | 1099 __ bind(deferred->exit()); |
| 1100 frame_->Push(eax); | 1100 frame_->Push(eax); |
| 1101 } | 1101 } |
| 1102 break; | 1102 break; |
| 1103 } | 1103 } |
| 1104 | 1104 |
| 1105 case Token::SHL: { | 1105 case Token::SHL: { |
| 1106 if (reversed) { | 1106 if (reversed) { |
| 1107 frame_->Pop(eax); | 1107 frame_->Pop(eax); |
| 1108 frame_->Push(Immediate(value)); | 1108 frame_->Push(Immediate(value)); |
| 1109 frame_->Push(eax); | 1109 frame_->Push(eax); |
| 1110 GenericBinaryOperation(op, type, overwrite_mode); | 1110 GenericBinaryOperation(op, type, overwrite_mode); |
| 1111 } else { | 1111 } else { |
| 1112 int shift_value = int_value & 0x1f; // only least significant 5 bits | 1112 int shift_value = int_value & 0x1f; // only least significant 5 bits |
| 1113 DeferredCode* deferred = | 1113 DeferredCode* deferred = |
| 1114 new DeferredInlinedSmiOperation(this, Token::SHL, shift_value, | 1114 new DeferredInlinedSmiOperation(this, Token::SHL, shift_value, |
| 1115 overwrite_mode); | 1115 overwrite_mode); |
| 1116 frame_->Pop(eax); | 1116 frame_->Pop(eax); |
| 1117 __ test(eax, Immediate(kSmiTagMask)); | 1117 __ test(eax, Immediate(kSmiTagMask)); |
| 1118 __ mov(ebx, Operand(eax)); | 1118 __ mov(ebx, Operand(eax)); |
| 1119 __ j(not_zero, deferred->enter(), not_taken); | 1119 __ j(not_zero, deferred->enter(), not_taken); |
| 1120 __ sar(ebx, kSmiTagSize); | 1120 __ sar(ebx, kSmiTagSize); |
| 1121 __ shl(ebx, shift_value); | 1121 __ shl(ebx, shift_value); |
| 1122 __ lea(ecx, Operand(ebx, 0x40000000)); | 1122 __ lea(ecx, Operand(ebx, 0x40000000)); |
| 1123 __ test(ecx, Immediate(0x80000000)); | 1123 __ test(ecx, Immediate(0x80000000)); |
| 1124 __ j(not_zero, deferred->enter(), not_taken); | 1124 __ j(not_zero, deferred->enter(), not_taken); |
| 1125 // tag result and store it in TOS (eax) | 1125 // tag result and store it in TOS (eax) |
| 1126 ASSERT(kSmiTagSize == times_2); // adjust code if not the case | 1126 ASSERT(kSmiTagSize == times_2); // adjust code if not the case |
| 1127 __ lea(eax, Operand(ebx, times_2, kSmiTag)); | 1127 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag)); |
| 1128 __ bind(deferred->exit()); | 1128 __ bind(deferred->exit()); |
| 1129 frame_->Push(eax); | 1129 frame_->Push(eax); |
| 1130 } | 1130 } |
| 1131 break; | 1131 break; |
| 1132 } | 1132 } |
| 1133 | 1133 |
| 1134 case Token::BIT_OR: | 1134 case Token::BIT_OR: |
| 1135 case Token::BIT_XOR: | 1135 case Token::BIT_XOR: |
| 1136 case Token::BIT_AND: { | 1136 case Token::BIT_AND: { |
| 1137 DeferredCode* deferred = NULL; | 1137 DeferredCode* deferred = NULL; |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1644 | 1644 |
| 1645 if (min_index != 0) { | 1645 if (min_index != 0) { |
| 1646 __ sub(Operand(eax), Immediate(min_index << kSmiTagSize)); | 1646 __ sub(Operand(eax), Immediate(min_index << kSmiTagSize)); |
| 1647 } | 1647 } |
| 1648 __ test(eax, Immediate(0x80000000 | kSmiTagMask)); // negative or not Smi | 1648 __ test(eax, Immediate(0x80000000 | kSmiTagMask)); // negative or not Smi |
| 1649 __ j(not_equal, fail_label, not_taken); | 1649 __ j(not_equal, fail_label, not_taken); |
| 1650 __ cmp(eax, range << kSmiTagSize); | 1650 __ cmp(eax, range << kSmiTagSize); |
| 1651 __ j(greater_equal, fail_label, not_taken); | 1651 __ j(greater_equal, fail_label, not_taken); |
| 1652 | 1652 |
| 1653 // 0 is placeholder. | 1653 // 0 is placeholder. |
| 1654 __ jmp(Operand(eax, times_2, 0x0, RelocInfo::INTERNAL_REFERENCE)); | 1654 __ jmp(Operand(eax, eax, times_1, 0x0, RelocInfo::INTERNAL_REFERENCE)); |
| 1655 // calculate address to overwrite later with actual address of table. | 1655 // calculate address to overwrite later with actual address of table. |
| 1656 int32_t jump_table_ref = __ pc_offset() - sizeof(int32_t); | 1656 int32_t jump_table_ref = __ pc_offset() - sizeof(int32_t); |
| 1657 | 1657 |
| 1658 __ Align(4); | 1658 __ Align(4); |
| 1659 Label table_start; | 1659 Label table_start; |
| 1660 __ bind(&table_start); | 1660 __ bind(&table_start); |
| 1661 __ WriteInternalReference(jump_table_ref, table_start); | 1661 __ WriteInternalReference(jump_table_ref, table_start); |
| 1662 | 1662 |
| 1663 for (int i = 0; i < range; i++) { | 1663 for (int i = 0; i < range; i++) { |
| 1664 // table entry, 0 is placeholder for case address | 1664 // table entry, 0 is placeholder for case address |
| (...skipping 2390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4055 ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | 4055 ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
| 4056 __ cmp(eax, 0x40000000); | 4056 __ cmp(eax, 0x40000000); |
| 4057 __ j(equal, slow); | 4057 __ j(equal, slow); |
| 4058 // Check for negative zero result. | 4058 // Check for negative zero result. |
| 4059 __ NegativeZeroTest(eax, ecx, slow); // use ecx = x | y | 4059 __ NegativeZeroTest(eax, ecx, slow); // use ecx = x | y |
| 4060 // Check that the remainder is zero. | 4060 // Check that the remainder is zero. |
| 4061 __ test(edx, Operand(edx)); | 4061 __ test(edx, Operand(edx)); |
| 4062 __ j(not_zero, slow); | 4062 __ j(not_zero, slow); |
| 4063 // Tag the result and store it in register eax. | 4063 // Tag the result and store it in register eax. |
| 4064 ASSERT(kSmiTagSize == times_2); // adjust code if not the case | 4064 ASSERT(kSmiTagSize == times_2); // adjust code if not the case |
| 4065 __ lea(eax, Operand(eax, times_2, kSmiTag)); | 4065 __ lea(eax, Operand(eax, eax, times_1, kSmiTag)); |
| 4066 break; | 4066 break; |
| 4067 | 4067 |
| 4068 case Token::MOD: | 4068 case Token::MOD: |
| 4069 // Divide edx:eax by ebx. | 4069 // Divide edx:eax by ebx. |
| 4070 __ idiv(ebx); | 4070 __ idiv(ebx); |
| 4071 // Check for negative zero result. | 4071 // Check for negative zero result. |
| 4072 __ NegativeZeroTest(edx, ecx, slow); // use ecx = x | y | 4072 __ NegativeZeroTest(edx, ecx, slow); // use ecx = x | y |
| 4073 // Move remainder to register eax. | 4073 // Move remainder to register eax. |
| 4074 __ mov(eax, Operand(edx)); | 4074 __ mov(eax, Operand(edx)); |
| 4075 break; | 4075 break; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4116 // Check that the *signed* result fits in a smi. | 4116 // Check that the *signed* result fits in a smi. |
| 4117 __ lea(ecx, Operand(eax, 0x40000000)); | 4117 __ lea(ecx, Operand(eax, 0x40000000)); |
| 4118 __ test(ecx, Immediate(0x80000000)); | 4118 __ test(ecx, Immediate(0x80000000)); |
| 4119 __ j(not_zero, slow, not_taken); | 4119 __ j(not_zero, slow, not_taken); |
| 4120 break; | 4120 break; |
| 4121 default: | 4121 default: |
| 4122 UNREACHABLE(); | 4122 UNREACHABLE(); |
| 4123 } | 4123 } |
| 4124 // Tag the result and store it in register eax. | 4124 // Tag the result and store it in register eax. |
| 4125 ASSERT(kSmiTagSize == times_2); // adjust code if not the case | 4125 ASSERT(kSmiTagSize == times_2); // adjust code if not the case |
| 4126 __ lea(eax, Operand(eax, times_2, kSmiTag)); | 4126 __ lea(eax, Operand(eax, eax, times_1, kSmiTag)); |
| 4127 break; | 4127 break; |
| 4128 | 4128 |
| 4129 default: | 4129 default: |
| 4130 UNREACHABLE(); | 4130 UNREACHABLE(); |
| 4131 break; | 4131 break; |
| 4132 } | 4132 } |
| 4133 } | 4133 } |
| 4134 | 4134 |
| 4135 | 4135 |
| 4136 void GenericBinaryOpStub::Generate(MacroAssembler* masm) { | 4136 void GenericBinaryOpStub::Generate(MacroAssembler* masm) { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4243 case Token::SHR: __ shr(eax); break; | 4243 case Token::SHR: __ shr(eax); break; |
| 4244 default: UNREACHABLE(); | 4244 default: UNREACHABLE(); |
| 4245 } | 4245 } |
| 4246 | 4246 |
| 4247 // Check if result is non-negative and fits in a smi. | 4247 // Check if result is non-negative and fits in a smi. |
| 4248 __ test(eax, Immediate(0xc0000000)); | 4248 __ test(eax, Immediate(0xc0000000)); |
| 4249 __ j(not_zero, &non_smi_result); | 4249 __ j(not_zero, &non_smi_result); |
| 4250 | 4250 |
| 4251 // Tag smi result and return. | 4251 // Tag smi result and return. |
| 4252 ASSERT(kSmiTagSize == times_2); // adjust code if not the case | 4252 ASSERT(kSmiTagSize == times_2); // adjust code if not the case |
| 4253 __ lea(eax, Operand(eax, times_2, kSmiTag)); | 4253 __ lea(eax, Operand(eax, eax, times_1, kSmiTag)); |
| 4254 __ ret(2 * kPointerSize); | 4254 __ ret(2 * kPointerSize); |
| 4255 | 4255 |
| 4256 // All ops except SHR return a signed int32 that we load in a HeapNumber. | 4256 // All ops except SHR return a signed int32 that we load in a HeapNumber. |
| 4257 if (op_ != Token::SHR) { | 4257 if (op_ != Token::SHR) { |
| 4258 __ bind(&non_smi_result); | 4258 __ bind(&non_smi_result); |
| 4259 // Allocate a heap number if needed. | 4259 // Allocate a heap number if needed. |
| 4260 __ mov(ebx, Operand(eax)); // ebx: result | 4260 __ mov(ebx, Operand(eax)); // ebx: result |
| 4261 switch (mode_) { | 4261 switch (mode_) { |
| 4262 case OVERWRITE_LEFT: | 4262 case OVERWRITE_LEFT: |
| 4263 case OVERWRITE_RIGHT: | 4263 case OVERWRITE_RIGHT: |
| (...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5149 | 5149 |
| 5150 // Slow-case: Go through the JavaScript implementation. | 5150 // Slow-case: Go through the JavaScript implementation. |
| 5151 __ bind(&slow); | 5151 __ bind(&slow); |
| 5152 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5152 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 5153 } | 5153 } |
| 5154 | 5154 |
| 5155 | 5155 |
| 5156 #undef __ | 5156 #undef __ |
| 5157 | 5157 |
| 5158 } } // namespace v8::internal | 5158 } } // namespace v8::internal |
| OLD | NEW |