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

Side by Side Diff: src/IceInstX8632.cpp

Issue 401523003: Lower insertelement and extractelement. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: Created 6 years, 5 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/IceInstX8632.cpp - X86-32 instruction implementation ---===// 1 //===- subzero/src/IceInstX8632.cpp - X86-32 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 // This file implements the InstX8632 and OperandX8632 classes, 10 // This file implements the InstX8632 and OperandX8632 classes,
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 template <> const char *InstX8632Divps::Opcode = "divps"; 463 template <> const char *InstX8632Divps::Opcode = "divps";
464 template <> const char *InstX8632Idiv::Opcode = "idiv"; 464 template <> const char *InstX8632Idiv::Opcode = "idiv";
465 template <> const char *InstX8632Divss::Opcode = "divss"; 465 template <> const char *InstX8632Divss::Opcode = "divss";
466 template <> const char *InstX8632Shl::Opcode = "shl"; 466 template <> const char *InstX8632Shl::Opcode = "shl";
467 template <> const char *InstX8632Psll::Opcode = "psll"; 467 template <> const char *InstX8632Psll::Opcode = "psll";
468 template <> const char *InstX8632Shr::Opcode = "shr"; 468 template <> const char *InstX8632Shr::Opcode = "shr";
469 template <> const char *InstX8632Sar::Opcode = "sar"; 469 template <> const char *InstX8632Sar::Opcode = "sar";
470 template <> const char *InstX8632Psra::Opcode = "psra"; 470 template <> const char *InstX8632Psra::Opcode = "psra";
471 template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq"; 471 template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq";
472 template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt"; 472 template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt";
473 template <> const char *InstX8632Pextrw::Opcode = "pextrw";
474 template <> const char *InstX8632Pinsrw::Opcode = "pinsrw";
475 template <> const char *InstX8632Shufps::Opcode = "shufps";
476 template <> const char *InstX8632Pshufd::Opcode = "pshufd";
477 template <> const char *InstX8632Lea::Opcode = "lea";
jvoung (off chromium) 2014/07/17 19:36:38 Cluster lea, and movd w/ the other unary ops? Cou
wala 2014/07/17 22:14:12 Done.
478 template <> const char *InstX8632Movd::Opcode = "movd";
479 template <> const char *InstX8632Movss::Opcode = "movss";
473 480
474 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { 481 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const {
475 Ostream &Str = Func->getContext()->getStrEmit(); 482 Ostream &Str = Func->getContext()->getStrEmit();
476 assert(getSrcSize() == 1); 483 assert(getSrcSize() == 1);
477 Type Ty = getSrc(0)->getType(); 484 Type Ty = getSrc(0)->getType();
478 assert(Ty == IceType_f32 || Ty == IceType_f64); 485 assert(Ty == IceType_f32 || Ty == IceType_f64);
479 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; 486 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t";
480 getDest()->emit(Func); 487 getDest()->emit(Func);
481 Str << ", "; 488 Str << ", ";
482 getSrc(0)->emit(Func); 489 getSrc(0)->emit(Func);
(...skipping 21 matching lines...) Expand all
504 emitTwoAddress(buf, this, Func); 511 emitTwoAddress(buf, this, Func);
505 } 512 }
506 513
507 template <> void InstX8632Divss::emit(const Cfg *Func) const { 514 template <> void InstX8632Divss::emit(const Cfg *Func) const {
508 char buf[30]; 515 char buf[30];
509 snprintf(buf, llvm::array_lengthof(buf), "div%s", 516 snprintf(buf, llvm::array_lengthof(buf), "div%s",
510 TypeX8632Attributes[getDest()->getType()].SdSsString); 517 TypeX8632Attributes[getDest()->getType()].SdSsString);
511 emitTwoAddress(buf, this, Func); 518 emitTwoAddress(buf, this, Func);
512 } 519 }
513 520
521 template <> void InstX8632Div::emit(const Cfg *Func) const {
522 Ostream &Str = Func->getContext()->getStrEmit();
523 assert(getSrcSize() == 3);
524 Str << "\t" << Opcode << "\t";
525 getSrc(1)->emit(Func);
526 Str << "\n";
527 }
528
529 template <> void InstX8632Idiv::emit(const Cfg *Func) const {
530 Ostream &Str = Func->getContext()->getStrEmit();
531 assert(getSrcSize() == 3);
532 Str << "\t" << Opcode << "\t";
533 getSrc(1)->emit(Func);
534 Str << "\n";
535 }
536
514 template <> void InstX8632Imul::emit(const Cfg *Func) const { 537 template <> void InstX8632Imul::emit(const Cfg *Func) const {
515 Ostream &Str = Func->getContext()->getStrEmit(); 538 Ostream &Str = Func->getContext()->getStrEmit();
516 assert(getSrcSize() == 2); 539 assert(getSrcSize() == 2);
517 if (getDest()->getType() == IceType_i8) { 540 if (getDest()->getType() == IceType_i8) {
518 // The 8-bit version of imul only allows the form "imul r/m8". 541 // The 8-bit version of imul only allows the form "imul r/m8".
519 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); 542 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0));
520 assert(Src0 && Src0->getRegNum() == TargetX8632::Reg_eax); 543 assert(Src0 && Src0->getRegNum() == TargetX8632::Reg_eax);
521 Str << "\timul\t"; 544 Str << "\timul\t";
522 getSrc(1)->emit(Func); 545 getSrc(1)->emit(Func);
523 Str << "\n"; 546 Str << "\n";
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 } 839 }
817 840
818 void InstX8632StoreQ::dump(const Cfg *Func) const { 841 void InstX8632StoreQ::dump(const Cfg *Func) const {
819 Ostream &Str = Func->getContext()->getStrDump(); 842 Ostream &Str = Func->getContext()->getStrDump();
820 Str << "storeq." << getSrc(0)->getType() << " "; 843 Str << "storeq." << getSrc(0)->getType() << " ";
821 getSrc(1)->dump(Func); 844 getSrc(1)->dump(Func);
822 Str << ", "; 845 Str << ", ";
823 getSrc(0)->dump(Func); 846 getSrc(0)->dump(Func);
824 } 847 }
825 848
849 template <> void InstX8632Lea::emit(const Cfg *Func) const {
850 Ostream &Str = Func->getContext()->getStrEmit();
851 assert(getSrcSize() == 1);
852 assert(getDest()->hasReg());
853 Str << "\tlea\t";
854 getDest()->emit(Func);
855 Str << ", ";
856 Operand *Src0 = getSrc(0);
857 if (Variable *VSrc0 = llvm::dyn_cast<Variable>(Src0)) {
858 Type Ty = VSrc0->getType();
859 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
860 // acceptable type.
861 VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func);
862 } else {
863 Src0->emit(Func);
864 }
865 Str << "\n";
866 }
867
826 void InstX8632Mov::emit(const Cfg *Func) const { 868 void InstX8632Mov::emit(const Cfg *Func) const {
827 Ostream &Str = Func->getContext()->getStrEmit(); 869 Ostream &Str = Func->getContext()->getStrEmit();
828 assert(getSrcSize() == 1); 870 assert(getSrcSize() == 1);
829 Operand *Src = getSrc(0); 871 Operand *Src = getSrc(0);
830 // The llvm-mc assembler using Intel syntax has a bug in which "mov 872 // The llvm-mc assembler using Intel syntax has a bug in which "mov
831 // reg, RelocatableConstant" does not generate the right instruction 873 // reg, RelocatableConstant" does not generate the right instruction
832 // with a relocation. To work around, we emit "lea reg, 874 // with a relocation. To work around, we emit "lea reg,
833 // [RelocatableConstant]". Also, the lowering and legalization is 875 // [RelocatableConstant]". Also, the lowering and legalization is
834 // changed to allow relocatable constants only in Assign and Call 876 // changed to allow relocatable constants only in Assign and Call
835 // instructions or in Mem operands. TODO(stichnot): remove LEAHACK 877 // instructions or in Mem operands. TODO(stichnot): remove LEAHACK
836 // once a proper emitter is used. 878 // once a proper emitter is used.
837 bool UseLeaHack = llvm::isa<ConstantRelocatable>(Src); 879 bool UseLeaHack = llvm::isa<ConstantRelocatable>(Src);
838 Str << "\t"; 880 Str << "\t";
839 if (UseLeaHack) 881 if (UseLeaHack)
840 Str << "lea"; 882 Str << "lea";
841 else 883 else
842 Str << "mov" << TypeX8632Attributes[getDest()->getType()].SdSsString; 884 Str << "mov" << TypeX8632Attributes[getDest()->getType()].SdSsString;
jvoung (off chromium) 2014/07/17 19:36:38 This regular mov will overlap a bit w/ the added m
wala 2014/07/17 22:14:12 I need to copy a single floating point value out o
Jim Stichnoth 2014/07/18 17:21:01 OK. This is something that will need to be cleane
wala 2014/07/18 19:36:13 Done.
843 Str << "\t"; 885 Str << "\t";
844 // For an integer truncation operation, src is wider than dest. 886 // For an integer truncation operation, src is wider than dest.
845 // Ideally, we use a mov instruction whose data width matches the 887 // Ideally, we use a mov instruction whose data width matches the
846 // narrower dest. This is a problem if e.g. src is a register like 888 // narrower dest. This is a problem if e.g. src is a register like
847 // esi or si where there is no 8-bit version of the register. To be 889 // esi or si where there is no 8-bit version of the register. To be
848 // safe, we instead widen the dest to match src. This works even 890 // safe, we instead widen the dest to match src. This works even
849 // for stack-allocated dest variables because typeWidthOnStack() 891 // for stack-allocated dest variables because typeWidthOnStack()
850 // pads to a 4-byte boundary even if only a lower portion is used. 892 // pads to a 4-byte boundary even if only a lower portion is used.
851 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == 893 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) ==
852 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); 894 Func->getTarget()->typeWidthInBytesOnStack(Src->getType()));
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 emitTwoAddress(buf, this, Func); 1056 emitTwoAddress(buf, this, Func);
1015 } 1057 }
1016 1058
1017 template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const { 1059 template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const {
1018 char buf[30]; 1060 char buf[30];
1019 snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s", 1061 snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s",
1020 TypeX8632Attributes[getDest()->getType()].PackString); 1062 TypeX8632Attributes[getDest()->getType()].PackString);
1021 emitTwoAddress(buf, this, Func); 1063 emitTwoAddress(buf, this, Func);
1022 } 1064 }
1023 1065
1066 template <> void InstX8632Pextrw::emit(const Cfg *Func) const {
1067 Ostream &Str = Func->getContext()->getStrEmit();
1068 assert(getSrcSize() == 2);
1069 Str << "\t" << Opcode << "\t";
1070 Variable *Dest = getDest();
1071 assert(Dest->hasReg() && Dest->getType() == IceType_i16);
1072 // pextrw takes r32 dest.
1073 Dest->asType(IceType_i32).emit(Func);
1074 Str << ", ";
1075 getSrc(0)->emit(Func);
1076 Str << ", ";
1077 getSrc(1)->emit(Func);
1078 Str << "\n";
1079 }
1080
1081 template <> void InstX8632Pinsrw::emit(const Cfg *Func) const {
1082 Ostream &Str = Func->getContext()->getStrEmit();
1083 assert(getSrcSize() == 3);
1084 Str << "\t" << Opcode << "\t";
1085 getDest()->emit(Func);
1086 Str << ", ";
1087 Operand *Src1 = getSrc(1);
1088 if (Variable *VSrc1 = llvm::dyn_cast<Variable>(Src1)) {
1089 // If src1 is a register, it should be r32.
1090 VSrc1->asType(VSrc1->hasReg() ? IceType_i32 : IceType_i16).emit(Func);
1091 } else {
1092 Src1->emit(Func);
1093 }
1094 Str << ", ";
1095 getSrc(2)->emit(Func);
1096 Str << "\n";
1097 }
1098
1024 void InstX8632Pop::emit(const Cfg *Func) const { 1099 void InstX8632Pop::emit(const Cfg *Func) const {
1025 Ostream &Str = Func->getContext()->getStrEmit(); 1100 Ostream &Str = Func->getContext()->getStrEmit();
1026 assert(getSrcSize() == 0); 1101 assert(getSrcSize() == 0);
1027 Str << "\tpop\t"; 1102 Str << "\tpop\t";
1028 getDest()->emit(Func); 1103 getDest()->emit(Func);
1029 Str << "\n"; 1104 Str << "\n";
1030 } 1105 }
1031 1106
1032 void InstX8632Pop::dump(const Cfg *Func) const { 1107 void InstX8632Pop::dump(const Cfg *Func) const {
1033 Ostream &Str = Func->getContext()->getStrDump(); 1108 Ostream &Str = Func->getContext()->getStrDump();
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 default: 1351 default:
1277 Str << "???"; 1352 Str << "???";
1278 break; 1353 break;
1279 } 1354 }
1280 Str << "("; 1355 Str << "(";
1281 Var->dump(Func); 1356 Var->dump(Func);
1282 Str << ")"; 1357 Str << ")";
1283 } 1358 }
1284 1359
1285 } // end of namespace Ice 1360 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698