Index: src/IceTargetLoweringMIPS32.cpp |
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
index f2651bf7bd312b94e196fd10b925173d09873d7e..4e0c046bedd52b2d27e782246a1adf692cd47980 100644 |
--- a/src/IceTargetLoweringMIPS32.cpp |
+++ b/src/IceTargetLoweringMIPS32.cpp |
@@ -2239,63 +2239,207 @@ void TargetMIPS32::lowerBr(const InstBr *Instr) { |
Operand *Src1 = CompareInst->getSrc(1); |
const Type Src0Ty = Src0->getType(); |
assert(Src0Ty == Src1->getType()); |
+ |
+ Variable *Src0R = nullptr; |
+ Variable *Src1R = nullptr; |
+ Variable *Src0HiR = nullptr; |
+ Variable *Src1HiR = nullptr; |
if (Src0Ty == IceType_i64) { |
- UnimplementedLoweringError(this, Instr); |
- return; |
+ Src0R = legalizeToReg(loOperand(Src0)); |
+ Src1R = legalizeToReg(loOperand(Src1)); |
+ Src0HiR = legalizeToReg(hiOperand(Src0)); |
+ Src1HiR = legalizeToReg(hiOperand(Src1)); |
+ } else { |
+ Src0R = legalizeToReg(Src0); |
+ Src1R = legalizeToReg(Src1); |
} |
- auto *Src0R = legalizeToReg(Src0); |
- auto *Src1R = legalizeToReg(Src1); |
- auto *DestT = makeReg(Src0Ty); |
+ auto *DestT = makeReg(IceType_i32); |
+ |
switch (CompareInst->getCondition()) { |
default: |
- break; |
+ llvm_unreachable("unexpected condition"); |
+ return; |
case InstIcmp::Eq: { |
- _br(TargetTrue, TargetFalse, Src0R, Src1R, CondMIPS32::Cond::NE); |
- break; |
+ if (Src0Ty == IceType_i64) { |
+ auto *T1 = I32Reg(); |
+ auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ _xor(T1, Src0HiR, Src1HiR); |
+ _xor(T2, Src0R, Src1R); |
+ _or(T3, T1, T2); |
+ _mov(DestT, T3); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } else { |
+ _br(TargetTrue, TargetFalse, Src0R, Src1R, CondMIPS32::Cond::NE); |
+ } |
+ return; |
} |
case InstIcmp::Ne: { |
- _br(TargetTrue, TargetFalse, Src0R, Src1R, CondMIPS32::Cond::EQ); |
- break; |
+ if (Src0Ty == IceType_i64) { |
+ auto *T1 = I32Reg(); |
+ auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ _xor(T1, Src0HiR, Src1HiR); |
+ _xor(T2, Src0R, Src1R); |
+ _or(T3, T1, T2); |
+ _mov(DestT, T3); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ); |
+ } else { |
+ _br(TargetTrue, TargetFalse, Src0R, Src1R, CondMIPS32::Cond::EQ); |
+ } |
+ return; |
} |
case InstIcmp::Ugt: { |
- _sltu(DestT, Src1R, Src0R); |
- _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ); |
- break; |
+ if (Src0Ty == IceType_i64) { |
+ auto *T1 = I32Reg(); |
+ auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ auto *T4 = I32Reg(); |
+ auto *T5 = I32Reg(); |
+ _xor(T1, Src0HiR, Src1HiR); |
+ _sltu(T2, Src1HiR, Src0HiR); |
+ _xori(T3, T2, 1); |
+ _sltu(T4, Src1R, Src0R); |
+ _xori(T5, T4, 1); |
+ _movz(T3, T5, T1); |
+ _mov(DestT, T3); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } else { |
+ _sltu(DestT, Src1R, Src0R); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ); |
+ } |
+ return; |
} |
case InstIcmp::Uge: { |
- _sltu(DestT, Src0R, Src1R); |
- _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
- break; |
+ if (Src0Ty == IceType_i64) { |
+ auto *T1 = I32Reg(); |
+ auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ _xor(T1, Src0HiR, Src1HiR); |
+ _sltu(T2, Src0HiR, Src1HiR); |
+ _sltu(T3, Src0R, Src1R); |
+ _movz(T2, T3, T1); |
+ _mov(DestT, T2); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } else { |
+ _sltu(DestT, Src0R, Src1R); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } |
+ return; |
} |
case InstIcmp::Ult: { |
- _sltu(DestT, Src0R, Src1R); |
- _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ); |
- break; |
+ if (Src0Ty == IceType_i64) { |
+ auto *T1 = I32Reg(); |
+ auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ auto *T4 = I32Reg(); |
+ auto *T5 = I32Reg(); |
+ _xor(T1, Src0HiR, Src1HiR); |
+ _sltu(T2, Src0HiR, Src1HiR); |
+ _xori(T3, T2, 1); |
+ _sltu(T4, Src0R, Src1R); |
+ _xori(T5, T4, 1); |
+ _movz(T3, T5, T1); |
+ _mov(DestT, T3); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } else { |
+ _sltu(DestT, Src0R, Src1R); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ); |
+ } |
+ return; |
} |
case InstIcmp::Ule: { |
- _sltu(DestT, Src1R, Src0R); |
- _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
- break; |
+ if (Src0Ty == IceType_i64) { |
+ auto *T1 = I32Reg(); |
+ auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ _xor(T1, Src0HiR, Src1HiR); |
+ _sltu(T2, Src1HiR, Src0HiR); |
+ _sltu(T3, Src1R, Src0R); |
+ _movz(T2, T3, T1); |
+ _mov(DestT, T2); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } else { |
+ _sltu(DestT, Src1R, Src0R); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } |
+ return; |
} |
case InstIcmp::Sgt: { |
- _slt(DestT, Src1R, Src0R); |
- _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ); |
- break; |
+ if (Src0Ty == IceType_i64) { |
+ auto *T1 = I32Reg(); |
+ auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ auto *T4 = I32Reg(); |
+ auto *T5 = I32Reg(); |
+ _xor(T1, Src0HiR, Src1HiR); |
+ _slt(T2, Src1HiR, Src0HiR); |
+ _xori(T3, T2, 1); |
+ _sltu(T4, Src1R, Src0R); |
+ _xori(T5, T4, 1); |
+ _movz(T3, T5, T1); |
+ _mov(DestT, T3); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } else { |
+ _slt(DestT, Src1R, Src0R); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ); |
+ } |
+ return; |
} |
case InstIcmp::Sge: { |
- _slt(DestT, Src0R, Src1R); |
- _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
- break; |
+ if (Src0Ty == IceType_i64) { |
+ auto *T1 = I32Reg(); |
+ auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ _xor(T1, Src0HiR, Src1HiR); |
+ _slt(T2, Src0HiR, Src1HiR); |
+ _sltu(T3, Src0R, Src1R); |
+ _movz(T2, T3, T1); |
+ _mov(DestT, T2); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } else { |
+ _slt(DestT, Src0R, Src1R); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } |
+ return; |
} |
case InstIcmp::Slt: { |
- _slt(DestT, Src0R, Src1R); |
- _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ); |
- break; |
+ if (Src0Ty == IceType_i64) { |
+ auto *T1 = I32Reg(); |
+ auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ auto *T4 = I32Reg(); |
+ auto *T5 = I32Reg(); |
+ _xor(T1, Src0HiR, Src1HiR); |
+ _slt(T2, Src0HiR, Src1HiR); |
+ _xori(T3, T2, 1); |
+ _sltu(T4, Src0R, Src1R); |
+ _xori(T5, T4, 1); |
+ _movz(T3, T5, T1); |
+ _mov(DestT, T3); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } else { |
+ _slt(DestT, Src0R, Src1R); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::EQZ); |
+ } |
+ return; |
} |
case InstIcmp::Sle: { |
- _slt(DestT, Src1R, Src0R); |
- _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
- break; |
+ if (Src0Ty == IceType_i64) { |
+ auto *T1 = I32Reg(); |
+ auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ _xor(T1, Src0HiR, Src1HiR); |
+ _slt(T2, Src1HiR, Src0HiR); |
+ _sltu(T3, Src1R, Src0R); |
+ _movz(T2, T3, T1); |
+ _mov(DestT, T2); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } else { |
+ _slt(DestT, Src1R, Src0R); |
+ _br(TargetTrue, TargetFalse, DestT, CondMIPS32::Cond::NEZ); |
+ } |
+ return; |
} |
} |
} |
@@ -2913,7 +3057,7 @@ void TargetMIPS32::lower64Icmp(const InstIcmp *Instr) { |
switch (Condition) { |
default: |
llvm_unreachable("unexpected condition"); |
- break; |
+ return; |
case InstIcmp::Eq: { |
auto *T1 = I32Reg(); |
auto *T2 = I32Reg(); |