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, const Operand *OpRs, |
| 65 const uint32_t Imm, const char *InsnName); |
| 66 |
| 67 void emitRdRtSa(IValueT Opcode, const Operand *OpRd, const Operand *OpRt, |
| 68 const uint32_t Sa, const char *InsnName); |
| 69 |
| 70 void emitRdRsRt(IValueT Opcode, const Operand *OpRd, const Operand *OpRs, |
| 71 const Operand *OpRt, const char *InsnName); |
| 72 |
| 73 void emitBr(const CondMIPS32::Cond Cond, const Operand *OpRs, |
| 74 const Operand *OpRt, IOffsetT Offset); |
| 75 |
| 76 void addiu(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 77 |
| 78 void slti(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 79 |
| 80 void sltiu(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 81 |
| 82 void and_(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 83 |
| 84 void andi(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 85 |
| 86 void or_(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 87 |
| 88 void ori(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 89 |
| 90 void xor_(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 91 |
| 92 void xori(const Operand *OpRt, const Operand *OpRs, const uint32_t Imm); |
| 93 |
| 94 void sll(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); |
| 95 |
| 96 void srl(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); |
| 97 |
| 98 void sra(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa); |
| 99 |
| 100 void move(const Operand *OpRd, const Operand *OpRs); |
| 101 |
| 102 void addu(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 103 |
| 104 void slt(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 105 |
| 106 void sltu(const Operand *OpRd, const Operand *OpRs, const Operand *OpRt); |
| 107 |
| 108 void sw(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset); |
| 109 |
| 110 void lw(const Operand *OpRt, const Operand *OpBase, const uint32_t Offset); |
| 111 |
| 112 void ret(void); |
| 113 |
| 114 void b(Label *TargetLabel); |
| 115 |
| 116 void bcc(const CondMIPS32::Cond Cond, const Operand *OpRs, |
| 117 const Operand *OpRt, Label *TargetLabel); |
| 118 |
| 119 void bzc(const CondMIPS32::Cond Cond, const Operand *OpRs, |
| 120 Label *TargetLabel); |
45 | 121 |
46 void alignFunction() override { | 122 void alignFunction() override { |
47 llvm::report_fatal_error("Not yet implemented."); | 123 const SizeT Align = 1 << getBundleAlignLog2Bytes(); |
| 124 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align); |
| 125 constexpr SizeT InstSize = sizeof(IValueT); |
| 126 assert(BytesNeeded % InstMIPS32::InstSize == 0); |
| 127 while (BytesNeeded > 0) { |
| 128 trap(); |
| 129 BytesNeeded -= InstSize; |
| 130 } |
48 } | 131 } |
49 | 132 |
50 SizeT getBundleAlignLog2Bytes() const override { return 4; } | 133 SizeT getBundleAlignLog2Bytes() const override { return 4; } |
51 | 134 |
52 const char *getAlignDirective() const override { return ".p2alignl"; } | 135 const char *getAlignDirective() const override { return ".p2alignl"; } |
53 | 136 |
54 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override { | 137 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override; |
55 // TODO(reed kotler) . Find out what this should be. | 138 |
56 static const uint8_t Padding[] = {0xE7, 0xFE, 0xDE, 0xF0}; | 139 void padWithNop(intptr_t Padding) override; |
57 return llvm::ArrayRef<uint8_t>(Padding, 4); | 140 |
| 141 void bind(Label *label); |
| 142 |
| 143 void emitTextInst(const std::string &Text, SizeT InstSize); |
| 144 |
| 145 Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { |
| 146 assert(NodeNumber < CfgNodeLabels.size()); |
| 147 return CfgNodeLabels[NodeNumber]; |
58 } | 148 } |
59 | 149 |
60 void padWithNop(intptr_t Padding) override { | 150 Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) { |
61 (void)Padding; | 151 return getOrCreateLabel(NodeNumber, CfgNodeLabels); |
62 llvm::report_fatal_error("Not yet implemented."); | |
63 } | 152 } |
64 | 153 |
65 Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { | 154 Label *getOrCreateLocalLabel(SizeT Number) { |
66 (void)NodeNumber; | 155 return getOrCreateLabel(Number, LocalLabels); |
67 llvm_unreachable("Not yet implemented."); | |
68 } | |
69 | |
70 void bindCfgNodeLabel(const CfgNode *) override { | |
71 llvm::report_fatal_error("Not yet implemented."); | |
72 } | 156 } |
73 | 157 |
74 bool fixupIsPCRel(FixupKind Kind) const override { | 158 bool fixupIsPCRel(FixupKind Kind) const override { |
75 (void)Kind; | 159 (void)Kind; |
76 llvm::report_fatal_error("Not yet implemented."); | 160 llvm::report_fatal_error("Not yet implemented."); |
77 } | 161 } |
78 | 162 |
79 static bool classof(const Assembler *Asm) { | 163 static bool classof(const Assembler *Asm) { |
80 return Asm->getKind() == Asm_MIPS32; | 164 return Asm->getKind() == Asm_MIPS32; |
81 } | 165 } |
82 | 166 |
83 private: | 167 private: |
84 ENABLE_MAKE_UNIQUE; | 168 ENABLE_MAKE_UNIQUE; |
| 169 |
| 170 using LabelVector = std::vector<Label *>; |
| 171 LabelVector CfgNodeLabels; |
| 172 LabelVector LocalLabels; |
| 173 |
| 174 // Returns the offset encoded in the branch instruction Inst. |
| 175 static IOffsetT decodeBranchOffset(IValueT Inst); |
| 176 |
| 177 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels); |
| 178 |
| 179 void bindCfgNodeLabel(const CfgNode *) override; |
| 180 |
| 181 void emitInst(IValueT Value) { |
| 182 AssemblerBuffer::EnsureCapacity _(&Buffer); |
| 183 Buffer.emit<IValueT>(Value); |
| 184 } |
85 }; | 185 }; |
86 | 186 |
87 } // end of namespace MIPS32 | 187 } // end of namespace MIPS32 |
88 } // end of namespace Ice | 188 } // end of namespace Ice |
89 | 189 |
90 #endif // SUBZERO_SRC_ICEASSEMBLERMIPS32_H | 190 #endif // SUBZERO_SRC_ICEASSEMBLERMIPS32_H |
OLD | NEW |