summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_generator_mips.cc
diff options
context:
space:
mode:
authorChris Larsen <chris.larsen@mips.com>2017-11-09 14:21:28 -0800
committerChris Larsen <chris.larsen@mips.com>2017-11-09 14:24:37 -0800
commit3e5fecdeacdacf847d376adb05a9ad5587648139 (patch)
tree5a846ea9547a03a0aa52197058c7fdb5e922c0f6 /compiler/optimizing/code_generator_mips.cc
parent2202d56061941b4fecbdb018d84bcefb05b6c683 (diff)
MIPS32: Use conditional moves to compute 64-bit shifts.
Use conditional moves in InstructionCodeGeneratorMIPS::HandleShift()'s 64-bit variable shifts to avoid conditional branches (Beqz(TMP, &done)). Also, on R6 use Beqzc(TMP, &done, /* is_bare */ true) in place of Beqz(TMP, &done). Test: Boot & run tests on MIPS32r6 QEMU & on CI-20 hardware (MIPS32r2). Test: test/testrunner/testrunner.py --target --optimizing Change-Id: I4d34a51cd2397c845f936af853cb5f30e82de438
Diffstat (limited to 'compiler/optimizing/code_generator_mips.cc')
-rw-r--r--compiler/optimizing/code_generator_mips.cc51
1 files changed, 37 insertions, 14 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc
index f9f5a4da56..ddec0cc453 100644
--- a/compiler/optimizing/code_generator_mips.cc
+++ b/compiler/optimizing/code_generator_mips.cc
@@ -2474,6 +2474,7 @@ void InstructionCodeGeneratorMIPS::HandleShift(HBinaryOperation* instr) {
}
}
} else {
+ const bool isR6 = codegen_->GetInstructionSetFeatures().IsR6();
MipsLabel done;
if (instr->IsShl()) {
__ Sllv(dst_low, lhs_low, rhs_reg);
@@ -2483,9 +2484,14 @@ void InstructionCodeGeneratorMIPS::HandleShift(HBinaryOperation* instr) {
__ Sllv(dst_high, lhs_high, rhs_reg);
__ Or(dst_high, dst_high, TMP);
__ Andi(TMP, rhs_reg, kMipsBitsPerWord);
- __ Beqz(TMP, &done);
- __ Move(dst_high, dst_low);
- __ Move(dst_low, ZERO);
+ if (isR6) {
+ __ Beqzc(TMP, &done, /* is_bare */ true);
+ __ Move(dst_high, dst_low);
+ __ Move(dst_low, ZERO);
+ } else {
+ __ Movn(dst_high, dst_low, TMP);
+ __ Movn(dst_low, ZERO, TMP);
+ }
} else if (instr->IsShr()) {
__ Srav(dst_high, lhs_high, rhs_reg);
__ Nor(AT, ZERO, rhs_reg);
@@ -2494,9 +2500,15 @@ void InstructionCodeGeneratorMIPS::HandleShift(HBinaryOperation* instr) {
__ Srlv(dst_low, lhs_low, rhs_reg);
__ Or(dst_low, dst_low, TMP);
__ Andi(TMP, rhs_reg, kMipsBitsPerWord);
- __ Beqz(TMP, &done);
- __ Move(dst_low, dst_high);
- __ Sra(dst_high, dst_high, 31);
+ if (isR6) {
+ __ Beqzc(TMP, &done, /* is_bare */ true);
+ __ Move(dst_low, dst_high);
+ __ Sra(dst_high, dst_high, 31);
+ } else {
+ __ Sra(AT, dst_high, 31);
+ __ Movn(dst_low, dst_high, TMP);
+ __ Movn(dst_high, AT, TMP);
+ }
} else if (instr->IsUShr()) {
__ Srlv(dst_high, lhs_high, rhs_reg);
__ Nor(AT, ZERO, rhs_reg);
@@ -2505,10 +2517,15 @@ void InstructionCodeGeneratorMIPS::HandleShift(HBinaryOperation* instr) {
__ Srlv(dst_low, lhs_low, rhs_reg);
__ Or(dst_low, dst_low, TMP);
__ Andi(TMP, rhs_reg, kMipsBitsPerWord);
- __ Beqz(TMP, &done);
- __ Move(dst_low, dst_high);
- __ Move(dst_high, ZERO);
- } else {
+ if (isR6) {
+ __ Beqzc(TMP, &done, /* is_bare */ true);
+ __ Move(dst_low, dst_high);
+ __ Move(dst_high, ZERO);
+ } else {
+ __ Movn(dst_low, dst_high, TMP);
+ __ Movn(dst_high, ZERO, TMP);
+ }
+ } else { // Rotate.
__ Nor(AT, ZERO, rhs_reg);
__ Srlv(TMP, lhs_low, rhs_reg);
__ Sll(dst_low, lhs_high, 1);
@@ -2519,10 +2536,16 @@ void InstructionCodeGeneratorMIPS::HandleShift(HBinaryOperation* instr) {
__ Sllv(dst_high, dst_high, AT);
__ Or(dst_high, dst_high, TMP);
__ Andi(TMP, rhs_reg, kMipsBitsPerWord);
- __ Beqz(TMP, &done);
- __ Move(TMP, dst_high);
- __ Move(dst_high, dst_low);
- __ Move(dst_low, TMP);
+ if (isR6) {
+ __ Beqzc(TMP, &done, /* is_bare */ true);
+ __ Move(TMP, dst_high);
+ __ Move(dst_high, dst_low);
+ __ Move(dst_low, TMP);
+ } else {
+ __ Movn(AT, dst_high, TMP);
+ __ Movn(dst_high, dst_low, TMP);
+ __ Movn(dst_low, AT, TMP);
+ }
}
__ Bind(&done);
}