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

Side by Side Diff: src/IceInstX8632.cpp

Issue 686913005: Turn off dump/emit routines when building minimal subzero. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 6 years, 1 month 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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 336
337 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) 337 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source)
338 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { 338 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) {
339 addSource(Dest); 339 addSource(Dest);
340 addSource(Source); 340 addSource(Source);
341 } 341 }
342 342
343 // ======================== Dump routines ======================== // 343 // ======================== Dump routines ======================== //
344 344
345 void InstX8632::dump(const Cfg *Func) const { 345 void InstX8632::dump(const Cfg *Func) const {
346 if (!ALLOW_DUMP)
347 return;
346 Ostream &Str = Func->getContext()->getStrDump(); 348 Ostream &Str = Func->getContext()->getStrDump();
347 Str << "[X8632] "; 349 Str << "[X8632] ";
348 Inst::dump(Func); 350 Inst::dump(Func);
349 } 351 }
350 352
351 void InstX8632Label::emit(const Cfg *Func) const { 353 void InstX8632Label::emit(const Cfg *Func) const {
354 if (!ALLOW_DUMP)
355 return;
352 Ostream &Str = Func->getContext()->getStrEmit(); 356 Ostream &Str = Func->getContext()->getStrEmit();
353 Str << getName(Func) << ":"; 357 Str << getName(Func) << ":";
354 } 358 }
355 359
356 void InstX8632Label::emitIAS(const Cfg *Func) const { 360 void InstX8632Label::emitIAS(const Cfg *Func) const {
357 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 361 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
358 Asm->BindLocalLabel(Number); 362 Asm->BindLocalLabel(Number);
359 } 363 }
360 364
361 void InstX8632Label::dump(const Cfg *Func) const { 365 void InstX8632Label::dump(const Cfg *Func) const {
366 if (!ALLOW_DUMP)
367 return;
362 Ostream &Str = Func->getContext()->getStrDump(); 368 Ostream &Str = Func->getContext()->getStrDump();
363 Str << getName(Func) << ":"; 369 Str << getName(Func) << ":";
364 } 370 }
365 371
366 void InstX8632Br::emit(const Cfg *Func) const { 372 void InstX8632Br::emit(const Cfg *Func) const {
373 if (!ALLOW_DUMP)
374 return;
367 Ostream &Str = Func->getContext()->getStrEmit(); 375 Ostream &Str = Func->getContext()->getStrEmit();
368 Str << "\t"; 376 Str << "\t";
369 377
370 if (Condition == CondX86::Br_None) { 378 if (Condition == CondX86::Br_None) {
371 Str << "jmp"; 379 Str << "jmp";
372 } else { 380 } else {
373 Str << InstX8632BrAttributes[Condition].EmitString; 381 Str << InstX8632BrAttributes[Condition].EmitString;
374 } 382 }
375 383
376 if (Label) { 384 if (Label) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 if (getTargetFalse()) { 421 if (getTargetFalse()) {
414 x86::Label *L2 = 422 x86::Label *L2 =
415 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); 423 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
416 Asm->jmp(L2, Near); 424 Asm->jmp(L2, Near);
417 } 425 }
418 } 426 }
419 } 427 }
420 } 428 }
421 429
422 void InstX8632Br::dump(const Cfg *Func) const { 430 void InstX8632Br::dump(const Cfg *Func) const {
431 if (!ALLOW_DUMP)
432 return;
423 Ostream &Str = Func->getContext()->getStrDump(); 433 Ostream &Str = Func->getContext()->getStrDump();
424 Str << "br "; 434 Str << "br ";
425 435
426 if (Condition == CondX86::Br_None) { 436 if (Condition == CondX86::Br_None) {
427 Str << "label %" 437 Str << "label %"
428 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); 438 << (Label ? Label->getName(Func) : getTargetFalse()->getName());
429 return; 439 return;
430 } 440 }
431 441
432 Str << InstX8632BrAttributes[Condition].DisplayString; 442 Str << InstX8632BrAttributes[Condition].DisplayString;
433 if (Label) { 443 if (Label) {
434 Str << ", label %" << Label->getName(Func); 444 Str << ", label %" << Label->getName(Func);
435 } else { 445 } else {
436 Str << ", label %" << getTargetTrue()->getName(); 446 Str << ", label %" << getTargetTrue()->getName();
437 if (getTargetFalse()) { 447 if (getTargetFalse()) {
438 Str << ", label %" << getTargetFalse()->getName(); 448 Str << ", label %" << getTargetFalse()->getName();
439 } 449 }
440 } 450 }
441 } 451 }
442 452
443 void InstX8632Call::emit(const Cfg *Func) const { 453 void InstX8632Call::emit(const Cfg *Func) const {
454 if (!ALLOW_DUMP)
455 return;
444 Ostream &Str = Func->getContext()->getStrEmit(); 456 Ostream &Str = Func->getContext()->getStrEmit();
445 assert(getSrcSize() == 1); 457 assert(getSrcSize() == 1);
446 Str << "\tcall\t"; 458 Str << "\tcall\t";
447 if (const auto CallTarget = 459 if (const auto CallTarget =
448 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { 460 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) {
449 // TODO(stichnot): All constant targets should suppress the '$', 461 // TODO(stichnot): All constant targets should suppress the '$',
450 // not just relocatables. 462 // not just relocatables.
451 CallTarget->emitWithoutDollar(Func->getContext()); 463 CallTarget->emitWithoutDollar(Func->getContext());
452 } else { 464 } else {
453 Str << "*"; 465 Str << "*";
(...skipping 28 matching lines...) Expand all
482 // TODO(jvoung): Do we need to support this? 494 // TODO(jvoung): Do we need to support this?
483 (void)Imm; 495 (void)Imm;
484 llvm_unreachable("Unexpected call to absolute address"); 496 llvm_unreachable("Unexpected call to absolute address");
485 } else { 497 } else {
486 llvm_unreachable("Unexpected operand type"); 498 llvm_unreachable("Unexpected operand type");
487 } 499 }
488 Func->getTarget()->resetStackAdjustment(); 500 Func->getTarget()->resetStackAdjustment();
489 } 501 }
490 502
491 void InstX8632Call::dump(const Cfg *Func) const { 503 void InstX8632Call::dump(const Cfg *Func) const {
504 if (!ALLOW_DUMP)
505 return;
492 Ostream &Str = Func->getContext()->getStrDump(); 506 Ostream &Str = Func->getContext()->getStrDump();
493 if (getDest()) { 507 if (getDest()) {
494 dumpDest(Func); 508 dumpDest(Func);
495 Str << " = "; 509 Str << " = ";
496 } 510 }
497 Str << "call "; 511 Str << "call ";
498 getCallTarget()->dump(Func); 512 getCallTarget()->dump(Func);
499 } 513 }
500 514
501 // The ShiftHack parameter is used to emit "cl" instead of "ecx" for 515 // The ShiftHack parameter is used to emit "cl" instead of "ecx" for
502 // shift instructions, in order to be syntactically valid. The 516 // shift instructions, in order to be syntactically valid. The
503 // Opcode parameter needs to be char* and not IceString because of 517 // Opcode parameter needs to be char* and not IceString because of
504 // template issues. 518 // template issues.
505 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, 519 void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
506 bool ShiftHack) { 520 bool ShiftHack) {
521 if (!ALLOW_DUMP)
522 return;
507 Ostream &Str = Func->getContext()->getStrEmit(); 523 Ostream &Str = Func->getContext()->getStrEmit();
508 assert(Inst->getSrcSize() == 2); 524 assert(Inst->getSrcSize() == 2);
509 Variable *Dest = Inst->getDest(); 525 Variable *Dest = Inst->getDest();
510 assert(Dest == Inst->getSrc(0)); 526 assert(Dest == Inst->getSrc(0));
511 Operand *Src1 = Inst->getSrc(1); 527 Operand *Src1 = Inst->getSrc(1);
512 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t"; 528 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t";
513 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); 529 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1);
514 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx) 530 if (ShiftHack && ShiftReg && ShiftReg->getRegNum() == RegX8632::Reg_ecx)
515 Str << "%cl"; 531 Str << "%cl";
516 else 532 else
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 template <> 1045 template <>
1030 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = { 1046 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psll::Emitter = {
1031 &x86::AssemblerX86::psll, &x86::AssemblerX86::psll, 1047 &x86::AssemblerX86::psll, &x86::AssemblerX86::psll,
1032 &x86::AssemblerX86::psll}; 1048 &x86::AssemblerX86::psll};
1033 template <> 1049 template <>
1034 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = { 1050 const x86::AssemblerX86::XmmEmitterShiftOp InstX8632Psra::Emitter = {
1035 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra, 1051 &x86::AssemblerX86::psra, &x86::AssemblerX86::psra,
1036 &x86::AssemblerX86::psra}; 1052 &x86::AssemblerX86::psra};
1037 1053
1038 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { 1054 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const {
1055 if (!ALLOW_DUMP)
1056 return;
1039 Ostream &Str = Func->getContext()->getStrEmit(); 1057 Ostream &Str = Func->getContext()->getStrEmit();
1040 assert(getSrcSize() == 1); 1058 assert(getSrcSize() == 1);
1041 Type Ty = getSrc(0)->getType(); 1059 Type Ty = getSrc(0)->getType();
1042 assert(isScalarFloatingType(Ty)); 1060 assert(isScalarFloatingType(Ty));
1043 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; 1061 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t";
1044 getSrc(0)->emit(Func); 1062 getSrc(0)->emit(Func);
1045 Str << ", "; 1063 Str << ", ";
1046 getDest()->emit(Func); 1064 getDest()->emit(Func);
1047 } 1065 }
1048 1066
1049 template <> void InstX8632Addss::emit(const Cfg *Func) const { 1067 template <> void InstX8632Addss::emit(const Cfg *Func) const {
1068 if (!ALLOW_DUMP)
1069 return;
1050 char buf[30]; 1070 char buf[30];
1051 snprintf(buf, llvm::array_lengthof(buf), "add%s", 1071 snprintf(buf, llvm::array_lengthof(buf), "add%s",
1052 TypeX8632Attributes[getDest()->getType()].SdSsString); 1072 TypeX8632Attributes[getDest()->getType()].SdSsString);
1053 emitTwoAddress(buf, this, Func); 1073 emitTwoAddress(buf, this, Func);
1054 } 1074 }
1055 1075
1056 template <> void InstX8632Padd::emit(const Cfg *Func) const { 1076 template <> void InstX8632Padd::emit(const Cfg *Func) const {
1077 if (!ALLOW_DUMP)
1078 return;
1057 char buf[30]; 1079 char buf[30];
1058 snprintf(buf, llvm::array_lengthof(buf), "padd%s", 1080 snprintf(buf, llvm::array_lengthof(buf), "padd%s",
1059 TypeX8632Attributes[getDest()->getType()].PackString); 1081 TypeX8632Attributes[getDest()->getType()].PackString);
1060 emitTwoAddress(buf, this, Func); 1082 emitTwoAddress(buf, this, Func);
1061 } 1083 }
1062 1084
1063 template <> void InstX8632Pmull::emit(const Cfg *Func) const { 1085 template <> void InstX8632Pmull::emit(const Cfg *Func) const {
1086 if (!ALLOW_DUMP)
1087 return;
1064 char buf[30]; 1088 char buf[30];
1065 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || 1089 bool TypesAreValid = getDest()->getType() == IceType_v4i32 ||
1066 getDest()->getType() == IceType_v8i16; 1090 getDest()->getType() == IceType_v8i16;
1067 bool InstructionSetIsValid = 1091 bool InstructionSetIsValid =
1068 getDest()->getType() == IceType_v8i16 || 1092 getDest()->getType() == IceType_v8i16 ||
1069 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 1093 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
1070 TargetX8632::SSE4_1; 1094 TargetX8632::SSE4_1;
1071 (void)TypesAreValid; 1095 (void)TypesAreValid;
1072 (void)InstructionSetIsValid; 1096 (void)InstructionSetIsValid;
1073 assert(TypesAreValid); 1097 assert(TypesAreValid);
(...skipping 13 matching lines...) Expand all
1087 (void)TypesAreValid; 1111 (void)TypesAreValid;
1088 (void)InstructionSetIsValid; 1112 (void)InstructionSetIsValid;
1089 assert(TypesAreValid); 1113 assert(TypesAreValid);
1090 assert(InstructionSetIsValid); 1114 assert(InstructionSetIsValid);
1091 assert(getSrcSize() == 2); 1115 assert(getSrcSize() == 2);
1092 Type ElementTy = typeElementType(Ty); 1116 Type ElementTy = typeElementType(Ty);
1093 emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); 1117 emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter);
1094 } 1118 }
1095 1119
1096 template <> void InstX8632Subss::emit(const Cfg *Func) const { 1120 template <> void InstX8632Subss::emit(const Cfg *Func) const {
1121 if (!ALLOW_DUMP)
1122 return;
1097 char buf[30]; 1123 char buf[30];
1098 snprintf(buf, llvm::array_lengthof(buf), "sub%s", 1124 snprintf(buf, llvm::array_lengthof(buf), "sub%s",
1099 TypeX8632Attributes[getDest()->getType()].SdSsString); 1125 TypeX8632Attributes[getDest()->getType()].SdSsString);
1100 emitTwoAddress(buf, this, Func); 1126 emitTwoAddress(buf, this, Func);
1101 } 1127 }
1102 1128
1103 template <> void InstX8632Psub::emit(const Cfg *Func) const { 1129 template <> void InstX8632Psub::emit(const Cfg *Func) const {
1130 if (!ALLOW_DUMP)
1131 return;
1104 char buf[30]; 1132 char buf[30];
1105 snprintf(buf, llvm::array_lengthof(buf), "psub%s", 1133 snprintf(buf, llvm::array_lengthof(buf), "psub%s",
1106 TypeX8632Attributes[getDest()->getType()].PackString); 1134 TypeX8632Attributes[getDest()->getType()].PackString);
1107 emitTwoAddress(buf, this, Func); 1135 emitTwoAddress(buf, this, Func);
1108 } 1136 }
1109 1137
1110 template <> void InstX8632Mulss::emit(const Cfg *Func) const { 1138 template <> void InstX8632Mulss::emit(const Cfg *Func) const {
1139 if (!ALLOW_DUMP)
1140 return;
1111 char buf[30]; 1141 char buf[30];
1112 snprintf(buf, llvm::array_lengthof(buf), "mul%s", 1142 snprintf(buf, llvm::array_lengthof(buf), "mul%s",
1113 TypeX8632Attributes[getDest()->getType()].SdSsString); 1143 TypeX8632Attributes[getDest()->getType()].SdSsString);
1114 emitTwoAddress(buf, this, Func); 1144 emitTwoAddress(buf, this, Func);
1115 } 1145 }
1116 1146
1117 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const { 1147 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const {
1148 if (!ALLOW_DUMP)
1149 return;
1118 assert(getSrc(0)->getType() == IceType_v4i32 && 1150 assert(getSrc(0)->getType() == IceType_v4i32 &&
1119 getSrc(1)->getType() == IceType_v4i32); 1151 getSrc(1)->getType() == IceType_v4i32);
1120 emitTwoAddress(Opcode, this, Func); 1152 emitTwoAddress(Opcode, this, Func);
1121 } 1153 }
1122 1154
1123 template <> void InstX8632Divss::emit(const Cfg *Func) const { 1155 template <> void InstX8632Divss::emit(const Cfg *Func) const {
1156 if (!ALLOW_DUMP)
1157 return;
1124 char buf[30]; 1158 char buf[30];
1125 snprintf(buf, llvm::array_lengthof(buf), "div%s", 1159 snprintf(buf, llvm::array_lengthof(buf), "div%s",
1126 TypeX8632Attributes[getDest()->getType()].SdSsString); 1160 TypeX8632Attributes[getDest()->getType()].SdSsString);
1127 emitTwoAddress(buf, this, Func); 1161 emitTwoAddress(buf, this, Func);
1128 } 1162 }
1129 1163
1130 template <> void InstX8632Div::emit(const Cfg *Func) const { 1164 template <> void InstX8632Div::emit(const Cfg *Func) const {
1165 if (!ALLOW_DUMP)
1166 return;
1131 Ostream &Str = Func->getContext()->getStrEmit(); 1167 Ostream &Str = Func->getContext()->getStrEmit();
1132 assert(getSrcSize() == 3); 1168 assert(getSrcSize() == 3);
1133 Operand *Src1 = getSrc(1); 1169 Operand *Src1 = getSrc(1);
1134 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; 1170 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t";
1135 Src1->emit(Func); 1171 Src1->emit(Func);
1136 } 1172 }
1137 1173
1138 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { 1174 template <> void InstX8632Div::emitIAS(const Cfg *Func) const {
1139 assert(getSrcSize() == 3); 1175 assert(getSrcSize() == 3);
1140 const Operand *Src = getSrc(1); 1176 const Operand *Src = getSrc(1);
1141 Type Ty = Src->getType(); 1177 Type Ty = Src->getType();
1142 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { 1178 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
1143 &x86::AssemblerX86::div, &x86::AssemblerX86::div}; 1179 &x86::AssemblerX86::div, &x86::AssemblerX86::div};
1144 emitIASOpTyGPR(Func, Ty, Src, Emitter); 1180 emitIASOpTyGPR(Func, Ty, Src, Emitter);
1145 } 1181 }
1146 1182
1147 template <> void InstX8632Idiv::emit(const Cfg *Func) const { 1183 template <> void InstX8632Idiv::emit(const Cfg *Func) const {
1184 if (!ALLOW_DUMP)
1185 return;
1148 Ostream &Str = Func->getContext()->getStrEmit(); 1186 Ostream &Str = Func->getContext()->getStrEmit();
1149 assert(getSrcSize() == 3); 1187 assert(getSrcSize() == 3);
1150 Operand *Src1 = getSrc(1); 1188 Operand *Src1 = getSrc(1);
1151 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; 1189 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t";
1152 Src1->emit(Func); 1190 Src1->emit(Func);
1153 } 1191 }
1154 1192
1155 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { 1193 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const {
1156 assert(getSrcSize() == 3); 1194 assert(getSrcSize() == 3);
1157 const Operand *Src = getSrc(1); 1195 const Operand *Src = getSrc(1);
1158 Type Ty = Src->getType(); 1196 Type Ty = Src->getType();
1159 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { 1197 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
1160 &x86::AssemblerX86::idiv, &x86::AssemblerX86::idiv}; 1198 &x86::AssemblerX86::idiv, &x86::AssemblerX86::idiv};
1161 emitIASOpTyGPR(Func, Ty, Src, Emitter); 1199 emitIASOpTyGPR(Func, Ty, Src, Emitter);
1162 } 1200 }
1163 1201
1164 namespace { 1202 namespace {
1165 1203
1166 // pblendvb and blendvps take xmm0 as a final implicit argument. 1204 // pblendvb and blendvps take xmm0 as a final implicit argument.
1167 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, 1205 void emitVariableBlendInst(const char *Opcode, const Inst *Inst,
1168 const Cfg *Func) { 1206 const Cfg *Func) {
1207 if (!ALLOW_DUMP)
1208 return;
1169 Ostream &Str = Func->getContext()->getStrEmit(); 1209 Ostream &Str = Func->getContext()->getStrEmit();
1170 assert(Inst->getSrcSize() == 3); 1210 assert(Inst->getSrcSize() == 3);
1171 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == 1211 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
1172 RegX8632::Reg_xmm0); 1212 RegX8632::Reg_xmm0);
1173 Str << "\t" << Opcode << "\t"; 1213 Str << "\t" << Opcode << "\t";
1174 Inst->getSrc(1)->emit(Func); 1214 Inst->getSrc(1)->emit(Func);
1175 Str << ", "; 1215 Str << ", ";
1176 Inst->getDest()->emit(Func); 1216 Inst->getDest()->emit(Func);
1177 } 1217 }
1178 1218
1179 void 1219 void
1180 emitIASVariableBlendInst(const Inst *Inst, const Cfg *Func, 1220 emitIASVariableBlendInst(const Inst *Inst, const Cfg *Func,
1181 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { 1221 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) {
1182 assert(Inst->getSrcSize() == 3); 1222 assert(Inst->getSrcSize() == 3);
1183 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == 1223 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() ==
1184 RegX8632::Reg_xmm0); 1224 RegX8632::Reg_xmm0);
1185 const Variable *Dest = Inst->getDest(); 1225 const Variable *Dest = Inst->getDest();
1186 const Operand *Src = Inst->getSrc(1); 1226 const Operand *Src = Inst->getSrc(1);
1187 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); 1227 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter);
1188 } 1228 }
1189 1229
1190 } // end anonymous namespace 1230 } // end anonymous namespace
1191 1231
1192 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { 1232 template <> void InstX8632Blendvps::emit(const Cfg *Func) const {
1233 if (!ALLOW_DUMP)
1234 return;
1193 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 1235 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
1194 TargetX8632::SSE4_1); 1236 TargetX8632::SSE4_1);
1195 emitVariableBlendInst(Opcode, this, Func); 1237 emitVariableBlendInst(Opcode, this, Func);
1196 } 1238 }
1197 1239
1198 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { 1240 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const {
1199 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 1241 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
1200 TargetX8632::SSE4_1); 1242 TargetX8632::SSE4_1);
1201 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { 1243 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = {
1202 &x86::AssemblerX86::blendvps, &x86::AssemblerX86::blendvps}; 1244 &x86::AssemblerX86::blendvps, &x86::AssemblerX86::blendvps};
1203 emitIASVariableBlendInst(this, Func, Emitter); 1245 emitIASVariableBlendInst(this, Func, Emitter);
1204 } 1246 }
1205 1247
1206 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { 1248 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const {
1249 if (!ALLOW_DUMP)
1250 return;
1207 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 1251 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
1208 TargetX8632::SSE4_1); 1252 TargetX8632::SSE4_1);
1209 emitVariableBlendInst(Opcode, this, Func); 1253 emitVariableBlendInst(Opcode, this, Func);
1210 } 1254 }
1211 1255
1212 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { 1256 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const {
1213 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 1257 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
1214 TargetX8632::SSE4_1); 1258 TargetX8632::SSE4_1);
1215 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { 1259 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = {
1216 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb}; 1260 &x86::AssemblerX86::pblendvb, &x86::AssemblerX86::pblendvb};
1217 emitIASVariableBlendInst(this, Func, Emitter); 1261 emitIASVariableBlendInst(this, Func, Emitter);
1218 } 1262 }
1219 1263
1220 template <> void InstX8632Imul::emit(const Cfg *Func) const { 1264 template <> void InstX8632Imul::emit(const Cfg *Func) const {
1265 if (!ALLOW_DUMP)
1266 return;
1221 Ostream &Str = Func->getContext()->getStrEmit(); 1267 Ostream &Str = Func->getContext()->getStrEmit();
1222 assert(getSrcSize() == 2); 1268 assert(getSrcSize() == 2);
1223 Variable *Dest = getDest(); 1269 Variable *Dest = getDest();
1224 if (isByteSizedArithType(Dest->getType())) { 1270 if (isByteSizedArithType(Dest->getType())) {
1225 // The 8-bit version of imul only allows the form "imul r/m8". 1271 // The 8-bit version of imul only allows the form "imul r/m8".
1226 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); 1272 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0));
1227 (void)Src0Var; 1273 (void)Src0Var;
1228 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); 1274 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax);
1229 Str << "\timulb\t"; 1275 Str << "\timulb\t";
1230 getSrc(1)->emit(Func); 1276 getSrc(1)->emit(Func);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 Type Ty = Dest->getType(); 1319 Type Ty = Dest->getType();
1274 static const x86::AssemblerX86::ThreeOpImmEmitter< 1320 static const x86::AssemblerX86::ThreeOpImmEmitter<
1275 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { 1321 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = {
1276 &x86::AssemblerX86::insertps, &x86::AssemblerX86::insertps}; 1322 &x86::AssemblerX86::insertps, &x86::AssemblerX86::insertps};
1277 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, 1323 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister,
1278 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( 1324 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>(
1279 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); 1325 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter);
1280 } 1326 }
1281 1327
1282 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { 1328 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const {
1329 if (!ALLOW_DUMP)
1330 return;
1283 Ostream &Str = Func->getContext()->getStrEmit(); 1331 Ostream &Str = Func->getContext()->getStrEmit();
1284 assert(getSrcSize() == 1); 1332 assert(getSrcSize() == 1);
1285 Operand *Src0 = getSrc(0); 1333 Operand *Src0 = getSrc(0);
1286 assert(llvm::isa<Variable>(Src0)); 1334 assert(llvm::isa<Variable>(Src0));
1287 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); 1335 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax);
1288 switch (Src0->getType()) { 1336 switch (Src0->getType()) {
1289 default: 1337 default:
1290 llvm_unreachable("unexpected source type!"); 1338 llvm_unreachable("unexpected source type!");
1291 break; 1339 break;
1292 case IceType_i8: 1340 case IceType_i8:
(...skipping 30 matching lines...) Expand all
1323 Asm->cwd(); 1371 Asm->cwd();
1324 break; 1372 break;
1325 case IceType_i32: 1373 case IceType_i32:
1326 assert(getDest()->getRegNum() == RegX8632::Reg_edx); 1374 assert(getDest()->getRegNum() == RegX8632::Reg_edx);
1327 Asm->cdq(); 1375 Asm->cdq();
1328 break; 1376 break;
1329 } 1377 }
1330 } 1378 }
1331 1379
1332 void InstX8632Mul::emit(const Cfg *Func) const { 1380 void InstX8632Mul::emit(const Cfg *Func) const {
1381 if (!ALLOW_DUMP)
1382 return;
1333 Ostream &Str = Func->getContext()->getStrEmit(); 1383 Ostream &Str = Func->getContext()->getStrEmit();
1334 assert(getSrcSize() == 2); 1384 assert(getSrcSize() == 2);
1335 assert(llvm::isa<Variable>(getSrc(0))); 1385 assert(llvm::isa<Variable>(getSrc(0)));
1336 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 1386 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
1337 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 1387 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
1338 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t"; 1388 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t";
1339 getSrc(1)->emit(Func); 1389 getSrc(1)->emit(Func);
1340 } 1390 }
1341 1391
1342 void InstX8632Mul::emitIAS(const Cfg *Func) const { 1392 void InstX8632Mul::emitIAS(const Cfg *Func) const {
1343 assert(getSrcSize() == 2); 1393 assert(getSrcSize() == 2);
1344 assert(llvm::isa<Variable>(getSrc(0))); 1394 assert(llvm::isa<Variable>(getSrc(0)));
1345 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 1395 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
1346 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 1396 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
1347 const Operand *Src = getSrc(1); 1397 const Operand *Src = getSrc(1);
1348 Type Ty = Src->getType(); 1398 Type Ty = Src->getType();
1349 const static x86::AssemblerX86::GPREmitterOneOp Emitter = { 1399 const static x86::AssemblerX86::GPREmitterOneOp Emitter = {
1350 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul}; 1400 &x86::AssemblerX86::mul, &x86::AssemblerX86::mul};
1351 emitIASOpTyGPR(Func, Ty, Src, Emitter); 1401 emitIASOpTyGPR(Func, Ty, Src, Emitter);
1352 } 1402 }
1353 1403
1354 void InstX8632Mul::dump(const Cfg *Func) const { 1404 void InstX8632Mul::dump(const Cfg *Func) const {
1405 if (!ALLOW_DUMP)
1406 return;
1355 Ostream &Str = Func->getContext()->getStrDump(); 1407 Ostream &Str = Func->getContext()->getStrDump();
1356 dumpDest(Func); 1408 dumpDest(Func);
1357 Str << " = mul." << getDest()->getType() << " "; 1409 Str << " = mul." << getDest()->getType() << " ";
1358 dumpSources(Func); 1410 dumpSources(Func);
1359 } 1411 }
1360 1412
1361 void InstX8632Shld::emit(const Cfg *Func) const { 1413 void InstX8632Shld::emit(const Cfg *Func) const {
1414 if (!ALLOW_DUMP)
1415 return;
1362 Ostream &Str = Func->getContext()->getStrEmit(); 1416 Ostream &Str = Func->getContext()->getStrEmit();
1363 Variable *Dest = getDest(); 1417 Variable *Dest = getDest();
1364 assert(getSrcSize() == 3); 1418 assert(getSrcSize() == 3);
1365 assert(Dest == getSrc(0)); 1419 assert(Dest == getSrc(0));
1366 Str << "\tshld" << getWidthString(Dest->getType()) << "\t"; 1420 Str << "\tshld" << getWidthString(Dest->getType()) << "\t";
1367 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { 1421 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
1368 (void)ShiftReg; 1422 (void)ShiftReg;
1369 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); 1423 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
1370 Str << "%cl"; 1424 Str << "%cl";
1371 } else { 1425 } else {
(...skipping 10 matching lines...) Expand all
1382 assert(getDest() == getSrc(0)); 1436 assert(getDest() == getSrc(0));
1383 const Variable *Dest = getDest(); 1437 const Variable *Dest = getDest();
1384 const Operand *Src1 = getSrc(1); 1438 const Operand *Src1 = getSrc(1);
1385 const Operand *Src2 = getSrc(2); 1439 const Operand *Src2 = getSrc(2);
1386 static const x86::AssemblerX86::GPREmitterShiftD Emitter = { 1440 static const x86::AssemblerX86::GPREmitterShiftD Emitter = {
1387 &x86::AssemblerX86::shld, &x86::AssemblerX86::shld}; 1441 &x86::AssemblerX86::shld, &x86::AssemblerX86::shld};
1388 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); 1442 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter);
1389 } 1443 }
1390 1444
1391 void InstX8632Shld::dump(const Cfg *Func) const { 1445 void InstX8632Shld::dump(const Cfg *Func) const {
1446 if (!ALLOW_DUMP)
1447 return;
1392 Ostream &Str = Func->getContext()->getStrDump(); 1448 Ostream &Str = Func->getContext()->getStrDump();
1393 dumpDest(Func); 1449 dumpDest(Func);
1394 Str << " = shld." << getDest()->getType() << " "; 1450 Str << " = shld." << getDest()->getType() << " ";
1395 dumpSources(Func); 1451 dumpSources(Func);
1396 } 1452 }
1397 1453
1398 void InstX8632Shrd::emit(const Cfg *Func) const { 1454 void InstX8632Shrd::emit(const Cfg *Func) const {
1455 if (!ALLOW_DUMP)
1456 return;
1399 Ostream &Str = Func->getContext()->getStrEmit(); 1457 Ostream &Str = Func->getContext()->getStrEmit();
1400 Variable *Dest = getDest(); 1458 Variable *Dest = getDest();
1401 assert(getSrcSize() == 3); 1459 assert(getSrcSize() == 3);
1402 assert(Dest == getSrc(0)); 1460 assert(Dest == getSrc(0));
1403 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t"; 1461 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t";
1404 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { 1462 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) {
1405 (void)ShiftReg; 1463 (void)ShiftReg;
1406 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); 1464 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx);
1407 Str << "%cl"; 1465 Str << "%cl";
1408 } else { 1466 } else {
(...skipping 10 matching lines...) Expand all
1419 assert(getDest() == getSrc(0)); 1477 assert(getDest() == getSrc(0));
1420 const Variable *Dest = getDest(); 1478 const Variable *Dest = getDest();
1421 const Operand *Src1 = getSrc(1); 1479 const Operand *Src1 = getSrc(1);
1422 const Operand *Src2 = getSrc(2); 1480 const Operand *Src2 = getSrc(2);
1423 static const x86::AssemblerX86::GPREmitterShiftD Emitter = { 1481 static const x86::AssemblerX86::GPREmitterShiftD Emitter = {
1424 &x86::AssemblerX86::shrd, &x86::AssemblerX86::shrd}; 1482 &x86::AssemblerX86::shrd, &x86::AssemblerX86::shrd};
1425 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); 1483 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter);
1426 } 1484 }
1427 1485
1428 void InstX8632Shrd::dump(const Cfg *Func) const { 1486 void InstX8632Shrd::dump(const Cfg *Func) const {
1487 if (!ALLOW_DUMP)
1488 return;
1429 Ostream &Str = Func->getContext()->getStrDump(); 1489 Ostream &Str = Func->getContext()->getStrDump();
1430 dumpDest(Func); 1490 dumpDest(Func);
1431 Str << " = shrd." << getDest()->getType() << " "; 1491 Str << " = shrd." << getDest()->getType() << " ";
1432 dumpSources(Func); 1492 dumpSources(Func);
1433 } 1493 }
1434 1494
1435 void InstX8632Cmov::emit(const Cfg *Func) const { 1495 void InstX8632Cmov::emit(const Cfg *Func) const {
1496 if (!ALLOW_DUMP)
1497 return;
1436 Ostream &Str = Func->getContext()->getStrEmit(); 1498 Ostream &Str = Func->getContext()->getStrEmit();
1437 Variable *Dest = getDest(); 1499 Variable *Dest = getDest();
1438 Str << "\t"; 1500 Str << "\t";
1439 assert(Condition != CondX86::Br_None); 1501 assert(Condition != CondX86::Br_None);
1440 assert(getDest()->hasReg()); 1502 assert(getDest()->hasReg());
1441 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString 1503 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString
1442 << getWidthString(Dest->getType()) << "\t"; 1504 << getWidthString(Dest->getType()) << "\t";
1443 getSrc(1)->emit(Func); 1505 getSrc(1)->emit(Func);
1444 Str << ", "; 1506 Str << ", ";
1445 Dest->emit(Func); 1507 Dest->emit(Func);
1446 } 1508 }
1447 1509
1448 void InstX8632Cmov::emitIAS(const Cfg *Func) const { 1510 void InstX8632Cmov::emitIAS(const Cfg *Func) const {
1449 assert(Condition != CondX86::Br_None); 1511 assert(Condition != CondX86::Br_None);
1450 assert(getDest()->hasReg()); 1512 assert(getDest()->hasReg());
1451 assert(getSrcSize() == 2); 1513 assert(getSrcSize() == 2);
1452 // Only need the reg/reg form now. 1514 // Only need the reg/reg form now.
1453 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); 1515 const auto SrcVar = llvm::cast<Variable>(getSrc(1));
1454 assert(SrcVar->hasReg()); 1516 assert(SrcVar->hasReg());
1455 assert(SrcVar->getType() == IceType_i32); 1517 assert(SrcVar->getType() == IceType_i32);
1456 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1518 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1457 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), 1519 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()),
1458 RegX8632::getEncodedGPR(SrcVar->getRegNum())); 1520 RegX8632::getEncodedGPR(SrcVar->getRegNum()));
1459 } 1521 }
1460 1522
1461 void InstX8632Cmov::dump(const Cfg *Func) const { 1523 void InstX8632Cmov::dump(const Cfg *Func) const {
1524 if (!ALLOW_DUMP)
1525 return;
1462 Ostream &Str = Func->getContext()->getStrDump(); 1526 Ostream &Str = Func->getContext()->getStrDump();
1463 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; 1527 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << ".";
1464 Str << getDest()->getType() << " "; 1528 Str << getDest()->getType() << " ";
1465 dumpDest(Func); 1529 dumpDest(Func);
1466 Str << ", "; 1530 Str << ", ";
1467 dumpSources(Func); 1531 dumpSources(Func);
1468 } 1532 }
1469 1533
1470 void InstX8632Cmpps::emit(const Cfg *Func) const { 1534 void InstX8632Cmpps::emit(const Cfg *Func) const {
1535 if (!ALLOW_DUMP)
1536 return;
1471 Ostream &Str = Func->getContext()->getStrEmit(); 1537 Ostream &Str = Func->getContext()->getStrEmit();
1472 assert(getSrcSize() == 2); 1538 assert(getSrcSize() == 2);
1473 assert(Condition < CondX86::Cmpps_Invalid); 1539 assert(Condition < CondX86::Cmpps_Invalid);
1474 Str << "\t"; 1540 Str << "\t";
1475 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1541 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
1476 << "\t"; 1542 << "\t";
1477 getSrc(1)->emit(Func); 1543 getSrc(1)->emit(Func);
1478 Str << ", "; 1544 Str << ", ";
1479 getDest()->emit(Func); 1545 getDest()->emit(Func);
1480 } 1546 }
(...skipping 11 matching lines...) Expand all
1492 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); 1558 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition);
1493 } else { 1559 } else {
1494 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 1560 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
1495 ->stackVarToAsmOperand(SrcVar); 1561 ->stackVarToAsmOperand(SrcVar);
1496 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, 1562 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr,
1497 Condition); 1563 Condition);
1498 } 1564 }
1499 } 1565 }
1500 1566
1501 void InstX8632Cmpps::dump(const Cfg *Func) const { 1567 void InstX8632Cmpps::dump(const Cfg *Func) const {
1568 if (!ALLOW_DUMP)
1569 return;
1502 Ostream &Str = Func->getContext()->getStrDump(); 1570 Ostream &Str = Func->getContext()->getStrDump();
1503 assert(Condition < CondX86::Cmpps_Invalid); 1571 assert(Condition < CondX86::Cmpps_Invalid);
1504 dumpDest(Func); 1572 dumpDest(Func);
1505 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1573 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
1506 << "\t"; 1574 << "\t";
1507 dumpSources(Func); 1575 dumpSources(Func);
1508 } 1576 }
1509 1577
1510 void InstX8632Cmpxchg::emit(const Cfg *Func) const { 1578 void InstX8632Cmpxchg::emit(const Cfg *Func) const {
1579 if (!ALLOW_DUMP)
1580 return;
1511 Ostream &Str = Func->getContext()->getStrEmit(); 1581 Ostream &Str = Func->getContext()->getStrEmit();
1512 assert(getSrcSize() == 3); 1582 assert(getSrcSize() == 3);
1513 if (Locked) { 1583 if (Locked) {
1514 Str << "\tlock"; 1584 Str << "\tlock";
1515 } 1585 }
1516 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; 1586 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t";
1517 getSrc(2)->emit(Func); 1587 getSrc(2)->emit(Func);
1518 Str << ", "; 1588 Str << ", ";
1519 getSrc(0)->emit(Func); 1589 getSrc(0)->emit(Func);
1520 } 1590 }
(...skipping 10 matching lines...) Expand all
1531 const RegX8632::GPRRegister Reg = 1601 const RegX8632::GPRRegister Reg =
1532 RegX8632::getEncodedGPR(VarReg->getRegNum()); 1602 RegX8632::getEncodedGPR(VarReg->getRegNum());
1533 if (Locked) { 1603 if (Locked) {
1534 Asm->LockCmpxchg(Ty, Addr, Reg); 1604 Asm->LockCmpxchg(Ty, Addr, Reg);
1535 } else { 1605 } else {
1536 Asm->cmpxchg(Ty, Addr, Reg); 1606 Asm->cmpxchg(Ty, Addr, Reg);
1537 } 1607 }
1538 } 1608 }
1539 1609
1540 void InstX8632Cmpxchg::dump(const Cfg *Func) const { 1610 void InstX8632Cmpxchg::dump(const Cfg *Func) const {
1611 if (!ALLOW_DUMP)
1612 return;
1541 Ostream &Str = Func->getContext()->getStrDump(); 1613 Ostream &Str = Func->getContext()->getStrDump();
1542 if (Locked) { 1614 if (Locked) {
1543 Str << "lock "; 1615 Str << "lock ";
1544 } 1616 }
1545 Str << "cmpxchg." << getSrc(0)->getType() << " "; 1617 Str << "cmpxchg." << getSrc(0)->getType() << " ";
1546 dumpSources(Func); 1618 dumpSources(Func);
1547 } 1619 }
1548 1620
1549 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { 1621 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const {
1622 if (!ALLOW_DUMP)
1623 return;
1550 Ostream &Str = Func->getContext()->getStrEmit(); 1624 Ostream &Str = Func->getContext()->getStrEmit();
1551 assert(getSrcSize() == 5); 1625 assert(getSrcSize() == 5);
1552 if (Locked) { 1626 if (Locked) {
1553 Str << "\tlock"; 1627 Str << "\tlock";
1554 } 1628 }
1555 Str << "\tcmpxchg8b\t"; 1629 Str << "\tcmpxchg8b\t";
1556 getSrc(0)->emit(Func); 1630 getSrc(0)->emit(Func);
1557 } 1631 }
1558 1632
1559 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { 1633 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const {
1560 assert(getSrcSize() == 5); 1634 assert(getSrcSize() == 5);
1561 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1635 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1562 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 1636 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
1563 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1637 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1564 const x86::Address Addr = Mem->toAsmAddress(Asm); 1638 const x86::Address Addr = Mem->toAsmAddress(Asm);
1565 if (Locked) { 1639 if (Locked) {
1566 Asm->lock(); 1640 Asm->lock();
1567 } 1641 }
1568 Asm->cmpxchg8b(Addr); 1642 Asm->cmpxchg8b(Addr);
1569 } 1643 }
1570 1644
1571 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { 1645 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const {
1646 if (!ALLOW_DUMP)
1647 return;
1572 Ostream &Str = Func->getContext()->getStrDump(); 1648 Ostream &Str = Func->getContext()->getStrDump();
1573 if (Locked) { 1649 if (Locked) {
1574 Str << "lock "; 1650 Str << "lock ";
1575 } 1651 }
1576 Str << "cmpxchg8b "; 1652 Str << "cmpxchg8b ";
1577 dumpSources(Func); 1653 dumpSources(Func);
1578 } 1654 }
1579 1655
1580 void InstX8632Cvt::emit(const Cfg *Func) const { 1656 void InstX8632Cvt::emit(const Cfg *Func) const {
1657 if (!ALLOW_DUMP)
1658 return;
1581 Ostream &Str = Func->getContext()->getStrEmit(); 1659 Ostream &Str = Func->getContext()->getStrEmit();
1582 assert(getSrcSize() == 1); 1660 assert(getSrcSize() == 1);
1583 Str << "\tcvt"; 1661 Str << "\tcvt";
1584 if (isTruncating()) 1662 if (isTruncating())
1585 Str << "t"; 1663 Str << "t";
1586 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" 1664 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2"
1587 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; 1665 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t";
1588 getSrc(0)->emit(Func); 1666 getSrc(0)->emit(Func);
1589 Str << ", "; 1667 Str << ", ";
1590 getDest()->emit(Func); 1668 getDest()->emit(Func);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1643 assert(isVectorIntegerType(DestTy)); 1721 assert(isVectorIntegerType(DestTy));
1644 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = { 1722 static const x86::AssemblerX86::XmmEmitterRegOp Emitter = {
1645 &x86::AssemblerX86::cvttps2dq, &x86::AssemblerX86::cvttps2dq}; 1723 &x86::AssemblerX86::cvttps2dq, &x86::AssemblerX86::cvttps2dq};
1646 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); 1724 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter);
1647 return; 1725 return;
1648 } 1726 }
1649 } 1727 }
1650 } 1728 }
1651 1729
1652 void InstX8632Cvt::dump(const Cfg *Func) const { 1730 void InstX8632Cvt::dump(const Cfg *Func) const {
1731 if (!ALLOW_DUMP)
1732 return;
1653 Ostream &Str = Func->getContext()->getStrDump(); 1733 Ostream &Str = Func->getContext()->getStrDump();
1654 dumpDest(Func); 1734 dumpDest(Func);
1655 Str << " = cvt"; 1735 Str << " = cvt";
1656 if (isTruncating()) 1736 if (isTruncating())
1657 Str << "t"; 1737 Str << "t";
1658 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" 1738 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2"
1659 << TypeX8632Attributes[getDest()->getType()].CvtString << " "; 1739 << TypeX8632Attributes[getDest()->getType()].CvtString << " ";
1660 dumpSources(Func); 1740 dumpSources(Func);
1661 } 1741 }
1662 1742
1663 void InstX8632Icmp::emit(const Cfg *Func) const { 1743 void InstX8632Icmp::emit(const Cfg *Func) const {
1744 if (!ALLOW_DUMP)
1745 return;
1664 Ostream &Str = Func->getContext()->getStrEmit(); 1746 Ostream &Str = Func->getContext()->getStrEmit();
1665 assert(getSrcSize() == 2); 1747 assert(getSrcSize() == 2);
1666 Str << "\tcmp" << getWidthString(getSrc(0)->getType()) << "\t"; 1748 Str << "\tcmp" << getWidthString(getSrc(0)->getType()) << "\t";
1667 getSrc(1)->emit(Func); 1749 getSrc(1)->emit(Func);
1668 Str << ", "; 1750 Str << ", ";
1669 getSrc(0)->emit(Func); 1751 getSrc(0)->emit(Func);
1670 } 1752 }
1671 1753
1672 void InstX8632Icmp::emitIAS(const Cfg *Func) const { 1754 void InstX8632Icmp::emitIAS(const Cfg *Func) const {
1673 assert(getSrcSize() == 2); 1755 assert(getSrcSize() == 2);
1674 const Operand *Src0 = getSrc(0); 1756 const Operand *Src0 = getSrc(0);
1675 const Operand *Src1 = getSrc(1); 1757 const Operand *Src1 = getSrc(1);
1676 Type Ty = Src0->getType(); 1758 Type Ty = Src0->getType();
1677 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = { 1759 static const x86::AssemblerX86::GPREmitterRegOp RegEmitter = {
1678 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp 1760 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp
1679 }; 1761 };
1680 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = { 1762 static const x86::AssemblerX86::GPREmitterAddrOp AddrEmitter = {
1681 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp 1763 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp
1682 }; 1764 };
1683 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { 1765 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) {
1684 if (SrcVar0->hasReg()) { 1766 if (SrcVar0->hasReg()) {
1685 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); 1767 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter);
1686 return; 1768 return;
1687 } 1769 }
1688 } 1770 }
1689 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); 1771 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter);
1690 } 1772 }
1691 1773
1692 void InstX8632Icmp::dump(const Cfg *Func) const { 1774 void InstX8632Icmp::dump(const Cfg *Func) const {
1775 if (!ALLOW_DUMP)
1776 return;
1693 Ostream &Str = Func->getContext()->getStrDump(); 1777 Ostream &Str = Func->getContext()->getStrDump();
1694 Str << "cmp." << getSrc(0)->getType() << " "; 1778 Str << "cmp." << getSrc(0)->getType() << " ";
1695 dumpSources(Func); 1779 dumpSources(Func);
1696 } 1780 }
1697 1781
1698 void InstX8632Ucomiss::emit(const Cfg *Func) const { 1782 void InstX8632Ucomiss::emit(const Cfg *Func) const {
1783 if (!ALLOW_DUMP)
1784 return;
1699 Ostream &Str = Func->getContext()->getStrEmit(); 1785 Ostream &Str = Func->getContext()->getStrEmit();
1700 assert(getSrcSize() == 2); 1786 assert(getSrcSize() == 2);
1701 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString 1787 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString
1702 << "\t"; 1788 << "\t";
1703 getSrc(1)->emit(Func); 1789 getSrc(1)->emit(Func);
1704 Str << ", "; 1790 Str << ", ";
1705 getSrc(0)->emit(Func); 1791 getSrc(0)->emit(Func);
1706 } 1792 }
1707 1793
1708 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { 1794 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const {
1709 assert(getSrcSize() == 2); 1795 assert(getSrcSize() == 2);
1710 // Currently src0 is always a variable by convention, to avoid having 1796 // Currently src0 is always a variable by convention, to avoid having
1711 // two memory operands. 1797 // two memory operands.
1712 assert(llvm::isa<Variable>(getSrc(0))); 1798 assert(llvm::isa<Variable>(getSrc(0)));
1713 const auto Src0Var = llvm::cast<Variable>(getSrc(0)); 1799 const auto Src0Var = llvm::cast<Variable>(getSrc(0));
1714 Type Ty = Src0Var->getType(); 1800 Type Ty = Src0Var->getType();
1715 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = { 1801 const static x86::AssemblerX86::XmmEmitterRegOp Emitter = {
1716 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss 1802 &x86::AssemblerX86::ucomiss, &x86::AssemblerX86::ucomiss
1717 }; 1803 };
1718 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter); 1804 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter);
1719 } 1805 }
1720 1806
1721 void InstX8632Ucomiss::dump(const Cfg *Func) const { 1807 void InstX8632Ucomiss::dump(const Cfg *Func) const {
1808 if (!ALLOW_DUMP)
1809 return;
1722 Ostream &Str = Func->getContext()->getStrDump(); 1810 Ostream &Str = Func->getContext()->getStrDump();
1723 Str << "ucomiss." << getSrc(0)->getType() << " "; 1811 Str << "ucomiss." << getSrc(0)->getType() << " ";
1724 dumpSources(Func); 1812 dumpSources(Func);
1725 } 1813 }
1726 1814
1727 void InstX8632UD2::emit(const Cfg *Func) const { 1815 void InstX8632UD2::emit(const Cfg *Func) const {
1816 if (!ALLOW_DUMP)
1817 return;
1728 Ostream &Str = Func->getContext()->getStrEmit(); 1818 Ostream &Str = Func->getContext()->getStrEmit();
1729 assert(getSrcSize() == 0); 1819 assert(getSrcSize() == 0);
1730 Str << "\tud2"; 1820 Str << "\tud2";
1731 } 1821 }
1732 1822
1733 void InstX8632UD2::emitIAS(const Cfg *Func) const { 1823 void InstX8632UD2::emitIAS(const Cfg *Func) const {
1734 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1824 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1735 Asm->ud2(); 1825 Asm->ud2();
1736 } 1826 }
1737 1827
1738 void InstX8632UD2::dump(const Cfg *Func) const { 1828 void InstX8632UD2::dump(const Cfg *Func) const {
1829 if (!ALLOW_DUMP)
1830 return;
1739 Ostream &Str = Func->getContext()->getStrDump(); 1831 Ostream &Str = Func->getContext()->getStrDump();
1740 Str << "ud2\n"; 1832 Str << "ud2\n";
1741 } 1833 }
1742 1834
1743 void InstX8632Test::emit(const Cfg *Func) const { 1835 void InstX8632Test::emit(const Cfg *Func) const {
1836 if (!ALLOW_DUMP)
1837 return;
1744 Ostream &Str = Func->getContext()->getStrEmit(); 1838 Ostream &Str = Func->getContext()->getStrEmit();
1745 assert(getSrcSize() == 2); 1839 assert(getSrcSize() == 2);
1746 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t"; 1840 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t";
1747 getSrc(1)->emit(Func); 1841 getSrc(1)->emit(Func);
1748 Str << ", "; 1842 Str << ", ";
1749 getSrc(0)->emit(Func); 1843 getSrc(0)->emit(Func);
1750 } 1844 }
1751 1845
1752 void InstX8632Test::emitIAS(const Cfg *Func) const { 1846 void InstX8632Test::emitIAS(const Cfg *Func) const {
1753 assert(getSrcSize() == 2); 1847 assert(getSrcSize() == 2);
(...skipping 10 matching lines...) Expand all
1764 if (SrcVar0->hasReg()) { 1858 if (SrcVar0->hasReg()) {
1765 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); 1859 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter);
1766 return; 1860 return;
1767 } 1861 }
1768 } 1862 }
1769 llvm_unreachable("Nothing actually generates this so it's untested"); 1863 llvm_unreachable("Nothing actually generates this so it's untested");
1770 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); 1864 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter);
1771 } 1865 }
1772 1866
1773 void InstX8632Test::dump(const Cfg *Func) const { 1867 void InstX8632Test::dump(const Cfg *Func) const {
1868 if (!ALLOW_DUMP)
1869 return;
1774 Ostream &Str = Func->getContext()->getStrDump(); 1870 Ostream &Str = Func->getContext()->getStrDump();
1775 Str << "test." << getSrc(0)->getType() << " "; 1871 Str << "test." << getSrc(0)->getType() << " ";
1776 dumpSources(Func); 1872 dumpSources(Func);
1777 } 1873 }
1778 1874
1779 void InstX8632Mfence::emit(const Cfg *Func) const { 1875 void InstX8632Mfence::emit(const Cfg *Func) const {
1876 if (!ALLOW_DUMP)
1877 return;
1780 Ostream &Str = Func->getContext()->getStrEmit(); 1878 Ostream &Str = Func->getContext()->getStrEmit();
1781 assert(getSrcSize() == 0); 1879 assert(getSrcSize() == 0);
1782 Str << "\tmfence"; 1880 Str << "\tmfence";
1783 } 1881 }
1784 1882
1785 void InstX8632Mfence::emitIAS(const Cfg *Func) const { 1883 void InstX8632Mfence::emitIAS(const Cfg *Func) const {
1786 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1884 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1787 Asm->mfence(); 1885 Asm->mfence();
1788 } 1886 }
1789 1887
1790 void InstX8632Mfence::dump(const Cfg *Func) const { 1888 void InstX8632Mfence::dump(const Cfg *Func) const {
1889 if (!ALLOW_DUMP)
1890 return;
1791 Ostream &Str = Func->getContext()->getStrDump(); 1891 Ostream &Str = Func->getContext()->getStrDump();
1792 Str << "mfence\n"; 1892 Str << "mfence\n";
1793 } 1893 }
1794 1894
1795 void InstX8632Store::emit(const Cfg *Func) const { 1895 void InstX8632Store::emit(const Cfg *Func) const {
1896 if (!ALLOW_DUMP)
1897 return;
1796 Ostream &Str = Func->getContext()->getStrEmit(); 1898 Ostream &Str = Func->getContext()->getStrEmit();
1797 assert(getSrcSize() == 2); 1899 assert(getSrcSize() == 2);
1798 Type Ty = getSrc(0)->getType(); 1900 Type Ty = getSrc(0)->getType();
1799 Str << "\tmov" << getWidthString(Ty) << TypeX8632Attributes[Ty].SdSsString 1901 Str << "\tmov" << getWidthString(Ty) << TypeX8632Attributes[Ty].SdSsString
1800 << "\t"; 1902 << "\t";
1801 getSrc(0)->emit(Func); 1903 getSrc(0)->emit(Func);
1802 Str << ", "; 1904 Str << ", ";
1803 getSrc(1)->emit(Func); 1905 getSrc(1)->emit(Func);
1804 } 1906 }
1805 1907
(...skipping 21 matching lines...) Expand all
1827 return; 1929 return;
1828 } else { 1930 } else {
1829 assert(isScalarIntegerType(DestTy)); 1931 assert(isScalarIntegerType(DestTy));
1830 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = { 1932 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = {
1831 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov}; 1933 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov};
1832 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter); 1934 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter);
1833 } 1935 }
1834 } 1936 }
1835 1937
1836 void InstX8632Store::dump(const Cfg *Func) const { 1938 void InstX8632Store::dump(const Cfg *Func) const {
1939 if (!ALLOW_DUMP)
1940 return;
1837 Ostream &Str = Func->getContext()->getStrDump(); 1941 Ostream &Str = Func->getContext()->getStrDump();
1838 Str << "mov." << getSrc(0)->getType() << " "; 1942 Str << "mov." << getSrc(0)->getType() << " ";
1839 getSrc(1)->dump(Func); 1943 getSrc(1)->dump(Func);
1840 Str << ", "; 1944 Str << ", ";
1841 getSrc(0)->dump(Func); 1945 getSrc(0)->dump(Func);
1842 } 1946 }
1843 1947
1844 void InstX8632StoreP::emit(const Cfg *Func) const { 1948 void InstX8632StoreP::emit(const Cfg *Func) const {
1949 if (!ALLOW_DUMP)
1950 return;
1845 Ostream &Str = Func->getContext()->getStrEmit(); 1951 Ostream &Str = Func->getContext()->getStrEmit();
1846 assert(getSrcSize() == 2); 1952 assert(getSrcSize() == 2);
1847 Str << "\tmovups\t"; 1953 Str << "\tmovups\t";
1848 getSrc(0)->emit(Func); 1954 getSrc(0)->emit(Func);
1849 Str << ", "; 1955 Str << ", ";
1850 getSrc(1)->emit(Func); 1956 getSrc(1)->emit(Func);
1851 } 1957 }
1852 1958
1853 void InstX8632StoreP::emitIAS(const Cfg *Func) const { 1959 void InstX8632StoreP::emitIAS(const Cfg *Func) const {
1854 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1960 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1855 assert(getSrcSize() == 2); 1961 assert(getSrcSize() == 2);
1856 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); 1962 const auto SrcVar = llvm::cast<Variable>(getSrc(0));
1857 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); 1963 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
1858 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1964 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1859 assert(SrcVar->hasReg()); 1965 assert(SrcVar->hasReg());
1860 Asm->movups(DestMem->toAsmAddress(Asm), 1966 Asm->movups(DestMem->toAsmAddress(Asm),
1861 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 1967 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
1862 } 1968 }
1863 1969
1864 void InstX8632StoreP::dump(const Cfg *Func) const { 1970 void InstX8632StoreP::dump(const Cfg *Func) const {
1971 if (!ALLOW_DUMP)
1972 return;
1865 Ostream &Str = Func->getContext()->getStrDump(); 1973 Ostream &Str = Func->getContext()->getStrDump();
1866 Str << "storep." << getSrc(0)->getType() << " "; 1974 Str << "storep." << getSrc(0)->getType() << " ";
1867 getSrc(1)->dump(Func); 1975 getSrc(1)->dump(Func);
1868 Str << ", "; 1976 Str << ", ";
1869 getSrc(0)->dump(Func); 1977 getSrc(0)->dump(Func);
1870 } 1978 }
1871 1979
1872 void InstX8632StoreQ::emit(const Cfg *Func) const { 1980 void InstX8632StoreQ::emit(const Cfg *Func) const {
1981 if (!ALLOW_DUMP)
1982 return;
1873 Ostream &Str = Func->getContext()->getStrEmit(); 1983 Ostream &Str = Func->getContext()->getStrEmit();
1874 assert(getSrcSize() == 2); 1984 assert(getSrcSize() == 2);
1875 assert(getSrc(1)->getType() == IceType_i64 || 1985 assert(getSrc(1)->getType() == IceType_i64 ||
1876 getSrc(1)->getType() == IceType_f64); 1986 getSrc(1)->getType() == IceType_f64);
1877 Str << "\tmovq\t"; 1987 Str << "\tmovq\t";
1878 getSrc(0)->emit(Func); 1988 getSrc(0)->emit(Func);
1879 Str << ", "; 1989 Str << ", ";
1880 getSrc(1)->emit(Func); 1990 getSrc(1)->emit(Func);
1881 } 1991 }
1882 1992
1883 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { 1993 void InstX8632StoreQ::emitIAS(const Cfg *Func) const {
1884 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1994 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1885 assert(getSrcSize() == 2); 1995 assert(getSrcSize() == 2);
1886 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); 1996 const auto SrcVar = llvm::cast<Variable>(getSrc(0));
1887 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); 1997 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
1888 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1998 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1889 assert(SrcVar->hasReg()); 1999 assert(SrcVar->hasReg());
1890 Asm->movq(DestMem->toAsmAddress(Asm), 2000 Asm->movq(DestMem->toAsmAddress(Asm),
1891 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 2001 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
1892 } 2002 }
1893 2003
1894 void InstX8632StoreQ::dump(const Cfg *Func) const { 2004 void InstX8632StoreQ::dump(const Cfg *Func) const {
2005 if (!ALLOW_DUMP)
2006 return;
1895 Ostream &Str = Func->getContext()->getStrDump(); 2007 Ostream &Str = Func->getContext()->getStrDump();
1896 Str << "storeq." << getSrc(0)->getType() << " "; 2008 Str << "storeq." << getSrc(0)->getType() << " ";
1897 getSrc(1)->dump(Func); 2009 getSrc(1)->dump(Func);
1898 Str << ", "; 2010 Str << ", ";
1899 getSrc(0)->dump(Func); 2011 getSrc(0)->dump(Func);
1900 } 2012 }
1901 2013
1902 template <> void InstX8632Lea::emit(const Cfg *Func) const { 2014 template <> void InstX8632Lea::emit(const Cfg *Func) const {
2015 if (!ALLOW_DUMP)
2016 return;
1903 Ostream &Str = Func->getContext()->getStrEmit(); 2017 Ostream &Str = Func->getContext()->getStrEmit();
1904 assert(getSrcSize() == 1); 2018 assert(getSrcSize() == 1);
1905 assert(getDest()->hasReg()); 2019 assert(getDest()->hasReg());
1906 Str << "\tleal\t"; 2020 Str << "\tleal\t";
1907 Operand *Src0 = getSrc(0); 2021 Operand *Src0 = getSrc(0);
1908 if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) { 2022 if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) {
1909 Type Ty = Src0Var->getType(); 2023 Type Ty = Src0Var->getType();
1910 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an 2024 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
1911 // acceptable type. 2025 // acceptable type.
1912 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func); 2026 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func);
1913 } else { 2027 } else {
1914 Src0->emit(Func); 2028 Src0->emit(Func);
1915 } 2029 }
1916 Str << ", "; 2030 Str << ", ";
1917 getDest()->emit(Func); 2031 getDest()->emit(Func);
1918 } 2032 }
1919 2033
1920 template <> void InstX8632Mov::emit(const Cfg *Func) const { 2034 template <> void InstX8632Mov::emit(const Cfg *Func) const {
2035 if (!ALLOW_DUMP)
2036 return;
1921 Ostream &Str = Func->getContext()->getStrEmit(); 2037 Ostream &Str = Func->getContext()->getStrEmit();
1922 assert(getSrcSize() == 1); 2038 assert(getSrcSize() == 1);
1923 Operand *Src = getSrc(0); 2039 Operand *Src = getSrc(0);
1924 Type SrcTy = Src->getType(); 2040 Type SrcTy = Src->getType();
1925 Type DestTy = getDest()->getType(); 2041 Type DestTy = getDest()->getType();
1926 Str << "\tmov" << (!isScalarFloatingType(DestTy) 2042 Str << "\tmov" << (!isScalarFloatingType(DestTy)
1927 ? getWidthString(SrcTy) 2043 ? getWidthString(SrcTy)
1928 : TypeX8632Attributes[DestTy].SdSsString) << "\t"; 2044 : TypeX8632Attributes[DestTy].SdSsString) << "\t";
1929 // For an integer truncation operation, src is wider than dest. 2045 // For an integer truncation operation, src is wider than dest.
1930 // Ideally, we use a mov instruction whose data width matches the 2046 // Ideally, we use a mov instruction whose data width matches the
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2039 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); 2155 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg);
2040 } else { 2156 } else {
2041 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2157 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2042 ->stackVarToAsmOperand(Dest)); 2158 ->stackVarToAsmOperand(Dest));
2043 Asm->movd(StackAddr, SrcReg); 2159 Asm->movd(StackAddr, SrcReg);
2044 } 2160 }
2045 } 2161 }
2046 } 2162 }
2047 2163
2048 template <> void InstX8632Movp::emit(const Cfg *Func) const { 2164 template <> void InstX8632Movp::emit(const Cfg *Func) const {
2165 if (!ALLOW_DUMP)
2166 return;
2049 // TODO(wala,stichnot): movups works with all vector operands, but 2167 // TODO(wala,stichnot): movups works with all vector operands, but
2050 // there exist other instructions (movaps, movdqa, movdqu) that may 2168 // there exist other instructions (movaps, movdqa, movdqu) that may
2051 // perform better, depending on the data type and alignment of the 2169 // perform better, depending on the data type and alignment of the
2052 // operands. 2170 // operands.
2053 Ostream &Str = Func->getContext()->getStrEmit(); 2171 Ostream &Str = Func->getContext()->getStrEmit();
2054 assert(getSrcSize() == 1); 2172 assert(getSrcSize() == 1);
2055 Str << "\tmovups\t"; 2173 Str << "\tmovups\t";
2056 getSrc(0)->emit(Func); 2174 getSrc(0)->emit(Func);
2057 Str << ", "; 2175 Str << ", ";
2058 getDest()->emit(Func); 2176 getDest()->emit(Func);
2059 } 2177 }
2060 2178
2061 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { 2179 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const {
2062 assert(getSrcSize() == 1); 2180 assert(getSrcSize() == 1);
2063 assert(isVectorType(getDest()->getType())); 2181 assert(isVectorType(getDest()->getType()));
2064 const Variable *Dest = getDest(); 2182 const Variable *Dest = getDest();
2065 const Operand *Src = getSrc(0); 2183 const Operand *Src = getSrc(0);
2066 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = { 2184 const static x86::AssemblerX86::XmmEmitterMovOps Emitter = {
2067 &x86::AssemblerX86::movups, &x86::AssemblerX86::movups, 2185 &x86::AssemblerX86::movups, &x86::AssemblerX86::movups,
2068 &x86::AssemblerX86::movups 2186 &x86::AssemblerX86::movups
2069 }; 2187 };
2070 emitIASMovlikeXMM(Func, Dest, Src, Emitter); 2188 emitIASMovlikeXMM(Func, Dest, Src, Emitter);
2071 } 2189 }
2072 2190
2073 template <> void InstX8632Movq::emit(const Cfg *Func) const { 2191 template <> void InstX8632Movq::emit(const Cfg *Func) const {
2192 if (!ALLOW_DUMP)
2193 return;
2074 Ostream &Str = Func->getContext()->getStrEmit(); 2194 Ostream &Str = Func->getContext()->getStrEmit();
2075 assert(getSrcSize() == 1); 2195 assert(getSrcSize() == 1);
2076 assert(getDest()->getType() == IceType_i64 || 2196 assert(getDest()->getType() == IceType_i64 ||
2077 getDest()->getType() == IceType_f64); 2197 getDest()->getType() == IceType_f64);
2078 Str << "\tmovq\t"; 2198 Str << "\tmovq\t";
2079 getSrc(0)->emit(Func); 2199 getSrc(0)->emit(Func);
2080 Str << ", "; 2200 Str << ", ";
2081 getDest()->emit(Func); 2201 getDest()->emit(Func);
2082 } 2202 }
2083 2203
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2123 assert(getSrcSize() == 1); 2243 assert(getSrcSize() == 1);
2124 const Variable *Dest = getDest(); 2244 const Variable *Dest = getDest();
2125 const Operand *Src = getSrc(0); 2245 const Operand *Src = getSrc(0);
2126 Type SrcTy = Src->getType(); 2246 Type SrcTy = Src->getType();
2127 assert(typeWidthInBytes(Dest->getType()) > 1); 2247 assert(typeWidthInBytes(Dest->getType()) > 1);
2128 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); 2248 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy));
2129 emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter); 2249 emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter);
2130 } 2250 }
2131 2251
2132 void InstX8632Nop::emit(const Cfg *Func) const { 2252 void InstX8632Nop::emit(const Cfg *Func) const {
2253 if (!ALLOW_DUMP)
2254 return;
2133 Ostream &Str = Func->getContext()->getStrEmit(); 2255 Ostream &Str = Func->getContext()->getStrEmit();
2134 // TODO: Emit the right code for each variant. 2256 // TODO: Emit the right code for each variant.
2135 Str << "\tnop\t# variant = " << Variant; 2257 Str << "\tnop\t# variant = " << Variant;
2136 } 2258 }
2137 2259
2138 void InstX8632Nop::emitIAS(const Cfg *Func) const { 2260 void InstX8632Nop::emitIAS(const Cfg *Func) const {
2139 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2261 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2140 // TODO: Emit the right code for the variant. 2262 // TODO: Emit the right code for the variant.
2141 Asm->nop(); 2263 Asm->nop();
2142 } 2264 }
2143 2265
2144 void InstX8632Nop::dump(const Cfg *Func) const { 2266 void InstX8632Nop::dump(const Cfg *Func) const {
2267 if (!ALLOW_DUMP)
2268 return;
2145 Ostream &Str = Func->getContext()->getStrDump(); 2269 Ostream &Str = Func->getContext()->getStrDump();
2146 Str << "nop (variant = " << Variant << ")"; 2270 Str << "nop (variant = " << Variant << ")";
2147 } 2271 }
2148 2272
2149 void InstX8632Fld::emit(const Cfg *Func) const { 2273 void InstX8632Fld::emit(const Cfg *Func) const {
2274 if (!ALLOW_DUMP)
2275 return;
2150 Ostream &Str = Func->getContext()->getStrEmit(); 2276 Ostream &Str = Func->getContext()->getStrEmit();
2151 assert(getSrcSize() == 1); 2277 assert(getSrcSize() == 1);
2152 Type Ty = getSrc(0)->getType(); 2278 Type Ty = getSrc(0)->getType();
2153 SizeT Width = typeWidthInBytes(Ty); 2279 SizeT Width = typeWidthInBytes(Ty);
2154 const auto Var = llvm::dyn_cast<Variable>(getSrc(0)); 2280 const auto Var = llvm::dyn_cast<Variable>(getSrc(0));
2155 if (Var && Var->hasReg()) { 2281 if (Var && Var->hasReg()) {
2156 // This is a physical xmm register, so we need to spill it to a 2282 // This is a physical xmm register, so we need to spill it to a
2157 // temporary stack slot. 2283 // temporary stack slot.
2158 Str << "\tsubl\t$" << Width << ", %esp" 2284 Str << "\tsubl\t$" << Width << ", %esp"
2159 << "\n"; 2285 << "\n";
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2193 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2319 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2194 Asm->fld(Ty, Mem->toAsmAddress(Asm)); 2320 Asm->fld(Ty, Mem->toAsmAddress(Asm));
2195 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { 2321 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
2196 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); 2322 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
2197 } else { 2323 } else {
2198 llvm_unreachable("Unexpected operand type"); 2324 llvm_unreachable("Unexpected operand type");
2199 } 2325 }
2200 } 2326 }
2201 2327
2202 void InstX8632Fld::dump(const Cfg *Func) const { 2328 void InstX8632Fld::dump(const Cfg *Func) const {
2329 if (!ALLOW_DUMP)
2330 return;
2203 Ostream &Str = Func->getContext()->getStrDump(); 2331 Ostream &Str = Func->getContext()->getStrDump();
2204 Str << "fld." << getSrc(0)->getType() << " "; 2332 Str << "fld." << getSrc(0)->getType() << " ";
2205 dumpSources(Func); 2333 dumpSources(Func);
2206 } 2334 }
2207 2335
2208 void InstX8632Fstp::emit(const Cfg *Func) const { 2336 void InstX8632Fstp::emit(const Cfg *Func) const {
2337 if (!ALLOW_DUMP)
2338 return;
2209 Ostream &Str = Func->getContext()->getStrEmit(); 2339 Ostream &Str = Func->getContext()->getStrEmit();
2210 assert(getSrcSize() == 0); 2340 assert(getSrcSize() == 0);
2211 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to 2341 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
2212 // "partially" delete the fstp if the Dest is unused. 2342 // "partially" delete the fstp if the Dest is unused.
2213 // Even if Dest is unused, the fstp should be kept for the SideEffects 2343 // Even if Dest is unused, the fstp should be kept for the SideEffects
2214 // of popping the stack. 2344 // of popping the stack.
2215 if (!getDest()) { 2345 if (!getDest()) {
2216 Str << "\tfstp\tst(0)"; 2346 Str << "\tfstp\tst(0)";
2217 return; 2347 return;
2218 } 2348 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2262 x86::Immediate Width(typeWidthInBytes(Ty)); 2392 x86::Immediate Width(typeWidthInBytes(Ty));
2263 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); 2393 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2264 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); 2394 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
2265 Asm->fstp(Ty, StackSlot); 2395 Asm->fstp(Ty, StackSlot);
2266 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); 2396 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot);
2267 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); 2397 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2268 } 2398 }
2269 } 2399 }
2270 2400
2271 void InstX8632Fstp::dump(const Cfg *Func) const { 2401 void InstX8632Fstp::dump(const Cfg *Func) const {
2402 if (!ALLOW_DUMP)
2403 return;
2272 Ostream &Str = Func->getContext()->getStrDump(); 2404 Ostream &Str = Func->getContext()->getStrDump();
2273 dumpDest(Func); 2405 dumpDest(Func);
2274 Str << " = fstp." << getDest()->getType() << ", st(0)"; 2406 Str << " = fstp." << getDest()->getType() << ", st(0)";
2275 Str << "\n"; 2407 Str << "\n";
2276 } 2408 }
2277 2409
2278 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { 2410 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const {
2411 if (!ALLOW_DUMP)
2412 return;
2279 char buf[30]; 2413 char buf[30];
2280 snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s", 2414 snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s",
2281 TypeX8632Attributes[getDest()->getType()].PackString); 2415 TypeX8632Attributes[getDest()->getType()].PackString);
2282 emitTwoAddress(buf, this, Func); 2416 emitTwoAddress(buf, this, Func);
2283 } 2417 }
2284 2418
2285 template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const { 2419 template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const {
2420 if (!ALLOW_DUMP)
2421 return;
2286 char buf[30]; 2422 char buf[30];
2287 snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s", 2423 snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s",
2288 TypeX8632Attributes[getDest()->getType()].PackString); 2424 TypeX8632Attributes[getDest()->getType()].PackString);
2289 emitTwoAddress(buf, this, Func); 2425 emitTwoAddress(buf, this, Func);
2290 } 2426 }
2291 2427
2292 template <> void InstX8632Pextr::emit(const Cfg *Func) const { 2428 template <> void InstX8632Pextr::emit(const Cfg *Func) const {
2429 if (!ALLOW_DUMP)
2430 return;
2293 Ostream &Str = Func->getContext()->getStrEmit(); 2431 Ostream &Str = Func->getContext()->getStrEmit();
2294 assert(getSrcSize() == 2); 2432 assert(getSrcSize() == 2);
2295 // pextrb and pextrd are SSE4.1 instructions. 2433 // pextrb and pextrd are SSE4.1 instructions.
2296 assert(getSrc(0)->getType() == IceType_v8i16 || 2434 assert(getSrc(0)->getType() == IceType_v8i16 ||
2297 getSrc(0)->getType() == IceType_v8i1 || 2435 getSrc(0)->getType() == IceType_v8i1 ||
2298 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() 2436 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet()
2299 >= TargetX8632::SSE4_1); 2437 >= TargetX8632::SSE4_1);
2300 Str << "\t" << Opcode 2438 Str << "\t" << Opcode
2301 << TypeX8632Attributes[getSrc(0)->getType()].PackString << "\t"; 2439 << TypeX8632Attributes[getSrc(0)->getType()].PackString << "\t";
2302 getSrc(1)->emit(Func); 2440 getSrc(1)->emit(Func);
(...skipping 24 matching lines...) Expand all
2327 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); 2465 assert(llvm::cast<Variable>(getSrc(0))->hasReg());
2328 static const x86::AssemblerX86::ThreeOpImmEmitter< 2466 static const x86::AssemblerX86::ThreeOpImmEmitter<
2329 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { 2467 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = {
2330 &x86::AssemblerX86::pextr, nullptr}; 2468 &x86::AssemblerX86::pextr, nullptr};
2331 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, 2469 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister,
2332 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( 2470 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>(
2333 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); 2471 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter);
2334 } 2472 }
2335 2473
2336 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { 2474 template <> void InstX8632Pinsr::emit(const Cfg *Func) const {
2475 if (!ALLOW_DUMP)
2476 return;
2337 Ostream &Str = Func->getContext()->getStrEmit(); 2477 Ostream &Str = Func->getContext()->getStrEmit();
2338 assert(getSrcSize() == 3); 2478 assert(getSrcSize() == 3);
2339 // pinsrb and pinsrd are SSE4.1 instructions. 2479 // pinsrb and pinsrd are SSE4.1 instructions.
2340 assert(getDest()->getType() == IceType_v8i16 || 2480 assert(getDest()->getType() == IceType_v8i16 ||
2341 getDest()->getType() == IceType_v8i1 || 2481 getDest()->getType() == IceType_v8i1 ||
2342 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() 2482 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet()
2343 >= TargetX8632::SSE4_1); 2483 >= TargetX8632::SSE4_1);
2344 Str << "\t" << Opcode 2484 Str << "\t" << Opcode
2345 << TypeX8632Attributes[getDest()->getType()].PackString << "\t"; 2485 << TypeX8632Attributes[getDest()->getType()].PackString << "\t";
2346 getSrc(2)->emit(Func); 2486 getSrc(2)->emit(Func);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2400 Type Ty = Dest->getType(); 2540 Type Ty = Dest->getType();
2401 static const x86::AssemblerX86::ThreeOpImmEmitter< 2541 static const x86::AssemblerX86::ThreeOpImmEmitter<
2402 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { 2542 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = {
2403 &x86::AssemblerX86::shufps, &x86::AssemblerX86::shufps}; 2543 &x86::AssemblerX86::shufps, &x86::AssemblerX86::shufps};
2404 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, 2544 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister,
2405 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( 2545 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>(
2406 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); 2546 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter);
2407 } 2547 }
2408 2548
2409 void InstX8632Pop::emit(const Cfg *Func) const { 2549 void InstX8632Pop::emit(const Cfg *Func) const {
2550 if (!ALLOW_DUMP)
2551 return;
2410 Ostream &Str = Func->getContext()->getStrEmit(); 2552 Ostream &Str = Func->getContext()->getStrEmit();
2411 assert(getSrcSize() == 0); 2553 assert(getSrcSize() == 0);
2412 Str << "\tpop\t"; 2554 Str << "\tpop\t";
2413 getDest()->emit(Func); 2555 getDest()->emit(Func);
2414 } 2556 }
2415 2557
2416 void InstX8632Pop::emitIAS(const Cfg *Func) const { 2558 void InstX8632Pop::emitIAS(const Cfg *Func) const {
2417 assert(getSrcSize() == 0); 2559 assert(getSrcSize() == 0);
2418 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2560 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2419 if (getDest()->hasReg()) { 2561 if (getDest()->hasReg()) {
2420 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); 2562 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum()));
2421 } else { 2563 } else {
2422 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) 2564 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget())
2423 ->stackVarToAsmOperand(getDest())); 2565 ->stackVarToAsmOperand(getDest()));
2424 } 2566 }
2425 } 2567 }
2426 2568
2427 void InstX8632Pop::dump(const Cfg *Func) const { 2569 void InstX8632Pop::dump(const Cfg *Func) const {
2570 if (!ALLOW_DUMP)
2571 return;
2428 Ostream &Str = Func->getContext()->getStrDump(); 2572 Ostream &Str = Func->getContext()->getStrDump();
2429 dumpDest(Func); 2573 dumpDest(Func);
2430 Str << " = pop." << getDest()->getType() << " "; 2574 Str << " = pop." << getDest()->getType() << " ";
2431 } 2575 }
2432 2576
2433 void InstX8632AdjustStack::emit(const Cfg *Func) const { 2577 void InstX8632AdjustStack::emit(const Cfg *Func) const {
2578 if (!ALLOW_DUMP)
2579 return;
2434 Ostream &Str = Func->getContext()->getStrEmit(); 2580 Ostream &Str = Func->getContext()->getStrEmit();
2435 Str << "\tsubl\t$" << Amount << ", %esp"; 2581 Str << "\tsubl\t$" << Amount << ", %esp";
2436 Func->getTarget()->updateStackAdjustment(Amount); 2582 Func->getTarget()->updateStackAdjustment(Amount);
2437 } 2583 }
2438 2584
2439 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { 2585 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const {
2440 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2586 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2441 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); 2587 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount));
2442 Func->getTarget()->updateStackAdjustment(Amount); 2588 Func->getTarget()->updateStackAdjustment(Amount);
2443 } 2589 }
2444 2590
2445 void InstX8632AdjustStack::dump(const Cfg *Func) const { 2591 void InstX8632AdjustStack::dump(const Cfg *Func) const {
2592 if (!ALLOW_DUMP)
2593 return;
2446 Ostream &Str = Func->getContext()->getStrDump(); 2594 Ostream &Str = Func->getContext()->getStrDump();
2447 Str << "esp = sub.i32 esp, " << Amount; 2595 Str << "esp = sub.i32 esp, " << Amount;
2448 } 2596 }
2449 2597
2450 void InstX8632Push::emit(const Cfg *Func) const { 2598 void InstX8632Push::emit(const Cfg *Func) const {
2599 if (!ALLOW_DUMP)
2600 return;
2451 Ostream &Str = Func->getContext()->getStrEmit(); 2601 Ostream &Str = Func->getContext()->getStrEmit();
2452 assert(getSrcSize() == 1); 2602 assert(getSrcSize() == 1);
2453 // Push is currently only used for saving GPRs. 2603 // Push is currently only used for saving GPRs.
2454 const auto Var = llvm::cast<Variable>(getSrc(0)); 2604 const auto Var = llvm::cast<Variable>(getSrc(0));
2455 assert(Var->hasReg()); 2605 assert(Var->hasReg());
2456 Str << "\tpush\t"; 2606 Str << "\tpush\t";
2457 Var->emit(Func); 2607 Var->emit(Func);
2458 } 2608 }
2459 2609
2460 void InstX8632Push::emitIAS(const Cfg *Func) const { 2610 void InstX8632Push::emitIAS(const Cfg *Func) const {
2461 assert(getSrcSize() == 1); 2611 assert(getSrcSize() == 1);
2462 // Push is currently only used for saving GPRs. 2612 // Push is currently only used for saving GPRs.
2463 const auto Var = llvm::cast<Variable>(getSrc(0)); 2613 const auto Var = llvm::cast<Variable>(getSrc(0));
2464 assert(Var->hasReg()); 2614 assert(Var->hasReg());
2465 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2615 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2466 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); 2616 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum()));
2467 } 2617 }
2468 2618
2469 void InstX8632Push::dump(const Cfg *Func) const { 2619 void InstX8632Push::dump(const Cfg *Func) const {
2620 if (!ALLOW_DUMP)
2621 return;
2470 Ostream &Str = Func->getContext()->getStrDump(); 2622 Ostream &Str = Func->getContext()->getStrDump();
2471 Str << "push." << getSrc(0)->getType() << " "; 2623 Str << "push." << getSrc(0)->getType() << " ";
2472 dumpSources(Func); 2624 dumpSources(Func);
2473 } 2625 }
2474 2626
2475 template <> void InstX8632Psll::emit(const Cfg *Func) const { 2627 template <> void InstX8632Psll::emit(const Cfg *Func) const {
2628 if (!ALLOW_DUMP)
2629 return;
2476 assert(getDest()->getType() == IceType_v8i16 || 2630 assert(getDest()->getType() == IceType_v8i16 ||
2477 getDest()->getType() == IceType_v8i1 || 2631 getDest()->getType() == IceType_v8i1 ||
2478 getDest()->getType() == IceType_v4i32 || 2632 getDest()->getType() == IceType_v4i32 ||
2479 getDest()->getType() == IceType_v4i1); 2633 getDest()->getType() == IceType_v4i1);
2480 char buf[30]; 2634 char buf[30];
2481 snprintf(buf, llvm::array_lengthof(buf), "psll%s", 2635 snprintf(buf, llvm::array_lengthof(buf), "psll%s",
2482 TypeX8632Attributes[getDest()->getType()].PackString); 2636 TypeX8632Attributes[getDest()->getType()].PackString);
2483 emitTwoAddress(buf, this, Func); 2637 emitTwoAddress(buf, this, Func);
2484 } 2638 }
2485 2639
2486 template <> void InstX8632Psra::emit(const Cfg *Func) const { 2640 template <> void InstX8632Psra::emit(const Cfg *Func) const {
2641 if (!ALLOW_DUMP)
2642 return;
2487 assert(getDest()->getType() == IceType_v8i16 || 2643 assert(getDest()->getType() == IceType_v8i16 ||
2488 getDest()->getType() == IceType_v8i1 || 2644 getDest()->getType() == IceType_v8i1 ||
2489 getDest()->getType() == IceType_v4i32 || 2645 getDest()->getType() == IceType_v4i32 ||
2490 getDest()->getType() == IceType_v4i1); 2646 getDest()->getType() == IceType_v4i1);
2491 char buf[30]; 2647 char buf[30];
2492 snprintf(buf, llvm::array_lengthof(buf), "psra%s", 2648 snprintf(buf, llvm::array_lengthof(buf), "psra%s",
2493 TypeX8632Attributes[getDest()->getType()].PackString); 2649 TypeX8632Attributes[getDest()->getType()].PackString);
2494 emitTwoAddress(buf, this, Func); 2650 emitTwoAddress(buf, this, Func);
2495 } 2651 }
2496 2652
2497 void InstX8632Ret::emit(const Cfg *Func) const { 2653 void InstX8632Ret::emit(const Cfg *Func) const {
2654 if (!ALLOW_DUMP)
2655 return;
2498 Ostream &Str = Func->getContext()->getStrEmit(); 2656 Ostream &Str = Func->getContext()->getStrEmit();
2499 Str << "\tret"; 2657 Str << "\tret";
2500 } 2658 }
2501 2659
2502 void InstX8632Ret::emitIAS(const Cfg *Func) const { 2660 void InstX8632Ret::emitIAS(const Cfg *Func) const {
2503 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2661 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2504 Asm->ret(); 2662 Asm->ret();
2505 } 2663 }
2506 2664
2507 void InstX8632Ret::dump(const Cfg *Func) const { 2665 void InstX8632Ret::dump(const Cfg *Func) const {
2666 if (!ALLOW_DUMP)
2667 return;
2508 Ostream &Str = Func->getContext()->getStrDump(); 2668 Ostream &Str = Func->getContext()->getStrDump();
2509 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); 2669 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType());
2510 Str << "ret." << Ty << " "; 2670 Str << "ret." << Ty << " ";
2511 dumpSources(Func); 2671 dumpSources(Func);
2512 } 2672 }
2513 2673
2514 void InstX8632Xadd::emit(const Cfg *Func) const { 2674 void InstX8632Xadd::emit(const Cfg *Func) const {
2675 if (!ALLOW_DUMP)
2676 return;
2515 Ostream &Str = Func->getContext()->getStrEmit(); 2677 Ostream &Str = Func->getContext()->getStrEmit();
2516 if (Locked) { 2678 if (Locked) {
2517 Str << "\tlock"; 2679 Str << "\tlock";
2518 } 2680 }
2519 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t"; 2681 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t";
2520 getSrc(1)->emit(Func); 2682 getSrc(1)->emit(Func);
2521 Str << ", "; 2683 Str << ", ";
2522 getSrc(0)->emit(Func); 2684 getSrc(0)->emit(Func);
2523 } 2685 }
2524 2686
2525 void InstX8632Xadd::emitIAS(const Cfg *Func) const { 2687 void InstX8632Xadd::emitIAS(const Cfg *Func) const {
2526 assert(getSrcSize() == 2); 2688 assert(getSrcSize() == 2);
2527 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2689 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2528 Type Ty = getSrc(0)->getType(); 2690 Type Ty = getSrc(0)->getType();
2529 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2691 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2530 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2692 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2531 const x86::Address Addr = Mem->toAsmAddress(Asm); 2693 const x86::Address Addr = Mem->toAsmAddress(Asm);
2532 const auto VarReg = llvm::cast<Variable>(getSrc(1)); 2694 const auto VarReg = llvm::cast<Variable>(getSrc(1));
2533 assert(VarReg->hasReg()); 2695 assert(VarReg->hasReg());
2534 const RegX8632::GPRRegister Reg = 2696 const RegX8632::GPRRegister Reg =
2535 RegX8632::getEncodedGPR(VarReg->getRegNum()); 2697 RegX8632::getEncodedGPR(VarReg->getRegNum());
2536 if (Locked) { 2698 if (Locked) {
2537 Asm->lock(); 2699 Asm->lock();
2538 } 2700 }
2539 Asm->xadd(Ty, Addr, Reg); 2701 Asm->xadd(Ty, Addr, Reg);
2540 } 2702 }
2541 2703
2542 void InstX8632Xadd::dump(const Cfg *Func) const { 2704 void InstX8632Xadd::dump(const Cfg *Func) const {
2705 if (!ALLOW_DUMP)
2706 return;
2543 Ostream &Str = Func->getContext()->getStrDump(); 2707 Ostream &Str = Func->getContext()->getStrDump();
2544 if (Locked) { 2708 if (Locked) {
2545 Str << "lock "; 2709 Str << "lock ";
2546 } 2710 }
2547 Type Ty = getSrc(0)->getType(); 2711 Type Ty = getSrc(0)->getType();
2548 Str << "xadd." << Ty << " "; 2712 Str << "xadd." << Ty << " ";
2549 dumpSources(Func); 2713 dumpSources(Func);
2550 } 2714 }
2551 2715
2552 void InstX8632Xchg::emit(const Cfg *Func) const { 2716 void InstX8632Xchg::emit(const Cfg *Func) const {
2717 if (!ALLOW_DUMP)
2718 return;
2553 Ostream &Str = Func->getContext()->getStrEmit(); 2719 Ostream &Str = Func->getContext()->getStrEmit();
2554 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t"; 2720 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t";
2555 getSrc(1)->emit(Func); 2721 getSrc(1)->emit(Func);
2556 Str << ", "; 2722 Str << ", ";
2557 getSrc(0)->emit(Func); 2723 getSrc(0)->emit(Func);
2558 } 2724 }
2559 2725
2560 void InstX8632Xchg::emitIAS(const Cfg *Func) const { 2726 void InstX8632Xchg::emitIAS(const Cfg *Func) const {
2561 assert(getSrcSize() == 2); 2727 assert(getSrcSize() == 2);
2562 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2728 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2563 Type Ty = getSrc(0)->getType(); 2729 Type Ty = getSrc(0)->getType();
2564 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2730 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2565 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2731 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2566 const x86::Address Addr = Mem->toAsmAddress(Asm); 2732 const x86::Address Addr = Mem->toAsmAddress(Asm);
2567 const auto VarReg = llvm::cast<Variable>(getSrc(1)); 2733 const auto VarReg = llvm::cast<Variable>(getSrc(1));
2568 assert(VarReg->hasReg()); 2734 assert(VarReg->hasReg());
2569 const RegX8632::GPRRegister Reg = 2735 const RegX8632::GPRRegister Reg =
2570 RegX8632::getEncodedGPR(VarReg->getRegNum()); 2736 RegX8632::getEncodedGPR(VarReg->getRegNum());
2571 Asm->xchg(Ty, Addr, Reg); 2737 Asm->xchg(Ty, Addr, Reg);
2572 } 2738 }
2573 2739
2574 void InstX8632Xchg::dump(const Cfg *Func) const { 2740 void InstX8632Xchg::dump(const Cfg *Func) const {
2741 if (!ALLOW_DUMP)
2742 return;
2575 Ostream &Str = Func->getContext()->getStrDump(); 2743 Ostream &Str = Func->getContext()->getStrDump();
2576 Type Ty = getSrc(0)->getType(); 2744 Type Ty = getSrc(0)->getType();
2577 Str << "xchg." << Ty << " "; 2745 Str << "xchg." << Ty << " ";
2578 dumpSources(Func); 2746 dumpSources(Func);
2579 } 2747 }
2580 2748
2581 void OperandX8632Mem::emit(const Cfg *Func) const { 2749 void OperandX8632Mem::emit(const Cfg *Func) const {
2750 if (!ALLOW_DUMP)
2751 return;
2582 Ostream &Str = Func->getContext()->getStrEmit(); 2752 Ostream &Str = Func->getContext()->getStrEmit();
2583 if (SegmentReg != DefaultSegment) { 2753 if (SegmentReg != DefaultSegment) {
2584 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); 2754 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
2585 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; 2755 Str << InstX8632SegmentRegNames[SegmentReg] << ":";
2586 } 2756 }
2587 // Emit as Offset(Base,Index,1<<Shift). 2757 // Emit as Offset(Base,Index,1<<Shift).
2588 // Offset is emitted without the leading '$'. 2758 // Offset is emitted without the leading '$'.
2589 // Omit the (Base,Index,1<<Shift) part if Base==nullptr. 2759 // Omit the (Base,Index,1<<Shift) part if Base==nullptr.
2590 if (!Offset) { 2760 if (!Offset) {
2591 // No offset, emit nothing. 2761 // No offset, emit nothing.
(...skipping 14 matching lines...) Expand all
2606 Str << ","; 2776 Str << ",";
2607 Index->emit(Func); 2777 Index->emit(Func);
2608 if (Shift) 2778 if (Shift)
2609 Str << "," << (1u << Shift); 2779 Str << "," << (1u << Shift);
2610 } 2780 }
2611 Str << ")"; 2781 Str << ")";
2612 } 2782 }
2613 } 2783 }
2614 2784
2615 void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const { 2785 void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const {
2786 if (!ALLOW_DUMP)
2787 return;
2616 if (SegmentReg != DefaultSegment) { 2788 if (SegmentReg != DefaultSegment) {
2617 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); 2789 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
2618 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; 2790 Str << InstX8632SegmentRegNames[SegmentReg] << ":";
2619 } 2791 }
2620 bool Dumped = false; 2792 bool Dumped = false;
2621 Str << "["; 2793 Str << "[";
2622 if (Base) { 2794 if (Base) {
2623 if (Func) 2795 if (Func)
2624 Base->dump(Func); 2796 Base->dump(Func);
2625 else 2797 else
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2705 x86::Address VariableSplit::toAsmAddress(const Cfg *Func) const { 2877 x86::Address VariableSplit::toAsmAddress(const Cfg *Func) const {
2706 assert(!Var->hasReg()); 2878 assert(!Var->hasReg());
2707 const TargetLowering *Target = Func->getTarget(); 2879 const TargetLowering *Target = Func->getTarget();
2708 int32_t Offset = 2880 int32_t Offset =
2709 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); 2881 Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
2710 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), 2882 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()),
2711 Offset); 2883 Offset);
2712 } 2884 }
2713 2885
2714 void VariableSplit::emit(const Cfg *Func) const { 2886 void VariableSplit::emit(const Cfg *Func) const {
2887 if (!ALLOW_DUMP)
2888 return;
2715 Ostream &Str = Func->getContext()->getStrEmit(); 2889 Ostream &Str = Func->getContext()->getStrEmit();
2716 assert(!Var->hasReg()); 2890 assert(!Var->hasReg());
2717 // The following is copied/adapted from TargetX8632::emitVariable(). 2891 // The following is copied/adapted from TargetX8632::emitVariable().
2718 const TargetLowering *Target = Func->getTarget(); 2892 const TargetLowering *Target = Func->getTarget();
2719 const Type Ty = IceType_i32; 2893 const Type Ty = IceType_i32;
2720 int32_t Offset = 2894 int32_t Offset =
2721 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); 2895 Var->getStackOffset() + Target->getStackAdjustment() + getOffset();
2722 if (Offset) 2896 if (Offset)
2723 Str << Offset; 2897 Str << Offset;
2724 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; 2898 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")";
2725 } 2899 }
2726 2900
2727 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { 2901 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const {
2902 if (!ALLOW_DUMP)
2903 return;
2728 switch (Part) { 2904 switch (Part) {
2729 case Low: 2905 case Low:
2730 Str << "low"; 2906 Str << "low";
2731 break; 2907 break;
2732 case High: 2908 case High:
2733 Str << "high"; 2909 Str << "high";
2734 break; 2910 break;
2735 default: 2911 default:
2736 Str << "???"; 2912 Str << "???";
2737 break; 2913 break;
2738 } 2914 }
2739 Str << "("; 2915 Str << "(";
2740 if (Func) 2916 if (Func)
2741 Var->dump(Func); 2917 Var->dump(Func);
2742 else 2918 else
2743 Var->dump(Str); 2919 Var->dump(Str);
2744 Str << ")"; 2920 Str << ")";
2745 } 2921 }
2746 2922
2747 } // end of namespace Ice 2923 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceOperand.h » ('j') | tests_lit/reader_tests/alloca.ll » ('J')

Powered by Google App Engine
This is Rietveld 408576698