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

Side by Side Diff: src/IceInstARM32.cpp

Issue 1356763004: Subzero. ARM32 Fcmp lowering. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Adds lit tests. Created 5 years, 3 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.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 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 addSource(Src1); 375 addSource(Src1);
376 } 376 }
377 377
378 InstARM32Vcvt::InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src, 378 InstARM32Vcvt::InstARM32Vcvt(Cfg *Func, Variable *Dest, Variable *Src,
379 VcvtVariant Variant, CondARM32::Cond Predicate) 379 VcvtVariant Variant, CondARM32::Cond Predicate)
380 : InstARM32Pred(Func, InstARM32::Vcvt, 1, Dest, Predicate), 380 : InstARM32Pred(Func, InstARM32::Vcvt, 1, Dest, Predicate),
381 Variant(Variant) { 381 Variant(Variant) {
382 addSource(Src); 382 addSource(Src);
383 } 383 }
384 384
385 InstARM32Vcmp::InstARM32Vcmp(Cfg *Func, Variable *Src0, Variable *Src1,
386 CondARM32::Cond Predicate)
387 : InstARM32Pred(Func, InstARM32::Vcmp, 2, nullptr, Predicate) {
388 addSource(Src0);
389 addSource(Src1);
390 }
391
392 InstARM32Vmrs::InstARM32Vmrs(Cfg *Func, CondARM32::Cond Predicate)
393 : InstARM32Pred(Func, InstARM32::Vmrs, 0, nullptr, Predicate) {}
394
385 // ======================== Dump routines ======================== // 395 // ======================== Dump routines ======================== //
386 396
387 // Two-addr ops 397 // Two-addr ops
388 template <> const char *InstARM32Movt::Opcode = "movt"; 398 template <> const char *InstARM32Movt::Opcode = "movt";
389 // Unary ops 399 // Unary ops
390 template <> const char *InstARM32Movw::Opcode = "movw"; 400 template <> const char *InstARM32Movw::Opcode = "movw";
391 template <> const char *InstARM32Clz::Opcode = "clz"; 401 template <> const char *InstARM32Clz::Opcode = "clz";
392 template <> const char *InstARM32Mvn::Opcode = "mvn"; 402 template <> const char *InstARM32Mvn::Opcode = "mvn";
393 template <> const char *InstARM32Rbit::Opcode = "rbit"; 403 template <> const char *InstARM32Rbit::Opcode = "rbit";
394 template <> const char *InstARM32Rev::Opcode = "rev"; 404 template <> const char *InstARM32Rev::Opcode = "rev";
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 return; 510 return;
501 Ostream &Str = Func->getContext()->getStrEmit(); 511 Ostream &Str = Func->getContext()->getStrEmit();
502 Variable *Dest0 = getDest(); 512 Variable *Dest0 = getDest();
503 Operand *Src0 = getSrc(0); 513 Operand *Src0 = getSrc(0);
504 514
505 assert(Dest0->hasReg()); 515 assert(Dest0->hasReg());
506 assert(Dest1->hasReg()); 516 assert(Dest1->hasReg());
507 assert(!llvm::isa<OperandARM32Mem>(Src0)); 517 assert(!llvm::isa<OperandARM32Mem>(Src0));
508 518
509 Str << "\t" 519 Str << "\t"
510 << "vmov" 520 << "vmov" << getPredicate() << "\t";
511 << "\t";
512 Dest0->emit(Func); 521 Dest0->emit(Func);
513 Str << ", "; 522 Str << ", ";
514 Dest1->emit(Func); 523 Dest1->emit(Func);
515 Str << ", "; 524 Str << ", ";
516 Src0->emit(Func); 525 Src0->emit(Func);
517 } 526 }
518 527
519 void InstARM32Vmov::emitSingleDestMultiSource(const Cfg *Func) const { 528 void InstARM32Vmov::emitSingleDestMultiSource(const Cfg *Func) const {
520 if (!BuildDefs::dump()) 529 if (!BuildDefs::dump())
521 return; 530 return;
522 Ostream &Str = Func->getContext()->getStrEmit(); 531 Ostream &Str = Func->getContext()->getStrEmit();
523 Variable *Dest0 = getDest(); 532 Variable *Dest0 = getDest();
524 Operand *Src0 = getSrc(0); 533 Operand *Src0 = getSrc(0);
525 Operand *Src1 = getSrc(1); 534 Operand *Src1 = getSrc(1);
526 535
527 assert(Dest0->hasReg()); 536 assert(Dest0->hasReg());
528 assert(!llvm::isa<OperandARM32Mem>(Src0)); 537 assert(!llvm::isa<OperandARM32Mem>(Src0));
529 assert(!llvm::isa<OperandARM32Mem>(Src1)); 538 assert(!llvm::isa<OperandARM32Mem>(Src1));
530 539
531 Str << "\t" 540 Str << "\t"
532 << "vmov" 541 << "vmov" << getPredicate() << "\t";
533 << "\t";
534 Dest0->emit(Func); 542 Dest0->emit(Func);
535 Str << ", "; 543 Str << ", ";
536 Src0->emit(Func); 544 Src0->emit(Func);
537 Str << ", "; 545 Str << ", ";
538 Src1->emit(Func); 546 Src1->emit(Func);
539 } 547 }
540 548
541 namespace { 549 namespace {
542 bool isVariableWithoutRegister(const Operand *Op) { 550 bool isVariableWithoutRegister(const Operand *Op) {
543 if (const auto *OpV = llvm::dyn_cast<const Variable>(Op)) { 551 if (const auto *OpV = llvm::dyn_cast<const Variable>(Op)) {
544 return !OpV->hasReg(); 552 return !OpV->hasReg();
545 } 553 }
546 return false; 554 return false;
547 } 555 }
548 556
549 bool isMemoryAccess(Operand *Op) { 557 bool isMemoryAccess(Operand *Op) {
550 return isVariableWithoutRegister(Op) || llvm::isa<OperandARM32Mem>(Op); 558 return isVariableWithoutRegister(Op) || llvm::isa<OperandARM32Mem>(Op);
551 } 559 }
560
561 bool isMoveBetweenCoreAndVFPRegisters(Variable *Dest, Operand *Src) {
562 const Type DestTy = Dest->getType();
563 const Type SrcTy = Src->getType();
564 assert(isScalarIntegerType(DestTy) + isScalarIntegerType(SrcTy) <= 1 &&
Jim Stichnoth 2015/09/18 19:28:55 Adding bool types? Ick. Can you just !(A&&B) ?
John 2015/09/18 22:55:53 I prefer adding the bools, but your solution works
565 "At most one of vmov's operands can be a core register.");
566 return isScalarIntegerType(DestTy) || isScalarIntegerType(SrcTy);
567 }
552 } // end of anonymous namespace 568 } // end of anonymous namespace
553 569
554 void InstARM32Vmov::emitSingleDestSingleSource(const Cfg *Func) const { 570 void InstARM32Vmov::emitSingleDestSingleSource(const Cfg *Func) const {
555 if (!BuildDefs::dump()) 571 if (!BuildDefs::dump())
556 return; 572 return;
557 Ostream &Str = Func->getContext()->getStrEmit(); 573 Ostream &Str = Func->getContext()->getStrEmit();
558 Variable *Dest = getDest(); 574 Variable *Dest = getDest();
559 if (Dest->hasReg()) { 575 if (Dest->hasReg()) {
560 Operand *Src0 = getSrc(0); 576 Operand *Src0 = getSrc(0);
561 const char *ActualOpcode = isMemoryAccess(Src0) ? "vldr" : "vmov"; 577 const char *ActualOpcode = isMemoryAccess(Src0) ? "vldr" : "vmov";
562 Str << "\t" << ActualOpcode << "\t"; 578 // 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
580 // is disallowed because ARM.
581 const char *WidthString =
582 (isMemoryAccess(Src0) || isMoveBetweenCoreAndVFPRegisters(Dest, Src0))
583 ? ""
584 : getVecWidthString(Src0->getType());
585 Str << "\t" << ActualOpcode << getPredicate() << WidthString << "\t";
563 Dest->emit(Func); 586 Dest->emit(Func);
564 Str << ", "; 587 Str << ", ";
565 Src0->emit(Func); 588 Src0->emit(Func);
566 } else { 589 } else {
567 Variable *Src0 = llvm::cast<Variable>(getSrc(0)); 590 Variable *Src0 = llvm::cast<Variable>(getSrc(0));
568 assert(Src0->hasReg()); 591 assert(Src0->hasReg());
569 Str << "\t" 592 Str << "\t"
570 "vstr" 593 "vstr" << getPredicate() << "\t";
571 "\t";
572 Src0->emit(Func); 594 Src0->emit(Func);
573 Str << ", "; 595 Str << ", ";
574 Dest->emit(Func); 596 Dest->emit(Func);
575 } 597 }
576 } 598 }
577 599
578 void InstARM32Vmov::emit(const Cfg *Func) const { 600 void InstARM32Vmov::emit(const Cfg *Func) const {
579 if (!BuildDefs::dump()) 601 if (!BuildDefs::dump())
580 return; 602 return;
581 assert(CondARM32::AL == getPredicate());
582 assert(isMultiDest() + isMultiSource() <= 1 && "Invalid vmov type."); 603 assert(isMultiDest() + isMultiSource() <= 1 && "Invalid vmov type.");
583 if (isMultiDest()) { 604 if (isMultiDest()) {
584 emitMultiDestSingleSource(Func); 605 emitMultiDestSingleSource(Func);
585 return; 606 return;
586 } 607 }
587 608
588 if (isMultiSource()) { 609 if (isMultiSource()) {
589 emitSingleDestMultiSource(Func); 610 emitSingleDestMultiSource(Func);
590 return; 611 return;
591 } 612 }
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 void InstARM32Vcvt::dump(const Cfg *Func) const { 1059 void InstARM32Vcvt::dump(const Cfg *Func) const {
1039 if (!BuildDefs::dump()) 1060 if (!BuildDefs::dump())
1040 return; 1061 return;
1041 Ostream &Str = Func->getContext()->getStrDump(); 1062 Ostream &Str = Func->getContext()->getStrDump();
1042 dumpDest(Func); 1063 dumpDest(Func);
1043 Str << " = " 1064 Str << " = "
1044 << "vcvt" << getPredicate() << vcvtVariantSuffix(Variant) << " "; 1065 << "vcvt" << getPredicate() << vcvtVariantSuffix(Variant) << " ";
1045 dumpSources(Func); 1066 dumpSources(Func);
1046 } 1067 }
1047 1068
1069 void InstARM32Vcmp::emit(const Cfg *Func) const {
1070 if (!BuildDefs::dump())
1071 return;
1072 Ostream &Str = Func->getContext()->getStrEmit();
1073 assert(getSrcSize() == 2);
1074 Str << "\t"
1075 "vcmp" << getPredicate() << getVecWidthString(getSrc(0)->getType())
1076 << "\t";
1077 getSrc(0)->emit(Func);
1078 Str << ", ";
1079 getSrc(1)->emit(Func);
1080 }
1081
1082 void InstARM32Vcmp::emitIAS(const Cfg *Func) const {
1083 assert(getSrcSize() == 2);
1084 (void)Func;
1085 llvm_unreachable("Not yet implemented");
1086 }
1087
1088 void InstARM32Vcmp::dump(const Cfg *Func) const {
1089 if (!BuildDefs::dump())
1090 return;
1091 Ostream &Str = Func->getContext()->getStrDump();
1092 Str << "vcmp" << getPredicate() << getVecWidthString(getSrc(0)->getType());
1093 dumpSources(Func);
1094 }
1095
1096 void InstARM32Vmrs::emit(const Cfg *Func) const {
1097 if (!BuildDefs::dump())
1098 return;
1099 Ostream &Str = Func->getContext()->getStrEmit();
1100 assert(getSrcSize() == 0);
1101 Str << "\t"
1102 "vmrs" << getPredicate() << "\t"
1103 "APSR_nzcv"
1104 ", "
1105 "FPSCR";
1106 }
1107
1108 void InstARM32Vmrs::emitIAS(const Cfg *Func) const {
1109 assert(getSrcSize() == 0);
1110 (void)Func;
1111 llvm_unreachable("Not yet implemented");
1112 }
1113
1114 void InstARM32Vmrs::dump(const Cfg *Func) const {
1115 if (!BuildDefs::dump())
1116 return;
1117 Ostream &Str = Func->getContext()->getStrDump();
1118 Str << "APSR{n,z,v,c} = vmrs" << getPredicate() << "\t"
1119 "FPSCR{n,z,c,v}";
1120 }
1121
1048 void OperandARM32Mem::emit(const Cfg *Func) const { 1122 void OperandARM32Mem::emit(const Cfg *Func) const {
1049 if (!BuildDefs::dump()) 1123 if (!BuildDefs::dump())
1050 return; 1124 return;
1051 Ostream &Str = Func->getContext()->getStrEmit(); 1125 Ostream &Str = Func->getContext()->getStrEmit();
1052 Str << "["; 1126 Str << "[";
1053 getBase()->emit(Func); 1127 getBase()->emit(Func);
1054 switch (getAddrMode()) { 1128 switch (getAddrMode()) {
1055 case PostIndex: 1129 case PostIndex:
1056 case NegPostIndex: 1130 case NegPostIndex:
1057 Str << "], "; 1131 Str << "], ";
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 if (getShiftOp() != kNoShift) { 1228 if (getShiftOp() != kNoShift) {
1155 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " "; 1229 Str << ", " << InstARM32ShiftAttributes[getShiftOp()].EmitString << " ";
1156 if (Func) 1230 if (Func)
1157 getShiftAmt()->dump(Func); 1231 getShiftAmt()->dump(Func);
1158 else 1232 else
1159 getShiftAmt()->dump(Str); 1233 getShiftAmt()->dump(Str);
1160 } 1234 }
1161 } 1235 }
1162 1236
1163 } // end of namespace Ice 1237 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstARM32.h ('k') | src/IceTargetLoweringARM32.h » ('j') | src/IceTargetLoweringARM32.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698