diff options
author | Chris Larsen <chris.larsen@mips.com> | 2017-11-09 14:21:28 -0800 |
---|---|---|
committer | Chris Larsen <chris.larsen@mips.com> | 2017-11-09 14:24:37 -0800 |
commit | 3e5fecdeacdacf847d376adb05a9ad5587648139 (patch) | |
tree | 5a846ea9547a03a0aa52197058c7fdb5e922c0f6 /compiler/optimizing/code_generator_mips.cc | |
parent | 2202d56061941b4fecbdb018d84bcefb05b6c683 (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.cc | 51 |
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); } |