Chromium Code Reviews| Index: src/IceAssemblerMIPS32.h |
| diff --git a/src/IceAssemblerMIPS32.h b/src/IceAssemblerMIPS32.h |
| index 9d78a5b93516f5d7b316ad9aadb3146fac34f6f7..4636a89d36669880b1747347dbe2fffce9bf2223 100644 |
| --- a/src/IceAssemblerMIPS32.h |
| +++ b/src/IceAssemblerMIPS32.h |
| @@ -26,10 +26,15 @@ |
| #include "IceAssembler.h" |
| #include "IceDefs.h" |
| #include "IceFixups.h" |
| +#include "IceInstMIPS32.h" |
| +#include "IceTargetLowering.h" |
| namespace Ice { |
| namespace MIPS32 { |
| +using IValueT = uint32_t; |
| +using IOffsetT = int32_t; |
| + |
| class AssemblerMIPS32 : public Assembler { |
| AssemblerMIPS32(const AssemblerMIPS32 &) = delete; |
| AssemblerMIPS32 &operator=(const AssemblerMIPS32 &) = delete; |
| @@ -41,36 +46,107 @@ public: |
| assert(!use_far_branches); |
| (void)use_far_branches; |
| } |
| - ~AssemblerMIPS32() override = default; |
| + ~AssemblerMIPS32() override { |
| + if (BuildDefs::asserts()) { |
| + for (const Label *Label : CfgNodeLabels) { |
| + Label->finalCheck(); |
| + } |
| + for (const Label *Label : LocalLabels) { |
| + Label->finalCheck(); |
| + } |
| + } |
| + } |
| + |
| + void trap(); |
| + |
| + void nop(); |
| + |
| + void emitRtRsImm16 (IValueT Opcode, const Operand *OpRt, |
| + const Operand *OpRs, const uint32_t Imm, |
| + const char *InsnName); |
| + |
| + void emitRdRtSa(IValueT Opcode, const Operand *OpRd, |
| + const Operand *OpRt, const uint32_t Sa, |
| + const char *InsnName); |
| + |
| + void emitRdRsRt(IValueT Opcode, const Operand *OpRd, |
| + const Operand *OpRs, const Operand *OpRt, |
| + const char *InsnName); |
| + |
| + void emitBr(const CondMIPS32::Cond Cond, const Operand *OpRs, |
| + const Operand *OpRt, IOffsetT Offset); |
| + |
| + void addiu(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| + |
| + void slti(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| + |
| + void sltiu(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| + |
| + void andi(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| + |
| + void ori(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| + |
| + void xori(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| + |
| + void sll(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); |
| + |
| + void srl(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); |
| + |
| + void sra(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); |
| + |
| + void addu(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| + |
| + void slt(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| + |
| + void sw(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset); |
| + |
| + void lw(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset); |
| + |
| + void ret(void); |
| + |
| + void b(Label *TargetLabel); |
| + |
| + void bcc(const CondMIPS32::Cond Cond, const Operand *OpRs, const Operand *OpRt, Label *TargetLabel); |
|
Jim Stichnoth
2016/08/19 17:12:21
80-col
This is usually automatically fixed by run
|
| + |
| + void bzc(const CondMIPS32::Cond Cond, const Operand *OpRs, Label *TargetLabel); |
| void alignFunction() override { |
| - llvm::report_fatal_error("Not yet implemented."); |
| + const SizeT Align = 1 << getBundleAlignLog2Bytes(); |
| + SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align); |
| + constexpr SizeT InstSize = sizeof(IValueT); |
| + assert(BytesNeeded % InstMIPS32::InstSize == 0); |
| + while (BytesNeeded > 0) { |
| + trap(); |
| + BytesNeeded -= InstSize; |
| + } |
| } |
| SizeT getBundleAlignLog2Bytes() const override { return 4; } |
| const char *getAlignDirective() const override { return ".p2alignl"; } |
| - llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override { |
| - // TODO(reed kotler) . Find out what this should be. |
| - static const uint8_t Padding[] = {0xE7, 0xFE, 0xDE, 0xF0}; |
| - return llvm::ArrayRef<uint8_t>(Padding, 4); |
| - } |
| + llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override; |
| - void padWithNop(intptr_t Padding) override { |
| - (void)Padding; |
| - llvm::report_fatal_error("Not yet implemented."); |
| - } |
| + void padWithNop(intptr_t Padding) override; |
| + |
| + void bind(Label *label); |
| + |
| + void emitTextInst(const std::string &Text, SizeT InstSize); |
| Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { |
| - (void)NodeNumber; |
| - llvm_unreachable("Not yet implemented."); |
| + assert(NodeNumber < CfgNodeLabels.size()); |
| + return CfgNodeLabels[NodeNumber]; |
| } |
| - void bindCfgNodeLabel(const CfgNode *) override { |
| - llvm::report_fatal_error("Not yet implemented."); |
| + Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) { |
| + return getOrCreateLabel(NodeNumber, CfgNodeLabels); |
| + } |
| + |
| + Label *getOrCreateLocalLabel(SizeT Number) { |
| + return getOrCreateLabel(Number, LocalLabels); |
| } |
| + |
| bool fixupIsPCRel(FixupKind Kind) const override { |
| (void)Kind; |
| llvm::report_fatal_error("Not yet implemented."); |
| @@ -82,6 +158,22 @@ public: |
| private: |
| ENABLE_MAKE_UNIQUE; |
| + |
| + using LabelVector = std::vector<Label *>; |
| + LabelVector CfgNodeLabels; |
| + LabelVector LocalLabels; |
| + |
| + // Returns the offset encoded in the branch instruction Inst. |
| + static IOffsetT decodeBranchOffset(IValueT Inst); |
| + |
| + Label *getOrCreateLabel(SizeT Number, LabelVector &Labels); |
| + |
| + void bindCfgNodeLabel(const CfgNode *) override; |
| + |
| + void emitInst(IValueT Value) { |
| + AssemblerBuffer::EnsureCapacity _(&Buffer); |
| + Buffer.emit<IValueT>(Value); |
| + } |
| }; |
| } // end of namespace MIPS32 |