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

Side by Side Diff: src/IceInstARM32.h

Issue 1181013016: Subzero. Fixes memory leaks. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: clang-format: for f in $(git diff --name-only HEAD~7); do if [[ ${f} == *h || ${f} == *cpp ]]; then… Created 5 years, 6 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
OLDNEW
1 //===- subzero/src/IceInstARM32.h - ARM32 machine instructions --*- C++ -*-===// 1 //===- subzero/src/IceInstARM32.h - ARM32 machine instructions --*- 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 // This file declares the InstARM32 and OperandARM32 classes and 10 // This file declares the InstARM32 and OperandARM32 classes and
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 using Operand::dump; 53 using Operand::dump;
54 void dump(const Cfg *, Ostream &Str) const override { 54 void dump(const Cfg *, Ostream &Str) const override {
55 if (ALLOW_DUMP) 55 if (ALLOW_DUMP)
56 Str << "<OperandARM32>"; 56 Str << "<OperandARM32>";
57 } 57 }
58 58
59 protected: 59 protected:
60 OperandARM32(OperandKindARM32 Kind, Type Ty) 60 OperandARM32(OperandKindARM32 Kind, Type Ty)
61 : Operand(static_cast<OperandKind>(Kind), Ty) {} 61 : Operand(static_cast<OperandKind>(Kind), Ty) {}
62 ~OperandARM32() override {}
63 }; 62 };
64 63
65 // OperandARM32Mem represents a memory operand in any of the various ARM32 64 // OperandARM32Mem represents a memory operand in any of the various ARM32
66 // addressing modes. 65 // addressing modes.
67 class OperandARM32Mem : public OperandARM32 { 66 class OperandARM32Mem : public OperandARM32 {
68 OperandARM32Mem() = delete; 67 OperandARM32Mem() = delete;
69 OperandARM32Mem(const OperandARM32Mem &) = delete; 68 OperandARM32Mem(const OperandARM32Mem &) = delete;
70 OperandARM32Mem &operator=(const OperandARM32Mem &) = delete; 69 OperandARM32Mem &operator=(const OperandARM32Mem &) = delete;
71 70
72 public: 71 public:
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 // can encode the Offset directly in the immediate field of the 32-bit 133 // can encode the Offset directly in the immediate field of the 32-bit
135 // ARM instruction. For some types, if the load is Sign extending, then 134 // ARM instruction. For some types, if the load is Sign extending, then
136 // the range is reduced. 135 // the range is reduced.
137 static bool canHoldOffset(Type Ty, bool SignExt, int32_t Offset); 136 static bool canHoldOffset(Type Ty, bool SignExt, int32_t Offset);
138 137
139 private: 138 private:
140 OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base, 139 OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base,
141 ConstantInteger32 *ImmOffset, AddrMode Mode); 140 ConstantInteger32 *ImmOffset, AddrMode Mode);
142 OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base, Variable *Index, 141 OperandARM32Mem(Cfg *Func, Type Ty, Variable *Base, Variable *Index,
143 ShiftKind ShiftOp, uint16_t ShiftAmt, AddrMode Mode); 142 ShiftKind ShiftOp, uint16_t ShiftAmt, AddrMode Mode);
144 ~OperandARM32Mem() override {} 143
145 Variable *Base; 144 Variable *Base;
146 ConstantInteger32 *ImmOffset; 145 ConstantInteger32 *ImmOffset;
147 Variable *Index; 146 Variable *Index;
148 ShiftKind ShiftOp; 147 ShiftKind ShiftOp;
149 uint16_t ShiftAmt; 148 uint16_t ShiftAmt;
150 AddrMode Mode; 149 AddrMode Mode;
151 }; 150 };
152 151
153 // OperandARM32Flex represent the "flexible second operand" for 152 // OperandARM32Flex represent the "flexible second operand" for
154 // data-processing instructions. It can be a rotatable 8-bit constant, or 153 // data-processing instructions. It can be a rotatable 8-bit constant, or
155 // a register with an optional shift operand. The shift amount can even be 154 // a register with an optional shift operand. The shift amount can even be
156 // a third register. 155 // a third register.
157 class OperandARM32Flex : public OperandARM32 { 156 class OperandARM32Flex : public OperandARM32 {
158 OperandARM32Flex() = delete; 157 OperandARM32Flex() = delete;
159 OperandARM32Flex(const OperandARM32Flex &) = delete; 158 OperandARM32Flex(const OperandARM32Flex &) = delete;
160 OperandARM32Flex &operator=(const OperandARM32Flex &) = delete; 159 OperandARM32Flex &operator=(const OperandARM32Flex &) = delete;
161 160
162 public: 161 public:
163 static bool classof(const Operand *Operand) { 162 static bool classof(const Operand *Operand) {
164 return static_cast<OperandKind>(kFlexStart) <= Operand->getKind() && 163 return static_cast<OperandKind>(kFlexStart) <= Operand->getKind() &&
165 Operand->getKind() <= static_cast<OperandKind>(kFlexEnd); 164 Operand->getKind() <= static_cast<OperandKind>(kFlexEnd);
166 } 165 }
167 166
168 protected: 167 protected:
169 OperandARM32Flex(OperandKindARM32 Kind, Type Ty) : OperandARM32(Kind, Ty) {} 168 OperandARM32Flex(OperandKindARM32 Kind, Type Ty) : OperandARM32(Kind, Ty) {}
170 ~OperandARM32Flex() override {}
171 }; 169 };
172 170
173 // Rotated immediate variant. 171 // Rotated immediate variant.
174 class OperandARM32FlexImm : public OperandARM32Flex { 172 class OperandARM32FlexImm : public OperandARM32Flex {
175 OperandARM32FlexImm() = delete; 173 OperandARM32FlexImm() = delete;
176 OperandARM32FlexImm(const OperandARM32FlexImm &) = delete; 174 OperandARM32FlexImm(const OperandARM32FlexImm &) = delete;
177 OperandARM32FlexImm &operator=(const OperandARM32FlexImm &) = delete; 175 OperandARM32FlexImm &operator=(const OperandARM32FlexImm &) = delete;
178 176
179 public: 177 public:
180 // Immed_8 rotated by an even number of bits (2 * RotateAmt). 178 // Immed_8 rotated by an even number of bits (2 * RotateAmt).
(...skipping 14 matching lines...) Expand all
195 // Return true if the Immediate can fit in the ARM flexible operand. 193 // Return true if the Immediate can fit in the ARM flexible operand.
196 // Fills in the out-params RotateAmt and Immed_8 if Immediate fits. 194 // Fills in the out-params RotateAmt and Immed_8 if Immediate fits.
197 static bool canHoldImm(uint32_t Immediate, uint32_t *RotateAmt, 195 static bool canHoldImm(uint32_t Immediate, uint32_t *RotateAmt,
198 uint32_t *Immed_8); 196 uint32_t *Immed_8);
199 197
200 uint32_t getImm() const { return Imm; } 198 uint32_t getImm() const { return Imm; }
201 uint32_t getRotateAmt() const { return RotateAmt; } 199 uint32_t getRotateAmt() const { return RotateAmt; }
202 200
203 private: 201 private:
204 OperandARM32FlexImm(Cfg *Func, Type Ty, uint32_t Imm, uint32_t RotateAmt); 202 OperandARM32FlexImm(Cfg *Func, Type Ty, uint32_t Imm, uint32_t RotateAmt);
205 ~OperandARM32FlexImm() override {}
206 203
207 uint32_t Imm; 204 uint32_t Imm;
208 uint32_t RotateAmt; 205 uint32_t RotateAmt;
209 }; 206 };
210 207
211 // Shifted register variant. 208 // Shifted register variant.
212 class OperandARM32FlexReg : public OperandARM32Flex { 209 class OperandARM32FlexReg : public OperandARM32Flex {
213 OperandARM32FlexReg() = delete; 210 OperandARM32FlexReg() = delete;
214 OperandARM32FlexReg(const OperandARM32FlexReg &) = delete; 211 OperandARM32FlexReg(const OperandARM32FlexReg &) = delete;
215 OperandARM32FlexReg &operator=(const OperandARM32FlexReg &) = delete; 212 OperandARM32FlexReg &operator=(const OperandARM32FlexReg &) = delete;
(...skipping 15 matching lines...) Expand all
231 } 228 }
232 229
233 Variable *getReg() const { return Reg; } 230 Variable *getReg() const { return Reg; }
234 ShiftKind getShiftOp() const { return ShiftOp; } 231 ShiftKind getShiftOp() const { return ShiftOp; }
235 // ShiftAmt can represent an immediate or a register. 232 // ShiftAmt can represent an immediate or a register.
236 Operand *getShiftAmt() const { return ShiftAmt; } 233 Operand *getShiftAmt() const { return ShiftAmt; }
237 234
238 private: 235 private:
239 OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *Reg, ShiftKind ShiftOp, 236 OperandARM32FlexReg(Cfg *Func, Type Ty, Variable *Reg, ShiftKind ShiftOp,
240 Operand *ShiftAmt); 237 Operand *ShiftAmt);
241 ~OperandARM32FlexReg() override {}
242 238
243 Variable *Reg; 239 Variable *Reg;
244 ShiftKind ShiftOp; 240 ShiftKind ShiftOp;
245 Operand *ShiftAmt; 241 Operand *ShiftAmt;
246 }; 242 };
247 243
248 // Base class for ARM instructions. While most ARM instructions can be 244 // Base class for ARM instructions. While most ARM instructions can be
249 // conditionally executed, a few of them are not predicable (halt, 245 // conditionally executed, a few of them are not predicable (halt,
250 // memory barriers, etc.). 246 // memory barriers, etc.).
251 class InstARM32 : public InstTarget { 247 class InstARM32 : public InstTarget {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 }; 284 };
289 285
290 static const char *getWidthString(Type Ty); 286 static const char *getWidthString(Type Ty);
291 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); 287 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond);
292 288
293 void dump(const Cfg *Func) const override; 289 void dump(const Cfg *Func) const override;
294 290
295 protected: 291 protected:
296 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) 292 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest)
297 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 293 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
298 ~InstARM32() override {} 294
299 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) { 295 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) {
300 return Inst->getKind() == static_cast<InstKind>(MyKind); 296 return Inst->getKind() == static_cast<InstKind>(MyKind);
301 } 297 }
302 }; 298 };
303 299
304 // A predicable ARM instruction. 300 // A predicable ARM instruction.
305 class InstARM32Pred : public InstARM32 { 301 class InstARM32Pred : public InstARM32 {
306 InstARM32Pred() = delete; 302 InstARM32Pred() = delete;
307 InstARM32Pred(const InstARM32Pred &) = delete; 303 InstARM32Pred(const InstARM32Pred &) = delete;
308 InstARM32Pred &operator=(const InstARM32Pred &) = delete; 304 InstARM32Pred &operator=(const InstARM32Pred &) = delete;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 dumpSources(Func); 365 dumpSources(Func);
370 } 366 }
371 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 367 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
372 368
373 private: 369 private:
374 InstARM32UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src, 370 InstARM32UnaryopGPR(Cfg *Func, Variable *Dest, Operand *Src,
375 CondARM32::Cond Predicate) 371 CondARM32::Cond Predicate)
376 : InstARM32Pred(Func, K, 1, Dest, Predicate) { 372 : InstARM32Pred(Func, K, 1, Dest, Predicate) {
377 addSource(Src); 373 addSource(Src);
378 } 374 }
379 ~InstARM32UnaryopGPR() override {} 375
380 static const char *Opcode; 376 static const char *Opcode;
381 }; 377 };
382 378
383 // Instructions of the form x := x op y. 379 // Instructions of the form x := x op y.
384 template <InstARM32::InstKindARM32 K> 380 template <InstARM32::InstKindARM32 K>
385 class InstARM32TwoAddrGPR : public InstARM32Pred { 381 class InstARM32TwoAddrGPR : public InstARM32Pred {
386 InstARM32TwoAddrGPR() = delete; 382 InstARM32TwoAddrGPR() = delete;
387 InstARM32TwoAddrGPR(const InstARM32TwoAddrGPR &) = delete; 383 InstARM32TwoAddrGPR(const InstARM32TwoAddrGPR &) = delete;
388 InstARM32TwoAddrGPR &operator=(const InstARM32TwoAddrGPR &) = delete; 384 InstARM32TwoAddrGPR &operator=(const InstARM32TwoAddrGPR &) = delete;
389 385
(...skipping 25 matching lines...) Expand all
415 } 411 }
416 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 412 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
417 413
418 private: 414 private:
419 InstARM32TwoAddrGPR(Cfg *Func, Variable *Dest, Operand *Src, 415 InstARM32TwoAddrGPR(Cfg *Func, Variable *Dest, Operand *Src,
420 CondARM32::Cond Predicate) 416 CondARM32::Cond Predicate)
421 : InstARM32Pred(Func, K, 2, Dest, Predicate) { 417 : InstARM32Pred(Func, K, 2, Dest, Predicate) {
422 addSource(Dest); 418 addSource(Dest);
423 addSource(Src); 419 addSource(Src);
424 } 420 }
425 ~InstARM32TwoAddrGPR() override {} 421
426 static const char *Opcode; 422 static const char *Opcode;
427 }; 423 };
428 424
429 // Base class for assignment instructions. 425 // Base class for assignment instructions.
430 // These can be tested for redundancy (and elided if redundant). 426 // These can be tested for redundancy (and elided if redundant).
431 template <InstARM32::InstKindARM32 K> 427 template <InstARM32::InstKindARM32 K>
432 class InstARM32Movlike : public InstARM32Pred { 428 class InstARM32Movlike : public InstARM32Pred {
433 InstARM32Movlike() = delete; 429 InstARM32Movlike() = delete;
434 InstARM32Movlike(const InstARM32Movlike &) = delete; 430 InstARM32Movlike(const InstARM32Movlike &) = delete;
435 InstARM32Movlike &operator=(const InstARM32Movlike &) = delete; 431 InstARM32Movlike &operator=(const InstARM32Movlike &) = delete;
(...skipping 21 matching lines...) Expand all
457 dumpSources(Func); 453 dumpSources(Func);
458 } 454 }
459 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 455 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
460 456
461 private: 457 private:
462 InstARM32Movlike(Cfg *Func, Variable *Dest, Operand *Source, 458 InstARM32Movlike(Cfg *Func, Variable *Dest, Operand *Source,
463 CondARM32::Cond Predicate) 459 CondARM32::Cond Predicate)
464 : InstARM32Pred(Func, K, 1, Dest, Predicate) { 460 : InstARM32Pred(Func, K, 1, Dest, Predicate) {
465 addSource(Source); 461 addSource(Source);
466 } 462 }
467 ~InstARM32Movlike() override {}
468 463
469 static const char *Opcode; 464 static const char *Opcode;
470 }; 465 };
471 466
472 // Instructions of the form x := y op z. May have the side-effect of setting 467 // Instructions of the form x := y op z. May have the side-effect of setting
473 // status flags. 468 // status flags.
474 template <InstARM32::InstKindARM32 K> 469 template <InstARM32::InstKindARM32 K>
475 class InstARM32ThreeAddrGPR : public InstARM32Pred { 470 class InstARM32ThreeAddrGPR : public InstARM32Pred {
476 InstARM32ThreeAddrGPR() = delete; 471 InstARM32ThreeAddrGPR() = delete;
477 InstARM32ThreeAddrGPR(const InstARM32ThreeAddrGPR &) = delete; 472 InstARM32ThreeAddrGPR(const InstARM32ThreeAddrGPR &) = delete;
(...skipping 30 matching lines...) Expand all
508 } 503 }
509 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } 504 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
510 505
511 private: 506 private:
512 InstARM32ThreeAddrGPR(Cfg *Func, Variable *Dest, Variable *Src1, 507 InstARM32ThreeAddrGPR(Cfg *Func, Variable *Dest, Variable *Src1,
513 Operand *Src2, CondARM32::Cond Predicate, bool SetFlags) 508 Operand *Src2, CondARM32::Cond Predicate, bool SetFlags)
514 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { 509 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) {
515 addSource(Src1); 510 addSource(Src1);
516 addSource(Src2); 511 addSource(Src2);
517 } 512 }
518 ~InstARM32ThreeAddrGPR() override {} 513
519 static const char *Opcode; 514 static const char *Opcode;
520 bool SetFlags; 515 bool SetFlags;
521 }; 516 };
522 517
523 typedef InstARM32ThreeAddrGPR<InstARM32::Adc> InstARM32Adc; 518 typedef InstARM32ThreeAddrGPR<InstARM32::Adc> InstARM32Adc;
524 typedef InstARM32ThreeAddrGPR<InstARM32::Add> InstARM32Add; 519 typedef InstARM32ThreeAddrGPR<InstARM32::Add> InstARM32Add;
525 typedef InstARM32ThreeAddrGPR<InstARM32::And> InstARM32And; 520 typedef InstARM32ThreeAddrGPR<InstARM32::And> InstARM32And;
526 typedef InstARM32ThreeAddrGPR<InstARM32::Asr> InstARM32Asr; 521 typedef InstARM32ThreeAddrGPR<InstARM32::Asr> InstARM32Asr;
527 typedef InstARM32ThreeAddrGPR<InstARM32::Bic> InstARM32Bic; 522 typedef InstARM32ThreeAddrGPR<InstARM32::Bic> InstARM32Bic;
528 typedef InstARM32ThreeAddrGPR<InstARM32::Eor> InstARM32Eor; 523 typedef InstARM32ThreeAddrGPR<InstARM32::Eor> InstARM32Eor;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 } 589 }
595 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override; 590 bool repointEdge(CfgNode *OldNode, CfgNode *NewNode) override;
596 void emit(const Cfg *Func) const override; 591 void emit(const Cfg *Func) const override;
597 void emitIAS(const Cfg *Func) const override; 592 void emitIAS(const Cfg *Func) const override;
598 void dump(const Cfg *Func) const override; 593 void dump(const Cfg *Func) const override;
599 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); } 594 static bool classof(const Inst *Inst) { return isClassof(Inst, Br); }
600 595
601 private: 596 private:
602 InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse, 597 InstARM32Br(Cfg *Func, const CfgNode *TargetTrue, const CfgNode *TargetFalse,
603 CondARM32::Cond Predicate); 598 CondARM32::Cond Predicate);
604 ~InstARM32Br() override {} 599
605 const CfgNode *TargetTrue; 600 const CfgNode *TargetTrue;
606 const CfgNode *TargetFalse; 601 const CfgNode *TargetFalse;
607 }; 602 };
608 603
609 // Call instruction (bl/blx). Arguments should have already been pushed. 604 // Call instruction (bl/blx). Arguments should have already been pushed.
610 // Technically bl and the register form of blx can be predicated, but we'll 605 // Technically bl and the register form of blx can be predicated, but we'll
611 // leave that out until needed. 606 // leave that out until needed.
612 class InstARM32Call : public InstARM32 { 607 class InstARM32Call : public InstARM32 {
613 InstARM32Call() = delete; 608 InstARM32Call() = delete;
614 InstARM32Call(const InstARM32Call &) = delete; 609 InstARM32Call(const InstARM32Call &) = delete;
615 InstARM32Call &operator=(const InstARM32Call &) = delete; 610 InstARM32Call &operator=(const InstARM32Call &) = delete;
616 611
617 public: 612 public:
618 static InstARM32Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) { 613 static InstARM32Call *create(Cfg *Func, Variable *Dest, Operand *CallTarget) {
619 return new (Func->allocate<InstARM32Call>()) 614 return new (Func->allocate<InstARM32Call>())
620 InstARM32Call(Func, Dest, CallTarget); 615 InstARM32Call(Func, Dest, CallTarget);
621 } 616 }
622 Operand *getCallTarget() const { return getSrc(0); } 617 Operand *getCallTarget() const { return getSrc(0); }
623 void emit(const Cfg *Func) const override; 618 void emit(const Cfg *Func) const override;
624 void emitIAS(const Cfg *Func) const override; 619 void emitIAS(const Cfg *Func) const override;
625 void dump(const Cfg *Func) const override; 620 void dump(const Cfg *Func) const override;
626 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } 621 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
627 622
628 private: 623 private:
629 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 624 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
630 ~InstARM32Call() override {}
631 }; 625 };
632 626
633 // Integer compare instruction. 627 // Integer compare instruction.
634 class InstARM32Cmp : public InstARM32Pred { 628 class InstARM32Cmp : public InstARM32Pred {
635 InstARM32Cmp() = delete; 629 InstARM32Cmp() = delete;
636 InstARM32Cmp(const InstARM32Cmp &) = delete; 630 InstARM32Cmp(const InstARM32Cmp &) = delete;
637 InstARM32Cmp &operator=(const InstARM32Cmp &) = delete; 631 InstARM32Cmp &operator=(const InstARM32Cmp &) = delete;
638 632
639 public: 633 public:
640 static InstARM32Cmp *create(Cfg *Func, Variable *Src1, Operand *Src2, 634 static InstARM32Cmp *create(Cfg *Func, Variable *Src1, Operand *Src2,
641 CondARM32::Cond Predicate) { 635 CondARM32::Cond Predicate) {
642 return new (Func->allocate<InstARM32Cmp>()) 636 return new (Func->allocate<InstARM32Cmp>())
643 InstARM32Cmp(Func, Src1, Src2, Predicate); 637 InstARM32Cmp(Func, Src1, Src2, Predicate);
644 } 638 }
645 void emit(const Cfg *Func) const override; 639 void emit(const Cfg *Func) const override;
646 void emitIAS(const Cfg *Func) const override; 640 void emitIAS(const Cfg *Func) const override;
647 void dump(const Cfg *Func) const override; 641 void dump(const Cfg *Func) const override;
648 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmp); } 642 static bool classof(const Inst *Inst) { return isClassof(Inst, Cmp); }
649 643
650 private: 644 private:
651 InstARM32Cmp(Cfg *Func, Variable *Src1, Operand *Src2, 645 InstARM32Cmp(Cfg *Func, Variable *Src1, Operand *Src2,
652 CondARM32::Cond Predicate); 646 CondARM32::Cond Predicate);
653 ~InstARM32Cmp() override {}
654 }; 647 };
655 648
656 // Load instruction. 649 // Load instruction.
657 class InstARM32Ldr : public InstARM32Pred { 650 class InstARM32Ldr : public InstARM32Pred {
658 InstARM32Ldr() = delete; 651 InstARM32Ldr() = delete;
659 InstARM32Ldr(const InstARM32Ldr &) = delete; 652 InstARM32Ldr(const InstARM32Ldr &) = delete;
660 InstARM32Ldr &operator=(const InstARM32Ldr &) = delete; 653 InstARM32Ldr &operator=(const InstARM32Ldr &) = delete;
661 654
662 public: 655 public:
663 // Dest must be a register. 656 // Dest must be a register.
664 static InstARM32Ldr *create(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, 657 static InstARM32Ldr *create(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem,
665 CondARM32::Cond Predicate) { 658 CondARM32::Cond Predicate) {
666 return new (Func->allocate<InstARM32Ldr>()) 659 return new (Func->allocate<InstARM32Ldr>())
667 InstARM32Ldr(Func, Dest, Mem, Predicate); 660 InstARM32Ldr(Func, Dest, Mem, Predicate);
668 } 661 }
669 void emit(const Cfg *Func) const override; 662 void emit(const Cfg *Func) const override;
670 void emitIAS(const Cfg *Func) const override; 663 void emitIAS(const Cfg *Func) const override;
671 void dump(const Cfg *Func) const override; 664 void dump(const Cfg *Func) const override;
672 static bool classof(const Inst *Inst) { return isClassof(Inst, Ldr); } 665 static bool classof(const Inst *Inst) { return isClassof(Inst, Ldr); }
673 666
674 private: 667 private:
675 InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem, 668 InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem,
676 CondARM32::Cond Predicate); 669 CondARM32::Cond Predicate);
677 ~InstARM32Ldr() override {}
678 }; 670 };
679 671
680 // Multiply Accumulate: d := x * y + a 672 // Multiply Accumulate: d := x * y + a
681 class InstARM32Mla : public InstARM32Pred { 673 class InstARM32Mla : public InstARM32Pred {
682 InstARM32Mla() = delete; 674 InstARM32Mla() = delete;
683 InstARM32Mla(const InstARM32Mla &) = delete; 675 InstARM32Mla(const InstARM32Mla &) = delete;
684 InstARM32Mla &operator=(const InstARM32Mla &) = delete; 676 InstARM32Mla &operator=(const InstARM32Mla &) = delete;
685 677
686 public: 678 public:
687 // Everything must be a register. 679 // Everything must be a register.
688 static InstARM32Mla *create(Cfg *Func, Variable *Dest, Variable *Src0, 680 static InstARM32Mla *create(Cfg *Func, Variable *Dest, Variable *Src0,
689 Variable *Src1, Variable *Acc, 681 Variable *Src1, Variable *Acc,
690 CondARM32::Cond Predicate) { 682 CondARM32::Cond Predicate) {
691 return new (Func->allocate<InstARM32Mla>()) 683 return new (Func->allocate<InstARM32Mla>())
692 InstARM32Mla(Func, Dest, Src0, Src1, Acc, Predicate); 684 InstARM32Mla(Func, Dest, Src0, Src1, Acc, Predicate);
693 } 685 }
694 void emit(const Cfg *Func) const override; 686 void emit(const Cfg *Func) const override;
695 void emitIAS(const Cfg *Func) const override; 687 void emitIAS(const Cfg *Func) const override;
696 void dump(const Cfg *Func) const override; 688 void dump(const Cfg *Func) const override;
697 static bool classof(const Inst *Inst) { return isClassof(Inst, Mla); } 689 static bool classof(const Inst *Inst) { return isClassof(Inst, Mla); }
698 690
699 private: 691 private:
700 InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1, 692 InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1,
701 Variable *Acc, CondARM32::Cond Predicate); 693 Variable *Acc, CondARM32::Cond Predicate);
702 ~InstARM32Mla() override {}
703 }; 694 };
704 695
705 // Pop into a list of GPRs. Technically this can be predicated, but we don't 696 // Pop into a list of GPRs. Technically this can be predicated, but we don't
706 // need that functionality. 697 // need that functionality.
707 class InstARM32Pop : public InstARM32 { 698 class InstARM32Pop : public InstARM32 {
708 InstARM32Pop() = delete; 699 InstARM32Pop() = delete;
709 InstARM32Pop(const InstARM32Pop &) = delete; 700 InstARM32Pop(const InstARM32Pop &) = delete;
710 InstARM32Pop &operator=(const InstARM32Pop &) = delete; 701 InstARM32Pop &operator=(const InstARM32Pop &) = delete;
711 702
712 public: 703 public:
713 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { 704 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) {
714 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); 705 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests);
715 } 706 }
716 void emit(const Cfg *Func) const override; 707 void emit(const Cfg *Func) const override;
717 void emitIAS(const Cfg *Func) const override; 708 void emitIAS(const Cfg *Func) const override;
718 void dump(const Cfg *Func) const override; 709 void dump(const Cfg *Func) const override;
719 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } 710 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
720 711
721 private: 712 private:
722 InstARM32Pop(Cfg *Func, const VarList &Dests); 713 InstARM32Pop(Cfg *Func, const VarList &Dests);
723 ~InstARM32Pop() override {} 714
724 VarList Dests; 715 VarList Dests;
725 }; 716 };
726 717
727 // Push a list of GPRs. Technically this can be predicated, but we don't 718 // Push a list of GPRs. Technically this can be predicated, but we don't
728 // need that functionality. 719 // need that functionality.
729 class InstARM32Push : public InstARM32 { 720 class InstARM32Push : public InstARM32 {
730 InstARM32Push() = delete; 721 InstARM32Push() = delete;
731 InstARM32Push(const InstARM32Push &) = delete; 722 InstARM32Push(const InstARM32Push &) = delete;
732 InstARM32Push &operator=(const InstARM32Push &) = delete; 723 InstARM32Push &operator=(const InstARM32Push &) = delete;
733 724
734 public: 725 public:
735 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) { 726 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) {
736 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs); 727 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs);
737 } 728 }
738 void emit(const Cfg *Func) const override; 729 void emit(const Cfg *Func) const override;
739 void emitIAS(const Cfg *Func) const override; 730 void emitIAS(const Cfg *Func) const override;
740 void dump(const Cfg *Func) const override; 731 void dump(const Cfg *Func) const override;
741 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } 732 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
742 733
743 private: 734 private:
744 InstARM32Push(Cfg *Func, const VarList &Srcs); 735 InstARM32Push(Cfg *Func, const VarList &Srcs);
745 ~InstARM32Push() override {}
746 }; 736 };
747 737
748 // Ret pseudo-instruction. This is actually a "bx" instruction with 738 // Ret pseudo-instruction. This is actually a "bx" instruction with
749 // an "lr" register operand, but epilogue lowering will search for a Ret 739 // an "lr" register operand, but epilogue lowering will search for a Ret
750 // instead of a generic "bx". This instruction also takes a Source 740 // instead of a generic "bx". This instruction also takes a Source
751 // operand (for non-void returning functions) for liveness analysis, though 741 // operand (for non-void returning functions) for liveness analysis, though
752 // a FakeUse before the ret would do just as well. 742 // a FakeUse before the ret would do just as well.
753 // 743 //
754 // NOTE: Even though "bx" can be predicated, for now leave out the predication 744 // NOTE: Even though "bx" can be predicated, for now leave out the predication
755 // since it's not yet known to be useful for Ret. That may complicate finding 745 // since it's not yet known to be useful for Ret. That may complicate finding
756 // the terminator instruction if it's not guaranteed to be executed. 746 // the terminator instruction if it's not guaranteed to be executed.
757 class InstARM32Ret : public InstARM32 { 747 class InstARM32Ret : public InstARM32 {
758 InstARM32Ret() = delete; 748 InstARM32Ret() = delete;
759 InstARM32Ret(const InstARM32Ret &) = delete; 749 InstARM32Ret(const InstARM32Ret &) = delete;
760 InstARM32Ret &operator=(const InstARM32Ret &) = delete; 750 InstARM32Ret &operator=(const InstARM32Ret &) = delete;
761 751
762 public: 752 public:
763 static InstARM32Ret *create(Cfg *Func, Variable *LR, 753 static InstARM32Ret *create(Cfg *Func, Variable *LR,
764 Variable *Source = nullptr) { 754 Variable *Source = nullptr) {
765 return new (Func->allocate<InstARM32Ret>()) InstARM32Ret(Func, LR, Source); 755 return new (Func->allocate<InstARM32Ret>()) InstARM32Ret(Func, LR, Source);
766 } 756 }
767 void emit(const Cfg *Func) const override; 757 void emit(const Cfg *Func) const override;
768 void emitIAS(const Cfg *Func) const override; 758 void emitIAS(const Cfg *Func) const override;
769 void dump(const Cfg *Func) const override; 759 void dump(const Cfg *Func) const override;
770 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } 760 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
771 761
772 private: 762 private:
773 InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source); 763 InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source);
774 ~InstARM32Ret() override {}
775 }; 764 };
776 765
777 // Store instruction. It's important for liveness that there is no Dest 766 // Store instruction. It's important for liveness that there is no Dest
778 // operand (OperandARM32Mem instead of Dest Variable). 767 // operand (OperandARM32Mem instead of Dest Variable).
779 class InstARM32Str : public InstARM32Pred { 768 class InstARM32Str : public InstARM32Pred {
780 InstARM32Str() = delete; 769 InstARM32Str() = delete;
781 InstARM32Str(const InstARM32Str &) = delete; 770 InstARM32Str(const InstARM32Str &) = delete;
782 InstARM32Str &operator=(const InstARM32Str &) = delete; 771 InstARM32Str &operator=(const InstARM32Str &) = delete;
783 772
784 public: 773 public:
785 // Value must be a register. 774 // Value must be a register.
786 static InstARM32Str *create(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, 775 static InstARM32Str *create(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
787 CondARM32::Cond Predicate) { 776 CondARM32::Cond Predicate) {
788 return new (Func->allocate<InstARM32Str>()) 777 return new (Func->allocate<InstARM32Str>())
789 InstARM32Str(Func, Value, Mem, Predicate); 778 InstARM32Str(Func, Value, Mem, Predicate);
790 } 779 }
791 void emit(const Cfg *Func) const override; 780 void emit(const Cfg *Func) const override;
792 void emitIAS(const Cfg *Func) const override; 781 void emitIAS(const Cfg *Func) const override;
793 void dump(const Cfg *Func) const override; 782 void dump(const Cfg *Func) const override;
794 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); } 783 static bool classof(const Inst *Inst) { return isClassof(Inst, Str); }
795 784
796 private: 785 private:
797 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem, 786 InstARM32Str(Cfg *Func, Variable *Value, OperandARM32Mem *Mem,
798 CondARM32::Cond Predicate); 787 CondARM32::Cond Predicate);
799 ~InstARM32Str() override {}
800 }; 788 };
801 789
802 // Unsigned Multiply Long: d.lo, d.hi := x * y 790 // Unsigned Multiply Long: d.lo, d.hi := x * y
803 class InstARM32Umull : public InstARM32Pred { 791 class InstARM32Umull : public InstARM32Pred {
804 InstARM32Umull() = delete; 792 InstARM32Umull() = delete;
805 InstARM32Umull(const InstARM32Umull &) = delete; 793 InstARM32Umull(const InstARM32Umull &) = delete;
806 InstARM32Umull &operator=(const InstARM32Umull &) = delete; 794 InstARM32Umull &operator=(const InstARM32Umull &) = delete;
807 795
808 public: 796 public:
809 // Everything must be a register. 797 // Everything must be a register.
810 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi, 798 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi,
811 Variable *Src0, Variable *Src1, 799 Variable *Src0, Variable *Src1,
812 CondARM32::Cond Predicate) { 800 CondARM32::Cond Predicate) {
813 return new (Func->allocate<InstARM32Umull>()) 801 return new (Func->allocate<InstARM32Umull>())
814 InstARM32Umull(Func, DestLo, DestHi, Src0, Src1, Predicate); 802 InstARM32Umull(Func, DestLo, DestHi, Src0, Src1, Predicate);
815 } 803 }
816 void emit(const Cfg *Func) const override; 804 void emit(const Cfg *Func) const override;
817 void emitIAS(const Cfg *Func) const override; 805 void emitIAS(const Cfg *Func) const override;
818 void dump(const Cfg *Func) const override; 806 void dump(const Cfg *Func) const override;
819 static bool classof(const Inst *Inst) { return isClassof(Inst, Umull); } 807 static bool classof(const Inst *Inst) { return isClassof(Inst, Umull); }
820 808
821 private: 809 private:
822 InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0, 810 InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0,
823 Variable *Src1, CondARM32::Cond Predicate); 811 Variable *Src1, CondARM32::Cond Predicate);
824 ~InstARM32Umull() override {} 812
825 Variable *DestHi; 813 Variable *DestHi;
826 }; 814 };
827 815
828 // Declare partial template specializations of emit() methods that 816 // Declare partial template specializations of emit() methods that
829 // already have default implementations. Without this, there is the 817 // already have default implementations. Without this, there is the
830 // possibility of ODR violations and link errors. 818 // possibility of ODR violations and link errors.
831 819
832 template <> void InstARM32Movw::emit(const Cfg *Func) const; 820 template <> void InstARM32Movw::emit(const Cfg *Func) const;
833 template <> void InstARM32Movt::emit(const Cfg *Func) const; 821 template <> void InstARM32Movt::emit(const Cfg *Func) const;
834 822
835 } // end of namespace Ice 823 } // end of namespace Ice
836 824
837 #endif // SUBZERO_SRC_ICEINSTARM32_H 825 #endif // SUBZERO_SRC_ICEINSTARM32_H
OLDNEW
« src/IceGlobalInits.h ('K') | « src/IceInst.h ('k') | src/IceInstX8632.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698