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

Side by Side Diff: src/IceInstX8632.cpp

Issue 700263003: Rearrange emit vs emitIAS. Wait till function is done before dumping text. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file implements the InstX8632 and OperandX8632 classes, 10 // This file implements the InstX8632 and OperandX8632 classes,
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 } 335 }
336 336
337 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) 337 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source)
338 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { 338 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) {
339 addSource(Dest); 339 addSource(Dest);
340 addSource(Source); 340 addSource(Source);
341 } 341 }
342 342
343 // ======================== Dump routines ======================== // 343 // ======================== Dump routines ======================== //
344 344
345 namespace {
Jim Stichnoth 2014/11/06 00:02:13 Sweet!
346
347 void emitIASBytes(const Cfg *Func, const x86::AssemblerX86 *Asm,
348 intptr_t StartPosition) {
349 GlobalContext *Ctx = Func->getContext();
350 Ostream &Str = Ctx->getStrEmit();
351 intptr_t EndPosition = Asm->GetPosition();
352 AssemblerFixup *LastFixup = Asm->GetLatestFixup(StartPosition);
353 if (!LastFixup) {
354 // The fixup doesn't apply to this current block.
355 for (intptr_t i = StartPosition; i < EndPosition; ++i) {
356 Str << "\t.byte 0x";
357 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
358 Str << "\n";
359 }
360 return;
361 }
362 intptr_t LastFixupLoc = LastFixup->position();
363 const intptr_t FixupSize = 4;
364 // The fixup does apply to this current block.
365 for (intptr_t i = StartPosition; i < LastFixupLoc; ++i) {
366 Str << "\t.byte 0x";
367 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
368 Str << "\n";
369 }
370 while (LastFixup) {
371 Str << "\t.long ";
372 const ConstantRelocatable *Reloc = LastFixup->value();
373 if (Reloc->getSuppressMangling())
374 Str << Reloc->getName();
375 else
376 Str << Ctx->mangleName(Reloc->getName());
377 if (LastFixup->value()->getOffset()) {
378 Str << " + " << LastFixup->value()->getOffset();
379 }
380 Str << "\n";
381 LastFixupLoc += FixupSize;
382 assert(LastFixupLoc <= EndPosition);
383 LastFixup = Asm->GetLatestFixup(LastFixupLoc);
384 // Assume multi-fixups are adjacent in the instruction encoding.
385 assert(!LastFixup || LastFixup->position() == LastFixupLoc);
386 }
387 for (intptr_t i = LastFixupLoc; i < EndPosition; ++i) {
388 Str << "\t.byte 0x";
389 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
390 Str << "\n";
391 }
392 }
393
394 void emitIASBytesBranch(const Cfg *Func, const x86::AssemblerX86 *Asm,
395 intptr_t StartPosition, const x86::Label *Label,
396 const IceString &LabelName, bool Near) {
397 // If this is a backward branch (label is bound), we're good and know
398 // the offset. If this is a forward branch, then we can't actually emit
399 // the thing as text in a streaming manner, because the fixup hasn't
400 // happened yet. Instead, emit .long ($BranchLabel) - (. + 4), in that
401 // case and let the external assembler take care of that fixup.
402 if (Label->IsBound()) {
403 emitIASBytes(Func, Asm, StartPosition);
404 return;
405 }
406 const intptr_t FwdBranchSize = Near ? 1 : 4;
407 const IceString FwdBranchDirective = Near ? ".byte" : ".long";
408 Ostream &Str = Func->getContext()->getStrEmit();
409 intptr_t EndPosition = Asm->GetPosition();
410 assert(EndPosition - StartPosition > FwdBranchSize);
411 for (intptr_t i = StartPosition; i < EndPosition - FwdBranchSize; ++i) {
412 Str << "\t.byte 0x";
413 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
414 Str << "\n";
415 }
416 Str << "\t" << FwdBranchDirective << " " << LabelName << " - (. + "
417 << FwdBranchSize << ")\n";
418 return;
419 }
420
421 } // end of anonymous namespace
422
423 void InstX8632::dump(const Cfg *Func) const { 345 void InstX8632::dump(const Cfg *Func) const {
424 Ostream &Str = Func->getContext()->getStrDump(); 346 Ostream &Str = Func->getContext()->getStrDump();
425 Str << "[X8632] "; 347 Str << "[X8632] ";
426 Inst::dump(Func); 348 Inst::dump(Func);
427 } 349 }
428 350
429 void InstX8632Label::emit(const Cfg *Func) const { 351 void InstX8632Label::emit(const Cfg *Func) const {
430 Ostream &Str = Func->getContext()->getStrEmit(); 352 Ostream &Str = Func->getContext()->getStrEmit();
431 Str << getName(Func) << ":"; 353 Str << getName(Func) << ":";
432 } 354 }
433 355
434 void InstX8632Label::emitIAS(const Cfg *Func) const { 356 void InstX8632Label::emitIAS(const Cfg *Func) const {
435 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 357 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
436 Asm->BindLocalLabel(Number); 358 Asm->BindLocalLabel(Number);
437 // TODO(jvoung): remove the the textual label once forward branch
438 // fixups are used (and text assembler is not used).
439 Ostream &Str = Func->getContext()->getStrEmit();
440 Str << getName(Func) << ":\n";
441 } 359 }
442 360
443 void InstX8632Label::dump(const Cfg *Func) const { 361 void InstX8632Label::dump(const Cfg *Func) const {
444 Ostream &Str = Func->getContext()->getStrDump(); 362 Ostream &Str = Func->getContext()->getStrDump();
445 Str << getName(Func) << ":"; 363 Str << getName(Func) << ":";
446 } 364 }
447 365
448 void InstX8632Br::emit(const Cfg *Func) const { 366 void InstX8632Br::emit(const Cfg *Func) const {
449 Ostream &Str = Func->getContext()->getStrEmit(); 367 Ostream &Str = Func->getContext()->getStrEmit();
450 Str << "\t"; 368 Str << "\t";
(...skipping 13 matching lines...) Expand all
464 Str << "\t" << getTargetTrue()->getAsmName(); 382 Str << "\t" << getTargetTrue()->getAsmName();
465 if (getTargetFalse()) { 383 if (getTargetFalse()) {
466 Str << "\n\tjmp\t" << getTargetFalse()->getAsmName(); 384 Str << "\n\tjmp\t" << getTargetFalse()->getAsmName();
467 } 385 }
468 } 386 }
469 } 387 }
470 } 388 }
471 389
472 void InstX8632Br::emitIAS(const Cfg *Func) const { 390 void InstX8632Br::emitIAS(const Cfg *Func) const {
473 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 391 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
474 intptr_t StartPosition = Asm->GetPosition();
475 if (Label) { 392 if (Label) {
476 x86::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber()); 393 x86::Label *L = Asm->GetOrCreateLocalLabel(Label->getNumber());
477 // In all these cases, local Labels should only be used for Near. 394 // In all these cases, local Labels should only be used for Near.
478 const bool Near = true; 395 const bool Near = true;
479 if (Condition == CondX86::Br_None) { 396 if (Condition == CondX86::Br_None) {
480 Asm->jmp(L, Near); 397 Asm->jmp(L, Near);
481 } else { 398 } else {
482 Asm->j(Condition, L, Near); 399 Asm->j(Condition, L, Near);
483 } 400 }
484 emitIASBytesBranch(Func, Asm, StartPosition, L, Label->getName(Func), Near);
485 } else { 401 } else {
486 // Pessimistically assume it's far. This only affects Labels that 402 // Pessimistically assume it's far. This only affects Labels that
487 // are not Bound. 403 // are not Bound.
488 const bool Near = false; 404 const bool Near = false;
489 if (Condition == CondX86::Br_None) { 405 if (Condition == CondX86::Br_None) {
490 x86::Label *L = 406 x86::Label *L =
491 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); 407 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
492 assert(!getTargetTrue()); 408 assert(!getTargetTrue());
493 Asm->jmp(L, Near); 409 Asm->jmp(L, Near);
494 emitIASBytesBranch(Func, Asm, StartPosition, L,
495 getTargetFalse()->getAsmName(), Near);
496 } else { 410 } else {
497 x86::Label *L = Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex()); 411 x86::Label *L = Asm->GetOrCreateCfgNodeLabel(getTargetTrue()->getIndex());
498 Asm->j(Condition, L, Near); 412 Asm->j(Condition, L, Near);
499 emitIASBytesBranch(Func, Asm, StartPosition, L,
500 getTargetTrue()->getAsmName(), Near);
501 StartPosition = Asm->GetPosition();
502 if (getTargetFalse()) { 413 if (getTargetFalse()) {
503 x86::Label *L2 = 414 x86::Label *L2 =
504 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex()); 415 Asm->GetOrCreateCfgNodeLabel(getTargetFalse()->getIndex());
505 Asm->jmp(L2, Near); 416 Asm->jmp(L2, Near);
506 emitIASBytesBranch(Func, Asm, StartPosition, L2,
507 getTargetFalse()->getAsmName(), Near);
508 } 417 }
509 } 418 }
510 } 419 }
511 } 420 }
512 421
513 void InstX8632Br::dump(const Cfg *Func) const { 422 void InstX8632Br::dump(const Cfg *Func) const {
514 Ostream &Str = Func->getContext()->getStrDump(); 423 Ostream &Str = Func->getContext()->getStrDump();
515 Str << "br "; 424 Str << "br ";
516 425
517 if (Condition == CondX86::Br_None) { 426 if (Condition == CondX86::Br_None) {
(...skipping 24 matching lines...) Expand all
542 CallTarget->emitWithoutDollar(Func->getContext()); 451 CallTarget->emitWithoutDollar(Func->getContext());
543 } else { 452 } else {
544 Str << "*"; 453 Str << "*";
545 getCallTarget()->emit(Func); 454 getCallTarget()->emit(Func);
546 } 455 }
547 Func->getTarget()->resetStackAdjustment(); 456 Func->getTarget()->resetStackAdjustment();
548 } 457 }
549 458
550 void InstX8632Call::emitIAS(const Cfg *Func) const { 459 void InstX8632Call::emitIAS(const Cfg *Func) const {
551 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 460 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
552 intptr_t StartPosition = Asm->GetPosition();
553 Operand *Target = getCallTarget(); 461 Operand *Target = getCallTarget();
554 bool NeedsFallback = false;
555 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { 462 if (const auto Var = llvm::dyn_cast<Variable>(Target)) {
556 if (Var->hasReg()) { 463 if (Var->hasReg()) {
557 Asm->call(RegX8632::getEncodedGPR(Var->getRegNum())); 464 Asm->call(RegX8632::getEncodedGPR(Var->getRegNum()));
558 } else { 465 } else {
559 Asm->call(static_cast<TargetX8632 *>(Func->getTarget()) 466 Asm->call(static_cast<TargetX8632 *>(Func->getTarget())
560 ->stackVarToAsmOperand(Var)); 467 ->stackVarToAsmOperand(Var));
561 } 468 }
562 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { 469 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) {
563 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 470 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
564 Asm->call(Mem->toAsmAddress(Asm)); 471 Asm->call(Mem->toAsmAddress(Asm));
565 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { 472 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) {
566 assert(CR->getOffset() == 0 && "We only support calling a function"); 473 assert(CR->getOffset() == 0 && "We only support calling a function");
567 Asm->call(CR); 474 Asm->call(CR);
568 NeedsFallback = true;
569 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { 475 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) {
570 // NaCl trampoline calls refer to an address within the sandbox directly. 476 // NaCl trampoline calls refer to an address within the sandbox directly.
571 // This is usually only needed for non-IRT builds and otherwise not 477 // This is usually only needed for non-IRT builds and otherwise not
572 // very portable or stable. For this, we would use the 0xE8 opcode 478 // very portable or stable. For this, we would use the 0xE8 opcode
573 // (relative version of call) and there should be a PC32 reloc too. 479 // (relative version of call) and there should be a PC32 reloc too.
574 // The PC32 reloc will have symbol index 0, and the absolute address 480 // The PC32 reloc will have symbol index 0, and the absolute address
575 // would be encoded as an offset relative to the next instruction. 481 // would be encoded as an offset relative to the next instruction.
576 // TODO(jvoung): Do we need to support this? 482 // TODO(jvoung): Do we need to support this?
577 (void)Imm; 483 (void)Imm;
578 llvm_unreachable("Unexpected call to absolute address"); 484 llvm_unreachable("Unexpected call to absolute address");
579 } else { 485 } else {
580 llvm_unreachable("Unexpected operand type"); 486 llvm_unreachable("Unexpected operand type");
581 } 487 }
582 if (NeedsFallback) {
583 // TODO(jvoung): The ".long sym" hack doesn't work, since we need
584 // a pc-rel relocation and not an absolute relocation.
585 //
586 // Still, we have at least filled the assembler buffer so that the
587 // instruction sizes/positions are correct for jumps.
588 // For now, fall back to the regular .s emission, after filling the buffer.
589 emit(Func);
590 Func->getContext()->getStrEmit() << "\n";
591 } else {
592 emitIASBytes(Func, Asm, StartPosition);
593 }
594 Func->getTarget()->resetStackAdjustment(); 488 Func->getTarget()->resetStackAdjustment();
595 } 489 }
596 490
597 void InstX8632Call::dump(const Cfg *Func) const { 491 void InstX8632Call::dump(const Cfg *Func) const {
598 Ostream &Str = Func->getContext()->getStrDump(); 492 Ostream &Str = Func->getContext()->getStrDump();
599 if (getDest()) { 493 if (getDest()) {
600 dumpDest(Func); 494 dumpDest(Func);
601 Str << " = "; 495 Str << " = ";
602 } 496 }
603 Str << "call "; 497 Str << "call ";
(...skipping 17 matching lines...) Expand all
621 Str << "%cl"; 515 Str << "%cl";
622 else 516 else
623 Src1->emit(Func); 517 Src1->emit(Func);
624 Str << ", "; 518 Str << ", ";
625 Dest->emit(Func); 519 Dest->emit(Func);
626 } 520 }
627 521
628 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, 522 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op,
629 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { 523 const x86::AssemblerX86::GPREmitterOneOp &Emitter) {
630 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 524 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
631 intptr_t StartPosition = Asm->GetPosition();
632 if (const auto Var = llvm::dyn_cast<Variable>(Op)) { 525 if (const auto Var = llvm::dyn_cast<Variable>(Op)) {
633 if (Var->hasReg()) { 526 if (Var->hasReg()) {
634 // We cheat a little and use GPRRegister even for byte operations. 527 // We cheat a little and use GPRRegister even for byte operations.
635 RegX8632::GPRRegister VarReg = 528 RegX8632::GPRRegister VarReg =
636 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); 529 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
637 (Asm->*(Emitter.Reg))(Ty, VarReg); 530 (Asm->*(Emitter.Reg))(Ty, VarReg);
638 } else { 531 } else {
639 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 532 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
640 ->stackVarToAsmOperand(Var)); 533 ->stackVarToAsmOperand(Var));
641 (Asm->*(Emitter.Addr))(Ty, StackAddr); 534 (Asm->*(Emitter.Addr))(Ty, StackAddr);
642 } 535 }
643 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { 536 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) {
644 Mem->emitSegmentOverride(Asm); 537 Mem->emitSegmentOverride(Asm);
645 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); 538 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm));
646 } else { 539 } else {
647 llvm_unreachable("Unexpected operand type"); 540 llvm_unreachable("Unexpected operand type");
648 } 541 }
649 emitIASBytes(Func, Asm, StartPosition);
650 } 542 }
651 543
652 template <bool VarCanBeByte, bool SrcCanBeByte> 544 template <bool VarCanBeByte, bool SrcCanBeByte>
653 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, 545 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
654 const Operand *Src, 546 const Operand *Src,
655 const x86::AssemblerX86::GPREmitterRegOp &Emitter) { 547 const x86::AssemblerX86::GPREmitterRegOp &Emitter) {
656 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 548 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
657 intptr_t StartPosition = Asm->GetPosition();
658 assert(Var->hasReg()); 549 assert(Var->hasReg());
659 // We cheat a little and use GPRRegister even for byte operations. 550 // We cheat a little and use GPRRegister even for byte operations.
660 RegX8632::GPRRegister VarReg = 551 RegX8632::GPRRegister VarReg =
661 VarCanBeByte ? RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()) 552 VarCanBeByte ? RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum())
662 : RegX8632::getEncodedGPR(Var->getRegNum()); 553 : RegX8632::getEncodedGPR(Var->getRegNum());
663 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { 554 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
664 if (SrcVar->hasReg()) { 555 if (SrcVar->hasReg()) {
665 RegX8632::GPRRegister SrcReg = 556 RegX8632::GPRRegister SrcReg =
666 SrcCanBeByte 557 SrcCanBeByte
667 ? RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()) 558 ? RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum())
(...skipping 11 matching lines...) Expand all
679 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); 570 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue()));
680 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { 571 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
681 AssemblerFixup *Fixup = 572 AssemblerFixup *Fixup =
682 x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc); 573 x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc);
683 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Fixup)); 574 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Fixup));
684 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) { 575 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) {
685 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); 576 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
686 } else { 577 } else {
687 llvm_unreachable("Unexpected operand type"); 578 llvm_unreachable("Unexpected operand type");
688 } 579 }
689 emitIASBytes(Func, Asm, StartPosition);
690 } 580 }
691 581
692 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, 582 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr,
693 const Operand *Src, 583 const Operand *Src,
694 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { 584 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) {
695 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 585 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
696 intptr_t StartPosition = Asm->GetPosition();
697 // Src can only be Reg or Immediate. 586 // Src can only be Reg or Immediate.
698 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { 587 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
699 assert(SrcVar->hasReg()); 588 assert(SrcVar->hasReg());
700 RegX8632::GPRRegister SrcReg = 589 RegX8632::GPRRegister SrcReg =
701 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); 590 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum());
702 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); 591 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg);
703 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { 592 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
704 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue())); 593 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue()));
705 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { 594 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
706 AssemblerFixup *Fixup = 595 AssemblerFixup *Fixup =
707 x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc); 596 x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc);
708 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Fixup)); 597 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Fixup));
709 } else { 598 } else {
710 llvm_unreachable("Unexpected operand type"); 599 llvm_unreachable("Unexpected operand type");
711 } 600 }
712 emitIASBytes(Func, Asm, StartPosition);
713 } 601 }
714 602
715 void emitIASAsAddrOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op0, 603 void emitIASAsAddrOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op0,
716 const Operand *Op1, 604 const Operand *Op1,
717 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { 605 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) {
718 if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) { 606 if (const auto Op0Var = llvm::dyn_cast<Variable>(Op0)) {
719 assert(!Op0Var->hasReg()); 607 assert(!Op0Var->hasReg());
720 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 608 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
721 ->stackVarToAsmOperand(Op0Var)); 609 ->stackVarToAsmOperand(Op0Var));
722 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter); 610 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Op1, Emitter);
723 } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) { 611 } else if (const auto Op0Mem = llvm::dyn_cast<OperandX8632Mem>(Op0)) {
724 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 612 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
725 Op0Mem->emitSegmentOverride(Asm); 613 Op0Mem->emitSegmentOverride(Asm);
726 emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter); 614 emitIASAddrOpTyGPR(Func, Ty, Op0Mem->toAsmAddress(Asm), Op1, Emitter);
727 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) { 615 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Op0)) {
728 emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter); 616 emitIASAddrOpTyGPR(Func, Ty, Split->toAsmAddress(Func), Op1, Emitter);
729 } else { 617 } else {
730 llvm_unreachable("Unexpected operand type"); 618 llvm_unreachable("Unexpected operand type");
731 } 619 }
732 } 620 }
733 621
734 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, 622 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
735 const Operand *Src, 623 const Operand *Src,
736 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { 624 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) {
737 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 625 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
738 intptr_t StartPosition = Asm->GetPosition();
739 // Technically, the Dest Var can be mem as well, but we only use Reg. 626 // Technically, the Dest Var can be mem as well, but we only use Reg.
740 // We can extend this to check Dest if we decide to use that form. 627 // We can extend this to check Dest if we decide to use that form.
741 assert(Var->hasReg()); 628 assert(Var->hasReg());
742 // We cheat a little and use GPRRegister even for byte operations. 629 // We cheat a little and use GPRRegister even for byte operations.
743 RegX8632::GPRRegister VarReg = 630 RegX8632::GPRRegister VarReg =
744 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); 631 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
745 // Src must be reg == ECX or an Imm8. 632 // Src must be reg == ECX or an Imm8.
746 // This is asserted by the assembler. 633 // This is asserted by the assembler.
747 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { 634 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
748 assert(SrcVar->hasReg()); 635 assert(SrcVar->hasReg());
749 RegX8632::GPRRegister SrcReg = 636 RegX8632::GPRRegister SrcReg =
750 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); 637 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum());
751 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); 638 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
752 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { 639 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
753 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); 640 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue()));
754 } else { 641 } else {
755 llvm_unreachable("Unexpected operand type"); 642 llvm_unreachable("Unexpected operand type");
756 } 643 }
757 emitIASBytes(Func, Asm, StartPosition);
758 } 644 }
759 645
760 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest, 646 void emitIASGPRShiftDouble(const Cfg *Func, const Variable *Dest,
761 const Operand *Src1Op, const Operand *Src2Op, 647 const Operand *Src1Op, const Operand *Src2Op,
762 const x86::AssemblerX86::GPREmitterShiftD &Emitter) { 648 const x86::AssemblerX86::GPREmitterShiftD &Emitter) {
763 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 649 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
764 intptr_t StartPosition = Asm->GetPosition();
765 // Dest can be reg or mem, but we only use the reg variant. 650 // Dest can be reg or mem, but we only use the reg variant.
766 assert(Dest->hasReg()); 651 assert(Dest->hasReg());
767 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum()); 652 RegX8632::GPRRegister DestReg = RegX8632::getEncodedGPR(Dest->getRegNum());
768 // SrcVar1 must be reg. 653 // SrcVar1 must be reg.
769 const auto SrcVar1 = llvm::cast<Variable>(Src1Op); 654 const auto SrcVar1 = llvm::cast<Variable>(Src1Op);
770 assert(SrcVar1->hasReg()); 655 assert(SrcVar1->hasReg());
771 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(SrcVar1->getRegNum()); 656 RegX8632::GPRRegister SrcReg = RegX8632::getEncodedGPR(SrcVar1->getRegNum());
772 Type Ty = SrcVar1->getType(); 657 Type Ty = SrcVar1->getType();
773 // Src2 can be the implicit CL register or an immediate. 658 // Src2 can be the implicit CL register or an immediate.
774 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) { 659 if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src2Op)) {
775 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg, 660 (Asm->*(Emitter.GPRGPRImm))(Ty, DestReg, SrcReg,
776 x86::Immediate(Imm->getValue())); 661 x86::Immediate(Imm->getValue()));
777 } else { 662 } else {
778 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx); 663 assert(llvm::cast<Variable>(Src2Op)->getRegNum() == RegX8632::Reg_ecx);
779 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg); 664 (Asm->*(Emitter.GPRGPR))(Ty, DestReg, SrcReg);
780 } 665 }
781 emitIASBytes(Func, Asm, StartPosition);
782 } 666 }
783 667
784 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, 668 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
785 const Operand *Src, 669 const Operand *Src,
786 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) { 670 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) {
787 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 671 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
788 intptr_t StartPosition = Asm->GetPosition();
789 assert(Var->hasReg()); 672 assert(Var->hasReg());
790 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); 673 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum());
791 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { 674 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
792 if (SrcVar->hasReg()) { 675 if (SrcVar->hasReg()) {
793 RegX8632::XmmRegister SrcReg = 676 RegX8632::XmmRegister SrcReg =
794 RegX8632::getEncodedXmm(SrcVar->getRegNum()); 677 RegX8632::getEncodedXmm(SrcVar->getRegNum());
795 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); 678 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
796 } else { 679 } else {
797 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 680 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
798 ->stackVarToAsmOperand(SrcVar); 681 ->stackVarToAsmOperand(SrcVar);
799 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); 682 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
800 } 683 }
801 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { 684 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
802 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 685 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
803 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); 686 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
804 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) { 687 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
805 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); 688 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue()));
806 } else { 689 } else {
807 llvm_unreachable("Unexpected operand type"); 690 llvm_unreachable("Unexpected operand type");
808 } 691 }
809 emitIASBytes(Func, Asm, StartPosition);
810 } 692 }
811 693
812 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, 694 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
813 const Operand *Src, 695 const Operand *Src,
814 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { 696 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) {
815 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 697 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
816 intptr_t StartPosition = Asm->GetPosition();
817 assert(Var->hasReg()); 698 assert(Var->hasReg());
818 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); 699 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum());
819 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { 700 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
820 if (SrcVar->hasReg()) { 701 if (SrcVar->hasReg()) {
821 RegX8632::XmmRegister SrcReg = 702 RegX8632::XmmRegister SrcReg =
822 RegX8632::getEncodedXmm(SrcVar->getRegNum()); 703 RegX8632::getEncodedXmm(SrcVar->getRegNum());
823 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); 704 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
824 } else { 705 } else {
825 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 706 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
826 ->stackVarToAsmOperand(SrcVar); 707 ->stackVarToAsmOperand(SrcVar);
827 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); 708 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
828 } 709 }
829 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { 710 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
830 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 711 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
831 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); 712 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
832 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { 713 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
833 (Asm->*(Emitter.XmmAddr))( 714 (Asm->*(Emitter.XmmAddr))(
834 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); 715 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
835 } else { 716 } else {
836 llvm_unreachable("Unexpected operand type"); 717 llvm_unreachable("Unexpected operand type");
837 } 718 }
838 emitIASBytes(Func, Asm, StartPosition);
839 } 719 }
840 720
841 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), 721 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t),
842 SReg_t (*srcEnc)(int32_t)> 722 SReg_t (*srcEnc)(int32_t)>
843 void emitIASCastRegOp( 723 void emitIASCastRegOp(
844 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, 724 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src,
845 const x86::AssemblerX86::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { 725 const x86::AssemblerX86::CastEmitterRegOp<DReg_t, SReg_t> Emitter) {
846 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 726 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
847 intptr_t StartPosition = Asm->GetPosition();
848 assert(Dest->hasReg()); 727 assert(Dest->hasReg());
849 DReg_t DestReg = destEnc(Dest->getRegNum()); 728 DReg_t DestReg = destEnc(Dest->getRegNum());
850 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { 729 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
851 if (SrcVar->hasReg()) { 730 if (SrcVar->hasReg()) {
852 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); 731 SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
853 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); 732 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg);
854 } else { 733 } else {
855 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 734 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
856 ->stackVarToAsmOperand(SrcVar); 735 ->stackVarToAsmOperand(SrcVar);
857 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); 736 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr);
858 } 737 }
859 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { 738 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
860 Mem->emitSegmentOverride(Asm); 739 Mem->emitSegmentOverride(Asm);
861 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm)); 740 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm));
862 } else { 741 } else {
863 llvm_unreachable("Unexpected operand type"); 742 llvm_unreachable("Unexpected operand type");
864 } 743 }
865 emitIASBytes(Func, Asm, StartPosition);
866 } 744 }
867 745
868 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), 746 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t),
869 SReg_t (*srcEnc)(int32_t)> 747 SReg_t (*srcEnc)(int32_t)>
870 void emitIASThreeOpImmOps( 748 void emitIASThreeOpImmOps(
871 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0, 749 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src0,
872 const Operand *Src1, 750 const Operand *Src1,
873 const x86::AssemblerX86::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) { 751 const x86::AssemblerX86::ThreeOpImmEmitter<DReg_t, SReg_t> Emitter) {
874 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 752 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
875 intptr_t StartPosition = Asm->GetPosition();
876 // This only handles Dest being a register, and Src1 being an immediate. 753 // This only handles Dest being a register, and Src1 being an immediate.
877 assert(Dest->hasReg()); 754 assert(Dest->hasReg());
878 DReg_t DestReg = destEnc(Dest->getRegNum()); 755 DReg_t DestReg = destEnc(Dest->getRegNum());
879 x86::Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue()); 756 x86::Immediate Imm(llvm::cast<ConstantInteger32>(Src1)->getValue());
880 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) { 757 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src0)) {
881 if (SrcVar->hasReg()) { 758 if (SrcVar->hasReg()) {
882 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); 759 SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
883 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm); 760 (Asm->*(Emitter.RegRegImm))(DispatchTy, DestReg, SrcReg, Imm);
884 } else { 761 } else {
885 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 762 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
886 ->stackVarToAsmOperand(SrcVar); 763 ->stackVarToAsmOperand(SrcVar);
887 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm); 764 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, SrcStackAddr, Imm);
888 } 765 }
889 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src0)) { 766 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src0)) {
890 Mem->emitSegmentOverride(Asm); 767 Mem->emitSegmentOverride(Asm);
891 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm), 768 (Asm->*(Emitter.RegAddrImm))(DispatchTy, DestReg, Mem->toAsmAddress(Asm),
892 Imm); 769 Imm);
893 } else { 770 } else {
894 llvm_unreachable("Unexpected operand type"); 771 llvm_unreachable("Unexpected operand type");
895 } 772 }
896 emitIASBytes(Func, Asm, StartPosition);
897 } 773 }
898 774
899 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, 775 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest,
900 const Operand *Src, 776 const Operand *Src,
901 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { 777 const x86::AssemblerX86::XmmEmitterMovOps Emitter) {
902 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 778 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
903 intptr_t StartPosition = Asm->GetPosition();
904 if (Dest->hasReg()) { 779 if (Dest->hasReg()) {
905 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); 780 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum());
906 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) { 781 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
907 if (SrcVar->hasReg()) { 782 if (SrcVar->hasReg()) {
908 (Asm->*(Emitter.XmmXmm))(DestReg, 783 (Asm->*(Emitter.XmmXmm))(DestReg,
909 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 784 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
910 } else { 785 } else {
911 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 786 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
912 ->stackVarToAsmOperand(SrcVar)); 787 ->stackVarToAsmOperand(SrcVar));
913 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); 788 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr);
914 } 789 }
915 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) { 790 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
916 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 791 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
917 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); 792 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm));
918 } else { 793 } else {
919 llvm_unreachable("Unexpected operand type"); 794 llvm_unreachable("Unexpected operand type");
920 } 795 }
921 } else { 796 } else {
922 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 797 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
923 ->stackVarToAsmOperand(Dest)); 798 ->stackVarToAsmOperand(Dest));
924 // Src must be a register in this case. 799 // Src must be a register in this case.
925 const auto SrcVar = llvm::cast<Variable>(Src); 800 const auto SrcVar = llvm::cast<Variable>(Src);
926 assert(SrcVar->hasReg()); 801 assert(SrcVar->hasReg());
927 (Asm->*(Emitter.AddrXmm))(StackAddr, 802 (Asm->*(Emitter.AddrXmm))(StackAddr,
928 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 803 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
929 } 804 }
930 emitIASBytes(Func, Asm, StartPosition);
931 } 805 }
932 806
933 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { 807 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) {
934 const auto SrcVar = llvm::dyn_cast<const Variable>(Source); 808 const auto SrcVar = llvm::dyn_cast<const Variable>(Source);
935 if (!SrcVar) 809 if (!SrcVar)
936 return false; 810 return false;
937 if (Dest->hasReg() && Dest->getRegNum() == SrcVar->getRegNum()) { 811 if (Dest->hasReg() && Dest->getRegNum() == SrcVar->getRegNum()) {
938 // TODO: On x86-64, instructions like "mov eax, eax" are used to 812 // TODO: On x86-64, instructions like "mov eax, eax" are used to
939 // clear the upper 32 bits of rax. We need to recognize and 813 // clear the upper 32 bits of rax. We need to recognize and
940 // preserve these. 814 // preserve these.
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 break; 1299 break;
1426 case IceType_i32: 1300 case IceType_i32:
1427 assert(getDest()->getRegNum() == RegX8632::Reg_edx); 1301 assert(getDest()->getRegNum() == RegX8632::Reg_edx);
1428 Str << "\tcltd"; 1302 Str << "\tcltd";
1429 break; 1303 break;
1430 } 1304 }
1431 } 1305 }
1432 1306
1433 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { 1307 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const {
1434 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1308 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1435 intptr_t StartPosition = Asm->GetPosition();
1436 assert(getSrcSize() == 1); 1309 assert(getSrcSize() == 1);
1437 Operand *Src0 = getSrc(0); 1310 Operand *Src0 = getSrc(0);
1438 assert(llvm::isa<Variable>(Src0)); 1311 assert(llvm::isa<Variable>(Src0));
1439 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); 1312 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax);
1440 switch (Src0->getType()) { 1313 switch (Src0->getType()) {
1441 default: 1314 default:
1442 llvm_unreachable("unexpected source type!"); 1315 llvm_unreachable("unexpected source type!");
1443 break; 1316 break;
1444 case IceType_i8: 1317 case IceType_i8:
1445 assert(getDest()->getRegNum() == RegX8632::Reg_eax); 1318 assert(getDest()->getRegNum() == RegX8632::Reg_eax);
1446 Asm->cbw(); 1319 Asm->cbw();
1447 break; 1320 break;
1448 case IceType_i16: 1321 case IceType_i16:
1449 assert(getDest()->getRegNum() == RegX8632::Reg_edx); 1322 assert(getDest()->getRegNum() == RegX8632::Reg_edx);
1450 Asm->cwd(); 1323 Asm->cwd();
1451 break; 1324 break;
1452 case IceType_i32: 1325 case IceType_i32:
1453 assert(getDest()->getRegNum() == RegX8632::Reg_edx); 1326 assert(getDest()->getRegNum() == RegX8632::Reg_edx);
1454 Asm->cdq(); 1327 Asm->cdq();
1455 break; 1328 break;
1456 } 1329 }
1457 emitIASBytes(Func, Asm, StartPosition);
1458 } 1330 }
1459 1331
1460 void InstX8632Mul::emit(const Cfg *Func) const { 1332 void InstX8632Mul::emit(const Cfg *Func) const {
1461 Ostream &Str = Func->getContext()->getStrEmit(); 1333 Ostream &Str = Func->getContext()->getStrEmit();
1462 assert(getSrcSize() == 2); 1334 assert(getSrcSize() == 2);
1463 assert(llvm::isa<Variable>(getSrc(0))); 1335 assert(llvm::isa<Variable>(getSrc(0)));
1464 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 1336 assert(llvm::cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
1465 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 1337 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
1466 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t"; 1338 Str << "\tmul" << getWidthString(getDest()->getType()) << "\t";
1467 getSrc(1)->emit(Func); 1339 getSrc(1)->emit(Func);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 1447
1576 void InstX8632Cmov::emitIAS(const Cfg *Func) const { 1448 void InstX8632Cmov::emitIAS(const Cfg *Func) const {
1577 assert(Condition != CondX86::Br_None); 1449 assert(Condition != CondX86::Br_None);
1578 assert(getDest()->hasReg()); 1450 assert(getDest()->hasReg());
1579 assert(getSrcSize() == 2); 1451 assert(getSrcSize() == 2);
1580 // Only need the reg/reg form now. 1452 // Only need the reg/reg form now.
1581 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); 1453 const auto SrcVar = llvm::cast<Variable>(getSrc(1));
1582 assert(SrcVar->hasReg()); 1454 assert(SrcVar->hasReg());
1583 assert(SrcVar->getType() == IceType_i32); 1455 assert(SrcVar->getType() == IceType_i32);
1584 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1456 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1585 intptr_t StartPosition = Asm->GetPosition();
1586 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), 1457 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()),
1587 RegX8632::getEncodedGPR(SrcVar->getRegNum())); 1458 RegX8632::getEncodedGPR(SrcVar->getRegNum()));
1588 emitIASBytes(Func, Asm, StartPosition);
1589 } 1459 }
1590 1460
1591 void InstX8632Cmov::dump(const Cfg *Func) const { 1461 void InstX8632Cmov::dump(const Cfg *Func) const {
1592 Ostream &Str = Func->getContext()->getStrDump(); 1462 Ostream &Str = Func->getContext()->getStrDump();
1593 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; 1463 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << ".";
1594 Str << getDest()->getType() << " "; 1464 Str << getDest()->getType() << " ";
1595 dumpDest(Func); 1465 dumpDest(Func);
1596 Str << ", "; 1466 Str << ", ";
1597 dumpSources(Func); 1467 dumpSources(Func);
1598 } 1468 }
1599 1469
1600 void InstX8632Cmpps::emit(const Cfg *Func) const { 1470 void InstX8632Cmpps::emit(const Cfg *Func) const {
1601 Ostream &Str = Func->getContext()->getStrEmit(); 1471 Ostream &Str = Func->getContext()->getStrEmit();
1602 assert(getSrcSize() == 2); 1472 assert(getSrcSize() == 2);
1603 assert(Condition < CondX86::Cmpps_Invalid); 1473 assert(Condition < CondX86::Cmpps_Invalid);
1604 Str << "\t"; 1474 Str << "\t";
1605 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1475 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
1606 << "\t"; 1476 << "\t";
1607 getSrc(1)->emit(Func); 1477 getSrc(1)->emit(Func);
1608 Str << ", "; 1478 Str << ", ";
1609 getDest()->emit(Func); 1479 getDest()->emit(Func);
1610 } 1480 }
1611 1481
1612 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { 1482 void InstX8632Cmpps::emitIAS(const Cfg *Func) const {
1613 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1483 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1614 intptr_t StartPosition = Asm->GetPosition();
1615 assert(getSrcSize() == 2); 1484 assert(getSrcSize() == 2);
1616 assert(Condition < CondX86::Cmpps_Invalid); 1485 assert(Condition < CondX86::Cmpps_Invalid);
1617 // Assuming there isn't any load folding for cmpps, and vector constants 1486 // Assuming there isn't any load folding for cmpps, and vector constants
1618 // are not allowed in PNaCl. 1487 // are not allowed in PNaCl.
1619 assert(llvm::isa<Variable>(getSrc(1))); 1488 assert(llvm::isa<Variable>(getSrc(1)));
1620 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); 1489 const auto SrcVar = llvm::cast<Variable>(getSrc(1));
1621 if (SrcVar->hasReg()) { 1490 if (SrcVar->hasReg()) {
1622 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), 1491 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()),
1623 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); 1492 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition);
1624 } else { 1493 } else {
1625 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 1494 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
1626 ->stackVarToAsmOperand(SrcVar); 1495 ->stackVarToAsmOperand(SrcVar);
1627 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, 1496 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr,
1628 Condition); 1497 Condition);
1629 } 1498 }
1630 emitIASBytes(Func, Asm, StartPosition);
1631 } 1499 }
1632 1500
1633 void InstX8632Cmpps::dump(const Cfg *Func) const { 1501 void InstX8632Cmpps::dump(const Cfg *Func) const {
1634 Ostream &Str = Func->getContext()->getStrDump(); 1502 Ostream &Str = Func->getContext()->getStrDump();
1635 assert(Condition < CondX86::Cmpps_Invalid); 1503 assert(Condition < CondX86::Cmpps_Invalid);
1636 dumpDest(Func); 1504 dumpDest(Func);
1637 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1505 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
1638 << "\t"; 1506 << "\t";
1639 dumpSources(Func); 1507 dumpSources(Func);
1640 } 1508 }
1641 1509
1642 void InstX8632Cmpxchg::emit(const Cfg *Func) const { 1510 void InstX8632Cmpxchg::emit(const Cfg *Func) const {
1643 Ostream &Str = Func->getContext()->getStrEmit(); 1511 Ostream &Str = Func->getContext()->getStrEmit();
1644 assert(getSrcSize() == 3); 1512 assert(getSrcSize() == 3);
1645 if (Locked) { 1513 if (Locked) {
1646 Str << "\tlock"; 1514 Str << "\tlock";
1647 } 1515 }
1648 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t"; 1516 Str << "\tcmpxchg" << getWidthString(getSrc(0)->getType()) << "\t";
1649 getSrc(2)->emit(Func); 1517 getSrc(2)->emit(Func);
1650 Str << ", "; 1518 Str << ", ";
1651 getSrc(0)->emit(Func); 1519 getSrc(0)->emit(Func);
1652 } 1520 }
1653 1521
1654 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { 1522 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const {
1655 assert(getSrcSize() == 3); 1523 assert(getSrcSize() == 3);
1656 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1524 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1657 intptr_t StartPosition = Asm->GetPosition();
1658 Type Ty = getSrc(0)->getType(); 1525 Type Ty = getSrc(0)->getType();
1659 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 1526 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
1660 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1527 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1661 const x86::Address Addr = Mem->toAsmAddress(Asm); 1528 const x86::Address Addr = Mem->toAsmAddress(Asm);
1662 const auto VarReg = llvm::cast<Variable>(getSrc(2)); 1529 const auto VarReg = llvm::cast<Variable>(getSrc(2));
1663 assert(VarReg->hasReg()); 1530 assert(VarReg->hasReg());
1664 const RegX8632::GPRRegister Reg = 1531 const RegX8632::GPRRegister Reg =
1665 RegX8632::getEncodedGPR(VarReg->getRegNum()); 1532 RegX8632::getEncodedGPR(VarReg->getRegNum());
1666 if (Locked) { 1533 if (Locked) {
1667 Asm->LockCmpxchg(Ty, Addr, Reg); 1534 Asm->LockCmpxchg(Ty, Addr, Reg);
1668 } else { 1535 } else {
1669 Asm->cmpxchg(Ty, Addr, Reg); 1536 Asm->cmpxchg(Ty, Addr, Reg);
1670 } 1537 }
1671 emitIASBytes(Func, Asm, StartPosition);
1672 } 1538 }
1673 1539
1674 void InstX8632Cmpxchg::dump(const Cfg *Func) const { 1540 void InstX8632Cmpxchg::dump(const Cfg *Func) const {
1675 Ostream &Str = Func->getContext()->getStrDump(); 1541 Ostream &Str = Func->getContext()->getStrDump();
1676 if (Locked) { 1542 if (Locked) {
1677 Str << "lock "; 1543 Str << "lock ";
1678 } 1544 }
1679 Str << "cmpxchg." << getSrc(0)->getType() << " "; 1545 Str << "cmpxchg." << getSrc(0)->getType() << " ";
1680 dumpSources(Func); 1546 dumpSources(Func);
1681 } 1547 }
1682 1548
1683 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { 1549 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const {
1684 Ostream &Str = Func->getContext()->getStrEmit(); 1550 Ostream &Str = Func->getContext()->getStrEmit();
1685 assert(getSrcSize() == 5); 1551 assert(getSrcSize() == 5);
1686 if (Locked) { 1552 if (Locked) {
1687 Str << "\tlock"; 1553 Str << "\tlock";
1688 } 1554 }
1689 Str << "\tcmpxchg8b\t"; 1555 Str << "\tcmpxchg8b\t";
1690 getSrc(0)->emit(Func); 1556 getSrc(0)->emit(Func);
1691 } 1557 }
1692 1558
1693 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { 1559 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const {
1694 assert(getSrcSize() == 5); 1560 assert(getSrcSize() == 5);
1695 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1561 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1696 intptr_t StartPosition = Asm->GetPosition();
1697 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 1562 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
1698 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1563 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1699 const x86::Address Addr = Mem->toAsmAddress(Asm); 1564 const x86::Address Addr = Mem->toAsmAddress(Asm);
1700 if (Locked) { 1565 if (Locked) {
1701 Asm->lock(); 1566 Asm->lock();
1702 } 1567 }
1703 Asm->cmpxchg8b(Addr); 1568 Asm->cmpxchg8b(Addr);
1704 emitIASBytes(Func, Asm, StartPosition);
1705 } 1569 }
1706 1570
1707 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { 1571 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const {
1708 Ostream &Str = Func->getContext()->getStrDump(); 1572 Ostream &Str = Func->getContext()->getStrDump();
1709 if (Locked) { 1573 if (Locked) {
1710 Str << "lock "; 1574 Str << "lock ";
1711 } 1575 }
1712 Str << "cmpxchg8b "; 1576 Str << "cmpxchg8b ";
1713 dumpSources(Func); 1577 dumpSources(Func);
1714 } 1578 }
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 } 1725 }
1862 1726
1863 void InstX8632UD2::emit(const Cfg *Func) const { 1727 void InstX8632UD2::emit(const Cfg *Func) const {
1864 Ostream &Str = Func->getContext()->getStrEmit(); 1728 Ostream &Str = Func->getContext()->getStrEmit();
1865 assert(getSrcSize() == 0); 1729 assert(getSrcSize() == 0);
1866 Str << "\tud2"; 1730 Str << "\tud2";
1867 } 1731 }
1868 1732
1869 void InstX8632UD2::emitIAS(const Cfg *Func) const { 1733 void InstX8632UD2::emitIAS(const Cfg *Func) const {
1870 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1734 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1871 intptr_t StartPosition = Asm->GetPosition();
1872 Asm->ud2(); 1735 Asm->ud2();
1873 emitIASBytes(Func, Asm, StartPosition);
1874 } 1736 }
1875 1737
1876 void InstX8632UD2::dump(const Cfg *Func) const { 1738 void InstX8632UD2::dump(const Cfg *Func) const {
1877 Ostream &Str = Func->getContext()->getStrDump(); 1739 Ostream &Str = Func->getContext()->getStrDump();
1878 Str << "ud2\n"; 1740 Str << "ud2\n";
1879 } 1741 }
1880 1742
1881 void InstX8632Test::emit(const Cfg *Func) const { 1743 void InstX8632Test::emit(const Cfg *Func) const {
1882 Ostream &Str = Func->getContext()->getStrEmit(); 1744 Ostream &Str = Func->getContext()->getStrEmit();
1883 assert(getSrcSize() == 2); 1745 assert(getSrcSize() == 2);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1915 } 1777 }
1916 1778
1917 void InstX8632Mfence::emit(const Cfg *Func) const { 1779 void InstX8632Mfence::emit(const Cfg *Func) const {
1918 Ostream &Str = Func->getContext()->getStrEmit(); 1780 Ostream &Str = Func->getContext()->getStrEmit();
1919 assert(getSrcSize() == 0); 1781 assert(getSrcSize() == 0);
1920 Str << "\tmfence"; 1782 Str << "\tmfence";
1921 } 1783 }
1922 1784
1923 void InstX8632Mfence::emitIAS(const Cfg *Func) const { 1785 void InstX8632Mfence::emitIAS(const Cfg *Func) const {
1924 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1786 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1925 intptr_t StartPosition = Asm->GetPosition();
1926 Asm->mfence(); 1787 Asm->mfence();
1927 emitIASBytes(Func, Asm, StartPosition);
1928 } 1788 }
1929 1789
1930 void InstX8632Mfence::dump(const Cfg *Func) const { 1790 void InstX8632Mfence::dump(const Cfg *Func) const {
1931 Ostream &Str = Func->getContext()->getStrDump(); 1791 Ostream &Str = Func->getContext()->getStrDump();
1932 Str << "mfence\n"; 1792 Str << "mfence\n";
1933 } 1793 }
1934 1794
1935 void InstX8632Store::emit(const Cfg *Func) const { 1795 void InstX8632Store::emit(const Cfg *Func) const {
1936 Ostream &Str = Func->getContext()->getStrEmit(); 1796 Ostream &Str = Func->getContext()->getStrEmit();
1937 assert(getSrcSize() == 2); 1797 assert(getSrcSize() == 2);
1938 Type Ty = getSrc(0)->getType(); 1798 Type Ty = getSrc(0)->getType();
1939 Str << "\tmov" << getWidthString(Ty) << TypeX8632Attributes[Ty].SdSsString 1799 Str << "\tmov" << getWidthString(Ty) << TypeX8632Attributes[Ty].SdSsString
1940 << "\t"; 1800 << "\t";
1941 getSrc(0)->emit(Func); 1801 getSrc(0)->emit(Func);
1942 Str << ", "; 1802 Str << ", ";
1943 getSrc(1)->emit(Func); 1803 getSrc(1)->emit(Func);
1944 } 1804 }
1945 1805
1946 void InstX8632Store::emitIAS(const Cfg *Func) const { 1806 void InstX8632Store::emitIAS(const Cfg *Func) const {
1947 assert(getSrcSize() == 2); 1807 assert(getSrcSize() == 2);
1948 const Operand *Dest = getSrc(1); 1808 const Operand *Dest = getSrc(1);
1949 const Operand *Src = getSrc(0); 1809 const Operand *Src = getSrc(0);
1950 Type DestTy = Dest->getType(); 1810 Type DestTy = Dest->getType();
1951 if (isScalarFloatingType(DestTy)) { 1811 if (isScalarFloatingType(DestTy)) {
1952 // Src must be a register, since Dest is a Mem operand of some kind. 1812 // Src must be a register, since Dest is a Mem operand of some kind.
1953 const auto SrcVar = llvm::cast<Variable>(Src); 1813 const auto SrcVar = llvm::cast<Variable>(Src);
1954 assert(SrcVar->hasReg()); 1814 assert(SrcVar->hasReg());
1955 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); 1815 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum());
1956 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1816 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1957 intptr_t StartPosition = Asm->GetPosition();
1958 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) { 1817 if (const auto DestVar = llvm::dyn_cast<Variable>(Dest)) {
1959 assert(!DestVar->hasReg()); 1818 assert(!DestVar->hasReg());
1960 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 1819 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1961 ->stackVarToAsmOperand(DestVar)); 1820 ->stackVarToAsmOperand(DestVar));
1962 Asm->movss(DestTy, StackAddr, SrcReg); 1821 Asm->movss(DestTy, StackAddr, SrcReg);
1963 } else { 1822 } else {
1964 const auto DestMem = llvm::cast<OperandX8632Mem>(Dest); 1823 const auto DestMem = llvm::cast<OperandX8632Mem>(Dest);
1965 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1824 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1966 Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg); 1825 Asm->movss(DestTy, DestMem->toAsmAddress(Asm), SrcReg);
1967 } 1826 }
1968 emitIASBytes(Func, Asm, StartPosition);
1969 return; 1827 return;
1970 } else { 1828 } else {
1971 assert(isScalarIntegerType(DestTy)); 1829 assert(isScalarIntegerType(DestTy));
1972 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = { 1830 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = {
1973 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov}; 1831 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov};
1974 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter); 1832 emitIASAsAddrOpTyGPR(Func, DestTy, Dest, Src, GPRAddrEmitter);
1975 } 1833 }
1976 } 1834 }
1977 1835
1978 void InstX8632Store::dump(const Cfg *Func) const { 1836 void InstX8632Store::dump(const Cfg *Func) const {
1979 Ostream &Str = Func->getContext()->getStrDump(); 1837 Ostream &Str = Func->getContext()->getStrDump();
1980 Str << "mov." << getSrc(0)->getType() << " "; 1838 Str << "mov." << getSrc(0)->getType() << " ";
1981 getSrc(1)->dump(Func); 1839 getSrc(1)->dump(Func);
1982 Str << ", "; 1840 Str << ", ";
1983 getSrc(0)->dump(Func); 1841 getSrc(0)->dump(Func);
1984 } 1842 }
1985 1843
1986 void InstX8632StoreP::emit(const Cfg *Func) const { 1844 void InstX8632StoreP::emit(const Cfg *Func) const {
1987 Ostream &Str = Func->getContext()->getStrEmit(); 1845 Ostream &Str = Func->getContext()->getStrEmit();
1988 assert(getSrcSize() == 2); 1846 assert(getSrcSize() == 2);
1989 Str << "\tmovups\t"; 1847 Str << "\tmovups\t";
1990 getSrc(0)->emit(Func); 1848 getSrc(0)->emit(Func);
1991 Str << ", "; 1849 Str << ", ";
1992 getSrc(1)->emit(Func); 1850 getSrc(1)->emit(Func);
1993 } 1851 }
1994 1852
1995 void InstX8632StoreP::emitIAS(const Cfg *Func) const { 1853 void InstX8632StoreP::emitIAS(const Cfg *Func) const {
1996 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1854 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1997 intptr_t StartPosition = Asm->GetPosition();
1998 assert(getSrcSize() == 2); 1855 assert(getSrcSize() == 2);
1999 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); 1856 const auto SrcVar = llvm::cast<Variable>(getSrc(0));
2000 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); 1857 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
2001 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1858 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2002 assert(SrcVar->hasReg()); 1859 assert(SrcVar->hasReg());
2003 Asm->movups(DestMem->toAsmAddress(Asm), 1860 Asm->movups(DestMem->toAsmAddress(Asm),
2004 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 1861 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
2005 emitIASBytes(Func, Asm, StartPosition);
2006 } 1862 }
2007 1863
2008 void InstX8632StoreP::dump(const Cfg *Func) const { 1864 void InstX8632StoreP::dump(const Cfg *Func) const {
2009 Ostream &Str = Func->getContext()->getStrDump(); 1865 Ostream &Str = Func->getContext()->getStrDump();
2010 Str << "storep." << getSrc(0)->getType() << " "; 1866 Str << "storep." << getSrc(0)->getType() << " ";
2011 getSrc(1)->dump(Func); 1867 getSrc(1)->dump(Func);
2012 Str << ", "; 1868 Str << ", ";
2013 getSrc(0)->dump(Func); 1869 getSrc(0)->dump(Func);
2014 } 1870 }
2015 1871
2016 void InstX8632StoreQ::emit(const Cfg *Func) const { 1872 void InstX8632StoreQ::emit(const Cfg *Func) const {
2017 Ostream &Str = Func->getContext()->getStrEmit(); 1873 Ostream &Str = Func->getContext()->getStrEmit();
2018 assert(getSrcSize() == 2); 1874 assert(getSrcSize() == 2);
2019 assert(getSrc(1)->getType() == IceType_i64 || 1875 assert(getSrc(1)->getType() == IceType_i64 ||
2020 getSrc(1)->getType() == IceType_f64); 1876 getSrc(1)->getType() == IceType_f64);
2021 Str << "\tmovq\t"; 1877 Str << "\tmovq\t";
2022 getSrc(0)->emit(Func); 1878 getSrc(0)->emit(Func);
2023 Str << ", "; 1879 Str << ", ";
2024 getSrc(1)->emit(Func); 1880 getSrc(1)->emit(Func);
2025 } 1881 }
2026 1882
2027 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { 1883 void InstX8632StoreQ::emitIAS(const Cfg *Func) const {
2028 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1884 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2029 intptr_t StartPosition = Asm->GetPosition();
2030 assert(getSrcSize() == 2); 1885 assert(getSrcSize() == 2);
2031 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); 1886 const auto SrcVar = llvm::cast<Variable>(getSrc(0));
2032 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); 1887 const auto DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
2033 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 1888 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2034 assert(SrcVar->hasReg()); 1889 assert(SrcVar->hasReg());
2035 Asm->movq(DestMem->toAsmAddress(Asm), 1890 Asm->movq(DestMem->toAsmAddress(Asm),
2036 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 1891 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
2037 emitIASBytes(Func, Asm, StartPosition);
2038 } 1892 }
2039 1893
2040 void InstX8632StoreQ::dump(const Cfg *Func) const { 1894 void InstX8632StoreQ::dump(const Cfg *Func) const {
2041 Ostream &Str = Func->getContext()->getStrDump(); 1895 Ostream &Str = Func->getContext()->getStrDump();
2042 Str << "storeq." << getSrc(0)->getType() << " "; 1896 Str << "storeq." << getSrc(0)->getType() << " ";
2043 getSrc(1)->dump(Func); 1897 getSrc(1)->dump(Func);
2044 Str << ", "; 1898 Str << ", ";
2045 getSrc(0)->dump(Func); 1899 getSrc(0)->dump(Func);
2046 } 1900 }
2047 1901
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
2138 } else { 1992 } else {
2139 // Dest must be Stack and Src *could* be a register. Use Src's type 1993 // Dest must be Stack and Src *could* be a register. Use Src's type
2140 // to decide on the emitters. 1994 // to decide on the emitters.
2141 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 1995 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2142 ->stackVarToAsmOperand(Dest)); 1996 ->stackVarToAsmOperand(Dest));
2143 if (isScalarFloatingType(SrcTy)) { 1997 if (isScalarFloatingType(SrcTy)) {
2144 // Src must be a register. 1998 // Src must be a register.
2145 const auto SrcVar = llvm::cast<Variable>(Src); 1999 const auto SrcVar = llvm::cast<Variable>(Src);
2146 assert(SrcVar->hasReg()); 2000 assert(SrcVar->hasReg());
2147 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2001 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2148 intptr_t StartPosition = Asm->GetPosition();
2149 Asm->movss(SrcTy, StackAddr, 2002 Asm->movss(SrcTy, StackAddr,
2150 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 2003 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
2151 emitIASBytes(Func, Asm, StartPosition);
2152 return; 2004 return;
2153 } else { 2005 } else {
2154 // Src can be a register or immediate. 2006 // Src can be a register or immediate.
2155 assert(isScalarIntegerType(SrcTy)); 2007 assert(isScalarIntegerType(SrcTy));
2156 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); 2008 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter);
2157 return; 2009 return;
2158 } 2010 }
2159 return; 2011 return;
2160 } 2012 }
2161 } 2013 }
2162 2014
2163 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { 2015 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const {
2164 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2016 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2165 intptr_t StartPosition = Asm->GetPosition();
2166 assert(getSrcSize() == 1); 2017 assert(getSrcSize() == 1);
2167 const Variable *Dest = getDest(); 2018 const Variable *Dest = getDest();
2168 const auto SrcVar = llvm::cast<Variable>(getSrc(0)); 2019 const auto SrcVar = llvm::cast<Variable>(getSrc(0));
2169 // For insert/extract element (one of Src/Dest is an Xmm vector and 2020 // For insert/extract element (one of Src/Dest is an Xmm vector and
2170 // the other is an int type). 2021 // the other is an int type).
2171 if (SrcVar->getType() == IceType_i32) { 2022 if (SrcVar->getType() == IceType_i32) {
2172 assert(isVectorType(Dest->getType())); 2023 assert(isVectorType(Dest->getType()));
2173 assert(Dest->hasReg()); 2024 assert(Dest->hasReg());
2174 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); 2025 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum());
2175 if (SrcVar->hasReg()) { 2026 if (SrcVar->hasReg()) {
2176 Asm->movd(DestReg, RegX8632::getEncodedGPR(SrcVar->getRegNum())); 2027 Asm->movd(DestReg, RegX8632::getEncodedGPR(SrcVar->getRegNum()));
2177 } else { 2028 } else {
2178 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2029 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2179 ->stackVarToAsmOperand(SrcVar)); 2030 ->stackVarToAsmOperand(SrcVar));
2180 Asm->movd(DestReg, StackAddr); 2031 Asm->movd(DestReg, StackAddr);
2181 } 2032 }
2182 } else { 2033 } else {
2183 assert(isVectorType(SrcVar->getType())); 2034 assert(isVectorType(SrcVar->getType()));
2184 assert(SrcVar->hasReg()); 2035 assert(SrcVar->hasReg());
2185 assert(Dest->getType() == IceType_i32); 2036 assert(Dest->getType() == IceType_i32);
2186 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum()); 2037 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(SrcVar->getRegNum());
2187 if (Dest->hasReg()) { 2038 if (Dest->hasReg()) {
2188 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); 2039 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg);
2189 } else { 2040 } else {
2190 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2041 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2191 ->stackVarToAsmOperand(Dest)); 2042 ->stackVarToAsmOperand(Dest));
2192 Asm->movd(StackAddr, SrcReg); 2043 Asm->movd(StackAddr, SrcReg);
2193 } 2044 }
2194 } 2045 }
2195 emitIASBytes(Func, Asm, StartPosition);
2196 } 2046 }
2197 2047
2198 template <> void InstX8632Movp::emit(const Cfg *Func) const { 2048 template <> void InstX8632Movp::emit(const Cfg *Func) const {
2199 // TODO(wala,stichnot): movups works with all vector operands, but 2049 // TODO(wala,stichnot): movups works with all vector operands, but
2200 // there exist other instructions (movaps, movdqa, movdqu) that may 2050 // there exist other instructions (movaps, movdqa, movdqu) that may
2201 // perform better, depending on the data type and alignment of the 2051 // perform better, depending on the data type and alignment of the
2202 // operands. 2052 // operands.
2203 Ostream &Str = Func->getContext()->getStrEmit(); 2053 Ostream &Str = Func->getContext()->getStrEmit();
2204 assert(getSrcSize() == 1); 2054 assert(getSrcSize() == 1);
2205 Str << "\tmovups\t"; 2055 Str << "\tmovups\t";
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2245 2095
2246 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const { 2096 template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const {
2247 // This is Binop variant is only intended to be used for reg-reg moves 2097 // This is Binop variant is only intended to be used for reg-reg moves
2248 // where part of the Dest register is untouched. 2098 // where part of the Dest register is untouched.
2249 assert(getSrcSize() == 2); 2099 assert(getSrcSize() == 2);
2250 const Variable *Dest = getDest(); 2100 const Variable *Dest = getDest();
2251 assert(Dest == getSrc(0)); 2101 assert(Dest == getSrc(0));
2252 const auto SrcVar = llvm::cast<Variable>(getSrc(1)); 2102 const auto SrcVar = llvm::cast<Variable>(getSrc(1));
2253 assert(Dest->hasReg() && SrcVar->hasReg()); 2103 assert(Dest->hasReg() && SrcVar->hasReg());
2254 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2104 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2255 intptr_t StartPosition = Asm->GetPosition();
2256 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), 2105 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()),
2257 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 2106 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
2258 emitIASBytes(Func, Asm, StartPosition);
2259 } 2107 }
2260 2108
2261 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const { 2109 template <> void InstX8632Movsx::emitIAS(const Cfg *Func) const {
2262 assert(getSrcSize() == 1); 2110 assert(getSrcSize() == 1);
2263 const Variable *Dest = getDest(); 2111 const Variable *Dest = getDest();
2264 const Operand *Src = getSrc(0); 2112 const Operand *Src = getSrc(0);
2265 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice 2113 // Dest must be a > 8-bit register, but Src can be 8-bit. In practice
2266 // we just use the full register for Dest to avoid having an 2114 // we just use the full register for Dest to avoid having an
2267 // OperandSizeOverride prefix. It also allows us to only dispatch on SrcTy. 2115 // OperandSizeOverride prefix. It also allows us to only dispatch on SrcTy.
2268 Type SrcTy = Src->getType(); 2116 Type SrcTy = Src->getType();
(...skipping 13 matching lines...) Expand all
2282 } 2130 }
2283 2131
2284 void InstX8632Nop::emit(const Cfg *Func) const { 2132 void InstX8632Nop::emit(const Cfg *Func) const {
2285 Ostream &Str = Func->getContext()->getStrEmit(); 2133 Ostream &Str = Func->getContext()->getStrEmit();
2286 // TODO: Emit the right code for each variant. 2134 // TODO: Emit the right code for each variant.
2287 Str << "\tnop\t# variant = " << Variant; 2135 Str << "\tnop\t# variant = " << Variant;
2288 } 2136 }
2289 2137
2290 void InstX8632Nop::emitIAS(const Cfg *Func) const { 2138 void InstX8632Nop::emitIAS(const Cfg *Func) const {
2291 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2139 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2292 intptr_t StartPosition = Asm->GetPosition();
2293 // TODO: Emit the right code for the variant. 2140 // TODO: Emit the right code for the variant.
2294 Asm->nop(); 2141 Asm->nop();
2295 emitIASBytes(Func, Asm, StartPosition);
2296 } 2142 }
2297 2143
2298 void InstX8632Nop::dump(const Cfg *Func) const { 2144 void InstX8632Nop::dump(const Cfg *Func) const {
2299 Ostream &Str = Func->getContext()->getStrDump(); 2145 Ostream &Str = Func->getContext()->getStrDump();
2300 Str << "nop (variant = " << Variant << ")"; 2146 Str << "nop (variant = " << Variant << ")";
2301 } 2147 }
2302 2148
2303 void InstX8632Fld::emit(const Cfg *Func) const { 2149 void InstX8632Fld::emit(const Cfg *Func) const {
2304 Ostream &Str = Func->getContext()->getStrEmit(); 2150 Ostream &Str = Func->getContext()->getStrEmit();
2305 assert(getSrcSize() == 1); 2151 assert(getSrcSize() == 1);
(...skipping 12 matching lines...) Expand all
2318 << "(%esp)\n"; 2164 << "(%esp)\n";
2319 Str << "\taddl\t$" << Width << ", %esp"; 2165 Str << "\taddl\t$" << Width << ", %esp";
2320 return; 2166 return;
2321 } 2167 }
2322 Str << "\tfld" << getFldString(Ty) << "\t"; 2168 Str << "\tfld" << getFldString(Ty) << "\t";
2323 getSrc(0)->emit(Func); 2169 getSrc(0)->emit(Func);
2324 } 2170 }
2325 2171
2326 void InstX8632Fld::emitIAS(const Cfg *Func) const { 2172 void InstX8632Fld::emitIAS(const Cfg *Func) const {
2327 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2173 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2328 intptr_t StartPosition = Asm->GetPosition();
2329 assert(getSrcSize() == 1); 2174 assert(getSrcSize() == 1);
2330 const Operand *Src = getSrc(0); 2175 const Operand *Src = getSrc(0);
2331 Type Ty = Src->getType(); 2176 Type Ty = Src->getType();
2332 if (const auto Var = llvm::dyn_cast<Variable>(Src)) { 2177 if (const auto Var = llvm::dyn_cast<Variable>(Src)) {
2333 if (Var->hasReg()) { 2178 if (Var->hasReg()) {
2334 // This is a physical xmm register, so we need to spill it to a 2179 // This is a physical xmm register, so we need to spill it to a
2335 // temporary stack slot. 2180 // temporary stack slot.
2336 x86::Immediate Width(typeWidthInBytes(Ty)); 2181 x86::Immediate Width(typeWidthInBytes(Ty));
2337 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); 2182 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2338 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); 2183 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
2339 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); 2184 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum()));
2340 Asm->fld(Ty, StackSlot); 2185 Asm->fld(Ty, StackSlot);
2341 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); 2186 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2342 } else { 2187 } else {
2343 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2188 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2344 ->stackVarToAsmOperand(Var)); 2189 ->stackVarToAsmOperand(Var));
2345 Asm->fld(Ty, StackAddr); 2190 Asm->fld(Ty, StackAddr);
2346 } 2191 }
2347 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { 2192 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
2348 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2193 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2349 Asm->fld(Ty, Mem->toAsmAddress(Asm)); 2194 Asm->fld(Ty, Mem->toAsmAddress(Asm));
2350 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { 2195 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
2351 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); 2196 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
2352 } else { 2197 } else {
2353 llvm_unreachable("Unexpected operand type"); 2198 llvm_unreachable("Unexpected operand type");
2354 } 2199 }
2355 emitIASBytes(Func, Asm, StartPosition);
2356 } 2200 }
2357 2201
2358 void InstX8632Fld::dump(const Cfg *Func) const { 2202 void InstX8632Fld::dump(const Cfg *Func) const {
2359 Ostream &Str = Func->getContext()->getStrDump(); 2203 Ostream &Str = Func->getContext()->getStrDump();
2360 Str << "fld." << getSrc(0)->getType() << " "; 2204 Str << "fld." << getSrc(0)->getType() << " ";
2361 dumpSources(Func); 2205 dumpSources(Func);
2362 } 2206 }
2363 2207
2364 void InstX8632Fstp::emit(const Cfg *Func) const { 2208 void InstX8632Fstp::emit(const Cfg *Func) const {
2365 Ostream &Str = Func->getContext()->getStrEmit(); 2209 Ostream &Str = Func->getContext()->getStrEmit();
(...skipping 22 matching lines...) Expand all
2388 << "(%esp)\n"; 2232 << "(%esp)\n";
2389 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" 2233 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"
2390 << "(%esp), "; 2234 << "(%esp), ";
2391 getDest()->emit(Func); 2235 getDest()->emit(Func);
2392 Str << "\n"; 2236 Str << "\n";
2393 Str << "\taddl\t$" << Width << ", %esp"; 2237 Str << "\taddl\t$" << Width << ", %esp";
2394 } 2238 }
2395 2239
2396 void InstX8632Fstp::emitIAS(const Cfg *Func) const { 2240 void InstX8632Fstp::emitIAS(const Cfg *Func) const {
2397 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2241 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2398 intptr_t StartPosition = Asm->GetPosition();
2399 assert(getSrcSize() == 0); 2242 assert(getSrcSize() == 0);
2400 const Variable *Dest = getDest(); 2243 const Variable *Dest = getDest();
2401 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to 2244 // TODO(jvoung,stichnot): Utilize this by setting Dest to nullptr to
2402 // "partially" delete the fstp if the Dest is unused. 2245 // "partially" delete the fstp if the Dest is unused.
2403 // Even if Dest is unused, the fstp should be kept for the SideEffects 2246 // Even if Dest is unused, the fstp should be kept for the SideEffects
2404 // of popping the stack. 2247 // of popping the stack.
2405 if (!Dest) { 2248 if (!Dest) {
2406 Asm->fstp(RegX8632::getEncodedSTReg(0)); 2249 Asm->fstp(RegX8632::getEncodedSTReg(0));
2407 emitIASBytes(Func, Asm, StartPosition);
2408 return; 2250 return;
2409 } 2251 }
2410 Type Ty = Dest->getType(); 2252 Type Ty = Dest->getType();
2411 if (!Dest->hasReg()) { 2253 if (!Dest->hasReg()) {
2412 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2254 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2413 ->stackVarToAsmOperand(Dest)); 2255 ->stackVarToAsmOperand(Dest));
2414 Asm->fstp(Ty, StackAddr); 2256 Asm->fstp(Ty, StackAddr);
2415 } else { 2257 } else {
2416 // Dest is a physical (xmm) register, so st(0) needs to go through 2258 // Dest is a physical (xmm) register, so st(0) needs to go through
2417 // memory. Hack this by creating a temporary stack slot, spilling 2259 // memory. Hack this by creating a temporary stack slot, spilling
2418 // st(0) there, loading it into the xmm register, and deallocating 2260 // st(0) there, loading it into the xmm register, and deallocating
2419 // the stack slot. 2261 // the stack slot.
2420 x86::Immediate Width(typeWidthInBytes(Ty)); 2262 x86::Immediate Width(typeWidthInBytes(Ty));
2421 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); 2263 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2422 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); 2264 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
2423 Asm->fstp(Ty, StackSlot); 2265 Asm->fstp(Ty, StackSlot);
2424 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); 2266 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot);
2425 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); 2267 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2426 } 2268 }
2427 emitIASBytes(Func, Asm, StartPosition);
2428 } 2269 }
2429 2270
2430 void InstX8632Fstp::dump(const Cfg *Func) const { 2271 void InstX8632Fstp::dump(const Cfg *Func) const {
2431 Ostream &Str = Func->getContext()->getStrDump(); 2272 Ostream &Str = Func->getContext()->getStrDump();
2432 dumpDest(Func); 2273 dumpDest(Func);
2433 Str << " = fstp." << getDest()->getType() << ", st(0)"; 2274 Str << " = fstp." << getDest()->getType() << ", st(0)";
2434 Str << "\n"; 2275 Str << "\n";
2435 } 2276 }
2436 2277
2437 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { 2278 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 void InstX8632Pop::emit(const Cfg *Func) const { 2409 void InstX8632Pop::emit(const Cfg *Func) const {
2569 Ostream &Str = Func->getContext()->getStrEmit(); 2410 Ostream &Str = Func->getContext()->getStrEmit();
2570 assert(getSrcSize() == 0); 2411 assert(getSrcSize() == 0);
2571 Str << "\tpop\t"; 2412 Str << "\tpop\t";
2572 getDest()->emit(Func); 2413 getDest()->emit(Func);
2573 } 2414 }
2574 2415
2575 void InstX8632Pop::emitIAS(const Cfg *Func) const { 2416 void InstX8632Pop::emitIAS(const Cfg *Func) const {
2576 assert(getSrcSize() == 0); 2417 assert(getSrcSize() == 0);
2577 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2418 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2578 intptr_t StartPosition = Asm->GetPosition();
2579 if (getDest()->hasReg()) { 2419 if (getDest()->hasReg()) {
2580 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); 2420 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum()));
2581 } else { 2421 } else {
2582 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) 2422 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget())
2583 ->stackVarToAsmOperand(getDest())); 2423 ->stackVarToAsmOperand(getDest()));
2584 } 2424 }
2585 emitIASBytes(Func, Asm, StartPosition);
2586 } 2425 }
2587 2426
2588 void InstX8632Pop::dump(const Cfg *Func) const { 2427 void InstX8632Pop::dump(const Cfg *Func) const {
2589 Ostream &Str = Func->getContext()->getStrDump(); 2428 Ostream &Str = Func->getContext()->getStrDump();
2590 dumpDest(Func); 2429 dumpDest(Func);
2591 Str << " = pop." << getDest()->getType() << " "; 2430 Str << " = pop." << getDest()->getType() << " ";
2592 } 2431 }
2593 2432
2594 void InstX8632AdjustStack::emit(const Cfg *Func) const { 2433 void InstX8632AdjustStack::emit(const Cfg *Func) const {
2595 Ostream &Str = Func->getContext()->getStrEmit(); 2434 Ostream &Str = Func->getContext()->getStrEmit();
2596 Str << "\tsubl\t$" << Amount << ", %esp"; 2435 Str << "\tsubl\t$" << Amount << ", %esp";
2597 Func->getTarget()->updateStackAdjustment(Amount); 2436 Func->getTarget()->updateStackAdjustment(Amount);
2598 } 2437 }
2599 2438
2600 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { 2439 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const {
2601 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2440 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2602 intptr_t StartPosition = Asm->GetPosition();
2603 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); 2441 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount));
2604 emitIASBytes(Func, Asm, StartPosition);
2605 Func->getTarget()->updateStackAdjustment(Amount); 2442 Func->getTarget()->updateStackAdjustment(Amount);
2606 } 2443 }
2607 2444
2608 void InstX8632AdjustStack::dump(const Cfg *Func) const { 2445 void InstX8632AdjustStack::dump(const Cfg *Func) const {
2609 Ostream &Str = Func->getContext()->getStrDump(); 2446 Ostream &Str = Func->getContext()->getStrDump();
2610 Str << "esp = sub.i32 esp, " << Amount; 2447 Str << "esp = sub.i32 esp, " << Amount;
2611 } 2448 }
2612 2449
2613 void InstX8632Push::emit(const Cfg *Func) const { 2450 void InstX8632Push::emit(const Cfg *Func) const {
2614 Ostream &Str = Func->getContext()->getStrEmit(); 2451 Ostream &Str = Func->getContext()->getStrEmit();
2615 assert(getSrcSize() == 1); 2452 assert(getSrcSize() == 1);
2616 // Push is currently only used for saving GPRs. 2453 // Push is currently only used for saving GPRs.
2617 const auto Var = llvm::cast<Variable>(getSrc(0)); 2454 const auto Var = llvm::cast<Variable>(getSrc(0));
2618 assert(Var->hasReg()); 2455 assert(Var->hasReg());
2619 Str << "\tpush\t"; 2456 Str << "\tpush\t";
2620 Var->emit(Func); 2457 Var->emit(Func);
2621 } 2458 }
2622 2459
2623 void InstX8632Push::emitIAS(const Cfg *Func) const { 2460 void InstX8632Push::emitIAS(const Cfg *Func) const {
2624 assert(getSrcSize() == 1); 2461 assert(getSrcSize() == 1);
2625 // Push is currently only used for saving GPRs. 2462 // Push is currently only used for saving GPRs.
2626 const auto Var = llvm::cast<Variable>(getSrc(0)); 2463 const auto Var = llvm::cast<Variable>(getSrc(0));
2627 assert(Var->hasReg()); 2464 assert(Var->hasReg());
2628 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2465 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2629 intptr_t StartPosition = Asm->GetPosition();
2630 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); 2466 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum()));
2631 emitIASBytes(Func, Asm, StartPosition);
2632 } 2467 }
2633 2468
2634 void InstX8632Push::dump(const Cfg *Func) const { 2469 void InstX8632Push::dump(const Cfg *Func) const {
2635 Ostream &Str = Func->getContext()->getStrDump(); 2470 Ostream &Str = Func->getContext()->getStrDump();
2636 Str << "push." << getSrc(0)->getType() << " "; 2471 Str << "push." << getSrc(0)->getType() << " ";
2637 dumpSources(Func); 2472 dumpSources(Func);
2638 } 2473 }
2639 2474
2640 template <> void InstX8632Psll::emit(const Cfg *Func) const { 2475 template <> void InstX8632Psll::emit(const Cfg *Func) const {
2641 assert(getDest()->getType() == IceType_v8i16 || 2476 assert(getDest()->getType() == IceType_v8i16 ||
(...skipping 17 matching lines...) Expand all
2659 emitTwoAddress(buf, this, Func); 2494 emitTwoAddress(buf, this, Func);
2660 } 2495 }
2661 2496
2662 void InstX8632Ret::emit(const Cfg *Func) const { 2497 void InstX8632Ret::emit(const Cfg *Func) const {
2663 Ostream &Str = Func->getContext()->getStrEmit(); 2498 Ostream &Str = Func->getContext()->getStrEmit();
2664 Str << "\tret"; 2499 Str << "\tret";
2665 } 2500 }
2666 2501
2667 void InstX8632Ret::emitIAS(const Cfg *Func) const { 2502 void InstX8632Ret::emitIAS(const Cfg *Func) const {
2668 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2503 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2669 intptr_t StartPosition = Asm->GetPosition();
2670 Asm->ret(); 2504 Asm->ret();
2671 emitIASBytes(Func, Asm, StartPosition);
2672 } 2505 }
2673 2506
2674 void InstX8632Ret::dump(const Cfg *Func) const { 2507 void InstX8632Ret::dump(const Cfg *Func) const {
2675 Ostream &Str = Func->getContext()->getStrDump(); 2508 Ostream &Str = Func->getContext()->getStrDump();
2676 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); 2509 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType());
2677 Str << "ret." << Ty << " "; 2510 Str << "ret." << Ty << " ";
2678 dumpSources(Func); 2511 dumpSources(Func);
2679 } 2512 }
2680 2513
2681 void InstX8632Xadd::emit(const Cfg *Func) const { 2514 void InstX8632Xadd::emit(const Cfg *Func) const {
2682 Ostream &Str = Func->getContext()->getStrEmit(); 2515 Ostream &Str = Func->getContext()->getStrEmit();
2683 if (Locked) { 2516 if (Locked) {
2684 Str << "\tlock"; 2517 Str << "\tlock";
2685 } 2518 }
2686 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t"; 2519 Str << "\txadd" << getWidthString(getSrc(0)->getType()) << "\t";
2687 getSrc(1)->emit(Func); 2520 getSrc(1)->emit(Func);
2688 Str << ", "; 2521 Str << ", ";
2689 getSrc(0)->emit(Func); 2522 getSrc(0)->emit(Func);
2690 } 2523 }
2691 2524
2692 void InstX8632Xadd::emitIAS(const Cfg *Func) const { 2525 void InstX8632Xadd::emitIAS(const Cfg *Func) const {
2693 assert(getSrcSize() == 2); 2526 assert(getSrcSize() == 2);
2694 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2527 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2695 intptr_t StartPosition = Asm->GetPosition();
2696 Type Ty = getSrc(0)->getType(); 2528 Type Ty = getSrc(0)->getType();
2697 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2529 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2698 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2530 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2699 const x86::Address Addr = Mem->toAsmAddress(Asm); 2531 const x86::Address Addr = Mem->toAsmAddress(Asm);
2700 const auto VarReg = llvm::cast<Variable>(getSrc(1)); 2532 const auto VarReg = llvm::cast<Variable>(getSrc(1));
2701 assert(VarReg->hasReg()); 2533 assert(VarReg->hasReg());
2702 const RegX8632::GPRRegister Reg = 2534 const RegX8632::GPRRegister Reg =
2703 RegX8632::getEncodedGPR(VarReg->getRegNum()); 2535 RegX8632::getEncodedGPR(VarReg->getRegNum());
2704 if (Locked) { 2536 if (Locked) {
2705 Asm->lock(); 2537 Asm->lock();
2706 } 2538 }
2707 Asm->xadd(Ty, Addr, Reg); 2539 Asm->xadd(Ty, Addr, Reg);
2708 emitIASBytes(Func, Asm, StartPosition);
2709 } 2540 }
2710 2541
2711 void InstX8632Xadd::dump(const Cfg *Func) const { 2542 void InstX8632Xadd::dump(const Cfg *Func) const {
2712 Ostream &Str = Func->getContext()->getStrDump(); 2543 Ostream &Str = Func->getContext()->getStrDump();
2713 if (Locked) { 2544 if (Locked) {
2714 Str << "lock "; 2545 Str << "lock ";
2715 } 2546 }
2716 Type Ty = getSrc(0)->getType(); 2547 Type Ty = getSrc(0)->getType();
2717 Str << "xadd." << Ty << " "; 2548 Str << "xadd." << Ty << " ";
2718 dumpSources(Func); 2549 dumpSources(Func);
2719 } 2550 }
2720 2551
2721 void InstX8632Xchg::emit(const Cfg *Func) const { 2552 void InstX8632Xchg::emit(const Cfg *Func) const {
2722 Ostream &Str = Func->getContext()->getStrEmit(); 2553 Ostream &Str = Func->getContext()->getStrEmit();
2723 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t"; 2554 Str << "\txchg" << getWidthString(getSrc(0)->getType()) << "\t";
2724 getSrc(1)->emit(Func); 2555 getSrc(1)->emit(Func);
2725 Str << ", "; 2556 Str << ", ";
2726 getSrc(0)->emit(Func); 2557 getSrc(0)->emit(Func);
2727 } 2558 }
2728 2559
2729 void InstX8632Xchg::emitIAS(const Cfg *Func) const { 2560 void InstX8632Xchg::emitIAS(const Cfg *Func) const {
2730 assert(getSrcSize() == 2); 2561 assert(getSrcSize() == 2);
2731 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2562 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2732 intptr_t StartPosition = Asm->GetPosition();
2733 Type Ty = getSrc(0)->getType(); 2563 Type Ty = getSrc(0)->getType();
2734 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2564 const auto Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2735 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); 2565 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2736 const x86::Address Addr = Mem->toAsmAddress(Asm); 2566 const x86::Address Addr = Mem->toAsmAddress(Asm);
2737 const auto VarReg = llvm::cast<Variable>(getSrc(1)); 2567 const auto VarReg = llvm::cast<Variable>(getSrc(1));
2738 assert(VarReg->hasReg()); 2568 assert(VarReg->hasReg());
2739 const RegX8632::GPRRegister Reg = 2569 const RegX8632::GPRRegister Reg =
2740 RegX8632::getEncodedGPR(VarReg->getRegNum()); 2570 RegX8632::getEncodedGPR(VarReg->getRegNum());
2741 Asm->xchg(Ty, Addr, Reg); 2571 Asm->xchg(Ty, Addr, Reg);
2742 emitIASBytes(Func, Asm, StartPosition);
2743 } 2572 }
2744 2573
2745 void InstX8632Xchg::dump(const Cfg *Func) const { 2574 void InstX8632Xchg::dump(const Cfg *Func) const {
2746 Ostream &Str = Func->getContext()->getStrDump(); 2575 Ostream &Str = Func->getContext()->getStrDump();
2747 Type Ty = getSrc(0)->getType(); 2576 Type Ty = getSrc(0)->getType();
2748 Str << "xchg." << Ty << " "; 2577 Str << "xchg." << Ty << " ";
2749 dumpSources(Func); 2578 dumpSources(Func);
2750 } 2579 }
2751 2580
2752 void OperandX8632Mem::emit(const Cfg *Func) const { 2581 void OperandX8632Mem::emit(const Cfg *Func) const {
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
2909 } 2738 }
2910 Str << "("; 2739 Str << "(";
2911 if (Func) 2740 if (Func)
2912 Var->dump(Func); 2741 Var->dump(Func);
2913 else 2742 else
2914 Var->dump(Str); 2743 Var->dump(Str);
2915 Str << ")"; 2744 Str << ")";
2916 } 2745 }
2917 2746
2918 } // end of namespace Ice 2747 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceCfgNode.cpp ('k') | src/IceTranslator.cpp » ('j') | src/assembler.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698