Chromium Code Reviews| 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>; |