diff options
| author | 2014-09-02 15:39:57 -0700 | |
|---|---|---|
| committer | 2014-09-02 16:01:53 -0700 | |
| commit | f77e977b04f1a73a52ea7965789cbda39d7734c4 (patch) | |
| tree | 86e480ec5d0fb520cd6f34a05c350a695512a5df | |
| parent | 6e3604287f73fbc58d8297c0bca6bfe808524a2b (diff) | |
Quick compiler, aarch64: Insane sanity checker
Fix bit-mask generation used in the sanity checking code
for long division by small constants via multiplication. The
failing case was a 64-bit wide mask. The macro was using the
desired width of the result as a shift count - and a left
shift of a 64-bit integer by 64 bits is undefined.
Note that the generated code is correct - it's just the sanity
checking code that was wrong.
Change-Id: Ic6654662f848d3caab2c3b1ef0d92fe2eb9673f4
| -rw-r--r-- | compiler/dex/quick/arm64/target_arm64.cc | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc index 0b58fb1d65..d7d5651b41 100644 --- a/compiler/dex/quick/arm64/target_arm64.cc +++ b/compiler/dex/quick/arm64/target_arm64.cc @@ -249,19 +249,22 @@ static void DecodeRegExtendOrShift(int operand, char *buf, size_t buf_size) { } } -#define BIT_MASK(w) ((UINT64_C(1) << (w)) - UINT64_C(1)) +static uint64_t bit_mask(unsigned width) { + DCHECK_LE(width, 64U); + return (width == 64) ? static_cast<uint64_t>(-1) : ((UINT64_C(1) << (width)) - UINT64_C(1)); +} static uint64_t RotateRight(uint64_t value, unsigned rotate, unsigned width) { DCHECK_LE(width, 64U); rotate &= 63; - value = value & BIT_MASK(width); - return ((value & BIT_MASK(rotate)) << (width - rotate)) | (value >> rotate); + value = value & bit_mask(width); + return ((value & bit_mask(rotate)) << (width - rotate)) | (value >> rotate); } static uint64_t RepeatBitsAcrossReg(bool is_wide, uint64_t value, unsigned width) { unsigned i; unsigned reg_size = (is_wide) ? 64 : 32; - uint64_t result = value & BIT_MASK(width); + uint64_t result = value & bit_mask(width); for (i = width; i < reg_size; i *= 2) { result |= (result << i); } @@ -300,7 +303,7 @@ uint64_t Arm64Mir2Lir::DecodeLogicalImmediate(bool is_wide, int value) { if (n == 1) { DCHECK_NE(imm_s, 0x3fU); - uint64_t bits = BIT_MASK(imm_s + 1); + uint64_t bits = bit_mask(imm_s + 1); return RotateRight(bits, imm_r, 64); } else { DCHECK_NE((imm_s >> 1), 0x1fU); @@ -308,7 +311,7 @@ uint64_t Arm64Mir2Lir::DecodeLogicalImmediate(bool is_wide, int value) { if ((imm_s & width) == 0) { unsigned mask = (unsigned)(width - 1); DCHECK_NE((imm_s & mask), mask); - uint64_t bits = BIT_MASK((imm_s & mask) + 1); + uint64_t bits = bit_mask((imm_s & mask) + 1); return RepeatBitsAcrossReg(is_wide, RotateRight(bits, imm_r & mask, width), width); } } |