summaryrefslogtreecommitdiff
path: root/compiler/utils
diff options
context:
space:
mode:
author Alexey Frunze <Alexey.Frunze@imgtec.com> 2015-09-24 14:41:59 -0700
committer Alexey Frunze <Alexey.Frunze@imgtec.com> 2015-11-06 13:13:47 -0800
commit5c75ffad3aaf9d62ea3ac4cf2c0a2fd699368f83 (patch)
tree15da165b06f99c55849e5431d8b405c2014883dc /compiler/utils
parentb203aad7a0db904efa8429d48b53e56583f61ec2 (diff)
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
Diffstat (limited to 'compiler/utils')
-rw-r--r--compiler/utils/mips64/assembler_mips64.cc38
1 files changed, 26 insertions, 12 deletions
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);