Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceAssemblerMIPS32.h - Assembler for MIPS ----*- C++ -*-===// | 1 //===- subzero/src/IceAssemblerMIPS32.h - Assembler for MIPS ----*- C++ -*-===// |
| 2 // | 2 // |
| 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 4 // for details. All rights reserved. Use of this source code is governed by a | 4 // for details. All rights reserved. Use of this source code is governed by a |
| 5 // BSD-style license that can be found in the LICENSE file. | 5 // BSD-style license that can be found in the LICENSE file. |
| 6 // | 6 // |
| 7 // Modified by the Subzero authors. | 7 // Modified by the Subzero authors. |
| 8 // | 8 // |
| 9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
| 10 // | 10 // |
| 11 // The Subzero Code Generator | 11 // The Subzero Code Generator |
| 12 // | 12 // |
| 13 // This file is distributed under the University of Illinois Open Source | 13 // This file is distributed under the University of Illinois Open Source |
| 14 // License. See LICENSE.TXT for details. | 14 // License. See LICENSE.TXT for details. |
| 15 // | 15 // |
| 16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// |
| 17 /// | 17 /// |
| 18 /// \file | 18 /// \file |
| 19 /// \brief Declares the Assembler class for MIPS32. | 19 /// \brief Declares the Assembler class for MIPS32. |
| 20 /// | 20 /// |
| 21 //===----------------------------------------------------------------------===// | 21 //===----------------------------------------------------------------------===// |
| 22 | 22 |
| 23 #ifndef SUBZERO_SRC_ICEASSEMBLERMIPS32_H | 23 #ifndef SUBZERO_SRC_ICEASSEMBLERMIPS32_H |
| 24 #define SUBZERO_SRC_ICEASSEMBLERMIPS32_H | 24 #define SUBZERO_SRC_ICEASSEMBLERMIPS32_H |
| 25 | 25 |
| 26 #include "IceAssembler.h" | 26 #include "IceAssembler.h" |
| 27 #include "IceDefs.h" | 27 #include "IceDefs.h" |
| 28 #include "IceFixups.h" | 28 #include "IceFixups.h" |
| 29 #include "IceInstMIPS32.h" | |
| 30 #include "IceTargetLowering.h" | |
| 29 | 31 |
| 30 namespace Ice { | 32 namespace Ice { |
| 31 namespace MIPS32 { | 33 namespace MIPS32 { |
| 32 | 34 |
| 35 using IValueT = uint32_t; | |
| 36 using IOffsetT = int32_t; | |
| 37 | |
| 33 class AssemblerMIPS32 : public Assembler { | 38 class AssemblerMIPS32 : public Assembler { |
| 34 AssemblerMIPS32(const AssemblerMIPS32 &) = delete; | 39 AssemblerMIPS32(const AssemblerMIPS32 &) = delete; |
| 35 AssemblerMIPS32 &operator=(const AssemblerMIPS32 &) = delete; | 40 AssemblerMIPS32 &operator=(const AssemblerMIPS32 &) = delete; |
| 36 | 41 |
| 37 public: | 42 public: |
| 38 explicit AssemblerMIPS32(bool use_far_branches = false) | 43 explicit AssemblerMIPS32(bool use_far_branches = false) |
| 39 : Assembler(Asm_MIPS32) { | 44 : Assembler(Asm_MIPS32) { |
| 40 // This mode is only needed and implemented for MIPS32 and ARM. | 45 // This mode is only needed and implemented for MIPS32 and ARM. |
| 41 assert(!use_far_branches); | 46 assert(!use_far_branches); |
| 42 (void)use_far_branches; | 47 (void)use_far_branches; |
| 43 } | 48 } |
| 44 ~AssemblerMIPS32() override = default; | 49 ~AssemblerMIPS32() override { |
| 50 if (BuildDefs::asserts()) { | |
| 51 for (const Label *Label : CfgNodeLabels) { | |
| 52 Label->finalCheck(); | |
| 53 } | |
| 54 for (const Label *Label : LocalLabels) { | |
| 55 Label->finalCheck(); | |
| 56 } | |
| 57 } | |
| 58 } | |
| 59 | |
| 60 void trap(); | |
| 61 | |
| 62 void nop(); | |
| 63 | |
| 64 void emitRtRsImm16 (IValueT Opcode, const Operand *OpRt, | |
| 65 const Operand *OpRs, const uint32_t Imm, | |
| 66 const char *InsnName); | |
| 67 | |
| 68 void emitRdRtSa(IValueT Opcode, const Operand *OpRd, | |
| 69 const Operand *OpRt, const uint32_t Sa, | |
| 70 const char *InsnName); | |
| 71 | |
| 72 void emitRdRsRt(IValueT Opcode, const Operand *OpRd, | |
| 73 const Operand *OpRs, const Operand *OpRt, | |
| 74 const char *InsnName); | |
| 75 | |
| 76 void emitBr(const CondMIPS32::Cond Cond, const Operand *OpRs, | |
| 77 const Operand *OpRt, IOffsetT Offset); | |
| 78 | |
| 79 void addiu(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); | |
| 80 | |
| 81 void slti(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); | |
| 82 | |
| 83 void sltiu(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); | |
| 84 | |
| 85 void andi(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); | |
| 86 | |
| 87 void ori(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); | |
| 88 | |
| 89 void xori(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); | |
| 90 | |
| 91 void sll(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); | |
| 92 | |
| 93 void srl(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); | |
| 94 | |
| 95 void sra(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); | |
| 96 | |
| 97 void addu(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); | |
| 98 | |
| 99 void slt(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); | |
| 100 | |
| 101 void sw(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset); | |
| 102 | |
| 103 void lw(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset); | |
| 104 | |
| 105 void ret(void); | |
| 106 | |
| 107 void b(Label *TargetLabel); | |
| 108 | |
| 109 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
| |
| 110 | |
| 111 void bzc(const CondMIPS32::Cond Cond, const Operand *OpRs, Label *TargetLabel) ; | |
| 45 | 112 |
| 46 void alignFunction() override { | 113 void alignFunction() override { |
| 47 llvm::report_fatal_error("Not yet implemented."); | 114 const SizeT Align = 1 << getBundleAlignLog2Bytes(); |
| 115 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align); | |
| 116 constexpr SizeT InstSize = sizeof(IValueT); | |
| 117 assert(BytesNeeded % InstMIPS32::InstSize == 0); | |
| 118 while (BytesNeeded > 0) { | |
| 119 trap(); | |
| 120 BytesNeeded -= InstSize; | |
| 121 } | |
| 48 } | 122 } |
| 49 | 123 |
| 50 SizeT getBundleAlignLog2Bytes() const override { return 4; } | 124 SizeT getBundleAlignLog2Bytes() const override { return 4; } |
| 51 | 125 |
| 52 const char *getAlignDirective() const override { return ".p2alignl"; } | 126 const char *getAlignDirective() const override { return ".p2alignl"; } |
| 53 | 127 |
| 54 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override { | 128 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override; |
| 55 // TODO(reed kotler) . Find out what this should be. | 129 |
| 56 static const uint8_t Padding[] = {0xE7, 0xFE, 0xDE, 0xF0}; | 130 void padWithNop(intptr_t Padding) override; |
| 57 return llvm::ArrayRef<uint8_t>(Padding, 4); | 131 |
| 132 void bind(Label *label); | |
| 133 | |
| 134 void emitTextInst(const std::string &Text, SizeT InstSize); | |
| 135 | |
| 136 Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { | |
| 137 assert(NodeNumber < CfgNodeLabels.size()); | |
| 138 return CfgNodeLabels[NodeNumber]; | |
| 58 } | 139 } |
| 59 | 140 |
| 60 void padWithNop(intptr_t Padding) override { | 141 Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) { |
| 61 (void)Padding; | 142 return getOrCreateLabel(NodeNumber, CfgNodeLabels); |
| 62 llvm::report_fatal_error("Not yet implemented."); | |
| 63 } | 143 } |
| 64 | 144 |
| 65 Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { | 145 Label *getOrCreateLocalLabel(SizeT Number) { |
| 66 (void)NodeNumber; | 146 return getOrCreateLabel(Number, LocalLabels); |
| 67 llvm_unreachable("Not yet implemented."); | |
| 68 } | 147 } |
| 69 | 148 |
| 70 void bindCfgNodeLabel(const CfgNode *) override { | |
| 71 llvm::report_fatal_error("Not yet implemented."); | |
| 72 } | |
| 73 | 149 |
| 74 bool fixupIsPCRel(FixupKind Kind) const override { | 150 bool fixupIsPCRel(FixupKind Kind) const override { |
| 75 (void)Kind; | 151 (void)Kind; |
| 76 llvm::report_fatal_error("Not yet implemented."); | 152 llvm::report_fatal_error("Not yet implemented."); |
| 77 } | 153 } |
| 78 | 154 |
| 79 static bool classof(const Assembler *Asm) { | 155 static bool classof(const Assembler *Asm) { |
| 80 return Asm->getKind() == Asm_MIPS32; | 156 return Asm->getKind() == Asm_MIPS32; |
| 81 } | 157 } |
| 82 | 158 |
| 83 private: | 159 private: |
| 84 ENABLE_MAKE_UNIQUE; | 160 ENABLE_MAKE_UNIQUE; |
| 161 | |
| 162 using LabelVector = std::vector<Label *>; | |
| 163 LabelVector CfgNodeLabels; | |
| 164 LabelVector LocalLabels; | |
| 165 | |
| 166 // Returns the offset encoded in the branch instruction Inst. | |
| 167 static IOffsetT decodeBranchOffset(IValueT Inst); | |
| 168 | |
| 169 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels); | |
| 170 | |
| 171 void bindCfgNodeLabel(const CfgNode *) override; | |
| 172 | |
| 173 void emitInst(IValueT Value) { | |
| 174 AssemblerBuffer::EnsureCapacity _(&Buffer); | |
| 175 Buffer.emit<IValueT>(Value); | |
| 176 } | |
| 85 }; | 177 }; |
| 86 | 178 |
| 87 } // end of namespace MIPS32 | 179 } // end of namespace MIPS32 |
| 88 } // end of namespace Ice | 180 } // end of namespace Ice |
| 89 | 181 |
| 90 #endif // SUBZERO_SRC_ICEASSEMBLERMIPS32_H | 182 #endif // SUBZERO_SRC_ICEASSEMBLERMIPS32_H |
| OLD | NEW |