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