From 5c75ffad3aaf9d62ea3ac4cf2c0a2fd699368f83 Mon Sep 17 00:00:00 2001 From: Alexey Frunze Date: Thu, 24 Sep 2015 14:41:59 -0700 Subject: MIPS64: small improvements in code generation Specifically: - More efficient load/store of constant 0 (and +0.0) - Improved swapping of floats/doubles in registers - Use kNoOutputOverlap wherever possible - More efficient 64-bit integer comparison with 0 - More efficient load of integer constants of the form (2**n)-1 Change-Id: Ic2914d8865aa6616b9a0b21b3cc173d4477eb8c7 --- compiler/utils/mips64/assembler_mips64.cc | 38 +++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'compiler/utils/mips64/assembler_mips64.cc') diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc index 00e8995bff..cedbedbc24 100644 --- a/compiler/utils/mips64/assembler_mips64.cc +++ b/compiler/utils/mips64/assembler_mips64.cc @@ -892,45 +892,58 @@ void Mips64Assembler::LoadConst64(GpuRegister rd, int64_t value) { } else if ((value & 0xFFFF) == 0 && ((value >> 31) & 0x1FFFF) == ((0x20000 - bit31) & 0x1FFFF)) { Lui(rd, value >> 16); Dati(rd, (value >> 48) + bit31); + } else if (IsPowerOfTwo(value + UINT64_C(1))) { + int shift_cnt = 64 - CTZ(value + UINT64_C(1)); + Daddiu(rd, ZERO, -1); + if (shift_cnt < 32) { + Dsrl(rd, rd, shift_cnt); + } else { + Dsrl32(rd, rd, shift_cnt & 31); + } } else { int shift_cnt = CTZ(value); int64_t tmp = value >> shift_cnt; if (IsUint<16>(tmp)) { Ori(rd, ZERO, tmp); - if (shift_cnt < 32) + if (shift_cnt < 32) { Dsll(rd, rd, shift_cnt); - else + } else { Dsll32(rd, rd, shift_cnt & 31); + } } else if (IsInt<16>(tmp)) { Daddiu(rd, ZERO, tmp); - if (shift_cnt < 32) + if (shift_cnt < 32) { Dsll(rd, rd, shift_cnt); - else + } else { Dsll32(rd, rd, shift_cnt & 31); + } } else if (IsInt<32>(tmp)) { // Loads with 3 instructions. Lui(rd, tmp >> 16); Ori(rd, rd, tmp); - if (shift_cnt < 32) + if (shift_cnt < 32) { Dsll(rd, rd, shift_cnt); - else + } else { Dsll32(rd, rd, shift_cnt & 31); + } } else { shift_cnt = 16 + CTZ(value >> 16); tmp = value >> shift_cnt; if (IsUint<16>(tmp)) { Ori(rd, ZERO, tmp); - if (shift_cnt < 32) + if (shift_cnt < 32) { Dsll(rd, rd, shift_cnt); - else + } else { Dsll32(rd, rd, shift_cnt & 31); + } Ori(rd, rd, value); } else if (IsInt<16>(tmp)) { Daddiu(rd, ZERO, tmp); - if (shift_cnt < 32) + if (shift_cnt < 32) { Dsll(rd, rd, shift_cnt); - else + } else { Dsll32(rd, rd, shift_cnt & 31); + } Ori(rd, rd, value); } else { // Loads with 3-4 instructions. @@ -941,10 +954,11 @@ void Mips64Assembler::LoadConst64(GpuRegister rd, int64_t value) { used_lui = true; } if ((tmp2 & 0xFFFF) != 0) { - if (used_lui) + if (used_lui) { Ori(rd, rd, tmp2); - else + } else { Ori(rd, ZERO, tmp2); + } } if (bit31) { tmp2 += UINT64_C(0x100000000); -- cgit v1.2.3-59-g8ed1b