summaryrefslogtreecommitdiff
path: root/compiler/utils/mips64/assembler_mips64.cc
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2015-11-07 14:15:46 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2015-11-07 14:15:46 +0000
commit2264f624e41acf09b17c3961bd52966e43f2b58f (patch)
treeb946c5ffdca5399408fc0769edb12762980087b8 /compiler/utils/mips64/assembler_mips64.cc
parent4202a2ff49d77eda813052d091675bf53c46cb0f (diff)
parent5c75ffad3aaf9d62ea3ac4cf2c0a2fd699368f83 (diff)
Merge "MIPS64: small improvements in code generation"
Diffstat (limited to 'compiler/utils/mips64/assembler_mips64.cc')
-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 8e9b509e30..ba2525e555 100644
--- a/compiler/utils/mips64/assembler_mips64.cc
+++ b/compiler/utils/mips64/assembler_mips64.cc
@@ -840,45 +840,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.
@@ -889,10 +902,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);