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 | 69 |
| 70 uint8_t InstX8632SegmentPrefixes[] = { |
| 71 #define X(val, name, prefix) prefix, |
| 72 SEG_REGX8632_TABLE |
| 73 #undef X |
| 74 }; |
| 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) |
79 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 85 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
(...skipping 247 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 = |
| 545 x86::DisplacementRelocation::create(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 = |
| 571 x86::DisplacementRelocation::create(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 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1184 Str << "\tcwd\n"; | 1193 Str << "\tcwd\n"; |
1185 break; | 1194 break; |
1186 case IceType_i32: | 1195 case IceType_i32: |
1187 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1196 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
1188 Str << "\tcdq\n"; | 1197 Str << "\tcdq\n"; |
1189 break; | 1198 break; |
1190 } | 1199 } |
1191 } | 1200 } |
1192 | 1201 |
1193 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { | 1202 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const { |
1194 Ostream &Str = Func->getContext()->getStrEmit(); | |
1195 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1203 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1196 intptr_t StartPosition = Asm->GetPosition(); | 1204 intptr_t StartPosition = Asm->GetPosition(); |
1197 assert(getSrcSize() == 1); | 1205 assert(getSrcSize() == 1); |
1198 Operand *Src0 = getSrc(0); | 1206 Operand *Src0 = getSrc(0); |
1199 assert(llvm::isa<Variable>(Src0)); | 1207 assert(llvm::isa<Variable>(Src0)); |
1200 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); | 1208 assert(llvm::cast<Variable>(Src0)->getRegNum() == RegX8632::Reg_eax); |
1201 switch (Src0->getType()) { | 1209 switch (Src0->getType()) { |
1202 default: | 1210 default: |
1203 llvm_unreachable("unexpected source type!"); | 1211 llvm_unreachable("unexpected source type!"); |
1204 break; | 1212 break; |
1205 case IceType_i8: | 1213 case IceType_i8: |
1206 assert(getDest()->getRegNum() == RegX8632::Reg_eax); | 1214 assert(getDest()->getRegNum() == RegX8632::Reg_eax); |
1207 Asm->cbw(); | 1215 Asm->cbw(); |
1208 break; | 1216 break; |
1209 case IceType_i16: | 1217 case IceType_i16: |
1210 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1218 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
1211 Asm->cwd(); | 1219 Asm->cwd(); |
1212 break; | 1220 break; |
1213 case IceType_i32: | 1221 case IceType_i32: |
1214 assert(getDest()->getRegNum() == RegX8632::Reg_edx); | 1222 assert(getDest()->getRegNum() == RegX8632::Reg_edx); |
1215 Asm->cdq(); | 1223 Asm->cdq(); |
1216 break; | 1224 break; |
1217 } | 1225 } |
1218 emitIASBytes(Str, Asm, StartPosition); | 1226 emitIASBytes(Func, Asm, StartPosition); |
1219 } | 1227 } |
1220 | 1228 |
1221 void InstX8632Mul::emit(const Cfg *Func) const { | 1229 void InstX8632Mul::emit(const Cfg *Func) const { |
1222 Ostream &Str = Func->getContext()->getStrEmit(); | 1230 Ostream &Str = Func->getContext()->getStrEmit(); |
1223 assert(getSrcSize() == 2); | 1231 assert(getSrcSize() == 2); |
1224 assert(llvm::isa<Variable>(getSrc(0))); | 1232 assert(llvm::isa<Variable>(getSrc(0))); |
1225 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); | 1233 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == RegX8632::Reg_eax); |
1226 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? | 1234 assert(getDest()->getRegNum() == RegX8632::Reg_eax); // TODO: allow edx? |
1227 Str << "\tmul\t"; | 1235 Str << "\tmul\t"; |
1228 getSrc(1)->emit(Func); | 1236 getSrc(1)->emit(Func); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1306 assert(Condition != CondX86::Br_None); | 1314 assert(Condition != CondX86::Br_None); |
1307 assert(getDest()->hasReg()); | 1315 assert(getDest()->hasReg()); |
1308 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; | 1316 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; |
1309 getDest()->emit(Func); | 1317 getDest()->emit(Func); |
1310 Str << ", "; | 1318 Str << ", "; |
1311 getSrc(1)->emit(Func); | 1319 getSrc(1)->emit(Func); |
1312 Str << "\n"; | 1320 Str << "\n"; |
1313 } | 1321 } |
1314 | 1322 |
1315 void InstX8632Cmov::emitIAS(const Cfg *Func) const { | 1323 void InstX8632Cmov::emitIAS(const Cfg *Func) const { |
1316 Ostream &Str = Func->getContext()->getStrEmit(); | |
1317 Str << "\t"; | |
1318 assert(Condition != CondX86::Br_None); | 1324 assert(Condition != CondX86::Br_None); |
1319 assert(getDest()->hasReg()); | 1325 assert(getDest()->hasReg()); |
1320 assert(getSrcSize() == 2); | 1326 assert(getSrcSize() == 2); |
1321 // Only need the reg/reg form now. | 1327 // Only need the reg/reg form now. |
1322 const Variable *Src = llvm::cast<Variable>(getSrc(1)); | 1328 const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
1323 assert(Src->hasReg()); | 1329 assert(Src->hasReg()); |
1324 assert(Src->getType() == IceType_i32); | 1330 assert(Src->getType() == IceType_i32); |
1325 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1331 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1326 intptr_t StartPosition = Asm->GetPosition(); | 1332 intptr_t StartPosition = Asm->GetPosition(); |
1327 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), | 1333 Asm->cmov(Condition, RegX8632::getEncodedGPR(getDest()->getRegNum()), |
1328 RegX8632::getEncodedGPR(Src->getRegNum())); | 1334 RegX8632::getEncodedGPR(Src->getRegNum())); |
1329 emitIASBytes(Str, Asm, StartPosition); | 1335 emitIASBytes(Func, Asm, StartPosition); |
1330 } | 1336 } |
1331 | 1337 |
1332 void InstX8632Cmov::dump(const Cfg *Func) const { | 1338 void InstX8632Cmov::dump(const Cfg *Func) const { |
1333 Ostream &Str = Func->getContext()->getStrDump(); | 1339 Ostream &Str = Func->getContext()->getStrDump(); |
1334 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; | 1340 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; |
1335 Str << getDest()->getType() << " "; | 1341 Str << getDest()->getType() << " "; |
1336 dumpDest(Func); | 1342 dumpDest(Func); |
1337 Str << ", "; | 1343 Str << ", "; |
1338 dumpSources(Func); | 1344 dumpSources(Func); |
1339 } | 1345 } |
1340 | 1346 |
1341 void InstX8632Cmpps::emit(const Cfg *Func) const { | 1347 void InstX8632Cmpps::emit(const Cfg *Func) const { |
1342 Ostream &Str = Func->getContext()->getStrEmit(); | 1348 Ostream &Str = Func->getContext()->getStrEmit(); |
1343 assert(getSrcSize() == 2); | 1349 assert(getSrcSize() == 2); |
1344 assert(Condition < CondX86::Cmpps_Invalid); | 1350 assert(Condition < CondX86::Cmpps_Invalid); |
1345 Str << "\t"; | 1351 Str << "\t"; |
1346 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1352 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
1347 << "\t"; | 1353 << "\t"; |
1348 getDest()->emit(Func); | 1354 getDest()->emit(Func); |
1349 Str << ", "; | 1355 Str << ", "; |
1350 getSrc(1)->emit(Func); | 1356 getSrc(1)->emit(Func); |
1351 Str << "\n"; | 1357 Str << "\n"; |
1352 } | 1358 } |
1353 | 1359 |
1354 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { | 1360 void InstX8632Cmpps::emitIAS(const Cfg *Func) const { |
1355 Ostream &Str = Func->getContext()->getStrEmit(); | |
1356 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1361 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1357 intptr_t StartPosition = Asm->GetPosition(); | 1362 intptr_t StartPosition = Asm->GetPosition(); |
1358 assert(getSrcSize() == 2); | 1363 assert(getSrcSize() == 2); |
1359 assert(Condition < CondX86::Cmpps_Invalid); | 1364 assert(Condition < CondX86::Cmpps_Invalid); |
1360 // Assuming there isn't any load folding for cmpps, and vector constants | 1365 // Assuming there isn't any load folding for cmpps, and vector constants |
1361 // are not allowed in PNaCl. | 1366 // are not allowed in PNaCl. |
1362 assert(llvm::isa<Variable>(getSrc(1))); | 1367 assert(llvm::isa<Variable>(getSrc(1))); |
1363 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); | 1368 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1)); |
1364 if (SrcVar->hasReg()) { | 1369 if (SrcVar->hasReg()) { |
1365 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), | 1370 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), |
1366 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); | 1371 RegX8632::getEncodedXmm(SrcVar->getRegNum()), Condition); |
1367 } else { | 1372 } else { |
1368 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) | 1373 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget()) |
1369 ->stackVarToAsmOperand(SrcVar); | 1374 ->stackVarToAsmOperand(SrcVar); |
1370 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, | 1375 Asm->cmpps(RegX8632::getEncodedXmm(getDest()->getRegNum()), SrcStackAddr, |
1371 Condition); | 1376 Condition); |
1372 } | 1377 } |
1373 emitIASBytes(Str, Asm, StartPosition); | 1378 emitIASBytes(Func, Asm, StartPosition); |
1374 } | 1379 } |
1375 | 1380 |
1376 void InstX8632Cmpps::dump(const Cfg *Func) const { | 1381 void InstX8632Cmpps::dump(const Cfg *Func) const { |
1377 Ostream &Str = Func->getContext()->getStrDump(); | 1382 Ostream &Str = Func->getContext()->getStrDump(); |
1378 assert(Condition < CondX86::Cmpps_Invalid); | 1383 assert(Condition < CondX86::Cmpps_Invalid); |
1379 dumpDest(Func); | 1384 dumpDest(Func); |
1380 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" | 1385 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" |
1381 << "\t"; | 1386 << "\t"; |
1382 dumpSources(Func); | 1387 dumpSources(Func); |
1383 } | 1388 } |
1384 | 1389 |
1385 void InstX8632Cmpxchg::emit(const Cfg *Func) const { | 1390 void InstX8632Cmpxchg::emit(const Cfg *Func) const { |
1386 Ostream &Str = Func->getContext()->getStrEmit(); | 1391 Ostream &Str = Func->getContext()->getStrEmit(); |
1387 assert(getSrcSize() == 3); | 1392 assert(getSrcSize() == 3); |
1388 if (Locked) { | 1393 if (Locked) { |
1389 Str << "\tlock"; | 1394 Str << "\tlock"; |
1390 } | 1395 } |
1391 Str << "\tcmpxchg\t"; | 1396 Str << "\tcmpxchg\t"; |
1392 getSrc(0)->emit(Func); | 1397 getSrc(0)->emit(Func); |
1393 Str << ", "; | 1398 Str << ", "; |
1394 getSrc(2)->emit(Func); | 1399 getSrc(2)->emit(Func); |
1395 Str << "\n"; | 1400 Str << "\n"; |
1396 } | 1401 } |
1397 | 1402 |
1398 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { | 1403 void InstX8632Cmpxchg::emitIAS(const Cfg *Func) const { |
1399 Ostream &Str = Func->getContext()->getStrEmit(); | |
1400 assert(getSrcSize() == 3); | 1404 assert(getSrcSize() == 3); |
1401 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1405 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1402 intptr_t StartPosition = Asm->GetPosition(); | 1406 intptr_t StartPosition = Asm->GetPosition(); |
1403 Type Ty = getSrc(0)->getType(); | 1407 Type Ty = getSrc(0)->getType(); |
1404 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1408 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1409 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1405 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1410 const x86::Address Addr = Mem->toAsmAddress(Asm); |
1406 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); | 1411 const Variable *VarReg = llvm::cast<Variable>(getSrc(2)); |
1407 assert(VarReg->hasReg()); | 1412 assert(VarReg->hasReg()); |
1408 const RegX8632::GPRRegister Reg = | 1413 const RegX8632::GPRRegister Reg = |
1409 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 1414 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
1410 if (Locked) { | 1415 if (Locked) { |
1411 Asm->LockCmpxchg(Ty, Addr, Reg); | 1416 Asm->LockCmpxchg(Ty, Addr, Reg); |
1412 } else { | 1417 } else { |
1413 Asm->cmpxchg(Ty, Addr, Reg); | 1418 Asm->cmpxchg(Ty, Addr, Reg); |
1414 } | 1419 } |
1415 emitIASBytes(Str, Asm, StartPosition); | 1420 emitIASBytes(Func, Asm, StartPosition); |
1416 } | 1421 } |
1417 | 1422 |
1418 void InstX8632Cmpxchg::dump(const Cfg *Func) const { | 1423 void InstX8632Cmpxchg::dump(const Cfg *Func) const { |
1419 Ostream &Str = Func->getContext()->getStrDump(); | 1424 Ostream &Str = Func->getContext()->getStrDump(); |
1420 if (Locked) { | 1425 if (Locked) { |
1421 Str << "lock "; | 1426 Str << "lock "; |
1422 } | 1427 } |
1423 Str << "cmpxchg." << getSrc(0)->getType() << " "; | 1428 Str << "cmpxchg." << getSrc(0)->getType() << " "; |
1424 dumpSources(Func); | 1429 dumpSources(Func); |
1425 } | 1430 } |
1426 | 1431 |
1427 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { | 1432 void InstX8632Cmpxchg8b::emit(const Cfg *Func) const { |
1428 Ostream &Str = Func->getContext()->getStrEmit(); | 1433 Ostream &Str = Func->getContext()->getStrEmit(); |
1429 assert(getSrcSize() == 5); | 1434 assert(getSrcSize() == 5); |
1430 if (Locked) { | 1435 if (Locked) { |
1431 Str << "\tlock"; | 1436 Str << "\tlock"; |
1432 } | 1437 } |
1433 Str << "\tcmpxchg8b\t"; | 1438 Str << "\tcmpxchg8b\t"; |
1434 getSrc(0)->emit(Func); | 1439 getSrc(0)->emit(Func); |
1435 Str << "\n"; | 1440 Str << "\n"; |
1436 } | 1441 } |
1437 | 1442 |
1438 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { | 1443 void InstX8632Cmpxchg8b::emitIAS(const Cfg *Func) const { |
1439 Ostream &Str = Func->getContext()->getStrEmit(); | |
1440 assert(getSrcSize() == 5); | 1444 assert(getSrcSize() == 5); |
1441 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1445 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1442 intptr_t StartPosition = Asm->GetPosition(); | 1446 intptr_t StartPosition = Asm->GetPosition(); |
1443 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 1447 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 1448 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1444 const x86::Address Addr = Mem->toAsmAddress(Asm); | 1449 const x86::Address Addr = Mem->toAsmAddress(Asm); |
1445 if (Locked) { | 1450 if (Locked) { |
1446 Asm->lock(); | 1451 Asm->lock(); |
1447 } | 1452 } |
1448 Asm->cmpxchg8b(Addr); | 1453 Asm->cmpxchg8b(Addr); |
1449 emitIASBytes(Str, Asm, StartPosition); | 1454 emitIASBytes(Func, Asm, StartPosition); |
1450 } | 1455 } |
1451 | 1456 |
1452 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { | 1457 void InstX8632Cmpxchg8b::dump(const Cfg *Func) const { |
1453 Ostream &Str = Func->getContext()->getStrDump(); | 1458 Ostream &Str = Func->getContext()->getStrDump(); |
1454 if (Locked) { | 1459 if (Locked) { |
1455 Str << "lock "; | 1460 Str << "lock "; |
1456 } | 1461 } |
1457 Str << "cmpxchg8b "; | 1462 Str << "cmpxchg8b "; |
1458 dumpSources(Func); | 1463 dumpSources(Func); |
1459 } | 1464 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1567 if (SrcVar0->hasReg()) { | 1572 if (SrcVar0->hasReg()) { |
1568 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); | 1573 emitIASRegOpTyGPR(Func, Ty, SrcVar0, Src1, RegEmitter); |
1569 } else { | 1574 } else { |
1570 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1575 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
1571 ->stackVarToAsmOperand(SrcVar0)); | 1576 ->stackVarToAsmOperand(SrcVar0)); |
1572 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); | 1577 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
1573 } | 1578 } |
1574 } else if (const OperandX8632Mem *SrcMem0 = | 1579 } else if (const OperandX8632Mem *SrcMem0 = |
1575 llvm::dyn_cast<OperandX8632Mem>(Src0)) { | 1580 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
1576 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1581 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1582 SrcMem0->emitSegmentOverride(Asm); |
1577 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); | 1583 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
1578 } | 1584 } |
1579 } | 1585 } |
1580 | 1586 |
1581 void InstX8632Icmp::dump(const Cfg *Func) const { | 1587 void InstX8632Icmp::dump(const Cfg *Func) const { |
1582 Ostream &Str = Func->getContext()->getStrDump(); | 1588 Ostream &Str = Func->getContext()->getStrDump(); |
1583 Str << "cmp." << getSrc(0)->getType() << " "; | 1589 Str << "cmp." << getSrc(0)->getType() << " "; |
1584 dumpSources(Func); | 1590 dumpSources(Func); |
1585 } | 1591 } |
1586 | 1592 |
(...skipping 30 matching lines...) Expand all Loading... |
1617 void InstX8632UD2::emit(const Cfg *Func) const { | 1623 void InstX8632UD2::emit(const Cfg *Func) const { |
1618 Ostream &Str = Func->getContext()->getStrEmit(); | 1624 Ostream &Str = Func->getContext()->getStrEmit(); |
1619 assert(getSrcSize() == 0); | 1625 assert(getSrcSize() == 0); |
1620 Str << "\tud2\n"; | 1626 Str << "\tud2\n"; |
1621 } | 1627 } |
1622 | 1628 |
1623 void InstX8632UD2::emitIAS(const Cfg *Func) const { | 1629 void InstX8632UD2::emitIAS(const Cfg *Func) const { |
1624 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1630 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1625 intptr_t StartPosition = Asm->GetPosition(); | 1631 intptr_t StartPosition = Asm->GetPosition(); |
1626 Asm->ud2(); | 1632 Asm->ud2(); |
1627 Ostream &Str = Func->getContext()->getStrEmit(); | 1633 emitIASBytes(Func, Asm, StartPosition); |
1628 emitIASBytes(Str, Asm, StartPosition); | |
1629 } | 1634 } |
1630 | 1635 |
1631 void InstX8632UD2::dump(const Cfg *Func) const { | 1636 void InstX8632UD2::dump(const Cfg *Func) const { |
1632 Ostream &Str = Func->getContext()->getStrDump(); | 1637 Ostream &Str = Func->getContext()->getStrDump(); |
1633 Str << "ud2\n"; | 1638 Str << "ud2\n"; |
1634 } | 1639 } |
1635 | 1640 |
1636 void InstX8632Test::emit(const Cfg *Func) const { | 1641 void InstX8632Test::emit(const Cfg *Func) const { |
1637 Ostream &Str = Func->getContext()->getStrEmit(); | 1642 Ostream &Str = Func->getContext()->getStrEmit(); |
1638 assert(getSrcSize() == 2); | 1643 assert(getSrcSize() == 2); |
(...skipping 22 matching lines...) Expand all Loading... |
1661 } else { | 1666 } else { |
1662 llvm_unreachable("Nothing actually generates this so it's untested"); | 1667 llvm_unreachable("Nothing actually generates this so it's untested"); |
1663 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1668 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
1664 ->stackVarToAsmOperand(SrcVar0)); | 1669 ->stackVarToAsmOperand(SrcVar0)); |
1665 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); | 1670 emitIASAddrOpTyGPR(Func, Ty, StackAddr, Src1, AddrEmitter); |
1666 } | 1671 } |
1667 } else if (const OperandX8632Mem *SrcMem0 = | 1672 } else if (const OperandX8632Mem *SrcMem0 = |
1668 llvm::dyn_cast<OperandX8632Mem>(Src0)) { | 1673 llvm::dyn_cast<OperandX8632Mem>(Src0)) { |
1669 llvm_unreachable("Nothing actually generates this so it's untested"); | 1674 llvm_unreachable("Nothing actually generates this so it's untested"); |
1670 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1675 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1676 SrcMem0->emitSegmentOverride(Asm); |
1671 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); | 1677 emitIASAddrOpTyGPR(Func, Ty, SrcMem0->toAsmAddress(Asm), Src1, AddrEmitter); |
1672 } | 1678 } |
1673 } | 1679 } |
1674 | 1680 |
1675 void InstX8632Test::dump(const Cfg *Func) const { | 1681 void InstX8632Test::dump(const Cfg *Func) const { |
1676 Ostream &Str = Func->getContext()->getStrDump(); | 1682 Ostream &Str = Func->getContext()->getStrDump(); |
1677 Str << "test." << getSrc(0)->getType() << " "; | 1683 Str << "test." << getSrc(0)->getType() << " "; |
1678 dumpSources(Func); | 1684 dumpSources(Func); |
1679 } | 1685 } |
1680 | 1686 |
1681 void InstX8632Mfence::emit(const Cfg *Func) const { | 1687 void InstX8632Mfence::emit(const Cfg *Func) const { |
1682 Ostream &Str = Func->getContext()->getStrEmit(); | 1688 Ostream &Str = Func->getContext()->getStrEmit(); |
1683 assert(getSrcSize() == 0); | 1689 assert(getSrcSize() == 0); |
1684 Str << "\tmfence\n"; | 1690 Str << "\tmfence\n"; |
1685 } | 1691 } |
1686 | 1692 |
1687 void InstX8632Mfence::emitIAS(const Cfg *Func) const { | 1693 void InstX8632Mfence::emitIAS(const Cfg *Func) const { |
1688 Ostream &Str = Func->getContext()->getStrEmit(); | |
1689 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1694 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1690 intptr_t StartPosition = Asm->GetPosition(); | 1695 intptr_t StartPosition = Asm->GetPosition(); |
1691 Asm->mfence(); | 1696 Asm->mfence(); |
1692 emitIASBytes(Str, Asm, StartPosition); | 1697 emitIASBytes(Func, Asm, StartPosition); |
1693 } | 1698 } |
1694 | 1699 |
1695 void InstX8632Mfence::dump(const Cfg *Func) const { | 1700 void InstX8632Mfence::dump(const Cfg *Func) const { |
1696 Ostream &Str = Func->getContext()->getStrDump(); | 1701 Ostream &Str = Func->getContext()->getStrDump(); |
1697 Str << "mfence\n"; | 1702 Str << "mfence\n"; |
1698 } | 1703 } |
1699 | 1704 |
1700 void InstX8632Store::emit(const Cfg *Func) const { | 1705 void InstX8632Store::emit(const Cfg *Func) const { |
1701 Ostream &Str = Func->getContext()->getStrEmit(); | 1706 Ostream &Str = Func->getContext()->getStrEmit(); |
1702 assert(getSrcSize() == 2); | 1707 assert(getSrcSize() == 2); |
(...skipping 22 matching lines...) Expand all Loading... |
1725 getSrc(0)->emit(Func); | 1730 getSrc(0)->emit(Func); |
1726 Str << "\n"; | 1731 Str << "\n"; |
1727 } | 1732 } |
1728 | 1733 |
1729 void InstX8632StoreP::emitIAS(const Cfg *Func) const { | 1734 void InstX8632StoreP::emitIAS(const Cfg *Func) const { |
1730 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1735 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1731 intptr_t StartPosition = Asm->GetPosition(); | 1736 intptr_t StartPosition = Asm->GetPosition(); |
1732 assert(getSrcSize() == 2); | 1737 assert(getSrcSize() == 2); |
1733 const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 1738 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
1734 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 1739 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1740 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1735 assert(Src->hasReg()); | 1741 assert(Src->hasReg()); |
1736 Asm->movups(DestMem->toAsmAddress(Asm), | 1742 Asm->movups(DestMem->toAsmAddress(Asm), |
1737 RegX8632::getEncodedXmm(Src->getRegNum())); | 1743 RegX8632::getEncodedXmm(Src->getRegNum())); |
1738 Ostream &Str = Func->getContext()->getStrEmit(); | 1744 emitIASBytes(Func, Asm, StartPosition); |
1739 emitIASBytes(Str, Asm, StartPosition); | |
1740 } | 1745 } |
1741 | 1746 |
1742 void InstX8632StoreP::dump(const Cfg *Func) const { | 1747 void InstX8632StoreP::dump(const Cfg *Func) const { |
1743 Ostream &Str = Func->getContext()->getStrDump(); | 1748 Ostream &Str = Func->getContext()->getStrDump(); |
1744 Str << "storep." << getSrc(0)->getType() << " "; | 1749 Str << "storep." << getSrc(0)->getType() << " "; |
1745 getSrc(1)->dump(Func); | 1750 getSrc(1)->dump(Func); |
1746 Str << ", "; | 1751 Str << ", "; |
1747 getSrc(0)->dump(Func); | 1752 getSrc(0)->dump(Func); |
1748 } | 1753 } |
1749 | 1754 |
1750 void InstX8632StoreQ::emit(const Cfg *Func) const { | 1755 void InstX8632StoreQ::emit(const Cfg *Func) const { |
1751 Ostream &Str = Func->getContext()->getStrEmit(); | 1756 Ostream &Str = Func->getContext()->getStrEmit(); |
1752 assert(getSrcSize() == 2); | 1757 assert(getSrcSize() == 2); |
1753 assert(getSrc(1)->getType() == IceType_i64 || | 1758 assert(getSrc(1)->getType() == IceType_i64 || |
1754 getSrc(1)->getType() == IceType_f64); | 1759 getSrc(1)->getType() == IceType_f64); |
1755 Str << "\tmovq\t"; | 1760 Str << "\tmovq\t"; |
1756 getSrc(1)->emit(Func); | 1761 getSrc(1)->emit(Func); |
1757 Str << ", "; | 1762 Str << ", "; |
1758 getSrc(0)->emit(Func); | 1763 getSrc(0)->emit(Func); |
1759 Str << "\n"; | 1764 Str << "\n"; |
1760 } | 1765 } |
1761 | 1766 |
1762 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { | 1767 void InstX8632StoreQ::emitIAS(const Cfg *Func) const { |
1763 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1768 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1764 intptr_t StartPosition = Asm->GetPosition(); | 1769 intptr_t StartPosition = Asm->GetPosition(); |
1765 assert(getSrcSize() == 2); | 1770 assert(getSrcSize() == 2); |
1766 const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 1771 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
1767 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); | 1772 const OperandX8632Mem *DestMem = llvm::cast<OperandX8632Mem>(getSrc(1)); |
| 1773 assert(DestMem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
1768 assert(Src->hasReg()); | 1774 assert(Src->hasReg()); |
1769 Asm->movq(DestMem->toAsmAddress(Asm), | 1775 Asm->movq(DestMem->toAsmAddress(Asm), |
1770 RegX8632::getEncodedXmm(Src->getRegNum())); | 1776 RegX8632::getEncodedXmm(Src->getRegNum())); |
1771 Ostream &Str = Func->getContext()->getStrEmit(); | 1777 emitIASBytes(Func, Asm, StartPosition); |
1772 emitIASBytes(Str, Asm, StartPosition); | |
1773 } | 1778 } |
1774 | 1779 |
1775 void InstX8632StoreQ::dump(const Cfg *Func) const { | 1780 void InstX8632StoreQ::dump(const Cfg *Func) const { |
1776 Ostream &Str = Func->getContext()->getStrDump(); | 1781 Ostream &Str = Func->getContext()->getStrDump(); |
1777 Str << "storeq." << getSrc(0)->getType() << " "; | 1782 Str << "storeq." << getSrc(0)->getType() << " "; |
1778 getSrc(1)->dump(Func); | 1783 getSrc(1)->dump(Func); |
1779 Str << ", "; | 1784 Str << ", "; |
1780 getSrc(0)->dump(Func); | 1785 getSrc(0)->dump(Func); |
1781 } | 1786 } |
1782 | 1787 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1842 Str << "\n"; | 1847 Str << "\n"; |
1843 Str << ".intel_syntax\n"; | 1848 Str << ".intel_syntax\n"; |
1844 } else { | 1849 } else { |
1845 getDest()->asType(Src->getType()).emit(Func); | 1850 getDest()->asType(Src->getType()).emit(Func); |
1846 Str << ", "; | 1851 Str << ", "; |
1847 Src->emit(Func); | 1852 Src->emit(Func); |
1848 Str << "\n"; | 1853 Str << "\n"; |
1849 } | 1854 } |
1850 } | 1855 } |
1851 | 1856 |
| 1857 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const { |
| 1858 assert(getSrcSize() == 1); |
| 1859 const Variable *Dest = getDest(); |
| 1860 const Operand *Src = getSrc(0); |
| 1861 Type DestTy = Dest->getType(); |
| 1862 Type SrcTy = Src->getType(); |
| 1863 // Mov can be used for GPRs or XMM registers. Also, the type does not |
| 1864 // necessarily match (Mov can be used for bitcasts). However, when |
| 1865 // the type does not match, one of the operands must be a register. |
| 1866 // Thus, the strategy is to find out if Src or Dest are a register, |
| 1867 // then use that register's type to decide on which emitter set to use. |
| 1868 // The emitter set will include reg-reg movs, but that case should |
| 1869 // be unused when the types don't match. |
| 1870 static const x86::AssemblerX86::XmmEmitterRegOp XmmRegEmitter = { |
| 1871 &x86::AssemblerX86::movss, &x86::AssemblerX86::movss}; |
| 1872 static const x86::AssemblerX86::GPREmitterRegOp GPRRegEmitter = { |
| 1873 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov, |
| 1874 &x86::AssemblerX86::mov}; |
| 1875 static const x86::AssemblerX86::GPREmitterAddrOp GPRAddrEmitter = { |
| 1876 &x86::AssemblerX86::mov, &x86::AssemblerX86::mov}; |
| 1877 // For an integer truncation operation, src is wider than dest. |
| 1878 // Ideally, we use a mov instruction whose data width matches the |
| 1879 // narrower dest. This is a problem if e.g. src is a register like |
| 1880 // esi or si where there is no 8-bit version of the register. To be |
| 1881 // safe, we instead widen the dest to match src. This works even |
| 1882 // for stack-allocated dest variables because typeWidthOnStack() |
| 1883 // pads to a 4-byte boundary even if only a lower portion is used. |
| 1884 // TODO: This assert disallows usages such as copying a floating point |
| 1885 // value between a vector and a scalar (which movss is used for). |
| 1886 // Clean this up. |
| 1887 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == |
| 1888 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); |
| 1889 if (Dest->hasReg()) { |
| 1890 if (isScalarFloatingType(DestTy)) { |
| 1891 emitIASRegOpTyXMM(Func, DestTy, Dest, Src, XmmRegEmitter); |
| 1892 return; |
| 1893 } else { |
| 1894 assert(isScalarIntegerType(DestTy)); |
| 1895 // Widen DestTy for truncation (see above note). We should only do this |
| 1896 // when both Src and Dest are integer types. |
| 1897 if (isScalarIntegerType(SrcTy)) { |
| 1898 DestTy = SrcTy; |
| 1899 } |
| 1900 emitIASRegOpTyGPR(Func, DestTy, Dest, Src, GPRRegEmitter); |
| 1901 return; |
| 1902 } |
| 1903 } else { |
| 1904 // Dest must be Stack and Src *could* be a register. Use Src's type |
| 1905 // to decide on the emitters. |
| 1906 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
| 1907 ->stackVarToAsmOperand(Dest)); |
| 1908 if (isScalarFloatingType(SrcTy)) { |
| 1909 // Src must be a register. |
| 1910 const Variable *SrcVar = llvm::cast<Variable>(Src); |
| 1911 assert(SrcVar->hasReg()); |
| 1912 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 1913 intptr_t StartPosition = Asm->GetPosition(); |
| 1914 Asm->movss(SrcTy, StackAddr, |
| 1915 RegX8632::getEncodedXmm(SrcVar->getRegNum())); |
| 1916 emitIASBytes(Func, Asm, StartPosition); |
| 1917 return; |
| 1918 } else { |
| 1919 // Src can be a register or immediate. |
| 1920 assert(isScalarIntegerType(SrcTy)); |
| 1921 emitIASAddrOpTyGPR(Func, SrcTy, StackAddr, Src, GPRAddrEmitter); |
| 1922 return; |
| 1923 } |
| 1924 return; |
| 1925 } |
| 1926 } |
| 1927 |
1852 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { | 1928 template <> void InstX8632Movd::emitIAS(const Cfg *Func) const { |
1853 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 1929 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1854 intptr_t StartPosition = Asm->GetPosition(); | 1930 intptr_t StartPosition = Asm->GetPosition(); |
1855 assert(getSrcSize() == 1); | 1931 assert(getSrcSize() == 1); |
1856 const Variable *Dest = getDest(); | 1932 const Variable *Dest = getDest(); |
1857 const Variable *Src = llvm::cast<Variable>(getSrc(0)); | 1933 const Variable *Src = llvm::cast<Variable>(getSrc(0)); |
1858 // For insert/extract element (one of Src/Dest is an Xmm vector and | 1934 // For insert/extract element (one of Src/Dest is an Xmm vector and |
1859 // the other is an int type). | 1935 // the other is an int type). |
1860 if (Src->getType() == IceType_i32) { | 1936 if (Src->getType() == IceType_i32) { |
1861 assert(isVectorType(Dest->getType())); | 1937 assert(isVectorType(Dest->getType())); |
(...skipping 12 matching lines...) Expand all Loading... |
1874 assert(Dest->getType() == IceType_i32); | 1950 assert(Dest->getType() == IceType_i32); |
1875 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum()); | 1951 RegX8632::XmmRegister SrcReg = RegX8632::getEncodedXmm(Src->getRegNum()); |
1876 if (Dest->hasReg()) { | 1952 if (Dest->hasReg()) { |
1877 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); | 1953 Asm->movd(RegX8632::getEncodedGPR(Dest->getRegNum()), SrcReg); |
1878 } else { | 1954 } else { |
1879 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 1955 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
1880 ->stackVarToAsmOperand(Dest)); | 1956 ->stackVarToAsmOperand(Dest)); |
1881 Asm->movd(StackAddr, SrcReg); | 1957 Asm->movd(StackAddr, SrcReg); |
1882 } | 1958 } |
1883 } | 1959 } |
1884 Ostream &Str = Func->getContext()->getStrEmit(); | 1960 emitIASBytes(Func, Asm, StartPosition); |
1885 emitIASBytes(Str, Asm, StartPosition); | |
1886 } | 1961 } |
1887 | 1962 |
1888 template <> void InstX8632Movp::emit(const Cfg *Func) const { | 1963 template <> void InstX8632Movp::emit(const Cfg *Func) const { |
1889 // TODO(wala,stichnot): movups works with all vector operands, but | 1964 // TODO(wala,stichnot): movups works with all vector operands, but |
1890 // there exist other instructions (movaps, movdqa, movdqu) that may | 1965 // there exist other instructions (movaps, movdqa, movdqu) that may |
1891 // perform better, depending on the data type and alignment of the | 1966 // perform better, depending on the data type and alignment of the |
1892 // operands. | 1967 // operands. |
1893 Ostream &Str = Func->getContext()->getStrEmit(); | 1968 Ostream &Str = Func->getContext()->getStrEmit(); |
1894 assert(getSrcSize() == 1); | 1969 assert(getSrcSize() == 1); |
1895 Str << "\tmovups\t"; | 1970 Str << "\tmovups\t"; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1940 // where part of the Dest register is untouched. | 2015 // where part of the Dest register is untouched. |
1941 assert(getSrcSize() == 2); | 2016 assert(getSrcSize() == 2); |
1942 const Variable *Dest = getDest(); | 2017 const Variable *Dest = getDest(); |
1943 assert(Dest == getSrc(0)); | 2018 assert(Dest == getSrc(0)); |
1944 const Variable *Src = llvm::cast<Variable>(getSrc(1)); | 2019 const Variable *Src = llvm::cast<Variable>(getSrc(1)); |
1945 assert(Dest->hasReg() && Src->hasReg()); | 2020 assert(Dest->hasReg() && Src->hasReg()); |
1946 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2021 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
1947 intptr_t StartPosition = Asm->GetPosition(); | 2022 intptr_t StartPosition = Asm->GetPosition(); |
1948 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), | 2023 Asm->movss(IceType_f32, RegX8632::getEncodedXmm(Dest->getRegNum()), |
1949 RegX8632::getEncodedXmm(Src->getRegNum())); | 2024 RegX8632::getEncodedXmm(Src->getRegNum())); |
1950 Ostream &Str = Func->getContext()->getStrEmit(); | 2025 emitIASBytes(Func, Asm, StartPosition); |
1951 emitIASBytes(Str, Asm, StartPosition); | |
1952 } | 2026 } |
1953 | 2027 |
1954 void InstX8632Movsx::emit(const Cfg *Func) const { | 2028 void InstX8632Movsx::emit(const Cfg *Func) const { |
1955 Ostream &Str = Func->getContext()->getStrEmit(); | 2029 Ostream &Str = Func->getContext()->getStrEmit(); |
1956 assert(getSrcSize() == 1); | 2030 assert(getSrcSize() == 1); |
1957 Str << "\tmovsx\t"; | 2031 Str << "\tmovsx\t"; |
1958 getDest()->emit(Func); | 2032 getDest()->emit(Func); |
1959 Str << ", "; | 2033 Str << ", "; |
1960 getSrc(0)->emit(Func); | 2034 getSrc(0)->emit(Func); |
1961 Str << "\n"; | 2035 Str << "\n"; |
(...skipping 27 matching lines...) Expand all Loading... |
1989 dumpSources(Func); | 2063 dumpSources(Func); |
1990 } | 2064 } |
1991 | 2065 |
1992 void InstX8632Nop::emit(const Cfg *Func) const { | 2066 void InstX8632Nop::emit(const Cfg *Func) const { |
1993 Ostream &Str = Func->getContext()->getStrEmit(); | 2067 Ostream &Str = Func->getContext()->getStrEmit(); |
1994 // TODO: Emit the right code for each variant. | 2068 // TODO: Emit the right code for each variant. |
1995 Str << "\tnop\t# variant = " << Variant << "\n"; | 2069 Str << "\tnop\t# variant = " << Variant << "\n"; |
1996 } | 2070 } |
1997 | 2071 |
1998 void InstX8632Nop::emitIAS(const Cfg *Func) const { | 2072 void InstX8632Nop::emitIAS(const Cfg *Func) const { |
1999 Ostream &Str = Func->getContext()->getStrEmit(); | |
2000 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2073 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
2001 intptr_t StartPosition = Asm->GetPosition(); | 2074 intptr_t StartPosition = Asm->GetPosition(); |
2002 // TODO: Emit the right code for the variant. | 2075 // TODO: Emit the right code for the variant. |
2003 Asm->nop(); | 2076 Asm->nop(); |
2004 emitIASBytes(Str, Asm, StartPosition); | 2077 emitIASBytes(Func, Asm, StartPosition); |
2005 } | 2078 } |
2006 | 2079 |
2007 void InstX8632Nop::dump(const Cfg *Func) const { | 2080 void InstX8632Nop::dump(const Cfg *Func) const { |
2008 Ostream &Str = Func->getContext()->getStrDump(); | 2081 Ostream &Str = Func->getContext()->getStrDump(); |
2009 Str << "nop (variant = " << Variant << ")"; | 2082 Str << "nop (variant = " << Variant << ")"; |
2010 } | 2083 } |
2011 | 2084 |
2012 void InstX8632Fld::emit(const Cfg *Func) const { | 2085 void InstX8632Fld::emit(const Cfg *Func) const { |
2013 Ostream &Str = Func->getContext()->getStrEmit(); | 2086 Ostream &Str = Func->getContext()->getStrEmit(); |
2014 assert(getSrcSize() == 1); | 2087 assert(getSrcSize() == 1); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2047 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); | 2120 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); |
2048 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); | 2121 Asm->movss(Ty, StackSlot, RegX8632::getEncodedXmm(Var->getRegNum())); |
2049 Asm->fld(Ty, StackSlot); | 2122 Asm->fld(Ty, StackSlot); |
2050 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2123 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
2051 } else { | 2124 } else { |
2052 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2125 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
2053 ->stackVarToAsmOperand(Var)); | 2126 ->stackVarToAsmOperand(Var)); |
2054 Asm->fld(Ty, StackAddr); | 2127 Asm->fld(Ty, StackAddr); |
2055 } | 2128 } |
2056 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { | 2129 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Src)) { |
| 2130 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2057 Asm->fld(Ty, Mem->toAsmAddress(Asm)); | 2131 Asm->fld(Ty, Mem->toAsmAddress(Asm)); |
2058 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { | 2132 } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { |
2059 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); | 2133 Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); |
2060 } else { | 2134 } else { |
2061 llvm_unreachable("Unexpected operand type"); | 2135 llvm_unreachable("Unexpected operand type"); |
2062 } | 2136 } |
2063 Ostream &Str = Func->getContext()->getStrEmit(); | 2137 emitIASBytes(Func, Asm, StartPosition); |
2064 emitIASBytes(Str, Asm, StartPosition); | |
2065 } | 2138 } |
2066 | 2139 |
2067 void InstX8632Fld::dump(const Cfg *Func) const { | 2140 void InstX8632Fld::dump(const Cfg *Func) const { |
2068 Ostream &Str = Func->getContext()->getStrDump(); | 2141 Ostream &Str = Func->getContext()->getStrDump(); |
2069 Str << "fld." << getSrc(0)->getType() << " "; | 2142 Str << "fld." << getSrc(0)->getType() << " "; |
2070 dumpSources(Func); | 2143 dumpSources(Func); |
2071 } | 2144 } |
2072 | 2145 |
2073 void InstX8632Fstp::emit(const Cfg *Func) const { | 2146 void InstX8632Fstp::emit(const Cfg *Func) const { |
2074 Ostream &Str = Func->getContext()->getStrEmit(); | 2147 Ostream &Str = Func->getContext()->getStrEmit(); |
(...skipping 30 matching lines...) Expand all Loading... |
2105 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2178 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
2106 intptr_t StartPosition = Asm->GetPosition(); | 2179 intptr_t StartPosition = Asm->GetPosition(); |
2107 assert(getSrcSize() == 0); | 2180 assert(getSrcSize() == 0); |
2108 const Variable *Dest = getDest(); | 2181 const Variable *Dest = getDest(); |
2109 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to | 2182 // TODO(jvoung,stichnot): Utilize this by setting Dest to NULL to |
2110 // "partially" delete the fstp if the Dest is unused. | 2183 // "partially" delete the fstp if the Dest is unused. |
2111 // Even if Dest is unused, the fstp should be kept for the SideEffects | 2184 // Even if Dest is unused, the fstp should be kept for the SideEffects |
2112 // of popping the stack. | 2185 // of popping the stack. |
2113 if (Dest == NULL) { | 2186 if (Dest == NULL) { |
2114 Asm->fstp(RegX8632::getEncodedSTReg(0)); | 2187 Asm->fstp(RegX8632::getEncodedSTReg(0)); |
2115 Ostream &Str = Func->getContext()->getStrEmit(); | 2188 emitIASBytes(Func, Asm, StartPosition); |
2116 emitIASBytes(Str, Asm, StartPosition); | |
2117 return; | 2189 return; |
2118 } | 2190 } |
2119 Type Ty = Dest->getType(); | 2191 Type Ty = Dest->getType(); |
2120 if (!Dest->hasReg()) { | 2192 if (!Dest->hasReg()) { |
2121 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) | 2193 x86::Address StackAddr(static_cast<TargetX8632 *>(Func->getTarget()) |
2122 ->stackVarToAsmOperand(Dest)); | 2194 ->stackVarToAsmOperand(Dest)); |
2123 Asm->fstp(Ty, StackAddr); | 2195 Asm->fstp(Ty, StackAddr); |
2124 } else { | 2196 } else { |
2125 // Dest is a physical (xmm) register, so st(0) needs to go through | 2197 // Dest is a physical (xmm) register, so st(0) needs to go through |
2126 // memory. Hack this by creating a temporary stack slot, spilling | 2198 // memory. Hack this by creating a temporary stack slot, spilling |
2127 // st(0) there, loading it into the xmm register, and deallocating | 2199 // st(0) there, loading it into the xmm register, and deallocating |
2128 // the stack slot. | 2200 // the stack slot. |
2129 x86::Immediate Width(typeWidthInBytes(Ty)); | 2201 x86::Immediate Width(typeWidthInBytes(Ty)); |
2130 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2202 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
2131 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); | 2203 x86::Address StackSlot = x86::Address(RegX8632::Encoded_Reg_esp, 0); |
2132 Asm->fstp(Ty, StackSlot); | 2204 Asm->fstp(Ty, StackSlot); |
2133 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); | 2205 Asm->movss(Ty, RegX8632::getEncodedXmm(Dest->getRegNum()), StackSlot); |
2134 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); | 2206 Asm->add(IceType_i32, RegX8632::Encoded_Reg_esp, Width); |
2135 } | 2207 } |
2136 Ostream &Str = Func->getContext()->getStrEmit(); | 2208 emitIASBytes(Func, Asm, StartPosition); |
2137 emitIASBytes(Str, Asm, StartPosition); | |
2138 } | 2209 } |
2139 | 2210 |
2140 void InstX8632Fstp::dump(const Cfg *Func) const { | 2211 void InstX8632Fstp::dump(const Cfg *Func) const { |
2141 Ostream &Str = Func->getContext()->getStrDump(); | 2212 Ostream &Str = Func->getContext()->getStrDump(); |
2142 dumpDest(Func); | 2213 dumpDest(Func); |
2143 Str << " = fstp." << getDest()->getType() << ", st(0)"; | 2214 Str << " = fstp." << getDest()->getType() << ", st(0)"; |
2144 Str << "\n"; | 2215 Str << "\n"; |
2145 } | 2216 } |
2146 | 2217 |
2147 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { | 2218 template <> void InstX8632Pcmpeq::emit(const Cfg *Func) const { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2209 | 2280 |
2210 void InstX8632Pop::emit(const Cfg *Func) const { | 2281 void InstX8632Pop::emit(const Cfg *Func) const { |
2211 Ostream &Str = Func->getContext()->getStrEmit(); | 2282 Ostream &Str = Func->getContext()->getStrEmit(); |
2212 assert(getSrcSize() == 0); | 2283 assert(getSrcSize() == 0); |
2213 Str << "\tpop\t"; | 2284 Str << "\tpop\t"; |
2214 getDest()->emit(Func); | 2285 getDest()->emit(Func); |
2215 Str << "\n"; | 2286 Str << "\n"; |
2216 } | 2287 } |
2217 | 2288 |
2218 void InstX8632Pop::emitIAS(const Cfg *Func) const { | 2289 void InstX8632Pop::emitIAS(const Cfg *Func) const { |
2219 Ostream &Str = Func->getContext()->getStrEmit(); | |
2220 assert(getSrcSize() == 0); | 2290 assert(getSrcSize() == 0); |
2221 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2291 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
2222 intptr_t StartPosition = Asm->GetPosition(); | 2292 intptr_t StartPosition = Asm->GetPosition(); |
2223 if (getDest()->hasReg()) { | 2293 if (getDest()->hasReg()) { |
2224 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); | 2294 Asm->popl(RegX8632::getEncodedGPR(getDest()->getRegNum())); |
2225 } else { | 2295 } else { |
2226 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) | 2296 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget()) |
2227 ->stackVarToAsmOperand(getDest())); | 2297 ->stackVarToAsmOperand(getDest())); |
2228 } | 2298 } |
2229 emitIASBytes(Str, Asm, StartPosition); | 2299 emitIASBytes(Func, Asm, StartPosition); |
2230 } | 2300 } |
2231 | 2301 |
2232 void InstX8632Pop::dump(const Cfg *Func) const { | 2302 void InstX8632Pop::dump(const Cfg *Func) const { |
2233 Ostream &Str = Func->getContext()->getStrDump(); | 2303 Ostream &Str = Func->getContext()->getStrDump(); |
2234 dumpDest(Func); | 2304 dumpDest(Func); |
2235 Str << " = pop." << getDest()->getType() << " "; | 2305 Str << " = pop." << getDest()->getType() << " "; |
2236 } | 2306 } |
2237 | 2307 |
2238 void InstX8632AdjustStack::emit(const Cfg *Func) const { | 2308 void InstX8632AdjustStack::emit(const Cfg *Func) const { |
2239 Ostream &Str = Func->getContext()->getStrEmit(); | 2309 Ostream &Str = Func->getContext()->getStrEmit(); |
2240 Str << "\tsub\tesp, " << Amount << "\n"; | 2310 Str << "\tsub\tesp, " << Amount << "\n"; |
2241 Func->getTarget()->updateStackAdjustment(Amount); | 2311 Func->getTarget()->updateStackAdjustment(Amount); |
2242 } | 2312 } |
2243 | 2313 |
2244 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { | 2314 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const { |
2245 Ostream &Str = Func->getContext()->getStrEmit(); | |
2246 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2315 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
2247 intptr_t StartPosition = Asm->GetPosition(); | 2316 intptr_t StartPosition = Asm->GetPosition(); |
2248 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); | 2317 Asm->sub(IceType_i32, RegX8632::Encoded_Reg_esp, x86::Immediate(Amount)); |
2249 emitIASBytes(Str, Asm, StartPosition); | 2318 emitIASBytes(Func, Asm, StartPosition); |
2250 Func->getTarget()->updateStackAdjustment(Amount); | 2319 Func->getTarget()->updateStackAdjustment(Amount); |
2251 } | 2320 } |
2252 | 2321 |
2253 void InstX8632AdjustStack::dump(const Cfg *Func) const { | 2322 void InstX8632AdjustStack::dump(const Cfg *Func) const { |
2254 Ostream &Str = Func->getContext()->getStrDump(); | 2323 Ostream &Str = Func->getContext()->getStrDump(); |
2255 Str << "esp = sub.i32 esp, " << Amount; | 2324 Str << "esp = sub.i32 esp, " << Amount; |
2256 } | 2325 } |
2257 | 2326 |
2258 void InstX8632Push::emit(const Cfg *Func) const { | 2327 void InstX8632Push::emit(const Cfg *Func) const { |
2259 Ostream &Str = Func->getContext()->getStrEmit(); | 2328 Ostream &Str = Func->getContext()->getStrEmit(); |
2260 assert(getSrcSize() == 1); | 2329 assert(getSrcSize() == 1); |
2261 // Push is currently only used for saving GPRs. | 2330 // Push is currently only used for saving GPRs. |
2262 Variable *Var = llvm::cast<Variable>(getSrc(0)); | 2331 Variable *Var = llvm::cast<Variable>(getSrc(0)); |
2263 assert(Var->hasReg()); | 2332 assert(Var->hasReg()); |
2264 Str << "\tpush\t"; | 2333 Str << "\tpush\t"; |
2265 Var->emit(Func); | 2334 Var->emit(Func); |
2266 Str << "\n"; | 2335 Str << "\n"; |
2267 } | 2336 } |
2268 | 2337 |
2269 void InstX8632Push::emitIAS(const Cfg *Func) const { | 2338 void InstX8632Push::emitIAS(const Cfg *Func) const { |
2270 Ostream &Str = Func->getContext()->getStrEmit(); | |
2271 assert(getSrcSize() == 1); | 2339 assert(getSrcSize() == 1); |
2272 // Push is currently only used for saving GPRs. | 2340 // Push is currently only used for saving GPRs. |
2273 Variable *Var = llvm::cast<Variable>(getSrc(0)); | 2341 Variable *Var = llvm::cast<Variable>(getSrc(0)); |
2274 assert(Var->hasReg()); | 2342 assert(Var->hasReg()); |
2275 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2343 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
2276 intptr_t StartPosition = Asm->GetPosition(); | 2344 intptr_t StartPosition = Asm->GetPosition(); |
2277 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); | 2345 Asm->pushl(RegX8632::getEncodedGPR(Var->getRegNum())); |
2278 emitIASBytes(Str, Asm, StartPosition); | 2346 emitIASBytes(Func, Asm, StartPosition); |
2279 } | 2347 } |
2280 | 2348 |
2281 void InstX8632Push::dump(const Cfg *Func) const { | 2349 void InstX8632Push::dump(const Cfg *Func) const { |
2282 Ostream &Str = Func->getContext()->getStrDump(); | 2350 Ostream &Str = Func->getContext()->getStrDump(); |
2283 Str << "push." << getSrc(0)->getType() << " "; | 2351 Str << "push." << getSrc(0)->getType() << " "; |
2284 dumpSources(Func); | 2352 dumpSources(Func); |
2285 } | 2353 } |
2286 | 2354 |
2287 template <> void InstX8632Psll::emit(const Cfg *Func) const { | 2355 template <> void InstX8632Psll::emit(const Cfg *Func) const { |
2288 assert(getDest()->getType() == IceType_v8i16 || | 2356 assert(getDest()->getType() == IceType_v8i16 || |
(...skipping 16 matching lines...) Expand all Loading... |
2305 TypeX8632Attributes[getDest()->getType()].PackString); | 2373 TypeX8632Attributes[getDest()->getType()].PackString); |
2306 emitTwoAddress(buf, this, Func); | 2374 emitTwoAddress(buf, this, Func); |
2307 } | 2375 } |
2308 | 2376 |
2309 void InstX8632Ret::emit(const Cfg *Func) const { | 2377 void InstX8632Ret::emit(const Cfg *Func) const { |
2310 Ostream &Str = Func->getContext()->getStrEmit(); | 2378 Ostream &Str = Func->getContext()->getStrEmit(); |
2311 Str << "\tret\n"; | 2379 Str << "\tret\n"; |
2312 } | 2380 } |
2313 | 2381 |
2314 void InstX8632Ret::emitIAS(const Cfg *Func) const { | 2382 void InstX8632Ret::emitIAS(const Cfg *Func) const { |
2315 Ostream &Str = Func->getContext()->getStrEmit(); | |
2316 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2383 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
2317 intptr_t StartPosition = Asm->GetPosition(); | 2384 intptr_t StartPosition = Asm->GetPosition(); |
2318 Asm->ret(); | 2385 Asm->ret(); |
2319 emitIASBytes(Str, Asm, StartPosition); | 2386 emitIASBytes(Func, Asm, StartPosition); |
2320 } | 2387 } |
2321 | 2388 |
2322 void InstX8632Ret::dump(const Cfg *Func) const { | 2389 void InstX8632Ret::dump(const Cfg *Func) const { |
2323 Ostream &Str = Func->getContext()->getStrDump(); | 2390 Ostream &Str = Func->getContext()->getStrDump(); |
2324 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 2391 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
2325 Str << "ret." << Ty << " "; | 2392 Str << "ret." << Ty << " "; |
2326 dumpSources(Func); | 2393 dumpSources(Func); |
2327 } | 2394 } |
2328 | 2395 |
2329 void InstX8632Xadd::emit(const Cfg *Func) const { | 2396 void InstX8632Xadd::emit(const Cfg *Func) const { |
2330 Ostream &Str = Func->getContext()->getStrEmit(); | 2397 Ostream &Str = Func->getContext()->getStrEmit(); |
2331 if (Locked) { | 2398 if (Locked) { |
2332 Str << "\tlock"; | 2399 Str << "\tlock"; |
2333 } | 2400 } |
2334 Str << "\txadd\t"; | 2401 Str << "\txadd\t"; |
2335 getSrc(0)->emit(Func); | 2402 getSrc(0)->emit(Func); |
2336 Str << ", "; | 2403 Str << ", "; |
2337 getSrc(1)->emit(Func); | 2404 getSrc(1)->emit(Func); |
2338 Str << "\n"; | 2405 Str << "\n"; |
2339 } | 2406 } |
2340 | 2407 |
2341 void InstX8632Xadd::emitIAS(const Cfg *Func) const { | 2408 void InstX8632Xadd::emitIAS(const Cfg *Func) const { |
2342 Ostream &Str = Func->getContext()->getStrEmit(); | |
2343 assert(getSrcSize() == 2); | 2409 assert(getSrcSize() == 2); |
2344 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2410 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
2345 intptr_t StartPosition = Asm->GetPosition(); | 2411 intptr_t StartPosition = Asm->GetPosition(); |
2346 Type Ty = getSrc(0)->getType(); | 2412 Type Ty = getSrc(0)->getType(); |
2347 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2413 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2414 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2348 const x86::Address Addr = Mem->toAsmAddress(Asm); | 2415 const x86::Address Addr = Mem->toAsmAddress(Asm); |
2349 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); | 2416 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); |
2350 assert(VarReg->hasReg()); | 2417 assert(VarReg->hasReg()); |
2351 const RegX8632::GPRRegister Reg = | 2418 const RegX8632::GPRRegister Reg = |
2352 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2419 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
2353 if (Locked) { | 2420 if (Locked) { |
2354 Asm->lock(); | 2421 Asm->lock(); |
2355 } | 2422 } |
2356 Asm->xadd(Ty, Addr, Reg); | 2423 Asm->xadd(Ty, Addr, Reg); |
2357 emitIASBytes(Str, Asm, StartPosition); | 2424 emitIASBytes(Func, Asm, StartPosition); |
2358 } | 2425 } |
2359 | 2426 |
2360 void InstX8632Xadd::dump(const Cfg *Func) const { | 2427 void InstX8632Xadd::dump(const Cfg *Func) const { |
2361 Ostream &Str = Func->getContext()->getStrDump(); | 2428 Ostream &Str = Func->getContext()->getStrDump(); |
2362 if (Locked) { | 2429 if (Locked) { |
2363 Str << "lock "; | 2430 Str << "lock "; |
2364 } | 2431 } |
2365 Type Ty = getSrc(0)->getType(); | 2432 Type Ty = getSrc(0)->getType(); |
2366 Str << "xadd." << Ty << " "; | 2433 Str << "xadd." << Ty << " "; |
2367 dumpSources(Func); | 2434 dumpSources(Func); |
2368 } | 2435 } |
2369 | 2436 |
2370 void InstX8632Xchg::emit(const Cfg *Func) const { | 2437 void InstX8632Xchg::emit(const Cfg *Func) const { |
2371 Ostream &Str = Func->getContext()->getStrEmit(); | 2438 Ostream &Str = Func->getContext()->getStrEmit(); |
2372 Str << "\txchg\t"; | 2439 Str << "\txchg\t"; |
2373 getSrc(0)->emit(Func); | 2440 getSrc(0)->emit(Func); |
2374 Str << ", "; | 2441 Str << ", "; |
2375 getSrc(1)->emit(Func); | 2442 getSrc(1)->emit(Func); |
2376 Str << "\n"; | 2443 Str << "\n"; |
2377 } | 2444 } |
2378 | 2445 |
2379 void InstX8632Xchg::emitIAS(const Cfg *Func) const { | 2446 void InstX8632Xchg::emitIAS(const Cfg *Func) const { |
2380 Ostream &Str = Func->getContext()->getStrEmit(); | |
2381 assert(getSrcSize() == 2); | 2447 assert(getSrcSize() == 2); |
2382 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 2448 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
2383 intptr_t StartPosition = Asm->GetPosition(); | 2449 intptr_t StartPosition = Asm->GetPosition(); |
2384 Type Ty = getSrc(0)->getType(); | 2450 Type Ty = getSrc(0)->getType(); |
2385 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); | 2451 const OperandX8632Mem *Mem = llvm::cast<OperandX8632Mem>(getSrc(0)); |
| 2452 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
2386 const x86::Address Addr = Mem->toAsmAddress(Asm); | 2453 const x86::Address Addr = Mem->toAsmAddress(Asm); |
2387 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); | 2454 const Variable *VarReg = llvm::cast<Variable>(getSrc(1)); |
2388 assert(VarReg->hasReg()); | 2455 assert(VarReg->hasReg()); |
2389 const RegX8632::GPRRegister Reg = | 2456 const RegX8632::GPRRegister Reg = |
2390 RegX8632::getEncodedGPR(VarReg->getRegNum()); | 2457 RegX8632::getEncodedGPR(VarReg->getRegNum()); |
2391 Asm->xchg(Ty, Addr, Reg); | 2458 Asm->xchg(Ty, Addr, Reg); |
2392 emitIASBytes(Str, Asm, StartPosition); | 2459 emitIASBytes(Func, Asm, StartPosition); |
2393 } | 2460 } |
2394 | 2461 |
2395 void InstX8632Xchg::dump(const Cfg *Func) const { | 2462 void InstX8632Xchg::dump(const Cfg *Func) const { |
2396 Ostream &Str = Func->getContext()->getStrDump(); | 2463 Ostream &Str = Func->getContext()->getStrDump(); |
2397 Type Ty = getSrc(0)->getType(); | 2464 Type Ty = getSrc(0)->getType(); |
2398 Str << "xchg." << Ty << " "; | 2465 Str << "xchg." << Ty << " "; |
2399 dumpSources(Func); | 2466 dumpSources(Func); |
2400 } | 2467 } |
2401 | 2468 |
2402 void OperandX8632Mem::emit(const Cfg *Func) const { | 2469 void OperandX8632Mem::emit(const Cfg *Func) const { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2489 Str << "+"; | 2556 Str << "+"; |
2490 Offset->dump(Func, Str); | 2557 Offset->dump(Func, Str); |
2491 } | 2558 } |
2492 } else { | 2559 } else { |
2493 // There is only the offset. | 2560 // There is only the offset. |
2494 Offset->dump(Func, Str); | 2561 Offset->dump(Func, Str); |
2495 } | 2562 } |
2496 Str << "]"; | 2563 Str << "]"; |
2497 } | 2564 } |
2498 | 2565 |
| 2566 void OperandX8632Mem::emitSegmentOverride(x86::AssemblerX86 *Asm) const { |
| 2567 if (SegmentReg != DefaultSegment) { |
| 2568 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); |
| 2569 Asm->EmitSegmentOverride(InstX8632SegmentPrefixes[SegmentReg]); |
| 2570 } |
| 2571 } |
| 2572 |
2499 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { | 2573 x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { |
2500 int32_t Disp = 0; | 2574 int32_t Disp = 0; |
2501 AssemblerFixup *Fixup = NULL; | 2575 AssemblerFixup *Fixup = NULL; |
2502 // Determine the offset (is it relocatable?) | 2576 // Determine the offset (is it relocatable?) |
2503 if (getOffset()) { | 2577 if (getOffset()) { |
2504 if (ConstantInteger32 *CI = | 2578 if (ConstantInteger32 *CI = |
2505 llvm::dyn_cast<ConstantInteger32>(getOffset())) { | 2579 llvm::dyn_cast<ConstantInteger32>(getOffset())) { |
2506 Disp = static_cast<int32_t>(CI->getValue()); | 2580 Disp = static_cast<int32_t>(CI->getValue()); |
2507 } else if (ConstantRelocatable *CR = | 2581 } else if (ConstantRelocatable *CR = |
2508 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { | 2582 llvm::dyn_cast<ConstantRelocatable>(getOffset())) { |
2509 // TODO(jvoung): CR + non-zero-offset isn't really tested yet, | |
2510 // since the addressing mode optimization doesn't try to combine | |
2511 // ConstantRelocatable with something else. | |
2512 assert(CR->getOffset() == 0); | |
2513 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); | 2583 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); |
2514 } else { | 2584 } else { |
2515 llvm_unreachable("Unexpected offset type"); | 2585 llvm_unreachable("Unexpected offset type"); |
2516 } | 2586 } |
2517 } | 2587 } |
2518 | 2588 |
2519 // Now convert to the various possible forms. | 2589 // Now convert to the various possible forms. |
2520 if (getBase() && getIndex()) { | 2590 if (getBase() && getIndex()) { |
2521 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), | 2591 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), |
2522 RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 2592 RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
2523 x86::ScaleFactor(getShift()), Disp); | 2593 x86::ScaleFactor(getShift()), Disp); |
2524 } else if (getBase()) { | 2594 } else if (getBase()) { |
2525 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); | 2595 return x86::Address(RegX8632::getEncodedGPR(getBase()->getRegNum()), Disp); |
2526 } else if (getIndex()) { | 2596 } else if (getIndex()) { |
2527 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), | 2597 return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), |
2528 x86::ScaleFactor(getShift()), Disp); | 2598 x86::ScaleFactor(getShift()), Disp); |
| 2599 } else if (Fixup) { |
| 2600 // The fixup itself has an offset, so Disp should still be 0. |
| 2601 assert(Disp == 0); |
| 2602 return x86::Address::Absolute(Fixup); |
2529 } else { | 2603 } else { |
2530 return x86::Address::Absolute(Disp, Fixup); | 2604 return x86::Address::Absolute(Disp); |
2531 } | 2605 } |
2532 } | 2606 } |
2533 | 2607 |
| 2608 x86::Address VariableSplit::toAsmAddress(const Cfg *Func) const { |
| 2609 assert(!Var->hasReg()); |
| 2610 const TargetLowering *Target = Func->getTarget(); |
| 2611 int32_t Offset = |
| 2612 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
| 2613 return x86::Address(RegX8632::getEncodedGPR(Target->getFrameOrStackReg()), |
| 2614 Offset); |
| 2615 } |
| 2616 |
2534 void VariableSplit::emit(const Cfg *Func) const { | 2617 void VariableSplit::emit(const Cfg *Func) const { |
2535 Ostream &Str = Func->getContext()->getStrEmit(); | 2618 Ostream &Str = Func->getContext()->getStrEmit(); |
2536 assert(!Var->hasReg()); | 2619 assert(!Var->hasReg()); |
2537 // The following is copied/adapted from TargetX8632::emitVariable(). | 2620 // The following is copied/adapted from TargetX8632::emitVariable(). |
2538 const TargetLowering *Target = Func->getTarget(); | 2621 const TargetLowering *Target = Func->getTarget(); |
2539 const Type Ty = IceType_i32; | 2622 const Type Ty = IceType_i32; |
2540 Str << TypeX8632Attributes[Ty].WidthString << " [" | 2623 Str << TypeX8632Attributes[Ty].WidthString << " [" |
2541 << Target->getRegName(Target->getFrameOrStackReg(), Ty); | 2624 << Target->getRegName(Target->getFrameOrStackReg(), Ty); |
2542 int32_t Offset = Var->getStackOffset() + Target->getStackAdjustment(); | 2625 int32_t Offset = |
2543 if (Part == High) | 2626 Var->getStackOffset() + Target->getStackAdjustment() + getOffset(); |
2544 Offset += 4; | |
2545 if (Offset) { | 2627 if (Offset) { |
2546 if (Offset > 0) | 2628 if (Offset > 0) |
2547 Str << "+"; | 2629 Str << "+"; |
2548 Str << Offset; | 2630 Str << Offset; |
2549 } | 2631 } |
2550 Str << "]"; | 2632 Str << "]"; |
2551 } | 2633 } |
2552 | 2634 |
2553 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { | 2635 void VariableSplit::dump(const Cfg *Func, Ostream &Str) const { |
2554 switch (Part) { | 2636 switch (Part) { |
2555 case Low: | 2637 case Low: |
2556 Str << "low"; | 2638 Str << "low"; |
2557 break; | 2639 break; |
2558 case High: | 2640 case High: |
2559 Str << "high"; | 2641 Str << "high"; |
2560 break; | 2642 break; |
2561 default: | 2643 default: |
2562 Str << "???"; | 2644 Str << "???"; |
2563 break; | 2645 break; |
2564 } | 2646 } |
2565 Str << "("; | 2647 Str << "("; |
2566 if (Func) | 2648 if (Func) |
2567 Var->dump(Func); | 2649 Var->dump(Func); |
2568 else | 2650 else |
2569 Var->dump(Str); | 2651 Var->dump(Str); |
2570 Str << ")"; | 2652 Str << ")"; |
2571 } | 2653 } |
2572 | 2654 |
2573 } // end of namespace Ice | 2655 } // end of namespace Ice |
OLD | NEW |