| 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 |