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