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

Side by Side Diff: src/IceInstARM32.h

Issue 1535233002: Refactor PUSH/POP in ARM assemblers. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Refactor and fix trivial bug (insertion of newline for vpush). Created 4 years, 11 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 /// \file 10 /// \file
11 /// \brief Declares the InstARM32 and OperandARM32 classes and their subclasses. 11 /// \brief Declares the InstARM32 and OperandARM32 classes and their subclasses.
12 /// 12 ///
13 /// This represents the machine instructions and operands used for ARM32 code 13 /// This represents the machine instructions and operands used for ARM32 code
14 /// selection. 14 /// selection.
15 /// 15 ///
16 //===----------------------------------------------------------------------===// 16 //===----------------------------------------------------------------------===//
17 17
18 #ifndef SUBZERO_SRC_ICEINSTARM32_H 18 #ifndef SUBZERO_SRC_ICEINSTARM32_H
19 #define SUBZERO_SRC_ICEINSTARM32_H 19 #define SUBZERO_SRC_ICEINSTARM32_H
20 20
21 #include "IceConditionCodesARM32.h" 21 #include "IceConditionCodesARM32.h"
22 #include "IceDefs.h" 22 #include "IceDefs.h"
23 #include "IceInst.h" 23 #include "IceInst.h"
24 #include "IceInstARM32.def" 24 #include "IceInstARM32.def"
25 #include "IceOperand.h" 25 #include "IceOperand.h"
26 26
27 namespace Ice { 27 namespace Ice {
28 namespace ARM32 { 28 namespace ARM32 {
29 29
30 /// Encoding of an ARM 32-bit instruction.
31 using IValueT = uint32_t;
32
33 /// An Offset value (+/-) used in an ARM 32-bit instruction.
34 using IOffsetT = int32_t;
35
30 class TargetARM32; 36 class TargetARM32;
31 37
32 /// OperandARM32 extends the Operand hierarchy. Its subclasses are 38 /// OperandARM32 extends the Operand hierarchy. Its subclasses are
33 /// OperandARM32Mem and OperandARM32Flex. 39 /// OperandARM32Mem and OperandARM32Flex.
34 class OperandARM32 : public Operand { 40 class OperandARM32 : public Operand {
35 OperandARM32() = delete; 41 OperandARM32() = delete;
36 OperandARM32(const OperandARM32 &) = delete; 42 OperandARM32(const OperandARM32 &) = delete;
37 OperandARM32 &operator=(const OperandARM32 &) = delete; 43 OperandARM32 &operator=(const OperandARM32 &) = delete;
38 44
39 public: 45 public:
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 363
358 /// Base class for ARM instructions. While most ARM instructions can be 364 /// Base class for ARM instructions. While most ARM instructions can be
359 /// conditionally executed, a few of them are not predicable (halt, memory 365 /// conditionally executed, a few of them are not predicable (halt, memory
360 /// barriers, etc.). 366 /// barriers, etc.).
361 class InstARM32 : public InstTarget { 367 class InstARM32 : public InstTarget {
362 InstARM32() = delete; 368 InstARM32() = delete;
363 InstARM32(const InstARM32 &) = delete; 369 InstARM32(const InstARM32 &) = delete;
364 InstARM32 &operator=(const InstARM32 &) = delete; 370 InstARM32 &operator=(const InstARM32 &) = delete;
365 371
366 public: 372 public:
373 // Defines form that assembly instruction should be synthesized.
374 enum OutputForm { TextualOutput, BinaryOutput };
375
367 enum InstKindARM32 { 376 enum InstKindARM32 {
368 k__Start = Inst::Target, 377 k__Start = Inst::Target,
369 Adc, 378 Adc,
370 Add, 379 Add,
371 And, 380 And,
372 Asr, 381 Asr,
373 Bic, 382 Bic,
374 Br, 383 Br,
375 Call, 384 Call,
376 Clz, 385 Clz,
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 Vsqrt, 431 Vsqrt,
423 Vsub 432 Vsub
424 }; 433 };
425 434
426 static constexpr size_t InstSize = sizeof(uint32_t); 435 static constexpr size_t InstSize = sizeof(uint32_t);
427 436
428 static const char *getWidthString(Type Ty); 437 static const char *getWidthString(Type Ty);
429 static const char *getVecWidthString(Type Ty); 438 static const char *getVecWidthString(Type Ty);
430 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond); 439 static CondARM32::Cond getOppositeCondition(CondARM32::Cond Cond);
431 440
441 template <OutputForm> inline void startNextAsmInst(const Cfg *Func) const;
442
432 /// Called inside derived methods emit() to communicate that multiple 443 /// Called inside derived methods emit() to communicate that multiple
433 /// instructions are being generated. Used by emitIAS() methods to 444 /// instructions are being generated. Used by emitIAS() methods to
434 /// generate textual fixups for instructions that are not yet 445 /// generate textual fixups for instructions that are not yet
435 /// implemented. 446 /// implemented.
436 void startNextInst(const Cfg *Func) const; 447 void startNextInst(const Cfg *Func) const;
437 448
438 /// Shared emit routines for common forms of instructions. 449 /// Shared emit routines for common forms of instructions.
439 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst, 450 static void emitThreeAddrFP(const char *Opcode, const InstARM32 *Inst,
440 const Cfg *Func); 451 const Cfg *Func);
441 static void emitFourAddrFP(const char *Opcode, const InstARM32 *Inst, 452 static void emitFourAddrFP(const char *Opcode, const InstARM32 *Inst,
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 void emitIAS(const Cfg *Func) const override; 1061 void emitIAS(const Cfg *Func) const override;
1051 void dump(const Cfg *Func) const override; 1062 void dump(const Cfg *Func) const override;
1052 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); } 1063 static bool classof(const Inst *Inst) { return isClassof(Inst, Call); }
1053 1064
1054 private: 1065 private:
1055 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget); 1066 InstARM32Call(Cfg *Func, Variable *Dest, Operand *CallTarget);
1056 }; 1067 };
1057 1068
1058 /// Pops a list of registers. It may be a list of GPRs, or a list of VFP "s" 1069 /// Pops a list of registers. It may be a list of GPRs, or a list of VFP "s"
1059 /// regs, but not both. In any case, the list must be sorted. 1070 /// regs, but not both. In any case, the list must be sorted.
1060 class InstARM32Pop : public InstARM32 { 1071 class InstARM32Pop : public InstARM32 {
John 2016/01/06 16:10:21 Push and pop have nearly-identical emitters. It se
Karl 2016/01/06 23:21:58 Rewrote with base class and virtuals.
1061 InstARM32Pop() = delete; 1072 InstARM32Pop() = delete;
1062 InstARM32Pop(const InstARM32Pop &) = delete; 1073 InstARM32Pop(const InstARM32Pop &) = delete;
1063 InstARM32Pop &operator=(const InstARM32Pop &) = delete; 1074 InstARM32Pop &operator=(const InstARM32Pop &) = delete;
1064 1075
1065 public: 1076 public:
1066 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) { 1077 static InstARM32Pop *create(Cfg *Func, const VarList &Dests) {
1067 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests); 1078 return new (Func->allocate<InstARM32Pop>()) InstARM32Pop(Func, Dests);
1068 } 1079 }
1069 void emit(const Cfg *Func) const override; 1080 void emit(const Cfg *Func) const override;
1070 void emitIAS(const Cfg *Func) const override; 1081 void emitIAS(const Cfg *Func) const override;
1071 void dump(const Cfg *Func) const override; 1082 void dump(const Cfg *Func) const override;
1072 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); } 1083 static bool classof(const Inst *Inst) { return isClassof(Inst, Pop); }
1073 1084
1074 private: 1085 private:
1075 InstARM32Pop(Cfg *Func, const VarList &Dests); 1086 InstARM32Pop(Cfg *Func, const VarList &Dests);
1076 1087 template <OutputForm> inline void assemble(const Cfg *Func) const;
1088 void emitPop(const Cfg *Func) const;
1089 template <OutputForm>
1090 inline void emitPop(const Cfg *Func, const Variable *Reg) const;
1091 template <OutputForm>
1092 inline void emitPopList(const Cfg *Func, ARM32::IValueT Registers) const;
1093 template <OutputForm>
1094 inline void emitVpop(const Cfg *Func, const Variable *BaseReg,
1095 SizeT RegCount) const;
1077 VarList Dests; 1096 VarList Dests;
1078 }; 1097 };
1079 1098
1080 /// Pushes a list of registers. Just like Pop (see above), the list may be of 1099 /// Pushes a list of registers. Just like Pop (see above), the list may be of
1081 /// GPRs, or VFP "s" registers, but not both. 1100 /// GPRs, or VFP "s" registers, but not both.
1082 class InstARM32Push : public InstARM32 { 1101 class InstARM32Push : public InstARM32 {
1083 InstARM32Push() = delete; 1102 InstARM32Push() = delete;
1084 InstARM32Push(const InstARM32Push &) = delete; 1103 InstARM32Push(const InstARM32Push &) = delete;
1085 InstARM32Push &operator=(const InstARM32Push &) = delete; 1104 InstARM32Push &operator=(const InstARM32Push &) = delete;
1086 1105
1087 public: 1106 public:
1088 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) { 1107 static InstARM32Push *create(Cfg *Func, const VarList &Srcs) {
1089 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs); 1108 return new (Func->allocate<InstARM32Push>()) InstARM32Push(Func, Srcs);
1090 } 1109 }
1091 void emit(const Cfg *Func) const override; 1110 void emit(const Cfg *Func) const override;
1092 void emitIAS(const Cfg *Func) const override; 1111 void emitIAS(const Cfg *Func) const override;
1093 void dump(const Cfg *Func) const override; 1112 void dump(const Cfg *Func) const override;
1094 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); } 1113 static bool classof(const Inst *Inst) { return isClassof(Inst, Push); }
1095 1114
1096 private: 1115 private:
1097 InstARM32Push(Cfg *Func, const VarList &Srcs); 1116 InstARM32Push(Cfg *Func, const VarList &Srcs);
1117 void emitPush(const Cfg *Func) const;
1118 template <OutputForm> inline void assemble(const Cfg *Func) const;
1119 template <OutputForm>
1120 inline void emitPush(const Cfg *Func, const Variable *Reg) const;
1121 template <OutputForm>
1122 inline void emitPushList(const Cfg *Func, ARM32::IValueT Registers) const;
1123 template <OutputForm>
1124 inline void emitVPush(const Cfg *Func, const Variable *BaseReg,
1125 SizeT RegCount) const;
1098 }; 1126 };
1099 1127
1100 /// Ret pseudo-instruction. This is actually a "bx" instruction with an "lr" 1128 /// Ret pseudo-instruction. This is actually a "bx" instruction with an "lr"
1101 /// register operand, but epilogue lowering will search for a Ret instead of a 1129 /// register operand, but epilogue lowering will search for a Ret instead of a
1102 /// generic "bx". This instruction also takes a Source operand (for non-void 1130 /// generic "bx". This instruction also takes a Source operand (for non-void
1103 /// returning functions) for liveness analysis, though a FakeUse before the ret 1131 /// returning functions) for liveness analysis, though a FakeUse before the ret
1104 /// would do just as well. 1132 /// would do just as well.
1105 /// 1133 ///
1106 /// NOTE: Even though "bx" can be predicated, for now leave out the predication 1134 /// NOTE: Even though "bx" can be predicated, for now leave out the predication
1107 /// since it's not yet known to be useful for Ret. That may complicate finding 1135 /// since it's not yet known to be useful for Ret. That may complicate finding
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 // violations and link errors. 1402 // violations and link errors.
1375 1403
1376 template <> void InstARM32Ldr::emit(const Cfg *Func) const; 1404 template <> void InstARM32Ldr::emit(const Cfg *Func) const;
1377 template <> void InstARM32Movw::emit(const Cfg *Func) const; 1405 template <> void InstARM32Movw::emit(const Cfg *Func) const;
1378 template <> void InstARM32Movt::emit(const Cfg *Func) const; 1406 template <> void InstARM32Movt::emit(const Cfg *Func) const;
1379 1407
1380 } // end of namespace ARM32 1408 } // end of namespace ARM32
1381 } // end of namespace Ice 1409 } // end of namespace Ice
1382 1410
1383 #endif // SUBZERO_SRC_ICEINSTARM32_H 1411 #endif // SUBZERO_SRC_ICEINSTARM32_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698