Commit 1a478b1c by Sagar Thakur Committed by Jim Stichnoth

[Subzero][MIPS] Implement conditional branches and integer comparisons

R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1898743002 . Patch from Sagar Thakur <sagar.thakur@imgtec.com>.
parent 29acb575
......@@ -65,10 +65,14 @@ template <> const char *InstMIPS32Mult::Opcode = "mult";
template <> const char *InstMIPS32Multu::Opcode = "multu";
template <> const char *InstMIPS32Or::Opcode = "or";
template <> const char *InstMIPS32Ori::Opcode = "ori";
template <> const char *InstMIPS32Slt::Opcode = "slt";
template <> const char *InstMIPS32Slti::Opcode = "slti";
template <> const char *InstMIPS32Sltiu::Opcode = "sltiu";
template <> const char *InstMIPS32Sltu::Opcode = "sltu";
template <> const char *InstMIPS32Sub::Opcode = "sub";
template <> const char *InstMIPS32Subu::Opcode = "subu";
template <> const char *InstMIPS32Xor::Opcode = "xor";
template <> const char *InstMIPS32Xori::Opcode = "xori";
template <> void InstMIPS32Mflo::emit(const Cfg *Func) const {
if (!BuildDefs::dump())
......
......@@ -118,9 +118,9 @@ public:
enum InstKindMIPS32 {
k__Start = Inst::Target,
Add,
Addiu,
Addu,
And,
Addiu,
Br,
Call,
La,
......@@ -137,10 +137,14 @@ public:
Or,
Ori,
Ret,
Slt,
Slti,
Sltiu,
Sltu,
Sub,
Subu,
Sltu,
Xor
Xor,
Xori
};
static const char *getWidthString(Type Ty);
......@@ -469,11 +473,15 @@ using InstMIPS32Mult = InstMIPS32ThreeAddrGPR<InstMIPS32::Mult>;
using InstMIPS32Multu = InstMIPS32ThreeAddrGPR<InstMIPS32::Multu>;
using InstMIPS32Or = InstMIPS32ThreeAddrGPR<InstMIPS32::Or>;
using InstMIPS32Ori = InstMIPS32Imm16<InstMIPS32::Ori>;
using InstMIPS32Slt = InstMIPS32ThreeAddrGPR<InstMIPS32::Slt>;
using InstMIPS32Slti = InstMIPS32Imm16<InstMIPS32::Slti>;
using InstMIPS32Sltiu = InstMIPS32Imm16<InstMIPS32::Sltiu>;
using InstMIPS32Sltu = InstMIPS32ThreeAddrGPR<InstMIPS32::Sltu>;
using InstMIPS32Sub = InstMIPS32ThreeAddrGPR<InstMIPS32::Sub>;
using InstMIPS32Subu = InstMIPS32ThreeAddrGPR<InstMIPS32::Subu>;
using InstMIPS32Ori = InstMIPS32Imm16<InstMIPS32::Ori>;
using InstMIPS32Xor = InstMIPS32ThreeAddrGPR<InstMIPS32::Xor>;
using InstMIPS32Xori = InstMIPS32Imm16<InstMIPS32::Xori>;
/// Handles (some of) vmov's various formats.
class InstMIPS32Mov final : public InstMIPS32 {
......
......@@ -956,8 +956,104 @@ void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) {
UnimplementedLoweringError(this, Instr);
}
void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) {
void TargetMIPS32::lower64Icmp(const InstIcmp *Instr) {
UnimplementedLoweringError(this, Instr);
return;
}
void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) {
auto *Src0 = Instr->getSrc(0);
auto *Src1 = Instr->getSrc(1);
if (Src0->getType() == IceType_i64) {
lower64Icmp(Instr);
return;
}
Variable *Dest = Instr->getDest();
if (isVectorType(Dest->getType())) {
UnimplementedLoweringError(this, Instr);
return;
}
InstIcmp::ICond Cond = Instr->getCondition();
auto *Src0R = legalizeToReg(Src0);
auto *Src1R = legalizeToReg(Src1);
switch (Cond) {
case InstIcmp::Eq: {
auto *DestT = I32Reg();
auto *T = I32Reg();
_xor(T, Src0R, Src1R);
_sltiu(DestT, T, 1);
_mov(Dest, DestT);
return;
}
case InstIcmp::Ne: {
auto *DestT = I32Reg();
auto *T = I32Reg();
auto *Zero = getZero();
_xor(T, Src0R, Src1R);
_sltu(DestT, Zero, T);
_mov(Dest, DestT);
return;
}
case InstIcmp::Ugt: {
auto *DestT = I32Reg();
_sltu(DestT, Src1R, Src0R);
_mov(Dest, DestT);
return;
}
case InstIcmp::Uge: {
auto *DestT = I32Reg();
auto *T = I32Reg();
_sltu(T, Src0R, Src1R);
_xori(DestT, T, 1);
_mov(Dest, DestT);
return;
}
case InstIcmp::Ult: {
auto *DestT = I32Reg();
_sltu(DestT, Src0R, Src1R);
_mov(Dest, DestT);
return;
}
case InstIcmp::Ule: {
auto *DestT = I32Reg();
auto *T = I32Reg();
_sltu(T, Src1R, Src0R);
_xori(DestT, T, 1);
_mov(Dest, DestT);
return;
}
case InstIcmp::Sgt: {
auto *DestT = I32Reg();
_slt(DestT, Src1R, Src0R);
_mov(Dest, DestT);
return;
}
case InstIcmp::Sge: {
auto *DestT = I32Reg();
auto *T = I32Reg();
_slt(T, Src1R, Src0R);
_xori(DestT, T, 1);
_mov(Dest, DestT);
return;
}
case InstIcmp::Slt: {
auto *DestT = I32Reg();
_slt(DestT, Src0R, Src1R);
_mov(Dest, DestT);
return;
}
case InstIcmp::Sle: {
auto *DestT = I32Reg();
auto *T = I32Reg();
_slt(T, Src1R, Src0R);
_xori(DestT, T, 1);
_mov(Dest, DestT);
return;
}
default:
llvm_unreachable("Invalid ICmp operator");
return;
}
}
void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) {
......
......@@ -216,14 +216,26 @@ public:
Context.insert<InstMIPS32Ori>(Dest, Src, Imm);
}
void _sub(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Sub>(Dest, Src0, Src1);
void _slt(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Slt>(Dest, Src0, Src1);
}
void _slti(Variable *Dest, Variable *Src, uint32_t Imm) {
Context.insert<InstMIPS32Slti>(Dest, Src, Imm);
}
void _sltiu(Variable *Dest, Variable *Src, uint32_t Imm) {
Context.insert<InstMIPS32Sltiu>(Dest, Src, Imm);
}
void _sltu(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Sltu>(Dest, Src0, Src1);
}
void _sub(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Sub>(Dest, Src0, Src1);
}
void _subu(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Subu>(Dest, Src0, Src1);
}
......@@ -232,6 +244,10 @@ public:
Context.insert<InstMIPS32Xor>(Dest, Src0, Src1);
}
void _xori(Variable *Dest, Variable *Src, uint32_t Imm) {
Context.insert<InstMIPS32Xori>(Dest, Src, Imm);
}
void lowerArguments() override;
/// Operand legalization helpers. To deal with address mode constraints,
......@@ -257,6 +273,10 @@ public:
Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT());
Variable *getZero() {
return getPhysicalRegister(RegMIPS32::Reg_ZERO, IceType_i32);
}
Variable *I32Reg(RegNumT RegNum = RegNumT()) {
return makeReg(IceType_i32, RegNum);
}
......@@ -293,6 +313,7 @@ protected:
void lowerExtractElement(const InstExtractElement *Instr) override;
void lowerFcmp(const InstFcmp *Instr) override;
void lowerIcmp(const InstIcmp *Instr) override;
void lower64Icmp(const InstIcmp *Instr);
void lowerIntrinsicCall(const InstIntrinsicCall *Instr) override;
void lowerInsertElement(const InstInsertElement *Instr) override;
void lowerLoad(const InstLoad *Instr) override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment