Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(948)

Unified Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2359713003: [Subzero][MIPS32] Implements 64-bit shl, lshr, ashr for MIPS (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Added lowering of shifts operations with constant shift amount Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceTargetLoweringMIPS32.cpp
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
index c4b602463f20af75a03df68d14f4f43a92998fa5..d9029a56fb96a0779334a98c68363ae3da4918ed 100644
--- a/src/IceTargetLoweringMIPS32.cpp
+++ b/src/IceTargetLoweringMIPS32.cpp
@@ -1788,30 +1788,22 @@ void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr,
Variable *Dest, Operand *Src0,
Operand *Src1) {
InstArithmetic::OpKind Op = Instr->getOp();
- switch (Op) {
- case InstArithmetic::Add:
- case InstArithmetic::And:
- case InstArithmetic::Or:
- case InstArithmetic::Sub:
- case InstArithmetic::Xor:
- case InstArithmetic::Mul:
- break;
- default:
- UnimplementedLoweringError(this, Instr);
- return;
- }
auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
- Variable *Src0LoR = legalizeToReg(loOperand(Src0));
- Variable *Src1LoR = legalizeToReg(loOperand(Src1));
- Variable *Src0HiR = legalizeToReg(hiOperand(Src0));
- Variable *Src1HiR = legalizeToReg(hiOperand(Src1));
+ Variable *Src0LoR = nullptr;
+ Variable *Src1LoR = nullptr;
+ Variable *Src0HiR = nullptr;
+ Variable *Src1HiR = nullptr;
switch (Op) {
case InstArithmetic::_num:
llvm::report_fatal_error("Unknown arithmetic operator");
return;
case InstArithmetic::Add: {
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ Src1LoR = legalizeToReg(loOperand(Src1));
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+ Src1HiR = legalizeToReg(hiOperand(Src1));
auto *T_Carry = I32Reg(), *T_Lo = I32Reg(), *T_Hi = I32Reg(),
*T_Hi2 = I32Reg();
_addu(T_Lo, Src0LoR, Src1LoR);
@@ -1823,6 +1815,10 @@ void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr,
return;
}
case InstArithmetic::And: {
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ Src1LoR = legalizeToReg(loOperand(Src1));
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+ Src1HiR = legalizeToReg(hiOperand(Src1));
auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
_and(T_Lo, Src0LoR, Src1LoR);
_mov(DestLo, T_Lo);
@@ -1831,6 +1827,10 @@ void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr,
return;
}
case InstArithmetic::Sub: {
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ Src1LoR = legalizeToReg(loOperand(Src1));
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+ Src1HiR = legalizeToReg(hiOperand(Src1));
auto *T_Borrow = I32Reg(), *T_Lo = I32Reg(), *T_Hi = I32Reg(),
*T_Hi2 = I32Reg();
_subu(T_Lo, Src0LoR, Src1LoR);
@@ -1842,6 +1842,10 @@ void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr,
return;
}
case InstArithmetic::Or: {
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ Src1LoR = legalizeToReg(loOperand(Src1));
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+ Src1HiR = legalizeToReg(hiOperand(Src1));
auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
_or(T_Lo, Src0LoR, Src1LoR);
_mov(DestLo, T_Lo);
@@ -1850,6 +1854,10 @@ void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr,
return;
}
case InstArithmetic::Xor: {
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ Src1LoR = legalizeToReg(loOperand(Src1));
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+ Src1HiR = legalizeToReg(hiOperand(Src1));
auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
_xor(T_Lo, Src0LoR, Src1LoR);
_mov(DestLo, T_Lo);
@@ -1860,6 +1868,10 @@ void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr,
case InstArithmetic::Mul: {
// TODO(rkotler): Make sure that mul has the side effect of clobbering
// LO, HI. Check for any other LO, HI quirkiness in this section.
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ Src1LoR = legalizeToReg(loOperand(Src1));
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+ Src1HiR = legalizeToReg(hiOperand(Src1));
auto *T_Lo = I32Reg(RegMIPS32::Reg_LO), *T_Hi = I32Reg(RegMIPS32::Reg_HI);
auto *T1 = I32Reg(), *T2 = I32Reg();
auto *TM1 = I32Reg(), *TM2 = I32Reg(), *TM3 = I32Reg(), *TM4 = I32Reg();
@@ -1875,6 +1887,172 @@ void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr,
_mov(DestHi, TM4);
return;
}
+ case InstArithmetic::Shl: {
+ auto *T_Lo = I32Reg();
+ auto *T_Hi = I32Reg();
+ auto *T1_Lo = I32Reg();
+ auto *T1_Hi = I32Reg();
+ auto *T1 = I32Reg();
+ auto *T2 = I32Reg();
+ auto *T3 = I32Reg();
+ auto *T4 = I32Reg();
+ auto *T5 = I32Reg();
+
+ if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Src1)) {
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ int64_t ShiftAmount = Const->getValue();
+ if (ShiftAmount == 1) {
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+ _addu(T_Lo, Src0LoR, Src0LoR);
+ _sltu(T1, T_Lo, Src0LoR);
+ _addu(T2, T1, Src0HiR);
+ _addu(T_Hi, Src0HiR, T2);
+ } else if (ShiftAmount < INT32_BITS) {
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+ _srl(T1, Src0LoR, INT32_BITS - ShiftAmount);
+ _sll(T2, Src0HiR, ShiftAmount);
+ _or(T_Hi, T1, T2);
+ _sll(T_Lo, Src0LoR, ShiftAmount);
+ } else if (ShiftAmount == INT32_BITS) {
+ _addiu(T_Lo, getZero(), 0);
+ _mov(T_Hi, Src0LoR);
+ } else if (ShiftAmount > INT32_BITS && ShiftAmount < 64) {
+ _sll(T_Hi, Src0LoR, ShiftAmount - INT32_BITS);
+ _addiu(T_Lo, getZero(), 0);
+ }
+ _mov(DestLo, T_Lo);
+ _mov(DestHi, T_Hi);
+ return;
+ }
+
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ Src1LoR = legalizeToReg(loOperand(Src1));
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+
+ _sllv(T1, Src0HiR, Src1LoR);
+ _not(T2, Src1LoR);
+ _srl(T3, Src0LoR, 1);
+ _srlv(T4, T3, T2);
+ _or(T_Hi, T1, T4);
+ _sllv(T_Lo, Src0LoR, Src1LoR);
+
+ _mov(T1_Hi, T_Hi);
+ _mov(T1_Lo, T_Lo);
+ _andi(T5, Src1LoR, INT32_BITS);
+ _movn(T1_Hi, T_Lo, T5);
+ _movn(T1_Lo, getZero(), T5);
+ _mov(DestHi, T1_Hi);
+ _mov(DestLo, T1_Lo);
+ return;
+ }
+ case InstArithmetic::Lshr: {
+
+ auto *T_Lo = I32Reg();
+ auto *T_Hi = I32Reg();
+ auto *T1_Lo = I32Reg();
+ auto *T1_Hi = I32Reg();
+ auto *T1 = I32Reg();
+ auto *T2 = I32Reg();
+ auto *T3 = I32Reg();
+ auto *T4 = I32Reg();
+ auto *T5 = I32Reg();
+
+ if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Src1)) {
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+ int64_t ShiftAmount = Const->getValue();
+ if (ShiftAmount < INT32_BITS) {
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ _sll(T1, Src0HiR, INT32_BITS - ShiftAmount);
+ _srl(T2, Src0LoR, ShiftAmount);
+ _or(T_Lo, T1, T2);
+ _srl(T_Hi, Src0HiR, ShiftAmount);
+ } else if (ShiftAmount == INT32_BITS) {
+ _mov(T_Lo, Src0HiR);
+ _addiu(T_Hi, getZero(), 0);
+ } else if (ShiftAmount > INT32_BITS && ShiftAmount < 64) {
+ _srl(T_Lo, Src0HiR, ShiftAmount - INT32_BITS);
+ _addiu(T_Hi, getZero(), 0);
+ }
+ _mov(DestLo, T_Lo);
+ _mov(DestHi, T_Hi);
+ return;
+ }
+
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ Src1LoR = legalizeToReg(loOperand(Src1));
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+
+ _srlv(T1, Src0LoR, Src1LoR);
+ _not(T2, Src1LoR);
+ _sll(T3, Src0HiR, 1);
+ _sllv(T4, T3, T2);
+ _or(T_Lo, T1, T4);
+ _srlv(T_Hi, Src0HiR, Src1LoR);
+
+ _mov(T1_Hi, T_Hi);
+ _mov(T1_Lo, T_Lo);
+ _andi(T5, Src1LoR, INT32_BITS);
+ _movn(T1_Lo, T_Hi, T5);
+ _movn(T1_Hi, getZero(), T5);
+ _mov(DestHi, T1_Hi);
+ _mov(DestLo, T1_Lo);
+ return;
+ }
+ case InstArithmetic::Ashr: {
+
+ auto *T_Lo = I32Reg();
+ auto *T_Hi = I32Reg();
+ auto *T1_Lo = I32Reg();
+ auto *T1_Hi = I32Reg();
+ auto *T1 = I32Reg();
+ auto *T2 = I32Reg();
+ auto *T3 = I32Reg();
+ auto *T4 = I32Reg();
+ auto *T5 = I32Reg();
+ auto *T6 = I32Reg();
+
+ if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Src1)) {
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+ int64_t ShiftAmount = Const->getValue();
+ if (ShiftAmount < INT32_BITS) {
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ _sll(T1, Src0HiR, INT32_BITS - ShiftAmount);
+ _srl(T2, Src0LoR, ShiftAmount);
+ _or(T_Lo, T1, T2);
+ _sra(T_Hi, Src0HiR, ShiftAmount);
+ } else if (ShiftAmount == INT32_BITS) {
+ _sra(T_Hi, Src0HiR, INT32_BITS - 1);
+ _mov(T_Lo, Src0HiR);
+ } else if (ShiftAmount > INT32_BITS && ShiftAmount < 64) {
+ _sra(T_Lo, Src0HiR, ShiftAmount - INT32_BITS);
+ _sra(T_Hi, Src0HiR, INT32_BITS - 1);
+ }
+ _mov(DestLo, T_Lo);
+ _mov(DestHi, T_Hi);
+ return;
+ }
+
+ Src0LoR = legalizeToReg(loOperand(Src0));
+ Src1LoR = legalizeToReg(loOperand(Src1));
+ Src0HiR = legalizeToReg(hiOperand(Src0));
+
+ _srlv(T1, Src0LoR, Src1LoR);
+ _not(T2, Src1LoR);
+ _sll(T3, Src0HiR, 1);
+ _sllv(T4, T3, T2);
+ _or(T_Lo, T1, T4);
+ _srav(T_Hi, Src0HiR, Src1LoR);
+
+ _mov(T1_Hi, T_Hi);
+ _mov(T1_Lo, T_Lo);
+ _andi(T5, Src1LoR, INT32_BITS);
+ _movn(T1_Lo, T_Hi, T5);
+ _sra(T6, Src0HiR, INT32_BITS - 1);
+ _movn(T1_Hi, T6, T5);
+ _mov(DestHi, T1_Hi);
+ _mov(DestLo, T1_Lo);
+ return;
+ }
default:
UnimplementedLoweringError(this, Instr);
return;
@@ -3373,9 +3551,8 @@ void TargetMIPS32::prelowerPhis() {
void TargetMIPS32::postLower() {
if (Func->getOptLevel() == Opt_m1)
return;
- // TODO(rkotler): Find two-address non-SSA instructions where Dest==Src0,
- // and set the IsDestRedefined flag to keep liveness analysis consistent.
- UnimplementedError(getFlags());
+ markRedefinitions();
+ Context.availabilityUpdate();
}
void TargetMIPS32::makeRandomRegisterPermutation(

Powered by Google App Engine
This is Rietveld 408576698