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 |