OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 | 409 |
410 // Like mul, but sets condition flags. | 410 // Like mul, but sets condition flags. |
411 void Assembler::muls(Register rd, Register rn, | 411 void Assembler::muls(Register rd, Register rn, |
412 Register rm, Condition cond) { | 412 Register rm, Condition cond) { |
413 EmitMulOp(cond, B20, R0, rd, rn, rm); | 413 EmitMulOp(cond, B20, R0, rd, rn, rm); |
414 } | 414 } |
415 | 415 |
416 | 416 |
417 void Assembler::mla(Register rd, Register rn, | 417 void Assembler::mla(Register rd, Register rn, |
418 Register rm, Register ra, Condition cond) { | 418 Register rm, Register ra, Condition cond) { |
419 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. | 419 // rd <- ra + rn * rm. |
420 EmitMulOp(cond, B21, ra, rd, rn, rm); | 420 if (TargetCPUFeatures::arm_version() == ARMv7) { |
| 421 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. |
| 422 EmitMulOp(cond, B21, ra, rd, rn, rm); |
| 423 } else { |
| 424 mul(IP, rn, rm, cond); |
| 425 add(rd, ra, ShifterOperand(IP), cond); |
| 426 } |
421 } | 427 } |
422 | 428 |
423 | 429 |
424 void Assembler::mls(Register rd, Register rn, | 430 void Assembler::mls(Register rd, Register rn, |
425 Register rm, Register ra, Condition cond) { | 431 Register rm, Register ra, Condition cond) { |
426 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. | 432 // rd <- ra - rn * rm. |
427 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); | 433 if (TargetCPUFeatures::arm_version() == ARMv7) { |
| 434 // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. |
| 435 EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); |
| 436 } else { |
| 437 mul(IP, rn, rm, cond); |
| 438 sub(rd, ra, ShifterOperand(IP), cond); |
| 439 } |
428 } | 440 } |
429 | 441 |
430 | 442 |
431 void Assembler::smull(Register rd_lo, Register rd_hi, | 443 void Assembler::smull(Register rd_lo, Register rd_hi, |
432 Register rn, Register rm, Condition cond) { | 444 Register rn, Register rm, Condition cond) { |
| 445 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); |
433 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 446 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
434 EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm); | 447 EmitMulOp(cond, B23 | B22, rd_lo, rd_hi, rn, rm); |
435 } | 448 } |
436 | 449 |
437 | 450 |
438 void Assembler::umull(Register rd_lo, Register rd_hi, | 451 void Assembler::umull(Register rd_lo, Register rd_hi, |
439 Register rn, Register rm, Condition cond) { | 452 Register rn, Register rm, Condition cond) { |
| 453 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); |
440 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 454 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
441 EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); | 455 EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); |
442 } | 456 } |
443 | 457 |
444 | 458 |
445 void Assembler::smlal(Register rd_lo, Register rd_hi, | 459 void Assembler::smlal(Register rd_lo, Register rd_hi, |
446 Register rn, Register rm, Condition cond) { | 460 Register rn, Register rm, Condition cond) { |
| 461 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); |
447 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 462 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
448 EmitMulOp(cond, B23 | B22 | B21, rd_lo, rd_hi, rn, rm); | 463 EmitMulOp(cond, B23 | B22 | B21, rd_lo, rd_hi, rn, rm); |
449 } | 464 } |
450 | 465 |
451 | 466 |
452 void Assembler::umlal(Register rd_lo, Register rd_hi, | 467 void Assembler::umlal(Register rd_lo, Register rd_hi, |
453 Register rn, Register rm, Condition cond) { | 468 Register rn, Register rm, Condition cond) { |
| 469 ASSERT(TargetCPUFeatures::arm_version() == ARMv7); |
454 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. | 470 // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. |
455 EmitMulOp(cond, B23 | B21, rd_lo, rd_hi, rn, rm); | 471 EmitMulOp(cond, B23 | B21, rd_lo, rd_hi, rn, rm); |
456 } | 472 } |
457 | 473 |
458 | 474 |
459 void Assembler::EmitDivOp(Condition cond, int32_t opcode, | 475 void Assembler::EmitDivOp(Condition cond, int32_t opcode, |
460 Register rd, Register rn, Register rm) { | 476 Register rd, Register rn, Register rm) { |
461 ASSERT(TargetCPUFeatures::integer_division_supported()); | 477 ASSERT(TargetCPUFeatures::integer_division_supported()); |
462 ASSERT(rd != kNoRegister); | 478 ASSERT(rd != kNoRegister); |
463 ASSERT(rn != kNoRegister); | 479 ASSERT(rn != kNoRegister); |
(...skipping 2110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2574 vcvtdi(tmpl, stmpl); // left is in tmpl. | 2590 vcvtdi(tmpl, stmpl); // left is in tmpl. |
2575 vmovsr(stmpr, right); | 2591 vmovsr(stmpr, right); |
2576 vcvtdi(tmpr, stmpr); // right is in tmpr. | 2592 vcvtdi(tmpr, stmpr); // right is in tmpr. |
2577 vdivd(tmpr, tmpl, tmpr); | 2593 vdivd(tmpr, tmpl, tmpr); |
2578 vcvtid(stmpr, tmpr); | 2594 vcvtid(stmpr, tmpr); |
2579 vmovrs(result, stmpr); | 2595 vmovrs(result, stmpr); |
2580 } | 2596 } |
2581 } | 2597 } |
2582 | 2598 |
2583 | 2599 |
| 2600 // If we aren't on ARMv7, there is no smull, and we have to check for overflow |
| 2601 // manually. |
| 2602 void Assembler::CheckMultSignedOverflow(Register left, |
| 2603 Register right, |
| 2604 Register tmp, |
| 2605 DRegister dtmp0, DRegister dtmp1, |
| 2606 Label* overflow) { |
| 2607 Label done, left_neg, left_pos_right_neg, left_neg_right_pos; |
| 2608 |
| 2609 CompareImmediate(left, 0); |
| 2610 b(&left_neg, LT); |
| 2611 b(&done, EQ); |
| 2612 CompareImmediate(right, 0); |
| 2613 b(&left_pos_right_neg, LT); |
| 2614 b(&done, EQ); |
| 2615 |
| 2616 // Both positive. |
| 2617 LoadImmediate(tmp, INT_MAX); |
| 2618 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); |
| 2619 cmp(tmp, ShifterOperand(right)); |
| 2620 b(overflow, LT); |
| 2621 b(&done); |
| 2622 |
| 2623 // left positive, right non-positive. |
| 2624 Bind(&left_pos_right_neg); |
| 2625 LoadImmediate(tmp, INT_MIN); |
| 2626 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); |
| 2627 cmp(tmp, ShifterOperand(right)); |
| 2628 b(overflow, GT); |
| 2629 b(&done); |
| 2630 |
| 2631 Bind(&left_neg); |
| 2632 CompareImmediate(right, 0); |
| 2633 b(&left_neg_right_pos, GT); |
| 2634 b(&done, EQ); |
| 2635 |
| 2636 // both negative. |
| 2637 LoadImmediate(tmp, INT_MAX); |
| 2638 IntegerDivide(tmp, tmp, left, dtmp0, dtmp1); |
| 2639 cmp(tmp, ShifterOperand(right)); |
| 2640 b(overflow, GT); |
| 2641 b(&done); |
| 2642 |
| 2643 // left non-positive, right positive. |
| 2644 Bind(&left_neg_right_pos); |
| 2645 LoadImmediate(tmp, INT_MIN); |
| 2646 IntegerDivide(tmp, tmp, right, dtmp0, dtmp1); |
| 2647 cmp(tmp, ShifterOperand(left)); |
| 2648 b(overflow, GT); |
| 2649 |
| 2650 Bind(&done); |
| 2651 } |
| 2652 |
| 2653 |
2584 static int NumRegsBelowFP(RegList regs) { | 2654 static int NumRegsBelowFP(RegList regs) { |
2585 int count = 0; | 2655 int count = 0; |
2586 for (int i = 0; i < FP; i++) { | 2656 for (int i = 0; i < FP; i++) { |
2587 if ((regs & (1 << i)) != 0) { | 2657 if ((regs & (1 << i)) != 0) { |
2588 count++; | 2658 count++; |
2589 } | 2659 } |
2590 } | 2660 } |
2591 return count; | 2661 return count; |
2592 } | 2662 } |
2593 | 2663 |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2952 | 3022 |
2953 | 3023 |
2954 const char* Assembler::FpuRegisterName(FpuRegister reg) { | 3024 const char* Assembler::FpuRegisterName(FpuRegister reg) { |
2955 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); | 3025 ASSERT((0 <= reg) && (reg < kNumberOfFpuRegisters)); |
2956 return fpu_reg_names[reg]; | 3026 return fpu_reg_names[reg]; |
2957 } | 3027 } |
2958 | 3028 |
2959 } // namespace dart | 3029 } // namespace dart |
2960 | 3030 |
2961 #endif // defined TARGET_ARCH_ARM | 3031 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |