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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 | 364 |
365 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) | 365 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) |
366 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { | 366 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { |
367 addSource(Dest); | 367 addSource(Dest); |
368 addSource(Source); | 368 addSource(Source); |
369 } | 369 } |
370 | 370 |
371 // ======================== Dump routines ======================== // | 371 // ======================== Dump routines ======================== // |
372 | 372 |
373 void InstX8632::dump(const Cfg *Func) const { | 373 void InstX8632::dump(const Cfg *Func) const { |
374 if (!ALLOW_DUMP) | 374 if (!buildAllowsDump()) |
375 return; | 375 return; |
376 Ostream &Str = Func->getContext()->getStrDump(); | 376 Ostream &Str = Func->getContext()->getStrDump(); |
377 Str << "[X8632] "; | 377 Str << "[X8632] "; |
378 Inst::dump(Func); | 378 Inst::dump(Func); |
379 } | 379 } |
380 | 380 |
381 void InstX8632FakeRMW::dump(const Cfg *Func) const { | 381 void InstX8632FakeRMW::dump(const Cfg *Func) const { |
382 if (!ALLOW_DUMP) | 382 if (!buildAllowsDump()) |
383 return; | 383 return; |
384 Ostream &Str = Func->getContext()->getStrDump(); | 384 Ostream &Str = Func->getContext()->getStrDump(); |
385 Type Ty = getData()->getType(); | 385 Type Ty = getData()->getType(); |
386 Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *"; | 386 Str << "rmw " << InstArithmetic::getOpName(getOp()) << " " << Ty << " *"; |
387 getAddr()->dump(Func); | 387 getAddr()->dump(Func); |
388 Str << ", "; | 388 Str << ", "; |
389 getData()->dump(Func); | 389 getData()->dump(Func); |
390 Str << ", beacon="; | 390 Str << ", beacon="; |
391 getBeacon()->dump(Func); | 391 getBeacon()->dump(Func); |
392 } | 392 } |
393 | 393 |
394 void InstX8632Label::emit(const Cfg *Func) const { | 394 void InstX8632Label::emit(const Cfg *Func) const { |
395 if (!ALLOW_DUMP) | 395 if (!buildAllowsDump()) |
396 return; | 396 return; |
397 Ostream &Str = Func->getContext()->getStrEmit(); | 397 Ostream &Str = Func->getContext()->getStrEmit(); |
398 Str << getName(Func) << ":"; | 398 Str << getName(Func) << ":"; |
399 } | 399 } |
400 | 400 |
401 void InstX8632Label::emitIAS(const Cfg *Func) const { | 401 void InstX8632Label::emitIAS(const Cfg *Func) const { |
402 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 402 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
403 Asm->BindLocalLabel(Number); | 403 Asm->BindLocalLabel(Number); |
404 } | 404 } |
405 | 405 |
406 void InstX8632Label::dump(const Cfg *Func) const { | 406 void InstX8632Label::dump(const Cfg *Func) const { |
407 if (!ALLOW_DUMP) | 407 if (!buildAllowsDump()) |
408 return; | 408 return; |
409 Ostream &Str = Func->getContext()->getStrDump(); | 409 Ostream &Str = Func->getContext()->getStrDump(); |
410 Str << getName(Func) << ":"; | 410 Str << getName(Func) << ":"; |
411 } | 411 } |
412 | 412 |
413 void InstX8632Br::emit(const Cfg *Func) const { | 413 void InstX8632Br::emit(const Cfg *Func) const { |
414 if (!ALLOW_DUMP) | 414 if (!buildAllowsDump()) |
415 return; | 415 return; |
416 Ostream &Str = Func->getContext()->getStrEmit(); | 416 Ostream &Str = Func->getContext()->getStrEmit(); |
417 Str << "\t"; | 417 Str << "\t"; |
418 | 418 |
419 if (Condition == CondX86::Br_None) { | 419 if (Condition == CondX86::Br_None) { |
420 Str << "jmp"; | 420 Str << "jmp"; |
421 } else { | 421 } else { |
422 Str << InstX8632BrAttributes[Condition].EmitString; | 422 Str << InstX8632BrAttributes[Condition].EmitString; |
423 } | 423 } |
424 | 424 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 if (getTargetFalse()) { | 463 if (getTargetFalse()) { |
464 X8632::Label *L2 = | 464 X8632::Label *L2 = |
465 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); | 465 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); |
466 Asm->jmp(L2, Near); | 466 Asm->jmp(L2, Near); |
467 } | 467 } |
468 } | 468 } |
469 } | 469 } |
470 } | 470 } |
471 | 471 |
472 void InstX8632Br::dump(const Cfg *Func) const { | 472 void InstX8632Br::dump(const Cfg *Func) const { |
473 if (!ALLOW_DUMP) | 473 if (!buildAllowsDump()) |
474 return; | 474 return; |
475 Ostream &Str = Func->getContext()->getStrDump(); | 475 Ostream &Str = Func->getContext()->getStrDump(); |
476 Str << "br "; | 476 Str << "br "; |
477 | 477 |
478 if (Condition == CondX86::Br_None) { | 478 if (Condition == CondX86::Br_None) { |
479 Str << "label %" | 479 Str << "label %" |
480 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); | 480 << (Label ? Label->getName(Func) : getTargetFalse()->getName()); |
481 return; | 481 return; |
482 } | 482 } |
483 | 483 |
484 Str << InstX8632BrAttributes[Condition].DisplayString; | 484 Str << InstX8632BrAttributes[Condition].DisplayString; |
485 if (Label) { | 485 if (Label) { |
486 Str << ", label %" << Label->getName(Func); | 486 Str << ", label %" << Label->getName(Func); |
487 } else { | 487 } else { |
488 Str << ", label %" << getTargetTrue()->getName(); | 488 Str << ", label %" << getTargetTrue()->getName(); |
489 if (getTargetFalse()) { | 489 if (getTargetFalse()) { |
490 Str << ", label %" << getTargetFalse()->getName(); | 490 Str << ", label %" << getTargetFalse()->getName(); |
491 } | 491 } |
492 } | 492 } |
493 } | 493 } |
494 | 494 |
495 void InstX8632Jmp::emit(const Cfg *Func) const { | 495 void InstX8632Jmp::emit(const Cfg *Func) const { |
496 if (!ALLOW_DUMP) | 496 if (!buildAllowsDump()) |
497 return; | 497 return; |
498 Ostream &Str = Func->getContext()->getStrEmit(); | 498 Ostream &Str = Func->getContext()->getStrEmit(); |
499 assert(getSrcSize() == 1); | 499 assert(getSrcSize() == 1); |
500 Str << "\tjmp\t*"; | 500 Str << "\tjmp\t*"; |
501 getJmpTarget()->emit(Func); | 501 getJmpTarget()->emit(Func); |
502 } | 502 } |
503 | 503 |
504 void InstX8632Jmp::emitIAS(const Cfg *Func) const { | 504 void InstX8632Jmp::emitIAS(const Cfg *Func) const { |
505 // Note: Adapted (mostly copied) from InstX8632Call::emitIAS(). | 505 // Note: Adapted (mostly copied) from InstX8632Call::emitIAS(). |
506 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 506 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
(...skipping 24 matching lines...) Expand all Loading... |
531 // TODO(jvoung): Support this when there is a lowering that | 531 // TODO(jvoung): Support this when there is a lowering that |
532 // actually triggers this case. | 532 // actually triggers this case. |
533 (void)Imm; | 533 (void)Imm; |
534 llvm::report_fatal_error("Unexpected jmp to absolute address"); | 534 llvm::report_fatal_error("Unexpected jmp to absolute address"); |
535 } else { | 535 } else { |
536 llvm::report_fatal_error("Unexpected operand type"); | 536 llvm::report_fatal_error("Unexpected operand type"); |
537 } | 537 } |
538 } | 538 } |
539 | 539 |
540 void InstX8632Jmp::dump(const Cfg *Func) const { | 540 void InstX8632Jmp::dump(const Cfg *Func) const { |
541 if (!ALLOW_DUMP) | 541 if (!buildAllowsDump()) |
542 return; | 542 return; |
543 Ostream &Str = Func->getContext()->getStrDump(); | 543 Ostream &Str = Func->getContext()->getStrDump(); |
544 Str << "jmp "; | 544 Str << "jmp "; |
545 getJmpTarget()->dump(Func); | 545 getJmpTarget()->dump(Func); |
546 } | 546 } |
547 | 547 |
548 void InstX8632Call::emit(const Cfg *Func) const { | 548 void InstX8632Call::emit(const Cfg *Func) const { |
549 if (!ALLOW_DUMP) | 549 if (!buildAllowsDump()) |
550 return; | 550 return; |
551 Ostream &Str = Func->getContext()->getStrEmit(); | 551 Ostream &Str = Func->getContext()->getStrEmit(); |
552 assert(getSrcSize() == 1); | 552 assert(getSrcSize() == 1); |
553 Str << "\tcall\t"; | 553 Str << "\tcall\t"; |
554 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) { | 554 if (const auto CI = llvm::dyn_cast<ConstantInteger32>(getCallTarget())) { |
555 // Emit without a leading '$'. | 555 // Emit without a leading '$'. |
556 Str << CI->getValue(); | 556 Str << CI->getValue(); |
557 } else if (const auto CallTarget = | 557 } else if (const auto CallTarget = |
558 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { | 558 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { |
559 CallTarget->emitWithoutPrefix(Func->getTarget()); | 559 CallTarget->emitWithoutPrefix(Func->getTarget()); |
(...skipping 22 matching lines...) Expand all Loading... |
582 Asm->call(CR); | 582 Asm->call(CR); |
583 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { | 583 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { |
584 Asm->call(X8632::Immediate(Imm->getValue())); | 584 Asm->call(X8632::Immediate(Imm->getValue())); |
585 } else { | 585 } else { |
586 llvm_unreachable("Unexpected operand type"); | 586 llvm_unreachable("Unexpected operand type"); |
587 } | 587 } |
588 Func->getTarget()->resetStackAdjustment(); | 588 Func->getTarget()->resetStackAdjustment(); |
589 } | 589 } |
590 | 590 |
591 void InstX8632Call::dump(const Cfg *Func) const { | 591 void InstX8632Call::dump(const Cfg *Func) const { |
592 if (!ALLOW_DUMP) | 592 if (!buildAllowsDump()) |
593 return; | 593 return; |
594 Ostream &Str = Func->getContext()->getStrDump(); | 594 Ostream &Str = Func->getContext()->getStrDump(); |
595 if (getDest()) { | 595 if (getDest()) { |
596 dumpDest(Func); | 596 dumpDest(Func); |
597 Str << " = "; | 597 Str << " = "; |
598 } | 598 } |
599 Str << "call "; | 599 Str << "call "; |
600 getCallTarget()->dump(Func); | 600 getCallTarget()->dump(Func); |
601 } | 601 } |
602 | 602 |
603 // The ShiftHack parameter is used to emit "cl" instead of "ecx" for | 603 // The ShiftHack parameter is used to emit "cl" instead of "ecx" for |
604 // shift instructions, in order to be syntactically valid. The | 604 // shift instructions, in order to be syntactically valid. The |
605 // Opcode parameter needs to be char* and not IceString because of | 605 // Opcode parameter needs to be char* and not IceString because of |
606 // template issues. | 606 // template issues. |
607 void InstX8632::emitTwoAddress(const char *Opcode, const Inst *Inst, | 607 void InstX8632::emitTwoAddress(const char *Opcode, const Inst *Inst, |
608 const Cfg *Func, bool ShiftHack) { | 608 const Cfg *Func, bool ShiftHack) { |
609 if (!ALLOW_DUMP) | 609 if (!buildAllowsDump()) |
610 return; | 610 return; |
611 Ostream &Str = Func->getContext()->getStrEmit(); | 611 Ostream &Str = Func->getContext()->getStrEmit(); |
612 assert(Inst->getSrcSize() == 2); | 612 assert(Inst->getSrcSize() == 2); |
613 Operand *Dest = Inst->getDest(); | 613 Operand *Dest = Inst->getDest(); |
614 if (Dest == nullptr) | 614 if (Dest == nullptr) |
615 Dest = Inst->getSrc(0); | 615 Dest = Inst->getSrc(0); |
616 assert(Dest == Inst->getSrc(0)); | 616 assert(Dest == Inst->getSrc(0)); |
617 Operand *Src1 = Inst->getSrc(1); | 617 Operand *Src1 = Inst->getSrc(1); |
618 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t"; | 618 Str << "\t" << Opcode << InstX8632::getWidthString(Dest->getType()) << "\t"; |
619 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); | 619 const auto ShiftReg = llvm::dyn_cast<Variable>(Src1); |
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 template <> | 1147 template <> |
1148 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psra::Emitter = { | 1148 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psra::Emitter = { |
1149 &X8632::AssemblerX8632::psra, &X8632::AssemblerX8632::psra, | 1149 &X8632::AssemblerX8632::psra, &X8632::AssemblerX8632::psra, |
1150 &X8632::AssemblerX8632::psra}; | 1150 &X8632::AssemblerX8632::psra}; |
1151 template <> | 1151 template <> |
1152 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psrl::Emitter = { | 1152 const X8632::AssemblerX8632::XmmEmitterShiftOp InstX8632Psrl::Emitter = { |
1153 &X8632::AssemblerX8632::psrl, &X8632::AssemblerX8632::psrl, | 1153 &X8632::AssemblerX8632::psrl, &X8632::AssemblerX8632::psrl, |
1154 &X8632::AssemblerX8632::psrl}; | 1154 &X8632::AssemblerX8632::psrl}; |
1155 | 1155 |
1156 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { | 1156 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { |
1157 if (!ALLOW_DUMP) | 1157 if (!buildAllowsDump()) |
1158 return; | 1158 return; |
1159 Ostream &Str = Func->getContext()->getStrEmit(); | 1159 Ostream &Str = Func->getContext()->getStrEmit(); |
1160 assert(getSrcSize() == 1); | 1160 assert(getSrcSize() == 1); |
1161 Type Ty = getSrc(0)->getType(); | 1161 Type Ty = getSrc(0)->getType(); |
1162 assert(isScalarFloatingType(Ty)); | 1162 assert(isScalarFloatingType(Ty)); |
1163 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 1163 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; |
1164 getSrc(0)->emit(Func); | 1164 getSrc(0)->emit(Func); |
1165 Str << ", "; | 1165 Str << ", "; |
1166 getDest()->emit(Func); | 1166 getDest()->emit(Func); |
1167 } | 1167 } |
1168 | 1168 |
1169 template <> void InstX8632Addss::emit(const Cfg *Func) const { | 1169 template <> void InstX8632Addss::emit(const Cfg *Func) const { |
1170 if (!ALLOW_DUMP) | 1170 if (!buildAllowsDump()) |
1171 return; | 1171 return; |
1172 char buf[30]; | 1172 char buf[30]; |
1173 snprintf(buf, llvm::array_lengthof(buf), "add%s", | 1173 snprintf(buf, llvm::array_lengthof(buf), "add%s", |
1174 TypeX8632Attributes[getDest()->getType()].SdSsString); | 1174 TypeX8632Attributes[getDest()->getType()].SdSsString); |
1175 emitTwoAddress(buf, this, Func); | 1175 emitTwoAddress(buf, this, Func); |
1176 } | 1176 } |
1177 | 1177 |
1178 template <> void InstX8632Padd::emit(const Cfg *Func) const { | 1178 template <> void InstX8632Padd::emit(const Cfg *Func) const { |
1179 if (!ALLOW_DUMP) | 1179 if (!buildAllowsDump()) |
1180 return; | 1180 return; |
1181 char buf[30]; | 1181 char buf[30]; |
1182 snprintf(buf, llvm::array_lengthof(buf), "padd%s", | 1182 snprintf(buf, llvm::array_lengthof(buf), "padd%s", |
1183 TypeX8632Attributes[getDest()->getType()].PackString); | 1183 TypeX8632Attributes[getDest()->getType()].PackString); |
1184 emitTwoAddress(buf, this, Func); | 1184 emitTwoAddress(buf, this, Func); |
1185 } | 1185 } |
1186 | 1186 |
1187 template <> void InstX8632Pmull::emit(const Cfg *Func) const { | 1187 template <> void InstX8632Pmull::emit(const Cfg *Func) const { |
1188 if (!ALLOW_DUMP) | 1188 if (!buildAllowsDump()) |
1189 return; | 1189 return; |
1190 char buf[30]; | 1190 char buf[30]; |
1191 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || | 1191 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || |
1192 getDest()->getType() == IceType_v8i16; | 1192 getDest()->getType() == IceType_v8i16; |
1193 bool InstructionSetIsValid = | 1193 bool InstructionSetIsValid = |
1194 getDest()->getType() == IceType_v8i16 || | 1194 getDest()->getType() == IceType_v8i16 || |
1195 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1195 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
1196 TargetX8632::SSE4_1; | 1196 TargetX8632::SSE4_1; |
1197 (void)TypesAreValid; | 1197 (void)TypesAreValid; |
1198 (void)InstructionSetIsValid; | 1198 (void)InstructionSetIsValid; |
(...skipping 14 matching lines...) Expand all Loading... |
1213 (void)TypesAreValid; | 1213 (void)TypesAreValid; |
1214 (void)InstructionSetIsValid; | 1214 (void)InstructionSetIsValid; |
1215 assert(TypesAreValid); | 1215 assert(TypesAreValid); |
1216 assert(InstructionSetIsValid); | 1216 assert(InstructionSetIsValid); |
1217 assert(getSrcSize() == 2); | 1217 assert(getSrcSize() == 2); |
1218 Type ElementTy = typeElementType(Ty); | 1218 Type ElementTy = typeElementType(Ty); |
1219 emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); | 1219 emitIASRegOpTyXMM(Func, ElementTy, getDest(), getSrc(1), Emitter); |
1220 } | 1220 } |
1221 | 1221 |
1222 template <> void InstX8632Subss::emit(const Cfg *Func) const { | 1222 template <> void InstX8632Subss::emit(const Cfg *Func) const { |
1223 if (!ALLOW_DUMP) | 1223 if (!buildAllowsDump()) |
1224 return; | 1224 return; |
1225 char buf[30]; | 1225 char buf[30]; |
1226 snprintf(buf, llvm::array_lengthof(buf), "sub%s", | 1226 snprintf(buf, llvm::array_lengthof(buf), "sub%s", |
1227 TypeX8632Attributes[getDest()->getType()].SdSsString); | 1227 TypeX8632Attributes[getDest()->getType()].SdSsString); |
1228 emitTwoAddress(buf, this, Func); | 1228 emitTwoAddress(buf, this, Func); |
1229 } | 1229 } |
1230 | 1230 |
1231 template <> void InstX8632Psub::emit(const Cfg *Func) const { | 1231 template <> void InstX8632Psub::emit(const Cfg *Func) const { |
1232 if (!ALLOW_DUMP) | 1232 if (!buildAllowsDump()) |
1233 return; | 1233 return; |
1234 char buf[30]; | 1234 char buf[30]; |
1235 snprintf(buf, llvm::array_lengthof(buf), "psub%s", | 1235 snprintf(buf, llvm::array_lengthof(buf), "psub%s", |
1236 TypeX8632Attributes[getDest()->getType()].PackString); | 1236 TypeX8632Attributes[getDest()->getType()].PackString); |
1237 emitTwoAddress(buf, this, Func); | 1237 emitTwoAddress(buf, this, Func); |
1238 } | 1238 } |
1239 | 1239 |
1240 template <> void InstX8632Mulss::emit(const Cfg *Func) const { | 1240 template <> void InstX8632Mulss::emit(const Cfg *Func) const { |
1241 if (!ALLOW_DUMP) | 1241 if (!buildAllowsDump()) |
1242 return; | 1242 return; |
1243 char buf[30]; | 1243 char buf[30]; |
1244 snprintf(buf, llvm::array_lengthof(buf), "mul%s", | 1244 snprintf(buf, llvm::array_lengthof(buf), "mul%s", |
1245 TypeX8632Attributes[getDest()->getType()].SdSsString); | 1245 TypeX8632Attributes[getDest()->getType()].SdSsString); |
1246 emitTwoAddress(buf, this, Func); | 1246 emitTwoAddress(buf, this, Func); |
1247 } | 1247 } |
1248 | 1248 |
1249 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const { | 1249 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const { |
1250 if (!ALLOW_DUMP) | 1250 if (!buildAllowsDump()) |
1251 return; | 1251 return; |
1252 assert(getSrc(0)->getType() == IceType_v4i32 && | 1252 assert(getSrc(0)->getType() == IceType_v4i32 && |
1253 getSrc(1)->getType() == IceType_v4i32); | 1253 getSrc(1)->getType() == IceType_v4i32); |
1254 emitTwoAddress(Opcode, this, Func); | 1254 emitTwoAddress(Opcode, this, Func); |
1255 } | 1255 } |
1256 | 1256 |
1257 template <> void InstX8632Divss::emit(const Cfg *Func) const { | 1257 template <> void InstX8632Divss::emit(const Cfg *Func) const { |
1258 if (!ALLOW_DUMP) | 1258 if (!buildAllowsDump()) |
1259 return; | 1259 return; |
1260 char buf[30]; | 1260 char buf[30]; |
1261 snprintf(buf, llvm::array_lengthof(buf), "div%s", | 1261 snprintf(buf, llvm::array_lengthof(buf), "div%s", |
1262 TypeX8632Attributes[getDest()->getType()].SdSsString); | 1262 TypeX8632Attributes[getDest()->getType()].SdSsString); |
1263 emitTwoAddress(buf, this, Func); | 1263 emitTwoAddress(buf, this, Func); |
1264 } | 1264 } |
1265 | 1265 |
1266 template <> void InstX8632Div::emit(const Cfg *Func) const { | 1266 template <> void InstX8632Div::emit(const Cfg *Func) const { |
1267 if (!ALLOW_DUMP) | 1267 if (!buildAllowsDump()) |
1268 return; | 1268 return; |
1269 Ostream &Str = Func->getContext()->getStrEmit(); | 1269 Ostream &Str = Func->getContext()->getStrEmit(); |
1270 assert(getSrcSize() == 3); | 1270 assert(getSrcSize() == 3); |
1271 Operand *Src1 = getSrc(1); | 1271 Operand *Src1 = getSrc(1); |
1272 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; | 1272 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; |
1273 Src1->emit(Func); | 1273 Src1->emit(Func); |
1274 } | 1274 } |
1275 | 1275 |
1276 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { | 1276 template <> void InstX8632Div::emitIAS(const Cfg *Func) const { |
1277 assert(getSrcSize() == 3); | 1277 assert(getSrcSize() == 3); |
1278 const Operand *Src = getSrc(1); | 1278 const Operand *Src = getSrc(1); |
1279 Type Ty = Src->getType(); | 1279 Type Ty = Src->getType(); |
1280 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { | 1280 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
1281 &X8632::AssemblerX8632::div, &X8632::AssemblerX8632::div}; | 1281 &X8632::AssemblerX8632::div, &X8632::AssemblerX8632::div}; |
1282 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1282 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
1283 } | 1283 } |
1284 | 1284 |
1285 template <> void InstX8632Idiv::emit(const Cfg *Func) const { | 1285 template <> void InstX8632Idiv::emit(const Cfg *Func) const { |
1286 if (!ALLOW_DUMP) | 1286 if (!buildAllowsDump()) |
1287 return; | 1287 return; |
1288 Ostream &Str = Func->getContext()->getStrEmit(); | 1288 Ostream &Str = Func->getContext()->getStrEmit(); |
1289 assert(getSrcSize() == 3); | 1289 assert(getSrcSize() == 3); |
1290 Operand *Src1 = getSrc(1); | 1290 Operand *Src1 = getSrc(1); |
1291 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; | 1291 Str << "\t" << Opcode << getWidthString(Src1->getType()) << "\t"; |
1292 Src1->emit(Func); | 1292 Src1->emit(Func); |
1293 } | 1293 } |
1294 | 1294 |
1295 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { | 1295 template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const { |
1296 assert(getSrcSize() == 3); | 1296 assert(getSrcSize() == 3); |
1297 const Operand *Src = getSrc(1); | 1297 const Operand *Src = getSrc(1); |
1298 Type Ty = Src->getType(); | 1298 Type Ty = Src->getType(); |
1299 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { | 1299 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
1300 &X8632::AssemblerX8632::idiv, &X8632::AssemblerX8632::idiv}; | 1300 &X8632::AssemblerX8632::idiv, &X8632::AssemblerX8632::idiv}; |
1301 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1301 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
1302 } | 1302 } |
1303 | 1303 |
1304 namespace { | 1304 namespace { |
1305 | 1305 |
1306 // pblendvb and blendvps take xmm0 as a final implicit argument. | 1306 // pblendvb and blendvps take xmm0 as a final implicit argument. |
1307 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, | 1307 void emitVariableBlendInst(const char *Opcode, const Inst *Inst, |
1308 const Cfg *Func) { | 1308 const Cfg *Func) { |
1309 if (!ALLOW_DUMP) | 1309 if (!buildAllowsDump()) |
1310 return; | 1310 return; |
1311 Ostream &Str = Func->getContext()->getStrEmit(); | 1311 Ostream &Str = Func->getContext()->getStrEmit(); |
1312 assert(Inst->getSrcSize() == 3); | 1312 assert(Inst->getSrcSize() == 3); |
1313 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 1313 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == |
1314 RegX8632::Reg_xmm0); | 1314 RegX8632::Reg_xmm0); |
1315 Str << "\t" << Opcode << "\t"; | 1315 Str << "\t" << Opcode << "\t"; |
1316 Inst->getSrc(1)->emit(Func); | 1316 Inst->getSrc(1)->emit(Func); |
1317 Str << ", "; | 1317 Str << ", "; |
1318 Inst->getDest()->emit(Func); | 1318 Inst->getDest()->emit(Func); |
1319 } | 1319 } |
1320 | 1320 |
1321 void emitIASVariableBlendInst( | 1321 void emitIASVariableBlendInst( |
1322 const Inst *Inst, const Cfg *Func, | 1322 const Inst *Inst, const Cfg *Func, |
1323 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) { | 1323 const X8632::AssemblerX8632::XmmEmitterRegOp &Emitter) { |
1324 assert(Inst->getSrcSize() == 3); | 1324 assert(Inst->getSrcSize() == 3); |
1325 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == | 1325 assert(llvm::cast<Variable>(Inst->getSrc(2))->getRegNum() == |
1326 RegX8632::Reg_xmm0); | 1326 RegX8632::Reg_xmm0); |
1327 const Variable *Dest = Inst->getDest(); | 1327 const Variable *Dest = Inst->getDest(); |
1328 const Operand *Src = Inst->getSrc(1); | 1328 const Operand *Src = Inst->getSrc(1); |
1329 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); | 1329 emitIASRegOpTyXMM(Func, Dest->getType(), Dest, Src, Emitter); |
1330 } | 1330 } |
1331 | 1331 |
1332 } // end anonymous namespace | 1332 } // end anonymous namespace |
1333 | 1333 |
1334 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { | 1334 template <> void InstX8632Blendvps::emit(const Cfg *Func) const { |
1335 if (!ALLOW_DUMP) | 1335 if (!buildAllowsDump()) |
1336 return; | 1336 return; |
1337 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1337 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
1338 TargetX8632::SSE4_1); | 1338 TargetX8632::SSE4_1); |
1339 emitVariableBlendInst(Opcode, this, Func); | 1339 emitVariableBlendInst(Opcode, this, Func); |
1340 } | 1340 } |
1341 | 1341 |
1342 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { | 1342 template <> void InstX8632Blendvps::emitIAS(const Cfg *Func) const { |
1343 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1343 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
1344 TargetX8632::SSE4_1); | 1344 TargetX8632::SSE4_1); |
1345 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { | 1345 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
1346 &X8632::AssemblerX8632::blendvps, &X8632::AssemblerX8632::blendvps}; | 1346 &X8632::AssemblerX8632::blendvps, &X8632::AssemblerX8632::blendvps}; |
1347 emitIASVariableBlendInst(this, Func, Emitter); | 1347 emitIASVariableBlendInst(this, Func, Emitter); |
1348 } | 1348 } |
1349 | 1349 |
1350 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { | 1350 template <> void InstX8632Pblendvb::emit(const Cfg *Func) const { |
1351 if (!ALLOW_DUMP) | 1351 if (!buildAllowsDump()) |
1352 return; | 1352 return; |
1353 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1353 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
1354 TargetX8632::SSE4_1); | 1354 TargetX8632::SSE4_1); |
1355 emitVariableBlendInst(Opcode, this, Func); | 1355 emitVariableBlendInst(Opcode, this, Func); |
1356 } | 1356 } |
1357 | 1357 |
1358 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { | 1358 template <> void InstX8632Pblendvb::emitIAS(const Cfg *Func) const { |
1359 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 1359 assert(static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
1360 TargetX8632::SSE4_1); | 1360 TargetX8632::SSE4_1); |
1361 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { | 1361 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
1362 &X8632::AssemblerX8632::pblendvb, &X8632::AssemblerX8632::pblendvb}; | 1362 &X8632::AssemblerX8632::pblendvb, &X8632::AssemblerX8632::pblendvb}; |
1363 emitIASVariableBlendInst(this, Func, Emitter); | 1363 emitIASVariableBlendInst(this, Func, Emitter); |
1364 } | 1364 } |
1365 | 1365 |
1366 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 1366 template <> void InstX8632Imul::emit(const Cfg *Func) const { |
1367 if (!ALLOW_DUMP) | 1367 if (!buildAllowsDump()) |
1368 return; | 1368 return; |
1369 Ostream &Str = Func->getContext()->getStrEmit(); | 1369 Ostream &Str = Func->getContext()->getStrEmit(); |
1370 assert(getSrcSize() == 2); | 1370 assert(getSrcSize() == 2); |
1371 Variable *Dest = getDest(); | 1371 Variable *Dest = getDest(); |
1372 if (isByteSizedArithType(Dest->getType())) { | 1372 if (isByteSizedArithType(Dest->getType())) { |
1373 // The 8-bit version of imul only allows the form "imul r/m8". | 1373 // The 8-bit version of imul only allows the form "imul r/m8". |
1374 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); | 1374 const auto Src0Var = llvm::dyn_cast<Variable>(getSrc(0)); |
1375 (void)Src0Var; | 1375 (void)Src0Var; |
1376 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); | 1376 assert(Src0Var && Src0Var->getRegNum() == RegX8632::Reg_eax); |
1377 Str << "\timulb\t"; | 1377 Str << "\timulb\t"; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 Type Ty = Dest->getType(); | 1421 Type Ty = Dest->getType(); |
1422 static const X8632::AssemblerX8632::ThreeOpImmEmitter< | 1422 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
1423 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 1423 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
1424 &X8632::AssemblerX8632::insertps, &X8632::AssemblerX8632::insertps}; | 1424 &X8632::AssemblerX8632::insertps, &X8632::AssemblerX8632::insertps}; |
1425 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 1425 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
1426 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 1426 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
1427 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 1427 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); |
1428 } | 1428 } |
1429 | 1429 |
1430 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { | 1430 template <> void InstX8632Cbwdq::emit(const Cfg *Func) const { |
1431 if (!ALLOW_DUMP) | 1431 if (!buildAllowsDump()) |
1432 return; | 1432 return; |
1433 Ostream &Str = Func->getContext()->getStrEmit(); | 1433 Ostream &Str = Func->getContext()->getStrEmit(); |
1434 assert(getSrcSize() == 1); | 1434 assert(getSrcSize() == 1); |
1435 Operand *Src0 = getSrc(0); | 1435 Operand *Src0 = getSrc(0); |
1436 assert(llvm::isa<Variable>(Src0)); | 1436 assert(llvm::isa<Variable>(Src0)); |
1437 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); | 1437 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); |
1438 switch (Src0->getType()) { | 1438 switch (Src0->getType()) { |
1439 default: | 1439 default: |
1440 llvm_unreachable("unexpected source type!"); | 1440 llvm_unreachable("unexpected source type!"); |
1441 break; | 1441 break; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1473 Asm->cwd(); | 1473 Asm->cwd(); |
1474 break; | 1474 break; |
1475 case IceType_i32: | 1475 case IceType_i32: |
1476 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1476 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
1477 Asm->cdq(); | 1477 Asm->cdq(); |
1478 break; | 1478 break; |
1479 } | 1479 } |
1480 } | 1480 } |
1481 | 1481 |
1482 void InstX8632Mul::emit(const Cfg *Func) const { | 1482 void InstX8632Mul::emit(const Cfg *Func) const { |
1483 if (!ALLOW_DUMP) | 1483 if (!buildAllowsDump()) |
1484 return; | 1484 return; |
1485 Ostream &Str = Func->getContext()->getStrEmit(); | 1485 Ostream &Str = Func->getContext()->getStrEmit(); |
1486 assert(getSrcSize() == 2); | 1486 assert(getSrcSize() == 2); |
1487 assert(llvm::isa<Variable>(getSrc(0))); | 1487 assert(llvm::isa<Variable>(getSrc(0))); |
1488 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1488 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
1489 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1489 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
1490 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t"; | 1490 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t"; |
1491 getSrc(1)->emit(Func); | 1491 getSrc(1)->emit(Func); |
1492 } | 1492 } |
1493 | 1493 |
1494 void InstX8632Mul::emitIAS(const Cfg *Func) const { | 1494 void InstX8632Mul::emitIAS(const Cfg *Func) const { |
1495 assert(getSrcSize() == 2); | 1495 assert(getSrcSize() == 2); |
1496 assert(llvm::isa<Variable>(getSrc(0))); | 1496 assert(llvm::isa<Variable>(getSrc(0))); |
1497 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1497 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
1498 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1498 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
1499 const Operand *Src = getSrc(1); | 1499 const Operand *Src = getSrc(1); |
1500 Type Ty = Src->getType(); | 1500 Type Ty = Src->getType(); |
1501 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { | 1501 const static X8632::AssemblerX8632::GPREmitterOneOp Emitter = { |
1502 &X8632::AssemblerX8632::mul, &X8632::AssemblerX8632::mul}; | 1502 &X8632::AssemblerX8632::mul, &X8632::AssemblerX8632::mul}; |
1503 emitIASOpTyGPR(Func, Ty, Src, Emitter); | 1503 emitIASOpTyGPR(Func, Ty, Src, Emitter); |
1504 } | 1504 } |
1505 | 1505 |
1506 void InstX8632Mul::dump(const Cfg *Func) const { | 1506 void InstX8632Mul::dump(const Cfg *Func) const { |
1507 if (!ALLOW_DUMP) | 1507 if (!buildAllowsDump()) |
1508 return; | 1508 return; |
1509 Ostream &Str = Func->getContext()->getStrDump(); | 1509 Ostream &Str = Func->getContext()->getStrDump(); |
1510 dumpDest(Func); | 1510 dumpDest(Func); |
1511 Str << " = mul." << getDest()->getType() << " "; | 1511 Str << " = mul." << getDest()->getType() << " "; |
1512 dumpSources(Func); | 1512 dumpSources(Func); |
1513 } | 1513 } |
1514 | 1514 |
1515 void InstX8632Shld::emit(const Cfg *Func) const { | 1515 void InstX8632Shld::emit(const Cfg *Func) const { |
1516 if (!ALLOW_DUMP) | 1516 if (!buildAllowsDump()) |
1517 return; | 1517 return; |
1518 Ostream &Str = Func->getContext()->getStrEmit(); | 1518 Ostream &Str = Func->getContext()->getStrEmit(); |
1519 Variable *Dest = getDest(); | 1519 Variable *Dest = getDest(); |
1520 assert(getSrcSize() == 3); | 1520 assert(getSrcSize() == 3); |
1521 assert(Dest == getSrc(0)); | 1521 assert(Dest == getSrc(0)); |
1522 Str << "\tshld" << getWidthString(Dest->getType()) << "\t"; | 1522 Str << "\tshld" << getWidthString(Dest->getType()) << "\t"; |
1523 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 1523 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
1524 (void)ShiftReg; | 1524 (void)ShiftReg; |
1525 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 1525 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); |
1526 Str << "%cl"; | 1526 Str << "%cl"; |
(...skipping 11 matching lines...) Expand all Loading... |
1538 assert(getDest() == getSrc(0)); | 1538 assert(getDest() == getSrc(0)); |
1539 const Variable *Dest = getDest(); | 1539 const Variable *Dest = getDest(); |
1540 const Operand *Src1 = getSrc(1); | 1540 const Operand *Src1 = getSrc(1); |
1541 const Operand *Src2 = getSrc(2); | 1541 const Operand *Src2 = getSrc(2); |
1542 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { | 1542 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { |
1543 &X8632::AssemblerX8632::shld, &X8632::AssemblerX8632::shld}; | 1543 &X8632::AssemblerX8632::shld, &X8632::AssemblerX8632::shld}; |
1544 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | 1544 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); |
1545 } | 1545 } |
1546 | 1546 |
1547 void InstX8632Shld::dump(const Cfg *Func) const { | 1547 void InstX8632Shld::dump(const Cfg *Func) const { |
1548 if (!ALLOW_DUMP) | 1548 if (!buildAllowsDump()) |
1549 return; | 1549 return; |
1550 Ostream &Str = Func->getContext()->getStrDump(); | 1550 Ostream &Str = Func->getContext()->getStrDump(); |
1551 dumpDest(Func); | 1551 dumpDest(Func); |
1552 Str << " = shld." << getDest()->getType() << " "; | 1552 Str << " = shld." << getDest()->getType() << " "; |
1553 dumpSources(Func); | 1553 dumpSources(Func); |
1554 } | 1554 } |
1555 | 1555 |
1556 void InstX8632Shrd::emit(const Cfg *Func) const { | 1556 void InstX8632Shrd::emit(const Cfg *Func) const { |
1557 if (!ALLOW_DUMP) | 1557 if (!buildAllowsDump()) |
1558 return; | 1558 return; |
1559 Ostream &Str = Func->getContext()->getStrEmit(); | 1559 Ostream &Str = Func->getContext()->getStrEmit(); |
1560 Variable *Dest = getDest(); | 1560 Variable *Dest = getDest(); |
1561 assert(getSrcSize() == 3); | 1561 assert(getSrcSize() == 3); |
1562 assert(Dest == getSrc(0)); | 1562 assert(Dest == getSrc(0)); |
1563 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t"; | 1563 Str << "\tshrd" << getWidthString(Dest->getType()) << "\t"; |
1564 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { | 1564 if (const auto ShiftReg = llvm::dyn_cast<Variable>(getSrc(2))) { |
1565 (void)ShiftReg; | 1565 (void)ShiftReg; |
1566 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); | 1566 assert(ShiftReg->getRegNum() == RegX8632::Reg_ecx); |
1567 Str << "%cl"; | 1567 Str << "%cl"; |
(...skipping 11 matching lines...) Expand all Loading... |
1579 assert(getDest() == getSrc(0)); | 1579 assert(getDest() == getSrc(0)); |
1580 const Variable *Dest = getDest(); | 1580 const Variable *Dest = getDest(); |
1581 const Operand *Src1 = getSrc(1); | 1581 const Operand *Src1 = getSrc(1); |
1582 const Operand *Src2 = getSrc(2); | 1582 const Operand *Src2 = getSrc(2); |
1583 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { | 1583 static const X8632::AssemblerX8632::GPREmitterShiftD Emitter = { |
1584 &X8632::AssemblerX8632::shrd, &X8632::AssemblerX8632::shrd}; | 1584 &X8632::AssemblerX8632::shrd, &X8632::AssemblerX8632::shrd}; |
1585 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); | 1585 emitIASGPRShiftDouble(Func, Dest, Src1, Src2, Emitter); |
1586 } | 1586 } |
1587 | 1587 |
1588 void InstX8632Shrd::dump(const Cfg *Func) const { | 1588 void InstX8632Shrd::dump(const Cfg *Func) const { |
1589 if (!ALLOW_DUMP) | 1589 if (!buildAllowsDump()) |
1590 return; | 1590 return; |
1591 Ostream &Str = Func->getContext()->getStrDump(); | 1591 Ostream &Str = Func->getContext()->getStrDump(); |
1592 dumpDest(Func); | 1592 dumpDest(Func); |
1593 Str << " = shrd." << getDest()->getType() << " "; | 1593 Str << " = shrd." << getDest()->getType() << " "; |
1594 dumpSources(Func); | 1594 dumpSources(Func); |
1595 } | 1595 } |
1596 | 1596 |
1597 void InstX8632Cmov::emit(const Cfg *Func) const { | 1597 void InstX8632Cmov::emit(const Cfg *Func) const { |
1598 if (!ALLOW_DUMP) | 1598 if (!buildAllowsDump()) |
1599 return; | 1599 return; |
1600 Ostream &Str = Func->getContext()->getStrEmit(); | 1600 Ostream &Str = Func->getContext()->getStrEmit(); |
1601 Variable *Dest = getDest(); | 1601 Variable *Dest = getDest(); |
1602 Str << "\t"; | 1602 Str << "\t"; |
1603 assert(Condition != CondX86::Br_None); | 1603 assert(Condition != CondX86::Br_None); |
1604 assert(getDest()->hasReg()); | 1604 assert(getDest()->hasReg()); |
1605 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString | 1605 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString |
1606 << getWidthString(Dest->getType()) << "\t"; | 1606 << getWidthString(Dest->getType()) << "\t"; |
1607 getSrc(1)->emit(Func); | 1607 getSrc(1)->emit(Func); |
1608 Str << ", "; | 1608 Str << ", "; |
(...skipping 22 matching lines...) Expand all Loading... |
1631 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 1631 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
1632 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1632 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1633 Asm->cmov(SrcTy, Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), | 1633 Asm->cmov(SrcTy, Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), |
1634 Mem->toAsmAddress(Asm)); | 1634 Mem->toAsmAddress(Asm)); |
1635 } else { | 1635 } else { |
1636 llvm_unreachable("Unexpected operand type"); | 1636 llvm_unreachable("Unexpected operand type"); |
1637 } | 1637 } |
1638 } | 1638 } |
1639 | 1639 |
1640 void InstX8632Cmov::dump(const Cfg *Func) const { | 1640 void InstX8632Cmov::dump(const Cfg *Func) const { |
1641 if (!ALLOW_DUMP) | 1641 if (!buildAllowsDump()) |
1642 return; | 1642 return; |
1643 Ostream &Str = Func->getContext()->getStrDump(); | 1643 Ostream &Str = Func->getContext()->getStrDump(); |
1644 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 1644 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
1645 Str << getDest()->getType() << " "; | 1645 Str << getDest()->getType() << " "; |
1646 dumpDest(Func); | 1646 dumpDest(Func); |
1647 Str << ", "; | 1647 Str << ", "; |
1648 dumpSources(Func); | 1648 dumpSources(Func); |
1649 } | 1649 } |
1650 | 1650 |
1651 void InstX8632Cmpps::emit(const Cfg *Func) const { | 1651 void InstX8632Cmpps::emit(const Cfg *Func) const { |
1652 if (!ALLOW_DUMP) | 1652 if (!buildAllowsDump()) |
1653 return; | 1653 return; |
1654 Ostream &Str = Func->getContext()->getStrEmit(); | 1654 Ostream &Str = Func->getContext()->getStrEmit(); |
1655 assert(getSrcSize() == 2); | 1655 assert(getSrcSize() == 2); |
1656 assert(Condition < CondX86::Cmpps_Invalid); | 1656 assert(Condition < CondX86::Cmpps_Invalid); |
1657 Str << "\t"; | 1657 Str << "\t"; |
1658 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1658 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
1659 << "\t"; | 1659 << "\t"; |
1660 getSrc(1)->emit(Func); | 1660 getSrc(1)->emit(Func); |
1661 Str << ", "; | 1661 Str << ", "; |
1662 getDest()->emit(Func); | 1662 getDest()->emit(Func); |
(...skipping 12 matching lines...) Expand all Loading... |
1675 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); | 1675 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); |
1676 } else { | 1676 } else { |
1677 X8632::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 1677 X8632::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
1678 ->stackVarToAsmOperand(SrcVar); | 1678 ->stackVarToAsmOperand(SrcVar); |
1679 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, | 1679 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, |
1680 Condition); | 1680 Condition); |
1681 } | 1681 } |
1682 } | 1682 } |
1683 | 1683 |
1684 void InstX8632Cmpps::dump(const Cfg *Func) const { | 1684 void InstX8632Cmpps::dump(const Cfg *Func) const { |
1685 if (!ALLOW_DUMP) | 1685 if (!buildAllowsDump()) |
1686 return; | 1686 return; |
1687 Ostream &Str = Func->getContext()->getStrDump(); | 1687 Ostream &Str = Func->getContext()->getStrDump(); |
1688 assert(Condition < CondX86::Cmpps_Invalid); | 1688 assert(Condition < CondX86::Cmpps_Invalid); |
1689 dumpDest(Func); | 1689 dumpDest(Func); |
1690 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1690 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
1691 << "\t"; | 1691 << "\t"; |
1692 dumpSources(Func); | 1692 dumpSources(Func); |
1693 } | 1693 } |
1694 | 1694 |
1695 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 1695 void InstX8632Cmpxchg::emit(const Cfg *Func) const { |
1696 if (!ALLOW_DUMP) | 1696 if (!buildAllowsDump()) |
1697 return; | 1697 return; |
1698 Ostream &Str = Func->getContext()->getStrEmit(); | 1698 Ostream &Str = Func->getContext()->getStrEmit(); |
1699 assert(getSrcSize() == 3); | 1699 assert(getSrcSize() == 3); |
1700 if (Locked) { | 1700 if (Locked) { |
1701 Str << "\tlock"; | 1701 Str << "\tlock"; |
1702 } | 1702 } |
1703 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; | 1703 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; |
1704 getSrc(2)->emit(Func); | 1704 getSrc(2)->emit(Func); |
1705 Str << ", "; | 1705 Str << ", "; |
1706 getSrc(0)->emit(Func); | 1706 getSrc(0)->emit(Func); |
1707 } | 1707 } |
1708 | 1708 |
1709 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 1709 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { |
1710 assert(getSrcSize() == 3); | 1710 assert(getSrcSize() == 3); |
1711 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1711 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1712 Type Ty = getSrc(0)->getType(); | 1712 Type Ty = getSrc(0)->getType(); |
1713 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1713 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
1714 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1714 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1715 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 1715 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
1716 const auto VarReg = llvm::cast<Variable>(getSrc(2)); | 1716 const auto VarReg = llvm::cast<Variable>(getSrc(2)); |
1717 assert(VarReg->hasReg()); | 1717 assert(VarReg->hasReg()); |
1718 const RegX8632::GPRRegister Reg = | 1718 const RegX8632::GPRRegister Reg = |
1719 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 1719 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
1720 Asm->cmpxchg(Ty, Addr, Reg, Locked); | 1720 Asm->cmpxchg(Ty, Addr, Reg, Locked); |
1721 } | 1721 } |
1722 | 1722 |
1723 void InstX8632Cmpxchg::dump(const Cfg *Func) const { | 1723 void InstX8632Cmpxchg::dump(const Cfg *Func) const { |
1724 if (!ALLOW_DUMP) | 1724 if (!buildAllowsDump()) |
1725 return; | 1725 return; |
1726 Ostream &Str = Func->getContext()->getStrDump(); | 1726 Ostream &Str = Func->getContext()->getStrDump(); |
1727 if (Locked) { | 1727 if (Locked) { |
1728 Str << "lock "; | 1728 Str << "lock "; |
1729 } | 1729 } |
1730 Str << "cmpxchg." << getSrc(0)->getType() << " "; | 1730 Str << "cmpxchg." << getSrc(0)->getType() << " "; |
1731 dumpSources(Func); | 1731 dumpSources(Func); |
1732 } | 1732 } |
1733 | 1733 |
1734 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { | 1734 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { |
1735 if (!ALLOW_DUMP) | 1735 if (!buildAllowsDump()) |
1736 return; | 1736 return; |
1737 Ostream &Str = Func->getContext()->getStrEmit(); | 1737 Ostream &Str = Func->getContext()->getStrEmit(); |
1738 assert(getSrcSize() == 5); | 1738 assert(getSrcSize() == 5); |
1739 if (Locked) { | 1739 if (Locked) { |
1740 Str << "\tlock"; | 1740 Str << "\tlock"; |
1741 } | 1741 } |
1742 Str << "\tcmpxchg8b\t"; | 1742 Str << "\tcmpxchg8b\t"; |
1743 getSrc(0)->emit(Func); | 1743 getSrc(0)->emit(Func); |
1744 } | 1744 } |
1745 | 1745 |
1746 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 1746 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { |
1747 assert(getSrcSize() == 5); | 1747 assert(getSrcSize() == 5); |
1748 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1748 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1749 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1749 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
1750 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 1750 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1751 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 1751 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
1752 Asm->cmpxchg8b(Addr, Locked); | 1752 Asm->cmpxchg8b(Addr, Locked); |
1753 } | 1753 } |
1754 | 1754 |
1755 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { | 1755 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { |
1756 if (!ALLOW_DUMP) | 1756 if (!buildAllowsDump()) |
1757 return; | 1757 return; |
1758 Ostream &Str = Func->getContext()->getStrDump(); | 1758 Ostream &Str = Func->getContext()->getStrDump(); |
1759 if (Locked) { | 1759 if (Locked) { |
1760 Str << "lock "; | 1760 Str << "lock "; |
1761 } | 1761 } |
1762 Str << "cmpxchg8b "; | 1762 Str << "cmpxchg8b "; |
1763 dumpSources(Func); | 1763 dumpSources(Func); |
1764 } | 1764 } |
1765 | 1765 |
1766 void InstX8632Cvt::emit(const Cfg *Func) const { | 1766 void InstX8632Cvt::emit(const Cfg *Func) const { |
1767 if (!ALLOW_DUMP) | 1767 if (!buildAllowsDump()) |
1768 return; | 1768 return; |
1769 Ostream &Str = Func->getContext()->getStrEmit(); | 1769 Ostream &Str = Func->getContext()->getStrEmit(); |
1770 assert(getSrcSize() == 1); | 1770 assert(getSrcSize() == 1); |
1771 Str << "\tcvt"; | 1771 Str << "\tcvt"; |
1772 if (isTruncating()) | 1772 if (isTruncating()) |
1773 Str << "t"; | 1773 Str << "t"; |
1774 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" | 1774 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" |
1775 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; | 1775 << TypeX8632Attributes[getDest()->getType()].CvtString << "\t"; |
1776 getSrc(0)->emit(Func); | 1776 getSrc(0)->emit(Func); |
1777 Str << ", "; | 1777 Str << ", "; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1832 assert(isVectorIntegerType(DestTy)); | 1832 assert(isVectorIntegerType(DestTy)); |
1833 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { | 1833 static const X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
1834 &X8632::AssemblerX8632::cvttps2dq, &X8632::AssemblerX8632::cvttps2dq}; | 1834 &X8632::AssemblerX8632::cvttps2dq, &X8632::AssemblerX8632::cvttps2dq}; |
1835 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); | 1835 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, Emitter); |
1836 return; | 1836 return; |
1837 } | 1837 } |
1838 } | 1838 } |
1839 } | 1839 } |
1840 | 1840 |
1841 void InstX8632Cvt::dump(const Cfg *Func) const { | 1841 void InstX8632Cvt::dump(const Cfg *Func) const { |
1842 if (!ALLOW_DUMP) | 1842 if (!buildAllowsDump()) |
1843 return; | 1843 return; |
1844 Ostream &Str = Func->getContext()->getStrDump(); | 1844 Ostream &Str = Func->getContext()->getStrDump(); |
1845 dumpDest(Func); | 1845 dumpDest(Func); |
1846 Str << " = cvt"; | 1846 Str << " = cvt"; |
1847 if (isTruncating()) | 1847 if (isTruncating()) |
1848 Str << "t"; | 1848 Str << "t"; |
1849 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" | 1849 Str << TypeX8632Attributes[getSrc(0)->getType()].CvtString << "2" |
1850 << TypeX8632Attributes[getDest()->getType()].CvtString << " "; | 1850 << TypeX8632Attributes[getDest()->getType()].CvtString << " "; |
1851 dumpSources(Func); | 1851 dumpSources(Func); |
1852 } | 1852 } |
1853 | 1853 |
1854 void InstX8632Icmp::emit(const Cfg *Func) const { | 1854 void InstX8632Icmp::emit(const Cfg *Func) const { |
1855 if (!ALLOW_DUMP) | 1855 if (!buildAllowsDump()) |
1856 return; | 1856 return; |
1857 Ostream &Str = Func->getContext()->getStrEmit(); | 1857 Ostream &Str = Func->getContext()->getStrEmit(); |
1858 assert(getSrcSize() == 2); | 1858 assert(getSrcSize() == 2); |
1859 Str << "\tcmp" << getWidthString(getSrc(0)->getType()) << "\t"; | 1859 Str << "\tcmp" << getWidthString(getSrc(0)->getType()) << "\t"; |
1860 getSrc(1)->emit(Func); | 1860 getSrc(1)->emit(Func); |
1861 Str << ", "; | 1861 Str << ", "; |
1862 getSrc(0)->emit(Func); | 1862 getSrc(0)->emit(Func); |
1863 } | 1863 } |
1864 | 1864 |
1865 void InstX8632Icmp::emitIAS(const Cfg *Func) const { | 1865 void InstX8632Icmp::emitIAS(const Cfg *Func) const { |
1866 assert(getSrcSize() == 2); | 1866 assert(getSrcSize() == 2); |
1867 const Operand *Src0 = getSrc(0); | 1867 const Operand *Src0 = getSrc(0); |
1868 const Operand *Src1 = getSrc(1); | 1868 const Operand *Src1 = getSrc(1); |
1869 Type Ty = Src0->getType(); | 1869 Type Ty = Src0->getType(); |
1870 static const X8632::AssemblerX8632::GPREmitterRegOp RegEmitter = { | 1870 static const X8632::AssemblerX8632::GPREmitterRegOp RegEmitter = { |
1871 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp, | 1871 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp, |
1872 &X8632::AssemblerX8632::cmp}; | 1872 &X8632::AssemblerX8632::cmp}; |
1873 static const X8632::AssemblerX8632::GPREmitterAddrOp AddrEmitter = { | 1873 static const X8632::AssemblerX8632::GPREmitterAddrOp AddrEmitter = { |
1874 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp}; | 1874 &X8632::AssemblerX8632::cmp, &X8632::AssemblerX8632::cmp}; |
1875 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { | 1875 if (const auto SrcVar0 = llvm::dyn_cast<Variable>(Src0)) { |
1876 if (SrcVar0->hasReg()) { | 1876 if (SrcVar0->hasReg()) { |
1877 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1877 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
1878 return; | 1878 return; |
1879 } | 1879 } |
1880 } | 1880 } |
1881 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); | 1881 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); |
1882 } | 1882 } |
1883 | 1883 |
1884 void InstX8632Icmp::dump(const Cfg *Func) const { | 1884 void InstX8632Icmp::dump(const Cfg *Func) const { |
1885 if (!ALLOW_DUMP) | 1885 if (!buildAllowsDump()) |
1886 return; | 1886 return; |
1887 Ostream &Str = Func->getContext()->getStrDump(); | 1887 Ostream &Str = Func->getContext()->getStrDump(); |
1888 Str << "cmp." << getSrc(0)->getType() << " "; | 1888 Str << "cmp." << getSrc(0)->getType() << " "; |
1889 dumpSources(Func); | 1889 dumpSources(Func); |
1890 } | 1890 } |
1891 | 1891 |
1892 void InstX8632Ucomiss::emit(const Cfg *Func) const { | 1892 void InstX8632Ucomiss::emit(const Cfg *Func) const { |
1893 if (!ALLOW_DUMP) | 1893 if (!buildAllowsDump()) |
1894 return; | 1894 return; |
1895 Ostream &Str = Func->getContext()->getStrEmit(); | 1895 Ostream &Str = Func->getContext()->getStrEmit(); |
1896 assert(getSrcSize() == 2); | 1896 assert(getSrcSize() == 2); |
1897 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString | 1897 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString |
1898 << "\t"; | 1898 << "\t"; |
1899 getSrc(1)->emit(Func); | 1899 getSrc(1)->emit(Func); |
1900 Str << ", "; | 1900 Str << ", "; |
1901 getSrc(0)->emit(Func); | 1901 getSrc(0)->emit(Func); |
1902 } | 1902 } |
1903 | 1903 |
1904 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { | 1904 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const { |
1905 assert(getSrcSize() == 2); | 1905 assert(getSrcSize() == 2); |
1906 // Currently src0 is always a variable by convention, to avoid having | 1906 // Currently src0 is always a variable by convention, to avoid having |
1907 // two memory operands. | 1907 // two memory operands. |
1908 assert(llvm::isa<Variable>(getSrc(0))); | 1908 assert(llvm::isa<Variable>(getSrc(0))); |
1909 const auto Src0Var = llvm::cast<Variable>(getSrc(0)); | 1909 const auto Src0Var = llvm::cast<Variable>(getSrc(0)); |
1910 Type Ty = Src0Var->getType(); | 1910 Type Ty = Src0Var->getType(); |
1911 const static X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { | 1911 const static X8632::AssemblerX8632::XmmEmitterRegOp Emitter = { |
1912 &X8632::AssemblerX8632::ucomiss, &X8632::AssemblerX8632::ucomiss}; | 1912 &X8632::AssemblerX8632::ucomiss, &X8632::AssemblerX8632::ucomiss}; |
1913 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter); | 1913 emitIASRegOpTyXMM(Func, Ty, Src0Var, getSrc(1), Emitter); |
1914 } | 1914 } |
1915 | 1915 |
1916 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 1916 void InstX8632Ucomiss::dump(const Cfg *Func) const { |
1917 if (!ALLOW_DUMP) | 1917 if (!buildAllowsDump()) |
1918 return; | 1918 return; |
1919 Ostream &Str = Func->getContext()->getStrDump(); | 1919 Ostream &Str = Func->getContext()->getStrDump(); |
1920 Str << "ucomiss." << getSrc(0)->getType() << " "; | 1920 Str << "ucomiss." << getSrc(0)->getType() << " "; |
1921 dumpSources(Func); | 1921 dumpSources(Func); |
1922 } | 1922 } |
1923 | 1923 |
1924 void InstX8632UD2::emit(const Cfg *Func) const { | 1924 void InstX8632UD2::emit(const Cfg *Func) const { |
1925 if (!ALLOW_DUMP) | 1925 if (!buildAllowsDump()) |
1926 return; | 1926 return; |
1927 Ostream &Str = Func->getContext()->getStrEmit(); | 1927 Ostream &Str = Func->getContext()->getStrEmit(); |
1928 assert(getSrcSize() == 0); | 1928 assert(getSrcSize() == 0); |
1929 Str << "\tud2"; | 1929 Str << "\tud2"; |
1930 } | 1930 } |
1931 | 1931 |
1932 void InstX8632UD2::emitIAS(const Cfg *Func) const { | 1932 void InstX8632UD2::emitIAS(const Cfg *Func) const { |
1933 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1933 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1934 Asm->ud2(); | 1934 Asm->ud2(); |
1935 } | 1935 } |
1936 | 1936 |
1937 void InstX8632UD2::dump(const Cfg *Func) const { | 1937 void InstX8632UD2::dump(const Cfg *Func) const { |
1938 if (!ALLOW_DUMP) | 1938 if (!buildAllowsDump()) |
1939 return; | 1939 return; |
1940 Ostream &Str = Func->getContext()->getStrDump(); | 1940 Ostream &Str = Func->getContext()->getStrDump(); |
1941 Str << "ud2\n"; | 1941 Str << "ud2\n"; |
1942 } | 1942 } |
1943 | 1943 |
1944 void InstX8632Test::emit(const Cfg *Func) const { | 1944 void InstX8632Test::emit(const Cfg *Func) const { |
1945 if (!ALLOW_DUMP) | 1945 if (!buildAllowsDump()) |
1946 return; | 1946 return; |
1947 Ostream &Str = Func->getContext()->getStrEmit(); | 1947 Ostream &Str = Func->getContext()->getStrEmit(); |
1948 assert(getSrcSize() == 2); | 1948 assert(getSrcSize() == 2); |
1949 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t"; | 1949 Str << "\ttest" << getWidthString(getSrc(0)->getType()) << "\t"; |
1950 getSrc(1)->emit(Func); | 1950 getSrc(1)->emit(Func); |
1951 Str << ", "; | 1951 Str << ", "; |
1952 getSrc(0)->emit(Func); | 1952 getSrc(0)->emit(Func); |
1953 } | 1953 } |
1954 | 1954 |
1955 void InstX8632Test::emitIAS(const Cfg *Func) const { | 1955 void InstX8632Test::emitIAS(const Cfg *Func) const { |
(...skipping 10 matching lines...) Expand all Loading... |
1966 if (SrcVar0->hasReg()) { | 1966 if (SrcVar0->hasReg()) { |
1967 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1967 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
1968 return; | 1968 return; |
1969 } | 1969 } |
1970 } | 1970 } |
1971 llvm_unreachable("Nothing actually generates this so it's untested"); | 1971 llvm_unreachable("Nothing actually generates this so it's untested"); |
1972 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); | 1972 emitIASAsAddrOpTyGPR(Func, Ty, Src0, Src1, AddrEmitter); |
1973 } | 1973 } |
1974 | 1974 |
1975 void InstX8632Test::dump(const Cfg *Func) const { | 1975 void InstX8632Test::dump(const Cfg *Func) const { |
1976 if (!ALLOW_DUMP) | 1976 if (!buildAllowsDump()) |
1977 return; | 1977 return; |
1978 Ostream &Str = Func->getContext()->getStrDump(); | 1978 Ostream &Str = Func->getContext()->getStrDump(); |
1979 Str << "test." << getSrc(0)->getType() << " "; | 1979 Str << "test." << getSrc(0)->getType() << " "; |
1980 dumpSources(Func); | 1980 dumpSources(Func); |
1981 } | 1981 } |
1982 | 1982 |
1983 void InstX8632Mfence::emit(const Cfg *Func) const { | 1983 void InstX8632Mfence::emit(const Cfg *Func) const { |
1984 if (!ALLOW_DUMP) | 1984 if (!buildAllowsDump()) |
1985 return; | 1985 return; |
1986 Ostream &Str = Func->getContext()->getStrEmit(); | 1986 Ostream &Str = Func->getContext()->getStrEmit(); |
1987 assert(getSrcSize() == 0); | 1987 assert(getSrcSize() == 0); |
1988 Str << "\tmfence"; | 1988 Str << "\tmfence"; |
1989 } | 1989 } |
1990 | 1990 |
1991 void InstX8632Mfence::emitIAS(const Cfg *Func) const { | 1991 void InstX8632Mfence::emitIAS(const Cfg *Func) const { |
1992 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 1992 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
1993 Asm->mfence(); | 1993 Asm->mfence(); |
1994 } | 1994 } |
1995 | 1995 |
1996 void InstX8632Mfence::dump(const Cfg *Func) const { | 1996 void InstX8632Mfence::dump(const Cfg *Func) const { |
1997 if (!ALLOW_DUMP) | 1997 if (!buildAllowsDump()) |
1998 return; | 1998 return; |
1999 Ostream &Str = Func->getContext()->getStrDump(); | 1999 Ostream &Str = Func->getContext()->getStrDump(); |
2000 Str << "mfence\n"; | 2000 Str << "mfence\n"; |
2001 } | 2001 } |
2002 | 2002 |
2003 void InstX8632Store::emit(const Cfg *Func) const { | 2003 void InstX8632Store::emit(const Cfg *Func) const { |
2004 if (!ALLOW_DUMP) | 2004 if (!buildAllowsDump()) |
2005 return; | 2005 return; |
2006 Ostream &Str = Func->getContext()->getStrEmit(); | 2006 Ostream &Str = Func->getContext()->getStrEmit(); |
2007 assert(getSrcSize() == 2); | 2007 assert(getSrcSize() == 2); |
2008 Type Ty = getSrc(0)->getType(); | 2008 Type Ty = getSrc(0)->getType(); |
2009 Str << "\tmov" << getWidthString(Ty) << TypeX8632Attributes[Ty].SdSsString | 2009 Str << "\tmov" << getWidthString(Ty) << TypeX8632Attributes[Ty].SdSsString |
2010 << "\t"; | 2010 << "\t"; |
2011 getSrc(0)->emit(Func); | 2011 getSrc(0)->emit(Func); |
2012 Str << ", "; | 2012 Str << ", "; |
2013 getSrc(1)->emit(Func); | 2013 getSrc(1)->emit(Func); |
2014 } | 2014 } |
(...skipping 22 matching lines...) Expand all Loading... |
2037 return; | 2037 return; |
2038 } else { | 2038 } else { |
2039 assert(isScalarIntegerType(DestTy)); | 2039 assert(isScalarIntegerType(DestTy)); |
2040 static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = { | 2040 static const X8632::AssemblerX8632::GPREmitterAddrOp GPRAddrEmitter = { |
2041 &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov}; | 2041 &X8632::AssemblerX8632::mov, &X8632::AssemblerX8632::mov}; |
2042 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter); | 2042 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter); |
2043 } | 2043 } |
2044 } | 2044 } |
2045 | 2045 |
2046 void InstX8632Store::dump(const Cfg *Func) const { | 2046 void InstX8632Store::dump(const Cfg *Func) const { |
2047 if (!ALLOW_DUMP) | 2047 if (!buildAllowsDump()) |
2048 return; | 2048 return; |
2049 Ostream &Str = Func->getContext()->getStrDump(); | 2049 Ostream &Str = Func->getContext()->getStrDump(); |
2050 Str << "mov." << getSrc(0)->getType() << " "; | 2050 Str << "mov." << getSrc(0)->getType() << " "; |
2051 getSrc(1)->dump(Func); | 2051 getSrc(1)->dump(Func); |
2052 Str << ", "; | 2052 Str << ", "; |
2053 getSrc(0)->dump(Func); | 2053 getSrc(0)->dump(Func); |
2054 } | 2054 } |
2055 | 2055 |
2056 void InstX8632StoreP::emit(const Cfg *Func) const { | 2056 void InstX8632StoreP::emit(const Cfg *Func) const { |
2057 if (!ALLOW_DUMP) | 2057 if (!buildAllowsDump()) |
2058 return; | 2058 return; |
2059 Ostream &Str = Func->getContext()->getStrEmit(); | 2059 Ostream &Str = Func->getContext()->getStrEmit(); |
2060 assert(getSrcSize() == 2); | 2060 assert(getSrcSize() == 2); |
2061 Str << "\tmovups\t"; | 2061 Str << "\tmovups\t"; |
2062 getSrc(0)->emit(Func); | 2062 getSrc(0)->emit(Func); |
2063 Str << ", "; | 2063 Str << ", "; |
2064 getSrc(1)->emit(Func); | 2064 getSrc(1)->emit(Func); |
2065 } | 2065 } |
2066 | 2066 |
2067 void InstX8632StoreP::emitIAS(const Cfg *Func) const { | 2067 void InstX8632StoreP::emitIAS(const Cfg *Func) const { |
2068 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2068 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2069 assert(getSrcSize() == 2); | 2069 assert(getSrcSize() == 2); |
2070 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2070 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
2071 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 2071 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
2072 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2072 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2073 assert(SrcVar->hasReg()); | 2073 assert(SrcVar->hasReg()); |
2074 Asm->movups(DestMem->toAsmAddress(Asm), | 2074 Asm->movups(DestMem->toAsmAddress(Asm), |
2075 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2075 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
2076 } | 2076 } |
2077 | 2077 |
2078 void InstX8632StoreP::dump(const Cfg *Func) const { | 2078 void InstX8632StoreP::dump(const Cfg *Func) const { |
2079 if (!ALLOW_DUMP) | 2079 if (!buildAllowsDump()) |
2080 return; | 2080 return; |
2081 Ostream &Str = Func->getContext()->getStrDump(); | 2081 Ostream &Str = Func->getContext()->getStrDump(); |
2082 Str << "storep." << getSrc(0)->getType() << " "; | 2082 Str << "storep." << getSrc(0)->getType() << " "; |
2083 getSrc(1)->dump(Func); | 2083 getSrc(1)->dump(Func); |
2084 Str << ", "; | 2084 Str << ", "; |
2085 getSrc(0)->dump(Func); | 2085 getSrc(0)->dump(Func); |
2086 } | 2086 } |
2087 | 2087 |
2088 void InstX8632StoreQ::emit(const Cfg *Func) const { | 2088 void InstX8632StoreQ::emit(const Cfg *Func) const { |
2089 if (!ALLOW_DUMP) | 2089 if (!buildAllowsDump()) |
2090 return; | 2090 return; |
2091 Ostream &Str = Func->getContext()->getStrEmit(); | 2091 Ostream &Str = Func->getContext()->getStrEmit(); |
2092 assert(getSrcSize() == 2); | 2092 assert(getSrcSize() == 2); |
2093 assert(getSrc(1)->getType() == IceType_i64 || | 2093 assert(getSrc(1)->getType() == IceType_i64 || |
2094 getSrc(1)->getType() == IceType_f64); | 2094 getSrc(1)->getType() == IceType_f64); |
2095 Str << "\tmovq\t"; | 2095 Str << "\tmovq\t"; |
2096 getSrc(0)->emit(Func); | 2096 getSrc(0)->emit(Func); |
2097 Str << ", "; | 2097 Str << ", "; |
2098 getSrc(1)->emit(Func); | 2098 getSrc(1)->emit(Func); |
2099 } | 2099 } |
2100 | 2100 |
2101 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { | 2101 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { |
2102 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2102 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2103 assert(getSrcSize() == 2); | 2103 assert(getSrcSize() == 2); |
2104 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); | 2104 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); |
2105 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 2105 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
2106 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2106 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2107 assert(SrcVar->hasReg()); | 2107 assert(SrcVar->hasReg()); |
2108 Asm->movq(DestMem->toAsmAddress(Asm), | 2108 Asm->movq(DestMem->toAsmAddress(Asm), |
2109 RegX8632::getEncodedXmm(SrcVar->getRegNum())); | 2109 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
2110 } | 2110 } |
2111 | 2111 |
2112 void InstX8632StoreQ::dump(const Cfg *Func) const { | 2112 void InstX8632StoreQ::dump(const Cfg *Func) const { |
2113 if (!ALLOW_DUMP) | 2113 if (!buildAllowsDump()) |
2114 return; | 2114 return; |
2115 Ostream &Str = Func->getContext()->getStrDump(); | 2115 Ostream &Str = Func->getContext()->getStrDump(); |
2116 Str << "storeq." << getSrc(0)->getType() << " "; | 2116 Str << "storeq." << getSrc(0)->getType() << " "; |
2117 getSrc(1)->dump(Func); | 2117 getSrc(1)->dump(Func); |
2118 Str << ", "; | 2118 Str << ", "; |
2119 getSrc(0)->dump(Func); | 2119 getSrc(0)->dump(Func); |
2120 } | 2120 } |
2121 | 2121 |
2122 template <> void InstX8632Lea::emit(const Cfg *Func) const { | 2122 template <> void InstX8632Lea::emit(const Cfg *Func) const { |
2123 if (!ALLOW_DUMP) | 2123 if (!buildAllowsDump()) |
2124 return; | 2124 return; |
2125 Ostream &Str = Func->getContext()->getStrEmit(); | 2125 Ostream &Str = Func->getContext()->getStrEmit(); |
2126 assert(getSrcSize() == 1); | 2126 assert(getSrcSize() == 1); |
2127 assert(getDest()->hasReg()); | 2127 assert(getDest()->hasReg()); |
2128 Str << "\tleal\t"; | 2128 Str << "\tleal\t"; |
2129 Operand *Src0 = getSrc(0); | 2129 Operand *Src0 = getSrc(0); |
2130 if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) { | 2130 if (const auto Src0Var = llvm::dyn_cast<Variable>(Src0)) { |
2131 Type Ty = Src0Var->getType(); | 2131 Type Ty = Src0Var->getType(); |
2132 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an | 2132 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an |
2133 // acceptable type. | 2133 // acceptable type. |
2134 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func); | 2134 Src0Var->asType(isVectorType(Ty) ? IceType_i32 : Ty)->emit(Func); |
2135 } else { | 2135 } else { |
2136 Src0->emit(Func); | 2136 Src0->emit(Func); |
2137 } | 2137 } |
2138 Str << ", "; | 2138 Str << ", "; |
2139 getDest()->emit(Func); | 2139 getDest()->emit(Func); |
2140 } | 2140 } |
2141 | 2141 |
2142 template <> void InstX8632Mov::emit(const Cfg *Func) const { | 2142 template <> void InstX8632Mov::emit(const Cfg *Func) const { |
2143 if (!ALLOW_DUMP) | 2143 if (!buildAllowsDump()) |
2144 return; | 2144 return; |
2145 Ostream &Str = Func->getContext()->getStrEmit(); | 2145 Ostream &Str = Func->getContext()->getStrEmit(); |
2146 assert(getSrcSize() == 1); | 2146 assert(getSrcSize() == 1); |
2147 Operand *Src = getSrc(0); | 2147 Operand *Src = getSrc(0); |
2148 Type SrcTy = Src->getType(); | 2148 Type SrcTy = Src->getType(); |
2149 Type DestTy = getDest()->getType(); | 2149 Type DestTy = getDest()->getType(); |
2150 Str << "\tmov" << (!isScalarFloatingType(DestTy) | 2150 Str << "\tmov" << (!isScalarFloatingType(DestTy) |
2151 ? getWidthString(SrcTy) | 2151 ? getWidthString(SrcTy) |
2152 : TypeX8632Attributes[DestTy].SdSsString) << "\t"; | 2152 : TypeX8632Attributes[DestTy].SdSsString) << "\t"; |
2153 // For an integer truncation operation, src is wider than dest. | 2153 // For an integer truncation operation, src is wider than dest. |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2263 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); | 2263 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); |
2264 } else { | 2264 } else { |
2265 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2265 X8632::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
2266 ->stackVarToAsmOperand(Dest)); | 2266 ->stackVarToAsmOperand(Dest)); |
2267 Asm->movd(StackAddr, SrcReg); | 2267 Asm->movd(StackAddr, SrcReg); |
2268 } | 2268 } |
2269 } | 2269 } |
2270 } | 2270 } |
2271 | 2271 |
2272 template <> void InstX8632Movp::emit(const Cfg *Func) const { | 2272 template <> void InstX8632Movp::emit(const Cfg *Func) const { |
2273 if (!ALLOW_DUMP) | 2273 if (!buildAllowsDump()) |
2274 return; | 2274 return; |
2275 // TODO(wala,stichnot): movups works with all vector operands, but | 2275 // TODO(wala,stichnot): movups works with all vector operands, but |
2276 // there exist other instructions (movaps, movdqa, movdqu) that may | 2276 // there exist other instructions (movaps, movdqa, movdqu) that may |
2277 // perform better, depending on the data type and alignment of the | 2277 // perform better, depending on the data type and alignment of the |
2278 // operands. | 2278 // operands. |
2279 Ostream &Str = Func->getContext()->getStrEmit(); | 2279 Ostream &Str = Func->getContext()->getStrEmit(); |
2280 assert(getSrcSize() == 1); | 2280 assert(getSrcSize() == 1); |
2281 Str << "\tmovups\t"; | 2281 Str << "\tmovups\t"; |
2282 getSrc(0)->emit(Func); | 2282 getSrc(0)->emit(Func); |
2283 Str << ", "; | 2283 Str << ", "; |
2284 getDest()->emit(Func); | 2284 getDest()->emit(Func); |
2285 } | 2285 } |
2286 | 2286 |
2287 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { | 2287 template <> void InstX8632Movp::emitIAS(const Cfg *Func) const { |
2288 assert(getSrcSize() == 1); | 2288 assert(getSrcSize() == 1); |
2289 assert(isVectorType(getDest()->getType())); | 2289 assert(isVectorType(getDest()->getType())); |
2290 const Variable *Dest = getDest(); | 2290 const Variable *Dest = getDest(); |
2291 const Operand *Src = getSrc(0); | 2291 const Operand *Src = getSrc(0); |
2292 const static X8632::AssemblerX8632::XmmEmitterMovOps Emitter = { | 2292 const static X8632::AssemblerX8632::XmmEmitterMovOps Emitter = { |
2293 &X8632::AssemblerX8632::movups, &X8632::AssemblerX8632::movups, | 2293 &X8632::AssemblerX8632::movups, &X8632::AssemblerX8632::movups, |
2294 &X8632::AssemblerX8632::movups}; | 2294 &X8632::AssemblerX8632::movups}; |
2295 emitIASMovlikeXMM(Func, Dest, Src, Emitter); | 2295 emitIASMovlikeXMM(Func, Dest, Src, Emitter); |
2296 } | 2296 } |
2297 | 2297 |
2298 template <> void InstX8632Movq::emit(const Cfg *Func) const { | 2298 template <> void InstX8632Movq::emit(const Cfg *Func) const { |
2299 if (!ALLOW_DUMP) | 2299 if (!buildAllowsDump()) |
2300 return; | 2300 return; |
2301 Ostream &Str = Func->getContext()->getStrEmit(); | 2301 Ostream &Str = Func->getContext()->getStrEmit(); |
2302 assert(getSrcSize() == 1); | 2302 assert(getSrcSize() == 1); |
2303 assert(getDest()->getType() == IceType_i64 || | 2303 assert(getDest()->getType() == IceType_i64 || |
2304 getDest()->getType() == IceType_f64); | 2304 getDest()->getType() == IceType_f64); |
2305 Str << "\tmovq\t"; | 2305 Str << "\tmovq\t"; |
2306 getSrc(0)->emit(Func); | 2306 getSrc(0)->emit(Func); |
2307 Str << ", "; | 2307 Str << ", "; |
2308 getDest()->emit(Func); | 2308 getDest()->emit(Func); |
2309 } | 2309 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2350 assert(getSrcSize() == 1); | 2350 assert(getSrcSize() == 1); |
2351 const Variable *Dest = getDest(); | 2351 const Variable *Dest = getDest(); |
2352 const Operand *Src = getSrc(0); | 2352 const Operand *Src = getSrc(0); |
2353 Type SrcTy = Src->getType(); | 2353 Type SrcTy = Src->getType(); |
2354 assert(typeWidthInBytes(Dest->getType()) > 1); | 2354 assert(typeWidthInBytes(Dest->getType()) > 1); |
2355 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); | 2355 assert(typeWidthInBytes(Dest->getType()) > typeWidthInBytes(SrcTy)); |
2356 emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter); | 2356 emitIASRegOpTyGPR<false, true>(Func, SrcTy, Dest, Src, Emitter); |
2357 } | 2357 } |
2358 | 2358 |
2359 void InstX8632Nop::emit(const Cfg *Func) const { | 2359 void InstX8632Nop::emit(const Cfg *Func) const { |
2360 if (!ALLOW_DUMP) | 2360 if (!buildAllowsDump()) |
2361 return; | 2361 return; |
2362 Ostream &Str = Func->getContext()->getStrEmit(); | 2362 Ostream &Str = Func->getContext()->getStrEmit(); |
2363 // TODO: Emit the right code for each variant. | 2363 // TODO: Emit the right code for each variant. |
2364 Str << "\tnop\t# variant = " << Variant; | 2364 Str << "\tnop\t# variant = " << Variant; |
2365 } | 2365 } |
2366 | 2366 |
2367 void InstX8632Nop::emitIAS(const Cfg *Func) const { | 2367 void InstX8632Nop::emitIAS(const Cfg *Func) const { |
2368 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2368 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2369 // TODO: Emit the right code for the variant. | 2369 // TODO: Emit the right code for the variant. |
2370 Asm->nop(); | 2370 Asm->nop(); |
2371 } | 2371 } |
2372 | 2372 |
2373 void InstX8632Nop::dump(const Cfg *Func) const { | 2373 void InstX8632Nop::dump(const Cfg *Func) const { |
2374 if (!ALLOW_DUMP) | 2374 if (!buildAllowsDump()) |
2375 return; | 2375 return; |
2376 Ostream &Str = Func->getContext()->getStrDump(); | 2376 Ostream &Str = Func->getContext()->getStrDump(); |
2377 Str << "nop (variant = " << Variant << ")"; | 2377 Str << "nop (variant = " << Variant << ")"; |
2378 } | 2378 } |
2379 | 2379 |
2380 void InstX8632Fld::emit(const Cfg *Func) const { | 2380 void InstX8632Fld::emit(const Cfg *Func) const { |
2381 if (!ALLOW_DUMP) | 2381 if (!buildAllowsDump()) |
2382 return; | 2382 return; |
2383 Ostream &Str = Func->getContext()->getStrEmit(); | 2383 Ostream &Str = Func->getContext()->getStrEmit(); |
2384 assert(getSrcSize() == 1); | 2384 assert(getSrcSize() == 1); |
2385 Type Ty = getSrc(0)->getType(); | 2385 Type Ty = getSrc(0)->getType(); |
2386 SizeT Width = typeWidthInBytes(Ty); | 2386 SizeT Width = typeWidthInBytes(Ty); |
2387 const auto Var = llvm::dyn_cast<Variable>(getSrc(0)); | 2387 const auto Var = llvm::dyn_cast<Variable>(getSrc(0)); |
2388 if (Var && Var->hasReg()) { | 2388 if (Var && Var->hasReg()) { |
2389 // This is a physical xmm register, so we need to spill it to a | 2389 // This is a physical xmm register, so we need to spill it to a |
2390 // temporary stack slot. | 2390 // temporary stack slot. |
2391 Str << "\tsubl\t$" << Width << ", %esp" | 2391 Str << "\tsubl\t$" << Width << ", %esp" |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2426 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2426 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2427 Asm->fld(Ty, Mem->toAsmAddress(Asm)); | 2427 Asm->fld(Ty, Mem->toAsmAddress(Asm)); |
2428 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 2428 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
2429 Asm->fld(Ty, X8632::Address::ofConstPool(Asm, Imm)); | 2429 Asm->fld(Ty, X8632::Address::ofConstPool(Asm, Imm)); |
2430 } else { | 2430 } else { |
2431 llvm_unreachable("Unexpected operand type"); | 2431 llvm_unreachable("Unexpected operand type"); |
2432 } | 2432 } |
2433 } | 2433 } |
2434 | 2434 |
2435 void InstX8632Fld::dump(const Cfg *Func) const { | 2435 void InstX8632Fld::dump(const Cfg *Func) const { |
2436 if (!ALLOW_DUMP) | 2436 if (!buildAllowsDump()) |
2437 return; | 2437 return; |
2438 Ostream &Str = Func->getContext()->getStrDump(); | 2438 Ostream &Str = Func->getContext()->getStrDump(); |
2439 Str << "fld." << getSrc(0)->getType() << " "; | 2439 Str << "fld." << getSrc(0)->getType() << " "; |
2440 dumpSources(Func); | 2440 dumpSources(Func); |
2441 } | 2441 } |
2442 | 2442 |
2443 void InstX8632Fstp::emit(const Cfg *Func) const { | 2443 void InstX8632Fstp::emit(const Cfg *Func) const { |
2444 if (!ALLOW_DUMP) | 2444 if (!buildAllowsDump()) |
2445 return; | 2445 return; |
2446 Ostream &Str = Func->getContext()->getStrEmit(); | 2446 Ostream &Str = Func->getContext()->getStrEmit(); |
2447 assert(getSrcSize() == 0); | 2447 assert(getSrcSize() == 0); |
2448 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to | 2448 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to |
2449 // "partially" delete the fstp if the Dest is unused. | 2449 // "partially" delete the fstp if the Dest is unused. |
2450 // Even if Dest is unused, the fstp should be kept for the SideEffects | 2450 // Even if Dest is unused, the fstp should be kept for the SideEffects |
2451 // of popping the stack. | 2451 // of popping the stack. |
2452 if (!getDest()) { | 2452 if (!getDest()) { |
2453 Str << "\tfstp\tst(0)"; | 2453 Str << "\tfstp\tst(0)"; |
2454 return; | 2454 return; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2499 X8632::Immediate Width(typeWidthInBytes(Ty)); | 2499 X8632::Immediate Width(typeWidthInBytes(Ty)); |
2500 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2500 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
2501 X8632::Address StackSlot = X8632::Address(RegX8632::Encoded_Reg_esp, 0); | 2501 X8632::Address StackSlot = X8632::Address(RegX8632::Encoded_Reg_esp, 0); |
2502 Asm->fstp(Ty, StackSlot); | 2502 Asm->fstp(Ty, StackSlot); |
2503 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); | 2503 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); |
2504 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2504 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
2505 } | 2505 } |
2506 } | 2506 } |
2507 | 2507 |
2508 void InstX8632Fstp::dump(const Cfg *Func) const { | 2508 void InstX8632Fstp::dump(const Cfg *Func) const { |
2509 if (!ALLOW_DUMP) | 2509 if (!buildAllowsDump()) |
2510 return; | 2510 return; |
2511 Ostream &Str = Func->getContext()->getStrDump(); | 2511 Ostream &Str = Func->getContext()->getStrDump(); |
2512 dumpDest(Func); | 2512 dumpDest(Func); |
2513 Str << " = fstp." << getDest()->getType() << ", st(0)"; | 2513 Str << " = fstp." << getDest()->getType() << ", st(0)"; |
2514 Str << "\n"; | 2514 Str << "\n"; |
2515 } | 2515 } |
2516 | 2516 |
2517 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { | 2517 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { |
2518 if (!ALLOW_DUMP) | 2518 if (!buildAllowsDump()) |
2519 return; | 2519 return; |
2520 char buf[30]; | 2520 char buf[30]; |
2521 snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s", | 2521 snprintf(buf, llvm::array_lengthof(buf), "pcmpeq%s", |
2522 TypeX8632Attributes[getDest()->getType()].PackString); | 2522 TypeX8632Attributes[getDest()->getType()].PackString); |
2523 emitTwoAddress(buf, this, Func); | 2523 emitTwoAddress(buf, this, Func); |
2524 } | 2524 } |
2525 | 2525 |
2526 template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const { | 2526 template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const { |
2527 if (!ALLOW_DUMP) | 2527 if (!buildAllowsDump()) |
2528 return; | 2528 return; |
2529 char buf[30]; | 2529 char buf[30]; |
2530 snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s", | 2530 snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s", |
2531 TypeX8632Attributes[getDest()->getType()].PackString); | 2531 TypeX8632Attributes[getDest()->getType()].PackString); |
2532 emitTwoAddress(buf, this, Func); | 2532 emitTwoAddress(buf, this, Func); |
2533 } | 2533 } |
2534 | 2534 |
2535 template <> void InstX8632Pextr::emit(const Cfg *Func) const { | 2535 template <> void InstX8632Pextr::emit(const Cfg *Func) const { |
2536 if (!ALLOW_DUMP) | 2536 if (!buildAllowsDump()) |
2537 return; | 2537 return; |
2538 Ostream &Str = Func->getContext()->getStrEmit(); | 2538 Ostream &Str = Func->getContext()->getStrEmit(); |
2539 assert(getSrcSize() == 2); | 2539 assert(getSrcSize() == 2); |
2540 // pextrb and pextrd are SSE4.1 instructions. | 2540 // pextrb and pextrd are SSE4.1 instructions. |
2541 assert(getSrc(0)->getType() == IceType_v8i16 || | 2541 assert(getSrc(0)->getType() == IceType_v8i16 || |
2542 getSrc(0)->getType() == IceType_v8i1 || | 2542 getSrc(0)->getType() == IceType_v8i1 || |
2543 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2543 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
2544 TargetX8632::SSE4_1); | 2544 TargetX8632::SSE4_1); |
2545 Str << "\t" << Opcode << TypeX8632Attributes[getSrc(0)->getType()].PackString | 2545 Str << "\t" << Opcode << TypeX8632Attributes[getSrc(0)->getType()].PackString |
2546 << "\t"; | 2546 << "\t"; |
(...skipping 25 matching lines...) Expand all Loading... |
2572 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); | 2572 assert(llvm::cast<Variable>(getSrc(0))->hasReg()); |
2573 static const X8632::AssemblerX8632::ThreeOpImmEmitter< | 2573 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
2574 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { | 2574 RegX8632::GPRRegister, RegX8632::XmmRegister> Emitter = { |
2575 &X8632::AssemblerX8632::pextr, nullptr}; | 2575 &X8632::AssemblerX8632::pextr, nullptr}; |
2576 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, | 2576 emitIASThreeOpImmOps<RegX8632::GPRRegister, RegX8632::XmmRegister, |
2577 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( | 2577 RegX8632::getEncodedGPR, RegX8632::getEncodedXmm>( |
2578 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); | 2578 Func, DispatchTy, Dest, getSrc(0), getSrc(1), Emitter); |
2579 } | 2579 } |
2580 | 2580 |
2581 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { | 2581 template <> void InstX8632Pinsr::emit(const Cfg *Func) const { |
2582 if (!ALLOW_DUMP) | 2582 if (!buildAllowsDump()) |
2583 return; | 2583 return; |
2584 Ostream &Str = Func->getContext()->getStrEmit(); | 2584 Ostream &Str = Func->getContext()->getStrEmit(); |
2585 assert(getSrcSize() == 3); | 2585 assert(getSrcSize() == 3); |
2586 // pinsrb and pinsrd are SSE4.1 instructions. | 2586 // pinsrb and pinsrd are SSE4.1 instructions. |
2587 assert(getDest()->getType() == IceType_v8i16 || | 2587 assert(getDest()->getType() == IceType_v8i16 || |
2588 getDest()->getType() == IceType_v8i1 || | 2588 getDest()->getType() == IceType_v8i1 || |
2589 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= | 2589 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= |
2590 TargetX8632::SSE4_1); | 2590 TargetX8632::SSE4_1); |
2591 Str << "\t" << Opcode << TypeX8632Attributes[getDest()->getType()].PackString | 2591 Str << "\t" << Opcode << TypeX8632Attributes[getDest()->getType()].PackString |
2592 << "\t"; | 2592 << "\t"; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2647 Type Ty = Dest->getType(); | 2647 Type Ty = Dest->getType(); |
2648 static const X8632::AssemblerX8632::ThreeOpImmEmitter< | 2648 static const X8632::AssemblerX8632::ThreeOpImmEmitter< |
2649 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { | 2649 RegX8632::XmmRegister, RegX8632::XmmRegister> Emitter = { |
2650 &X8632::AssemblerX8632::shufps, &X8632::AssemblerX8632::shufps}; | 2650 &X8632::AssemblerX8632::shufps, &X8632::AssemblerX8632::shufps}; |
2651 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, | 2651 emitIASThreeOpImmOps<RegX8632::XmmRegister, RegX8632::XmmRegister, |
2652 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( | 2652 RegX8632::getEncodedXmm, RegX8632::getEncodedXmm>( |
2653 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); | 2653 Func, Ty, Dest, getSrc(1), getSrc(2), Emitter); |
2654 } | 2654 } |
2655 | 2655 |
2656 void InstX8632Pop::emit(const Cfg *Func) const { | 2656 void InstX8632Pop::emit(const Cfg *Func) const { |
2657 if (!ALLOW_DUMP) | 2657 if (!buildAllowsDump()) |
2658 return; | 2658 return; |
2659 Ostream &Str = Func->getContext()->getStrEmit(); | 2659 Ostream &Str = Func->getContext()->getStrEmit(); |
2660 assert(getSrcSize() == 0); | 2660 assert(getSrcSize() == 0); |
2661 Str << "\tpop\t"; | 2661 Str << "\tpop\t"; |
2662 getDest()->emit(Func); | 2662 getDest()->emit(Func); |
2663 } | 2663 } |
2664 | 2664 |
2665 void InstX8632Pop::emitIAS(const Cfg *Func) const { | 2665 void InstX8632Pop::emitIAS(const Cfg *Func) const { |
2666 assert(getSrcSize() == 0); | 2666 assert(getSrcSize() == 0); |
2667 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2667 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2668 if (getDest()->hasReg()) { | 2668 if (getDest()->hasReg()) { |
2669 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); | 2669 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); |
2670 } else { | 2670 } else { |
2671 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) | 2671 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) |
2672 ->stackVarToAsmOperand(getDest())); | 2672 ->stackVarToAsmOperand(getDest())); |
2673 } | 2673 } |
2674 } | 2674 } |
2675 | 2675 |
2676 void InstX8632Pop::dump(const Cfg *Func) const { | 2676 void InstX8632Pop::dump(const Cfg *Func) const { |
2677 if (!ALLOW_DUMP) | 2677 if (!buildAllowsDump()) |
2678 return; | 2678 return; |
2679 Ostream &Str = Func->getContext()->getStrDump(); | 2679 Ostream &Str = Func->getContext()->getStrDump(); |
2680 dumpDest(Func); | 2680 dumpDest(Func); |
2681 Str << " = pop." << getDest()->getType() << " "; | 2681 Str << " = pop." << getDest()->getType() << " "; |
2682 } | 2682 } |
2683 | 2683 |
2684 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 2684 void InstX8632AdjustStack::emit(const Cfg *Func) const { |
2685 if (!ALLOW_DUMP) | 2685 if (!buildAllowsDump()) |
2686 return; | 2686 return; |
2687 Ostream &Str = Func->getContext()->getStrEmit(); | 2687 Ostream &Str = Func->getContext()->getStrEmit(); |
2688 Str << "\tsubl\t$" << Amount << ", %esp"; | 2688 Str << "\tsubl\t$" << Amount << ", %esp"; |
2689 Func->getTarget()->updateStackAdjustment(Amount); | 2689 Func->getTarget()->updateStackAdjustment(Amount); |
2690 } | 2690 } |
2691 | 2691 |
2692 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { | 2692 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { |
2693 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2693 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2694 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, X8632::Immediate(Amount)); | 2694 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, X8632::Immediate(Amount)); |
2695 Func->getTarget()->updateStackAdjustment(Amount); | 2695 Func->getTarget()->updateStackAdjustment(Amount); |
2696 } | 2696 } |
2697 | 2697 |
2698 void InstX8632AdjustStack::dump(const Cfg *Func) const { | 2698 void InstX8632AdjustStack::dump(const Cfg *Func) const { |
2699 if (!ALLOW_DUMP) | 2699 if (!buildAllowsDump()) |
2700 return; | 2700 return; |
2701 Ostream &Str = Func->getContext()->getStrDump(); | 2701 Ostream &Str = Func->getContext()->getStrDump(); |
2702 Str << "esp = sub.i32 esp, " << Amount; | 2702 Str << "esp = sub.i32 esp, " << Amount; |
2703 } | 2703 } |
2704 | 2704 |
2705 void InstX8632Push::emit(const Cfg *Func) const { | 2705 void InstX8632Push::emit(const Cfg *Func) const { |
2706 if (!ALLOW_DUMP) | 2706 if (!buildAllowsDump()) |
2707 return; | 2707 return; |
2708 Ostream &Str = Func->getContext()->getStrEmit(); | 2708 Ostream &Str = Func->getContext()->getStrEmit(); |
2709 assert(getSrcSize() == 1); | 2709 assert(getSrcSize() == 1); |
2710 // Push is currently only used for saving GPRs. | 2710 // Push is currently only used for saving GPRs. |
2711 const auto Var = llvm::cast<Variable>(getSrc(0)); | 2711 const auto Var = llvm::cast<Variable>(getSrc(0)); |
2712 assert(Var->hasReg()); | 2712 assert(Var->hasReg()); |
2713 Str << "\tpush\t"; | 2713 Str << "\tpush\t"; |
2714 Var->emit(Func); | 2714 Var->emit(Func); |
2715 } | 2715 } |
2716 | 2716 |
2717 void InstX8632Push::emitIAS(const Cfg *Func) const { | 2717 void InstX8632Push::emitIAS(const Cfg *Func) const { |
2718 assert(getSrcSize() == 1); | 2718 assert(getSrcSize() == 1); |
2719 // Push is currently only used for saving GPRs. | 2719 // Push is currently only used for saving GPRs. |
2720 const auto Var = llvm::cast<Variable>(getSrc(0)); | 2720 const auto Var = llvm::cast<Variable>(getSrc(0)); |
2721 assert(Var->hasReg()); | 2721 assert(Var->hasReg()); |
2722 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2722 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2723 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); | 2723 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); |
2724 } | 2724 } |
2725 | 2725 |
2726 void InstX8632Push::dump(const Cfg *Func) const { | 2726 void InstX8632Push::dump(const Cfg *Func) const { |
2727 if (!ALLOW_DUMP) | 2727 if (!buildAllowsDump()) |
2728 return; | 2728 return; |
2729 Ostream &Str = Func->getContext()->getStrDump(); | 2729 Ostream &Str = Func->getContext()->getStrDump(); |
2730 Str << "push." << getSrc(0)->getType() << " "; | 2730 Str << "push." << getSrc(0)->getType() << " "; |
2731 dumpSources(Func); | 2731 dumpSources(Func); |
2732 } | 2732 } |
2733 | 2733 |
2734 template <> void InstX8632Psll::emit(const Cfg *Func) const { | 2734 template <> void InstX8632Psll::emit(const Cfg *Func) const { |
2735 if (!ALLOW_DUMP) | 2735 if (!buildAllowsDump()) |
2736 return; | 2736 return; |
2737 assert(getDest()->getType() == IceType_v8i16 || | 2737 assert(getDest()->getType() == IceType_v8i16 || |
2738 getDest()->getType() == IceType_v8i1 || | 2738 getDest()->getType() == IceType_v8i1 || |
2739 getDest()->getType() == IceType_v4i32 || | 2739 getDest()->getType() == IceType_v4i32 || |
2740 getDest()->getType() == IceType_v4i1); | 2740 getDest()->getType() == IceType_v4i1); |
2741 char buf[30]; | 2741 char buf[30]; |
2742 snprintf(buf, llvm::array_lengthof(buf), "psll%s", | 2742 snprintf(buf, llvm::array_lengthof(buf), "psll%s", |
2743 TypeX8632Attributes[getDest()->getType()].PackString); | 2743 TypeX8632Attributes[getDest()->getType()].PackString); |
2744 emitTwoAddress(buf, this, Func); | 2744 emitTwoAddress(buf, this, Func); |
2745 } | 2745 } |
2746 | 2746 |
2747 template <> void InstX8632Psra::emit(const Cfg *Func) const { | 2747 template <> void InstX8632Psra::emit(const Cfg *Func) const { |
2748 if (!ALLOW_DUMP) | 2748 if (!buildAllowsDump()) |
2749 return; | 2749 return; |
2750 assert(getDest()->getType() == IceType_v8i16 || | 2750 assert(getDest()->getType() == IceType_v8i16 || |
2751 getDest()->getType() == IceType_v8i1 || | 2751 getDest()->getType() == IceType_v8i1 || |
2752 getDest()->getType() == IceType_v4i32 || | 2752 getDest()->getType() == IceType_v4i32 || |
2753 getDest()->getType() == IceType_v4i1); | 2753 getDest()->getType() == IceType_v4i1); |
2754 char buf[30]; | 2754 char buf[30]; |
2755 snprintf(buf, llvm::array_lengthof(buf), "psra%s", | 2755 snprintf(buf, llvm::array_lengthof(buf), "psra%s", |
2756 TypeX8632Attributes[getDest()->getType()].PackString); | 2756 TypeX8632Attributes[getDest()->getType()].PackString); |
2757 emitTwoAddress(buf, this, Func); | 2757 emitTwoAddress(buf, this, Func); |
2758 } | 2758 } |
2759 | 2759 |
2760 template <> void InstX8632Psrl::emit(const Cfg *Func) const { | 2760 template <> void InstX8632Psrl::emit(const Cfg *Func) const { |
2761 if (!ALLOW_DUMP) | 2761 if (!buildAllowsDump()) |
2762 return; | 2762 return; |
2763 char buf[30]; | 2763 char buf[30]; |
2764 snprintf(buf, llvm::array_lengthof(buf), "psrl%s", | 2764 snprintf(buf, llvm::array_lengthof(buf), "psrl%s", |
2765 TypeX8632Attributes[getDest()->getType()].PackString); | 2765 TypeX8632Attributes[getDest()->getType()].PackString); |
2766 emitTwoAddress(buf, this, Func); | 2766 emitTwoAddress(buf, this, Func); |
2767 } | 2767 } |
2768 | 2768 |
2769 void InstX8632Ret::emit(const Cfg *Func) const { | 2769 void InstX8632Ret::emit(const Cfg *Func) const { |
2770 if (!ALLOW_DUMP) | 2770 if (!buildAllowsDump()) |
2771 return; | 2771 return; |
2772 Ostream &Str = Func->getContext()->getStrEmit(); | 2772 Ostream &Str = Func->getContext()->getStrEmit(); |
2773 Str << "\tret"; | 2773 Str << "\tret"; |
2774 } | 2774 } |
2775 | 2775 |
2776 void InstX8632Ret::emitIAS(const Cfg *Func) const { | 2776 void InstX8632Ret::emitIAS(const Cfg *Func) const { |
2777 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2777 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2778 Asm->ret(); | 2778 Asm->ret(); |
2779 } | 2779 } |
2780 | 2780 |
2781 void InstX8632Ret::dump(const Cfg *Func) const { | 2781 void InstX8632Ret::dump(const Cfg *Func) const { |
2782 if (!ALLOW_DUMP) | 2782 if (!buildAllowsDump()) |
2783 return; | 2783 return; |
2784 Ostream &Str = Func->getContext()->getStrDump(); | 2784 Ostream &Str = Func->getContext()->getStrDump(); |
2785 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 2785 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
2786 Str << "ret." << Ty << " "; | 2786 Str << "ret." << Ty << " "; |
2787 dumpSources(Func); | 2787 dumpSources(Func); |
2788 } | 2788 } |
2789 | 2789 |
2790 void InstX8632Setcc::emit(const Cfg *Func) const { | 2790 void InstX8632Setcc::emit(const Cfg *Func) const { |
2791 if (!ALLOW_DUMP) | 2791 if (!buildAllowsDump()) |
2792 return; | 2792 return; |
2793 Ostream &Str = Func->getContext()->getStrEmit(); | 2793 Ostream &Str = Func->getContext()->getStrEmit(); |
2794 Str << "\tset" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 2794 Str << "\tset" << InstX8632BrAttributes[Condition].DisplayString << "\t"; |
2795 Dest->emit(Func); | 2795 Dest->emit(Func); |
2796 } | 2796 } |
2797 | 2797 |
2798 void InstX8632Setcc::emitIAS(const Cfg *Func) const { | 2798 void InstX8632Setcc::emitIAS(const Cfg *Func) const { |
2799 assert(Condition != CondX86::Br_None); | 2799 assert(Condition != CondX86::Br_None); |
2800 assert(getDest()->getType() == IceType_i1); | 2800 assert(getDest()->getType() == IceType_i1); |
2801 assert(getSrcSize() == 0); | 2801 assert(getSrcSize() == 0); |
2802 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2802 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2803 if (getDest()->hasReg()) | 2803 if (getDest()->hasReg()) |
2804 Asm->setcc(Condition, RegX8632::getEncodedByteReg(getDest()->getRegNum())); | 2804 Asm->setcc(Condition, RegX8632::getEncodedByteReg(getDest()->getRegNum())); |
2805 else | 2805 else |
2806 Asm->setcc(Condition, static_cast<TargetX8632 *>(Func->getTarget()) | 2806 Asm->setcc(Condition, static_cast<TargetX8632 *>(Func->getTarget()) |
2807 ->stackVarToAsmOperand(getDest())); | 2807 ->stackVarToAsmOperand(getDest())); |
2808 return; | 2808 return; |
2809 } | 2809 } |
2810 | 2810 |
2811 void InstX8632Setcc::dump(const Cfg *Func) const { | 2811 void InstX8632Setcc::dump(const Cfg *Func) const { |
2812 if (!ALLOW_DUMP) | 2812 if (!buildAllowsDump()) |
2813 return; | 2813 return; |
2814 Ostream &Str = Func->getContext()->getStrDump(); | 2814 Ostream &Str = Func->getContext()->getStrDump(); |
2815 Str << "setcc." << InstX8632BrAttributes[Condition].DisplayString << " "; | 2815 Str << "setcc." << InstX8632BrAttributes[Condition].DisplayString << " "; |
2816 dumpDest(Func); | 2816 dumpDest(Func); |
2817 } | 2817 } |
2818 | 2818 |
2819 void InstX8632Xadd::emit(const Cfg *Func) const { | 2819 void InstX8632Xadd::emit(const Cfg *Func) const { |
2820 if (!ALLOW_DUMP) | 2820 if (!buildAllowsDump()) |
2821 return; | 2821 return; |
2822 Ostream &Str = Func->getContext()->getStrEmit(); | 2822 Ostream &Str = Func->getContext()->getStrEmit(); |
2823 if (Locked) { | 2823 if (Locked) { |
2824 Str << "\tlock"; | 2824 Str << "\tlock"; |
2825 } | 2825 } |
2826 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t"; | 2826 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t"; |
2827 getSrc(1)->emit(Func); | 2827 getSrc(1)->emit(Func); |
2828 Str << ", "; | 2828 Str << ", "; |
2829 getSrc(0)->emit(Func); | 2829 getSrc(0)->emit(Func); |
2830 } | 2830 } |
2831 | 2831 |
2832 void InstX8632Xadd::emitIAS(const Cfg *Func) const { | 2832 void InstX8632Xadd::emitIAS(const Cfg *Func) const { |
2833 assert(getSrcSize() == 2); | 2833 assert(getSrcSize() == 2); |
2834 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2834 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2835 Type Ty = getSrc(0)->getType(); | 2835 Type Ty = getSrc(0)->getType(); |
2836 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2836 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
2837 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2837 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2838 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 2838 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
2839 const auto VarReg = llvm::cast<Variable>(getSrc(1)); | 2839 const auto VarReg = llvm::cast<Variable>(getSrc(1)); |
2840 assert(VarReg->hasReg()); | 2840 assert(VarReg->hasReg()); |
2841 const RegX8632::GPRRegister Reg = | 2841 const RegX8632::GPRRegister Reg = |
2842 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2842 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
2843 Asm->xadd(Ty, Addr, Reg, Locked); | 2843 Asm->xadd(Ty, Addr, Reg, Locked); |
2844 } | 2844 } |
2845 | 2845 |
2846 void InstX8632Xadd::dump(const Cfg *Func) const { | 2846 void InstX8632Xadd::dump(const Cfg *Func) const { |
2847 if (!ALLOW_DUMP) | 2847 if (!buildAllowsDump()) |
2848 return; | 2848 return; |
2849 Ostream &Str = Func->getContext()->getStrDump(); | 2849 Ostream &Str = Func->getContext()->getStrDump(); |
2850 if (Locked) { | 2850 if (Locked) { |
2851 Str << "lock "; | 2851 Str << "lock "; |
2852 } | 2852 } |
2853 Type Ty = getSrc(0)->getType(); | 2853 Type Ty = getSrc(0)->getType(); |
2854 Str << "xadd." << Ty << " "; | 2854 Str << "xadd." << Ty << " "; |
2855 dumpSources(Func); | 2855 dumpSources(Func); |
2856 } | 2856 } |
2857 | 2857 |
2858 void InstX8632Xchg::emit(const Cfg *Func) const { | 2858 void InstX8632Xchg::emit(const Cfg *Func) const { |
2859 if (!ALLOW_DUMP) | 2859 if (!buildAllowsDump()) |
2860 return; | 2860 return; |
2861 Ostream &Str = Func->getContext()->getStrEmit(); | 2861 Ostream &Str = Func->getContext()->getStrEmit(); |
2862 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t"; | 2862 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t"; |
2863 getSrc(1)->emit(Func); | 2863 getSrc(1)->emit(Func); |
2864 Str << ", "; | 2864 Str << ", "; |
2865 getSrc(0)->emit(Func); | 2865 getSrc(0)->emit(Func); |
2866 } | 2866 } |
2867 | 2867 |
2868 void InstX8632Xchg::emitIAS(const Cfg *Func) const { | 2868 void InstX8632Xchg::emitIAS(const Cfg *Func) const { |
2869 assert(getSrcSize() == 2); | 2869 assert(getSrcSize() == 2); |
2870 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); | 2870 X8632::AssemblerX8632 *Asm = Func->getAssembler<X8632::AssemblerX8632>(); |
2871 Type Ty = getSrc(0)->getType(); | 2871 Type Ty = getSrc(0)->getType(); |
2872 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2872 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
2873 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 2873 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2874 const X8632::Address Addr = Mem->toAsmAddress(Asm); | 2874 const X8632::Address Addr = Mem->toAsmAddress(Asm); |
2875 const auto VarReg = llvm::cast<Variable>(getSrc(1)); | 2875 const auto VarReg = llvm::cast<Variable>(getSrc(1)); |
2876 assert(VarReg->hasReg()); | 2876 assert(VarReg->hasReg()); |
2877 const RegX8632::GPRRegister Reg = | 2877 const RegX8632::GPRRegister Reg = |
2878 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2878 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
2879 Asm->xchg(Ty, Addr, Reg); | 2879 Asm->xchg(Ty, Addr, Reg); |
2880 } | 2880 } |
2881 | 2881 |
2882 void InstX8632Xchg::dump(const Cfg *Func) const { | 2882 void InstX8632Xchg::dump(const Cfg *Func) const { |
2883 if (!ALLOW_DUMP) | 2883 if (!buildAllowsDump()) |
2884 return; | 2884 return; |
2885 Ostream &Str = Func->getContext()->getStrDump(); | 2885 Ostream &Str = Func->getContext()->getStrDump(); |
2886 Type Ty = getSrc(0)->getType(); | 2886 Type Ty = getSrc(0)->getType(); |
2887 Str << "xchg." << Ty << " "; | 2887 Str << "xchg." << Ty << " "; |
2888 dumpSources(Func); | 2888 dumpSources(Func); |
2889 } | 2889 } |
2890 | 2890 |
2891 void OperandX8632Mem::emit(const Cfg *Func) const { | 2891 void OperandX8632Mem::emit(const Cfg *Func) const { |
2892 if (!ALLOW_DUMP) | 2892 if (!buildAllowsDump()) |
2893 return; | 2893 return; |
2894 Ostream &Str = Func->getContext()->getStrEmit(); | 2894 Ostream &Str = Func->getContext()->getStrEmit(); |
2895 if (SegmentReg != DefaultSegment) { | 2895 if (SegmentReg != DefaultSegment) { |
2896 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | 2896 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
2897 Str << "%" << InstX8632SegmentRegNames[SegmentReg] << ":"; | 2897 Str << "%" << InstX8632SegmentRegNames[SegmentReg] << ":"; |
2898 } | 2898 } |
2899 // Emit as Offset(Base,Index,1<<Shift). | 2899 // Emit as Offset(Base,Index,1<<Shift). |
2900 // Offset is emitted without the leading '$'. | 2900 // Offset is emitted without the leading '$'. |
2901 // Omit the (Base,Index,1<<Shift) part if Base==nullptr. | 2901 // Omit the (Base,Index,1<<Shift) part if Base==nullptr. |
2902 if (!Offset) { | 2902 if (!Offset) { |
(...skipping 15 matching lines...) Expand all Loading... |
2918 Str << ","; | 2918 Str << ","; |
2919 Index->emit(Func); | 2919 Index->emit(Func); |
2920 if (Shift) | 2920 if (Shift) |
2921 Str << "," << (1u << Shift); | 2921 Str << "," << (1u << Shift); |
2922 } | 2922 } |
2923 Str << ")"; | 2923 Str << ")"; |
2924 } | 2924 } |
2925 } | 2925 } |
2926 | 2926 |
2927 void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const { | 2927 void OperandX8632Mem::dump(const Cfg *Func, Ostream &Str) const { |
2928 if (!ALLOW_DUMP) | 2928 if (!buildAllowsDump()) |
2929 return; | 2929 return; |
2930 if (SegmentReg != DefaultSegment) { | 2930 if (SegmentReg != DefaultSegment) { |
2931 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); | 2931 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
2932 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; | 2932 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; |
2933 } | 2933 } |
2934 bool Dumped = false; | 2934 bool Dumped = false; |
2935 Str << "["; | 2935 Str << "["; |
2936 if (Base) { | 2936 if (Base) { |
2937 if (Func) | 2937 if (Func) |
2938 Base->dump(Func); | 2938 Base->dump(Func); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3019 X8632::Address VariableSplit::toAsmAddress(const Cfg *Func) const { | 3019 X8632::Address VariableSplit::toAsmAddress(const Cfg *Func) const { |
3020 assert(!Var->hasReg()); | 3020 assert(!Var->hasReg()); |
3021 const TargetLowering *Target = Func->getTarget(); | 3021 const TargetLowering *Target = Func->getTarget(); |
3022 int32_t Offset = | 3022 int32_t Offset = |
3023 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 3023 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
3024 return X8632::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), | 3024 return X8632::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), |
3025 Offset); | 3025 Offset); |
3026 } | 3026 } |
3027 | 3027 |
3028 void VariableSplit::emit(const Cfg *Func) const { | 3028 void VariableSplit::emit(const Cfg *Func) const { |
3029 if (!ALLOW_DUMP) | 3029 if (!buildAllowsDump()) |
3030 return; | 3030 return; |
3031 Ostream &Str = Func->getContext()->getStrEmit(); | 3031 Ostream &Str = Func->getContext()->getStrEmit(); |
3032 assert(!Var->hasReg()); | 3032 assert(!Var->hasReg()); |
3033 // The following is copied/adapted from TargetX8632::emitVariable(). | 3033 // The following is copied/adapted from TargetX8632::emitVariable(). |
3034 const TargetLowering *Target = Func->getTarget(); | 3034 const TargetLowering *Target = Func->getTarget(); |
3035 const Type Ty = IceType_i32; | 3035 const Type Ty = IceType_i32; |
3036 int32_t Offset = | 3036 int32_t Offset = |
3037 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); | 3037 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
3038 if (Offset) | 3038 if (Offset) |
3039 Str << Offset; | 3039 Str << Offset; |
3040 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; | 3040 Str << "(%" << Target->getRegName(Target->getFrameOrStackReg(), Ty) << ")"; |
3041 } | 3041 } |
3042 | 3042 |
3043 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { | 3043 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { |
3044 if (!ALLOW_DUMP) | 3044 if (!buildAllowsDump()) |
3045 return; | 3045 return; |
3046 switch (Part) { | 3046 switch (Part) { |
3047 case Low: | 3047 case Low: |
3048 Str << "low"; | 3048 Str << "low"; |
3049 break; | 3049 break; |
3050 case High: | 3050 case High: |
3051 Str << "high"; | 3051 Str << "high"; |
3052 break; | 3052 break; |
3053 } | 3053 } |
3054 Str << "("; | 3054 Str << "("; |
3055 if (Func) | 3055 if (Func) |
3056 Var->dump(Func); | 3056 Var->dump(Func); |
3057 else | 3057 else |
3058 Var->dump(Str); | 3058 Var->dump(Str); |
3059 Str << ")"; | 3059 Str << ")"; |
3060 } | 3060 } |
3061 | 3061 |
3062 } // end of namespace Ice | 3062 } // end of namespace Ice |
OLD | NEW |