OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 2528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2539 DCHECK(!base.is(pc)); | 2539 DCHECK(!base.is(pc)); |
2540 | 2540 |
2541 int sd, d; | 2541 int sd, d; |
2542 first.split_code(&sd, &d); | 2542 first.split_code(&sd, &d); |
2543 int count = last.code() - first.code() + 1; | 2543 int count = last.code() - first.code() + 1; |
2544 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | | 2544 emit(cond | B27 | B26 | am | d*B22 | base.code()*B16 | sd*B12 | |
2545 0xA*B8 | count); | 2545 0xA*B8 | count); |
2546 } | 2546 } |
2547 | 2547 |
2548 | 2548 |
2549 void Assembler::vmov(const SwVfpRegister dst, float imm) { | |
2550 mov(ip, Operand(bit_cast<int32_t>(imm))); | |
2551 vmov(dst, ip); | |
2552 } | |
2553 | |
2554 | |
2555 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { | 2549 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { |
2556 uint64_t i; | 2550 uint64_t i; |
2557 memcpy(&i, &d, 8); | 2551 memcpy(&i, &d, 8); |
2558 | 2552 |
2559 *lo = i & 0xffffffff; | 2553 *lo = i & 0xffffffff; |
2560 *hi = i >> 32; | 2554 *hi = i >> 32; |
2561 } | 2555 } |
2562 | 2556 |
2563 | 2557 |
2564 // Only works for little endian floating point formats. | 2558 // Only works for little endian floating point formats. |
2565 // We don't support VFP on the mixed endian floating point platform. | 2559 // We don't support VFP on the mixed endian floating point platform. |
2566 static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) { | 2560 static bool FitsVmovFPImmediate(double d, uint32_t* encoding) { |
2567 DCHECK(CpuFeatures::IsSupported(VFP3)); | 2561 DCHECK(CpuFeatures::IsSupported(VFP3)); |
2568 | 2562 |
2569 // VMOV can accept an immediate of the form: | 2563 // VMOV can accept an immediate of the form: |
2570 // | 2564 // |
2571 // +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7 | 2565 // +/- m * 2^(-n) where 16 <= m <= 31 and 0 <= n <= 7 |
2572 // | 2566 // |
2573 // The immediate is encoded using an 8-bit quantity, comprised of two | 2567 // The immediate is encoded using an 8-bit quantity, comprised of two |
2574 // 4-bit fields. For an 8-bit immediate of the form: | 2568 // 4-bit fields. For an 8-bit immediate of the form: |
2575 // | 2569 // |
2576 // [abcdefgh] | 2570 // [abcdefgh] |
2577 // | 2571 // |
2578 // where a is the MSB and h is the LSB, an immediate 64-bit double can be | 2572 // where a is the MSB and h is the LSB, an immediate 64-bit double can be |
2579 // created of the form: | 2573 // created of the form: |
2580 // | 2574 // |
2581 // [aBbbbbbb,bbcdefgh,00000000,00000000, | 2575 // [aBbbbbbb,bbcdefgh,00000000,00000000, |
2582 // 00000000,00000000,00000000,00000000] | 2576 // 00000000,00000000,00000000,00000000] |
2583 // | 2577 // |
2584 // where B = ~b. | 2578 // where B = ~b. |
2585 // | 2579 // |
2586 | 2580 |
2587 uint32_t lo, hi; | 2581 uint32_t lo, hi; |
2588 DoubleAsTwoUInt32(d, &lo, &hi); | 2582 DoubleAsTwoUInt32(d, &lo, &hi); |
2589 | 2583 |
2590 // The most obvious constraint is the long block of zeroes. | 2584 // The most obvious constraint is the long block of zeroes. |
2591 if ((lo != 0) || ((hi & 0xffff) != 0)) { | 2585 if ((lo != 0) || ((hi & 0xffff) != 0)) { |
2592 return false; | 2586 return false; |
2593 } | 2587 } |
2594 | 2588 |
2595 // Bits 62:55 must be all clear or all set. | 2589 // Bits 61:54 must be all clear or all set. |
2596 if (((hi & 0x3fc00000) != 0) && ((hi & 0x3fc00000) != 0x3fc00000)) { | 2590 if (((hi & 0x3fc00000) != 0) && ((hi & 0x3fc00000) != 0x3fc00000)) { |
2597 return false; | 2591 return false; |
2598 } | 2592 } |
2599 | 2593 |
2600 // Bit 63 must be NOT bit 62. | 2594 // Bit 62 must be NOT bit 61. |
2601 if (((hi ^ (hi << 1)) & (0x40000000)) == 0) { | 2595 if (((hi ^ (hi << 1)) & (0x40000000)) == 0) { |
2602 return false; | 2596 return false; |
2603 } | 2597 } |
2604 | 2598 |
2605 // Create the encoded immediate in the form: | 2599 // Create the encoded immediate in the form: |
2606 // [00000000,0000abcd,00000000,0000efgh] | 2600 // [00000000,0000abcd,00000000,0000efgh] |
2607 *encoding = (hi >> 16) & 0xf; // Low nybble. | 2601 *encoding = (hi >> 16) & 0xf; // Low nybble. |
2608 *encoding |= (hi >> 4) & 0x70000; // Low three bits of the high nybble. | 2602 *encoding |= (hi >> 4) & 0x70000; // Low three bits of the high nybble. |
2609 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. | 2603 *encoding |= (hi >> 12) & 0x80000; // Top bit of the high nybble. |
2610 | 2604 |
2611 return true; | 2605 return true; |
2612 } | 2606 } |
2613 | 2607 |
2614 | 2608 |
| 2609 void Assembler::vmov(const SwVfpRegister dst, float imm) { |
| 2610 uint32_t enc; |
| 2611 if (CpuFeatures::IsSupported(VFP3) && FitsVmovFPImmediate(imm, &enc)) { |
| 2612 // The float can be encoded in the instruction. |
| 2613 // |
| 2614 // Sd = immediate |
| 2615 // Instruction details available in ARM DDI 0406C.b, A8-936. |
| 2616 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | |
| 2617 // Vd(15-12) | 101(11-9) | sz=0(8) | imm4L(3-0) |
| 2618 int vd, d; |
| 2619 dst.split_code(&vd, &d); |
| 2620 emit(al | 0x1D * B23 | d * B22 | 0x3 * B20 | vd * B12 | 0x5 * B9 | enc); |
| 2621 } else { |
| 2622 mov(ip, Operand(bit_cast<int32_t>(imm))); |
| 2623 vmov(dst, ip); |
| 2624 } |
| 2625 } |
| 2626 |
| 2627 |
2615 void Assembler::vmov(const DwVfpRegister dst, | 2628 void Assembler::vmov(const DwVfpRegister dst, |
2616 double imm, | 2629 double imm, |
2617 const Register scratch) { | 2630 const Register scratch) { |
2618 uint32_t enc; | 2631 uint32_t enc; |
2619 // If the embedded constant pool is disabled, we can use the normal, inline | 2632 // If the embedded constant pool is disabled, we can use the normal, inline |
2620 // constant pool. If the embedded constant pool is enabled (via | 2633 // constant pool. If the embedded constant pool is enabled (via |
2621 // FLAG_enable_embedded_constant_pool), we can only use it where the pool | 2634 // FLAG_enable_embedded_constant_pool), we can only use it where the pool |
2622 // pointer (pp) is valid. | 2635 // pointer (pp) is valid. |
2623 bool can_use_pool = | 2636 bool can_use_pool = |
2624 !FLAG_enable_embedded_constant_pool || is_constant_pool_available(); | 2637 !FLAG_enable_embedded_constant_pool || is_constant_pool_available(); |
2625 if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { | 2638 if (CpuFeatures::IsSupported(VFP3) && FitsVmovFPImmediate(imm, &enc)) { |
2626 // The double can be encoded in the instruction. | 2639 // The double can be encoded in the instruction. |
2627 // | 2640 // |
2628 // Dd = immediate | 2641 // Dd = immediate |
2629 // Instruction details available in ARM DDI 0406C.b, A8-936. | 2642 // Instruction details available in ARM DDI 0406C.b, A8-936. |
2630 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | | 2643 // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | |
2631 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) | 2644 // Vd(15-12) | 101(11-9) | sz=1(8) | imm4L(3-0) |
2632 int vd, d; | 2645 int vd, d; |
2633 dst.split_code(&vd, &d); | 2646 dst.split_code(&vd, &d); |
2634 emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc); | 2647 emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc); |
2635 } else if (FLAG_enable_vldr_imm && can_use_pool) { | 2648 } else if (FLAG_enable_vldr_imm && can_use_pool) { |
(...skipping 1512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4148 DCHECK(is_uint12(offset)); | 4161 DCHECK(is_uint12(offset)); |
4149 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); | 4162 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); |
4150 } | 4163 } |
4151 } | 4164 } |
4152 | 4165 |
4153 | 4166 |
4154 } // namespace internal | 4167 } // namespace internal |
4155 } // namespace v8 | 4168 } // namespace v8 |
4156 | 4169 |
4157 #endif // V8_TARGET_ARCH_ARM | 4170 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |