OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 vmov(dst, src); | 297 vmov(dst, src); |
298 } | 298 } |
299 } | 299 } |
300 | 300 |
301 | 301 |
302 void MacroAssembler::And(Register dst, Register src1, const Operand& src2, | 302 void MacroAssembler::And(Register dst, Register src1, const Operand& src2, |
303 Condition cond) { | 303 Condition cond) { |
304 if (!src2.is_reg() && | 304 if (!src2.is_reg() && |
305 !src2.must_output_reloc_info(this) && | 305 !src2.must_output_reloc_info(this) && |
306 src2.immediate() == 0) { | 306 src2.immediate() == 0) { |
307 mov(dst, Operand(0, RelocInfo::NONE), LeaveCC, cond); | 307 mov(dst, Operand(0, RelocInfo::NONE32), LeaveCC, cond); |
308 } else if (!src2.is_single_instruction(this) && | 308 } else if (!src2.is_single_instruction(this) && |
309 !src2.must_output_reloc_info(this) && | 309 !src2.must_output_reloc_info(this) && |
310 CpuFeatures::IsSupported(ARMv7) && | 310 CpuFeatures::IsSupported(ARMv7) && |
311 IsPowerOf2(src2.immediate() + 1)) { | 311 IsPowerOf2(src2.immediate() + 1)) { |
312 ubfx(dst, src1, 0, | 312 ubfx(dst, src1, 0, |
313 WhichPowerOf2(static_cast<uint32_t>(src2.immediate()) + 1), cond); | 313 WhichPowerOf2(static_cast<uint32_t>(src2.immediate()) + 1), cond); |
314 } else { | 314 } else { |
315 and_(dst, src1, src2, LeaveCC, cond); | 315 and_(dst, src1, src2, LeaveCC, cond); |
316 } | 316 } |
317 } | 317 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 int satval = (1 << satpos) - 1; | 403 int satval = (1 << satpos) - 1; |
404 | 404 |
405 if (cond != al) { | 405 if (cond != al) { |
406 b(NegateCondition(cond), &done); // Skip saturate if !condition. | 406 b(NegateCondition(cond), &done); // Skip saturate if !condition. |
407 } | 407 } |
408 if (!(src.is_reg() && dst.is(src.rm()))) { | 408 if (!(src.is_reg() && dst.is(src.rm()))) { |
409 mov(dst, src); | 409 mov(dst, src); |
410 } | 410 } |
411 tst(dst, Operand(~satval)); | 411 tst(dst, Operand(~satval)); |
412 b(eq, &done); | 412 b(eq, &done); |
413 mov(dst, Operand(0, RelocInfo::NONE), LeaveCC, mi); // 0 if negative. | 413 mov(dst, Operand(0, RelocInfo::NONE32), LeaveCC, mi); // 0 if negative. |
414 mov(dst, Operand(satval), LeaveCC, pl); // satval if positive. | 414 mov(dst, Operand(satval), LeaveCC, pl); // satval if positive. |
415 bind(&done); | 415 bind(&done); |
416 } else { | 416 } else { |
417 usat(dst, satpos, src, cond); | 417 usat(dst, satpos, src, cond); |
418 } | 418 } |
419 } | 419 } |
420 | 420 |
421 | 421 |
422 void MacroAssembler::LoadRoot(Register destination, | 422 void MacroAssembler::LoadRoot(Register destination, |
423 Heap::RootListIndex index, | 423 Heap::RootListIndex index, |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
941 // Calculate the stack location of the saved doubles and restore them. | 941 // Calculate the stack location of the saved doubles and restore them. |
942 const int offset = 2 * kPointerSize; | 942 const int offset = 2 * kPointerSize; |
943 sub(r3, fp, Operand(offset + DwVfpRegister::kNumRegisters * kDoubleSize)); | 943 sub(r3, fp, Operand(offset + DwVfpRegister::kNumRegisters * kDoubleSize)); |
944 DwVfpRegister first = d0; | 944 DwVfpRegister first = d0; |
945 DwVfpRegister last = | 945 DwVfpRegister last = |
946 DwVfpRegister::from_code(DwVfpRegister::kNumRegisters - 1); | 946 DwVfpRegister::from_code(DwVfpRegister::kNumRegisters - 1); |
947 vldm(ia, r3, first, last); | 947 vldm(ia, r3, first, last); |
948 } | 948 } |
949 | 949 |
950 // Clear top frame. | 950 // Clear top frame. |
951 mov(r3, Operand(0, RelocInfo::NONE)); | 951 mov(r3, Operand(0, RelocInfo::NONE32)); |
952 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 952 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
953 str(r3, MemOperand(ip)); | 953 str(r3, MemOperand(ip)); |
954 | 954 |
955 // Restore current context from top and clear it in debug mode. | 955 // Restore current context from top and clear it in debug mode. |
956 mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); | 956 mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
957 ldr(cp, MemOperand(ip)); | 957 ldr(cp, MemOperand(ip)); |
958 #ifdef DEBUG | 958 #ifdef DEBUG |
959 str(r3, MemOperand(ip)); | 959 str(r3, MemOperand(ip)); |
960 #endif | 960 #endif |
961 | 961 |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 | 1211 |
1212 ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); | 1212 ldr(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
1213 ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); | 1213 ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); |
1214 tst(scratch, Operand(kIsNotStringMask)); | 1214 tst(scratch, Operand(kIsNotStringMask)); |
1215 b(ne, fail); | 1215 b(ne, fail); |
1216 } | 1216 } |
1217 | 1217 |
1218 | 1218 |
1219 #ifdef ENABLE_DEBUGGER_SUPPORT | 1219 #ifdef ENABLE_DEBUGGER_SUPPORT |
1220 void MacroAssembler::DebugBreak() { | 1220 void MacroAssembler::DebugBreak() { |
1221 mov(r0, Operand(0, RelocInfo::NONE)); | 1221 mov(r0, Operand(0, RelocInfo::NONE32)); |
1222 mov(r1, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); | 1222 mov(r1, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); |
1223 CEntryStub ces(1); | 1223 CEntryStub ces(1); |
1224 ASSERT(AllowThisStubCall(&ces)); | 1224 ASSERT(AllowThisStubCall(&ces)); |
1225 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 1225 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
1226 } | 1226 } |
1227 #endif | 1227 #endif |
1228 | 1228 |
1229 | 1229 |
1230 void MacroAssembler::PushTryHandler(StackHandler::Kind kind, | 1230 void MacroAssembler::PushTryHandler(StackHandler::Kind kind, |
1231 int handler_index) { | 1231 int handler_index) { |
(...skipping 10 matching lines...) Expand all Loading... |
1242 // Set up the code object (r5) and the state (r6) for pushing. | 1242 // Set up the code object (r5) and the state (r6) for pushing. |
1243 unsigned state = | 1243 unsigned state = |
1244 StackHandler::IndexField::encode(handler_index) | | 1244 StackHandler::IndexField::encode(handler_index) | |
1245 StackHandler::KindField::encode(kind); | 1245 StackHandler::KindField::encode(kind); |
1246 mov(r5, Operand(CodeObject())); | 1246 mov(r5, Operand(CodeObject())); |
1247 mov(r6, Operand(state)); | 1247 mov(r6, Operand(state)); |
1248 | 1248 |
1249 // Push the frame pointer, context, state, and code object. | 1249 // Push the frame pointer, context, state, and code object. |
1250 if (kind == StackHandler::JS_ENTRY) { | 1250 if (kind == StackHandler::JS_ENTRY) { |
1251 mov(r7, Operand(Smi::FromInt(0))); // Indicates no context. | 1251 mov(r7, Operand(Smi::FromInt(0))); // Indicates no context. |
1252 mov(ip, Operand(0, RelocInfo::NONE)); // NULL frame pointer. | 1252 mov(ip, Operand(0, RelocInfo::NONE32)); // NULL frame pointer. |
1253 stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | ip.bit()); | 1253 stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | ip.bit()); |
1254 } else { | 1254 } else { |
1255 stm(db_w, sp, r5.bit() | r6.bit() | cp.bit() | fp.bit()); | 1255 stm(db_w, sp, r5.bit() | r6.bit() | cp.bit() | fp.bit()); |
1256 } | 1256 } |
1257 | 1257 |
1258 // Link the current handler as the next handler. | 1258 // Link the current handler as the next handler. |
1259 mov(r6, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); | 1259 mov(r6, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); |
1260 ldr(r5, MemOperand(r6)); | 1260 ldr(r5, MemOperand(r6)); |
1261 push(r5); | 1261 push(r5); |
1262 // Set this new handler as the current one. | 1262 // Set this new handler as the current one. |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1366 Label same_contexts; | 1366 Label same_contexts; |
1367 | 1367 |
1368 ASSERT(!holder_reg.is(scratch)); | 1368 ASSERT(!holder_reg.is(scratch)); |
1369 ASSERT(!holder_reg.is(ip)); | 1369 ASSERT(!holder_reg.is(ip)); |
1370 ASSERT(!scratch.is(ip)); | 1370 ASSERT(!scratch.is(ip)); |
1371 | 1371 |
1372 // Load current lexical context from the stack frame. | 1372 // Load current lexical context from the stack frame. |
1373 ldr(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1373 ldr(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
1374 // In debug mode, make sure the lexical context is set. | 1374 // In debug mode, make sure the lexical context is set. |
1375 #ifdef DEBUG | 1375 #ifdef DEBUG |
1376 cmp(scratch, Operand(0, RelocInfo::NONE)); | 1376 cmp(scratch, Operand(0, RelocInfo::NONE32)); |
1377 Check(ne, "we should not have an empty lexical context"); | 1377 Check(ne, "we should not have an empty lexical context"); |
1378 #endif | 1378 #endif |
1379 | 1379 |
1380 // Load the native context of the current context. | 1380 // Load the native context of the current context. |
1381 int offset = | 1381 int offset = |
1382 Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; | 1382 Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; |
1383 ldr(scratch, FieldMemOperand(scratch, offset)); | 1383 ldr(scratch, FieldMemOperand(scratch, offset)); |
1384 ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); | 1384 ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); |
1385 | 1385 |
1386 // Check the context is a native context. | 1386 // Check the context is a native context. |
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2449 Label right_exponent, done; | 2449 Label right_exponent, done; |
2450 // Get exponent word. | 2450 // Get exponent word. |
2451 ldr(scratch, FieldMemOperand(source, HeapNumber::kExponentOffset)); | 2451 ldr(scratch, FieldMemOperand(source, HeapNumber::kExponentOffset)); |
2452 // Get exponent alone in scratch2. | 2452 // Get exponent alone in scratch2. |
2453 Ubfx(scratch2, | 2453 Ubfx(scratch2, |
2454 scratch, | 2454 scratch, |
2455 HeapNumber::kExponentShift, | 2455 HeapNumber::kExponentShift, |
2456 HeapNumber::kExponentBits); | 2456 HeapNumber::kExponentBits); |
2457 // Load dest with zero. We use this either for the final shift or | 2457 // Load dest with zero. We use this either for the final shift or |
2458 // for the answer. | 2458 // for the answer. |
2459 mov(dest, Operand(0, RelocInfo::NONE)); | 2459 mov(dest, Operand(0, RelocInfo::NONE32)); |
2460 // Check whether the exponent matches a 32 bit signed int that is not a Smi. | 2460 // Check whether the exponent matches a 32 bit signed int that is not a Smi. |
2461 // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased). This is | 2461 // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased). This is |
2462 // the exponent that we are fastest at and also the highest exponent we can | 2462 // the exponent that we are fastest at and also the highest exponent we can |
2463 // handle here. | 2463 // handle here. |
2464 const uint32_t non_smi_exponent = HeapNumber::kExponentBias + 30; | 2464 const uint32_t non_smi_exponent = HeapNumber::kExponentBias + 30; |
2465 // The non_smi_exponent, 0x41d, is too big for ARM's immediate field so we | 2465 // The non_smi_exponent, 0x41d, is too big for ARM's immediate field so we |
2466 // split it up to avoid a constant pool entry. You can't do that in general | 2466 // split it up to avoid a constant pool entry. You can't do that in general |
2467 // for cmp because of the overflow flag, but we know the exponent is in the | 2467 // for cmp because of the overflow flag, but we know the exponent is in the |
2468 // range 0-2047 so there is no overflow. | 2468 // range 0-2047 so there is no overflow. |
2469 int fudge_factor = 0x400; | 2469 int fudge_factor = 0x400; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2503 tst(scratch, Operand(HeapNumber::kSignMask)); | 2503 tst(scratch, Operand(HeapNumber::kSignMask)); |
2504 // Get the second half of the double. For some exponents we don't | 2504 // Get the second half of the double. For some exponents we don't |
2505 // actually need this because the bits get shifted out again, but | 2505 // actually need this because the bits get shifted out again, but |
2506 // it's probably slower to test than just to do it. | 2506 // it's probably slower to test than just to do it. |
2507 ldr(scratch, FieldMemOperand(source, HeapNumber::kMantissaOffset)); | 2507 ldr(scratch, FieldMemOperand(source, HeapNumber::kMantissaOffset)); |
2508 // Shift down 22 bits to get the last 10 bits. | 2508 // Shift down 22 bits to get the last 10 bits. |
2509 orr(scratch, scratch2, Operand(scratch, LSR, 32 - shift_distance)); | 2509 orr(scratch, scratch2, Operand(scratch, LSR, 32 - shift_distance)); |
2510 // Move down according to the exponent. | 2510 // Move down according to the exponent. |
2511 mov(dest, Operand(scratch, LSR, dest)); | 2511 mov(dest, Operand(scratch, LSR, dest)); |
2512 // Fix sign if sign bit was set. | 2512 // Fix sign if sign bit was set. |
2513 rsb(dest, dest, Operand(0, RelocInfo::NONE), LeaveCC, ne); | 2513 rsb(dest, dest, Operand(0, RelocInfo::NONE32), LeaveCC, ne); |
2514 bind(&done); | 2514 bind(&done); |
2515 } | 2515 } |
2516 } | 2516 } |
2517 | 2517 |
2518 | 2518 |
2519 void MacroAssembler::TryFastDoubleToInt32(Register result, | 2519 void MacroAssembler::TryFastDoubleToInt32(Register result, |
2520 DwVfpRegister double_input, | 2520 DwVfpRegister double_input, |
2521 DwVfpRegister double_scratch, | 2521 DwVfpRegister double_scratch, |
2522 Label* done) { | 2522 Label* done) { |
2523 ASSERT(!double_input.is(double_scratch)); | 2523 ASSERT(!double_input.is(double_scratch)); |
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3361 ASSERT(!zeros.is(scratch)); | 3361 ASSERT(!zeros.is(scratch)); |
3362 ASSERT(!scratch.is(ip)); | 3362 ASSERT(!scratch.is(ip)); |
3363 ASSERT(!source.is(ip)); | 3363 ASSERT(!source.is(ip)); |
3364 ASSERT(!zeros.is(ip)); | 3364 ASSERT(!zeros.is(ip)); |
3365 #ifdef CAN_USE_ARMV5_INSTRUCTIONS | 3365 #ifdef CAN_USE_ARMV5_INSTRUCTIONS |
3366 clz(zeros, source); // This instruction is only supported after ARM5. | 3366 clz(zeros, source); // This instruction is only supported after ARM5. |
3367 #else | 3367 #else |
3368 // Order of the next two lines is important: zeros register | 3368 // Order of the next two lines is important: zeros register |
3369 // can be the same as source register. | 3369 // can be the same as source register. |
3370 Move(scratch, source); | 3370 Move(scratch, source); |
3371 mov(zeros, Operand(0, RelocInfo::NONE)); | 3371 mov(zeros, Operand(0, RelocInfo::NONE32)); |
3372 // Top 16. | 3372 // Top 16. |
3373 tst(scratch, Operand(0xffff0000)); | 3373 tst(scratch, Operand(0xffff0000)); |
3374 add(zeros, zeros, Operand(16), LeaveCC, eq); | 3374 add(zeros, zeros, Operand(16), LeaveCC, eq); |
3375 mov(scratch, Operand(scratch, LSL, 16), LeaveCC, eq); | 3375 mov(scratch, Operand(scratch, LSL, 16), LeaveCC, eq); |
3376 // Top 8. | 3376 // Top 8. |
3377 tst(scratch, Operand(0xff000000)); | 3377 tst(scratch, Operand(0xff000000)); |
3378 add(zeros, zeros, Operand(8), LeaveCC, eq); | 3378 add(zeros, zeros, Operand(8), LeaveCC, eq); |
3379 mov(scratch, Operand(scratch, LSL, 8), LeaveCC, eq); | 3379 mov(scratch, Operand(scratch, LSL, 8), LeaveCC, eq); |
3380 // Top 4. | 3380 // Top 4. |
3381 tst(scratch, Operand(0xf0000000)); | 3381 tst(scratch, Operand(0xf0000000)); |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3942 void CodePatcher::EmitCondition(Condition cond) { | 3942 void CodePatcher::EmitCondition(Condition cond) { |
3943 Instr instr = Assembler::instr_at(masm_.pc_); | 3943 Instr instr = Assembler::instr_at(masm_.pc_); |
3944 instr = (instr & ~kCondMask) | cond; | 3944 instr = (instr & ~kCondMask) | cond; |
3945 masm_.emit(instr); | 3945 masm_.emit(instr); |
3946 } | 3946 } |
3947 | 3947 |
3948 | 3948 |
3949 } } // namespace v8::internal | 3949 } } // namespace v8::internal |
3950 | 3950 |
3951 #endif // V8_TARGET_ARCH_ARM | 3951 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |