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

Side by Side Diff: src/IceInstX8632.cpp

Issue 649463002: Handle "Mov" which is mov, movss, movsd, and used for nacl.read.tp. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 6 years, 2 months 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 const char *WidthString; // {byte,word,dword,qword} ptr 55 const char *WidthString; // {byte,word,dword,qword} ptr
56 } TypeX8632Attributes[] = { 56 } TypeX8632Attributes[] = {
57 #define X(tag, elementty, cvt, sdss, pack, width) \ 57 #define X(tag, elementty, cvt, sdss, pack, width) \
58 { cvt, "" sdss, pack, width } \ 58 { cvt, "" sdss, pack, width } \
59 , 59 ,
60 ICETYPEX8632_TABLE 60 ICETYPEX8632_TABLE
61 #undef X 61 #undef X
62 }; 62 };
63 63
64 const char *InstX8632SegmentRegNames[] = { 64 const char *InstX8632SegmentRegNames[] = {
65 #define X(val, name) name, 65 #define X(val, name, prefix) name,
66 SEG_REGX8632_TABLE 66 SEG_REGX8632_TABLE
67 #undef X 67 #undef X
68 }; 68 };
69
70 uint8_t InstX8632SegmentPrefixes[] = {
71 #define X(val, name, prefix) prefix,
72 SEG_REGX8632_TABLE
73 #undef X
74 };
69 75
70 } // end of anonymous namespace 76 } // end of anonymous namespace
71 77
72 const char *InstX8632::getWidthString(Type Ty) { 78 const char *InstX8632::getWidthString(Type Ty) {
73 return TypeX8632Attributes[Ty].WidthString; 79 return TypeX8632Attributes[Ty].WidthString;
74 } 80 }
75 81
76 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, 82 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base,
77 Constant *Offset, Variable *Index, 83 Constant *Offset, Variable *Index,
78 uint16_t Shift, SegmentRegisters SegmentReg) 84 uint16_t Shift, SegmentRegisters SegmentReg)
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) 333 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source)
328 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { 334 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) {
329 addSource(Dest); 335 addSource(Dest);
330 addSource(Source); 336 addSource(Source);
331 } 337 }
332 338
333 // ======================== Dump routines ======================== // 339 // ======================== Dump routines ======================== //
334 340
335 namespace { 341 namespace {
336 342
337 void emitIASBytes(Ostream &Str, const x86::AssemblerX86 *Asm, 343 void emitIASBytes(const Cfg *Func, const x86::AssemblerX86 *Asm,
338 intptr_t StartPosition) { 344 intptr_t StartPosition) {
345 GlobalContext *Ctx = Func->getContext();
346 Ostream &Str = Ctx->getStrEmit();
339 intptr_t EndPosition = Asm->GetPosition(); 347 intptr_t EndPosition = Asm->GetPosition();
340 intptr_t LastFixupLoc = -1; 348 intptr_t LastFixupLoc = -1;
341 AssemblerFixup *LastFixup = NULL; 349 AssemblerFixup *LastFixup = NULL;
342 if (Asm->GetLatestFixup()) { 350 if (Asm->GetLatestFixup()) {
343 LastFixup = Asm->GetLatestFixup(); 351 LastFixup = Asm->GetLatestFixup();
344 LastFixupLoc = LastFixup->position(); 352 LastFixupLoc = LastFixup->position();
345 } 353 }
346 if (LastFixupLoc < StartPosition) { 354 if (LastFixupLoc < StartPosition) {
347 // The fixup doesn't apply to this current block. 355 // The fixup doesn't apply to this current block.
348 for (intptr_t i = StartPosition; i < EndPosition; ++i) { 356 for (intptr_t i = StartPosition; i < EndPosition; ++i) {
349 Str << "\t.byte 0x"; 357 Str << "\t.byte 0x";
350 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); 358 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
351 Str << "\n"; 359 Str << "\n";
352 } 360 }
353 return; 361 return;
354 } 362 }
355 const intptr_t FixupSize = 4; 363 const intptr_t FixupSize = 4;
356 assert(LastFixupLoc + FixupSize <= EndPosition); 364 assert(LastFixupLoc + FixupSize <= EndPosition);
357 // The fixup does apply to this current block. 365 // The fixup does apply to this current block.
358 for (intptr_t i = StartPosition; i < LastFixupLoc; ++i) { 366 for (intptr_t i = StartPosition; i < LastFixupLoc; ++i) {
359 Str << "\t.byte 0x"; 367 Str << "\t.byte 0x";
360 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); 368 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
361 Str << "\n"; 369 Str << "\n";
362 } 370 }
363 Str << "\t.long " << LastFixup->value()->getName(); 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());
364 if (LastFixup->value()->getOffset()) { 377 if (LastFixup->value()->getOffset()) {
365 Str << " + " << LastFixup->value()->getOffset(); 378 Str << " + " << LastFixup->value()->getOffset();
366 } 379 }
367 Str << "\n"; 380 Str << "\n";
368 for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) { 381 for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) {
369 Str << "\t.byte 0x"; 382 Str << "\t.byte 0x";
370 Str.write_hex(Asm->LoadBuffer<uint8_t>(i)); 383 Str.write_hex(Asm->LoadBuffer<uint8_t>(i));
371 Str << "\n"; 384 Str << "\n";
372 } 385 }
373 } 386 }
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 } 489 }
477 if (!EmittedSrc1) 490 if (!EmittedSrc1)
478 Inst->getSrc(1)->emit(Func); 491 Inst->getSrc(1)->emit(Func);
479 Str << "\n"; 492 Str << "\n";
480 } 493 }
481 494
482 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op, 495 void emitIASOpTyGPR(const Cfg *Func, Type Ty, const Operand *Op,
483 const x86::AssemblerX86::GPREmitterOneOp &Emitter) { 496 const x86::AssemblerX86::GPREmitterOneOp &Emitter) {
484 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 497 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
485 intptr_t StartPosition = Asm->GetPosition(); 498 intptr_t StartPosition = Asm->GetPosition();
486 if (const Variable *Var = llvm::dyn_cast<Variable>(Op)) { 499 if (const auto Var = llvm::dyn_cast<Variable>(Op)) {
487 if (Var->hasReg()) { 500 if (Var->hasReg()) {
488 // We cheat a little and use GPRRegister even for byte operations. 501 // We cheat a little and use GPRRegister even for byte operations.
489 RegX8632::GPRRegister VarReg = 502 RegX8632::GPRRegister VarReg =
490 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); 503 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
491 (Asm->*(Emitter.Reg))(Ty, VarReg); 504 (Asm->*(Emitter.Reg))(Ty, VarReg);
492 } else { 505 } else {
493 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 506 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
494 ->stackVarToAsmOperand(Var)); 507 ->stackVarToAsmOperand(Var));
495 (Asm->*(Emitter.Addr))(Ty, StackAddr); 508 (Asm->*(Emitter.Addr))(Ty, StackAddr);
496 } 509 }
497 } else if (const OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) { 510 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Op)) {
511 Mem->emitSegmentOverride(Asm);
498 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm)); 512 (Asm->*(Emitter.Addr))(Ty, Mem->toAsmAddress(Asm));
499 } else { 513 } else {
500 llvm_unreachable("Unexpected operand type"); 514 llvm_unreachable("Unexpected operand type");
501 } 515 }
502 Ostream &Str = Func->getContext()->getStrEmit(); 516 emitIASBytes(Func, Asm, StartPosition);
503 emitIASBytes(Str, Asm, StartPosition);
504 } 517 }
505 518
506 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, 519 void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
507 const Operand *Src, 520 const Operand *Src,
508 const x86::AssemblerX86::GPREmitterRegOp &Emitter) { 521 const x86::AssemblerX86::GPREmitterRegOp &Emitter) {
509 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 522 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
510 intptr_t StartPosition = Asm->GetPosition(); 523 intptr_t StartPosition = Asm->GetPosition();
511 assert(Var->hasReg()); 524 assert(Var->hasReg());
512 // We cheat a little and use GPRRegister even for byte operations. 525 // We cheat a little and use GPRRegister even for byte operations.
513 RegX8632::GPRRegister VarReg = 526 RegX8632::GPRRegister VarReg =
514 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); 527 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
515 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { 528 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
516 if (SrcVar->hasReg()) { 529 if (SrcVar->hasReg()) {
517 RegX8632::GPRRegister SrcReg = 530 RegX8632::GPRRegister SrcReg =
518 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); 531 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum());
519 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); 532 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
520 } else { 533 } else {
521 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 534 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
522 ->stackVarToAsmOperand(SrcVar); 535 ->stackVarToAsmOperand(SrcVar);
523 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr); 536 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcStackAddr);
524 } 537 }
525 } else if (const OperandX8632Mem *Mem = 538 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
526 llvm::dyn_cast<OperandX8632Mem>(Src)) { 539 Mem->emitSegmentOverride(Asm);
527 x86::Address SrcAddr = Mem->toAsmAddress(Asm); 540 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
541 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
542 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue()));
543 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
544 AssemblerFixup *Fixup = x86::DisplacementRelocation::create(
545 Asm, FK_Abs_4, Reloc);
546 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Fixup));
547 } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) {
548 x86::Address SrcAddr = Split->toAsmAddress(Func);
528 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcAddr); 549 (Asm->*(Emitter.GPRAddr))(Ty, VarReg, SrcAddr);
529 } else if (const ConstantInteger32 *Imm =
530 llvm::dyn_cast<ConstantInteger32>(Src)) {
531 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue()));
532 } else { 550 } else {
533 llvm_unreachable("Unexpected operand type"); 551 llvm_unreachable("Unexpected operand type");
534 } 552 }
535 Ostream &Str = Func->getContext()->getStrEmit(); 553 emitIASBytes(Func, Asm, StartPosition);
536 emitIASBytes(Str, Asm, StartPosition);
537 } 554 }
538 555
539 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, 556 void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr,
540 const Operand *Src, 557 const Operand *Src,
541 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) { 558 const x86::AssemblerX86::GPREmitterAddrOp &Emitter) {
542 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 559 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
543 intptr_t StartPosition = Asm->GetPosition(); 560 intptr_t StartPosition = Asm->GetPosition();
544 // Src can only be Reg or Immediate. 561 // Src can only be Reg or Immediate.
545 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { 562 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
546 assert(SrcVar->hasReg()); 563 assert(SrcVar->hasReg());
547 RegX8632::GPRRegister SrcReg = 564 RegX8632::GPRRegister SrcReg =
548 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); 565 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum());
549 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg); 566 (Asm->*(Emitter.AddrGPR))(Ty, Addr, SrcReg);
550 } else if (const ConstantInteger32 *Imm = 567 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
551 llvm::dyn_cast<ConstantInteger32>(Src)) {
552 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue())); 568 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Imm->getValue()));
569 } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
570 AssemblerFixup *Fixup = x86::DisplacementRelocation::create(
571 Asm, FK_Abs_4, Reloc);
572 (Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Fixup));
553 } else { 573 } else {
554 llvm_unreachable("Unexpected operand type"); 574 llvm_unreachable("Unexpected operand type");
555 } 575 }
556 Ostream &Str = Func->getContext()->getStrEmit(); 576 emitIASBytes(Func, Asm, StartPosition);
557 emitIASBytes(Str, Asm, StartPosition);
558 } 577 }
559 578
560 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, 579 void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var,
561 const Operand *Src, 580 const Operand *Src,
562 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) { 581 const x86::AssemblerX86::GPREmitterShiftOp &Emitter) {
563 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 582 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
564 intptr_t StartPosition = Asm->GetPosition(); 583 intptr_t StartPosition = Asm->GetPosition();
565 // Technically, the Dest Var can be mem as well, but we only use Reg. 584 // Technically, the Dest Var can be mem as well, but we only use Reg.
566 // We can extend this to check Dest if we decide to use that form. 585 // We can extend this to check Dest if we decide to use that form.
567 assert(Var->hasReg()); 586 assert(Var->hasReg());
568 // We cheat a little and use GPRRegister even for byte operations. 587 // We cheat a little and use GPRRegister even for byte operations.
569 RegX8632::GPRRegister VarReg = 588 RegX8632::GPRRegister VarReg =
570 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum()); 589 RegX8632::getEncodedByteRegOrGPR(Ty, Var->getRegNum());
571 // Src must be reg == ECX or an Imm8. 590 // Src must be reg == ECX or an Imm8.
572 // This is asserted by the assembler. 591 // This is asserted by the assembler.
573 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { 592 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
574 assert(SrcVar->hasReg()); 593 assert(SrcVar->hasReg());
575 RegX8632::GPRRegister SrcReg = 594 RegX8632::GPRRegister SrcReg =
576 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum()); 595 RegX8632::getEncodedByteRegOrGPR(Ty, SrcVar->getRegNum());
577 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg); 596 (Asm->*(Emitter.GPRGPR))(Ty, VarReg, SrcReg);
578 } else if (const ConstantInteger32 *Imm = 597 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
579 llvm::dyn_cast<ConstantInteger32>(Src)) {
580 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); 598 (Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Imm->getValue()));
581 } else { 599 } else {
582 llvm_unreachable("Unexpected operand type"); 600 llvm_unreachable("Unexpected operand type");
583 } 601 }
584 Ostream &Str = Func->getContext()->getStrEmit(); 602 emitIASBytes(Func, Asm, StartPosition);
585 emitIASBytes(Str, Asm, StartPosition);
586 } 603 }
587 604
588 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, 605 void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var,
589 const Operand *Src, 606 const Operand *Src,
590 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) { 607 const x86::AssemblerX86::XmmEmitterShiftOp &Emitter) {
591 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 608 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
592 intptr_t StartPosition = Asm->GetPosition(); 609 intptr_t StartPosition = Asm->GetPosition();
593 assert(Var->hasReg()); 610 assert(Var->hasReg());
594 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); 611 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum());
595 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { 612 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
596 if (SrcVar->hasReg()) { 613 if (SrcVar->hasReg()) {
597 RegX8632::XmmRegister SrcReg = 614 RegX8632::XmmRegister SrcReg =
598 RegX8632::getEncodedXmm(SrcVar->getRegNum()); 615 RegX8632::getEncodedXmm(SrcVar->getRegNum());
599 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); 616 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
600 } else { 617 } else {
601 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 618 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
602 ->stackVarToAsmOperand(SrcVar); 619 ->stackVarToAsmOperand(SrcVar);
603 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); 620 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
604 } 621 }
605 } else if (const OperandX8632Mem *Mem = 622 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
606 llvm::dyn_cast<OperandX8632Mem>(Src)) { 623 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
607 x86::Address SrcAddr = Mem->toAsmAddress(Asm); 624 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
608 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr); 625 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Src)) {
609 } else if (const ConstantInteger32 *Imm =
610 llvm::dyn_cast<ConstantInteger32>(Src)) {
611 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue())); 626 (Asm->*(Emitter.XmmImm))(Ty, VarReg, x86::Immediate(Imm->getValue()));
612 } else { 627 } else {
613 llvm_unreachable("Unexpected operand type"); 628 llvm_unreachable("Unexpected operand type");
614 } 629 }
615 Ostream &Str = Func->getContext()->getStrEmit(); 630 emitIASBytes(Func, Asm, StartPosition);
616 emitIASBytes(Str, Asm, StartPosition);
617 } 631 }
618 632
619 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, 633 void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
620 const Operand *Src, 634 const Operand *Src,
621 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) { 635 const x86::AssemblerX86::XmmEmitterRegOp &Emitter) {
622 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 636 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
623 intptr_t StartPosition = Asm->GetPosition(); 637 intptr_t StartPosition = Asm->GetPosition();
624 assert(Var->hasReg()); 638 assert(Var->hasReg());
625 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum()); 639 RegX8632::XmmRegister VarReg = RegX8632::getEncodedXmm(Var->getRegNum());
626 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { 640 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
627 if (SrcVar->hasReg()) { 641 if (SrcVar->hasReg()) {
628 RegX8632::XmmRegister SrcReg = 642 RegX8632::XmmRegister SrcReg =
629 RegX8632::getEncodedXmm(SrcVar->getRegNum()); 643 RegX8632::getEncodedXmm(SrcVar->getRegNum());
630 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg); 644 (Asm->*(Emitter.XmmXmm))(Ty, VarReg, SrcReg);
631 } else { 645 } else {
632 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 646 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
633 ->stackVarToAsmOperand(SrcVar); 647 ->stackVarToAsmOperand(SrcVar);
634 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr); 648 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcStackAddr);
635 } 649 }
636 } else if (const OperandX8632Mem *Mem = 650 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
637 llvm::dyn_cast<OperandX8632Mem>(Src)) { 651 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
638 x86::Address SrcAddr = Mem->toAsmAddress(Asm); 652 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
639 (Asm->*(Emitter.XmmAddr))(Ty, VarReg, SrcAddr); 653 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
640 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) {
641 (Asm->*(Emitter.XmmAddr))( 654 (Asm->*(Emitter.XmmAddr))(
642 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); 655 Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
643 } else { 656 } else {
644 llvm_unreachable("Unexpected operand type"); 657 llvm_unreachable("Unexpected operand type");
645 } 658 }
646 Ostream &Str = Func->getContext()->getStrEmit(); 659 emitIASBytes(Func, Asm, StartPosition);
647 emitIASBytes(Str, Asm, StartPosition);
648 } 660 }
649 661
650 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t), 662 template <typename DReg_t, typename SReg_t, DReg_t (*destEnc)(int32_t),
651 SReg_t (*srcEnc)(int32_t)> 663 SReg_t (*srcEnc)(int32_t)>
652 void emitIASCastRegOp( 664 void emitIASCastRegOp(
653 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src, 665 const Cfg *Func, Type DispatchTy, const Variable *Dest, const Operand *Src,
654 const x86::AssemblerX86::CastEmitterRegOp<DReg_t, SReg_t> Emitter) { 666 const x86::AssemblerX86::CastEmitterRegOp<DReg_t, SReg_t> Emitter) {
655 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 667 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
656 intptr_t StartPosition = Asm->GetPosition(); 668 intptr_t StartPosition = Asm->GetPosition();
657 assert(Dest->hasReg()); 669 assert(Dest->hasReg());
658 DReg_t DestReg = destEnc(Dest->getRegNum()); 670 DReg_t DestReg = destEnc(Dest->getRegNum());
659 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { 671 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
660 if (SrcVar->hasReg()) { 672 if (SrcVar->hasReg()) {
661 SReg_t SrcReg = srcEnc(SrcVar->getRegNum()); 673 SReg_t SrcReg = srcEnc(SrcVar->getRegNum());
662 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg); 674 (Asm->*(Emitter.RegReg))(DispatchTy, DestReg, SrcReg);
663 } else { 675 } else {
664 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 676 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
665 ->stackVarToAsmOperand(SrcVar); 677 ->stackVarToAsmOperand(SrcVar);
666 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr); 678 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcStackAddr);
667 } 679 }
668 } else if (const OperandX8632Mem *Mem = 680 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
669 llvm::dyn_cast<OperandX8632Mem>(Src)) { 681 Mem->emitSegmentOverride(Asm);
670 x86::Address SrcAddr = Mem->toAsmAddress(Asm); 682 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, Mem->toAsmAddress(Asm));
671 (Asm->*(Emitter.RegAddr))(DispatchTy, DestReg, SrcAddr);
672 } else { 683 } else {
673 llvm_unreachable("Unexpected operand type"); 684 llvm_unreachable("Unexpected operand type");
674 } 685 }
675 Ostream &Str = Func->getContext()->getStrEmit(); 686 emitIASBytes(Func, Asm, StartPosition);
676 emitIASBytes(Str, Asm, StartPosition);
677 } 687 }
678 688
679 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest, 689 void emitIASMovlikeXMM(const Cfg *Func, const Variable *Dest,
680 const Operand *Src, 690 const Operand *Src,
681 const x86::AssemblerX86::XmmEmitterMovOps Emitter) { 691 const x86::AssemblerX86::XmmEmitterMovOps Emitter) {
682 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 692 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
683 intptr_t StartPosition = Asm->GetPosition(); 693 intptr_t StartPosition = Asm->GetPosition();
684 if (Dest->hasReg()) { 694 if (Dest->hasReg()) {
685 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum()); 695 RegX8632::XmmRegister DestReg = RegX8632::getEncodedXmm(Dest->getRegNum());
686 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) { 696 if (const auto SrcVar = llvm::dyn_cast<Variable>(Src)) {
687 if (SrcVar->hasReg()) { 697 if (SrcVar->hasReg()) {
688 (Asm->*(Emitter.XmmXmm))(DestReg, 698 (Asm->*(Emitter.XmmXmm))(DestReg,
689 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 699 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
690 } else { 700 } else {
691 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 701 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
692 ->stackVarToAsmOperand(SrcVar)); 702 ->stackVarToAsmOperand(SrcVar));
693 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr); 703 (Asm->*(Emitter.XmmAddr))(DestReg, StackAddr);
694 } 704 }
695 } else if (const OperandX8632Mem *SrcMem = 705 } else if (const auto SrcMem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
696 llvm::dyn_cast<OperandX8632Mem>(Src)) { 706 assert(SrcMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
697 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm)); 707 (Asm->*(Emitter.XmmAddr))(DestReg, SrcMem->toAsmAddress(Asm));
698 } else { 708 } else {
699 llvm_unreachable("Unexpected operand type"); 709 llvm_unreachable("Unexpected operand type");
700 } 710 }
701 } else { 711 } else {
702 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 712 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
703 ->stackVarToAsmOperand(Dest)); 713 ->stackVarToAsmOperand(Dest));
704 // Src must be a register in this case. 714 // Src must be a register in this case.
705 const Variable *SrcVar = llvm::cast<Variable>(Src); 715 const Variable *SrcVar = llvm::cast<Variable>(Src);
706 assert(SrcVar->hasReg()); 716 assert(SrcVar->hasReg());
707 (Asm->*(Emitter.AddrXmm))(StackAddr, 717 (Asm->*(Emitter.AddrXmm))(StackAddr,
708 RegX8632::getEncodedXmm(SrcVar->getRegNum())); 718 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
709 } 719 }
710 Ostream &Str = Func->getContext()->getStrEmit(); 720 emitIASBytes(Func, Asm, StartPosition);
711 emitIASBytes(Str, Asm, StartPosition);
712 } 721 }
713 722
714 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) { 723 bool checkForRedundantAssign(const Variable *Dest, const Operand *Source) {
715 const Variable *Src = llvm::dyn_cast<const Variable>(Source); 724 const Variable *Src = llvm::dyn_cast<const Variable>(Source);
716 if (Src == NULL) 725 if (Src == NULL)
717 return false; 726 return false;
718 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) { 727 if (Dest->hasReg() && Dest->getRegNum() == Src->getRegNum()) {
719 // TODO: On x86-64, instructions like "mov eax, eax" are used to 728 // TODO: On x86-64, instructions like "mov eax, eax" are used to
720 // clear the upper 32 bits of rax. We need to recognize and 729 // clear the upper 32 bits of rax. We need to recognize and
721 // preserve these. 730 // preserve these.
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 Str << "\tcwd\n"; 1167 Str << "\tcwd\n";
1159 break; 1168 break;
1160 case IceType_i32: 1169 case IceType_i32:
1161 assert(getDest()->getRegNum() == RegX8632::Reg_edx); 1170 assert(getDest()->getRegNum() == RegX8632::Reg_edx);
1162 Str << "\tcdq\n"; 1171 Str << "\tcdq\n";
1163 break; 1172 break;
1164 } 1173 }
1165 } 1174 }
1166 1175
1167 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { 1176 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const {
1168 Ostream &Str = Func->getContext()->getStrEmit();
1169 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1177 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1170 intptr_t StartPosition = Asm->GetPosition(); 1178 intptr_t StartPosition = Asm->GetPosition();
1171 assert(getSrcSize() == 1); 1179 assert(getSrcSize() == 1);
1172 Operand *Src0 = getSrc(0); 1180 Operand *Src0 = getSrc(0);
1173 assert(llvm::isa<Variable>(Src0)); 1181 assert(llvm::isa<Variable>(Src0));
1174 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); 1182 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax);
1175 switch (Src0->getType()) { 1183 switch (Src0->getType()) {
1176 default: 1184 default:
1177 llvm_unreachable("unexpected source type!"); 1185 llvm_unreachable("unexpected source type!");
1178 break; 1186 break;
1179 case IceType_i8: 1187 case IceType_i8:
1180 assert(getDest()->getRegNum() == RegX8632::Reg_eax); 1188 assert(getDest()->getRegNum() == RegX8632::Reg_eax);
1181 Asm->cbw(); 1189 Asm->cbw();
1182 break; 1190 break;
1183 case IceType_i16: 1191 case IceType_i16:
1184 assert(getDest()->getRegNum() == RegX8632::Reg_edx); 1192 assert(getDest()->getRegNum() == RegX8632::Reg_edx);
1185 Asm->cwd(); 1193 Asm->cwd();
1186 break; 1194 break;
1187 case IceType_i32: 1195 case IceType_i32:
1188 assert(getDest()->getRegNum() == RegX8632::Reg_edx); 1196 assert(getDest()->getRegNum() == RegX8632::Reg_edx);
1189 Asm->cdq(); 1197 Asm->cdq();
1190 break; 1198 break;
1191 } 1199 }
1192 emitIASBytes(Str, Asm, StartPosition); 1200 emitIASBytes(Func, Asm, StartPosition);
1193 } 1201 }
1194 1202
1195 void InstX8632Mul::emit(const Cfg *Func) const { 1203 void InstX8632Mul::emit(const Cfg *Func) const {
1196 Ostream &Str = Func->getContext()->getStrEmit(); 1204 Ostream &Str = Func->getContext()->getStrEmit();
1197 assert(getSrcSize() == 2); 1205 assert(getSrcSize() == 2);
1198 assert(llvm::isa<Variable>(getSrc(0))); 1206 assert(llvm::isa<Variable>(getSrc(0)));
1199 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); 1207 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax);
1200 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? 1208 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx?
1201 Str << "\tmul\t"; 1209 Str << "\tmul\t";
1202 getSrc(1)->emit(Func); 1210 getSrc(1)->emit(Func);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 assert(Condition != CondX86::Br_None); 1288 assert(Condition != CondX86::Br_None);
1281 assert(getDest()->hasReg()); 1289 assert(getDest()->hasReg());
1282 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; 1290 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t";
1283 getDest()->emit(Func); 1291 getDest()->emit(Func);
1284 Str << ", "; 1292 Str << ", ";
1285 getSrc(1)->emit(Func); 1293 getSrc(1)->emit(Func);
1286 Str << "\n"; 1294 Str << "\n";
1287 } 1295 }
1288 1296
1289 void InstX8632Cmov::emitIAS(const Cfg *Func) const { 1297 void InstX8632Cmov::emitIAS(const Cfg *Func) const {
1290 Ostream &Str = Func->getContext()->getStrEmit();
1291 Str << "\t";
1292 assert(Condition != CondX86::Br_None); 1298 assert(Condition != CondX86::Br_None);
1293 assert(getDest()->hasReg()); 1299 assert(getDest()->hasReg());
1294 assert(getSrcSize() == 2); 1300 assert(getSrcSize() == 2);
1295 // Only need the reg/reg form now. 1301 // Only need the reg/reg form now.
1296 const Variable *Src = llvm::cast<Variable>(getSrc(1)); 1302 const Variable *Src = llvm::cast<Variable>(getSrc(1));
1297 assert(Src->hasReg()); 1303 assert(Src->hasReg());
1298 assert(Src->getType() == IceType_i32); 1304 assert(Src->getType() == IceType_i32);
1299 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1305 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1300 intptr_t StartPosition = Asm->GetPosition(); 1306 intptr_t StartPosition = Asm->GetPosition();
1301 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), 1307 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()),
1302 RegX8632::getEncodedGPR(Src->getRegNum())); 1308 RegX8632::getEncodedGPR(Src->getRegNum()));
1303 emitIASBytes(Str, Asm, StartPosition); 1309 emitIASBytes(Func, Asm, StartPosition);
1304 } 1310 }
1305 1311
1306 void InstX8632Cmov::dump(const Cfg *Func) const { 1312 void InstX8632Cmov::dump(const Cfg *Func) const {
1307 Ostream &Str = Func->getContext()->getStrDump(); 1313 Ostream &Str = Func->getContext()->getStrDump();
1308 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; 1314 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << ".";
1309 Str << getDest()->getType() << " "; 1315 Str << getDest()->getType() << " ";
1310 dumpDest(Func); 1316 dumpDest(Func);
1311 Str << ", "; 1317 Str << ", ";
1312 dumpSources(Func); 1318 dumpSources(Func);
1313 } 1319 }
1314 1320
1315 void InstX8632Cmpps::emit(const Cfg *Func) const { 1321 void InstX8632Cmpps::emit(const Cfg *Func) const {
1316 Ostream &Str = Func->getContext()->getStrEmit(); 1322 Ostream &Str = Func->getContext()->getStrEmit();
1317 assert(getSrcSize() == 2); 1323 assert(getSrcSize() == 2);
1318 assert(Condition < CondX86::Cmpps_Invalid); 1324 assert(Condition < CondX86::Cmpps_Invalid);
1319 Str << "\t"; 1325 Str << "\t";
1320 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1326 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
1321 << "\t"; 1327 << "\t";
1322 getDest()->emit(Func); 1328 getDest()->emit(Func);
1323 Str << ", "; 1329 Str << ", ";
1324 getSrc(1)->emit(Func); 1330 getSrc(1)->emit(Func);
1325 Str << "\n"; 1331 Str << "\n";
1326 } 1332 }
1327 1333
1328 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { 1334 void InstX8632Cmpps::emitIAS(const Cfg *Func) const {
1329 Ostream &Str = Func->getContext()->getStrEmit();
1330 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1335 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1331 intptr_t StartPosition = Asm->GetPosition(); 1336 intptr_t StartPosition = Asm->GetPosition();
1332 assert(getSrcSize() == 2); 1337 assert(getSrcSize() == 2);
1333 assert(Condition < CondX86::Cmpps_Invalid); 1338 assert(Condition < CondX86::Cmpps_Invalid);
1334 // Assuming there isn't any load folding for cmpps, and vector constants 1339 // Assuming there isn't any load folding for cmpps, and vector constants
1335 // are not allowed in PNaCl. 1340 // are not allowed in PNaCl.
1336 assert(llvm::isa<Variable>(getSrc(1))); 1341 assert(llvm::isa<Variable>(getSrc(1)));
1337 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); 1342 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1));
1338 if (SrcVar->hasReg()) { 1343 if (SrcVar->hasReg()) {
1339 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), 1344 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()),
1340 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); 1345 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition);
1341 } else { 1346 } else {
1342 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) 1347 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
1343 ->stackVarToAsmOperand(SrcVar); 1348 ->stackVarToAsmOperand(SrcVar);
1344 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, 1349 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr,
1345 Condition); 1350 Condition);
1346 } 1351 }
1347 emitIASBytes(Str, Asm, StartPosition); 1352 emitIASBytes(Func, Asm, StartPosition);
1348 } 1353 }
1349 1354
1350 void InstX8632Cmpps::dump(const Cfg *Func) const { 1355 void InstX8632Cmpps::dump(const Cfg *Func) const {
1351 Ostream &Str = Func->getContext()->getStrDump(); 1356 Ostream &Str = Func->getContext()->getStrDump();
1352 assert(Condition < CondX86::Cmpps_Invalid); 1357 assert(Condition < CondX86::Cmpps_Invalid);
1353 dumpDest(Func); 1358 dumpDest(Func);
1354 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1359 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
1355 << "\t"; 1360 << "\t";
1356 dumpSources(Func); 1361 dumpSources(Func);
1357 } 1362 }
1358 1363
1359 void InstX8632Cmpxchg::emit(const Cfg *Func) const { 1364 void InstX8632Cmpxchg::emit(const Cfg *Func) const {
1360 Ostream &Str = Func->getContext()->getStrEmit(); 1365 Ostream &Str = Func->getContext()->getStrEmit();
1361 assert(getSrcSize() == 3); 1366 assert(getSrcSize() == 3);
1362 if (Locked) { 1367 if (Locked) {
1363 Str << "\tlock"; 1368 Str << "\tlock";
1364 } 1369 }
1365 Str << "\tcmpxchg\t"; 1370 Str << "\tcmpxchg\t";
1366 getSrc(0)->emit(Func); 1371 getSrc(0)->emit(Func);
1367 Str << ", "; 1372 Str << ", ";
1368 getSrc(2)->emit(Func); 1373 getSrc(2)->emit(Func);
1369 Str << "\n"; 1374 Str << "\n";
1370 } 1375 }
1371 1376
1372 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { 1377 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const {
1373 Ostream &Str = Func->getContext()->getStrEmit();
1374 assert(getSrcSize() == 3); 1378 assert(getSrcSize() == 3);
1375 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1379 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1376 intptr_t StartPosition = Asm->GetPosition(); 1380 intptr_t StartPosition = Asm->GetPosition();
1377 Type Ty = getSrc(0)->getType(); 1381 Type Ty = getSrc(0)->getType();
1378 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 1382 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
1383 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1379 const x86::Address Addr = Mem->toAsmAddress(Asm); 1384 const x86::Address Addr = Mem->toAsmAddress(Asm);
1380 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); 1385 const Variable *VarReg = llvm::cast<Variable>(getSrc(2));
1381 assert(VarReg->hasReg()); 1386 assert(VarReg->hasReg());
1382 const RegX8632::GPRRegister Reg = 1387 const RegX8632::GPRRegister Reg =
1383 RegX8632::getEncodedGPR(VarReg->getRegNum()); 1388 RegX8632::getEncodedGPR(VarReg->getRegNum());
1384 if (Locked) { 1389 if (Locked) {
1385 Asm->LockCmpxchg(Ty, Addr, Reg); 1390 Asm->LockCmpxchg(Ty, Addr, Reg);
1386 } else { 1391 } else {
1387 Asm->cmpxchg(Ty, Addr, Reg); 1392 Asm->cmpxchg(Ty, Addr, Reg);
1388 } 1393 }
1389 emitIASBytes(Str, Asm, StartPosition); 1394 emitIASBytes(Func, Asm, StartPosition);
1390 } 1395 }
1391 1396
1392 void InstX8632Cmpxchg::dump(const Cfg *Func) const { 1397 void InstX8632Cmpxchg::dump(const Cfg *Func) const {
1393 Ostream &Str = Func->getContext()->getStrDump(); 1398 Ostream &Str = Func->getContext()->getStrDump();
1394 if (Locked) { 1399 if (Locked) {
1395 Str << "lock "; 1400 Str << "lock ";
1396 } 1401 }
1397 Str << "cmpxchg." << getSrc(0)->getType() << " "; 1402 Str << "cmpxchg." << getSrc(0)->getType() << " ";
1398 dumpSources(Func); 1403 dumpSources(Func);
1399 } 1404 }
1400 1405
1401 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { 1406 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const {
1402 Ostream &Str = Func->getContext()->getStrEmit(); 1407 Ostream &Str = Func->getContext()->getStrEmit();
1403 assert(getSrcSize() == 5); 1408 assert(getSrcSize() == 5);
1404 if (Locked) { 1409 if (Locked) {
1405 Str << "\tlock"; 1410 Str << "\tlock";
1406 } 1411 }
1407 Str << "\tcmpxchg8b\t"; 1412 Str << "\tcmpxchg8b\t";
1408 getSrc(0)->emit(Func); 1413 getSrc(0)->emit(Func);
1409 Str << "\n"; 1414 Str << "\n";
1410 } 1415 }
1411 1416
1412 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { 1417 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const {
1413 Ostream &Str = Func->getContext()->getStrEmit();
1414 assert(getSrcSize() == 5); 1418 assert(getSrcSize() == 5);
1415 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1419 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1416 intptr_t StartPosition = Asm->GetPosition(); 1420 intptr_t StartPosition = Asm->GetPosition();
1417 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 1421 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
1422 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1418 const x86::Address Addr = Mem->toAsmAddress(Asm); 1423 const x86::Address Addr = Mem->toAsmAddress(Asm);
1419 if (Locked) { 1424 if (Locked) {
1420 Asm->lock(); 1425 Asm->lock();
1421 } 1426 }
1422 Asm->cmpxchg8b(Addr); 1427 Asm->cmpxchg8b(Addr);
1423 emitIASBytes(Str, Asm, StartPosition); 1428 emitIASBytes(Func, Asm, StartPosition);
1424 } 1429 }
1425 1430
1426 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { 1431 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const {
1427 Ostream &Str = Func->getContext()->getStrDump(); 1432 Ostream &Str = Func->getContext()->getStrDump();
1428 if (Locked) { 1433 if (Locked) {
1429 Str << "lock "; 1434 Str << "lock ";
1430 } 1435 }
1431 Str << "cmpxchg8b "; 1436 Str << "cmpxchg8b ";
1432 dumpSources(Func); 1437 dumpSources(Func);
1433 } 1438 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 if (SrcVar0->hasReg()) { 1546 if (SrcVar0->hasReg()) {
1542 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); 1547 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter);
1543 } else { 1548 } else {
1544 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 1549 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1545 ->stackVarToAsmOperand(SrcVar0)); 1550 ->stackVarToAsmOperand(SrcVar0));
1546 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); 1551 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter);
1547 } 1552 }
1548 } else if (const OperandX8632Mem *SrcMem0 = 1553 } else if (const OperandX8632Mem *SrcMem0 =
1549 llvm::dyn_cast<OperandX8632Mem>(Src0)) { 1554 llvm::dyn_cast<OperandX8632Mem>(Src0)) {
1550 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1555 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1556 SrcMem0->emitSegmentOverride(Asm);
1551 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); 1557 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter);
1552 } 1558 }
1553 } 1559 }
1554 1560
1555 void InstX8632Icmp::dump(const Cfg *Func) const { 1561 void InstX8632Icmp::dump(const Cfg *Func) const {
1556 Ostream &Str = Func->getContext()->getStrDump(); 1562 Ostream &Str = Func->getContext()->getStrDump();
1557 Str << "cmp." << getSrc(0)->getType() << " "; 1563 Str << "cmp." << getSrc(0)->getType() << " ";
1558 dumpSources(Func); 1564 dumpSources(Func);
1559 } 1565 }
1560 1566
(...skipping 30 matching lines...) Expand all
1591 void InstX8632UD2::emit(const Cfg *Func) const { 1597 void InstX8632UD2::emit(const Cfg *Func) const {
1592 Ostream &Str = Func->getContext()->getStrEmit(); 1598 Ostream &Str = Func->getContext()->getStrEmit();
1593 assert(getSrcSize() == 0); 1599 assert(getSrcSize() == 0);
1594 Str << "\tud2\n"; 1600 Str << "\tud2\n";
1595 } 1601 }
1596 1602
1597 void InstX8632UD2::emitIAS(const Cfg *Func) const { 1603 void InstX8632UD2::emitIAS(const Cfg *Func) const {
1598 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1604 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1599 intptr_t StartPosition = Asm->GetPosition(); 1605 intptr_t StartPosition = Asm->GetPosition();
1600 Asm->ud2(); 1606 Asm->ud2();
1601 Ostream &Str = Func->getContext()->getStrEmit(); 1607 emitIASBytes(Func, Asm, StartPosition);
1602 emitIASBytes(Str, Asm, StartPosition);
1603 } 1608 }
1604 1609
1605 void InstX8632UD2::dump(const Cfg *Func) const { 1610 void InstX8632UD2::dump(const Cfg *Func) const {
1606 Ostream &Str = Func->getContext()->getStrDump(); 1611 Ostream &Str = Func->getContext()->getStrDump();
1607 Str << "ud2\n"; 1612 Str << "ud2\n";
1608 } 1613 }
1609 1614
1610 void InstX8632Test::emit(const Cfg *Func) const { 1615 void InstX8632Test::emit(const Cfg *Func) const {
1611 Ostream &Str = Func->getContext()->getStrEmit(); 1616 Ostream &Str = Func->getContext()->getStrEmit();
1612 assert(getSrcSize() == 2); 1617 assert(getSrcSize() == 2);
(...skipping 22 matching lines...) Expand all
1635 } else { 1640 } else {
1636 llvm_unreachable("Nothing actually generates this so it's untested"); 1641 llvm_unreachable("Nothing actually generates this so it's untested");
1637 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 1642 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1638 ->stackVarToAsmOperand(SrcVar0)); 1643 ->stackVarToAsmOperand(SrcVar0));
1639 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); 1644 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter);
1640 } 1645 }
1641 } else if (const OperandX8632Mem *SrcMem0 = 1646 } else if (const OperandX8632Mem *SrcMem0 =
1642 llvm::dyn_cast<OperandX8632Mem>(Src0)) { 1647 llvm::dyn_cast<OperandX8632Mem>(Src0)) {
1643 llvm_unreachable("Nothing actually generates this so it's untested"); 1648 llvm_unreachable("Nothing actually generates this so it's untested");
1644 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1649 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1650 SrcMem0->emitSegmentOverride(Asm);
1645 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); 1651 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter);
1646 } 1652 }
1647 } 1653 }
1648 1654
1649 void InstX8632Test::dump(const Cfg *Func) const { 1655 void InstX8632Test::dump(const Cfg *Func) const {
1650 Ostream &Str = Func->getContext()->getStrDump(); 1656 Ostream &Str = Func->getContext()->getStrDump();
1651 Str << "test." << getSrc(0)->getType() << " "; 1657 Str << "test." << getSrc(0)->getType() << " ";
1652 dumpSources(Func); 1658 dumpSources(Func);
1653 } 1659 }
1654 1660
1655 void InstX8632Mfence::emit(const Cfg *Func) const { 1661 void InstX8632Mfence::emit(const Cfg *Func) const {
1656 Ostream &Str = Func->getContext()->getStrEmit(); 1662 Ostream &Str = Func->getContext()->getStrEmit();
1657 assert(getSrcSize() == 0); 1663 assert(getSrcSize() == 0);
1658 Str << "\tmfence\n"; 1664 Str << "\tmfence\n";
1659 } 1665 }
1660 1666
1661 void InstX8632Mfence::emitIAS(const Cfg *Func) const { 1667 void InstX8632Mfence::emitIAS(const Cfg *Func) const {
1662 Ostream &Str = Func->getContext()->getStrEmit();
1663 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1668 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1664 intptr_t StartPosition = Asm->GetPosition(); 1669 intptr_t StartPosition = Asm->GetPosition();
1665 Asm->mfence(); 1670 Asm->mfence();
1666 emitIASBytes(Str, Asm, StartPosition); 1671 emitIASBytes(Func, Asm, StartPosition);
1667 } 1672 }
1668 1673
1669 void InstX8632Mfence::dump(const Cfg *Func) const { 1674 void InstX8632Mfence::dump(const Cfg *Func) const {
1670 Ostream &Str = Func->getContext()->getStrDump(); 1675 Ostream &Str = Func->getContext()->getStrDump();
1671 Str << "mfence\n"; 1676 Str << "mfence\n";
1672 } 1677 }
1673 1678
1674 void InstX8632Store::emit(const Cfg *Func) const { 1679 void InstX8632Store::emit(const Cfg *Func) const {
1675 Ostream &Str = Func->getContext()->getStrEmit(); 1680 Ostream &Str = Func->getContext()->getStrEmit();
1676 assert(getSrcSize() == 2); 1681 assert(getSrcSize() == 2);
(...skipping 22 matching lines...) Expand all
1699 getSrc(0)->emit(Func); 1704 getSrc(0)->emit(Func);
1700 Str << "\n"; 1705 Str << "\n";
1701 } 1706 }
1702 1707
1703 void InstX8632StoreP::emitIAS(const Cfg *Func) const { 1708 void InstX8632StoreP::emitIAS(const Cfg *Func) const {
1704 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1709 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1705 intptr_t StartPosition = Asm->GetPosition(); 1710 intptr_t StartPosition = Asm->GetPosition();
1706 assert(getSrcSize() == 2); 1711 assert(getSrcSize() == 2);
1707 const Variable *Src = llvm::cast<Variable>(getSrc(0)); 1712 const Variable *Src = llvm::cast<Variable>(getSrc(0));
1708 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); 1713 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
1714 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1709 assert(Src->hasReg()); 1715 assert(Src->hasReg());
1710 Asm->movups(DestMem->toAsmAddress(Asm), 1716 Asm->movups(DestMem->toAsmAddress(Asm),
1711 RegX8632::getEncodedXmm(Src->getRegNum())); 1717 RegX8632::getEncodedXmm(Src->getRegNum()));
1712 Ostream &Str = Func->getContext()->getStrEmit(); 1718 emitIASBytes(Func, Asm, StartPosition);
1713 emitIASBytes(Str, Asm, StartPosition);
1714 } 1719 }
1715 1720
1716 void InstX8632StoreP::dump(const Cfg *Func) const { 1721 void InstX8632StoreP::dump(const Cfg *Func) const {
1717 Ostream &Str = Func->getContext()->getStrDump(); 1722 Ostream &Str = Func->getContext()->getStrDump();
1718 Str << "storep." << getSrc(0)->getType() << " "; 1723 Str << "storep." << getSrc(0)->getType() << " ";
1719 getSrc(1)->dump(Func); 1724 getSrc(1)->dump(Func);
1720 Str << ", "; 1725 Str << ", ";
1721 getSrc(0)->dump(Func); 1726 getSrc(0)->dump(Func);
1722 } 1727 }
1723 1728
1724 void InstX8632StoreQ::emit(const Cfg *Func) const { 1729 void InstX8632StoreQ::emit(const Cfg *Func) const {
1725 Ostream &Str = Func->getContext()->getStrEmit(); 1730 Ostream &Str = Func->getContext()->getStrEmit();
1726 assert(getSrcSize() == 2); 1731 assert(getSrcSize() == 2);
1727 assert(getSrc(1)->getType() == IceType_i64 || 1732 assert(getSrc(1)->getType() == IceType_i64 ||
1728 getSrc(1)->getType() == IceType_f64); 1733 getSrc(1)->getType() == IceType_f64);
1729 Str << "\tmovq\t"; 1734 Str << "\tmovq\t";
1730 getSrc(1)->emit(Func); 1735 getSrc(1)->emit(Func);
1731 Str << ", "; 1736 Str << ", ";
1732 getSrc(0)->emit(Func); 1737 getSrc(0)->emit(Func);
1733 Str << "\n"; 1738 Str << "\n";
1734 } 1739 }
1735 1740
1736 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { 1741 void InstX8632StoreQ::emitIAS(const Cfg *Func) const {
1737 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1742 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1738 intptr_t StartPosition = Asm->GetPosition(); 1743 intptr_t StartPosition = Asm->GetPosition();
1739 assert(getSrcSize() == 2); 1744 assert(getSrcSize() == 2);
1740 const Variable *Src = llvm::cast<Variable>(getSrc(0)); 1745 const Variable *Src = llvm::cast<Variable>(getSrc(0));
1741 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); 1746 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1));
1747 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
1742 assert(Src->hasReg()); 1748 assert(Src->hasReg());
1743 Asm->movq(DestMem->toAsmAddress(Asm), 1749 Asm->movq(DestMem->toAsmAddress(Asm),
1744 RegX8632::getEncodedXmm(Src->getRegNum())); 1750 RegX8632::getEncodedXmm(Src->getRegNum()));
1745 Ostream &Str = Func->getContext()->getStrEmit(); 1751 emitIASBytes(Func, Asm, StartPosition);
1746 emitIASBytes(Str, Asm, StartPosition);
1747 } 1752 }
1748 1753
1749 void InstX8632StoreQ::dump(const Cfg *Func) const { 1754 void InstX8632StoreQ::dump(const Cfg *Func) const {
1750 Ostream &Str = Func->getContext()->getStrDump(); 1755 Ostream &Str = Func->getContext()->getStrDump();
1751 Str << "storeq." << getSrc(0)->getType() << " "; 1756 Str << "storeq." << getSrc(0)->getType() << " ";
1752 getSrc(1)->dump(Func); 1757 getSrc(1)->dump(Func);
1753 Str << ", "; 1758 Str << ", ";
1754 getSrc(0)->dump(Func); 1759 getSrc(0)->dump(Func);
1755 } 1760 }
1756 1761
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1816 Str << "\n"; 1821 Str << "\n";
1817 Str << ".intel_syntax\n"; 1822 Str << ".intel_syntax\n";
1818 } else { 1823 } else {
1819 getDest()->asType(Src->getType()).emit(Func); 1824 getDest()->asType(Src->getType()).emit(Func);
1820 Str << ", "; 1825 Str << ", ";
1821 Src->emit(Func); 1826 Src->emit(Func);
1822 Str << "\n"; 1827 Str << "\n";
1823 } 1828 }
1824 } 1829 }
1825 1830
1831 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const {
1832 assert(getSrcSize() == 1);
1833 const Variable *Dest = getDest();
1834 const Operand *Src = getSrc(0);
1835 Type DestTy = Dest->getType();
1836 Type SrcTy = Src->getType();
1837 // Mov can be used for GPRs or XMM registers. Also, the type does not
1838 // necessarily match (Mov can be used for bitcasts). However, when
1839 // the type does not match, one of the operands must be a register.
1840 // Thus, the strategy is to find out if Src or Dest are a register,
1841 // then use that register's type to decide on which emitter set to use.
1842 // The emitter set will include reg-reg movs, but that case should
1843 // be unused when the types don't match.
1844 static const x86::AssemblerX86::XmmEmitterRegOp XmmRegEmitter = {
1845 &x86::AssemblerX86::movss, &x86::AssemblerX86::movss};
1846 static const x86::AssemblerX86::GPREmitterRegOp GPRRegEmitter = {
1847 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov, &x86::AssemblerX86::mov};
1848 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = {
1849 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov};
1850 // For an integer truncation operation, src is wider than dest.
1851 // Ideally, we use a mov instruction whose data width matches the
1852 // narrower dest. This is a problem if e.g. src is a register like
1853 // esi or si where there is no 8-bit version of the register. To be
1854 // safe, we instead widen the dest to match src. This works even
1855 // for stack-allocated dest variables because typeWidthOnStack()
1856 // pads to a 4-byte boundary even if only a lower portion is used.
1857 // TODO: This assert disallows usages such as copying a floating point
1858 // value between a vector and a scalar (which movss is used for).
1859 // Clean this up.
1860 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) ==
1861 Func->getTarget()->typeWidthInBytesOnStack(Src->getType()));
1862 if (Dest->hasReg()) {
1863 if (isScalarFloatingType(DestTy)) {
1864 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, XmmRegEmitter);
1865 return;
1866 } else {
1867 assert(isScalarIntegerType(DestTy));
1868 // Widen DestTy for truncation (see above note). We should only do this
1869 // when both Src and Dest are integer types.
1870 if (isScalarIntegerType(SrcTy)) {
1871 DestTy = SrcTy;
1872 }
1873 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter);
1874 return;
1875 }
1876 } else {
1877 // Dest must be Stack and Src *could* be a register. Use Src's type
1878 // to decide on the emitters.
1879 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1880 ->stackVarToAsmOperand(Dest));
1881 if (isScalarFloatingType(SrcTy)) {
1882 // Src must be a register.
1883 const Variable *SrcVar = llvm::cast<Variable>(Src);
1884 assert(SrcVar->hasReg());
1885 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1886 intptr_t StartPosition = Asm->GetPosition();
1887 Asm->movss(SrcTy, StackAddr,
1888 RegX8632::getEncodedXmm(SrcVar->getRegNum()));
1889 emitIASBytes(Func, Asm, StartPosition);
1890 return;
1891 } else {
1892 // Src can be a register or immediate.
1893 assert(isScalarIntegerType(SrcTy));
1894 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter);
1895 return;
1896 }
1897 return;
1898 }
1899 }
1900
1826 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { 1901 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const {
1827 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1902 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1828 intptr_t StartPosition = Asm->GetPosition(); 1903 intptr_t StartPosition = Asm->GetPosition();
1829 assert(getSrcSize() == 1); 1904 assert(getSrcSize() == 1);
1830 const Variable *Dest = getDest(); 1905 const Variable *Dest = getDest();
1831 const Variable *Src = llvm::cast<Variable>(getSrc(0)); 1906 const Variable *Src = llvm::cast<Variable>(getSrc(0));
1832 // For insert/extract element (one of Src/Dest is an Xmm vector and 1907 // For insert/extract element (one of Src/Dest is an Xmm vector and
1833 // the other is an int type). 1908 // the other is an int type).
1834 if (Src->getType() == IceType_i32) { 1909 if (Src->getType() == IceType_i32) {
1835 assert(isVectorType(Dest->getType())); 1910 assert(isVectorType(Dest->getType()));
(...skipping 12 matching lines...) Expand all
1848 assert(Dest->getType() == IceType_i32); 1923 assert(Dest->getType() == IceType_i32);
1849 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum()); 1924 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum());
1850 if (Dest->hasReg()) { 1925 if (Dest->hasReg()) {
1851 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); 1926 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg);
1852 } else { 1927 } else {
1853 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 1928 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
1854 ->stackVarToAsmOperand(Dest)); 1929 ->stackVarToAsmOperand(Dest));
1855 Asm->movd(StackAddr, SrcReg); 1930 Asm->movd(StackAddr, SrcReg);
1856 } 1931 }
1857 } 1932 }
1858 Ostream &Str = Func->getContext()->getStrEmit(); 1933 emitIASBytes(Func, Asm, StartPosition);
1859 emitIASBytes(Str, Asm, StartPosition);
1860 } 1934 }
1861 1935
1862 template <> void InstX8632Movp::emit(const Cfg *Func) const { 1936 template <> void InstX8632Movp::emit(const Cfg *Func) const {
1863 // TODO(wala,stichnot): movups works with all vector operands, but 1937 // TODO(wala,stichnot): movups works with all vector operands, but
1864 // there exist other instructions (movaps, movdqa, movdqu) that may 1938 // there exist other instructions (movaps, movdqa, movdqu) that may
1865 // perform better, depending on the data type and alignment of the 1939 // perform better, depending on the data type and alignment of the
1866 // operands. 1940 // operands.
1867 Ostream &Str = Func->getContext()->getStrEmit(); 1941 Ostream &Str = Func->getContext()->getStrEmit();
1868 assert(getSrcSize() == 1); 1942 assert(getSrcSize() == 1);
1869 Str << "\tmovups\t"; 1943 Str << "\tmovups\t";
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 // where part of the Dest register is untouched. 1988 // where part of the Dest register is untouched.
1915 assert(getSrcSize() == 2); 1989 assert(getSrcSize() == 2);
1916 const Variable *Dest = getDest(); 1990 const Variable *Dest = getDest();
1917 assert(Dest == getSrc(0)); 1991 assert(Dest == getSrc(0));
1918 const Variable *Src = llvm::cast<Variable>(getSrc(1)); 1992 const Variable *Src = llvm::cast<Variable>(getSrc(1));
1919 assert(Dest->hasReg() && Src->hasReg()); 1993 assert(Dest->hasReg() && Src->hasReg());
1920 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 1994 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1921 intptr_t StartPosition = Asm->GetPosition(); 1995 intptr_t StartPosition = Asm->GetPosition();
1922 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), 1996 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()),
1923 RegX8632::getEncodedXmm(Src->getRegNum())); 1997 RegX8632::getEncodedXmm(Src->getRegNum()));
1924 Ostream &Str = Func->getContext()->getStrEmit(); 1998 emitIASBytes(Func, Asm, StartPosition);
1925 emitIASBytes(Str, Asm, StartPosition);
1926 } 1999 }
1927 2000
1928 void InstX8632Movsx::emit(const Cfg *Func) const { 2001 void InstX8632Movsx::emit(const Cfg *Func) const {
1929 Ostream &Str = Func->getContext()->getStrEmit(); 2002 Ostream &Str = Func->getContext()->getStrEmit();
1930 assert(getSrcSize() == 1); 2003 assert(getSrcSize() == 1);
1931 Str << "\tmovsx\t"; 2004 Str << "\tmovsx\t";
1932 getDest()->emit(Func); 2005 getDest()->emit(Func);
1933 Str << ", "; 2006 Str << ", ";
1934 getSrc(0)->emit(Func); 2007 getSrc(0)->emit(Func);
1935 Str << "\n"; 2008 Str << "\n";
(...skipping 27 matching lines...) Expand all
1963 dumpSources(Func); 2036 dumpSources(Func);
1964 } 2037 }
1965 2038
1966 void InstX8632Nop::emit(const Cfg *Func) const { 2039 void InstX8632Nop::emit(const Cfg *Func) const {
1967 Ostream &Str = Func->getContext()->getStrEmit(); 2040 Ostream &Str = Func->getContext()->getStrEmit();
1968 // TODO: Emit the right code for each variant. 2041 // TODO: Emit the right code for each variant.
1969 Str << "\tnop\t# variant = " << Variant << "\n"; 2042 Str << "\tnop\t# variant = " << Variant << "\n";
1970 } 2043 }
1971 2044
1972 void InstX8632Nop::emitIAS(const Cfg *Func) const { 2045 void InstX8632Nop::emitIAS(const Cfg *Func) const {
1973 Ostream &Str = Func->getContext()->getStrEmit();
1974 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2046 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1975 intptr_t StartPosition = Asm->GetPosition(); 2047 intptr_t StartPosition = Asm->GetPosition();
1976 // TODO: Emit the right code for the variant. 2048 // TODO: Emit the right code for the variant.
1977 Asm->nop(); 2049 Asm->nop();
1978 emitIASBytes(Str, Asm, StartPosition); 2050 emitIASBytes(Func, Asm, StartPosition);
1979 } 2051 }
1980 2052
1981 void InstX8632Nop::dump(const Cfg *Func) const { 2053 void InstX8632Nop::dump(const Cfg *Func) const {
1982 Ostream &Str = Func->getContext()->getStrDump(); 2054 Ostream &Str = Func->getContext()->getStrDump();
1983 Str << "nop (variant = " << Variant << ")"; 2055 Str << "nop (variant = " << Variant << ")";
1984 } 2056 }
1985 2057
1986 void InstX8632Fld::emit(const Cfg *Func) const { 2058 void InstX8632Fld::emit(const Cfg *Func) const {
1987 Ostream &Str = Func->getContext()->getStrEmit(); 2059 Ostream &Str = Func->getContext()->getStrEmit();
1988 assert(getSrcSize() == 1); 2060 assert(getSrcSize() == 1);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); 2093 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
2022 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); 2094 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum()));
2023 Asm->fld(Ty, StackSlot); 2095 Asm->fld(Ty, StackSlot);
2024 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); 2096 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2025 } else { 2097 } else {
2026 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2098 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2027 ->stackVarToAsmOperand(Var)); 2099 ->stackVarToAsmOperand(Var));
2028 Asm->fld(Ty, StackAddr); 2100 Asm->fld(Ty, StackAddr);
2029 } 2101 }
2030 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { 2102 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) {
2103 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2031 Asm->fld(Ty, Mem->toAsmAddress(Asm)); 2104 Asm->fld(Ty, Mem->toAsmAddress(Asm));
2032 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { 2105 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
2033 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); 2106 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
2034 } else { 2107 } else {
2035 llvm_unreachable("Unexpected operand type"); 2108 llvm_unreachable("Unexpected operand type");
2036 } 2109 }
2037 Ostream &Str = Func->getContext()->getStrEmit(); 2110 emitIASBytes(Func, Asm, StartPosition);
2038 emitIASBytes(Str, Asm, StartPosition);
2039 } 2111 }
2040 2112
2041 void InstX8632Fld::dump(const Cfg *Func) const { 2113 void InstX8632Fld::dump(const Cfg *Func) const {
2042 Ostream &Str = Func->getContext()->getStrDump(); 2114 Ostream &Str = Func->getContext()->getStrDump();
2043 Str << "fld." << getSrc(0)->getType() << " "; 2115 Str << "fld." << getSrc(0)->getType() << " ";
2044 dumpSources(Func); 2116 dumpSources(Func);
2045 } 2117 }
2046 2118
2047 void InstX8632Fstp::emit(const Cfg *Func) const { 2119 void InstX8632Fstp::emit(const Cfg *Func) const {
2048 Ostream &Str = Func->getContext()->getStrEmit(); 2120 Ostream &Str = Func->getContext()->getStrEmit();
(...skipping 30 matching lines...) Expand all
2079 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2151 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2080 intptr_t StartPosition = Asm->GetPosition(); 2152 intptr_t StartPosition = Asm->GetPosition();
2081 assert(getSrcSize() == 0); 2153 assert(getSrcSize() == 0);
2082 const Variable *Dest = getDest(); 2154 const Variable *Dest = getDest();
2083 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to 2155 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to
2084 // "partially" delete the fstp if the Dest is unused. 2156 // "partially" delete the fstp if the Dest is unused.
2085 // Even if Dest is unused, the fstp should be kept for the SideEffects 2157 // Even if Dest is unused, the fstp should be kept for the SideEffects
2086 // of popping the stack. 2158 // of popping the stack.
2087 if (Dest == NULL) { 2159 if (Dest == NULL) {
2088 Asm->fstp(RegX8632::getEncodedSTReg(0)); 2160 Asm->fstp(RegX8632::getEncodedSTReg(0));
2089 Ostream &Str = Func->getContext()->getStrEmit(); 2161 emitIASBytes(Func, Asm, StartPosition);
2090 emitIASBytes(Str, Asm, StartPosition);
2091 return; 2162 return;
2092 } 2163 }
2093 Type Ty = Dest->getType(); 2164 Type Ty = Dest->getType();
2094 if (!Dest->hasReg()) { 2165 if (!Dest->hasReg()) {
2095 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) 2166 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget())
2096 ->stackVarToAsmOperand(Dest)); 2167 ->stackVarToAsmOperand(Dest));
2097 Asm->fstp(Ty, StackAddr); 2168 Asm->fstp(Ty, StackAddr);
2098 } else { 2169 } else {
2099 // Dest is a physical (xmm) register, so st(0) needs to go through 2170 // Dest is a physical (xmm) register, so st(0) needs to go through
2100 // memory. Hack this by creating a temporary stack slot, spilling 2171 // memory. Hack this by creating a temporary stack slot, spilling
2101 // st(0) there, loading it into the xmm register, and deallocating 2172 // st(0) there, loading it into the xmm register, and deallocating
2102 // the stack slot. 2173 // the stack slot.
2103 x86::Immediate Width(typeWidthInBytes(Ty)); 2174 x86::Immediate Width(typeWidthInBytes(Ty));
2104 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); 2175 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2105 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); 2176 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0);
2106 Asm->fstp(Ty, StackSlot); 2177 Asm->fstp(Ty, StackSlot);
2107 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); 2178 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot);
2108 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); 2179 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width);
2109 } 2180 }
2110 Ostream &Str = Func->getContext()->getStrEmit(); 2181 emitIASBytes(Func, Asm, StartPosition);
2111 emitIASBytes(Str, Asm, StartPosition);
2112 } 2182 }
2113 2183
2114 void InstX8632Fstp::dump(const Cfg *Func) const { 2184 void InstX8632Fstp::dump(const Cfg *Func) const {
2115 Ostream &Str = Func->getContext()->getStrDump(); 2185 Ostream &Str = Func->getContext()->getStrDump();
2116 dumpDest(Func); 2186 dumpDest(Func);
2117 Str << " = fstp." << getDest()->getType() << ", st(0)"; 2187 Str << " = fstp." << getDest()->getType() << ", st(0)";
2118 Str << "\n"; 2188 Str << "\n";
2119 } 2189 }
2120 2190
2121 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { 2191 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 2253
2184 void InstX8632Pop::emit(const Cfg *Func) const { 2254 void InstX8632Pop::emit(const Cfg *Func) const {
2185 Ostream &Str = Func->getContext()->getStrEmit(); 2255 Ostream &Str = Func->getContext()->getStrEmit();
2186 assert(getSrcSize() == 0); 2256 assert(getSrcSize() == 0);
2187 Str << "\tpop\t"; 2257 Str << "\tpop\t";
2188 getDest()->emit(Func); 2258 getDest()->emit(Func);
2189 Str << "\n"; 2259 Str << "\n";
2190 } 2260 }
2191 2261
2192 void InstX8632Pop::emitIAS(const Cfg *Func) const { 2262 void InstX8632Pop::emitIAS(const Cfg *Func) const {
2193 Ostream &Str = Func->getContext()->getStrEmit();
2194 assert(getSrcSize() == 0); 2263 assert(getSrcSize() == 0);
2195 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2264 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2196 intptr_t StartPosition = Asm->GetPosition(); 2265 intptr_t StartPosition = Asm->GetPosition();
2197 if (getDest()->hasReg()) { 2266 if (getDest()->hasReg()) {
2198 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); 2267 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum()));
2199 } else { 2268 } else {
2200 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) 2269 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget())
2201 ->stackVarToAsmOperand(getDest())); 2270 ->stackVarToAsmOperand(getDest()));
2202 } 2271 }
2203 emitIASBytes(Str, Asm, StartPosition); 2272 emitIASBytes(Func, Asm, StartPosition);
2204 } 2273 }
2205 2274
2206 void InstX8632Pop::dump(const Cfg *Func) const { 2275 void InstX8632Pop::dump(const Cfg *Func) const {
2207 Ostream &Str = Func->getContext()->getStrDump(); 2276 Ostream &Str = Func->getContext()->getStrDump();
2208 dumpDest(Func); 2277 dumpDest(Func);
2209 Str << " = pop." << getDest()->getType() << " "; 2278 Str << " = pop." << getDest()->getType() << " ";
2210 } 2279 }
2211 2280
2212 void InstX8632AdjustStack::emit(const Cfg *Func) const { 2281 void InstX8632AdjustStack::emit(const Cfg *Func) const {
2213 Ostream &Str = Func->getContext()->getStrEmit(); 2282 Ostream &Str = Func->getContext()->getStrEmit();
2214 Str << "\tsub\tesp, " << Amount << "\n"; 2283 Str << "\tsub\tesp, " << Amount << "\n";
2215 Func->getTarget()->updateStackAdjustment(Amount); 2284 Func->getTarget()->updateStackAdjustment(Amount);
2216 } 2285 }
2217 2286
2218 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { 2287 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const {
2219 Ostream &Str = Func->getContext()->getStrEmit();
2220 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2288 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2221 intptr_t StartPosition = Asm->GetPosition(); 2289 intptr_t StartPosition = Asm->GetPosition();
2222 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); 2290 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount));
2223 emitIASBytes(Str, Asm, StartPosition); 2291 emitIASBytes(Func, Asm, StartPosition);
2224 Func->getTarget()->updateStackAdjustment(Amount); 2292 Func->getTarget()->updateStackAdjustment(Amount);
2225 } 2293 }
2226 2294
2227 void InstX8632AdjustStack::dump(const Cfg *Func) const { 2295 void InstX8632AdjustStack::dump(const Cfg *Func) const {
2228 Ostream &Str = Func->getContext()->getStrDump(); 2296 Ostream &Str = Func->getContext()->getStrDump();
2229 Str << "esp = sub.i32 esp, " << Amount; 2297 Str << "esp = sub.i32 esp, " << Amount;
2230 } 2298 }
2231 2299
2232 void InstX8632Push::emit(const Cfg *Func) const { 2300 void InstX8632Push::emit(const Cfg *Func) const {
2233 Ostream &Str = Func->getContext()->getStrEmit(); 2301 Ostream &Str = Func->getContext()->getStrEmit();
2234 assert(getSrcSize() == 1); 2302 assert(getSrcSize() == 1);
2235 // Push is currently only used for saving GPRs. 2303 // Push is currently only used for saving GPRs.
2236 Variable *Var = llvm::cast<Variable>(getSrc(0)); 2304 Variable *Var = llvm::cast<Variable>(getSrc(0));
2237 assert(Var->hasReg()); 2305 assert(Var->hasReg());
2238 Str << "\tpush\t"; 2306 Str << "\tpush\t";
2239 Var->emit(Func); 2307 Var->emit(Func);
2240 Str << "\n"; 2308 Str << "\n";
2241 } 2309 }
2242 2310
2243 void InstX8632Push::emitIAS(const Cfg *Func) const { 2311 void InstX8632Push::emitIAS(const Cfg *Func) const {
2244 Ostream &Str = Func->getContext()->getStrEmit();
2245 assert(getSrcSize() == 1); 2312 assert(getSrcSize() == 1);
2246 // Push is currently only used for saving GPRs. 2313 // Push is currently only used for saving GPRs.
2247 Variable *Var = llvm::cast<Variable>(getSrc(0)); 2314 Variable *Var = llvm::cast<Variable>(getSrc(0));
2248 assert(Var->hasReg()); 2315 assert(Var->hasReg());
2249 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2316 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2250 intptr_t StartPosition = Asm->GetPosition(); 2317 intptr_t StartPosition = Asm->GetPosition();
2251 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); 2318 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum()));
2252 emitIASBytes(Str, Asm, StartPosition); 2319 emitIASBytes(Func, Asm, StartPosition);
2253 } 2320 }
2254 2321
2255 void InstX8632Push::dump(const Cfg *Func) const { 2322 void InstX8632Push::dump(const Cfg *Func) const {
2256 Ostream &Str = Func->getContext()->getStrDump(); 2323 Ostream &Str = Func->getContext()->getStrDump();
2257 Str << "push." << getSrc(0)->getType() << " "; 2324 Str << "push." << getSrc(0)->getType() << " ";
2258 dumpSources(Func); 2325 dumpSources(Func);
2259 } 2326 }
2260 2327
2261 template <> void InstX8632Psll::emit(const Cfg *Func) const { 2328 template <> void InstX8632Psll::emit(const Cfg *Func) const {
2262 assert(getDest()->getType() == IceType_v8i16 || 2329 assert(getDest()->getType() == IceType_v8i16 ||
(...skipping 16 matching lines...) Expand all
2279 TypeX8632Attributes[getDest()->getType()].PackString); 2346 TypeX8632Attributes[getDest()->getType()].PackString);
2280 emitTwoAddress(buf, this, Func); 2347 emitTwoAddress(buf, this, Func);
2281 } 2348 }
2282 2349
2283 void InstX8632Ret::emit(const Cfg *Func) const { 2350 void InstX8632Ret::emit(const Cfg *Func) const {
2284 Ostream &Str = Func->getContext()->getStrEmit(); 2351 Ostream &Str = Func->getContext()->getStrEmit();
2285 Str << "\tret\n"; 2352 Str << "\tret\n";
2286 } 2353 }
2287 2354
2288 void InstX8632Ret::emitIAS(const Cfg *Func) const { 2355 void InstX8632Ret::emitIAS(const Cfg *Func) const {
2289 Ostream &Str = Func->getContext()->getStrEmit();
2290 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2356 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2291 intptr_t StartPosition = Asm->GetPosition(); 2357 intptr_t StartPosition = Asm->GetPosition();
2292 Asm->ret(); 2358 Asm->ret();
2293 emitIASBytes(Str, Asm, StartPosition); 2359 emitIASBytes(Func, Asm, StartPosition);
2294 } 2360 }
2295 2361
2296 void InstX8632Ret::dump(const Cfg *Func) const { 2362 void InstX8632Ret::dump(const Cfg *Func) const {
2297 Ostream &Str = Func->getContext()->getStrDump(); 2363 Ostream &Str = Func->getContext()->getStrDump();
2298 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); 2364 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType());
2299 Str << "ret." << Ty << " "; 2365 Str << "ret." << Ty << " ";
2300 dumpSources(Func); 2366 dumpSources(Func);
2301 } 2367 }
2302 2368
2303 void InstX8632Xadd::emit(const Cfg *Func) const { 2369 void InstX8632Xadd::emit(const Cfg *Func) const {
2304 Ostream &Str = Func->getContext()->getStrEmit(); 2370 Ostream &Str = Func->getContext()->getStrEmit();
2305 if (Locked) { 2371 if (Locked) {
2306 Str << "\tlock"; 2372 Str << "\tlock";
2307 } 2373 }
2308 Str << "\txadd\t"; 2374 Str << "\txadd\t";
2309 getSrc(0)->emit(Func); 2375 getSrc(0)->emit(Func);
2310 Str << ", "; 2376 Str << ", ";
2311 getSrc(1)->emit(Func); 2377 getSrc(1)->emit(Func);
2312 Str << "\n"; 2378 Str << "\n";
2313 } 2379 }
2314 2380
2315 void InstX8632Xadd::emitIAS(const Cfg *Func) const { 2381 void InstX8632Xadd::emitIAS(const Cfg *Func) const {
2316 Ostream &Str = Func->getContext()->getStrEmit();
2317 assert(getSrcSize() == 2); 2382 assert(getSrcSize() == 2);
2318 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2383 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2319 intptr_t StartPosition = Asm->GetPosition(); 2384 intptr_t StartPosition = Asm->GetPosition();
2320 Type Ty = getSrc(0)->getType(); 2385 Type Ty = getSrc(0)->getType();
2321 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2386 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2387 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2322 const x86::Address Addr = Mem->toAsmAddress(Asm); 2388 const x86::Address Addr = Mem->toAsmAddress(Asm);
2323 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); 2389 const Variable *VarReg = llvm::cast<Variable>(getSrc(1));
2324 assert(VarReg->hasReg()); 2390 assert(VarReg->hasReg());
2325 const RegX8632::GPRRegister Reg = 2391 const RegX8632::GPRRegister Reg =
2326 RegX8632::getEncodedGPR(VarReg->getRegNum()); 2392 RegX8632::getEncodedGPR(VarReg->getRegNum());
2327 if (Locked) { 2393 if (Locked) {
2328 Asm->lock(); 2394 Asm->lock();
2329 } 2395 }
2330 Asm->xadd(Ty, Addr, Reg); 2396 Asm->xadd(Ty, Addr, Reg);
2331 emitIASBytes(Str, Asm, StartPosition); 2397 emitIASBytes(Func, Asm, StartPosition);
2332 } 2398 }
2333 2399
2334 void InstX8632Xadd::dump(const Cfg *Func) const { 2400 void InstX8632Xadd::dump(const Cfg *Func) const {
2335 Ostream &Str = Func->getContext()->getStrDump(); 2401 Ostream &Str = Func->getContext()->getStrDump();
2336 if (Locked) { 2402 if (Locked) {
2337 Str << "lock "; 2403 Str << "lock ";
2338 } 2404 }
2339 Type Ty = getSrc(0)->getType(); 2405 Type Ty = getSrc(0)->getType();
2340 Str << "xadd." << Ty << " "; 2406 Str << "xadd." << Ty << " ";
2341 dumpSources(Func); 2407 dumpSources(Func);
2342 } 2408 }
2343 2409
2344 void InstX8632Xchg::emit(const Cfg *Func) const { 2410 void InstX8632Xchg::emit(const Cfg *Func) const {
2345 Ostream &Str = Func->getContext()->getStrEmit(); 2411 Ostream &Str = Func->getContext()->getStrEmit();
2346 Str << "\txchg\t"; 2412 Str << "\txchg\t";
2347 getSrc(0)->emit(Func); 2413 getSrc(0)->emit(Func);
2348 Str << ", "; 2414 Str << ", ";
2349 getSrc(1)->emit(Func); 2415 getSrc(1)->emit(Func);
2350 Str << "\n"; 2416 Str << "\n";
2351 } 2417 }
2352 2418
2353 void InstX8632Xchg::emitIAS(const Cfg *Func) const { 2419 void InstX8632Xchg::emitIAS(const Cfg *Func) const {
2354 Ostream &Str = Func->getContext()->getStrEmit();
2355 assert(getSrcSize() == 2); 2420 assert(getSrcSize() == 2);
2356 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); 2421 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
2357 intptr_t StartPosition = Asm->GetPosition(); 2422 intptr_t StartPosition = Asm->GetPosition();
2358 Type Ty = getSrc(0)->getType(); 2423 Type Ty = getSrc(0)->getType();
2359 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); 2424 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0));
2425 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
2360 const x86::Address Addr = Mem->toAsmAddress(Asm); 2426 const x86::Address Addr = Mem->toAsmAddress(Asm);
2361 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); 2427 const Variable *VarReg = llvm::cast<Variable>(getSrc(1));
2362 assert(VarReg->hasReg()); 2428 assert(VarReg->hasReg());
2363 const RegX8632::GPRRegister Reg = 2429 const RegX8632::GPRRegister Reg =
2364 RegX8632::getEncodedGPR(VarReg->getRegNum()); 2430 RegX8632::getEncodedGPR(VarReg->getRegNum());
2365 Asm->xchg(Ty, Addr, Reg); 2431 Asm->xchg(Ty, Addr, Reg);
2366 emitIASBytes(Str, Asm, StartPosition); 2432 emitIASBytes(Func, Asm, StartPosition);
2367 } 2433 }
2368 2434
2369 void InstX8632Xchg::dump(const Cfg *Func) const { 2435 void InstX8632Xchg::dump(const Cfg *Func) const {
2370 Ostream &Str = Func->getContext()->getStrDump(); 2436 Ostream &Str = Func->getContext()->getStrDump();
2371 Type Ty = getSrc(0)->getType(); 2437 Type Ty = getSrc(0)->getType();
2372 Str << "xchg." << Ty << " "; 2438 Str << "xchg." << Ty << " ";
2373 dumpSources(Func); 2439 dumpSources(Func);
2374 } 2440 }
2375 2441
2376 void OperandX8632Mem::emit(const Cfg *Func) const { 2442 void OperandX8632Mem::emit(const Cfg *Func) const {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2463 Str << "+"; 2529 Str << "+";
2464 Offset->dump(Func, Str); 2530 Offset->dump(Func, Str);
2465 } 2531 }
2466 } else { 2532 } else {
2467 // There is only the offset. 2533 // There is only the offset.
2468 Offset->dump(Func, Str); 2534 Offset->dump(Func, Str);
2469 } 2535 }
2470 Str << "]"; 2536 Str << "]";
2471 } 2537 }
2472 2538
2539 void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const {
2540 if (SegmentReg != DefaultSegment) {
2541 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]);
2542 }
2543 }
2544
2473 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { 2545 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const {
2474 int32_t Disp = 0; 2546 int32_t Disp = 0;
2475 AssemblerFixup *Fixup = NULL; 2547 AssemblerFixup *Fixup = NULL;
2476 // Determine the offset (is it relocatable?) 2548 // Determine the offset (is it relocatable?)
2477 if (getOffset()) { 2549 if (getOffset()) {
2478 if (ConstantInteger32 *CI = 2550 if (ConstantInteger32 *CI =
2479 llvm::dyn_cast<ConstantInteger32>(getOffset())) { 2551 llvm::dyn_cast<ConstantInteger32>(getOffset())) {
2480 Disp = static_cast<int32_t>(CI->getValue()); 2552 Disp = static_cast<int32_t>(CI->getValue());
2481 } else if (ConstantRelocatable *CR = 2553 } else if (ConstantRelocatable *CR =
2482 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { 2554 llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
2483 // TODO(jvoung): CR + non-zero-offset isn't really tested yet,
2484 // since the addressing mode optimization doesn't try to combine
2485 // ConstantRelocatable with something else.
2486 assert(CR->getOffset() == 0);
2487 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); 2555 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR);
2488 } else { 2556 } else {
2489 llvm_unreachable("Unexpected offset type"); 2557 llvm_unreachable("Unexpected offset type");
2490 } 2558 }
2491 } 2559 }
2492 2560
2493 // Now convert to the various possible forms. 2561 // Now convert to the various possible forms.
2494 if (getBase() && getIndex()) { 2562 if (getBase() && getIndex()) {
2495 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), 2563 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()),
2496 RegX8632::getEncodedGPR(getIndex()->getRegNum()), 2564 RegX8632::getEncodedGPR(getIndex()->getRegNum()),
2497 x86::ScaleFactor(getShift()), Disp); 2565 x86::ScaleFactor(getShift()), Disp);
2498 } else if (getBase()) { 2566 } else if (getBase()) {
2499 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); 2567 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp);
2500 } else if (getIndex()) { 2568 } else if (getIndex()) {
2501 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), 2569 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()),
2502 x86::ScaleFactor(getShift()), Disp); 2570 x86::ScaleFactor(getShift()), Disp);
2571 } else if (Fixup) {
2572 // The fixup itself has an offset, so Disp should still be 0.
2573 assert(Disp == 0);
2574 return x86::Address::Absolute(Fixup);
2503 } else { 2575 } else {
2504 return x86::Address::Absolute(Disp, Fixup); 2576 return x86::Address::Absolute(Disp);
2505 } 2577 }
2506 } 2578 }
2507 2579
2580 x86::Address VariableSplit::toAsmAddress(const Cfg *Func) const {
2581 assert(!Var->hasReg());
2582 const TargetLowering *Target = Func->getTarget();
2583 int32_t Offset = Var->getStackOffset() + Target->getStackAdjustment();
2584 if (Part == High)
2585 Offset += 4;
2586 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()),
2587 Offset);
2588 }
2589
2508 void VariableSplit::emit(const Cfg *Func) const { 2590 void VariableSplit::emit(const Cfg *Func) const {
2509 Ostream &Str = Func->getContext()->getStrEmit(); 2591 Ostream &Str = Func->getContext()->getStrEmit();
2510 assert(!Var->hasReg()); 2592 assert(!Var->hasReg());
2511 // The following is copied/adapted from TargetX8632::emitVariable(). 2593 // The following is copied/adapted from TargetX8632::emitVariable().
2512 const TargetLowering *Target = Func->getTarget(); 2594 const TargetLowering *Target = Func->getTarget();
2513 const Type Ty = IceType_i32; 2595 const Type Ty = IceType_i32;
2514 Str << TypeX8632Attributes[Ty].WidthString << " [" 2596 Str << TypeX8632Attributes[Ty].WidthString << " ["
2515 << Target->getRegName(Target->getFrameOrStackReg(), Ty); 2597 << Target->getRegName(Target->getFrameOrStackReg(), Ty);
2516 int32_t Offset = Var->getStackOffset() + Target->getStackAdjustment(); 2598 int32_t Offset = Var->getStackOffset() + Target->getStackAdjustment();
2517 if (Part == High) 2599 if (Part == High)
(...skipping 20 matching lines...) Expand all
2538 } 2620 }
2539 Str << "("; 2621 Str << "(";
2540 if (Func) 2622 if (Func)
2541 Var->dump(Func); 2623 Var->dump(Func);
2542 else 2624 else
2543 Var->dump(Str); 2625 Var->dump(Str);
2544 Str << ")"; 2626 Str << ")";
2545 } 2627 }
2546 2628
2547 } // end of namespace Ice 2629 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceInstX8632.def » ('j') | src/IceOperand.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698