Index: src/IceAssemblerMIPS32.h |
diff --git a/src/IceAssemblerMIPS32.h b/src/IceAssemblerMIPS32.h |
index 9d78a5b93516f5d7b316ad9aadb3146fac34f6f7..eefb1b2004e7f0e55c73013bba50967dd4b17d15 100644 |
--- a/src/IceAssemblerMIPS32.h |
+++ b/src/IceAssemblerMIPS32.h |
@@ -1,13 +1,5 @@ |
//===- subzero/src/IceAssemblerMIPS32.h - Assembler for MIPS ----*- C++ -*-===// |
// |
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
-// |
-// Modified by the Subzero authors. |
-// |
-//===----------------------------------------------------------------------===// |
-// |
// The Subzero Code Generator |
// |
// This file is distributed under the University of Illinois Open Source |
@@ -26,10 +18,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,34 +38,113 @@ 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 and_(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
+ |
+ void andi(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
+ |
+ void or_(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
+ |
+ void ori(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
+ |
+ void xor_(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
+ |
+ 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 move(const Operand *OpRd, const Operand *OpRs); |
+ |
+ void addu(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
+ |
+ void slt(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
+ |
+ void sltu(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); |
+ |
+ 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 { |
@@ -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 |