Index: src/IceTargetLoweringMIPS32.cpp |
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
index 66d17f87bb72969244b628d5cf9a293e11ca47e4..baea0ff87884a321ac5346cf473a1582c2536a69 100644 |
--- a/src/IceTargetLoweringMIPS32.cpp |
+++ b/src/IceTargetLoweringMIPS32.cpp |
@@ -2553,30 +2553,75 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { |
Variable *T = makeReg(Dest->getType()); |
Variable *Src0R = legalizeToReg(Src0); |
- Variable *Src1R = legalizeToReg(Src1); |
+ Variable *Src1R = nullptr; |
+ uint32_t Value = 0; |
+ bool IsSrc1Imm16 = false; |
+ |
+ switch (Instr->getOp()) { |
+ case InstArithmetic::Add: |
+ case InstArithmetic::And: |
+ case InstArithmetic::Or: |
+ case InstArithmetic::Xor: |
+ case InstArithmetic::Sub: |
+ case InstArithmetic::Shl: |
+ case InstArithmetic::Lshr: |
+ case InstArithmetic::Ashr: { |
+ auto *Const32 = llvm::dyn_cast<ConstantInteger32>(Src1); |
+ if (Const32 != nullptr && isInt<16>(int32_t(Const32->getValue()))) { |
+ IsSrc1Imm16 = true; |
+ Value = Const32->getValue(); |
+ } else { |
+ Src1R = legalizeToReg(Src1); |
+ } |
+ break; |
+ } |
+ default: |
+ Src1R = legalizeToReg(Src1); |
+ break; |
+ } |
constexpr uint32_t DivideByZeroTrapCode = 7; |
switch (Instr->getOp()) { |
case InstArithmetic::_num: |
break; |
case InstArithmetic::Add: |
- _addu(T, Src0R, Src1R); |
+ if (IsSrc1Imm16) { |
+ _addiu(T, Src0R, Value); |
+ } else { |
+ _addu(T, Src0R, Src1R); |
+ } |
_mov(Dest, T); |
return; |
case InstArithmetic::And: |
- _and(T, Src0R, Src1R); |
+ if (IsSrc1Imm16) { |
+ _andi(T, Src0R, Value); |
+ } else { |
+ _and(T, Src0R, Src1R); |
+ } |
_mov(Dest, T); |
return; |
case InstArithmetic::Or: |
- _or(T, Src0R, Src1R); |
+ if (IsSrc1Imm16) { |
+ _ori(T, Src0R, Value); |
+ } else { |
+ _or(T, Src0R, Src1R); |
+ } |
_mov(Dest, T); |
return; |
case InstArithmetic::Xor: |
- _xor(T, Src0R, Src1R); |
+ if (IsSrc1Imm16) { |
+ _xori(T, Src0R, Value); |
+ } else { |
+ _xor(T, Src0R, Src1R); |
+ } |
_mov(Dest, T); |
return; |
case InstArithmetic::Sub: |
- _subu(T, Src0R, Src1R); |
+ if (IsSrc1Imm16) { |
+ _addiu(T, Src0R, -Value); |
+ } else { |
+ _subu(T, Src0R, Src1R); |
+ } |
_mov(Dest, T); |
return; |
case InstArithmetic::Mul: { |
@@ -2585,7 +2630,11 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { |
return; |
} |
case InstArithmetic::Shl: { |
- _sllv(T, Src0R, Src1R); |
+ if (IsSrc1Imm16) { |
+ _sll(T, Src0R, Value); |
+ } else { |
+ _sllv(T, Src0R, Src1R); |
+ } |
_mov(Dest, T); |
return; |
} |
@@ -2595,15 +2644,25 @@ void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { |
if (Dest->getType() != IceType_i32) { |
T0R = makeReg(IceType_i32); |
lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); |
- T1R = makeReg(IceType_i32); |
- lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); |
+ if (!IsSrc1Imm16) { |
+ T1R = makeReg(IceType_i32); |
+ lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); |
+ } |
+ } |
+ if (IsSrc1Imm16) { |
+ _srl(T, T0R, Value); |
+ } else { |
+ _srlv(T, T0R, T1R); |
} |
- _srlv(T, T0R, T1R); |
_mov(Dest, T); |
return; |
} |
case InstArithmetic::Ashr: { |
- _srav(T, Src0R, Src1R); |
+ if (IsSrc1Imm16) { |
+ _sra(T, Src0R, Value); |
+ } else { |
+ _srav(T, Src0R, Src1R); |
+ } |
_mov(Dest, T); |
return; |
} |