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

Side by Side Diff: src/IceInstARM32.cpp

Issue 1359193003: Subzero. Enables (most) crosstests for ARM32. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. 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 | « src/IceInstARM32.h ('k') | src/IceInstARM32.def » ('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.cpp - ARM32 instruction implementation ----===// 1 //===- subzero/src/IceInstARM32.cpp - ARM32 instruction implementation ----===//
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 15 matching lines...) Expand all
26 namespace Ice { 26 namespace Ice {
27 27
28 namespace { 28 namespace {
29 29
30 const struct TypeARM32Attributes_ { 30 const struct TypeARM32Attributes_ {
31 const char *WidthString; // b, h, <blank>, or d 31 const char *WidthString; // b, h, <blank>, or d
32 const char *VecWidthString; // i8, i16, i32, f32, f64 32 const char *VecWidthString; // i8, i16, i32, f32, f64
33 int8_t SExtAddrOffsetBits; 33 int8_t SExtAddrOffsetBits;
34 int8_t ZExtAddrOffsetBits; 34 int8_t ZExtAddrOffsetBits;
35 } TypeARM32Attributes[] = { 35 } TypeARM32Attributes[] = {
36 #define X(tag, elementty, int_width, vec_width, sbits, ubits) \ 36 #define X(tag, elementty, int_width, vec_width, sbits, ubits, rraddr) \
37 { int_width, vec_width, sbits, ubits } \ 37 { int_width, vec_width, sbits, ubits } \
38 , 38 ,
39 ICETYPEARM32_TABLE 39 ICETYPEARM32_TABLE
40 #undef X 40 #undef X
41 }; 41 };
42 42
43 const struct InstARM32ShiftAttributes_ { 43 const struct InstARM32ShiftAttributes_ {
44 const char *EmitString; 44 const char *EmitString;
45 } InstARM32ShiftAttributes[] = { 45 } InstARM32ShiftAttributes[] = {
46 #define X(tag, emit) \ 46 #define X(tag, emit) \
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 Vars[1] = Index; 204 Vars[1] = Index;
205 } 205 }
206 206
207 bool OperandARM32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) { 207 bool OperandARM32Mem::canHoldOffset(Type Ty, bool SignExt, int32_t Offset) {
208 int32_t Bits = SignExt ? TypeARM32Attributes[Ty].SExtAddrOffsetBits 208 int32_t Bits = SignExt ? TypeARM32Attributes[Ty].SExtAddrOffsetBits
209 : TypeARM32Attributes[Ty].ZExtAddrOffsetBits; 209 : TypeARM32Attributes[Ty].ZExtAddrOffsetBits;
210 if (Bits == 0) 210 if (Bits == 0)
211 return Offset == 0; 211 return Offset == 0;
212 // Note that encodings for offsets are sign-magnitude for ARM, so we check 212 // Note that encodings for offsets are sign-magnitude for ARM, so we check
213 // with IsAbsoluteUint(). 213 // with IsAbsoluteUint().
214 if (isScalarFloatingType(Ty))
215 return Utils::IsAligned(Offset, 4) && Utils::IsAbsoluteUint(Bits, Offset);
216 return Utils::IsAbsoluteUint(Bits, Offset); 214 return Utils::IsAbsoluteUint(Bits, Offset);
217 } 215 }
218 216
219 OperandARM32FlexImm::OperandARM32FlexImm(Cfg * /* Func */, Type Ty, 217 OperandARM32FlexImm::OperandARM32FlexImm(Cfg * /* Func */, Type Ty,
220 uint32_t Imm, uint32_t RotateAmt) 218 uint32_t Imm, uint32_t RotateAmt)
221 : OperandARM32Flex(kFlexImm, Ty), Imm(Imm), RotateAmt(RotateAmt) { 219 : OperandARM32Flex(kFlexImm, Ty), Imm(Imm), RotateAmt(RotateAmt) {
222 NumVars = 0; 220 NumVars = 0;
223 Vars = nullptr; 221 Vars = nullptr;
224 } 222 }
225 223
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 InstARM32Vcmp::InstARM32Vcmp(Cfg *Func, Variable *Src0, Variable *Src1, 383 InstARM32Vcmp::InstARM32Vcmp(Cfg *Func, Variable *Src0, Variable *Src1,
386 CondARM32::Cond Predicate) 384 CondARM32::Cond Predicate)
387 : InstARM32Pred(Func, InstARM32::Vcmp, 2, nullptr, Predicate) { 385 : InstARM32Pred(Func, InstARM32::Vcmp, 2, nullptr, Predicate) {
388 addSource(Src0); 386 addSource(Src0);
389 addSource(Src1); 387 addSource(Src1);
390 } 388 }
391 389
392 InstARM32Vmrs::InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate) 390 InstARM32Vmrs::InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate)
393 : InstARM32Pred(Func, InstARM32::Vmrs, 0, nullptr, Predicate) {} 391 : InstARM32Pred(Func, InstARM32::Vmrs, 0, nullptr, Predicate) {}
394 392
393 InstARM32Vabs::InstARM32Vabs(Cfg *Func, Variable *Dest, Variable *Src,
394 CondARM32::Cond Predicate)
395 : InstARM32Pred(Func, InstARM32::Vabs, 1, Dest, Predicate) {
396 addSource(Src);
397 }
395 // ======================== Dump routines ======================== // 398 // ======================== Dump routines ======================== //
396 399
397 // Two-addr ops 400 // Two-addr ops
398 template <> const char *InstARM32Movt::Opcode = "movt"; 401 template <> const char *InstARM32Movt::Opcode = "movt";
399 // Unary ops 402 // Unary ops
400 template <> const char *InstARM32Movw::Opcode = "movw"; 403 template <> const char *InstARM32Movw::Opcode = "movw";
401 template <> const char *InstARM32Clz::Opcode = "clz"; 404 template <> const char *InstARM32Clz::Opcode = "clz";
402 template <> const char *InstARM32Mvn::Opcode = "mvn"; 405 template <> const char *InstARM32Mvn::Opcode = "mvn";
403 template <> const char *InstARM32Rbit::Opcode = "rbit"; 406 template <> const char *InstARM32Rbit::Opcode = "rbit";
404 template <> const char *InstARM32Rev::Opcode = "rev"; 407 template <> const char *InstARM32Rev::Opcode = "rev";
405 template <> const char *InstARM32Sxt::Opcode = "sxt"; // still requires b/h 408 template <> const char *InstARM32Sxt::Opcode = "sxt"; // still requires b/h
406 template <> const char *InstARM32Uxt::Opcode = "uxt"; // still requires b/h 409 template <> const char *InstARM32Uxt::Opcode = "uxt"; // still requires b/h
407 // FP 410 // FP
408 template <> const char *InstARM32Vsqrt::Opcode = "vsqrt"; 411 template <> const char *InstARM32Vsqrt::Opcode = "vsqrt";
409 // Mov-like ops 412 // Mov-like ops
410 template <> const char *InstARM32Ldr::Opcode = "ldr"; 413 template <> const char *InstARM32Ldr::Opcode = "ldr";
411 template <> const char *InstARM32Mov::Opcode = "mov";
412 // FP
413 template <> const char *InstARM32Vldr::Opcode = "vldr";
414 // Three-addr ops 414 // Three-addr ops
415 template <> const char *InstARM32Adc::Opcode = "adc"; 415 template <> const char *InstARM32Adc::Opcode = "adc";
416 template <> const char *InstARM32Add::Opcode = "add"; 416 template <> const char *InstARM32Add::Opcode = "add";
417 template <> const char *InstARM32And::Opcode = "and"; 417 template <> const char *InstARM32And::Opcode = "and";
418 template <> const char *InstARM32Asr::Opcode = "asr"; 418 template <> const char *InstARM32Asr::Opcode = "asr";
419 template <> const char *InstARM32Bic::Opcode = "bic"; 419 template <> const char *InstARM32Bic::Opcode = "bic";
420 template <> const char *InstARM32Eor::Opcode = "eor"; 420 template <> const char *InstARM32Eor::Opcode = "eor";
421 template <> const char *InstARM32Lsl::Opcode = "lsl"; 421 template <> const char *InstARM32Lsl::Opcode = "lsl";
422 template <> const char *InstARM32Lsr::Opcode = "lsr"; 422 template <> const char *InstARM32Lsr::Opcode = "lsr";
423 template <> const char *InstARM32Mul::Opcode = "mul"; 423 template <> const char *InstARM32Mul::Opcode = "mul";
(...skipping 16 matching lines...) Expand all
440 template <> const char *InstARM32Tst::Opcode = "tst"; 440 template <> const char *InstARM32Tst::Opcode = "tst";
441 441
442 void InstARM32::dump(const Cfg *Func) const { 442 void InstARM32::dump(const Cfg *Func) const {
443 if (!BuildDefs::dump()) 443 if (!BuildDefs::dump())
444 return; 444 return;
445 Ostream &Str = Func->getContext()->getStrDump(); 445 Ostream &Str = Func->getContext()->getStrDump();
446 Str << "[ARM32] "; 446 Str << "[ARM32] ";
447 Inst::dump(Func); 447 Inst::dump(Func);
448 } 448 }
449 449
450 template <> void InstARM32Mov::emit(const Cfg *Func) const { 450 void InstARM32Mov::emitMultiDestSingleSource(const Cfg *Func) const {
451 if (!BuildDefs::dump()) 451 if (!BuildDefs::dump())
452 return; 452 return;
453 Ostream &Str = Func->getContext()->getStrEmit(); 453 Ostream &Str = Func->getContext()->getStrEmit();
454 assert(getSrcSize() == 1); 454 auto *Dest = llvm::cast<Variable64On32>(getDest());
455 Variable *Dest = getDest(); 455 Operand *Src = getSrc(0);
456 if (Dest->hasReg()) { 456
457 IceString ActualOpcode = Opcode; 457 assert(Dest->getType() == IceType_i64);
458 Operand *Src0 = getSrc(0); 458 assert(Dest->getHi()->hasReg());
459 if (const auto *Src0V = llvm::dyn_cast<Variable>(Src0)) { 459 assert(Dest->getLo()->hasReg());
460 if (!Src0V->hasReg()) { 460 assert(!llvm::isa<OperandARM32Mem>(Src));
461 // Always use the whole stack slot. A 32-bit load has a larger range of 461
462 // offsets than 16-bit, etc. 462 Str << "\t"
463 ActualOpcode = IceString("ldr"); 463 << "vmov" << getPredicate() << "\t";
464 } 464 Dest->getLo()->emit(Func);
465 } else { 465 Str << ", ";
466 if (llvm::isa<OperandARM32Mem>(Src0)) 466 Dest->getHi()->emit(Func);
467 ActualOpcode = IceString("ldr") + getWidthString(Dest->getType()); 467 Str << ", ";
468 } 468 Src->emit(Func);
469 Str << "\t" << ActualOpcode << getPredicate() << "\t";
470 getDest()->emit(Func);
471 Str << ", ";
472 getSrc(0)->emit(Func);
473 } else {
474 Variable *Src0 = llvm::cast<Variable>(getSrc(0));
475 assert(Src0->hasReg());
476 Str << "\t"
477 << "str" << getPredicate() << "\t";
478 Src0->emit(Func);
479 Str << ", ";
480 Dest->emit(Func);
481 }
482 } 469 }
483 470
484 template <> void InstARM32Mov::emitIAS(const Cfg *Func) const { 471 void InstARM32Mov::emitSingleDestMultiSource(const Cfg *Func) const {
485 assert(getSrcSize() == 1);
486 (void)Func;
487 llvm_unreachable("Not yet implemented");
488 }
489
490 template <> void InstARM32Vldr::emit(const Cfg *Func) const {
491 if (!BuildDefs::dump()) 472 if (!BuildDefs::dump())
492 return; 473 return;
493 Ostream &Str = Func->getContext()->getStrEmit(); 474 Ostream &Str = Func->getContext()->getStrEmit();
494 assert(getSrcSize() == 1); 475 Variable *Dest = getDest();
495 assert(getDest()->hasReg()); 476 auto *Src = llvm::cast<Variable64On32>(getSrc(0));
496 Str << "\t" << Opcode << getPredicate() << "\t";
497 getDest()->emit(Func);
498 Str << ", ";
499 getSrc(0)->emit(Func);
500 }
501 477
502 template <> void InstARM32Vldr::emitIAS(const Cfg *Func) const { 478 assert(Src->getType() == IceType_i64);
503 assert(getSrcSize() == 1); 479 assert(Src->getHi()->hasReg());
504 (void)Func; 480 assert(Src->getLo()->hasReg());
505 llvm_unreachable("Not yet implemented"); 481 assert(Dest->hasReg());
506 }
507
508 void InstARM32Vmov::emitMultiDestSingleSource(const Cfg *Func) const {
509 if (!BuildDefs::dump())
510 return;
511 Ostream &Str = Func->getContext()->getStrEmit();
512 Variable *Dest0 = getDest();
513 Operand *Src0 = getSrc(0);
514
515 assert(Dest0->hasReg());
516 assert(Dest1->hasReg());
517 assert(!llvm::isa<OperandARM32Mem>(Src0));
518 482
519 Str << "\t" 483 Str << "\t"
520 << "vmov" << getPredicate() << "\t"; 484 << "vmov" << getPredicate() << "\t";
521 Dest0->emit(Func); 485 Dest->emit(Func);
522 Str << ", "; 486 Str << ", ";
523 Dest1->emit(Func); 487 Src->getLo()->emit(Func);
524 Str << ", "; 488 Str << ", ";
525 Src0->emit(Func); 489 Src->getHi()->emit(Func);
526 }
527
528 void InstARM32Vmov::emitSingleDestMultiSource(const Cfg *Func) const {
529 if (!BuildDefs::dump())
530 return;
531 Ostream &Str = Func->getContext()->getStrEmit();
532 Variable *Dest0 = getDest();
533 Operand *Src0 = getSrc(0);
534 Operand *Src1 = getSrc(1);
535
536 assert(Dest0->hasReg());
537 assert(!llvm::isa<OperandARM32Mem>(Src0));
538 assert(!llvm::isa<OperandARM32Mem>(Src1));
539
540 Str << "\t"
541 << "vmov" << getPredicate() << "\t";
542 Dest0->emit(Func);
543 Str << ", ";
544 Src0->emit(Func);
545 Str << ", ";
546 Src1->emit(Func);
547 } 490 }
548 491
549 namespace { 492 namespace {
493
550 bool isVariableWithoutRegister(const Operand *Op) { 494 bool isVariableWithoutRegister(const Operand *Op) {
551 if (const auto *OpV = llvm::dyn_cast<const Variable>(Op)) { 495 if (const auto *OpV = llvm::dyn_cast<const Variable>(Op)) {
552 return !OpV->hasReg(); 496 return !OpV->hasReg();
553 } 497 }
554 return false; 498 return false;
555 } 499 }
556
557 bool isMemoryAccess(Operand *Op) { 500 bool isMemoryAccess(Operand *Op) {
558 return isVariableWithoutRegister(Op) || llvm::isa<OperandARM32Mem>(Op); 501 return isVariableWithoutRegister(Op) || llvm::isa<OperandARM32Mem>(Op);
559 } 502 }
560 503
561 bool isMoveBetweenCoreAndVFPRegisters(Variable *Dest, Operand *Src) { 504 bool isMoveBetweenCoreAndVFPRegisters(Variable *Dest, Operand *Src) {
562 const Type DestTy = Dest->getType(); 505 const Type DestTy = Dest->getType();
563 const Type SrcTy = Src->getType(); 506 const Type SrcTy = Src->getType();
564 assert(!(isScalarIntegerType(DestTy) && isScalarIntegerType(SrcTy)) && 507 return !isVectorType(DestTy) && !isVectorType(SrcTy) &&
565 "At most one of vmov's operands can be a core register."); 508 (isScalarIntegerType(DestTy) == isScalarFloatingType(SrcTy));
566 return isScalarIntegerType(DestTy) || isScalarIntegerType(SrcTy);
567 } 509 }
510
568 } // end of anonymous namespace 511 } // end of anonymous namespace
569 512
570 void InstARM32Vmov::emitSingleDestSingleSource(const Cfg *Func) const { 513 void InstARM32Mov::emitSingleDestSingleSource(const Cfg *Func) const {
571 if (!BuildDefs::dump()) 514 if (!BuildDefs::dump())
572 return; 515 return;
573 Ostream &Str = Func->getContext()->getStrEmit(); 516 Ostream &Str = Func->getContext()->getStrEmit();
574 Variable *Dest = getDest(); 517 Variable *Dest = getDest();
518
575 if (Dest->hasReg()) { 519 if (Dest->hasReg()) {
520 Type DestTy = Dest->getType();
576 Operand *Src0 = getSrc(0); 521 Operand *Src0 = getSrc(0);
577 const char *ActualOpcode = isMemoryAccess(Src0) ? "vldr" : "vmov"; 522 const bool DestIsVector = isVectorType(DestTy);
523 const bool DestIsScalarFP = isScalarFloatingType(Dest->getType());
524 const bool CoreVFPMove = isMoveBetweenCoreAndVFPRegisters(Dest, Src0);
525 const char *LoadOpcode =
526 DestIsVector ? "vld1" : (DestIsScalarFP ? "vldr" : "ldr");
527 const char *RegMovOpcode =
528 (DestIsVector || DestIsScalarFP || CoreVFPMove) ? "vmov" : "mov";
529 const char *ActualOpcode = isMemoryAccess(Src0) ? LoadOpcode : RegMovOpcode;
578 // when vmov{c}'ing, we need to emit a width string. Otherwise, the 530 // when vmov{c}'ing, we need to emit a width string. Otherwise, the
579 // assembler might be tempted to assume we want a vector vmov{c}, and that 531 // assembler might be tempted to assume we want a vector vmov{c}, and that
580 // is disallowed because ARM. 532 // is disallowed because ARM.
533 const char *NoWidthString = "";
581 const char *WidthString = 534 const char *WidthString =
582 (isMemoryAccess(Src0) || isMoveBetweenCoreAndVFPRegisters(Dest, Src0)) 535 isMemoryAccess(Src0)
583 ? "" 536 ? (DestIsVector ? ".64" : NoWidthString)
584 : getVecWidthString(Src0->getType()); 537 : (!CoreVFPMove ? getVecWidthString(DestTy) : NoWidthString);
538
585 Str << "\t" << ActualOpcode << getPredicate() << WidthString << "\t"; 539 Str << "\t" << ActualOpcode << getPredicate() << WidthString << "\t";
586 Dest->emit(Func); 540 Dest->emit(Func);
587 Str << ", "; 541 Str << ", ";
588 Src0->emit(Func); 542 Src0->emit(Func);
589 } else { 543 } else {
590 Variable *Src0 = llvm::cast<Variable>(getSrc(0)); 544 Variable *Src0 = llvm::cast<Variable>(getSrc(0));
591 assert(Src0->hasReg()); 545 assert(Src0->hasReg());
592 Str << "\t" 546 const char *ActualOpcode =
593 "vstr" << getPredicate() << "\t"; 547 isVectorType(Src0->getType())
548 ? "vst1"
549 : (isScalarFloatingType(Src0->getType()) ? "vstr" : "str");
550 const char *NoWidthString = "";
551 const char *WidthString =
552 isVectorType(Src0->getType()) ? ".64" : NoWidthString;
553 Str << "\t" << ActualOpcode << getPredicate() << WidthString << "\t";
594 Src0->emit(Func); 554 Src0->emit(Func);
595 Str << ", "; 555 Str << ", ";
596 Dest->emit(Func); 556 Dest->emit(Func);
597 } 557 }
598 } 558 }
599 559
600 void InstARM32Vmov::emit(const Cfg *Func) const { 560 void InstARM32Mov::emit(const Cfg *Func) const {
601 if (!BuildDefs::dump()) 561 if (!BuildDefs::dump())
602 return; 562 return;
603 assert(isMultiDest() + isMultiSource() <= 1 && "Invalid vmov type."); 563 assert(!(isMultiDest() && isMultiSource()) && "Invalid vmov type.");
604 if (isMultiDest()) { 564 if (isMultiDest()) {
605 emitMultiDestSingleSource(Func); 565 emitMultiDestSingleSource(Func);
606 return; 566 return;
607 } 567 }
608 568
609 if (isMultiSource()) { 569 if (isMultiSource()) {
610 emitSingleDestMultiSource(Func); 570 emitSingleDestMultiSource(Func);
611 return; 571 return;
612 } 572 }
613 573
614 emitSingleDestSingleSource(Func); 574 emitSingleDestSingleSource(Func);
615 } 575 }
616 576
617 void InstARM32Vmov::emitIAS(const Cfg *Func) const { 577 void InstARM32Mov::emitIAS(const Cfg *Func) const {
618 assert(getSrcSize() == 1); 578 assert(getSrcSize() == 1);
619 (void)Func; 579 (void)Func;
620 llvm_unreachable("Not yet implemented"); 580 llvm_unreachable("Not yet implemented");
621 } 581 }
622 582
623 void InstARM32Vmov::dump(const Cfg *Func) const { 583 void InstARM32Mov::dump(const Cfg *Func) const {
624 if (!BuildDefs::dump()) 584 if (!BuildDefs::dump())
625 return; 585 return;
586 assert(getSrcSize() == 1);
626 Ostream &Str = Func->getContext()->getStrDump(); 587 Ostream &Str = Func->getContext()->getStrDump();
627 dumpOpcodePred(Str, "vmov", getDest()->getType()); 588 Variable *Dest = getDest();
589 if (auto *Dest64 = llvm::dyn_cast<Variable64On32>(Dest)) {
590 Dest64->getLo()->dump(Func);
591 Str << ", ";
592 Dest64->getHi()->dump(Func);
593 } else {
594 Dest->dump(Func);
595 }
596
597 dumpOpcodePred(Str, " = mov", getDest()->getType());
628 Str << " "; 598 Str << " ";
629 dumpDest(Func); 599
630 Str << ", "; 600 Operand *Src = getSrc(0);
631 dumpSources(Func); 601 if (auto *Src64 = llvm::dyn_cast<Variable64On32>(Src)) {
602 Src64->getLo()->dump(Func);
603 Str << ", ";
604 Src64->getHi()->dump(Func);
605 } else {
606 Src->dump(Func);
607 }
632 } 608 }
633 609
634 void InstARM32Br::emit(const Cfg *Func) const { 610 void InstARM32Br::emit(const Cfg *Func) const {
635 if (!BuildDefs::dump()) 611 if (!BuildDefs::dump())
636 return; 612 return;
637 Ostream &Str = Func->getContext()->getStrEmit(); 613 Ostream &Str = Func->getContext()->getStrEmit();
638 Str << "\t" 614 Str << "\t"
639 << "b" << getPredicate() << "\t"; 615 << "b" << getPredicate() << "\t";
640 if (Label) { 616 if (Label) {
641 Str << Label->getName(Func); 617 Str << Label->getName(Func);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 Ostream &Str = Func->getContext()->getStrDump(); 717 Ostream &Str = Func->getContext()->getStrDump();
742 Str << getName(Func) << ":"; 718 Str << getName(Func) << ":";
743 } 719 }
744 720
745 template <> void InstARM32Ldr::emit(const Cfg *Func) const { 721 template <> void InstARM32Ldr::emit(const Cfg *Func) const {
746 if (!BuildDefs::dump()) 722 if (!BuildDefs::dump())
747 return; 723 return;
748 Ostream &Str = Func->getContext()->getStrEmit(); 724 Ostream &Str = Func->getContext()->getStrEmit();
749 assert(getSrcSize() == 1); 725 assert(getSrcSize() == 1);
750 assert(getDest()->hasReg()); 726 assert(getDest()->hasReg());
751 Type Ty = getSrc(0)->getType(); 727 Variable *Dest = getDest();
752 Str << "\t" << Opcode << getWidthString(Ty) << getPredicate() << "\t"; 728 Type DestTy = Dest->getType();
729 const bool DestIsVector = isVectorType(DestTy);
730 const bool DestIsScalarFloat = isScalarFloatingType(DestTy);
731 const char *ActualOpcode =
732 DestIsVector ? "vld1" : (DestIsScalarFloat ? "vldr" : "ldr");
733 const char *VectorMarker = DestIsVector ? ".64" : "";
734 const char *WidthString = DestIsVector ? "" : getWidthString(DestTy);
735 Str << "\t" << ActualOpcode << WidthString << getPredicate() << VectorMarker
736 << "\t";
753 getDest()->emit(Func); 737 getDest()->emit(Func);
754 Str << ", "; 738 Str << ", ";
755 getSrc(0)->emit(Func); 739 getSrc(0)->emit(Func);
756 } 740 }
757 741
758 template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const { 742 template <> void InstARM32Ldr::emitIAS(const Cfg *Func) const {
759 assert(getSrcSize() == 1); 743 assert(getSrcSize() == 1);
760 (void)Func; 744 (void)Func;
761 llvm_unreachable("Not yet implemented"); 745 llvm_unreachable("Not yet implemented");
762 } 746 }
(...skipping 29 matching lines...) Expand all
792 Str << "#:upper16:"; 776 Str << "#:upper16:";
793 CR->emitWithoutPrefix(Func->getTarget()); 777 CR->emitWithoutPrefix(Func->getTarget());
794 } else { 778 } else {
795 Src1->emit(Func); 779 Src1->emit(Func);
796 } 780 }
797 } 781 }
798 782
799 void InstARM32Pop::emit(const Cfg *Func) const { 783 void InstARM32Pop::emit(const Cfg *Func) const {
800 if (!BuildDefs::dump()) 784 if (!BuildDefs::dump())
801 return; 785 return;
802 assert(Dests.size() > 0); 786 SizeT IntegerCount = 0;
787 for (const Operand *Op : Dests) {
788 if (isScalarIntegerType(Op->getType())) {
789 ++IntegerCount;
790 }
791 }
803 Ostream &Str = Func->getContext()->getStrEmit(); 792 Ostream &Str = Func->getContext()->getStrEmit();
793 if (IntegerCount == 0) {
794 Str << "\t@ empty pop";
795 return;
796 }
804 Str << "\t" 797 Str << "\t"
805 << "pop" 798 << "pop"
806 << "\t{"; 799 << "\t{";
807 for (SizeT I = 0; I < Dests.size(); ++I) { 800 bool PrintComma = false;
808 if (I > 0) 801 for (const Operand *Op : Dests) {
809 Str << ", "; 802 if (isScalarIntegerType(Op->getType())) {
810 Dests[I]->emit(Func); 803 if (PrintComma)
804 Str << ", ";
805 Op->emit(Func);
806 PrintComma = true;
807 }
811 } 808 }
812 Str << "}"; 809 Str << "}";
813 } 810 }
814 811
815 void InstARM32Pop::emitIAS(const Cfg *Func) const { 812 void InstARM32Pop::emitIAS(const Cfg *Func) const {
816 (void)Func; 813 (void)Func;
817 llvm_unreachable("Not yet implemented"); 814 llvm_unreachable("Not yet implemented");
818 } 815 }
819 816
820 void InstARM32Pop::dump(const Cfg *Func) const { 817 void InstARM32Pop::dump(const Cfg *Func) const {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 getDest()->dump(Func); 856 getDest()->dump(Func);
860 Str << " = sub.i32 "; 857 Str << " = sub.i32 ";
861 getSrc(0)->dump(Func); 858 getSrc(0)->dump(Func);
862 Str << ", " << Amount << " ; "; 859 Str << ", " << Amount << " ; ";
863 getSrc(1)->dump(Func); 860 getSrc(1)->dump(Func);
864 } 861 }
865 862
866 void InstARM32Push::emit(const Cfg *Func) const { 863 void InstARM32Push::emit(const Cfg *Func) const {
867 if (!BuildDefs::dump()) 864 if (!BuildDefs::dump())
868 return; 865 return;
869 assert(getSrcSize() > 0); 866 SizeT IntegerCount = 0;
867 for (SizeT i = 0; i < getSrcSize(); ++i) {
868 if (isScalarIntegerType(getSrc(i)->getType())) {
869 ++IntegerCount;
870 }
871 }
870 Ostream &Str = Func->getContext()->getStrEmit(); 872 Ostream &Str = Func->getContext()->getStrEmit();
873 if (IntegerCount == 0) {
874 Str << "\t"
875 << "@empty push";
876 return;
877 }
871 Str << "\t" 878 Str << "\t"
872 << "push" 879 << "push"
873 << "\t{"; 880 << "\t{";
874 emitSources(Func); 881 bool PrintComma = false;
882 for (SizeT i = 0; i < getSrcSize(); ++i) {
883 Operand *Op = getSrc(i);
884 if (isScalarIntegerType(Op->getType())) {
885 if (PrintComma)
886 Str << ", ";
887 Op->emit(Func);
888 PrintComma = true;
889 }
890 }
875 Str << "}"; 891 Str << "}";
876 } 892 }
877 893
878 void InstARM32Push::emitIAS(const Cfg *Func) const { 894 void InstARM32Push::emitIAS(const Cfg *Func) const {
879 (void)Func; 895 (void)Func;
880 llvm_unreachable("Not yet implemented"); 896 llvm_unreachable("Not yet implemented");
881 } 897 }
882 898
883 void InstARM32Push::dump(const Cfg *Func) const { 899 void InstARM32Push::dump(const Cfg *Func) const {
884 if (!BuildDefs::dump()) 900 if (!BuildDefs::dump())
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 Str << "ret." << Ty << " "; 932 Str << "ret." << Ty << " ";
917 dumpSources(Func); 933 dumpSources(Func);
918 } 934 }
919 935
920 void InstARM32Str::emit(const Cfg *Func) const { 936 void InstARM32Str::emit(const Cfg *Func) const {
921 if (!BuildDefs::dump()) 937 if (!BuildDefs::dump())
922 return; 938 return;
923 Ostream &Str = Func->getContext()->getStrEmit(); 939 Ostream &Str = Func->getContext()->getStrEmit();
924 assert(getSrcSize() == 2); 940 assert(getSrcSize() == 2);
925 Type Ty = getSrc(0)->getType(); 941 Type Ty = getSrc(0)->getType();
926 const char *Opcode = isScalarFloatingType(Ty) ? "vstr" : "str"; 942 const bool IsVectorStore = isVectorType(Ty);
927 Str << "\t" << Opcode << getWidthString(Ty) << getPredicate() << "\t"; 943 const char *Opcode =
944 IsVectorStore ? "vst1" : (isScalarFloatingType(Ty) ? "vstr" : "str");
945 const char *VecEltWidthString = IsVectorStore ? ".64" : "";
946 Str << "\t" << Opcode << getWidthString(Ty) << getPredicate()
947 << VecEltWidthString << "\t";
928 getSrc(0)->emit(Func); 948 getSrc(0)->emit(Func);
929 Str << ", "; 949 Str << ", ";
930 getSrc(1)->emit(Func); 950 getSrc(1)->emit(Func);
931 } 951 }
932 952
933 void InstARM32Str::emitIAS(const Cfg *Func) const { 953 void InstARM32Str::emitIAS(const Cfg *Func) const {
934 assert(getSrcSize() == 2); 954 assert(getSrcSize() == 2);
935 (void)Func; 955 (void)Func;
936 llvm_unreachable("Not yet implemented"); 956 llvm_unreachable("Not yet implemented");
937 } 957 }
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 } 1132 }
1113 1133
1114 void InstARM32Vmrs::dump(const Cfg *Func) const { 1134 void InstARM32Vmrs::dump(const Cfg *Func) const {
1115 if (!BuildDefs::dump()) 1135 if (!BuildDefs::dump())
1116 return; 1136 return;
1117 Ostream &Str = Func->getContext()->getStrDump(); 1137 Ostream &Str = Func->getContext()->getStrDump();
1118 Str << "APSR{n,z,v,c} = vmrs" << getPredicate() << "\t" 1138 Str << "APSR{n,z,v,c} = vmrs" << getPredicate() << "\t"
1119 "FPSCR{n,z,c,v}"; 1139 "FPSCR{n,z,c,v}";
1120 } 1140 }
1121 1141
1142 void InstARM32Vabs::emit(const Cfg *Func) const {
1143 if (!BuildDefs::dump())
1144 return;
1145 Ostream &Str = Func->getContext()->getStrEmit();
1146 assert(getSrcSize() == 1);
1147 Str << "\t"
1148 "vabs" << getPredicate() << getVecWidthString(getSrc(0)->getType())
1149 << "\t";
1150 getDest()->emit(Func);
1151 Str << ", ";
1152 getSrc(0)->emit(Func);
1153 }
1154
1155 void InstARM32Vabs::emitIAS(const Cfg *Func) const {
1156 assert(getSrcSize() == 1);
1157 (void)Func;
1158 llvm_unreachable("Not yet implemented");
1159 }
1160
1161 void InstARM32Vabs::dump(const Cfg *Func) const {
1162 if (!BuildDefs::dump())
1163 return;
1164 Ostream &Str = Func->getContext()->getStrDump();
1165 dumpDest(Func);
1166 Str << " = vabs" << getPredicate() << getVecWidthString(getSrc(0)->getType());
1167 }
1168
1122 void OperandARM32Mem::emit(const Cfg *Func) const { 1169 void OperandARM32Mem::emit(const Cfg *Func) const {
1123 if (!BuildDefs::dump()) 1170 if (!BuildDefs::dump())
1124 return; 1171 return;
1125 Ostream &Str = Func->getContext()->getStrEmit(); 1172 Ostream &Str = Func->getContext()->getStrEmit();
1126 Str << "["; 1173 Str << "[";
1127 getBase()->emit(Func); 1174 getBase()->emit(Func);
1128 switch (getAddrMode()) { 1175 switch (getAddrMode()) {
1129 case PostIndex: 1176 case PostIndex:
1130 case NegPostIndex: 1177 case NegPostIndex:
1131 Str << "], "; 1178 Str << "]";
1132 break; 1179 break;
1133 default: 1180 default:
1134 Str << ", ";
1135 break; 1181 break;
1136 } 1182 }
1137 if (isRegReg()) { 1183 if (isRegReg()) {
1184 Str << ", ";
1138 if (isNegAddrMode()) { 1185 if (isNegAddrMode()) {
1139 Str << "-"; 1186 Str << "-";
1140 } 1187 }
1141 getIndex()->emit(Func); 1188 getIndex()->emit(Func);
1142 if (getShiftOp() != kNoShift) { 1189 if (getShiftOp() != kNoShift) {
1143 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " #" 1190 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " #"
1144 << getShiftAmt(); 1191 << getShiftAmt();
1145 } 1192 }
1146 } else { 1193 } else {
1147 getOffset()->emit(Func); 1194 ConstantInteger32 *Offset = getOffset();
1195 if (Offset && Offset->getValue() != 0) {
1196 Str << ", ";
1197 Offset->emit(Func);
1198 }
1148 } 1199 }
1149 switch (getAddrMode()) { 1200 switch (getAddrMode()) {
1150 case Offset: 1201 case Offset:
1151 case NegOffset: 1202 case NegOffset:
1152 Str << "]"; 1203 Str << "]";
1153 break; 1204 break;
1154 case PreIndex: 1205 case PreIndex:
1155 case NegPreIndex: 1206 case NegPreIndex:
1156 Str << "]!"; 1207 Str << "]!";
1157 break; 1208 break;
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 if (getShiftOp() != kNoShift) { 1279 if (getShiftOp() != kNoShift) {
1229 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; 1280 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " ";
1230 if (Func) 1281 if (Func)
1231 getShiftAmt()->dump(Func); 1282 getShiftAmt()->dump(Func);
1232 else 1283 else
1233 getShiftAmt()->dump(Str); 1284 getShiftAmt()->dump(Str);
1234 } 1285 }
1235 } 1286 }
1236 1287
1237 } // end of namespace Ice 1288 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstARM32.h ('k') | src/IceInstARM32.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698