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

Side by Side Diff: src/IceInstARM32.h

Issue 1127003003: Lower a few basic ARM binops for i{8,16,32,64}. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: added condition and target to test Created 5 years, 7 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/IceInstARM32.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 }; 238 };
239 239
240 class InstARM32 : public InstTarget { 240 class InstARM32 : public InstTarget {
241 InstARM32() = delete; 241 InstARM32() = delete;
242 InstARM32(const InstARM32 &) = delete; 242 InstARM32(const InstARM32 &) = delete;
243 InstARM32 &operator=(const InstARM32 &) = delete; 243 InstARM32 &operator=(const InstARM32 &) = delete;
244 244
245 public: 245 public:
246 enum InstKindARM32 { 246 enum InstKindARM32 {
247 k__Start = Inst::Target, 247 k__Start = Inst::Target,
248 Adc,
249 Add,
250 And,
251 Eor,
252 Ldr,
253 Mla,
248 Mov, 254 Mov,
249 Movt, 255 Movt,
250 Movw, 256 Movw,
257 Mul,
251 Mvn, 258 Mvn,
259 Orr,
252 Ret, 260 Ret,
253 Ldr 261 Sbc,
262 Sub,
263 Umull
254 }; 264 };
255 265
256 static const char *getWidthString(Type Ty); 266 static const char *getWidthString(Type Ty);
257 267
258 void dump(const Cfg *Func) const override; 268 void dump(const Cfg *Func) const override;
259 269
260 protected: 270 protected:
261 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest) 271 InstARM32(Cfg *Func, InstKindARM32 Kind, SizeT Maxsrcs, Variable *Dest)
262 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {} 272 : InstTarget(Func, static_cast<InstKind>(Kind), Maxsrcs, Dest) {}
263 ~InstARM32() override {} 273 ~InstARM32() override {}
264 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) { 274 static bool isClassof(const Inst *Inst, InstKindARM32 MyKind) {
265 return Inst->getKind() == static_cast<InstKind>(MyKind); 275 return Inst->getKind() == static_cast<InstKind>(MyKind);
266 } 276 }
267 }; 277 };
268 278
269 void emitTwoAddr(const char *Opcode, const Inst *Inst, const Cfg *Func); 279 void emitTwoAddr(const char *Opcode, const Inst *Inst, const Cfg *Func);
280 void emitThreeAddr(const char *Opcode, const Inst *Inst, const Cfg *Func,
281 bool SetFlags);
270 282
271 // TODO(jvoung): add condition codes if instruction can be predicated. 283 // TODO(jvoung): add condition codes if instruction can be predicated.
272 284
273 // Instructions of the form x := op(y). 285 // Instructions of the form x := op(y).
274 template <InstARM32::InstKindARM32 K> 286 template <InstARM32::InstKindARM32 K>
275 class InstARM32UnaryopGPR : public InstARM32 { 287 class InstARM32UnaryopGPR : public InstARM32 {
276 InstARM32UnaryopGPR() = delete; 288 InstARM32UnaryopGPR() = delete;
277 InstARM32UnaryopGPR(const InstARM32UnaryopGPR &) = delete; 289 InstARM32UnaryopGPR(const InstARM32UnaryopGPR &) = delete;
278 InstARM32UnaryopGPR &operator=(const InstARM32UnaryopGPR &) = delete; 290 InstARM32UnaryopGPR &operator=(const InstARM32UnaryopGPR &) = delete;
279 291
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 private: 402 private:
391 InstARM32Movlike(Cfg *Func, Variable *Dest, Operand *Source) 403 InstARM32Movlike(Cfg *Func, Variable *Dest, Operand *Source)
392 : InstARM32(Func, K, 1, Dest) { 404 : InstARM32(Func, K, 1, Dest) {
393 addSource(Source); 405 addSource(Source);
394 } 406 }
395 ~InstARM32Movlike() override {} 407 ~InstARM32Movlike() override {}
396 408
397 static const char *Opcode; 409 static const char *Opcode;
398 }; 410 };
399 411
412 // Instructions of the form x := y op z. May have the side-effect of setting
413 // status flags.
414 template <InstARM32::InstKindARM32 K>
415 class InstARM32ThreeAddrGPR : public InstARM32 {
416 InstARM32ThreeAddrGPR() = delete;
417 InstARM32ThreeAddrGPR(const InstARM32ThreeAddrGPR &) = delete;
418 InstARM32ThreeAddrGPR &operator=(const InstARM32ThreeAddrGPR &) = delete;
419
420 public:
421 // Create an ordinary binary-op instruction like add, and sub.
422 // Dest and Src1 must be registers.
423 static InstARM32ThreeAddrGPR *create(Cfg *Func, Variable *Dest,
424 Variable *Src1, Operand *Src2,
425 bool SetFlags = false) {
426 return new (Func->allocate<InstARM32ThreeAddrGPR>())
427 InstARM32ThreeAddrGPR(Func, Dest, Src1, Src2, SetFlags);
428 }
429 void emit(const Cfg *Func) const override {
430 if (!ALLOW_DUMP)
431 return;
432 emitThreeAddr(Opcode, this, Func, SetFlags);
433 }
434 void emitIAS(const Cfg *Func) const override {
435 (void)Func;
436 llvm::report_fatal_error("Not yet implemented");
437 }
438 void dump(const Cfg *Func) const override {
439 if (!ALLOW_DUMP)
440 return;
441 Ostream &Str = Func->getContext()->getStrDump();
442 dumpDest(Func);
443 Str << " = " << Opcode << (SetFlags ? "s" : "") << "."
444 << getDest()->getType() << " ";
445 dumpSources(Func);
446 }
447 static bool classof(const Inst *Inst) { return isClassof(Inst, K); }
448
449 private:
450 InstARM32ThreeAddrGPR(Cfg *Func, Variable *Dest, Variable *Src1,
451 Operand *Src2, bool SetFlags)
452 : InstARM32(Func, K, 2, Dest), SetFlags(SetFlags) {
453 addSource(Src1);
454 addSource(Src2);
455 }
456 ~InstARM32ThreeAddrGPR() override {}
457 static const char *Opcode;
458 bool SetFlags;
459 };
460
461 typedef InstARM32ThreeAddrGPR<InstARM32::Adc> InstARM32Adc;
462 typedef InstARM32ThreeAddrGPR<InstARM32::Add> InstARM32Add;
463 typedef InstARM32ThreeAddrGPR<InstARM32::And> InstARM32And;
464 typedef InstARM32ThreeAddrGPR<InstARM32::Eor> InstARM32Eor;
465 typedef InstARM32ThreeAddrGPR<InstARM32::Mul> InstARM32Mul;
466 typedef InstARM32ThreeAddrGPR<InstARM32::Orr> InstARM32Orr;
467 typedef InstARM32ThreeAddrGPR<InstARM32::Sbc> InstARM32Sbc;
468 typedef InstARM32ThreeAddrGPR<InstARM32::Sub> InstARM32Sub;
400 // Move instruction (variable <- flex). This is more of a pseudo-inst. 469 // Move instruction (variable <- flex). This is more of a pseudo-inst.
401 // If var is a register, then we use "mov". If var is stack, then we use 470 // If var is a register, then we use "mov". If var is stack, then we use
402 // "str" to store to the stack. 471 // "str" to store to the stack.
403 typedef InstARM32Movlike<InstARM32::Mov> InstARM32Mov; 472 typedef InstARM32Movlike<InstARM32::Mov> InstARM32Mov;
404 // MovT leaves the bottom bits alone so dest is also a source. 473 // MovT leaves the bottom bits alone so dest is also a source.
405 // This helps indicate that a previous MovW setting dest is not dead code. 474 // This helps indicate that a previous MovW setting dest is not dead code.
406 typedef InstARM32TwoAddrGPR<InstARM32::Movt> InstARM32Movt; 475 typedef InstARM32TwoAddrGPR<InstARM32::Movt> InstARM32Movt;
407 typedef InstARM32UnaryopGPR<InstARM32::Movw> InstARM32Movw; 476 typedef InstARM32UnaryopGPR<InstARM32::Movw> InstARM32Movw;
408 typedef InstARM32UnaryopGPR<InstARM32::Mvn> InstARM32Mvn; 477 typedef InstARM32UnaryopGPR<InstARM32::Mvn> InstARM32Mvn;
409 478
(...skipping 11 matching lines...) Expand all
421 void emit(const Cfg *Func) const override; 490 void emit(const Cfg *Func) const override;
422 void emitIAS(const Cfg *Func) const override; 491 void emitIAS(const Cfg *Func) const override;
423 void dump(const Cfg *Func) const override; 492 void dump(const Cfg *Func) const override;
424 static bool classof(const Inst *Inst) { return isClassof(Inst, Ldr); } 493 static bool classof(const Inst *Inst) { return isClassof(Inst, Ldr); }
425 494
426 private: 495 private:
427 InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem); 496 InstARM32Ldr(Cfg *Func, Variable *Dest, OperandARM32Mem *Mem);
428 ~InstARM32Ldr() override {} 497 ~InstARM32Ldr() override {}
429 }; 498 };
430 499
500 // Multiply Accumulate: d := x * y + a
501 class InstARM32Mla : public InstARM32 {
502 InstARM32Mla() = delete;
503 InstARM32Mla(const InstARM32Mla &) = delete;
504 InstARM32Mla &operator=(const InstARM32Mla &) = delete;
505
506 public:
507 // Everything must be a register.
508 static InstARM32Mla *create(Cfg *Func, Variable *Dest, Variable *Src0,
509 Variable *Src1, Variable *Acc) {
510 return new (Func->allocate<InstARM32Mla>())
511 InstARM32Mla(Func, Dest, Src0, Src1, Acc);
512 }
513 void emit(const Cfg *Func) const override;
514 void emitIAS(const Cfg *Func) const override;
515 void dump(const Cfg *Func) const override;
516 static bool classof(const Inst *Inst) { return isClassof(Inst, Mla); }
517
518 private:
519 InstARM32Mla(Cfg *Func, Variable *Dest, Variable *Src0, Variable *Src1,
520 Variable *Acc);
521 ~InstARM32Mla() override {}
522 };
523
431 // Ret pseudo-instruction. This is actually a "bx" instruction with 524 // Ret pseudo-instruction. This is actually a "bx" instruction with
432 // an "lr" register operand, but epilogue lowering will search for a Ret 525 // an "lr" register operand, but epilogue lowering will search for a Ret
433 // instead of a generic "bx". This instruction also takes a Source 526 // instead of a generic "bx". This instruction also takes a Source
434 // operand (for non-void returning functions) for liveness analysis, though 527 // operand (for non-void returning functions) for liveness analysis, though
435 // a FakeUse before the ret would do just as well. 528 // a FakeUse before the ret would do just as well.
436 class InstARM32Ret : public InstARM32 { 529 class InstARM32Ret : public InstARM32 {
437 InstARM32Ret() = delete; 530 InstARM32Ret() = delete;
438 InstARM32Ret(const InstARM32Ret &) = delete; 531 InstARM32Ret(const InstARM32Ret &) = delete;
439 InstARM32Ret &operator=(const InstARM32Ret &) = delete; 532 InstARM32Ret &operator=(const InstARM32Ret &) = delete;
440 533
441 public: 534 public:
442 static InstARM32Ret *create(Cfg *Func, Variable *LR, 535 static InstARM32Ret *create(Cfg *Func, Variable *LR,
443 Variable *Source = nullptr) { 536 Variable *Source = nullptr) {
444 return new (Func->allocate<InstARM32Ret>()) InstARM32Ret(Func, LR, Source); 537 return new (Func->allocate<InstARM32Ret>()) InstARM32Ret(Func, LR, Source);
445 } 538 }
446 void emit(const Cfg *Func) const override; 539 void emit(const Cfg *Func) const override;
447 void emitIAS(const Cfg *Func) const override; 540 void emitIAS(const Cfg *Func) const override;
448 void dump(const Cfg *Func) const override; 541 void dump(const Cfg *Func) const override;
449 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); } 542 static bool classof(const Inst *Inst) { return isClassof(Inst, Ret); }
450 543
451 private: 544 private:
452 InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source); 545 InstARM32Ret(Cfg *Func, Variable *LR, Variable *Source);
453 ~InstARM32Ret() override {} 546 ~InstARM32Ret() override {}
454 }; 547 };
455 548
549 // Unsigned Multiply Long: d.lo, d.hi := x * y
550 class InstARM32Umull : public InstARM32 {
551 InstARM32Umull() = delete;
552 InstARM32Umull(const InstARM32Umull &) = delete;
553 InstARM32Umull &operator=(const InstARM32Umull &) = delete;
554
555 public:
556 // Everything must be a register.
557 static InstARM32Umull *create(Cfg *Func, Variable *DestLo, Variable *DestHi,
558 Variable *Src0, Variable *Src1) {
559 return new (Func->allocate<InstARM32Umull>())
560 InstARM32Umull(Func, DestLo, DestHi, Src0, Src1);
561 }
562 void emit(const Cfg *Func) const override;
563 void emitIAS(const Cfg *Func) const override;
564 void dump(const Cfg *Func) const override;
565 static bool classof(const Inst *Inst) { return isClassof(Inst, Umull); }
566
567 private:
568 InstARM32Umull(Cfg *Func, Variable *DestLo, Variable *DestHi, Variable *Src0,
569 Variable *Src1);
570 ~InstARM32Umull() override {}
571 Variable *DestHi;
572 };
573
456 // Declare partial template specializations of emit() methods that 574 // Declare partial template specializations of emit() methods that
457 // already have default implementations. Without this, there is the 575 // already have default implementations. Without this, there is the
458 // possibility of ODR violations and link errors. 576 // possibility of ODR violations and link errors.
459 577
460 template <> void InstARM32Movw::emit(const Cfg *Func) const; 578 template <> void InstARM32Movw::emit(const Cfg *Func) const;
461 template <> void InstARM32Movt::emit(const Cfg *Func) const; 579 template <> void InstARM32Movt::emit(const Cfg *Func) const;
462 580
463 } // end of namespace Ice 581 } // end of namespace Ice
464 582
465 #endif // SUBZERO_SRC_ICEINSTARM32_H 583 #endif // SUBZERO_SRC_ICEINSTARM32_H
OLDNEW
« no previous file with comments | « no previous file | src/IceInstARM32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698