OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 __ Subu(result_reg, zero_reg, input_high); | 265 __ Subu(result_reg, zero_reg, input_high); |
266 __ Movz(result_reg, input_high, scratch); | 266 __ Movz(result_reg, input_high, scratch); |
267 | 267 |
268 __ bind(&done); | 268 __ bind(&done); |
269 | 269 |
270 __ Pop(scratch, scratch2, scratch3); | 270 __ Pop(scratch, scratch2, scratch3); |
271 __ Ret(); | 271 __ Ret(); |
272 } | 272 } |
273 | 273 |
274 | 274 |
275 void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime( | |
276 Isolate* isolate) { | |
277 WriteInt32ToHeapNumberStub stub1(isolate, a1, v0, a2, a3); | |
278 WriteInt32ToHeapNumberStub stub2(isolate, a2, v0, a3, a0); | |
279 stub1.GetCode(); | |
280 stub2.GetCode(); | |
281 } | |
282 | |
283 | |
284 // See comment for class, this does NOT work for int32's that are in Smi range. | |
285 void WriteInt32ToHeapNumberStub::Generate(MacroAssembler* masm) { | |
286 Label max_negative_int; | |
287 // the_int_ has the answer which is a signed int32 but not a Smi. | |
288 // We test for the special value that has a different exponent. | |
289 STATIC_ASSERT(HeapNumber::kSignMask == 0x80000000u); | |
290 // Test sign, and save for later conditionals. | |
291 __ And(sign(), the_int(), Operand(0x80000000u)); | |
292 __ Branch(&max_negative_int, eq, the_int(), Operand(0x80000000u)); | |
293 | |
294 // Set up the correct exponent in scratch_. All non-Smi int32s have the same. | |
295 // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased). | |
296 uint32_t non_smi_exponent = | |
297 (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift; | |
298 __ li(scratch(), Operand(non_smi_exponent)); | |
299 // Set the sign bit in scratch_ if the value was negative. | |
300 __ or_(scratch(), scratch(), sign()); | |
301 // Subtract from 0 if the value was negative. | |
302 __ subu(at, zero_reg, the_int()); | |
303 __ Movn(the_int(), at, sign()); | |
304 // We should be masking the implict first digit of the mantissa away here, | |
305 // but it just ends up combining harmlessly with the last digit of the | |
306 // exponent that happens to be 1. The sign bit is 0 so we shift 10 to get | |
307 // the most significant 1 to hit the last bit of the 12 bit sign and exponent. | |
308 DCHECK(((1 << HeapNumber::kExponentShift) & non_smi_exponent) != 0); | |
309 const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2; | |
310 __ srl(at, the_int(), shift_distance); | |
311 __ or_(scratch(), scratch(), at); | |
312 __ sw(scratch(), FieldMemOperand(the_heap_number(), | |
313 HeapNumber::kExponentOffset)); | |
314 __ sll(scratch(), the_int(), 32 - shift_distance); | |
315 __ Ret(USE_DELAY_SLOT); | |
316 __ sw(scratch(), FieldMemOperand(the_heap_number(), | |
317 HeapNumber::kMantissaOffset)); | |
318 | |
319 __ bind(&max_negative_int); | |
320 // The max negative int32 is stored as a positive number in the mantissa of | |
321 // a double because it uses a sign bit instead of using two's complement. | |
322 // The actual mantissa bits stored are all 0 because the implicit most | |
323 // significant 1 bit is not stored. | |
324 non_smi_exponent += 1 << HeapNumber::kExponentShift; | |
325 __ li(scratch(), Operand(HeapNumber::kSignMask | non_smi_exponent)); | |
326 __ sw(scratch(), | |
327 FieldMemOperand(the_heap_number(), HeapNumber::kExponentOffset)); | |
328 __ mov(scratch(), zero_reg); | |
329 __ Ret(USE_DELAY_SLOT); | |
330 __ sw(scratch(), | |
331 FieldMemOperand(the_heap_number(), HeapNumber::kMantissaOffset)); | |
332 } | |
333 | |
334 | |
335 // Handle the case where the lhs and rhs are the same object. | 275 // Handle the case where the lhs and rhs are the same object. |
336 // Equality is almost reflexive (everything but NaN), so this is a test | 276 // Equality is almost reflexive (everything but NaN), so this is a test |
337 // for "identity and not NaN". | 277 // for "identity and not NaN". |
338 static void EmitIdenticalObjectComparison(MacroAssembler* masm, | 278 static void EmitIdenticalObjectComparison(MacroAssembler* masm, |
339 Label* slow, | 279 Label* slow, |
340 Condition cc) { | 280 Condition cc) { |
341 Label not_identical; | 281 Label not_identical; |
342 Label heap_number, return_equal; | 282 Label heap_number, return_equal; |
343 Register exp_mask_reg = t5; | 283 Register exp_mask_reg = t5; |
344 | 284 |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1051 } | 991 } |
1052 | 992 |
1053 | 993 |
1054 bool CEntryStub::NeedsImmovableCode() { | 994 bool CEntryStub::NeedsImmovableCode() { |
1055 return true; | 995 return true; |
1056 } | 996 } |
1057 | 997 |
1058 | 998 |
1059 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { | 999 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { |
1060 CEntryStub::GenerateAheadOfTime(isolate); | 1000 CEntryStub::GenerateAheadOfTime(isolate); |
1061 WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate); | |
1062 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); | 1001 StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate); |
1063 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); | 1002 StubFailureTrampolineStub::GenerateAheadOfTime(isolate); |
1064 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); | 1003 ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); |
1065 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); | 1004 CreateAllocationSiteStub::GenerateAheadOfTime(isolate); |
1066 BinaryOpICStub::GenerateAheadOfTime(isolate); | 1005 BinaryOpICStub::GenerateAheadOfTime(isolate); |
1067 StoreRegistersStateStub::GenerateAheadOfTime(isolate); | 1006 StoreRegistersStateStub::GenerateAheadOfTime(isolate); |
1068 RestoreRegistersStateStub::GenerateAheadOfTime(isolate); | 1007 RestoreRegistersStateStub::GenerateAheadOfTime(isolate); |
1069 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate); | 1008 BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate); |
1070 } | 1009 } |
1071 | 1010 |
(...skipping 3921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4993 MemOperand(fp, 6 * kPointerSize), | 4932 MemOperand(fp, 6 * kPointerSize), |
4994 NULL); | 4933 NULL); |
4995 } | 4934 } |
4996 | 4935 |
4997 | 4936 |
4998 #undef __ | 4937 #undef __ |
4999 | 4938 |
5000 } } // namespace v8::internal | 4939 } } // namespace v8::internal |
5001 | 4940 |
5002 #endif // V8_TARGET_ARCH_MIPS | 4941 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |