Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: src/IceInstMIPS32.h

Issue 1416493002: Implements simple returns and call args for Mips. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Incorporating changes from stichnot Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/IceInstMIPS32.cpp » ('j') | src/IceInstMIPS32.cpp » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceInstMIPS32.h - MIPS32 machine instrs --*- C++ -*-=== // 1 //===- subzero/src/IceInstMIPS32.h - MIPS32 machine instrs --*- C++ -*-=== //
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
11 /// This file declares the InstMIPS32 and OperandMIPS32 classes and their 11 /// This file declares the InstMIPS32 and OperandMIPS32 classes and their
12 /// subclasses. This represents the machine instructions and operands used for 12 /// subclasses. This represents the machine instructions and operands used for
13 /// MIPS32 code selection. 13 /// MIPS32 code selection.
14 /// 14 ///
15 //===----------------------------------------------------------------------===// 15 //===----------------------------------------------------------------------===//
16 16
17 #ifndef SUBZERO_SRC_ICEINSTMIPS32_H 17 #ifndef SUBZERO_SRC_ICEINSTMIPS32_H
18 #define SUBZERO_SRC_ICEINSTMIPS32_H 18 #define SUBZERO_SRC_ICEINSTMIPS32_H
19 19
20 #include "IceDefs.h" 20 #include "IceDefs.h"
21 #include "IceInst.h" 21 #include "IceInst.h"
22 #include "IceInstMIPS32.def" 22 #include "IceInstMIPS32.def"
23 #include "IceOperand.h" 23 #include "IceOperand.h"
24 24
25 namespace Ice { 25 namespace Ice {
26 26
27 class TargetMIPS32; 27 class TargetMIPS32;
28 28
29 /// OperandMips32 extends the Operand hierarchy.
30 //
31 class OperandMIPS32 : public Operand {
32 OperandMIPS32() = delete;
33 OperandMIPS32(const OperandMIPS32 &) = delete;
34 OperandMIPS32 &operator=(const OperandMIPS32 &) = delete;
35
36 public:
37 enum OperandKindMIPS32 {
38 k__Start = Operand::kTarget,
39 kMem,
40 };
41
42 using Operand::dump;
43 void dump(const Cfg *, Ostream &Str) const override {
44 if (BuildDefs::dump())
45 Str << "<OperandMIPS32>";
46 }
47 protected:
48 OperandMIPS32(OperandKindMIPS32 Kind, Type Ty)
49 : Operand(static_cast<OperandKind>(Kind), Ty) {}
50 };
51
52 class OperandMIPS32Mem : public OperandMIPS32 {
53 OperandMIPS32Mem() = delete;
54 OperandMIPS32Mem(const OperandMIPS32Mem &) = delete;
55 OperandMIPS32Mem &operator=(const OperandMIPS32Mem &) = delete;
56
57 public:
58 /// Memory operand addressing mode.
59 /// The enum value also carries the encoding.
60 // TODO(jvoung): unify with the assembler.
61 enum AddrMode { Offset };
62
63 /// NOTE: The Variable-typed operands have to be registers.
64 ///
65 /// Reg + Imm. The Immediate actually has a limited number of bits
66 /// for encoding, so check canHoldOffset first. It cannot handle
67 /// general Constant operands like ConstantRelocatable, since a relocatable
68 /// can potentially take up too many bits.
69 static OperandMIPS32Mem *create(Cfg *Func, Type Ty, Variable *Base,
70 ConstantInteger32 *ImmOffset,
71 AddrMode Mode = Offset) {
72 return new (Func->allocate<OperandMIPS32Mem>())
73 OperandMIPS32Mem(Func, Ty, Base, ImmOffset, Mode);
74 }
75
76 Variable *getBase() const { return Base; }
77 ConstantInteger32 *getOffset() const { return ImmOffset; }
78 AddrMode getAddrMode() const { return Mode; }
79
80 void emit(const Cfg *Func) const override;
81 using OperandMIPS32::dump;
82
83 static bool classof(const Operand *Operand) {
84 return Operand->getKind() == static_cast<OperandKind>(kMem);
85 }
86
87 /// Return true if a load/store instruction for an element of type Ty
88 /// can encode the Offset directly in the immediate field of the 32-bit
89 /// MIPS instruction. For some types, if the load is Sign extending, then
90 /// the range is reduced.
91 static bool canHoldOffset(Type Ty, bool SignExt, int32_t Offset);
92
93 void dump(const Cfg *Func, Ostream &Str) const override {
94 (void)Func;
95 (void)Str;
96 }
97
98 private:
99 OperandMIPS32Mem(Cfg *Func, Type Ty, Variable *Base,
100 ConstantInteger32 *ImmOffset, AddrMode Mode);
101
102 Variable *Base;
103 ConstantInteger32 *ImmOffset;
104 AddrMode Mode;
105 };
106
29 /// Base class for Mips instructions. 107 /// Base class for Mips instructions.
30 class InstMIPS32 : public InstTarget { 108 class InstMIPS32 : public InstTarget {
31 InstMIPS32() = delete; 109 InstMIPS32() = delete;
32 InstMIPS32(const InstMIPS32 &) = delete; 110 InstMIPS32(const InstMIPS32 &) = delete;
33 InstMIPS32 &operator=(const InstMIPS32 &) = delete; 111 InstMIPS32 &operator=(const InstMIPS32 &) = delete;
34 112
35 public: 113 public:
36 enum InstKindMIPS32 { k__Start = Inst::Target, Ret }; 114 enum InstKindMIPS32 {
115 k__Start = Inst::Target,
116 Addiu,
117 La,
118 Lui,
119 Mov, // actually a pseudo op for addi rd, rs, 0
120 Ori,
121 Ret
122 };
37 123
38 static const char *getWidthString(Type Ty); 124 static const char *getWidthString(Type Ty);
39 125
40 void dump(const Cfg *Func) const override; 126 void dump(const Cfg *Func) const override;
41 127
128 void dumpOpcode(Ostream &Str, const char *Opcode, Type Ty) const {
129 Str << Opcode << "." << Ty;
130 }
131
132 /// Shared emit routines for common forms of instructions.
133 static void emitUnaryopGPR(const char *Opcode, const InstMIPS32 *Inst,
134 const Cfg *Func);
135
42 protected: 136 protected:
43 InstMIPS32(Cfg *Func, InstKindMIPS32 Kind, SizeT Maxsrcs, Variable *Dest) 137 InstMIPS32(Cfg *Func, InstKindMIPS32 Kind, SizeT Maxsrcs, Variable *Dest)
44 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 138 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
45 static bool isClassof(const Inst *Inst, InstKindMIPS32 MyKind) { 139 static bool isClassof(const Inst *Inst, InstKindMIPS32 MyKind) {
46 return Inst->getKind() == static_cast<InstKind>(MyKind); 140 return Inst->getKind() == static_cast<InstKind>(MyKind);
47 } 141 }
48 }; 142 };
49 143
50 /// Ret pseudo-instruction. This is actually a "jr" instruction with an "ra" 144 /// Ret pseudo-instruction. This is actually a "jr" instruction with an "ra"
51 /// register operand, but epilogue lowering will search for a Ret instead of a 145 /// register operand, but epilogue lowering will search for a Ret instead of a
(...skipping 16 matching lines...) Expand all
68 } 162 }
69 void emit(const Cfg *Func) const override; 163 void emit(const Cfg *Func) const override;
70 void emitIAS(const Cfg *Func) const override; 164 void emitIAS(const Cfg *Func) const override;
71 void dump(const Cfg *Func) const override; 165 void dump(const Cfg *Func) const override;
72 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } 166 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
73 167
74 private: 168 private:
75 InstMIPS32Ret(Cfg *Func, Variable *RA, Variable *Source); 169 InstMIPS32Ret(Cfg *Func, Variable *RA, Variable *Source);
76 }; 170 };
77 171
172 /// Instructions of the form x := op(y).
173 template <InstMIPS32::InstKindMIPS32 K>
174 class InstMIPS32UnaryopGPR : public InstMIPS32 {
175 InstMIPS32UnaryopGPR() = delete;
176 InstMIPS32UnaryopGPR(const InstMIPS32UnaryopGPR &) = delete;
177 InstMIPS32UnaryopGPR &operator=(const InstMIPS32UnaryopGPR &) = delete;
178
179 public:
180 static InstMIPS32UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) {
181 return new (Func->allocate<InstMIPS32UnaryopGPR>())
182 InstMIPS32UnaryopGPR(Func, Dest, Src);
183 }
184 void emit(const Cfg *Func) const override {
185 if (!BuildDefs::dump())
186 return;
187 emitUnaryopGPR(Opcode, this, Func);
188 }
189 void emitIAS(const Cfg *Func) const override {
190 (void)Func;
191 llvm_unreachable("Not yet implemented");
192 }
193 void dump(const Cfg *Func) const override {
194 if (!BuildDefs::dump())
195 return;
196 Ostream &Str = Func->getContext()->getStrDump();
197 dumpOpcode(Str, Opcode, getDest()->getType());
198 Str << " ";
199 dumpDest(Func);
200 Str << ", ";
201 dumpSources(Func);
202 }
203 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
204
205 protected:
206 InstMIPS32UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
207 : InstMIPS32(Func, K, 2, Dest) {
Jim Stichnoth 2015/10/20 04:41:00 I think the "2" should be a "1". This argument te
rkotlerimgtec 2015/10/21 00:30:54 Done.
208 addSource(Src);
209 }
210
211 private:
212 static const char *Opcode;
213 };
214
215 template <InstMIPS32::InstKindMIPS32 K, bool Signed = false>
216 class InstMIPS32Imm16 : public InstMIPS32 {
217 InstMIPS32Imm16() = delete;
218 InstMIPS32Imm16(const InstMIPS32Imm16 &) = delete;
219 InstMIPS32Imm16 &operator=(const InstMIPS32Imm16 &) = delete;
220
221 public:
222 static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, Operand *Source,
223 uint32_t Imm) {
224 return new (Func->allocate<InstMIPS32Imm16>())
225 InstMIPS32Imm16(Func, Dest, Source, Imm);
226 }
227
228 static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, uint32_t Imm) {
229 return new (Func->allocate<InstMIPS32Imm16>())
230 InstMIPS32Imm16(Func, Dest, Imm);
231 }
232
233 void emit(const Cfg *Func) const override {
234 if (!BuildDefs::dump())
235 return;
236 Ostream &Str = Func->getContext()->getStrEmit();
237 Str << "\t" << Opcode << "\t";
238 getDest()->emit(Func);
239 if (getSrcSize() > 0) {
240 Str << ", ";
241 getSrc(0)->emit(Func);
242 }
243 Str << ", ";
244 if (Signed)
245 Str << (int32_t)Imm;
246 else
247 Str << Imm;
248 Str << "\n";
249 }
250
251 void emitIAS(const Cfg *Func) const override {
252 (void)Func;
253 llvm_unreachable("Not yet implemented");
254 }
255 void dump(const Cfg *Func) const override {
256 if (!BuildDefs::dump())
257 return;
258 Ostream &Str = Func->getContext()->getStrDump();
259 Str << " ";
260 Str << "\t" << Opcode << "\t";
261 dumpDest(Func);
262 Str << ", ";
263 dumpSources(Func);
264 if (Signed)
265 Str << (int32_t)Imm;
266 else
267 Str << Imm;
268 Str << "\n";
269 }
270
271 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
272
273 private:
274 InstMIPS32Imm16(Cfg *Func, Variable *Dest, Operand *Source, uint32_t Imm)
275 : InstMIPS32(Func, K, 2, Dest), Imm(Imm){
Jim Stichnoth 2015/10/20 04:41:00 As above, the "2" should be a "1".
rkotlerimgtec 2015/10/21 00:30:54 Done.
276 addSource(Source);
277 }
278
279 InstMIPS32Imm16(Cfg *Func, Variable *Dest, uint32_t Imm)
280 : InstMIPS32(Func, K, 1, Dest), Imm(Imm) {
Jim Stichnoth 2015/10/20 04:41:00 Similarly, the "1" would be "0".
rkotlerimgtec 2015/10/21 00:30:54 Done.
281 }
282
283 static const char *Opcode;
284
285 const uint32_t Imm;
286 };
287
288 typedef InstMIPS32Imm16<InstMIPS32::Addiu, true> InstMIPS32Addiu;
289 typedef InstMIPS32Imm16<InstMIPS32::Lui> InstMIPS32Lui;
290 typedef InstMIPS32UnaryopGPR<InstMIPS32::Mov> InstMIPS32MovBase;
291 typedef InstMIPS32UnaryopGPR<InstMIPS32::La> InstMIPS32La;
292 typedef InstMIPS32Imm16<InstMIPS32::Ori> InstMIPS32Ori;
293
294 /// Handles (some of) vmov's various formats.
295 class InstMIPS32Mov final : public InstMIPS32 {
296 InstMIPS32Mov() = delete;
297 InstMIPS32Mov(const InstMIPS32Mov &) = delete;
298 InstMIPS32Mov &operator=(const InstMIPS32Mov &) = delete;
299
300 public:
301 static InstMIPS32Mov *create(Cfg *Func, Variable *Dest, Operand *Src) {
302 return new (Func->allocate<InstMIPS32Mov>()) InstMIPS32Mov(Func, Dest, Src);
303 }
304 bool isRedundantAssign() const override {
305 return !isMultiDest() && !isMultiSource() &&
306 checkForRedundantAssign(getDest(), getSrc(0));
307 }
308 //bool isSimpleAssign() const override { return true; }
309 void emit(const Cfg *Func) const override;
310 void emitIAS(const Cfg *Func) const override;
311 void dump(const Cfg *Func) const override;
312 static bool classof(const Inst *Inst) { return isClassof(Inst, Mov); }
313
314 bool isMultiDest() const { return DestHi != nullptr; }
315
316 bool isMultiSource() const {
317 assert(getSrcSize() == 1 || getSrcSize() == 2);
318 return getSrcSize() == 2;
319 }
320
321 Variable *getDestHi() const { return DestHi; }
322
323 private:
324 InstMIPS32Mov(Cfg *Func, Variable *Dest, Operand *Src);
325
326 void emitMultiDestSingleSource(const Cfg *Func) const;
327 void emitSingleDestMultiSource(const Cfg *Func) const;
328 void emitSingleDestSingleSource(const Cfg *Func) const;
329
330 Variable *DestHi = nullptr;
331 };
332
78 } // end of namespace Ice 333 } // end of namespace Ice
79 334
80 #endif // SUBZERO_SRC_ICEINSTMIPS32_H 335 #endif // SUBZERO_SRC_ICEINSTMIPS32_H
OLDNEW
« no previous file with comments | « no previous file | src/IceInstMIPS32.cpp » ('j') | src/IceInstMIPS32.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698