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

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: 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 void emit(const Cfg *Func) const override {
Jim Stichnoth 2015/10/18 11:48:39 Remove this emit() method?
rkotlerimgtec 2015/10/19 00:12:00 Done.
48 if (!BuildDefs::dump())
49 return;
50 Ostream &Str = Func->getContext()->getStrEmit();
51 // if (isRegReg()) {
52 Str << "reed\t";
53 }
54
55 protected:
56 OperandMIPS32(OperandKindMIPS32 Kind, Type Ty)
57 : Operand(static_cast<OperandKind>(Kind), Ty) {}
58 };
59
60 class OperandMIPS32Mem : public OperandMIPS32 {
61 OperandMIPS32Mem() = delete;
62 OperandMIPS32Mem(const OperandMIPS32Mem &) = delete;
63 OperandMIPS32Mem &operator=(const OperandMIPS32Mem &) = delete;
64
65 public:
66 /// Memory operand addressing mode.
67 /// The enum value also carries the encoding.
68 // TODO(jvoung): unify with the assembler.
69 enum AddrMode { Offset };
70
71 /// NOTE: The Variable-typed operands have to be registers.
72 ///
73 /// Reg + Imm. The Immediate actually has a limited number of bits
74 /// for encoding, so check canHoldOffset first. It cannot handle
75 /// general Constant operands like ConstantRelocatable, since a relocatable
76 /// can potentially take up too many bits.
77 static OperandMIPS32Mem *create(Cfg *Func, Type Ty, Variable *Base,
78 ConstantInteger32 *ImmOffset,
79 AddrMode Mode = Offset) {
80 return new (Func->allocate<OperandMIPS32Mem>())
81 OperandMIPS32Mem(Func, Ty, Base, ImmOffset, Mode);
82 }
83
84 Variable *getBase() const { return Base; }
85 ConstantInteger32 *getOffset() const { return ImmOffset; }
86 AddrMode getAddrMode() const { return Mode; }
87
88 void emit(const Cfg *Func) const override;
89 using OperandMIPS32::dump;
90 // void dump(const Cfg *Func, Ostream &Str) const override;
Jim Stichnoth 2015/10/18 11:48:39 remove commented-out code
rkotlerimgtec 2015/10/19 00:12:00 Done.
91
92 static bool classof(const Operand *Operand) {
93 return Operand->getKind() == static_cast<OperandKind>(kMem);
94 }
95
96 /// Return true if a load/store instruction for an element of type Ty
97 /// can encode the Offset directly in the immediate field of the 32-bit
98 /// MIPS instruction. For some types, if the load is Sign extending, then
99 /// the range is reduced.
100 static bool canHoldOffset(Type Ty, bool SignExt, int32_t Offset);
101
102 virtual void dump(const Cfg *Func, Ostream &Str) const override {
Jim Stichnoth 2015/10/18 11:48:39 I don't think you need both "virtual" and "overrid
rkotlerimgtec 2015/10/19 00:12:00 Done.
103 (void)Func;
104 (void)Str;
105 }
106
107 private:
108 OperandMIPS32Mem(Cfg *Func, Type Ty, Variable *Base,
109 ConstantInteger32 *ImmOffset, AddrMode Mode);
110
111 Variable *Base;
112 ConstantInteger32 *ImmOffset;
113 // Variable *Index;
Jim Stichnoth 2015/10/18 11:48:39 remove
rkotlerimgtec 2015/10/19 00:12:00 Done.
114 AddrMode Mode;
115 };
116
29 /// Base class for Mips instructions. 117 /// Base class for Mips instructions.
30 class InstMIPS32 : public InstTarget { 118 class InstMIPS32 : public InstTarget {
31 InstMIPS32() = delete; 119 InstMIPS32() = delete;
32 InstMIPS32(const InstMIPS32 &) = delete; 120 InstMIPS32(const InstMIPS32 &) = delete;
33 InstMIPS32 &operator=(const InstMIPS32 &) = delete; 121 InstMIPS32 &operator=(const InstMIPS32 &) = delete;
34 122
35 public: 123 public:
36 enum InstKindMIPS32 { k__Start = Inst::Target, Ret }; 124 enum InstKindMIPS32 {
125 k__Start = Inst::Target,
126 Addiu,
127 La,
128 Lui,
129 Mov, // actually a pseudo op for addi rd, rs, 0
130 Ori,
131 Ret
132 };
37 133
38 static const char *getWidthString(Type Ty); 134 static const char *getWidthString(Type Ty);
39 135
40 void dump(const Cfg *Func) const override; 136 void dump(const Cfg *Func) const override;
41 137
138 void dumpOpcode(Ostream &Str, const char *Opcode, Type Ty) const {
139 Str << Opcode << "." << Ty;
140 }
141
142 /// Shared emit routines for common forms of instructions.
143 static void emitUnaryopGPR(const char *Opcode, const InstMIPS32 *Inst,
144 const Cfg *Func);
145
42 protected: 146 protected:
43 InstMIPS32(Cfg *Func, InstKindMIPS32 Kind, SizeT Maxsrcs, Variable *Dest) 147 InstMIPS32(Cfg *Func, InstKindMIPS32 Kind, SizeT Maxsrcs, Variable *Dest)
44 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 148 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
45 static bool isClassof(const Inst *Inst, InstKindMIPS32 MyKind) { 149 static bool isClassof(const Inst *Inst, InstKindMIPS32 MyKind) {
46 return Inst->getKind() == static_cast<InstKind>(MyKind); 150 return Inst->getKind() == static_cast<InstKind>(MyKind);
47 } 151 }
48 }; 152 };
49 153
50 /// Ret pseudo-instruction. This is actually a "jr" instruction with an "ra" 154 /// 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 155 /// register operand, but epilogue lowering will search for a Ret instead of a
(...skipping 16 matching lines...) Expand all
68 } 172 }
69 void emit(const Cfg *Func) const override; 173 void emit(const Cfg *Func) const override;
70 void emitIAS(const Cfg *Func) const override; 174 void emitIAS(const Cfg *Func) const override;
71 void dump(const Cfg *Func) const override; 175 void dump(const Cfg *Func) const override;
72 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } 176 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
73 177
74 private: 178 private:
75 InstMIPS32Ret(Cfg *Func, Variable *RA, Variable *Source); 179 InstMIPS32Ret(Cfg *Func, Variable *RA, Variable *Source);
76 }; 180 };
77 181
182 /// Instructions of the form x := op(y).
183 template <InstMIPS32::InstKindMIPS32 K>
184 class InstMIPS32UnaryopGPR : public InstMIPS32 {
185 InstMIPS32UnaryopGPR() = delete;
186 InstMIPS32UnaryopGPR(const InstMIPS32UnaryopGPR &) = delete;
187 InstMIPS32UnaryopGPR &operator=(const InstMIPS32UnaryopGPR &) = delete;
188
189 public:
190 static InstMIPS32UnaryopGPR *create(Cfg *Func, Variable *Dest, Operand *Src) {
191 return new (Func->allocate<InstMIPS32UnaryopGPR>())
192 InstMIPS32UnaryopGPR(Func, Dest, Src);
193 }
194 void emit(const Cfg *Func) const override {
195 if (!BuildDefs::dump())
196 return;
197 emitUnaryopGPR(Opcode, this, Func);
198 }
199 void emitIAS(const Cfg *Func) const override {
200 (void)Func;
201 llvm_unreachable("Not yet implemented");
202 }
203 void dump(const Cfg *Func) const override {
204 if (!BuildDefs::dump())
205 return;
206 Ostream &Str = Func->getContext()->getStrDump();
207 dumpOpcode(Str, Opcode, getDest()->getType());
208 Str << " ";
209 dumpDest(Func);
210 Str << ", ";
211 dumpSources(Func);
212 }
213 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
214
215 protected:
216 InstMIPS32UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src)
217 : InstMIPS32(Func, K, 2, Dest) {
218 addSource(Src);
219 }
220
221 private:
222 static const char *Opcode;
223 };
224
225 template <InstMIPS32::InstKindMIPS32 K, bool Signed = false>
226 class InstMIPS32Imm16 : public InstMIPS32 {
227 InstMIPS32Imm16() = delete;
228 InstMIPS32Imm16(const InstMIPS32Imm16 &) = delete;
229 InstMIPS32Imm16 &operator=(const InstMIPS32Imm16 &) = delete;
230
231 public:
232 static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, Operand *Source,
233 uint32_t Imm) {
234 return new (Func->allocate<InstMIPS32Imm16>())
235 InstMIPS32Imm16(Func, Dest, Source, Imm);
236 }
237
238 static InstMIPS32Imm16 *create(Cfg *Func, Variable *Dest, uint32_t Imm) {
239 return new (Func->allocate<InstMIPS32Imm16>())
240 InstMIPS32Imm16(Func, Dest, Imm);
241 }
242
243 void emit(const Cfg *Func) const override {
244 (void)Func;
Jim Stichnoth 2015/10/18 11:48:39 remove this, as Func is used below.
rkotlerimgtec 2015/10/19 00:12:00 Done.
245 if (!BuildDefs::dump())
246 return;
247 Ostream &Str = Func->getContext()->getStrEmit();
248 Str << "\t" << Opcode << "\t";
249 getDest()->emit(Func);
250 if (getSrcSize() > 0) {
251 Str << ", ";
252 getSrc(0)->emit(Func);
253 }
254 Str << ", ";
255 if (Signed)
256 Str << (int32_t)Imm;
257 else
258 Str << Imm;
259 Str << "\n";
260 }
261
262 void emitIAS(const Cfg *Func) const override {
263 (void)Func;
264 llvm_unreachable("Not yet implemented");
265 }
266 void dump(const Cfg *Func) const override {
267 if (!BuildDefs::dump())
268 return;
269 Ostream &Str = Func->getContext()->getStrDump();
270 Str << " ";
271 Str << "\t" << Opcode << "\t";
272 dumpDest(Func);
273 Str << ", ";
274 dumpSources(Func);
275 if (Signed)
276 Str << (int32_t)Imm;
277 else
278 Str << Imm;
279 Str << "\n";
280 }
281
282 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
283
284 private:
285 InstMIPS32Imm16(Cfg *Func, Variable *Dest, Operand *Source, uint32_t Imm)
286 : InstMIPS32(Func, K, 2, Dest) {
287 this->Dead = Dest;
Jim Stichnoth 2015/10/18 11:48:39 I think maybe you meant to set this->Dest, not thi
rkotlerimgtec 2015/10/19 00:12:00 Done.
288 addSource(Source);
289 this->Imm = Imm;
Jim Stichnoth 2015/10/18 11:48:38 Initialize this->Imm in the initializer list.
rkotlerimgtec 2015/10/19 00:12:00 Done.
290 }
291
292 InstMIPS32Imm16(Cfg *Func, Variable *Dest, uint32_t Imm)
293 : InstMIPS32(Func, K, 1, Dest) {
294 this->Dest = Dest;
Jim Stichnoth 2015/10/18 11:48:38 Dest is already initialized in the Inst base class
rkotlerimgtec 2015/10/19 00:12:00 Done.
295 this->Imm = Imm;
Jim Stichnoth 2015/10/18 11:48:38 Initialize in the initializer list.
rkotlerimgtec 2015/10/19 00:12:00 Done.
296 }
297
298 static const char *Opcode;
299
300 uint32_t Imm;
Jim Stichnoth 2015/10/18 11:48:38 If you initialize Imm everywhere via an initialize
rkotlerimgtec 2015/10/19 00:12:00 Done.
301 };
302
303 typedef InstMIPS32Imm16<InstMIPS32::Addiu, true> InstMIPS32Addiu;
304 typedef InstMIPS32Imm16<InstMIPS32::Lui> InstMIPS32Lui;
305 typedef InstMIPS32UnaryopGPR<InstMIPS32::Mov> InstMIPS32MovBase;
306 typedef InstMIPS32UnaryopGPR<InstMIPS32::La> InstMIPS32La;
307 typedef InstMIPS32Imm16<InstMIPS32::Ori> InstMIPS32Ori;
308
309 /// Handles (some of) vmov's various formats.
310 class InstMIPS32Mov final : public InstMIPS32 {
311 InstMIPS32Mov() = delete;
312 InstMIPS32Mov(const InstMIPS32Mov &) = delete;
313 InstMIPS32Mov &operator=(const InstMIPS32Mov &) = delete;
314
315 public:
316 static InstMIPS32Mov *create(Cfg *Func, Variable *Dest, Operand *Src) {
317 return new (Func->allocate<InstMIPS32Mov>()) InstMIPS32Mov(Func, Dest, Src);
318 }
319 bool isRedundantAssign() const override {
320 return !isMultiDest() && !isMultiSource() &&
321 checkForRedundantAssign(getDest(), getSrc(0));
322 }
323 bool isSimpleAssign() const override { return true; }
324 void emit(const Cfg *Func) const override;
325 void emitIAS(const Cfg *Func) const override;
326 void dump(const Cfg *Func) const override;
327 static bool classof(const Inst *Inst) { return isClassof(Inst, Mov); }
328
329 bool isMultiDest() const { return DestHi != nullptr; }
330
331 bool isMultiSource() const {
332 assert(getSrcSize() == 1 || getSrcSize() == 2);
333 return getSrcSize() == 2;
334 }
335
336 Variable *getDestHi() const { return DestHi; }
337
338 private:
339 InstMIPS32Mov(Cfg *Func, Variable *Dest, Operand *Src);
340
341 void emitMultiDestSingleSource(const Cfg *Func) const;
342 void emitSingleDestMultiSource(const Cfg *Func) const;
343 void emitSingleDestSingleSource(const Cfg *Func) const;
344
345 Variable *DestHi = nullptr;
346 };
347
78 } // end of namespace Ice 348 } // end of namespace Ice
79 349
80 #endif // SUBZERO_SRC_ICEINSTMIPS32_H 350 #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