OLD | NEW |
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |