Index: src/IceInstMIPS32.h |
diff --git a/src/IceInstMIPS32.h b/src/IceInstMIPS32.h |
index 636c1af8e6452a9a8b09e3fccb4477f1ed305f55..288d3af39450843bbf00feec7cac9d047b1ad41d 100644 |
--- a/src/IceInstMIPS32.h |
+++ b/src/IceInstMIPS32.h |
@@ -55,6 +55,7 @@ class OperandMIPS32 : public Operand { |
public: |
enum OperandKindMIPS32 { |
k__Start = Operand::kTarget, |
+ kFCC, |
kMem, |
}; |
@@ -69,6 +70,43 @@ protected: |
: Operand(static_cast<OperandKind>(Kind), Ty) {} |
}; |
+class OperandMIPS32FCC : public OperandMIPS32 { |
+ OperandMIPS32FCC() = delete; |
+ OperandMIPS32FCC(const OperandMIPS32FCC &) = delete; |
+ OperandMIPS32FCC &operator=(const OperandMIPS32FCC &) = delete; |
+ |
+public: |
+ enum FCC { FCC0 = 0, FCC1, FCC2, FCC3, FCC4, FCC5, FCC6, FCC7 }; |
+ static OperandMIPS32FCC *create(Cfg *Func, Type Ty, |
+ OperandMIPS32FCC::FCC FCC) { |
+ return new (Func->allocate<OperandMIPS32FCC>()) |
+ OperandMIPS32FCC(Func, Ty, FCC); |
+ } |
+ |
+ void emit(const Cfg *Func) const override { |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
Jim Stichnoth
2016/09/12 14:14:40
Add the usual pattern at the beginning of emit() a
obucinac
2016/09/12 19:16:15
Done.
|
+ |
+ Str << "$fcc" << (uint16_t)FCC; |
Jim Stichnoth
2016/09/12 14:14:40
static_cast<>
obucinac
2016/09/12 19:16:16
Done.
|
+ } |
+ |
+ static bool classof(const Operand *Operand) { |
+ return Operand->getKind() == static_cast<OperandKind>(kFCC); |
+ } |
+ |
+ void dump(const Cfg *Func, Ostream &Str) const override { |
+ (void)Func; |
+ (void)Str; |
+ } |
+ |
+private: |
+ OperandMIPS32FCC(Cfg *Func, Type Ty, OperandMIPS32FCC::FCC FCC) |
Jim Stichnoth
2016/09/12 14:14:40
Optional:
s/Func//
Then you can remove the void-ca
obucinac
2016/09/12 19:16:16
Done.
|
+ : OperandMIPS32(kFCC, Ty), FCC(FCC) { |
Jim Stichnoth
2016/09/12 14:14:41
I don't think the Type makes much sense here, espe
obucinac
2016/09/12 19:16:15
Done.
|
+ (void)Func; |
+ }; |
+ |
+ OperandMIPS32FCC::FCC FCC; |
Jim Stichnoth
2016/09/12 14:14:40
const
obucinac
2016/09/12 19:16:15
Done.
|
+}; |
+ |
class OperandMIPS32Mem : public OperandMIPS32 { |
OperandMIPS32Mem() = delete; |
OperandMIPS32Mem(const OperandMIPS32Mem &) = delete; |
@@ -153,6 +191,20 @@ public: |
And, |
Andi, |
Br, |
+ C_eq_d, |
+ C_eq_s, |
+ C_ole_d, |
+ C_ole_s, |
+ C_olt_d, |
+ C_olt_s, |
+ C_ueq_d, |
+ C_ueq_s, |
+ C_ule_d, |
+ C_ule_s, |
+ C_ult_d, |
+ C_ult_s, |
+ C_un_d, |
+ C_un_s, |
Call, |
Cvt_d_l, |
Cvt_d_s, |
@@ -176,6 +228,8 @@ public: |
Mov, // actually a pseudo op for addi rd, rs, 0 |
Mov_d, |
Mov_s, |
+ Movf, |
+ Movt, |
Mtc1, |
Mthi, |
Mtlo, |
@@ -802,6 +856,56 @@ private: |
InstMIPS32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); |
}; |
+template <InstMIPS32::InstKindMIPS32 K> |
Jim Stichnoth
2016/09/12 14:14:40
You may want to consider defining a single InstMIP
obucinac
2016/09/12 19:16:15
I would like to leave it as it is, for the consist
|
+class InstMIPS32FPCmp : public InstMIPS32 { |
+ InstMIPS32FPCmp() = delete; |
+ InstMIPS32FPCmp(const InstMIPS32FPCmp &) = delete; |
+ InstMIPS32Call &operator=(const InstMIPS32FPCmp &) = delete; |
+ |
+public: |
+ static InstMIPS32FPCmp *create(Cfg *Func, Variable *Src0, Variable *Src1) { |
+ return new (Func->allocate<InstMIPS32FPCmp>()) |
+ InstMIPS32FPCmp(Func, Src0, Src1); |
+ } |
+ |
+ void emit(const Cfg *Func) const override { |
+ if (!BuildDefs::dump()) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ assert(getSrcSize() == 2); |
+ Str << "\t" << Opcode << "\t"; |
+ getSrc(0)->emit(Func); |
+ Str << ", "; |
+ getSrc(1)->emit(Func); |
+ } |
+ |
+ void emitIAS(const Cfg *Func) const override { |
+ (void)Func; |
+ llvm_unreachable("Not yet implemented"); |
+ } |
+ |
+ void dump(const Cfg *Func) const override { |
+ (void)Func; |
+ if (!BuildDefs::dump()) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrDump(); |
+ dumpOpcode(Str, Opcode, getSrc(0)->getType()); |
+ Str << " "; |
+ dumpSources(Func); |
+ } |
+ |
+ static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } |
+ |
+private: |
+ InstMIPS32FPCmp(Cfg *Func, Variable *Src0, Variable *Src1) |
+ : InstMIPS32(Func, K, 2, nullptr) { |
+ addSource(Src0); |
+ addSource(Src1); |
+ }; |
+ |
+ static const char *Opcode; |
+}; |
+ |
template <InstMIPS32::InstKindMIPS32 K, bool Signed = false> |
class InstMIPS32Imm16 : public InstMIPS32 { |
InstMIPS32Imm16() = delete; |
@@ -873,6 +977,62 @@ private: |
const uint32_t Imm; |
}; |
+/// Conditional mov |
+template <InstMIPS32::InstKindMIPS32 K> |
+class InstMIPS32MovConditional : public InstMIPS32 { |
+ InstMIPS32MovConditional() = delete; |
+ InstMIPS32MovConditional(const InstMIPS32MovConditional &) = delete; |
+ InstMIPS32MovConditional & |
+ operator=(const InstMIPS32MovConditional &) = delete; |
+ |
+public: |
+ static InstMIPS32MovConditional *create(Cfg *Func, Variable *Dest, |
+ Variable *Src, Operand *FCC) { |
+ return new (Func->allocate<InstMIPS32MovConditional>()) |
+ InstMIPS32MovConditional(Func, Dest, Src, FCC); |
+ } |
+ |
+ void emit(const Cfg *Func) const override { |
+ if (!BuildDefs::dump()) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrEmit(); |
+ assert(getSrcSize() == 2); |
+ Str << "\t" << Opcode << "\t"; |
+ getDest()->emit(Func); |
+ Str << ", "; |
+ getSrc(0)->emit(Func); |
+ Str << ", "; |
+ getSrc(1)->emit(Func); |
+ } |
+ |
+ void emitIAS(const Cfg *Func) const override { |
+ (void)Func; |
+ llvm_unreachable("Not yet implemented"); |
+ } |
+ |
+ void dump(const Cfg *Func) const override { |
+ if (!BuildDefs::dump()) |
+ return; |
+ Ostream &Str = Func->getContext()->getStrDump(); |
+ dumpDest(Func); |
+ Str << " = "; |
+ dumpOpcode(Str, Opcode, getDest()->getType()); |
+ Str << " "; |
+ dumpSources(Func); |
+ } |
+ static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
+ |
+private: |
+ InstMIPS32MovConditional(Cfg *Func, Variable *Dest, Variable *Src, |
+ Operand *FCC) |
+ : InstMIPS32(Func, K, 2, Dest) { |
+ addSource(Src); |
+ addSource(FCC); |
+ } |
+ |
+ static const char *Opcode; |
+}; |
+ |
using InstMIPS32Add = InstMIPS32ThreeAddrGPR<InstMIPS32::Add>; |
using InstMIPS32Add_d = InstMIPS32ThreeAddrFPR<InstMIPS32::Add_d>; |
using InstMIPS32Add_s = InstMIPS32ThreeAddrFPR<InstMIPS32::Add_s>; |
@@ -880,6 +1040,20 @@ using InstMIPS32Addu = InstMIPS32ThreeAddrGPR<InstMIPS32::Addu>; |
using InstMIPS32Addiu = InstMIPS32Imm16<InstMIPS32::Addiu, true>; |
using InstMIPS32And = InstMIPS32ThreeAddrGPR<InstMIPS32::And>; |
using InstMIPS32Andi = InstMIPS32Imm16<InstMIPS32::Andi>; |
+using InstMIPS32C_eq_d = InstMIPS32FPCmp<InstMIPS32::C_eq_d>; |
+using InstMIPS32C_eq_s = InstMIPS32FPCmp<InstMIPS32::C_eq_s>; |
+using InstMIPS32C_ole_d = InstMIPS32FPCmp<InstMIPS32::C_ole_d>; |
+using InstMIPS32C_ole_s = InstMIPS32FPCmp<InstMIPS32::C_ole_s>; |
+using InstMIPS32C_olt_d = InstMIPS32FPCmp<InstMIPS32::C_olt_d>; |
+using InstMIPS32C_olt_s = InstMIPS32FPCmp<InstMIPS32::C_olt_s>; |
+using InstMIPS32C_ueq_d = InstMIPS32FPCmp<InstMIPS32::C_ueq_d>; |
+using InstMIPS32C_ueq_s = InstMIPS32FPCmp<InstMIPS32::C_ueq_s>; |
+using InstMIPS32C_ule_d = InstMIPS32FPCmp<InstMIPS32::C_ule_d>; |
+using InstMIPS32C_ule_s = InstMIPS32FPCmp<InstMIPS32::C_ule_s>; |
+using InstMIPS32C_ult_d = InstMIPS32FPCmp<InstMIPS32::C_ult_d>; |
+using InstMIPS32C_ult_s = InstMIPS32FPCmp<InstMIPS32::C_ult_s>; |
+using InstMIPS32C_un_d = InstMIPS32FPCmp<InstMIPS32::C_un_d>; |
+using InstMIPS32C_un_s = InstMIPS32FPCmp<InstMIPS32::C_un_s>; |
using InstMIPS32Cvt_d_s = InstMIPS32TwoAddrFPR<InstMIPS32::Cvt_d_s>; |
using InstMIPS32Cvt_d_l = InstMIPS32TwoAddrFPR<InstMIPS32::Cvt_d_l>; |
using InstMIPS32Cvt_d_w = InstMIPS32TwoAddrFPR<InstMIPS32::Cvt_d_w>; |
@@ -900,6 +1074,8 @@ using InstMIPS32Mfhi = InstMIPS32UnaryopGPR<InstMIPS32::Mfhi>; |
using InstMIPS32Mflo = InstMIPS32UnaryopGPR<InstMIPS32::Mflo>; |
using InstMIPS32Mov_d = InstMIPS32TwoAddrFPR<InstMIPS32::Mov_d>; |
using InstMIPS32Mov_s = InstMIPS32TwoAddrFPR<InstMIPS32::Mov_s>; |
+using InstMIPS32Movf = InstMIPS32MovConditional<InstMIPS32::Movf>; |
+using InstMIPS32Movt = InstMIPS32MovConditional<InstMIPS32::Movt>; |
using InstMIPS32Mtc1 = InstMIPS32TwoAddrGPR<InstMIPS32::Mtc1>; |
using InstMIPS32Mthi = InstMIPS32UnaryopGPR<InstMIPS32::Mthi>; |
using InstMIPS32Mtlo = InstMIPS32UnaryopGPR<InstMIPS32::Mtlo>; |