OLD | NEW |
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 21 matching lines...) Expand all Loading... |
32 , | 32 , |
33 ICEINSTX8632BR_TABLE | 33 ICEINSTX8632BR_TABLE |
34 #undef X | 34 #undef X |
35 }; | 35 }; |
36 const size_t InstX8632BrAttributesSize = | 36 const size_t InstX8632BrAttributesSize = |
37 llvm::array_lengthof(InstX8632BrAttributes); | 37 llvm::array_lengthof(InstX8632BrAttributes); |
38 | 38 |
39 const struct TypeX8632Attributes_ { | 39 const struct TypeX8632Attributes_ { |
40 const char *CvtString; // i (integer), s (single FP), d (double FP) | 40 const char *CvtString; // i (integer), s (single FP), d (double FP) |
41 const char *SdSsString; // ss, sd, or <blank> | 41 const char *SdSsString; // ss, sd, or <blank> |
| 42 const char *PackString; // b, w, d, or <blank> |
42 const char *WidthString; // {byte,word,dword,qword} ptr | 43 const char *WidthString; // {byte,word,dword,qword} ptr |
43 } TypeX8632Attributes[] = { | 44 } TypeX8632Attributes[] = { |
44 #define X(tag, cvt, sdss, width) \ | 45 #define X(tag, cvt, sdss, pack, width) \ |
45 { cvt, "" sdss, width } \ | 46 { cvt, "" sdss, pack, width } \ |
46 , | 47 , |
47 ICETYPEX8632_TABLE | 48 ICETYPEX8632_TABLE |
48 #undef X | 49 #undef X |
49 }; | 50 }; |
50 const size_t TypeX8632AttributesSize = | 51 const size_t TypeX8632AttributesSize = |
51 llvm::array_lengthof(TypeX8632Attributes); | 52 llvm::array_lengthof(TypeX8632Attributes); |
52 | 53 |
53 const char *InstX8632SegmentRegNames[] = { | 54 const char *InstX8632SegmentRegNames[] = { |
54 #define X(val, name) name, | 55 #define X(val, name) name, |
55 SEG_REGX8632_TABLE | 56 SEG_REGX8632_TABLE |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 return false; | 291 return false; |
291 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { | 292 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { |
292 return true; | 293 return true; |
293 } | 294 } |
294 if (!getDest()->hasReg() && !Src->hasReg() && | 295 if (!getDest()->hasReg() && !Src->hasReg() && |
295 Dest->getStackOffset() == Src->getStackOffset()) | 296 Dest->getStackOffset() == Src->getStackOffset()) |
296 return true; | 297 return true; |
297 return false; | 298 return false; |
298 } | 299 } |
299 | 300 |
| 301 InstX8632Pshufd::InstX8632Pshufd(Cfg *Func, Variable *Dest, Operand *Source1, |
| 302 Operand *Source2) |
| 303 : InstX8632(Func, InstX8632::Pshufd, 2, Dest) { |
| 304 addSource(Source1); |
| 305 addSource(Source2); |
| 306 } |
| 307 |
| 308 InstX8632Shufps::InstX8632Shufps(Cfg *Func, Variable *Dest, Operand *Source1, |
| 309 Operand *Source2) |
| 310 : InstX8632(Func, InstX8632::Shufps, 3, Dest) { |
| 311 addSource(Dest); |
| 312 addSource(Source1); |
| 313 addSource(Source2); |
| 314 } |
| 315 |
300 InstX8632Sqrtss::InstX8632Sqrtss(Cfg *Func, Variable *Dest, Operand *Source) | 316 InstX8632Sqrtss::InstX8632Sqrtss(Cfg *Func, Variable *Dest, Operand *Source) |
301 : InstX8632(Func, InstX8632::Sqrtss, 1, Dest) { | 317 : InstX8632(Func, InstX8632::Sqrtss, 1, Dest) { |
302 addSource(Source); | 318 addSource(Source); |
303 } | 319 } |
304 | 320 |
305 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) | 321 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) |
306 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) { | 322 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) { |
307 if (Source) | 323 if (Source) |
308 addSource(Source); | 324 addSource(Source); |
309 } | 325 } |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 if (!EmittedSrc1) | 443 if (!EmittedSrc1) |
428 Inst->getSrc(1)->emit(Func); | 444 Inst->getSrc(1)->emit(Func); |
429 Str << "\n"; | 445 Str << "\n"; |
430 } | 446 } |
431 | 447 |
432 template <> const char *InstX8632Neg::Opcode = "neg"; | 448 template <> const char *InstX8632Neg::Opcode = "neg"; |
433 template <> const char *InstX8632Add::Opcode = "add"; | 449 template <> const char *InstX8632Add::Opcode = "add"; |
434 template <> const char *InstX8632Addps::Opcode = "addps"; | 450 template <> const char *InstX8632Addps::Opcode = "addps"; |
435 template <> const char *InstX8632Adc::Opcode = "adc"; | 451 template <> const char *InstX8632Adc::Opcode = "adc"; |
436 template <> const char *InstX8632Addss::Opcode = "addss"; | 452 template <> const char *InstX8632Addss::Opcode = "addss"; |
| 453 template <> const char *InstX8632Padd::Opcode = "padd"; |
437 template <> const char *InstX8632Sub::Opcode = "sub"; | 454 template <> const char *InstX8632Sub::Opcode = "sub"; |
438 template <> const char *InstX8632Subps::Opcode = "subps"; | 455 template <> const char *InstX8632Subps::Opcode = "subps"; |
439 template <> const char *InstX8632Subss::Opcode = "subss"; | 456 template <> const char *InstX8632Subss::Opcode = "subss"; |
440 template <> const char *InstX8632Sbb::Opcode = "sbb"; | 457 template <> const char *InstX8632Sbb::Opcode = "sbb"; |
| 458 template <> const char *InstX8632Psub::Opcode = "psub"; |
441 template <> const char *InstX8632And::Opcode = "and"; | 459 template <> const char *InstX8632And::Opcode = "and"; |
| 460 template <> const char *InstX8632Pand::Opcode = "pand"; |
442 template <> const char *InstX8632Or::Opcode = "or"; | 461 template <> const char *InstX8632Or::Opcode = "or"; |
| 462 template <> const char *InstX8632Por::Opcode = "por"; |
443 template <> const char *InstX8632Xor::Opcode = "xor"; | 463 template <> const char *InstX8632Xor::Opcode = "xor"; |
444 template <> const char *InstX8632Pxor::Opcode = "pxor"; | 464 template <> const char *InstX8632Pxor::Opcode = "pxor"; |
445 template <> const char *InstX8632Imul::Opcode = "imul"; | 465 template <> const char *InstX8632Imul::Opcode = "imul"; |
446 template <> const char *InstX8632Mulps::Opcode = "mulps"; | 466 template <> const char *InstX8632Mulps::Opcode = "mulps"; |
447 template <> const char *InstX8632Mulss::Opcode = "mulss"; | 467 template <> const char *InstX8632Mulss::Opcode = "mulss"; |
| 468 template <> const char *InstX8632Pmullw::Opcode = "pmullw"; |
| 469 template <> const char *InstX8632Pmuludq::Opcode = "pmuludq"; |
448 template <> const char *InstX8632Div::Opcode = "div"; | 470 template <> const char *InstX8632Div::Opcode = "div"; |
449 template <> const char *InstX8632Divps::Opcode = "divps"; | 471 template <> const char *InstX8632Divps::Opcode = "divps"; |
450 template <> const char *InstX8632Idiv::Opcode = "idiv"; | 472 template <> const char *InstX8632Idiv::Opcode = "idiv"; |
451 template <> const char *InstX8632Divss::Opcode = "divss"; | 473 template <> const char *InstX8632Divss::Opcode = "divss"; |
452 template <> const char *InstX8632Shl::Opcode = "shl"; | 474 template <> const char *InstX8632Shl::Opcode = "shl"; |
453 template <> const char *InstX8632Shr::Opcode = "shr"; | 475 template <> const char *InstX8632Shr::Opcode = "shr"; |
454 template <> const char *InstX8632Sar::Opcode = "sar"; | 476 template <> const char *InstX8632Sar::Opcode = "sar"; |
455 | 477 |
456 template <> void InstX8632Addss::emit(const Cfg *Func) const { | 478 template <> void InstX8632Addss::emit(const Cfg *Func) const { |
457 char buf[30]; | 479 char buf[30]; |
458 snprintf(buf, llvm::array_lengthof(buf), "add%s", | 480 snprintf(buf, llvm::array_lengthof(buf), "add%s", |
459 TypeX8632Attributes[getDest()->getType()].SdSsString); | 481 TypeX8632Attributes[getDest()->getType()].SdSsString); |
460 emitTwoAddress(buf, this, Func); | 482 emitTwoAddress(buf, this, Func); |
461 } | 483 } |
462 | 484 |
| 485 template <> void InstX8632Padd::emit(const Cfg *Func) const { |
| 486 char buf[30]; |
| 487 snprintf(buf, llvm::array_lengthof(buf), "padd%s", |
| 488 TypeX8632Attributes[getDest()->getType()].PackString); |
| 489 emitTwoAddress(buf, this, Func); |
| 490 } |
| 491 |
463 template <> void InstX8632Subss::emit(const Cfg *Func) const { | 492 template <> void InstX8632Subss::emit(const Cfg *Func) const { |
464 char buf[30]; | 493 char buf[30]; |
465 snprintf(buf, llvm::array_lengthof(buf), "sub%s", | 494 snprintf(buf, llvm::array_lengthof(buf), "sub%s", |
466 TypeX8632Attributes[getDest()->getType()].SdSsString); | 495 TypeX8632Attributes[getDest()->getType()].SdSsString); |
467 emitTwoAddress(buf, this, Func); | 496 emitTwoAddress(buf, this, Func); |
468 } | 497 } |
469 | 498 |
| 499 template <> void InstX8632Psub::emit(const Cfg *Func) const { |
| 500 char buf[30]; |
| 501 snprintf(buf, llvm::array_lengthof(buf), "psub%s", |
| 502 TypeX8632Attributes[getDest()->getType()].PackString); |
| 503 emitTwoAddress(buf, this, Func); |
| 504 } |
| 505 |
470 template <> void InstX8632Mulss::emit(const Cfg *Func) const { | 506 template <> void InstX8632Mulss::emit(const Cfg *Func) const { |
471 char buf[30]; | 507 char buf[30]; |
472 snprintf(buf, llvm::array_lengthof(buf), "mul%s", | 508 snprintf(buf, llvm::array_lengthof(buf), "mul%s", |
473 TypeX8632Attributes[getDest()->getType()].SdSsString); | 509 TypeX8632Attributes[getDest()->getType()].SdSsString); |
474 emitTwoAddress(buf, this, Func); | 510 emitTwoAddress(buf, this, Func); |
475 } | 511 } |
476 | 512 |
| 513 template <> void InstX8632Pmullw::emit(const Cfg *Func) const { |
| 514 assert(getSrc(0)->getType() == IceType_v8i16 && |
| 515 getSrc(1)->getType() == IceType_v8i16); |
| 516 emitTwoAddress(Opcode, this, Func); |
| 517 } |
| 518 |
| 519 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const { |
| 520 assert(getSrc(0)->getType() == IceType_v4i32 && |
| 521 getSrc(1)->getType() == IceType_v4i32); |
| 522 emitTwoAddress(Opcode, this, Func); |
| 523 } |
| 524 |
477 template <> void InstX8632Divss::emit(const Cfg *Func) const { | 525 template <> void InstX8632Divss::emit(const Cfg *Func) const { |
478 char buf[30]; | 526 char buf[30]; |
479 snprintf(buf, llvm::array_lengthof(buf), "div%s", | 527 snprintf(buf, llvm::array_lengthof(buf), "div%s", |
480 TypeX8632Attributes[getDest()->getType()].SdSsString); | 528 TypeX8632Attributes[getDest()->getType()].SdSsString); |
481 emitTwoAddress(buf, this, Func); | 529 emitTwoAddress(buf, this, Func); |
482 } | 530 } |
483 | 531 |
484 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 532 template <> void InstX8632Imul::emit(const Cfg *Func) const { |
485 Ostream &Str = Func->getContext()->getStrEmit(); | 533 Ostream &Str = Func->getContext()->getStrEmit(); |
486 assert(getSrcSize() == 2); | 534 assert(getSrcSize() == 2); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 if (Locked) { | 672 if (Locked) { |
625 Str << "lock "; | 673 Str << "lock "; |
626 } | 674 } |
627 Str << "cmpxchg8b "; | 675 Str << "cmpxchg8b "; |
628 dumpSources(Func); | 676 dumpSources(Func); |
629 } | 677 } |
630 | 678 |
631 void InstX8632Cvt::emit(const Cfg *Func) const { | 679 void InstX8632Cvt::emit(const Cfg *Func) const { |
632 Ostream &Str = Func->getContext()->getStrEmit(); | 680 Ostream &Str = Func->getContext()->getStrEmit(); |
633 assert(getSrcSize() == 1); | 681 assert(getSrcSize() == 1); |
634 Str << "\tcvts" << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2s" | 682 Str << "\tcvt" << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" |
635 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; | 683 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; |
636 getDest()->emit(Func); | 684 getDest()->emit(Func); |
637 Str << ", "; | 685 Str << ", "; |
638 getSrc(0)->emit(Func); | 686 getSrc(0)->emit(Func); |
639 Str << "\n"; | 687 Str << "\n"; |
640 } | 688 } |
641 | 689 |
642 void InstX8632Cvt::dump(const Cfg *Func) const { | 690 void InstX8632Cvt::dump(const Cfg *Func) const { |
643 Ostream &Str = Func->getContext()->getStrDump(); | 691 Ostream &Str = Func->getContext()->getStrDump(); |
644 dumpDest(Func); | 692 dumpDest(Func); |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
988 Func->getTarget()->updateStackAdjustment(4); | 1036 Func->getTarget()->updateStackAdjustment(4); |
989 } | 1037 } |
990 } | 1038 } |
991 | 1039 |
992 void InstX8632Push::dump(const Cfg *Func) const { | 1040 void InstX8632Push::dump(const Cfg *Func) const { |
993 Ostream &Str = Func->getContext()->getStrDump(); | 1041 Ostream &Str = Func->getContext()->getStrDump(); |
994 Str << "push." << getSrc(0)->getType() << " "; | 1042 Str << "push." << getSrc(0)->getType() << " "; |
995 dumpSources(Func); | 1043 dumpSources(Func); |
996 } | 1044 } |
997 | 1045 |
| 1046 void InstX8632Pshufd::emit(const Cfg *Func) const { |
| 1047 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1048 assert(getSrcSize() == 2); |
| 1049 Str << "\tpshufd\t"; |
| 1050 getDest()->emit(Func); |
| 1051 Str << ", "; |
| 1052 getSrc(0)->emit(Func); |
| 1053 Str << ", "; |
| 1054 getSrc(1)->emit(Func); |
| 1055 Str << "\n"; |
| 1056 } |
| 1057 |
| 1058 void InstX8632Pshufd::dump(const Cfg *Func) const { |
| 1059 Ostream &Str = Func->getContext()->getStrDump(); |
| 1060 dumpDest(Func); |
| 1061 Str << " = pshufd." << getDest()->getType() << " "; |
| 1062 dumpSources(Func); |
| 1063 } |
| 1064 |
998 void InstX8632Ret::emit(const Cfg *Func) const { | 1065 void InstX8632Ret::emit(const Cfg *Func) const { |
999 Ostream &Str = Func->getContext()->getStrEmit(); | 1066 Ostream &Str = Func->getContext()->getStrEmit(); |
1000 Str << "\tret\n"; | 1067 Str << "\tret\n"; |
1001 } | 1068 } |
1002 | 1069 |
1003 void InstX8632Ret::dump(const Cfg *Func) const { | 1070 void InstX8632Ret::dump(const Cfg *Func) const { |
1004 Ostream &Str = Func->getContext()->getStrDump(); | 1071 Ostream &Str = Func->getContext()->getStrDump(); |
1005 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 1072 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
1006 Str << "ret." << Ty << " "; | 1073 Str << "ret." << Ty << " "; |
1007 dumpSources(Func); | 1074 dumpSources(Func); |
1008 } | 1075 } |
1009 | 1076 |
| 1077 void InstX8632Shufps::emit(const Cfg *Func) const { |
| 1078 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1079 assert(getSrcSize() == 3); |
| 1080 Str << "\tshufps\t"; |
| 1081 getDest()->emit(Func); |
| 1082 Str << ", "; |
| 1083 getSrc(1)->emit(Func); |
| 1084 Str << ", "; |
| 1085 getSrc(2)->emit(Func); |
| 1086 Str << "\n"; |
| 1087 } |
| 1088 |
| 1089 void InstX8632Shufps::dump(const Cfg *Func) const { |
| 1090 Ostream &Str = Func->getContext()->getStrDump(); |
| 1091 dumpDest(Func); |
| 1092 Str << " = shufps." << getDest()->getType() << " "; |
| 1093 dumpSources(Func); |
| 1094 } |
| 1095 |
1010 void InstX8632Sqrtss::emit(const Cfg *Func) const { | 1096 void InstX8632Sqrtss::emit(const Cfg *Func) const { |
1011 Ostream &Str = Func->getContext()->getStrEmit(); | 1097 Ostream &Str = Func->getContext()->getStrEmit(); |
1012 assert(getSrcSize() == 1); | 1098 assert(getSrcSize() == 1); |
1013 Type Ty = getSrc(0)->getType(); | 1099 Type Ty = getSrc(0)->getType(); |
1014 assert(Ty == IceType_f32 || Ty == IceType_f64); | 1100 assert(Ty == IceType_f32 || Ty == IceType_f64); |
1015 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 1101 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; |
1016 getDest()->emit(Func); | 1102 getDest()->emit(Func); |
1017 Str << ", "; | 1103 Str << ", "; |
1018 getSrc(0)->emit(Func); | 1104 getSrc(0)->emit(Func); |
1019 Str << "\n"; | 1105 Str << "\n"; |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1190 default: | 1276 default: |
1191 Str << "???"; | 1277 Str << "???"; |
1192 break; | 1278 break; |
1193 } | 1279 } |
1194 Str << "("; | 1280 Str << "("; |
1195 Var->dump(Func); | 1281 Var->dump(Func); |
1196 Str << ")"; | 1282 Str << ")"; |
1197 } | 1283 } |
1198 | 1284 |
1199 } // end of namespace Ice | 1285 } // end of namespace Ice |
OLD | NEW |