Chromium Code Reviews| Index: src/IceInstMIPS32.h |
| diff --git a/src/IceInstMIPS32.h b/src/IceInstMIPS32.h |
| index 4b492c0b6783020c744fa1a9fa1828993922c76f..84624f17bf6dbba90a4bb9f95723b47c763325b3 100644 |
| --- a/src/IceInstMIPS32.h |
| +++ b/src/IceInstMIPS32.h |
| @@ -121,8 +121,10 @@ public: |
| Addu, |
| And, |
| Addiu, |
| + Br, |
| Call, |
| La, |
| + Label, |
| Lui, |
| Mfhi, |
| Mflo, |
| @@ -292,6 +294,71 @@ private: |
| static const char *Opcode; |
| }; |
| +// InstMIPS32Label represents an intra-block label that is the target of an |
| +// intra-block branch. The offset between the label and the branch must be fit |
| +// in the instruction immediate (considered "near"). |
| +class InstMIPS32Label : public InstMIPS32 { |
| + InstMIPS32Label() = delete; |
| + InstMIPS32Label(const InstMIPS32Label &) = delete; |
| + InstMIPS32Label &operator=(const InstMIPS32Label &) = delete; |
| + |
| +public: |
| + static InstMIPS32Label *create(Cfg *Func, TargetMIPS32 *Target) { |
| + return new (Func->allocate<InstMIPS32Label>()) |
| + InstMIPS32Label(Func, Target); |
| + } |
| + uint32_t getEmitInstCount() const override { return 0; } |
| + IceString getName(const Cfg *Func) const; |
| + SizeT getNumber() const { return Number; } |
| + void emit(const Cfg *Func) const override; |
| + void emitIAS(const Cfg *Func) const override; |
|
Jim Stichnoth
2016/02/23 06:18:51
Missing definitions of emitIAS() and dump().
rkotlerimgtec
2016/02/23 23:17:20
Done.
|
| + void dump(const Cfg *Func) const override; |
|
Jim Stichnoth
2016/02/23 06:18:51
There should probably be a static classof() method
rkotlerimgtec
2016/02/23 23:17:20
Done.
|
| + |
| +private: |
| + InstMIPS32Label(Cfg *Func, TargetMIPS32 *Target); |
| + |
| + RelocOffset *OffsetReloc = nullptr; |
| + |
| + SizeT Number; // used for unique label generation. |
| +}; |
| + |
| +/// Direct branch instruction. |
| +class InstMIPS32Br : public InstMIPS32 { |
| + InstMIPS32Br() = delete; |
| + InstMIPS32Br(const InstMIPS32Br &) = delete; |
| + InstMIPS32Br &operator=(const InstMIPS32Br &) = delete; |
| + |
| +public: |
| + /// Create an unconditional branch to a node. |
| + static InstMIPS32Br *create(Cfg *Func, CfgNode *Target) { |
| + constexpr CfgNode *NoCondTarget = nullptr; |
| + constexpr InstMIPS32Label *NoLabel = nullptr; |
| + return new (Func->allocate<InstMIPS32Br>()) |
| + InstMIPS32Br(Func, NoCondTarget, Target, NoLabel); |
| + } |
| + const CfgNode *getTargetTrue() const { return TargetTrue; } |
| + const CfgNode *getTargetFalse() const { return TargetFalse; } |
| + |
| + bool isUnconditionalBranch() const override { return true; } |
| + bool repointEdges(CfgNode *OldNode, CfgNode *NewNode) override { |
| + (void)OldNode; |
| + (void)NewNode; |
| + return true; |
| + }; |
| + void emit(const Cfg *Func) const override; |
| + void emitIAS(const Cfg *Func) const override { (void)Func; }; |
| + void dump(const Cfg *Func) const override { (void)Func; }; |
| + static bool classof(const Inst *Instr) { return isClassof(Instr, Br); } |
| + |
| +private: |
| + InstMIPS32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, |
| + const InstMIPS32Label *Label); |
| + |
| + const CfgNode *TargetTrue; |
| + const CfgNode *TargetFalse; |
| + const InstMIPS32Label *Label; // Intra-block branch target |
| +}; |
| + |
| class InstMIPS32Call : public InstMIPS32 { |
| InstMIPS32Call() = delete; |
| InstMIPS32Call(const InstMIPS32Call &) = delete; |