Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // | 2 // |
| 3 // Redistribution and use in source and binary forms, with or without | 3 // Redistribution and use in source and binary forms, with or without |
| 4 // modification, are permitted provided that the following conditions are | 4 // modification, are permitted provided that the following conditions are |
| 5 // met: | 5 // met: |
| 6 // | 6 // |
| 7 // * Redistributions of source code must retain the above copyright | 7 // * Redistributions of source code must retain the above copyright |
| 8 // notice, this list of conditions and the following disclaimer. | 8 // notice, this list of conditions and the following disclaimer. |
| 9 // * Redistributions in binary form must reproduce the above | 9 // * Redistributions in binary form must reproduce the above |
| 10 // copyright notice, this list of conditions and the following | 10 // copyright notice, this list of conditions and the following |
| (...skipping 2085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2096 | 2096 |
| 2097 return (bit7 | bit6 | bit5_to_0) << ImmFP_offset; | 2097 return (bit7 | bit6 | bit5_to_0) << ImmFP_offset; |
| 2098 } | 2098 } |
| 2099 | 2099 |
| 2100 | 2100 |
| 2101 // Code generation helpers. | 2101 // Code generation helpers. |
| 2102 void Assembler::MoveWide(const Register& rd, | 2102 void Assembler::MoveWide(const Register& rd, |
| 2103 uint64_t imm, | 2103 uint64_t imm, |
| 2104 int shift, | 2104 int shift, |
| 2105 MoveWideImmediateOp mov_op) { | 2105 MoveWideImmediateOp mov_op) { |
| 2106 // Ignore the top 32 bits of an immediate if we're moving to a W register. | |
| 2107 if (rd.Is32Bits()) { | |
| 2108 // Check that the top 32 bits are zero (a positive 32-bit number) or top | |
| 2109 // 33 bits are one (a negative 32-bit number, sign extended to 64 bits). | |
| 2110 ASSERT(((imm >> kWRegSizeInBits) == 0) || | |
| 2111 ((imm >> (kWRegSizeInBits - 1)) == 0x1ffffffff)); | |
| 2112 imm &= kWRegMask; | |
| 2113 } | |
| 2114 | |
| 2106 if (shift >= 0) { | 2115 if (shift >= 0) { |
| 2107 // Explicit shift specified. | 2116 // Explicit shift specified. |
| 2108 ASSERT((shift == 0) || (shift == 16) || (shift == 32) || (shift == 48)); | 2117 ASSERT((shift == 0) || (shift == 16) || (shift == 32) || (shift == 48)); |
| 2109 ASSERT(rd.Is64Bits() || (shift == 0) || (shift == 16)); | 2118 ASSERT(rd.Is64Bits() || (shift == 0) || (shift == 16)); |
| 2110 shift /= 16; | 2119 shift /= 16; |
| 2111 } else { | 2120 } else { |
| 2112 // Calculate a new immediate and shift combination to encode the immediate | 2121 // Calculate a new immediate and shift combination to encode the immediate |
| 2113 // argument. | 2122 // argument. |
| 2114 shift = 0; | 2123 shift = 0; |
| 2115 if ((imm & ~0xffffUL) == 0) { | 2124 if ((imm & ~0xffffUL) == 0) { |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2501 // If it can not be encoded, the function returns false, and the values pointed | 2510 // If it can not be encoded, the function returns false, and the values pointed |
| 2502 // to by n, imm_s and imm_r are undefined. | 2511 // to by n, imm_s and imm_r are undefined. |
| 2503 bool Assembler::IsImmLogical(uint64_t value, | 2512 bool Assembler::IsImmLogical(uint64_t value, |
| 2504 unsigned width, | 2513 unsigned width, |
| 2505 unsigned* n, | 2514 unsigned* n, |
| 2506 unsigned* imm_s, | 2515 unsigned* imm_s, |
| 2507 unsigned* imm_r) { | 2516 unsigned* imm_r) { |
| 2508 ASSERT((n != NULL) && (imm_s != NULL) && (imm_r != NULL)); | 2517 ASSERT((n != NULL) && (imm_s != NULL) && (imm_r != NULL)); |
| 2509 ASSERT((width == kWRegSizeInBits) || (width == kXRegSizeInBits)); | 2518 ASSERT((width == kWRegSizeInBits) || (width == kXRegSizeInBits)); |
| 2510 | 2519 |
| 2520 bool negate = false; | |
| 2521 | |
| 2511 // Logical immediates are encoded using parameters n, imm_s and imm_r using | 2522 // Logical immediates are encoded using parameters n, imm_s and imm_r using |
| 2512 // the following table: | 2523 // the following table: |
| 2513 // | 2524 // |
| 2514 // N imms immr size S R | 2525 // N imms immr size S R |
| 2515 // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr) | 2526 // 1 ssssss rrrrrr 64 UInt(ssssss) UInt(rrrrrr) |
| 2516 // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr) | 2527 // 0 0sssss xrrrrr 32 UInt(sssss) UInt(rrrrr) |
| 2517 // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr) | 2528 // 0 10ssss xxrrrr 16 UInt(ssss) UInt(rrrr) |
| 2518 // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr) | 2529 // 0 110sss xxxrrr 8 UInt(sss) UInt(rrr) |
| 2519 // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr) | 2530 // 0 1110ss xxxxrr 4 UInt(ss) UInt(rr) |
| 2520 // 0 11110s xxxxxr 2 UInt(s) UInt(r) | 2531 // 0 11110s xxxxxr 2 UInt(s) UInt(r) |
| 2521 // (s bits must not be all set) | 2532 // (s bits must not be all set) |
| 2522 // | 2533 // |
| 2523 // A pattern is constructed of size bits, where the least significant S+1 | 2534 // A pattern is constructed of size bits, where the least significant S+1 bits |
| 2524 // bits are set. The pattern is rotated right by R, and repeated across a | 2535 // are set. The pattern is rotated right by R, and repeated across a 32 or |
| 2525 // 32 or 64-bit value, depending on destination register width. | 2536 // 64-bit value, depending on destination register width. |
| 2526 // | 2537 // |
| 2527 // To test if an arbitary immediate can be encoded using this scheme, an | 2538 // Put another way: the basic format of a logical immediate is a single |
| 2528 // iterative algorithm is used. | 2539 // contiguous stretch of 1 bits, repeated across the whole word at intervals |
| 2540 // given by a power of 2. To identify them quickly, we first locate the | |
| 2541 // lowest stretch of 1 bits, then the next 1 bit above that; that combination | |
| 2542 // is different for every logical immediate, so it gives us all the | |
| 2543 // information we need to identify the only logical immediate that our input | |
| 2544 // could be, and then we simply check if that's the value we actually have. | |
| 2529 // | 2545 // |
| 2530 // TODO(mcapewel) This code does not consider using X/W register overlap to | 2546 // (The rotation parameter does give the possibility of the stretch of 1 bits |
| 2531 // support 64-bit immediates where the top 32-bits are zero, and the bottom | 2547 // going 'round the end' of the word. To deal with that, we observe that in |
| 2532 // 32-bits are an encodable logical immediate. | 2548 // any situation where that happens the bitwise NOT of the value is also a |
| 2549 // valid logical immediate. So we simply invert the input whenever its low bit | |
| 2550 // is set, and then we know that the rotated case can't arise.) | |
| 2533 | 2551 |
| 2534 // 1. If the value has all set or all clear bits, it can't be encoded. | 2552 if (value & 1) { |
| 2535 if ((value == 0) || (value == 0xffffffffffffffffUL) || | 2553 // If the low bit is 1, negate the value, and set a flag to remember that we |
| 2536 ((width == kWRegSizeInBits) && (value == 0xffffffff))) { | 2554 // did (so that we can adjust the return values appropriately). |
| 2555 negate = true; | |
| 2556 value = ~value; | |
| 2557 } | |
| 2558 | |
| 2559 if (width == kWRegSizeInBits) { | |
| 2560 // To handle 32-bit logical immediates, the very easiest thing is to repeat | |
| 2561 // the input value twice to make a 64-bit word. The correct encoding of that | |
| 2562 // as a logical immediate will also be the correct encoding of the 32-bit | |
| 2563 // value. | |
| 2564 | |
| 2565 // Avoid making the assumption that the most-significant 32 bits are zero by | |
|
ulan
2014/06/30 12:50:08
Yes, this assumption will not hold if negate = tru
m.m.capewell
2014/07/01 09:45:46
Altered the comment to make this clear.
| |
| 2566 // shifting the value left before duplicating it. | |
| 2567 value <<= kWRegSizeInBits; | |
| 2568 value |= value >> kWRegSizeInBits; | |
| 2569 } | |
| 2570 | |
| 2571 // The basic analysis idea: imagine our input word looks like this. | |
| 2572 // | |
| 2573 // 0011111000111110001111100011111000111110001111100011111000111110 | |
| 2574 // c b a | |
| 2575 // |<--d-->| | |
| 2576 // | |
| 2577 // We find the lowest set bit (as an actual power-of-2 value, not its index) | |
| 2578 // and call it a. Then we add a to our original number, which wipes out the | |
| 2579 // bottommost stretch of set bits and replaces it with a 1 carried into the | |
| 2580 // next zero bit. Then we look for the new lowest set bit, which is in | |
| 2581 // position b, and subtract it, so now our number is just like the original | |
| 2582 // but with the lowest stretch of set bits completely gone. Now we find the | |
| 2583 // lowest set bit again, which is position c in the diagram above. Then we'll | |
| 2584 // measure the distance d between bit positions a and c (using CLZ), and that | |
| 2585 // tells us that the only valid logical immediate that could possibly be equal | |
| 2586 // to this number is the one in which a stretch of bits running from a to just | |
| 2587 // below b is replicated every d bits. | |
| 2588 uint64_t a = LowestSetBit(value); | |
| 2589 uint64_t value_plus_a = value + a; | |
| 2590 uint64_t b = LowestSetBit(value_plus_a); | |
| 2591 uint64_t value_plus_a_minus_b = value_plus_a - b; | |
| 2592 uint64_t c = LowestSetBit(value_plus_a_minus_b); | |
| 2593 | |
| 2594 int d, clz_a, out_n; | |
| 2595 uint64_t mask; | |
| 2596 | |
| 2597 if (c != 0) { | |
| 2598 // The general case, in which there is more than one stretch of set bits. | |
| 2599 // Compute the repeat distance d, and set up a bitmask covering the basic | |
| 2600 // unit of repetition (i.e. a word with the bottom d bits set). Also, in all | |
| 2601 // of these cases the N bit of the output will be zero. | |
| 2602 clz_a = CountLeadingZeros(a, kXRegSizeInBits); | |
| 2603 int clz_c = CountLeadingZeros(c, kXRegSizeInBits); | |
| 2604 d = clz_a - clz_c; | |
| 2605 mask = ((UINT64_C(1) << d) - 1); | |
| 2606 out_n = 0; | |
| 2607 } else { | |
| 2608 // Handle degenerate cases. | |
| 2609 // | |
| 2610 // If any of those 'find lowest set bit' operations didn't find a set bit at | |
| 2611 // all, then the word will have been zero thereafter, so in particular the | |
| 2612 // last lowest_set_bit operation will have returned zero. So we can test for | |
| 2613 // all the special case conditions in one go by seeing if c is zero. | |
| 2614 if (a == 0) { | |
| 2615 // The input was zero (or all 1 bits, which will come to here too after we | |
| 2616 // inverted it at the start of the function), for which we just return | |
| 2617 // false. | |
| 2618 return false; | |
| 2619 } else { | |
| 2620 // Otherwise, if c was zero but a was not, then there's just one stretch | |
| 2621 // of set bits in our word, meaning that we have the trivial case of | |
| 2622 // d == 64 and only one 'repetition'. Set up all the same variables as in | |
| 2623 // the general case above, and set the N bit in the output. | |
| 2624 clz_a = CountLeadingZeros(a, kXRegSizeInBits); | |
| 2625 d = 64; | |
| 2626 mask = ~UINT64_C(0); | |
| 2627 out_n = 1; | |
| 2628 } | |
| 2629 } | |
| 2630 | |
| 2631 // If the repeat period d is not a power of two, it can't be encoded. | |
| 2632 if (!IS_POWER_OF_TWO(d)) { | |
| 2537 return false; | 2633 return false; |
| 2538 } | 2634 } |
|
ulan
2014/06/30 12:50:08
ASSERT(d >= 2) or assert below that CountLeadingZe
m.m.capewell
2014/07/01 09:45:46
Asserted the index to the multipliers array, as I
| |
| 2539 | 2635 |
| 2540 unsigned lead_zero = CountLeadingZeros(value, width); | 2636 if (((b - a) & ~mask) != 0) { |
| 2541 unsigned lead_one = CountLeadingZeros(~value, width); | 2637 // If the bit stretch (b - a) does not fit within the mask derived from the |
| 2542 unsigned trail_zero = CountTrailingZeros(value, width); | 2638 // repeat period, then fail. |
| 2543 unsigned trail_one = CountTrailingZeros(~value, width); | |
| 2544 unsigned set_bits = CountSetBits(value, width); | |
| 2545 | |
| 2546 // The fixed bits in the immediate s field. | |
| 2547 // If width == 64 (X reg), start at 0xFFFFFF80. | |
| 2548 // If width == 32 (W reg), start at 0xFFFFFFC0, as the iteration for 64-bit | |
| 2549 // widths won't be executed. | |
| 2550 int imm_s_fixed = (width == kXRegSizeInBits) ? -128 : -64; | |
| 2551 int imm_s_mask = 0x3F; | |
| 2552 | |
| 2553 for (;;) { | |
| 2554 // 2. If the value is two bits wide, it can be encoded. | |
| 2555 if (width == 2) { | |
| 2556 *n = 0; | |
| 2557 *imm_s = 0x3C; | |
| 2558 *imm_r = (value & 3) - 1; | |
| 2559 return true; | |
| 2560 } | |
| 2561 | |
| 2562 *n = (width == 64) ? 1 : 0; | |
| 2563 *imm_s = ((imm_s_fixed | (set_bits - 1)) & imm_s_mask); | |
| 2564 if ((lead_zero + set_bits) == width) { | |
| 2565 *imm_r = 0; | |
| 2566 } else { | |
| 2567 *imm_r = (lead_zero > 0) ? (width - trail_zero) : lead_one; | |
| 2568 } | |
| 2569 | |
| 2570 // 3. If the sum of leading zeros, trailing zeros and set bits is equal to | |
| 2571 // the bit width of the value, it can be encoded. | |
| 2572 if (lead_zero + trail_zero + set_bits == width) { | |
| 2573 return true; | |
| 2574 } | |
| 2575 | |
| 2576 // 4. If the sum of leading ones, trailing ones and unset bits in the | |
| 2577 // value is equal to the bit width of the value, it can be encoded. | |
| 2578 if (lead_one + trail_one + (width - set_bits) == width) { | |
| 2579 return true; | |
| 2580 } | |
| 2581 | |
| 2582 // 5. If the most-significant half of the bitwise value is equal to the | |
| 2583 // least-significant half, return to step 2 using the least-significant | |
| 2584 // half of the value. | |
| 2585 uint64_t mask = (1UL << (width >> 1)) - 1; | |
| 2586 if ((value & mask) == ((value >> (width >> 1)) & mask)) { | |
| 2587 width >>= 1; | |
| 2588 set_bits >>= 1; | |
| 2589 imm_s_fixed >>= 1; | |
| 2590 continue; | |
| 2591 } | |
| 2592 | |
| 2593 // 6. Otherwise, the value can't be encoded. | |
| 2594 return false; | 2639 return false; |
| 2595 } | 2640 } |
| 2641 | |
| 2642 // The only possible option is b - a repeated every d bits. Now we're going to | |
| 2643 // actually construct the valid logical immediate derived from that | |
| 2644 // specification, and see if it equals our original input. | |
| 2645 // | |
| 2646 // To repeat a value every d bits, we multiply it by a number of the form | |
| 2647 // (1 + 2^d + 2^(2d) + ...), i.e. 0x0001000100010001 or similar. These can | |
| 2648 // be derived using a table lookup on CLZ(d). | |
| 2649 static const uint64_t multipliers[] = { | |
| 2650 0x0000000000000001UL, | |
| 2651 0x0000000100000001UL, | |
| 2652 0x0001000100010001UL, | |
| 2653 0x0101010101010101UL, | |
| 2654 0x1111111111111111UL, | |
| 2655 0x5555555555555555UL, | |
| 2656 }; | |
| 2657 uint64_t multiplier = multipliers[CountLeadingZeros(d, kXRegSizeInBits) - 57]; | |
| 2658 uint64_t candidate = (b - a) * multiplier; | |
| 2659 | |
| 2660 if (value != candidate) { | |
| 2661 // The candidate pattern doesn't match our input value, so fail. | |
| 2662 return false; | |
| 2663 } | |
| 2664 | |
| 2665 // We have a match! This is a valid logical immediate, so now we have to | |
| 2666 // construct the bits and pieces of the instruction encoding that generates | |
| 2667 // it. | |
| 2668 | |
| 2669 // Count the set bits in our basic stretch. The special case of clz(0) == -1 | |
| 2670 // makes the answer come out right for stretches that reach the very top of | |
| 2671 // the word (e.g. numbers like 0xffffc00000000000). | |
| 2672 int clz_b = (b == 0) ? -1 : CountLeadingZeros(b, kXRegSizeInBits); | |
| 2673 int s = clz_a - clz_b; | |
| 2674 | |
| 2675 // Decide how many bits to rotate right by, to put the low bit of that basic | |
| 2676 // stretch in position a. | |
| 2677 int r; | |
| 2678 if (negate) { | |
| 2679 // If we inverted the input right at the start of this function, here's | |
| 2680 // where we compensate: the number of set bits becomes the number of clear | |
| 2681 // bits, and the rotation count is based on position b rather than position | |
| 2682 // a (since b is the location of the 'lowest' 1 bit after inversion). | |
| 2683 s = d - s; | |
| 2684 r = (clz_b + 1) & (d - 1); | |
| 2685 } else { | |
| 2686 r = (clz_a + 1) & (d - 1); | |
| 2687 } | |
| 2688 | |
| 2689 // Now we're done, except for having to encode the S output in such a way that | |
| 2690 // it gives both the number of set bits and the length of the repeated | |
| 2691 // segment. The s field is encoded like this: | |
| 2692 // | |
| 2693 // imms size S | |
| 2694 // ssssss 64 UInt(ssssss) | |
| 2695 // 0sssss 32 UInt(sssss) | |
| 2696 // 10ssss 16 UInt(ssss) | |
| 2697 // 110sss 8 UInt(sss) | |
| 2698 // 1110ss 4 UInt(ss) | |
| 2699 // 11110s 2 UInt(s) | |
| 2700 // | |
| 2701 // So we 'or' (-d << 1) with our computed s to form imms. | |
| 2702 *n = out_n; | |
| 2703 *imm_s = ((-d << 1) | (s - 1)) & 0x3f; | |
| 2704 *imm_r = r; | |
| 2705 | |
| 2706 return true; | |
| 2596 } | 2707 } |
| 2597 | 2708 |
| 2598 | 2709 |
| 2599 bool Assembler::IsImmConditionalCompare(int64_t immediate) { | 2710 bool Assembler::IsImmConditionalCompare(int64_t immediate) { |
| 2600 return is_uint5(immediate); | 2711 return is_uint5(immediate); |
| 2601 } | 2712 } |
| 2602 | 2713 |
| 2603 | 2714 |
| 2604 bool Assembler::IsImmFP32(float imm) { | 2715 bool Assembler::IsImmFP32(float imm) { |
| 2605 // Valid values will have the form: | 2716 // Valid values will have the form: |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3037 adr(rd, 0); | 3148 adr(rd, 0); |
| 3038 MovInt64(scratch, target_offset); | 3149 MovInt64(scratch, target_offset); |
| 3039 add(rd, rd, scratch); | 3150 add(rd, rd, scratch); |
| 3040 } | 3151 } |
| 3041 } | 3152 } |
| 3042 | 3153 |
| 3043 | 3154 |
| 3044 } } // namespace v8::internal | 3155 } } // namespace v8::internal |
| 3045 | 3156 |
| 3046 #endif // V8_TARGET_ARCH_ARM64 | 3157 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |