OLD | NEW |
---|---|
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 |
(...skipping 22 matching lines...) Expand all Loading... | |
33 OperandARM32() = delete; | 33 OperandARM32() = delete; |
34 OperandARM32(const OperandARM32 &) = delete; | 34 OperandARM32(const OperandARM32 &) = delete; |
35 OperandARM32 &operator=(const OperandARM32 &) = delete; | 35 OperandARM32 &operator=(const OperandARM32 &) = delete; |
36 | 36 |
37 public: | 37 public: |
38 enum OperandKindARM32 { | 38 enum OperandKindARM32 { |
39 k__Start = Operand::kTarget, | 39 k__Start = Operand::kTarget, |
40 kMem, | 40 kMem, |
41 kFlexStart, | 41 kFlexStart, |
42 kFlexImm = kFlexStart, | 42 kFlexImm = kFlexStart, |
43 kFlexFpImm, | |
44 kFlexFpZero, | |
43 kFlexReg, | 45 kFlexReg, |
44 kFlexEnd = kFlexReg | 46 kFlexEnd = kFlexReg |
45 }; | 47 }; |
46 | 48 |
47 enum ShiftKind { | 49 enum ShiftKind { |
48 kNoShift = -1, | 50 kNoShift = -1, |
49 #define X(enum, emit) enum, | 51 #define X(enum, emit) enum, |
50 ICEINSTARM32SHIFT_TABLE | 52 ICEINSTARM32SHIFT_TABLE |
51 #undef X | 53 #undef X |
52 }; | 54 }; |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
198 uint32_t getImm() const { return Imm; } | 200 uint32_t getImm() const { return Imm; } |
199 uint32_t getRotateAmt() const { return RotateAmt; } | 201 uint32_t getRotateAmt() const { return RotateAmt; } |
200 | 202 |
201 private: | 203 private: |
202 OperandARM32FlexImm(Cfg *Func, Type Ty, uint32_t Imm, uint32_t RotateAmt); | 204 OperandARM32FlexImm(Cfg *Func, Type Ty, uint32_t Imm, uint32_t RotateAmt); |
203 | 205 |
204 uint32_t Imm; | 206 uint32_t Imm; |
205 uint32_t RotateAmt; | 207 uint32_t RotateAmt; |
206 }; | 208 }; |
207 | 209 |
210 /// Modified Floating-point constant. | |
211 class OperandARM32FlexFpImm : public OperandARM32Flex { | |
212 OperandARM32FlexFpImm() = delete; | |
213 OperandARM32FlexFpImm(const OperandARM32FlexFpImm &) = delete; | |
214 OperandARM32FlexFpImm &operator=(const OperandARM32FlexFpImm &) = delete; | |
215 | |
216 public: | |
217 static OperandARM32FlexFpImm *create(Cfg *Func, Type Ty, | |
218 uint32_t ModifiedImm) { | |
219 return new (Func->allocate<OperandARM32FlexFpImm>()) | |
220 OperandARM32FlexFpImm(Func, Ty, ModifiedImm); | |
221 } | |
222 | |
223 void emit(const Cfg *Func) const override; | |
224 using OperandARM32::dump; | |
sehr
2015/11/13 21:56:29
What does this using do?
John
2015/11/14 00:00:38
Operand::dump is overloaded. The
OperandARM32Fle
Jim Stichnoth
2015/11/16 23:06:26
Interesting. Maybe we (I) should later take a pas
| |
225 void dump(const Cfg *Func, Ostream &Str) const override; | |
226 | |
227 static bool classof(const Operand *Operand) { | |
228 return Operand->getKind() == static_cast<OperandKind>(kFlexFpImm); | |
229 } | |
230 | |
231 static bool canHoldImm(Operand *C, uint32_t *ModifiedImm); | |
232 | |
233 private: | |
234 OperandARM32FlexFpImm(Cfg *Func, Type Ty, uint32_t ModifiedImm); | |
235 | |
236 uint32_t ModifiedImm; | |
237 }; | |
238 | |
239 /// An operand for representing the 0.0 immediate in vcmp. | |
240 class OperandARM32FlexFpZero : public OperandARM32Flex { | |
241 OperandARM32FlexFpZero() = delete; | |
242 OperandARM32FlexFpZero(const OperandARM32FlexFpZero &) = delete; | |
243 OperandARM32FlexFpZero &operator=(const OperandARM32FlexFpZero &) = delete; | |
244 | |
245 public: | |
246 static OperandARM32FlexFpZero *create(Cfg *Func, Type Ty) { | |
247 return new (Func->allocate<OperandARM32FlexFpZero>()) | |
248 OperandARM32FlexFpZero(Func, Ty); | |
249 } | |
250 | |
251 void emit(const Cfg *Func) const override; | |
252 using OperandARM32::dump; | |
253 void dump(const Cfg *Func, Ostream &Str) const override; | |
254 | |
255 static bool classof(const Operand *Operand) { | |
256 return Operand->getKind() == static_cast<OperandKind>(kFlexFpZero); | |
257 } | |
258 | |
259 private: | |
260 OperandARM32FlexFpZero(Cfg *Func, Type Ty); | |
261 }; | |
262 | |
208 /// Shifted register variant. | 263 /// Shifted register variant. |
209 class OperandARM32FlexReg : public OperandARM32Flex { | 264 class OperandARM32FlexReg : public OperandARM32Flex { |
210 OperandARM32FlexReg() = delete; | 265 OperandARM32FlexReg() = delete; |
211 OperandARM32FlexReg(const OperandARM32FlexReg &) = delete; | 266 OperandARM32FlexReg(const OperandARM32FlexReg &) = delete; |
212 OperandARM32FlexReg &operator=(const OperandARM32FlexReg &) = delete; | 267 OperandARM32FlexReg &operator=(const OperandARM32FlexReg &) = delete; |
213 | 268 |
214 public: | 269 public: |
215 /// Register with immediate/reg shift amount and shift operation. | 270 /// Register with immediate/reg shift amount and shift operation. |
216 static OperandARM32FlexReg *create(Cfg *Func, Type Ty, Variable *Reg, | 271 static OperandARM32FlexReg *create(Cfg *Func, Type Ty, Variable *Reg, |
217 ShiftKind ShiftOp, Operand *ShiftAmt) { | 272 ShiftKind ShiftOp, Operand *ShiftAmt) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
305 Movw, | 360 Movw, |
306 Mul, | 361 Mul, |
307 Mvn, | 362 Mvn, |
308 Orr, | 363 Orr, |
309 Pop, | 364 Pop, |
310 Push, | 365 Push, |
311 Rbit, | 366 Rbit, |
312 Ret, | 367 Ret, |
313 Rev, | 368 Rev, |
314 Rsb, | 369 Rsb, |
370 Rsc, | |
315 Sbc, | 371 Sbc, |
316 Sdiv, | 372 Sdiv, |
317 Str, | 373 Str, |
318 Strex, | 374 Strex, |
319 Sub, | 375 Sub, |
320 Sxt, | 376 Sxt, |
321 Trap, | 377 Trap, |
322 Tst, | 378 Tst, |
323 Udiv, | 379 Udiv, |
324 Umull, | 380 Umull, |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
602 dumpOpcodePred(Str, Opcode, getDest()->getType()); | 658 dumpOpcodePred(Str, Opcode, getDest()->getType()); |
603 Str << (SetFlags ? ".s " : " "); | 659 Str << (SetFlags ? ".s " : " "); |
604 dumpSources(Func); | 660 dumpSources(Func); |
605 } | 661 } |
606 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 662 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
607 | 663 |
608 private: | 664 private: |
609 InstARM32ThreeAddrGPR(Cfg *Func, Variable *Dest, Variable *Src0, | 665 InstARM32ThreeAddrGPR(Cfg *Func, Variable *Dest, Variable *Src0, |
610 Operand *Src1, CondARM32::Cond Predicate, bool SetFlags) | 666 Operand *Src1, CondARM32::Cond Predicate, bool SetFlags) |
611 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { | 667 : InstARM32Pred(Func, K, 2, Dest, Predicate), SetFlags(SetFlags) { |
668 HasSideEffects = SetFlags; | |
612 addSource(Src0); | 669 addSource(Src0); |
613 addSource(Src1); | 670 addSource(Src1); |
614 } | 671 } |
615 | 672 |
616 static const char *Opcode; | 673 static const char *Opcode; |
617 bool SetFlags; | 674 bool SetFlags; |
618 }; | 675 }; |
619 | 676 |
620 /// Instructions of the form x := y op z, for vector/FP. We leave these as | 677 /// Instructions of the form x := y op z, for vector/FP. We leave these as |
621 /// unconditional: "ARM deprecates the conditional execution of any instruction | 678 /// unconditional: "ARM deprecates the conditional execution of any instruction |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
734 dumpOpcodePred(Str, Opcode, getSrc(0)->getType()); | 791 dumpOpcodePred(Str, Opcode, getSrc(0)->getType()); |
735 Str << " "; | 792 Str << " "; |
736 dumpSources(Func); | 793 dumpSources(Func); |
737 } | 794 } |
738 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } | 795 static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
739 | 796 |
740 private: | 797 private: |
741 InstARM32CmpLike(Cfg *Func, Variable *Src0, Operand *Src1, | 798 InstARM32CmpLike(Cfg *Func, Variable *Src0, Operand *Src1, |
742 CondARM32::Cond Predicate) | 799 CondARM32::Cond Predicate) |
743 : InstARM32Pred(Func, K, 2, nullptr, Predicate) { | 800 : InstARM32Pred(Func, K, 2, nullptr, Predicate) { |
801 HasSideEffects = true; | |
744 addSource(Src0); | 802 addSource(Src0); |
745 addSource(Src1); | 803 addSource(Src1); |
746 } | 804 } |
747 | 805 |
748 static const char *Opcode; | 806 static const char *Opcode; |
749 }; | 807 }; |
750 | 808 |
751 using InstARM32Adc = InstARM32ThreeAddrGPR<InstARM32::Adc>; | 809 using InstARM32Adc = InstARM32ThreeAddrGPR<InstARM32::Adc>; |
752 using InstARM32Add = InstARM32ThreeAddrGPR<InstARM32::Add>; | 810 using InstARM32Add = InstARM32ThreeAddrGPR<InstARM32::Add>; |
753 using InstARM32And = InstARM32ThreeAddrGPR<InstARM32::And>; | 811 using InstARM32And = InstARM32ThreeAddrGPR<InstARM32::And>; |
754 using InstARM32Asr = InstARM32ThreeAddrGPR<InstARM32::Asr>; | 812 using InstARM32Asr = InstARM32ThreeAddrGPR<InstARM32::Asr>; |
755 using InstARM32Bic = InstARM32ThreeAddrGPR<InstARM32::Bic>; | 813 using InstARM32Bic = InstARM32ThreeAddrGPR<InstARM32::Bic>; |
756 using InstARM32Eor = InstARM32ThreeAddrGPR<InstARM32::Eor>; | 814 using InstARM32Eor = InstARM32ThreeAddrGPR<InstARM32::Eor>; |
757 using InstARM32Lsl = InstARM32ThreeAddrGPR<InstARM32::Lsl>; | 815 using InstARM32Lsl = InstARM32ThreeAddrGPR<InstARM32::Lsl>; |
758 using InstARM32Lsr = InstARM32ThreeAddrGPR<InstARM32::Lsr>; | 816 using InstARM32Lsr = InstARM32ThreeAddrGPR<InstARM32::Lsr>; |
759 using InstARM32Mul = InstARM32ThreeAddrGPR<InstARM32::Mul>; | 817 using InstARM32Mul = InstARM32ThreeAddrGPR<InstARM32::Mul>; |
760 using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>; | 818 using InstARM32Orr = InstARM32ThreeAddrGPR<InstARM32::Orr>; |
761 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; | 819 using InstARM32Rsb = InstARM32ThreeAddrGPR<InstARM32::Rsb>; |
820 using InstARM32Rsc = InstARM32ThreeAddrGPR<InstARM32::Rsc>; | |
762 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; | 821 using InstARM32Sbc = InstARM32ThreeAddrGPR<InstARM32::Sbc>; |
763 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; | 822 using InstARM32Sdiv = InstARM32ThreeAddrGPR<InstARM32::Sdiv>; |
764 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; | 823 using InstARM32Sub = InstARM32ThreeAddrGPR<InstARM32::Sub>; |
765 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; | 824 using InstARM32Udiv = InstARM32ThreeAddrGPR<InstARM32::Udiv>; |
766 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; | 825 using InstARM32Vadd = InstARM32ThreeAddrFP<InstARM32::Vadd>; |
767 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; | 826 using InstARM32Vdiv = InstARM32ThreeAddrFP<InstARM32::Vdiv>; |
768 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; | 827 using InstARM32Vmul = InstARM32ThreeAddrFP<InstARM32::Vmul>; |
769 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; | 828 using InstARM32Vsub = InstARM32ThreeAddrFP<InstARM32::Vsub>; |
770 using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>; | 829 using InstARM32Ldr = InstARM32LoadBase<InstARM32::Ldr>; |
771 using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>; | 830 using InstARM32Ldrex = InstARM32LoadBase<InstARM32::Ldrex>; |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1171 InstARM32Vcmp() = delete; | 1230 InstARM32Vcmp() = delete; |
1172 InstARM32Vcmp(const InstARM32Vcmp &) = delete; | 1231 InstARM32Vcmp(const InstARM32Vcmp &) = delete; |
1173 InstARM32Vcmp &operator=(const InstARM32Vcmp &) = delete; | 1232 InstARM32Vcmp &operator=(const InstARM32Vcmp &) = delete; |
1174 | 1233 |
1175 public: | 1234 public: |
1176 static InstARM32Vcmp *create(Cfg *Func, Variable *Src0, Variable *Src1, | 1235 static InstARM32Vcmp *create(Cfg *Func, Variable *Src0, Variable *Src1, |
1177 CondARM32::Cond Predicate) { | 1236 CondARM32::Cond Predicate) { |
1178 return new (Func->allocate<InstARM32Vcmp>()) | 1237 return new (Func->allocate<InstARM32Vcmp>()) |
1179 InstARM32Vcmp(Func, Src0, Src1, Predicate); | 1238 InstARM32Vcmp(Func, Src0, Src1, Predicate); |
1180 } | 1239 } |
1240 static InstARM32Vcmp *create(Cfg *Func, Variable *Src0, | |
1241 OperandARM32FlexFpZero *Src1, | |
1242 CondARM32::Cond Predicate) { | |
1243 return new (Func->allocate<InstARM32Vcmp>()) | |
1244 InstARM32Vcmp(Func, Src0, Src1, Predicate); | |
1245 } | |
1181 void emit(const Cfg *Func) const override; | 1246 void emit(const Cfg *Func) const override; |
1182 void dump(const Cfg *Func) const override; | 1247 void dump(const Cfg *Func) const override; |
1183 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcmp); } | 1248 static bool classof(const Inst *Inst) { return isClassof(Inst, Vcmp); } |
1184 | 1249 |
1185 private: | 1250 private: |
1186 InstARM32Vcmp(Cfg *Func, Variable *Src0, Variable *Src1, | 1251 InstARM32Vcmp(Cfg *Func, Variable *Src0, Operand *Src1, |
1187 CondARM32::Cond Predicate); | 1252 CondARM32::Cond Predicate); |
1188 }; | 1253 }; |
1189 | 1254 |
1190 /// Copies the FP Status and Control Register the core flags. | 1255 /// Copies the FP Status and Control Register the core flags. |
1191 class InstARM32Vmrs final : public InstARM32Pred { | 1256 class InstARM32Vmrs final : public InstARM32Pred { |
1192 InstARM32Vmrs() = delete; | 1257 InstARM32Vmrs() = delete; |
1193 InstARM32Vmrs(const InstARM32Vmrs &) = delete; | 1258 InstARM32Vmrs(const InstARM32Vmrs &) = delete; |
1194 InstARM32Vmrs &operator=(const InstARM32Vmrs &) = delete; | 1259 InstARM32Vmrs &operator=(const InstARM32Vmrs &) = delete; |
1195 | 1260 |
1196 public: | 1261 public: |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1246 // default implementations. Without this, there is the possibility of ODR | 1311 // default implementations. Without this, there is the possibility of ODR |
1247 // violations and link errors. | 1312 // violations and link errors. |
1248 | 1313 |
1249 template <> void InstARM32Ldr::emit(const Cfg *Func) const; | 1314 template <> void InstARM32Ldr::emit(const Cfg *Func) const; |
1250 template <> void InstARM32Movw::emit(const Cfg *Func) const; | 1315 template <> void InstARM32Movw::emit(const Cfg *Func) const; |
1251 template <> void InstARM32Movt::emit(const Cfg *Func) const; | 1316 template <> void InstARM32Movt::emit(const Cfg *Func) const; |
1252 | 1317 |
1253 } // end of namespace Ice | 1318 } // end of namespace Ice |
1254 | 1319 |
1255 #endif // SUBZERO_SRC_ICEINSTARM32_H | 1320 #endif // SUBZERO_SRC_ICEINSTARM32_H |
OLD | NEW |