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

Side by Side Diff: src/IceInstX8632.cpp

Issue 476323004: Start adding an integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: simplify Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file implements the InstX8632 and OperandX8632 classes, 10 // This file implements the InstX8632 and OperandX8632 classes,
11 // primarily the constructors and the dump()/emit() methods. 11 // primarily the constructors and the dump()/emit() methods.
12 // 12 //
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #include "assembler_ia32.h"
15 #include "IceCfg.h" 16 #include "IceCfg.h"
16 #include "IceCfgNode.h" 17 #include "IceCfgNode.h"
17 #include "IceInst.h" 18 #include "IceInst.h"
18 #include "IceInstX8632.h" 19 #include "IceInstX8632.h"
19 #include "IceTargetLoweringX8632.h" 20 #include "IceTargetLoweringX8632.h"
20 #include "IceOperand.h" 21 #include "IceOperand.h"
21 22
22 namespace Ice { 23 namespace Ice {
23 24
24 namespace { 25 namespace {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 ICETYPEX8632_TABLE 57 ICETYPEX8632_TABLE
57 #undef X 58 #undef X
58 }; 59 };
59 60
60 const char *InstX8632SegmentRegNames[] = { 61 const char *InstX8632SegmentRegNames[] = {
61 #define X(val, name) name, 62 #define X(val, name) name,
62 SEG_REGX8632_TABLE 63 SEG_REGX8632_TABLE
63 #undef X 64 #undef X
64 }; 65 };
65 66
67 x86::Condition convertToAsmCondition(InstX8632::BrCond Cond) {
68 return x86::Condition(Cond);
69 }
70
71 x86::Register convertToAsmGPR(int32_t RegNum) {
72 assert(TargetX8632::Reg_eax <= RegNum && RegNum <= TargetX8632::Reg_edi);
73 // TODO(jvoung): do some sort of cross-check that the numbers are the same.
74 return x86::Register(RegNum);
75 }
76
77 x86::ByteRegister convertToAsmByteRegister(int32_t RegNum) {
78 if (RegNum == TargetX8632::Reg_ah) {
79 return x86::AH;
80 }
81 // TODO(jvoung): do some sort of cross-check that the numbers are the same.
82 assert(TargetX8632::Reg_eax <= RegNum && RegNum <= TargetX8632::Reg_ebx);
83 return x86::ByteRegister(RegNum);
84 }
85
86 x86::XmmRegister convertToAsmXMMReg(int32_t RegNum) {
87 assert(TargetX8632::Reg_xmm0 <= RegNum && RegNum <= TargetX8632::Reg_xmm7);
88 // TODO(jvoung): do some sort of cross-check that the numbers are the same.
89 return x86::XmmRegister(RegNum - TargetX8632::Reg_xmm0);
90 }
91
92 // Convert a float or double immediate to an Address Operand.
93 // Modifies SymbolicOffset to contain the symbol.
94 x86::Address convertImmToAsmAddress(const Constant *Imm,
95 IceString &SymbolicOffset) {
96 std::string Buffer;
97 llvm::raw_string_ostream StrBuf(Buffer);
98 Type Ty = Imm->getType();
99 assert(llvm::isa<ConstantFloat>(Imm) || llvm::isa<ConstantDouble>(Imm));
100 StrBuf << "L$" << Ty << "$" << Imm->getPoolEntryID();
101 SymbolicOffset = StrBuf.str();
102 return x86::Address::Absolute(0);
103 }
104
66 } // end of anonymous namespace 105 } // end of anonymous namespace
67 106
68 const char *InstX8632::getWidthString(Type Ty) { 107 const char *InstX8632::getWidthString(Type Ty) {
69 return TypeX8632Attributes[Ty].WidthString; 108 return TypeX8632Attributes[Ty].WidthString;
70 } 109 }
71 110
72 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, 111 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base,
73 Constant *Offset, Variable *Index, 112 Constant *Offset, Variable *Index,
74 uint16_t Shift, SegmentRegisters SegmentReg) 113 uint16_t Shift, SegmentRegisters SegmentReg)
75 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), 114 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index),
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 } 316 }
278 317
279 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) 318 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source)
280 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { 319 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) {
281 addSource(Dest); 320 addSource(Dest);
282 addSource(Source); 321 addSource(Source);
283 } 322 }
284 323
285 // ======================== Dump routines ======================== // 324 // ======================== Dump routines ======================== //
286 325
326 namespace {
327
328 void emitIASBytes(Ostream &Str, const x86::AssemblerX86 *Asm,
329 intptr_t StartPosition) {
330 intptr_t EndPosition = Asm->GetPosition();
331 for (intptr_t i = 0; i < EndPosition - StartPosition; ++i) {
332 Str << "\t.byte "
333 << static_cast<uint32_t>(Asm->LoadBuffer(StartPosition + i)) << "\n";
334 }
335 }
336
337 void emitIASBytesRelocatable(Ostream &Str, const x86::AssemblerX86 *Asm,
338 intptr_t StartPosition,
339 const IceString &SymbolicOffset) {
340 const intptr_t OffsetSize = 4;
341 intptr_t EndPosition = Asm->GetPosition() - OffsetSize;
342 for (intptr_t i = 0; i < EndPosition - StartPosition; ++i) {
343 Str << "\t.byte "
344 << static_cast<uint32_t>(Asm->LoadBuffer(StartPosition + i)) << "\n";
345 }
346 Str << "\t.long " << SymbolicOffset << "\n";
347 }
348
349 void emitIASDestSrcXMM(const Cfg *Func, const Variable *Dest,
350 const Operand *Src,
351 x86::AssemblerX86::EmitXmmXmm EmitXmmXmm,
352 x86::AssemblerX86::EmitXmmAddr EmitXmmAddr) {
353 Ostream &Str = Func->getContext()->getStrEmit();
354 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
355 intptr_t StartPosition = Asm->GetPosition();
356 assert(Dest->hasReg());
357 x86::XmmRegister DestReg = convertToAsmXMMReg(Dest->getRegNum());
358 IceString SymbolicOffset = "";
359 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) {
360 if (SrcVar->hasReg()) {
361 x86::XmmRegister SrcReg = convertToAsmXMMReg(SrcVar->getRegNum());
362 (Asm->*EmitXmmXmm)(DestReg, SrcReg);
363 } else {
364 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
365 ->stackVarToAsmOperand(SrcVar);
366 (Asm->*EmitXmmAddr)(DestReg, SrcStackAddr);
367 }
368 } else if (const OperandX8632Mem *Mem =
369 llvm::dyn_cast<OperandX8632Mem>(Src)) {
370 x86::Address SrcAddr = Mem->convertToAsmAddress(SymbolicOffset);
371 (Asm->*EmitXmmAddr)(DestReg, SrcAddr);
372 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) {
373 (Asm->*EmitXmmAddr)(DestReg, convertImmToAsmAddress(Imm, SymbolicOffset));
374 } else {
375 llvm_unreachable("Unexpected operand type");
376 }
377 // TODO(jvoung): Record the buffer position containing the relocation,
378 // instead of just assuming it's the last 4 bytes.
379 if (!SymbolicOffset.empty()) {
380 emitIASBytesRelocatable(Str, Asm, StartPosition, SymbolicOffset);
381 } else {
382 emitIASBytes(Str, Asm, StartPosition);
383 }
384 }
385
386 } // end of anonymous namespace
387
287 void InstX8632::dump(const Cfg *Func) const { 388 void InstX8632::dump(const Cfg *Func) const {
288 Ostream &Str = Func->getContext()->getStrDump(); 389 Ostream &Str = Func->getContext()->getStrDump();
289 Str << "[X8632] "; 390 Str << "[X8632] ";
290 Inst::dump(Func); 391 Inst::dump(Func);
291 } 392 }
292 393
394 void InstX8632::emitIAS(const Cfg *Func) const { emit(Func); }
395
293 void InstX8632Label::emit(const Cfg *Func) const { 396 void InstX8632Label::emit(const Cfg *Func) const {
294 Ostream &Str = Func->getContext()->getStrEmit(); 397 Ostream &Str = Func->getContext()->getStrEmit();
295 Str << getName(Func) << ":\n"; 398 Str << getName(Func) << ":\n";
296 } 399 }
297 400
298 void InstX8632Label::dump(const Cfg *Func) const { 401 void InstX8632Label::dump(const Cfg *Func) const {
299 Ostream &Str = Func->getContext()->getStrDump(); 402 Ostream &Str = Func->getContext()->getStrDump();
300 Str << getName(Func) << ":"; 403 Str << getName(Func) << ":";
301 } 404 }
302 405
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 450
348 void InstX8632Call::emit(const Cfg *Func) const { 451 void InstX8632Call::emit(const Cfg *Func) const {
349 Ostream &Str = Func->getContext()->getStrEmit(); 452 Ostream &Str = Func->getContext()->getStrEmit();
350 assert(getSrcSize() == 1); 453 assert(getSrcSize() == 1);
351 Str << "\tcall\t"; 454 Str << "\tcall\t";
352 getCallTarget()->emit(Func); 455 getCallTarget()->emit(Func);
353 Str << "\n"; 456 Str << "\n";
354 Func->getTarget()->resetStackAdjustment(); 457 Func->getTarget()->resetStackAdjustment();
355 } 458 }
356 459
460 void InstX8632Call::emitIAS(const Cfg *Func) const {
461 Ostream &Str = Func->getContext()->getStrEmit();
462 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
463 intptr_t StartPosition = Asm->GetPosition();
464 Operand *Target = getCallTarget();
465 IceString SymbolicOffset = "";
466 if (Variable *Var = llvm::dyn_cast<Variable>(Target)) {
467 if (Var->hasReg()) {
468 Asm->call(convertToAsmGPR(Var->getRegNum()));
469 } else {
470 Asm->call(static_cast<TargetX8632 *>(Func->getTarget())
471 ->stackVarToAsmOperand(Var));
472 }
473 } else if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) {
474 Asm->call(Mem->convertToAsmAddress(SymbolicOffset));
475 } else if (ConstantRelocatable *CR =
476 llvm::dyn_cast<ConstantRelocatable>(Target)) {
477 assert(CR->getOffset() == 0 && "We only support calling a function");
478 SymbolicOffset = CR->getName();
479 Asm->call(CR);
480 }
481 if (!SymbolicOffset.empty()) {
482 // TODO(jvoung): This .byte and .long hack doesn't work, since we need
483 // a pc-rel relocation, and we also need the section contents to be
484 // -4 instead of 0.
485 //
486 // Still, we have at least filled the assembler buffer so that the
487 // instruction sizes/positions are correct for jumps.
488 //
489 // For now, fall back to the regular .s emission.
490 emit(Func);
491 } else {
492 emitIASBytes(Str, Asm, StartPosition);
493 }
494 Func->getTarget()->resetStackAdjustment();
495 }
496
357 void InstX8632Call::dump(const Cfg *Func) const { 497 void InstX8632Call::dump(const Cfg *Func) const {
358 Ostream &Str = Func->getContext()->getStrDump(); 498 Ostream &Str = Func->getContext()->getStrDump();
359 if (getDest()) { 499 if (getDest()) {
360 dumpDest(Func); 500 dumpDest(Func);
361 Str << " = "; 501 Str << " = ";
362 } 502 }
363 Str << "call "; 503 Str << "call ";
364 getCallTarget()->dump(Func); 504 getCallTarget()->dump(Func);
365 } 505 }
366 506
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 assert(getSrcSize() == 1); 610 assert(getSrcSize() == 1);
471 Type Ty = getSrc(0)->getType(); 611 Type Ty = getSrc(0)->getType();
472 assert(Ty == IceType_f32 || Ty == IceType_f64); 612 assert(Ty == IceType_f32 || Ty == IceType_f64);
473 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; 613 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t";
474 getDest()->emit(Func); 614 getDest()->emit(Func);
475 Str << ", "; 615 Str << ", ";
476 getSrc(0)->emit(Func); 616 getSrc(0)->emit(Func);
477 Str << "\n"; 617 Str << "\n";
478 } 618 }
479 619
620 template <> void InstX8632Sqrtss::emitIAS(const Cfg *Func) const {
621 assert(getDest()->hasReg());
622 assert(getSrcSize() == 1);
623 const Operand *Src = getSrc(0);
624 Type Ty = getSrc(0)->getType();
625 assert(Ty == IceType_f32 || Ty == IceType_f64);
626 if (Ty == IceType_f64) {
627 emitIASDestSrcXMM(Func, getDest(), Src, &x86::AssemblerX86::sqrtsd,
628 &x86::AssemblerX86::sqrtsd);
629 } else {
630 emitIASDestSrcXMM(Func, getDest(), Src, &x86::AssemblerX86::sqrtss,
631 &x86::AssemblerX86::sqrtss);
632 }
633 }
634
635 template <> void InstX8632Addps::emitIAS(const Cfg *Func) const {
636 assert(getSrcSize() == 2);
637 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::addps,
638 &x86::AssemblerX86::addps);
639 }
640
480 template <> void InstX8632Addss::emit(const Cfg *Func) const { 641 template <> void InstX8632Addss::emit(const Cfg *Func) const {
481 char buf[30]; 642 char buf[30];
482 snprintf(buf, llvm::array_lengthof(buf), "add%s", 643 snprintf(buf, llvm::array_lengthof(buf), "add%s",
483 TypeX8632Attributes[getDest()->getType()].SdSsString); 644 TypeX8632Attributes[getDest()->getType()].SdSsString);
484 emitTwoAddress(buf, this, Func); 645 emitTwoAddress(buf, this, Func);
485 } 646 }
486 647
648 template <> void InstX8632Addss::emitIAS(const Cfg *Func) const {
649 Type Ty = getDest()->getType();
650 assert(getSrcSize() == 2);
651 if (Ty == IceType_f64) {
652 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::addsd,
653 &x86::AssemblerX86::addsd);
654 } else {
655 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::addss,
656 &x86::AssemblerX86::addss);
657 }
658 }
659
487 template <> void InstX8632Padd::emit(const Cfg *Func) const { 660 template <> void InstX8632Padd::emit(const Cfg *Func) const {
488 char buf[30]; 661 char buf[30];
489 snprintf(buf, llvm::array_lengthof(buf), "padd%s", 662 snprintf(buf, llvm::array_lengthof(buf), "padd%s",
490 TypeX8632Attributes[getDest()->getType()].PackString); 663 TypeX8632Attributes[getDest()->getType()].PackString);
491 emitTwoAddress(buf, this, Func); 664 emitTwoAddress(buf, this, Func);
492 } 665 }
493 666
494 template <> void InstX8632Pmull::emit(const Cfg *Func) const { 667 template <> void InstX8632Pmull::emit(const Cfg *Func) const {
495 char buf[30]; 668 char buf[30];
496 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || 669 bool TypesAreValid = getDest()->getType() == IceType_v4i32 ||
497 getDest()->getType() == IceType_v8i16; 670 getDest()->getType() == IceType_v8i16;
498 bool InstructionSetIsValid = 671 bool InstructionSetIsValid =
499 getDest()->getType() == IceType_v8i16 || 672 getDest()->getType() == IceType_v8i16 ||
500 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 673 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
501 TargetX8632::SSE4_1; 674 TargetX8632::SSE4_1;
502 (void)TypesAreValid; 675 (void)TypesAreValid;
503 (void)InstructionSetIsValid; 676 (void)InstructionSetIsValid;
504 assert(TypesAreValid); 677 assert(TypesAreValid);
505 assert(InstructionSetIsValid); 678 assert(InstructionSetIsValid);
506 snprintf(buf, llvm::array_lengthof(buf), "pmull%s", 679 snprintf(buf, llvm::array_lengthof(buf), "pmull%s",
507 TypeX8632Attributes[getDest()->getType()].PackString); 680 TypeX8632Attributes[getDest()->getType()].PackString);
508 emitTwoAddress(buf, this, Func); 681 emitTwoAddress(buf, this, Func);
509 } 682 }
510 683
684 template <> void InstX8632Subps::emitIAS(const Cfg *Func) const {
685 assert(getSrcSize() == 2);
686 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::subps,
687 &x86::AssemblerX86::subps);
688 }
689
511 template <> void InstX8632Subss::emit(const Cfg *Func) const { 690 template <> void InstX8632Subss::emit(const Cfg *Func) const {
512 char buf[30]; 691 char buf[30];
513 snprintf(buf, llvm::array_lengthof(buf), "sub%s", 692 snprintf(buf, llvm::array_lengthof(buf), "sub%s",
514 TypeX8632Attributes[getDest()->getType()].SdSsString); 693 TypeX8632Attributes[getDest()->getType()].SdSsString);
515 emitTwoAddress(buf, this, Func); 694 emitTwoAddress(buf, this, Func);
516 } 695 }
517 696
697 template <> void InstX8632Subss::emitIAS(const Cfg *Func) const {
698 Type Ty = getDest()->getType();
699 assert(getSrcSize() == 2);
700 if (Ty == IceType_f64) {
701 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::subsd,
702 &x86::AssemblerX86::subsd);
703 } else {
704 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::subss,
705 &x86::AssemblerX86::subss);
706 }
707 }
708
518 template <> void InstX8632Psub::emit(const Cfg *Func) const { 709 template <> void InstX8632Psub::emit(const Cfg *Func) const {
519 char buf[30]; 710 char buf[30];
520 snprintf(buf, llvm::array_lengthof(buf), "psub%s", 711 snprintf(buf, llvm::array_lengthof(buf), "psub%s",
521 TypeX8632Attributes[getDest()->getType()].PackString); 712 TypeX8632Attributes[getDest()->getType()].PackString);
522 emitTwoAddress(buf, this, Func); 713 emitTwoAddress(buf, this, Func);
523 } 714 }
524 715
716 template <> void InstX8632Mulps::emitIAS(const Cfg *Func) const {
717 assert(getSrcSize() == 2);
718 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::mulps,
719 &x86::AssemblerX86::mulps);
720 }
721
525 template <> void InstX8632Mulss::emit(const Cfg *Func) const { 722 template <> void InstX8632Mulss::emit(const Cfg *Func) const {
526 char buf[30]; 723 char buf[30];
527 snprintf(buf, llvm::array_lengthof(buf), "mul%s", 724 snprintf(buf, llvm::array_lengthof(buf), "mul%s",
528 TypeX8632Attributes[getDest()->getType()].SdSsString); 725 TypeX8632Attributes[getDest()->getType()].SdSsString);
529 emitTwoAddress(buf, this, Func); 726 emitTwoAddress(buf, this, Func);
530 } 727 }
531 728
729 template <> void InstX8632Mulss::emitIAS(const Cfg *Func) const {
730 Type Ty = getDest()->getType();
731 assert(getSrcSize() == 2);
732 if (Ty == IceType_f64) {
733 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::mulsd,
734 &x86::AssemblerX86::mulsd);
735 } else {
736 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::mulss,
737 &x86::AssemblerX86::mulss);
738 }
739 }
740
532 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const { 741 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const {
533 assert(getSrc(0)->getType() == IceType_v4i32 && 742 assert(getSrc(0)->getType() == IceType_v4i32 &&
534 getSrc(1)->getType() == IceType_v4i32); 743 getSrc(1)->getType() == IceType_v4i32);
535 emitTwoAddress(Opcode, this, Func); 744 emitTwoAddress(Opcode, this, Func);
536 } 745 }
537 746
747 template <> void InstX8632Divps::emitIAS(const Cfg *Func) const {
748 assert(getSrcSize() == 2);
749 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::divps,
750 &x86::AssemblerX86::divps);
751 }
752
538 template <> void InstX8632Divss::emit(const Cfg *Func) const { 753 template <> void InstX8632Divss::emit(const Cfg *Func) const {
539 char buf[30]; 754 char buf[30];
540 snprintf(buf, llvm::array_lengthof(buf), "div%s", 755 snprintf(buf, llvm::array_lengthof(buf), "div%s",
541 TypeX8632Attributes[getDest()->getType()].SdSsString); 756 TypeX8632Attributes[getDest()->getType()].SdSsString);
542 emitTwoAddress(buf, this, Func); 757 emitTwoAddress(buf, this, Func);
543 } 758 }
544 759
760 template <> void InstX8632Divss::emitIAS(const Cfg *Func) const {
761 Type Ty = getDest()->getType();
762 assert(getSrcSize() == 2);
763 if (Ty == IceType_f64) {
764 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::divsd,
765 &x86::AssemblerX86::divsd);
766 } else {
767 emitIASDestSrcXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::divss,
768 &x86::AssemblerX86::divss);
769 }
770 }
771
545 template <> void InstX8632Div::emit(const Cfg *Func) const { 772 template <> void InstX8632Div::emit(const Cfg *Func) const {
546 Ostream &Str = Func->getContext()->getStrEmit(); 773 Ostream &Str = Func->getContext()->getStrEmit();
547 assert(getSrcSize() == 3); 774 assert(getSrcSize() == 3);
548 Str << "\t" << Opcode << "\t"; 775 Str << "\t" << Opcode << "\t";
549 getSrc(1)->emit(Func); 776 getSrc(1)->emit(Func);
550 Str << "\n"; 777 Str << "\n";
551 } 778 }
552 779
553 template <> void InstX8632Idiv::emit(const Cfg *Func) const { 780 template <> void InstX8632Idiv::emit(const Cfg *Func) const {
554 Ostream &Str = Func->getContext()->getStrEmit(); 781 Ostream &Str = Func->getContext()->getStrEmit();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); 859 assert(getDest()->getRegNum() == TargetX8632::Reg_edx);
633 Str << "\tcwd\n"; 860 Str << "\tcwd\n";
634 break; 861 break;
635 case IceType_i32: 862 case IceType_i32:
636 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); 863 assert(getDest()->getRegNum() == TargetX8632::Reg_edx);
637 Str << "\tcdq\n"; 864 Str << "\tcdq\n";
638 break; 865 break;
639 } 866 }
640 } 867 }
641 868
869 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const {
870 Ostream &Str = Func->getContext()->getStrEmit();
871 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
872 intptr_t StartPosition = Asm->GetPosition();
873 assert(getSrcSize() == 1);
874 Operand *Src0 = getSrc(0);
875 assert(llvm::isa<Variable>(Src0));
876 assert(llvm::cast<Variable>(Src0)->getRegNum() == TargetX8632::Reg_eax);
877 switch (Src0->getType()) {
878 default:
879 llvm_unreachable("unexpected source type!");
880 break;
881 case IceType_i8:
882 assert(getDest()->getRegNum() == TargetX8632::Reg_eax);
883 Asm->cbw();
884 break;
885 case IceType_i16:
886 assert(getDest()->getRegNum() == TargetX8632::Reg_edx);
887 Asm->cwd();
888 break;
889 case IceType_i32:
890 assert(getDest()->getRegNum() == TargetX8632::Reg_edx);
891 Asm->cdq();
892 break;
893 }
894 emitIASBytes(Str, Asm, StartPosition);
895 }
896
642 void InstX8632Mul::emit(const Cfg *Func) const { 897 void InstX8632Mul::emit(const Cfg *Func) const {
643 Ostream &Str = Func->getContext()->getStrEmit(); 898 Ostream &Str = Func->getContext()->getStrEmit();
644 assert(getSrcSize() == 2); 899 assert(getSrcSize() == 2);
645 assert(llvm::isa<Variable>(getSrc(0))); 900 assert(llvm::isa<Variable>(getSrc(0)));
646 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == 901 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() ==
647 TargetX8632::Reg_eax); 902 TargetX8632::Reg_eax);
648 assert(getDest()->getRegNum() == TargetX8632::Reg_eax); // TODO: allow edx? 903 assert(getDest()->getRegNum() == TargetX8632::Reg_eax); // TODO: allow edx?
649 Str << "\tmul\t"; 904 Str << "\tmul\t";
650 getSrc(1)->emit(Func); 905 getSrc(1)->emit(Func);
651 Str << "\n"; 906 Str << "\n";
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 Str << "\t"; 970 Str << "\t";
716 assert(Condition != Br_None); 971 assert(Condition != Br_None);
717 assert(getDest()->hasReg()); 972 assert(getDest()->hasReg());
718 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; 973 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t";
719 getDest()->emit(Func); 974 getDest()->emit(Func);
720 Str << ", "; 975 Str << ", ";
721 getSrc(1)->emit(Func); 976 getSrc(1)->emit(Func);
722 Str << "\n"; 977 Str << "\n";
723 } 978 }
724 979
980 void InstX8632Cmov::emitIAS(const Cfg *Func) const {
981 Ostream &Str = Func->getContext()->getStrEmit();
982 assert(Condition != Br_None);
983 assert(getDest()->hasReg());
984 assert(getSrcSize() == 2);
985 const Variable *Src = llvm::cast<Variable>(getSrc(1));
986 // Only need the 32-bit register form right now.
987 assert(Src->hasReg());
988 assert(Src->getType() == IceType_i32);
989 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
990 intptr_t StartPosition = Asm->GetPosition();
991 Asm->cmov(convertToAsmCondition(Condition),
992 convertToAsmGPR(getDest()->getRegNum()),
993 convertToAsmGPR(Src->getRegNum()));
994 emitIASBytes(Str, Asm, StartPosition);
995 }
996
725 void InstX8632Cmov::dump(const Cfg *Func) const { 997 void InstX8632Cmov::dump(const Cfg *Func) const {
726 Ostream &Str = Func->getContext()->getStrDump(); 998 Ostream &Str = Func->getContext()->getStrDump();
727 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; 999 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << ".";
728 Str << getDest()->getType() << " "; 1000 Str << getDest()->getType() << " ";
729 dumpDest(Func); 1001 dumpDest(Func);
730 Str << ", "; 1002 Str << ", ";
731 dumpSources(Func); 1003 dumpSources(Func);
732 } 1004 }
733 1005
734 void InstX8632Cmpps::emit(const Cfg *Func) const { 1006 void InstX8632Cmpps::emit(const Cfg *Func) const {
735 Ostream &Str = Func->getContext()->getStrEmit(); 1007 Ostream &Str = Func->getContext()->getStrEmit();
736 assert(getSrcSize() == 2); 1008 assert(getSrcSize() == 2);
737 assert(Condition < Cmpps_Invalid); 1009 assert(Condition < Cmpps_Invalid);
738 Str << "\t"; 1010 Str << "\t";
739 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1011 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
740 << "\t"; 1012 << "\t";
741 getDest()->emit(Func); 1013 getDest()->emit(Func);
742 Str << ", "; 1014 Str << ", ";
743 getSrc(1)->emit(Func); 1015 getSrc(1)->emit(Func);
744 Str << "\n"; 1016 Str << "\n";
745 } 1017 }
746 1018
1019 void InstX8632Cmpps::emitIAS(const Cfg *Func) const {
1020 Ostream &Str = Func->getContext()->getStrEmit();
1021 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1022 intptr_t StartPosition = Asm->GetPosition();
1023 assert(getSrcSize() == 2);
1024 assert(Condition < Cmpps_Invalid);
1025 // Assuming there isn't any load folding for cmpps, and vector constants
1026 // are not allowed in PNaCl.
1027 assert(llvm::isa<Variable>(getSrc(1)));
1028 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1));
1029 if (SrcVar->hasReg()) {
1030 Asm->cmpps(convertToAsmXMMReg(getDest()->getRegNum()),
1031 convertToAsmXMMReg(SrcVar->getRegNum()), Condition);
1032 } else {
1033 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
1034 ->stackVarToAsmOperand(SrcVar);
1035 Asm->cmpps(convertToAsmXMMReg(getDest()->getRegNum()), SrcStackAddr,
1036 Condition);
1037 }
1038 emitIASBytes(Str, Asm, StartPosition);
1039 }
1040
747 void InstX8632Cmpps::dump(const Cfg *Func) const { 1041 void InstX8632Cmpps::dump(const Cfg *Func) const {
748 Ostream &Str = Func->getContext()->getStrDump(); 1042 Ostream &Str = Func->getContext()->getStrDump();
749 assert(Condition < Cmpps_Invalid); 1043 assert(Condition < Cmpps_Invalid);
750 dumpDest(Func); 1044 dumpDest(Func);
751 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1045 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
752 << "\t"; 1046 << "\t";
753 dumpSources(Func); 1047 dumpSources(Func);
754 } 1048 }
755 1049
756 void InstX8632Cmpxchg::emit(const Cfg *Func) const { 1050 void InstX8632Cmpxchg::emit(const Cfg *Func) const {
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 // value between a vector and a scalar (which movss is used for). 1284 // value between a vector and a scalar (which movss is used for).
991 // Clean this up. 1285 // Clean this up.
992 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == 1286 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) ==
993 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); 1287 Func->getTarget()->typeWidthInBytesOnStack(Src->getType()));
994 getDest()->asType(Src->getType()).emit(Func); 1288 getDest()->asType(Src->getType()).emit(Func);
995 Str << ", "; 1289 Str << ", ";
996 Src->emit(Func); 1290 Src->emit(Func);
997 Str << "\n"; 1291 Str << "\n";
998 } 1292 }
999 1293
1294 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const {
1295 // Could be movss/sd, or movb/movw/movl.
1296 emit(Func);
1297 }
1298
1000 template <> void InstX8632Movp::emit(const Cfg *Func) const { 1299 template <> void InstX8632Movp::emit(const Cfg *Func) const {
1001 // TODO(wala,stichnot): movups works with all vector operands, but 1300 // TODO(wala,stichnot): movups works with all vector operands, but
1002 // there exist other instructions (movaps, movdqa, movdqu) that may 1301 // there exist other instructions (movaps, movdqa, movdqu) that may
1003 // perform better, depending on the data type and alignment of the 1302 // perform better, depending on the data type and alignment of the
1004 // operands. 1303 // operands.
1005 Ostream &Str = Func->getContext()->getStrEmit(); 1304 Ostream &Str = Func->getContext()->getStrEmit();
1006 assert(getSrcSize() == 1); 1305 assert(getSrcSize() == 1);
1007 Str << "\tmovups\t"; 1306 Str << "\tmovups\t";
1008 getDest()->emit(Func); 1307 getDest()->emit(Func);
1009 Str << ", "; 1308 Str << ", ";
1010 getSrc(0)->emit(Func); 1309 getSrc(0)->emit(Func);
1011 Str << "\n"; 1310 Str << "\n";
1012 } 1311 }
1013 1312
1014 template <> void InstX8632Movq::emit(const Cfg *Func) const { 1313 template <> void InstX8632Movq::emit(const Cfg *Func) const {
1015 Ostream &Str = Func->getContext()->getStrEmit(); 1314 Ostream &Str = Func->getContext()->getStrEmit();
1016 assert(getSrcSize() == 1); 1315 assert(getSrcSize() == 1);
1017 assert(getDest()->getType() == IceType_i64 || 1316 assert(getDest()->getType() == IceType_i64 ||
1018 getDest()->getType() == IceType_f64); 1317 getDest()->getType() == IceType_f64);
1019 Str << "\tmovq\t"; 1318 Str << "\tmovq\t";
1020 getDest()->emit(Func); 1319 getDest()->emit(Func);
1021 Str << ", "; 1320 Str << ", ";
1022 getSrc(0)->emit(Func); 1321 getSrc(0)->emit(Func);
1023 Str << "\n"; 1322 Str << "\n";
1024 } 1323 }
1025 1324
1325 static void emitIASSignZeroExt(const Cfg *Func, const Variable *Dest,
1326 const Operand *Src0,
1327 x86::AssemblerX86::EmitRegByteR EmitByte,
1328 x86::AssemblerX86::EmitRegReg EmitWord,
1329 x86::AssemblerX86::EmitRegAddr EmitAddress) {
1330 Ostream &Str = Func->getContext()->getStrEmit();
1331 assert(Dest->hasReg());
1332 x86::Register DestReg = convertToAsmGPR(Dest->getRegNum());
1333 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1334 intptr_t StartPosition = Asm->GetPosition();
1335 IceString SymbolicOffset = "";
1336 Type SrcType = Src0->getType();
1337 // Source is ByteReg, WordReg, or stack slot, or other memory operand.
1338 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src0)) {
1339 if (SrcVar->hasReg()) {
1340 if (SrcType == IceType_i8 || SrcType == IceType_i1) {
1341 (Asm->*EmitByte)(DestReg,
1342 convertToAsmByteRegister(SrcVar->getRegNum()));
1343 } else {
1344 assert(SrcType == IceType_i16);
1345 (Asm->*EmitWord)(DestReg, convertToAsmGPR(SrcVar->getRegNum()));
1346 }
1347 } else {
1348 x86::Address StackAddr = static_cast<TargetX8632 *>(Func->getTarget())
1349 ->stackVarToAsmOperand(SrcVar);
1350 (Asm->*EmitAddress)(DestReg, StackAddr);
1351 }
1352 } else if (const OperandX8632Mem *Mem =
1353 llvm::dyn_cast<OperandX8632Mem>(Src0)) {
1354 x86::Address SrcAddr = Mem->convertToAsmAddress(SymbolicOffset);
1355 (Asm->*EmitAddress)(DestReg, SrcAddr);
1356 } else {
1357 llvm_unreachable("Unexpected operand type for Movzx");
1358 }
1359
1360 if (!SymbolicOffset.empty()) {
1361 emitIASBytesRelocatable(Str, Func->getAssembler<x86::AssemblerX86>(),
1362 StartPosition, SymbolicOffset);
1363 } else {
1364 emitIASBytes(Str, Func->getAssembler<x86::AssemblerX86>(), StartPosition);
1365 }
1366 }
1367
1026 void InstX8632Movsx::emit(const Cfg *Func) const { 1368 void InstX8632Movsx::emit(const Cfg *Func) const {
1027 Ostream &Str = Func->getContext()->getStrEmit(); 1369 Ostream &Str = Func->getContext()->getStrEmit();
1028 assert(getSrcSize() == 1); 1370 assert(getSrcSize() == 1);
1029 Str << "\tmovsx\t"; 1371 Str << "\tmovsx\t";
1030 getDest()->emit(Func); 1372 getDest()->emit(Func);
1031 Str << ", "; 1373 Str << ", ";
1032 getSrc(0)->emit(Func); 1374 getSrc(0)->emit(Func);
1033 Str << "\n"; 1375 Str << "\n";
1034 } 1376 }
1035 1377
1378 void InstX8632Movsx::emitIAS(const Cfg *Func) const {
1379 assert(getSrcSize() == 1);
1380 const Operand *Src0 = getSrc(0);
1381 Type SrcType = Src0->getType();
1382 if (SrcType == IceType_i8 || SrcType == IceType_i1) {
1383 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movsxb,
1384 &x86::AssemblerX86::movsxw, &x86::AssemblerX86::movsxb);
1385 } else {
1386 assert(SrcType == IceType_i16);
1387 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movsxb,
1388 &x86::AssemblerX86::movsxw, &x86::AssemblerX86::movsxw);
1389 }
1390 }
1391
1036 void InstX8632Movsx::dump(const Cfg *Func) const { 1392 void InstX8632Movsx::dump(const Cfg *Func) const {
1037 Ostream &Str = Func->getContext()->getStrDump(); 1393 Ostream &Str = Func->getContext()->getStrDump();
1038 Str << "movsx." << getDest()->getType() << "." << getSrc(0)->getType(); 1394 Str << "movsx." << getDest()->getType() << "." << getSrc(0)->getType();
1039 Str << " "; 1395 Str << " ";
1040 dumpDest(Func); 1396 dumpDest(Func);
1041 Str << ", "; 1397 Str << ", ";
1042 dumpSources(Func); 1398 dumpSources(Func);
1043 } 1399 }
1044 1400
1045 void InstX8632Movzx::emit(const Cfg *Func) const { 1401 void InstX8632Movzx::emit(const Cfg *Func) const {
1046 Ostream &Str = Func->getContext()->getStrEmit(); 1402 Ostream &Str = Func->getContext()->getStrEmit();
1047 assert(getSrcSize() == 1); 1403 assert(getSrcSize() == 1);
1048 Str << "\tmovzx\t"; 1404 Str << "\tmovzx\t";
1049 getDest()->emit(Func); 1405 getDest()->emit(Func);
1050 Str << ", "; 1406 Str << ", ";
1051 getSrc(0)->emit(Func); 1407 getSrc(0)->emit(Func);
1052 Str << "\n"; 1408 Str << "\n";
1053 } 1409 }
1054 1410
1411 void InstX8632Movzx::emitIAS(const Cfg *Func) const {
1412 assert(getSrcSize() == 1);
1413 const Operand *Src0 = getSrc(0);
1414 Type SrcType = Src0->getType();
1415 if (SrcType == IceType_i8 || SrcType == IceType_i1) {
1416 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movzxb,
1417 &x86::AssemblerX86::movzxw, &x86::AssemblerX86::movzxb);
1418 } else {
1419 assert(SrcType == IceType_i16);
1420 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movzxb,
1421 &x86::AssemblerX86::movzxw, &x86::AssemblerX86::movzxw);
1422 }
1423 }
1424
1055 void InstX8632Movzx::dump(const Cfg *Func) const { 1425 void InstX8632Movzx::dump(const Cfg *Func) const {
1056 Ostream &Str = Func->getContext()->getStrDump(); 1426 Ostream &Str = Func->getContext()->getStrDump();
1057 Str << "movzx." << getDest()->getType() << "." << getSrc(0)->getType(); 1427 Str << "movzx." << getDest()->getType() << "." << getSrc(0)->getType();
1058 Str << " "; 1428 Str << " ";
1059 dumpDest(Func); 1429 dumpDest(Func);
1060 Str << ", "; 1430 Str << ", ";
1061 dumpSources(Func); 1431 dumpSources(Func);
1062 } 1432 }
1063 1433
1064 void InstX8632Nop::emit(const Cfg *Func) const { 1434 void InstX8632Nop::emit(const Cfg *Func) const {
1065 Ostream &Str = Func->getContext()->getStrEmit(); 1435 Ostream &Str = Func->getContext()->getStrEmit();
1066 // TODO: Emit the right code for each variant. 1436 // TODO: Emit the right code for each variant.
1067 Str << "\tnop\t# variant = " << Variant << "\n"; 1437 Str << "\tnop\t# variant = " << Variant << "\n";
1068 } 1438 }
1069 1439
1440 void InstX8632Nop::emitIAS(const Cfg *Func) const {
1441 Ostream &Str = Func->getContext()->getStrEmit();
1442 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1443 intptr_t StartPosition = Asm->GetPosition();
1444 // TODO: Emit the right code for the variant.
1445 Asm->nop();
1446 emitIASBytes(Str, Asm, StartPosition);
1447 }
1448
1070 void InstX8632Nop::dump(const Cfg *Func) const { 1449 void InstX8632Nop::dump(const Cfg *Func) const {
1071 Ostream &Str = Func->getContext()->getStrDump(); 1450 Ostream &Str = Func->getContext()->getStrDump();
1072 Str << "nop (variant = " << Variant << ")"; 1451 Str << "nop (variant = " << Variant << ")";
1073 } 1452 }
1074 1453
1075 void InstX8632Fld::emit(const Cfg *Func) const { 1454 void InstX8632Fld::emit(const Cfg *Func) const {
1076 Ostream &Str = Func->getContext()->getStrEmit(); 1455 Ostream &Str = Func->getContext()->getStrEmit();
1077 assert(getSrcSize() == 1); 1456 assert(getSrcSize() == 1);
1078 Type Ty = getSrc(0)->getType(); 1457 Type Ty = getSrc(0)->getType();
1079 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); 1458 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0));
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 Src1->emit(Func); 1573 Src1->emit(Func);
1195 } 1574 }
1196 Str << ", "; 1575 Str << ", ";
1197 getSrc(2)->emit(Func); 1576 getSrc(2)->emit(Func);
1198 Str << "\n"; 1577 Str << "\n";
1199 } 1578 }
1200 1579
1201 void InstX8632Pop::emit(const Cfg *Func) const { 1580 void InstX8632Pop::emit(const Cfg *Func) const {
1202 Ostream &Str = Func->getContext()->getStrEmit(); 1581 Ostream &Str = Func->getContext()->getStrEmit();
1203 assert(getSrcSize() == 0); 1582 assert(getSrcSize() == 0);
1583 assert(getDest()->getType() == IceType_i32);
1204 Str << "\tpop\t"; 1584 Str << "\tpop\t";
1205 getDest()->emit(Func); 1585 getDest()->emit(Func);
1206 Str << "\n"; 1586 Str << "\n";
1207 } 1587 }
1208 1588
1589 void InstX8632Pop::emitIAS(const Cfg *Func) const {
1590 Ostream &Str = Func->getContext()->getStrEmit();
1591 assert(getSrcSize() == 0);
1592 assert(getDest()->getType() == IceType_i32);
1593 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1594 intptr_t StartPosition = Asm->GetPosition();
1595 if (getDest()->hasReg()) {
1596 Asm->popl(convertToAsmGPR(getDest()->getRegNum()));
1597 } else {
1598 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget())
1599 ->stackVarToAsmOperand(getDest()));
1600 }
1601 emitIASBytes(Str, Asm, StartPosition);
1602 }
1603
1209 void InstX8632Pop::dump(const Cfg *Func) const { 1604 void InstX8632Pop::dump(const Cfg *Func) const {
1210 Ostream &Str = Func->getContext()->getStrDump(); 1605 Ostream &Str = Func->getContext()->getStrDump();
1211 dumpDest(Func); 1606 dumpDest(Func);
1212 Str << " = pop." << getDest()->getType() << " "; 1607 Str << " = pop." << getDest()->getType() << " ";
1213 } 1608 }
1214 1609
1215 void InstX8632AdjustStack::emit(const Cfg *Func) const { 1610 void InstX8632AdjustStack::emit(const Cfg *Func) const {
1216 Ostream &Str = Func->getContext()->getStrEmit(); 1611 Ostream &Str = Func->getContext()->getStrEmit();
1217 Str << "\tsub\tesp, " << Amount << "\n"; 1612 Str << "\tsub\tesp, " << Amount << "\n";
1218 Func->getTarget()->updateStackAdjustment(Amount); 1613 Func->getTarget()->updateStackAdjustment(Amount);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 snprintf(buf, llvm::array_lengthof(buf), "psra%s", 1678 snprintf(buf, llvm::array_lengthof(buf), "psra%s",
1284 TypeX8632Attributes[getDest()->getType()].PackString); 1679 TypeX8632Attributes[getDest()->getType()].PackString);
1285 emitTwoAddress(buf, this, Func); 1680 emitTwoAddress(buf, this, Func);
1286 } 1681 }
1287 1682
1288 void InstX8632Ret::emit(const Cfg *Func) const { 1683 void InstX8632Ret::emit(const Cfg *Func) const {
1289 Ostream &Str = Func->getContext()->getStrEmit(); 1684 Ostream &Str = Func->getContext()->getStrEmit();
1290 Str << "\tret\n"; 1685 Str << "\tret\n";
1291 } 1686 }
1292 1687
1688 void InstX8632Ret::emitIAS(const Cfg *Func) const {
1689 Ostream &Str = Func->getContext()->getStrEmit();
1690 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1691 intptr_t StartPosition = Asm->GetPosition();
1692 Asm->ret();
1693 emitIASBytes(Str, Asm, StartPosition);
1694 }
1695
1293 void InstX8632Ret::dump(const Cfg *Func) const { 1696 void InstX8632Ret::dump(const Cfg *Func) const {
1294 Ostream &Str = Func->getContext()->getStrDump(); 1697 Ostream &Str = Func->getContext()->getStrDump();
1295 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); 1698 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType());
1296 Str << "ret." << Ty << " "; 1699 Str << "ret." << Ty << " ";
1297 dumpSources(Func); 1700 dumpSources(Func);
1298 } 1701 }
1299 1702
1300 void InstX8632Xadd::emit(const Cfg *Func) const { 1703 void InstX8632Xadd::emit(const Cfg *Func) const {
1301 Ostream &Str = Func->getContext()->getStrEmit(); 1704 Ostream &Str = Func->getContext()->getStrEmit();
1302 if (Locked) { 1705 if (Locked) {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 Str << "+"; 1822 Str << "+";
1420 Offset->dump(Func); 1823 Offset->dump(Func);
1421 } 1824 }
1422 } else { 1825 } else {
1423 // There is only the offset. 1826 // There is only the offset.
1424 Offset->dump(Func); 1827 Offset->dump(Func);
1425 } 1828 }
1426 Str << "]"; 1829 Str << "]";
1427 } 1830 }
1428 1831
1832 x86::Address
1833 OperandX8632Mem::convertToAsmAddress(IceString &SymbolicOffset) const {
1834 int32_t Disp = 0;
1835 // Determine the offset (is it relocatable?)
1836 if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(getOffset())) {
1837 // Should there be a subclass of ConstantInteger that is just int32_t?
1838 assert(Utils::IsInt<int64_t>(32, CI->getValue()));
1839 Disp = static_cast<int32_t>(CI->getValue());
1840 } else if (ConstantRelocatable *CR =
1841 llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
1842 SymbolicOffset = CR->getName();
1843 assert(CR->getOffset() == 0 && "Not yet handling Reloc + offset");
1844 }
1845
1846 // Now convert to the various possible forms.
1847 if (getBase() && getIndex()) {
1848 return x86::Address(convertToAsmGPR(getBase()->getRegNum()),
1849 convertToAsmGPR(getIndex()->getRegNum()),
1850 x86::ScaleFactor(getShift()), Disp);
1851 } else if (getBase()) {
1852 return x86::Address(convertToAsmGPR(getBase()->getRegNum()), Disp);
1853 } else if (getIndex()) {
1854 return x86::Address(convertToAsmGPR(getIndex()->getRegNum()),
1855 x86::ScaleFactor(getShift()), Disp);
1856 } else {
1857 assert(!SymbolicOffset.empty() && Disp == 0 &&
1858 "Remaining case is symbolic offset...");
1859 return x86::Address::Absolute(Disp);
1860 }
1861 }
1862
1429 void VariableSplit::emit(const Cfg *Func) const { 1863 void VariableSplit::emit(const Cfg *Func) const {
1430 Ostream &Str = Func->getContext()->getStrEmit(); 1864 Ostream &Str = Func->getContext()->getStrEmit();
1431 assert(Var->getLocalUseNode() == NULL || 1865 assert(Var->getLocalUseNode() == NULL ||
1432 Var->getLocalUseNode() == Func->getCurrentNode()); 1866 Var->getLocalUseNode() == Func->getCurrentNode());
1433 assert(!Var->hasReg()); 1867 assert(!Var->hasReg());
1434 // The following is copied/adapted from TargetX8632::emitVariable(). 1868 // The following is copied/adapted from TargetX8632::emitVariable().
1435 const TargetLowering *Target = Func->getTarget(); 1869 const TargetLowering *Target = Func->getTarget();
1436 const Type Ty = IceType_i32; 1870 const Type Ty = IceType_i32;
1437 Str << TypeX8632Attributes[Ty].WidthString << " [" 1871 Str << TypeX8632Attributes[Ty].WidthString << " ["
1438 << Target->getRegName(Target->getFrameOrStackReg(), Ty); 1872 << Target->getRegName(Target->getFrameOrStackReg(), Ty);
(...skipping 20 matching lines...) Expand all
1459 default: 1893 default:
1460 Str << "???"; 1894 Str << "???";
1461 break; 1895 break;
1462 } 1896 }
1463 Str << "("; 1897 Str << "(";
1464 Var->dump(Func); 1898 Var->dump(Func);
1465 Str << ")"; 1899 Str << ")";
1466 } 1900 }
1467 1901
1468 } // end of namespace Ice 1902 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceInstX8632.def » ('j') | src/IceUtils.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698