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"; ...@@ -65,10 +65,14 @@ template <> const char *InstMIPS32Mult::Opcode = "mult";
template <> const char *InstMIPS32Multu::Opcode = "multu"; template <> const char *InstMIPS32Multu::Opcode = "multu";
template <> const char *InstMIPS32Or::Opcode = "or"; template <> const char *InstMIPS32Or::Opcode = "or";
template <> const char *InstMIPS32Ori::Opcode = "ori"; 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 *InstMIPS32Sltu::Opcode = "sltu";
template <> const char *InstMIPS32Sub::Opcode = "sub"; template <> const char *InstMIPS32Sub::Opcode = "sub";
template <> const char *InstMIPS32Subu::Opcode = "subu"; template <> const char *InstMIPS32Subu::Opcode = "subu";
template <> const char *InstMIPS32Xor::Opcode = "xor"; template <> const char *InstMIPS32Xor::Opcode = "xor";
template <> const char *InstMIPS32Xori::Opcode = "xori";
template <> void InstMIPS32Mflo::emit(const Cfg *Func) const { template <> void InstMIPS32Mflo::emit(const Cfg *Func) const {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
......
...@@ -118,9 +118,9 @@ public: ...@@ -118,9 +118,9 @@ public:
enum InstKindMIPS32 { enum InstKindMIPS32 {
k__Start = Inst::Target, k__Start = Inst::Target,
Add, Add,
Addiu,
Addu, Addu,
And, And,
Addiu,
Br, Br,
Call, Call,
La, La,
...@@ -137,10 +137,14 @@ public: ...@@ -137,10 +137,14 @@ public:
Or, Or,
Ori, Ori,
Ret, Ret,
Slt,
Slti,
Sltiu,
Sltu,
Sub, Sub,
Subu, Subu,
Sltu, Xor,
Xor Xori
}; };
static const char *getWidthString(Type Ty); static const char *getWidthString(Type Ty);
...@@ -469,11 +473,15 @@ using InstMIPS32Mult = InstMIPS32ThreeAddrGPR<InstMIPS32::Mult>; ...@@ -469,11 +473,15 @@ using InstMIPS32Mult = InstMIPS32ThreeAddrGPR<InstMIPS32::Mult>;
using InstMIPS32Multu = InstMIPS32ThreeAddrGPR<InstMIPS32::Multu>; using InstMIPS32Multu = InstMIPS32ThreeAddrGPR<InstMIPS32::Multu>;
using InstMIPS32Or = InstMIPS32ThreeAddrGPR<InstMIPS32::Or>; using InstMIPS32Or = InstMIPS32ThreeAddrGPR<InstMIPS32::Or>;
using InstMIPS32Ori = InstMIPS32Imm16<InstMIPS32::Ori>; 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 InstMIPS32Sltu = InstMIPS32ThreeAddrGPR<InstMIPS32::Sltu>;
using InstMIPS32Sub = InstMIPS32ThreeAddrGPR<InstMIPS32::Sub>; using InstMIPS32Sub = InstMIPS32ThreeAddrGPR<InstMIPS32::Sub>;
using InstMIPS32Subu = InstMIPS32ThreeAddrGPR<InstMIPS32::Subu>; using InstMIPS32Subu = InstMIPS32ThreeAddrGPR<InstMIPS32::Subu>;
using InstMIPS32Ori = InstMIPS32Imm16<InstMIPS32::Ori>; using InstMIPS32Ori = InstMIPS32Imm16<InstMIPS32::Ori>;
using InstMIPS32Xor = InstMIPS32ThreeAddrGPR<InstMIPS32::Xor>; using InstMIPS32Xor = InstMIPS32ThreeAddrGPR<InstMIPS32::Xor>;
using InstMIPS32Xori = InstMIPS32Imm16<InstMIPS32::Xori>;
/// Handles (some of) vmov's various formats. /// Handles (some of) vmov's various formats.
class InstMIPS32Mov final : public InstMIPS32 { class InstMIPS32Mov final : public InstMIPS32 {
......
...@@ -956,8 +956,104 @@ void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) { ...@@ -956,8 +956,104 @@ void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) {
UnimplementedLoweringError(this, Instr); UnimplementedLoweringError(this, Instr);
} }
void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) { void TargetMIPS32::lower64Icmp(const InstIcmp *Instr) {
UnimplementedLoweringError(this, 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) { void TargetMIPS32::lowerInsertElement(const InstInsertElement *Instr) {
......
...@@ -216,14 +216,26 @@ public: ...@@ -216,14 +216,26 @@ public:
Context.insert<InstMIPS32Ori>(Dest, Src, Imm); Context.insert<InstMIPS32Ori>(Dest, Src, Imm);
} }
void _sub(Variable *Dest, Variable *Src0, Variable *Src1) { void _slt(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Sub>(Dest, Src0, 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) { void _sltu(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Sltu>(Dest, Src0, 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) { void _subu(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Subu>(Dest, Src0, Src1); Context.insert<InstMIPS32Subu>(Dest, Src0, Src1);
} }
...@@ -232,6 +244,10 @@ public: ...@@ -232,6 +244,10 @@ public:
Context.insert<InstMIPS32Xor>(Dest, Src0, Src1); Context.insert<InstMIPS32Xor>(Dest, Src0, Src1);
} }
void _xori(Variable *Dest, Variable *Src, uint32_t Imm) {
Context.insert<InstMIPS32Xori>(Dest, Src, Imm);
}
void lowerArguments() override; void lowerArguments() override;
/// Operand legalization helpers. To deal with address mode constraints, /// Operand legalization helpers. To deal with address mode constraints,
...@@ -257,6 +273,10 @@ public: ...@@ -257,6 +273,10 @@ public:
Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT()); Variable *makeReg(Type Ty, RegNumT RegNum = RegNumT());
Variable *getZero() {
return getPhysicalRegister(RegMIPS32::Reg_ZERO, IceType_i32);
}
Variable *I32Reg(RegNumT RegNum = RegNumT()) { Variable *I32Reg(RegNumT RegNum = RegNumT()) {
return makeReg(IceType_i32, RegNum); return makeReg(IceType_i32, RegNum);
} }
...@@ -293,6 +313,7 @@ protected: ...@@ -293,6 +313,7 @@ protected:
void lowerExtractElement(const InstExtractElement *Instr) override; void lowerExtractElement(const InstExtractElement *Instr) override;
void lowerFcmp(const InstFcmp *Instr) override; void lowerFcmp(const InstFcmp *Instr) override;
void lowerIcmp(const InstIcmp *Instr) override; void lowerIcmp(const InstIcmp *Instr) override;
void lower64Icmp(const InstIcmp *Instr);
void lowerIntrinsicCall(const InstIntrinsicCall *Instr) override; void lowerIntrinsicCall(const InstIntrinsicCall *Instr) override;
void lowerInsertElement(const InstInsertElement *Instr) override; void lowerInsertElement(const InstInsertElement *Instr) override;
void lowerLoad(const InstLoad *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