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

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: make fixups part of address 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
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceInstX8632.def » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 return x86::Register(RegNum);
74 }
75
76 x86::ByteRegister convertToAsmByteRegister(int32_t RegNum) {
77 if (RegNum == TargetX8632::Reg_ah) {
78 return x86::AH;
79 }
80 assert(TargetX8632::Reg_eax <= RegNum && RegNum <= TargetX8632::Reg_ebx);
81 return x86::ByteRegister(RegNum);
82 }
83
84 x86::Immediate convertIntImmToAsmImm(const ConstantInteger32 *CI) {
85 int32_t V = static_cast<int32_t>(CI->getValue());
86 return x86::Immediate(V);
87 }
88
89 x86::XmmRegister convertToAsmXMMReg(int32_t RegNum) {
90 assert(TargetX8632::Reg_xmm0 <= RegNum && RegNum <= TargetX8632::Reg_xmm7);
91 return x86::XmmRegister(RegNum - TargetX8632::Reg_xmm0);
92 }
93
94 // Convert a float or double immediate to an Address Operand.
95 x86::Address convertFloatImmToAsmAddr(GlobalContext *Ctx, Assembler *Asm,
96 const Constant *Imm) {
97 std::string Buffer;
98 llvm::raw_string_ostream StrBuf(Buffer);
99 Type Ty = Imm->getType();
100 assert(llvm::isa<ConstantFloat>(Imm) || llvm::isa<ConstantDouble>(Imm));
101 StrBuf << "L$" << Ty << "$" << Imm->getPoolEntryID();
102 const int64_t Offset = 0;
103 const bool SuppressMangling = true;
104 Constant *Sym =
105 Ctx->getConstantSym(Ty, Offset, StrBuf.str(), SuppressMangling);
106 AssemblerFixup *Fixup = x86::DisplacementRelocation::create(
107 Asm, FK_Abs_4, llvm::cast<ConstantRelocatable>(Sym));
108 return x86::Address::Absolute(Offset, Fixup);
109 }
110
66 } // end of anonymous namespace 111 } // end of anonymous namespace
67 112
68 const char *InstX8632::getWidthString(Type Ty) { 113 const char *InstX8632::getWidthString(Type Ty) {
69 return TypeX8632Attributes[Ty].WidthString; 114 return TypeX8632Attributes[Ty].WidthString;
70 } 115 }
71 116
72 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, 117 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base,
73 Constant *Offset, Variable *Index, 118 Constant *Offset, Variable *Index,
74 uint16_t Shift, SegmentRegisters SegmentReg) 119 uint16_t Shift, SegmentRegisters SegmentReg)
75 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), 120 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index),
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 } 323 }
279 324
280 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source) 325 InstX8632Xchg::InstX8632Xchg(Cfg *Func, Operand *Dest, Variable *Source)
281 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) { 326 : InstX8632(Func, InstX8632::Xchg, 2, llvm::dyn_cast<Variable>(Dest)) {
282 addSource(Dest); 327 addSource(Dest);
283 addSource(Source); 328 addSource(Source);
284 } 329 }
285 330
286 // ======================== Dump routines ======================== // 331 // ======================== Dump routines ======================== //
287 332
333 namespace {
334
335 void emitIASBytes(Ostream &Str, const x86::AssemblerX86 *Asm,
336 intptr_t StartPosition) {
337 intptr_t EndPosition = Asm->GetPosition();
338 intptr_t LastFixupLoc = -1;
339 AssemblerFixup *LastFixup = NULL;
340 if (Asm->GetLatestFixup()) {
341 LastFixup = Asm->GetLatestFixup();
342 LastFixupLoc = LastFixup->position();
343 }
344 if (LastFixupLoc < StartPosition) {
345 // The fixup doesn't apply to this current block.
346 for (intptr_t i = 0; i < EndPosition - StartPosition; ++i) {
347 Str << "\t.byte "
348 << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(StartPosition + i))
349 << "\n";
350 }
351 return;
352 }
353 const intptr_t FixupSize = 4;
354 assert(LastFixupLoc + FixupSize <= EndPosition);
355 // The fixup does apply to this current block.
356 for (intptr_t i = 0; i < LastFixupLoc - StartPosition; ++i) {
357 Str << "\t.byte "
358 << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(StartPosition + i))
359 << "\n";
360 }
361 Str << "\t.long " << LastFixup->value()->getName();
362 if (LastFixup->value()->getOffset()) {
363 Str << " + " << LastFixup->value()->getOffset();
364 }
365 Str << "\n";
366 for (intptr_t i = LastFixupLoc + FixupSize; i < EndPosition; ++i) {
367 Str << "\t.byte " << static_cast<uint32_t>(Asm->LoadBuffer<uint8_t>(i))
368 << "\n";
369 }
370 }
371
372 void emitIASTwoOperandGPR(const Cfg *Func, const Operand *Src0,
373 const Operand *Src1,
374 x86::AssemblerX86::EmitTyRegReg EmitRegReg,
375 x86::AssemblerX86::EmitTyRegAddr EmitRegAddr,
376 x86::AssemblerX86::EmitTyRegImm EmitRegImm,
377 x86::AssemblerX86::EmitTyAddrReg EmitAddrReg = NULL,
378 x86::AssemblerX86::EmitTyAddrImm EmitAddrImm = NULL) {
379 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
380 intptr_t StartPosition = Asm->GetPosition();
381 Type Ty = Src0->getType();
382
383 // Classify Src0 (Reg or Mem).
384 bool Src0IsReg = false;
385 x86::Register Src0Reg = x86::kNoRegister;
386 x86::Address Src0Addr = x86::Address::Absolute(0, NULL);
387 if (const Variable *Src0Var = llvm::dyn_cast<Variable>(Src0)) {
388 if (Src0Var->hasReg()) {
389 Src0IsReg = true;
390 if (typeWidthInBytes(Ty) == 1) {
391 Src0Reg =
392 convertToAsmGPR(convertToAsmByteRegister(Src0Var->getRegNum()));
393 } else {
394 Src0Reg = convertToAsmGPR(Src0Var->getRegNum());
395 }
396 } else {
397 Src0Addr = static_cast<TargetX8632 *>(Func->getTarget())
398 ->stackVarToAsmOperand(Src0Var);
399 }
400 } else if (const OperandX8632Mem *Mem =
401 llvm::dyn_cast<OperandX8632Mem>(Src0)) {
402 assert(EmitAddrReg != NULL && EmitAddrImm != NULL);
403 Src0Addr = Mem->convertToAsmAddress(Asm);
404 }
405
406 // Classify Src1 (Reg, Mem, or Imm).
407 if (const Variable *Src1Var = llvm::dyn_cast<Variable>(Src1)) {
408 if (Src1Var->hasReg()) {
409 x86::Register Src1Reg;
410 if (typeWidthInBytes(Ty) == 1) {
411 Src1Reg =
412 convertToAsmGPR(convertToAsmByteRegister(Src1Var->getRegNum()));
413 } else {
414 Src1Reg = convertToAsmGPR(Src1Var->getRegNum());
415 }
416 if (Src0IsReg)
417 (Asm->*EmitRegReg)(Ty, Src0Reg, Src1Reg);
418 else
419 (Asm->*EmitAddrReg)(Ty, Src0Addr, Src1Reg);
420 } else {
421 x86::Address Src1Addr = static_cast<TargetX8632 *>(Func->getTarget())
422 ->stackVarToAsmOperand(Src1Var);
423 assert(Src0IsReg);
424 (Asm->*EmitRegAddr)(Ty, Src0Reg, Src1Addr);
425 }
426 } else if (const OperandX8632Mem *Mem =
427 llvm::dyn_cast<OperandX8632Mem>(Src1)) {
428 x86::Address Src1Addr = Mem->convertToAsmAddress(Asm);
429 assert(Src0IsReg);
430 (Asm->*EmitRegAddr)(Ty, Src0Reg, Src1Addr);
431 } else if (const ConstantInteger32 *CI =
432 llvm::dyn_cast<ConstantInteger32>(Src1)) {
433 x86::Immediate Imm = convertIntImmToAsmImm(CI);
434 if (Src0IsReg)
435 (Asm->*EmitRegImm)(Ty, Src0Reg, Imm);
436 else
437 (Asm->*EmitAddrImm)(Ty, Src0Addr, Imm);
438 } else {
439 llvm_unreachable("Unexpected operand type");
440 }
441 Ostream &Str = Func->getContext()->getStrEmit();
442 emitIASBytes(Str, Asm, StartPosition);
443 }
444
445 void emitIASVarOperandXMM(const Cfg *Func, const Variable *Var,
446 const Operand *Src,
447 x86::AssemblerX86::EmitXmmXmm EmitXmmXmm,
448 x86::AssemblerX86::EmitXmmAddr EmitXmmAddr) {
449 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
450 intptr_t StartPosition = Asm->GetPosition();
451 assert(Var->hasReg());
452 x86::XmmRegister VarReg = convertToAsmXMMReg(Var->getRegNum());
453 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src)) {
454 if (SrcVar->hasReg()) {
455 x86::XmmRegister SrcReg = convertToAsmXMMReg(SrcVar->getRegNum());
456 (Asm->*EmitXmmXmm)(VarReg, SrcReg);
457 } else {
458 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
459 ->stackVarToAsmOperand(SrcVar);
460 (Asm->*EmitXmmAddr)(VarReg, SrcStackAddr);
461 }
462 } else if (const OperandX8632Mem *Mem =
463 llvm::dyn_cast<OperandX8632Mem>(Src)) {
464 x86::Address SrcAddr = Mem->convertToAsmAddress(Asm);
465 (Asm->*EmitXmmAddr)(VarReg, SrcAddr);
466 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src)) {
467 (Asm->*EmitXmmAddr)(VarReg,
468 convertFloatImmToAsmAddr(Func->getContext(), Asm, Imm));
469 } else {
470 llvm_unreachable("Unexpected operand type");
471 }
472 Ostream &Str = Func->getContext()->getStrEmit();
473 emitIASBytes(Str, Asm, StartPosition);
474 }
475
476 void
477 emitIASTwoOperandTyXMM(const Cfg *Func, Type Ty, const Operand *Src0,
478 const Operand *Src1,
479 x86::AssemblerX86::EmitTyXmmXmm EmitXmmXmm,
480 x86::AssemblerX86::EmitTyXmmAddr EmitXmmAddr,
481 x86::AssemblerX86::EmitTyAddrXmm EmitAddrXmm = NULL) {
482 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
483 intptr_t StartPosition = Asm->GetPosition();
484
485 // Classify Src0 (Reg or Mem).
486 bool Src0IsReg = false;
487 x86::XmmRegister Src0Reg = x86::kNoXmmRegister;
488 x86::Address Src0Addr = x86::Address::Absolute(0, NULL);
489 if (const Variable *Src0Var = llvm::dyn_cast<Variable>(Src0)) {
490 if (Src0Var->hasReg()) {
491 Src0IsReg = true;
492 Src0Reg = convertToAsmXMMReg(Src0Var->getRegNum());
493 } else {
494 Src0Addr = static_cast<TargetX8632 *>(Func->getTarget())
495 ->stackVarToAsmOperand(Src0Var);
496 }
497 } else if (const OperandX8632Mem *Mem =
498 llvm::dyn_cast<OperandX8632Mem>(Src0)) {
499 assert(EmitAddrXmm != NULL);
500 Src0Addr = Mem->convertToAsmAddress(Asm);
501 }
502
503 if (const Variable *Src1Var = llvm::dyn_cast<Variable>(Src1)) {
504 if (Src1Var->hasReg()) {
505 x86::XmmRegister Src1Reg = convertToAsmXMMReg(Src1Var->getRegNum());
506 if (Src0IsReg) {
507 (Asm->*EmitXmmXmm)(Ty, Src0Reg, Src1Reg);
508 } else {
509 (Asm->*EmitAddrXmm)(Ty, Src0Addr, Src1Reg);
510 }
511 } else {
512 x86::Address Src1StackAddr = static_cast<TargetX8632 *>(Func->getTarget())
513 ->stackVarToAsmOperand(Src1Var);
514 assert(Src0IsReg);
515 (Asm->*EmitXmmAddr)(Ty, Src0Reg, Src1StackAddr);
516 }
517 } else if (const OperandX8632Mem *Mem =
518 llvm::dyn_cast<OperandX8632Mem>(Src1)) {
519 x86::Address Src1Addr = Mem->convertToAsmAddress(Asm);
520 assert(Src0IsReg);
521 (Asm->*EmitXmmAddr)(Ty, Src0Reg, Src1Addr);
522 } else if (const Constant *Imm = llvm::dyn_cast<Constant>(Src1)) {
523 assert(Src0IsReg);
524 (Asm->*EmitXmmAddr)(Ty, Src0Reg,
525 convertFloatImmToAsmAddr(Func->getContext(), Asm, Imm));
526 } else {
527 llvm_unreachable("Unexpected operand type");
528 }
529 Ostream &Str = Func->getContext()->getStrEmit();
530 emitIASBytes(Str, Asm, StartPosition);
531 }
532
533 } // end of anonymous namespace
534
288 void InstX8632::dump(const Cfg *Func) const { 535 void InstX8632::dump(const Cfg *Func) const {
289 Ostream &Str = Func->getContext()->getStrDump(); 536 Ostream &Str = Func->getContext()->getStrDump();
290 Str << "[X8632] "; 537 Str << "[X8632] ";
291 Inst::dump(Func); 538 Inst::dump(Func);
292 } 539 }
293 540
541 void InstX8632::emitIAS(const Cfg *Func) const { emit(Func); }
542
294 void InstX8632Label::emit(const Cfg *Func) const { 543 void InstX8632Label::emit(const Cfg *Func) const {
295 Ostream &Str = Func->getContext()->getStrEmit(); 544 Ostream &Str = Func->getContext()->getStrEmit();
296 Str << getName(Func) << ":\n"; 545 Str << getName(Func) << ":\n";
297 } 546 }
298 547
299 void InstX8632Label::dump(const Cfg *Func) const { 548 void InstX8632Label::dump(const Cfg *Func) const {
300 Ostream &Str = Func->getContext()->getStrDump(); 549 Ostream &Str = Func->getContext()->getStrDump();
301 Str << getName(Func) << ":"; 550 Str << getName(Func) << ":";
302 } 551 }
303 552
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 597
349 void InstX8632Call::emit(const Cfg *Func) const { 598 void InstX8632Call::emit(const Cfg *Func) const {
350 Ostream &Str = Func->getContext()->getStrEmit(); 599 Ostream &Str = Func->getContext()->getStrEmit();
351 assert(getSrcSize() == 1); 600 assert(getSrcSize() == 1);
352 Str << "\tcall\t"; 601 Str << "\tcall\t";
353 getCallTarget()->emit(Func); 602 getCallTarget()->emit(Func);
354 Str << "\n"; 603 Str << "\n";
355 Func->getTarget()->resetStackAdjustment(); 604 Func->getTarget()->resetStackAdjustment();
356 } 605 }
357 606
607 void InstX8632Call::emitIAS(const Cfg *Func) const {
608 Ostream &Str = Func->getContext()->getStrEmit();
609 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
610 intptr_t StartPosition = Asm->GetPosition();
611 Operand *Target = getCallTarget();
612 bool NeedsFallback = false;
613 if (Variable *Var = llvm::dyn_cast<Variable>(Target)) {
614 if (Var->hasReg()) {
615 Asm->call(convertToAsmGPR(Var->getRegNum()));
616 } else {
617 Asm->call(static_cast<TargetX8632 *>(Func->getTarget())
618 ->stackVarToAsmOperand(Var));
619 }
620 } else if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) {
621 Asm->call(Mem->convertToAsmAddress(Asm));
622 } else if (ConstantRelocatable *CR =
623 llvm::dyn_cast<ConstantRelocatable>(Target)) {
624 assert(CR->getOffset() == 0 && "We only support calling a function");
625 Asm->call(CR);
626 NeedsFallback = true;
627 }
628 if (NeedsFallback) {
629 // TODO(jvoung): This .byte and .long hack doesn't work, since we need
630 // a pc-rel relocation, and we also need the section contents to be
631 // -4 instead of 0.
632 //
633 // Still, we have at least filled the assembler buffer so that the
634 // instruction sizes/positions are correct for jumps.
635 //
636 // For now, fall back to the regular .s emission.
637 emit(Func);
638 } else {
639 emitIASBytes(Str, Asm, StartPosition);
640 }
641 Func->getTarget()->resetStackAdjustment();
642 }
643
358 void InstX8632Call::dump(const Cfg *Func) const { 644 void InstX8632Call::dump(const Cfg *Func) const {
359 Ostream &Str = Func->getContext()->getStrDump(); 645 Ostream &Str = Func->getContext()->getStrDump();
360 if (getDest()) { 646 if (getDest()) {
361 dumpDest(Func); 647 dumpDest(Func);
362 Str << " = "; 648 Str << " = ";
363 } 649 }
364 Str << "call "; 650 Str << "call ";
365 getCallTarget()->dump(Func); 651 getCallTarget()->dump(Func);
366 } 652 }
367 653
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 assert(getSrcSize() == 1); 757 assert(getSrcSize() == 1);
472 Type Ty = getSrc(0)->getType(); 758 Type Ty = getSrc(0)->getType();
473 assert(Ty == IceType_f32 || Ty == IceType_f64); 759 assert(Ty == IceType_f32 || Ty == IceType_f64);
474 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; 760 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t";
475 getDest()->emit(Func); 761 getDest()->emit(Func);
476 Str << ", "; 762 Str << ", ";
477 getSrc(0)->emit(Func); 763 getSrc(0)->emit(Func);
478 Str << "\n"; 764 Str << "\n";
479 } 765 }
480 766
767 template <> void InstX8632Sqrtss::emitIAS(const Cfg *Func) const {
768 Type Ty = getDest()->getType();
769 assert(getSrcSize() == 1);
770 assert(Ty == IceType_f32 || Ty == IceType_f64);
771 if (Ty == IceType_f64) {
772 emitIASVarOperandXMM(Func, getDest(), getSrc(0), &x86::AssemblerX86::sqrtsd,
773 &x86::AssemblerX86::sqrtsd);
774 } else {
775 emitIASVarOperandXMM(Func, getDest(), getSrc(0), &x86::AssemblerX86::sqrtss,
776 &x86::AssemblerX86::sqrtss);
777 }
778 }
779
780 template <> void InstX8632Adc::emitIAS(const Cfg *Func) const {
781 assert(getSrcSize() == 2);
782 emitIASTwoOperandGPR(Func, getDest(), getSrc(1), &x86::AssemblerX86::adc,
783 &x86::AssemblerX86::adc, &x86::AssemblerX86::adc);
784 }
785
786 template <> void InstX8632Add::emitIAS(const Cfg *Func) const {
787 assert(getSrcSize() == 2);
788 emitIASTwoOperandGPR(Func, getDest(), getSrc(1), &x86::AssemblerX86::add,
789 &x86::AssemblerX86::add, &x86::AssemblerX86::add);
790 }
791
792 template <> void InstX8632Addps::emitIAS(const Cfg *Func) const {
793 assert(getSrcSize() == 2);
794 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::addps,
795 &x86::AssemblerX86::addps);
796 }
797
481 template <> void InstX8632Addss::emit(const Cfg *Func) const { 798 template <> void InstX8632Addss::emit(const Cfg *Func) const {
482 char buf[30]; 799 char buf[30];
483 snprintf(buf, llvm::array_lengthof(buf), "add%s", 800 snprintf(buf, llvm::array_lengthof(buf), "add%s",
484 TypeX8632Attributes[getDest()->getType()].SdSsString); 801 TypeX8632Attributes[getDest()->getType()].SdSsString);
485 emitTwoAddress(buf, this, Func); 802 emitTwoAddress(buf, this, Func);
486 } 803 }
487 804
805 template <> void InstX8632Addss::emitIAS(const Cfg *Func) const {
806 Type Ty = getDest()->getType();
807 assert(getSrcSize() == 2);
808 if (Ty == IceType_f64) {
809 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::addsd,
810 &x86::AssemblerX86::addsd);
811 } else {
812 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::addss,
813 &x86::AssemblerX86::addss);
814 }
815 }
816
817 template <> void InstX8632And::emitIAS(const Cfg *Func) const {
818 assert(getSrcSize() == 2);
819 emitIASTwoOperandGPR(Func, getDest(), getSrc(1), &x86::AssemblerX86::_and,
820 &x86::AssemblerX86::_and, &x86::AssemblerX86::_and);
821 }
822
488 template <> void InstX8632Padd::emit(const Cfg *Func) const { 823 template <> void InstX8632Padd::emit(const Cfg *Func) const {
489 char buf[30]; 824 char buf[30];
490 snprintf(buf, llvm::array_lengthof(buf), "padd%s", 825 snprintf(buf, llvm::array_lengthof(buf), "padd%s",
491 TypeX8632Attributes[getDest()->getType()].PackString); 826 TypeX8632Attributes[getDest()->getType()].PackString);
492 emitTwoAddress(buf, this, Func); 827 emitTwoAddress(buf, this, Func);
493 } 828 }
494 829
830 template <> void InstX8632Padd::emitIAS(const Cfg *Func) const {
831 Type Ty = getDest()->getType();
832 assert(isVectorType(Ty));
833 Type ElTy = typeElementType(Ty);
834 assert(getSrcSize() == 2);
835 emitIASTwoOperandTyXMM(Func, ElTy, getDest(), getSrc(1),
836 &x86::AssemblerX86::padd, &x86::AssemblerX86::padd);
837 }
838
495 template <> void InstX8632Pmull::emit(const Cfg *Func) const { 839 template <> void InstX8632Pmull::emit(const Cfg *Func) const {
496 char buf[30]; 840 char buf[30];
497 bool TypesAreValid = getDest()->getType() == IceType_v4i32 || 841 bool TypesAreValid = getDest()->getType() == IceType_v4i32 ||
498 getDest()->getType() == IceType_v8i16; 842 getDest()->getType() == IceType_v8i16;
499 bool InstructionSetIsValid = 843 bool InstructionSetIsValid =
500 getDest()->getType() == IceType_v8i16 || 844 getDest()->getType() == IceType_v8i16 ||
501 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >= 845 static_cast<TargetX8632 *>(Func->getTarget())->getInstructionSet() >=
502 TargetX8632::SSE4_1; 846 TargetX8632::SSE4_1;
503 (void)TypesAreValid; 847 (void)TypesAreValid;
504 (void)InstructionSetIsValid; 848 (void)InstructionSetIsValid;
505 assert(TypesAreValid); 849 assert(TypesAreValid);
506 assert(InstructionSetIsValid); 850 assert(InstructionSetIsValid);
507 snprintf(buf, llvm::array_lengthof(buf), "pmull%s", 851 snprintf(buf, llvm::array_lengthof(buf), "pmull%s",
508 TypeX8632Attributes[getDest()->getType()].PackString); 852 TypeX8632Attributes[getDest()->getType()].PackString);
509 emitTwoAddress(buf, this, Func); 853 emitTwoAddress(buf, this, Func);
510 } 854 }
511 855
856 template <> void InstX8632Sbb::emitIAS(const Cfg *Func) const {
857 assert(getSrcSize() == 2);
858 emitIASTwoOperandGPR(Func, getDest(), getSrc(1), &x86::AssemblerX86::sbb,
859 &x86::AssemblerX86::sbb, &x86::AssemblerX86::sbb);
860 }
861
862 template <> void InstX8632Sub::emitIAS(const Cfg *Func) const {
863 assert(getSrcSize() == 2);
864 emitIASTwoOperandGPR(Func, getDest(), getSrc(1), &x86::AssemblerX86::sub,
865 &x86::AssemblerX86::sub, &x86::AssemblerX86::sub);
866 }
867
868 template <> void InstX8632Subps::emitIAS(const Cfg *Func) const {
869 assert(getSrcSize() == 2);
870 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::subps,
871 &x86::AssemblerX86::subps);
872 }
873
512 template <> void InstX8632Subss::emit(const Cfg *Func) const { 874 template <> void InstX8632Subss::emit(const Cfg *Func) const {
513 char buf[30]; 875 char buf[30];
514 snprintf(buf, llvm::array_lengthof(buf), "sub%s", 876 snprintf(buf, llvm::array_lengthof(buf), "sub%s",
515 TypeX8632Attributes[getDest()->getType()].SdSsString); 877 TypeX8632Attributes[getDest()->getType()].SdSsString);
516 emitTwoAddress(buf, this, Func); 878 emitTwoAddress(buf, this, Func);
517 } 879 }
518 880
881 template <> void InstX8632Subss::emitIAS(const Cfg *Func) const {
882 Type Ty = getDest()->getType();
883 assert(getSrcSize() == 2);
884 if (Ty == IceType_f64) {
885 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::subsd,
886 &x86::AssemblerX86::subsd);
887 } else {
888 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::subss,
889 &x86::AssemblerX86::subss);
890 }
891 }
892
519 template <> void InstX8632Psub::emit(const Cfg *Func) const { 893 template <> void InstX8632Psub::emit(const Cfg *Func) const {
520 char buf[30]; 894 char buf[30];
521 snprintf(buf, llvm::array_lengthof(buf), "psub%s", 895 snprintf(buf, llvm::array_lengthof(buf), "psub%s",
522 TypeX8632Attributes[getDest()->getType()].PackString); 896 TypeX8632Attributes[getDest()->getType()].PackString);
523 emitTwoAddress(buf, this, Func); 897 emitTwoAddress(buf, this, Func);
524 } 898 }
525 899
900 template <> void InstX8632Psub::emitIAS(const Cfg *Func) const {
901 Type Ty = getDest()->getType();
902 assert(isVectorType(Ty));
903 Type ElTy = typeElementType(Ty);
904 assert(getSrcSize() == 2);
905 emitIASTwoOperandTyXMM(Func, ElTy, getDest(), getSrc(1),
906 &x86::AssemblerX86::psub, &x86::AssemblerX86::psub);
907 }
908
909 template <> void InstX8632Mulps::emitIAS(const Cfg *Func) const {
910 assert(getSrcSize() == 2);
911 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::mulps,
912 &x86::AssemblerX86::mulps);
913 }
914
526 template <> void InstX8632Mulss::emit(const Cfg *Func) const { 915 template <> void InstX8632Mulss::emit(const Cfg *Func) const {
527 char buf[30]; 916 char buf[30];
528 snprintf(buf, llvm::array_lengthof(buf), "mul%s", 917 snprintf(buf, llvm::array_lengthof(buf), "mul%s",
529 TypeX8632Attributes[getDest()->getType()].SdSsString); 918 TypeX8632Attributes[getDest()->getType()].SdSsString);
530 emitTwoAddress(buf, this, Func); 919 emitTwoAddress(buf, this, Func);
531 } 920 }
532 921
922 template <> void InstX8632Mulss::emitIAS(const Cfg *Func) const {
923 Type Ty = getDest()->getType();
924 assert(getSrcSize() == 2);
925 if (Ty == IceType_f64) {
926 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::mulsd,
927 &x86::AssemblerX86::mulsd);
928 } else {
929 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::mulss,
930 &x86::AssemblerX86::mulss);
931 }
932 }
933
533 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const { 934 template <> void InstX8632Pmuludq::emit(const Cfg *Func) const {
534 assert(getSrc(0)->getType() == IceType_v4i32 && 935 assert(getSrc(0)->getType() == IceType_v4i32 &&
535 getSrc(1)->getType() == IceType_v4i32); 936 getSrc(1)->getType() == IceType_v4i32);
536 emitTwoAddress(Opcode, this, Func); 937 emitTwoAddress(Opcode, this, Func);
537 } 938 }
538 939
940 template <> void InstX8632Divps::emitIAS(const Cfg *Func) const {
941 assert(getSrcSize() == 2);
942 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::divps,
943 &x86::AssemblerX86::divps);
944 }
945
539 template <> void InstX8632Divss::emit(const Cfg *Func) const { 946 template <> void InstX8632Divss::emit(const Cfg *Func) const {
540 char buf[30]; 947 char buf[30];
541 snprintf(buf, llvm::array_lengthof(buf), "div%s", 948 snprintf(buf, llvm::array_lengthof(buf), "div%s",
542 TypeX8632Attributes[getDest()->getType()].SdSsString); 949 TypeX8632Attributes[getDest()->getType()].SdSsString);
543 emitTwoAddress(buf, this, Func); 950 emitTwoAddress(buf, this, Func);
544 } 951 }
545 952
953 template <> void InstX8632Divss::emitIAS(const Cfg *Func) const {
954 Type Ty = getDest()->getType();
955 assert(getSrcSize() == 2);
956 if (Ty == IceType_f64) {
957 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::divsd,
958 &x86::AssemblerX86::divsd);
959 } else {
960 emitIASVarOperandXMM(Func, getDest(), getSrc(1), &x86::AssemblerX86::divss,
961 &x86::AssemblerX86::divss);
962 }
963 }
964
546 template <> void InstX8632Div::emit(const Cfg *Func) const { 965 template <> void InstX8632Div::emit(const Cfg *Func) const {
547 Ostream &Str = Func->getContext()->getStrEmit(); 966 Ostream &Str = Func->getContext()->getStrEmit();
548 assert(getSrcSize() == 3); 967 assert(getSrcSize() == 3);
549 Str << "\t" << Opcode << "\t"; 968 Str << "\t" << Opcode << "\t";
550 getSrc(1)->emit(Func); 969 getSrc(1)->emit(Func);
551 Str << "\n"; 970 Str << "\n";
552 } 971 }
553 972
554 template <> void InstX8632Idiv::emit(const Cfg *Func) const { 973 template <> void InstX8632Idiv::emit(const Cfg *Func) const {
555 Ostream &Str = Func->getContext()->getStrEmit(); 974 Ostream &Str = Func->getContext()->getStrEmit();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); 1052 assert(getDest()->getRegNum() == TargetX8632::Reg_edx);
634 Str << "\tcwd\n"; 1053 Str << "\tcwd\n";
635 break; 1054 break;
636 case IceType_i32: 1055 case IceType_i32:
637 assert(getDest()->getRegNum() == TargetX8632::Reg_edx); 1056 assert(getDest()->getRegNum() == TargetX8632::Reg_edx);
638 Str << "\tcdq\n"; 1057 Str << "\tcdq\n";
639 break; 1058 break;
640 } 1059 }
641 } 1060 }
642 1061
1062 template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const {
1063 Ostream &Str = Func->getContext()->getStrEmit();
1064 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1065 intptr_t StartPosition = Asm->GetPosition();
1066 assert(getSrcSize() == 1);
1067 Operand *Src0 = getSrc(0);
1068 assert(llvm::isa<Variable>(Src0));
1069 assert(llvm::cast<Variable>(Src0)->getRegNum() == TargetX8632::Reg_eax);
1070 switch (Src0->getType()) {
1071 default:
1072 llvm_unreachable("unexpected source type!");
1073 break;
1074 case IceType_i8:
1075 assert(getDest()->getRegNum() == TargetX8632::Reg_eax);
1076 Asm->cbw();
1077 break;
1078 case IceType_i16:
1079 assert(getDest()->getRegNum() == TargetX8632::Reg_edx);
1080 Asm->cwd();
1081 break;
1082 case IceType_i32:
1083 assert(getDest()->getRegNum() == TargetX8632::Reg_edx);
1084 Asm->cdq();
1085 break;
1086 }
1087 emitIASBytes(Str, Asm, StartPosition);
1088 }
1089
643 void InstX8632Mul::emit(const Cfg *Func) const { 1090 void InstX8632Mul::emit(const Cfg *Func) const {
644 Ostream &Str = Func->getContext()->getStrEmit(); 1091 Ostream &Str = Func->getContext()->getStrEmit();
645 assert(getSrcSize() == 2); 1092 assert(getSrcSize() == 2);
646 assert(llvm::isa<Variable>(getSrc(0))); 1093 assert(llvm::isa<Variable>(getSrc(0)));
647 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() == 1094 assert(llvm::dyn_cast<Variable>(getSrc(0))->getRegNum() ==
648 TargetX8632::Reg_eax); 1095 TargetX8632::Reg_eax);
649 assert(getDest()->getRegNum() == TargetX8632::Reg_eax); // TODO: allow edx? 1096 assert(getDest()->getRegNum() == TargetX8632::Reg_eax); // TODO: allow edx?
650 Str << "\tmul\t"; 1097 Str << "\tmul\t";
651 getSrc(1)->emit(Func); 1098 getSrc(1)->emit(Func);
652 Str << "\n"; 1099 Str << "\n";
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 Str << "\t"; 1163 Str << "\t";
717 assert(Condition != Br_None); 1164 assert(Condition != Br_None);
718 assert(getDest()->hasReg()); 1165 assert(getDest()->hasReg());
719 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t"; 1166 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "\t";
720 getDest()->emit(Func); 1167 getDest()->emit(Func);
721 Str << ", "; 1168 Str << ", ";
722 getSrc(1)->emit(Func); 1169 getSrc(1)->emit(Func);
723 Str << "\n"; 1170 Str << "\n";
724 } 1171 }
725 1172
1173 void InstX8632Cmov::emitIAS(const Cfg *Func) const {
1174 Ostream &Str = Func->getContext()->getStrEmit();
1175 assert(Condition != Br_None);
1176 assert(getDest()->hasReg());
1177 assert(getSrcSize() == 2);
1178 const Variable *Src = llvm::cast<Variable>(getSrc(1));
1179 // Only need the 32-bit register form right now.
1180 assert(Src->hasReg());
1181 assert(Src->getType() == IceType_i32);
1182 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1183 intptr_t StartPosition = Asm->GetPosition();
1184 Asm->cmov(convertToAsmCondition(Condition),
1185 convertToAsmGPR(getDest()->getRegNum()),
1186 convertToAsmGPR(Src->getRegNum()));
1187 emitIASBytes(Str, Asm, StartPosition);
1188 }
1189
726 void InstX8632Cmov::dump(const Cfg *Func) const { 1190 void InstX8632Cmov::dump(const Cfg *Func) const {
727 Ostream &Str = Func->getContext()->getStrDump(); 1191 Ostream &Str = Func->getContext()->getStrDump();
728 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << "."; 1192 Str << "cmov" << InstX8632BrAttributes[Condition].DisplayString << ".";
729 Str << getDest()->getType() << " "; 1193 Str << getDest()->getType() << " ";
730 dumpDest(Func); 1194 dumpDest(Func);
731 Str << ", "; 1195 Str << ", ";
732 dumpSources(Func); 1196 dumpSources(Func);
733 } 1197 }
734 1198
735 void InstX8632Cmpps::emit(const Cfg *Func) const { 1199 void InstX8632Cmpps::emit(const Cfg *Func) const {
736 Ostream &Str = Func->getContext()->getStrEmit(); 1200 Ostream &Str = Func->getContext()->getStrEmit();
737 assert(getSrcSize() == 2); 1201 assert(getSrcSize() == 2);
738 assert(Condition < Cmpps_Invalid); 1202 assert(Condition < Cmpps_Invalid);
739 Str << "\t"; 1203 Str << "\t";
740 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1204 Str << "cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
741 << "\t"; 1205 << "\t";
742 getDest()->emit(Func); 1206 getDest()->emit(Func);
743 Str << ", "; 1207 Str << ", ";
744 getSrc(1)->emit(Func); 1208 getSrc(1)->emit(Func);
745 Str << "\n"; 1209 Str << "\n";
746 } 1210 }
747 1211
1212 void InstX8632Cmpps::emitIAS(const Cfg *Func) const {
1213 Ostream &Str = Func->getContext()->getStrEmit();
1214 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1215 intptr_t StartPosition = Asm->GetPosition();
1216 assert(getSrcSize() == 2);
1217 assert(Condition < Cmpps_Invalid);
1218 // Assuming there isn't any load folding for cmpps, and vector constants
1219 // are not allowed in PNaCl.
1220 assert(llvm::isa<Variable>(getSrc(1)));
1221 const Variable *SrcVar = llvm::cast<Variable>(getSrc(1));
1222 if (SrcVar->hasReg()) {
1223 Asm->cmpps(convertToAsmXMMReg(getDest()->getRegNum()),
1224 convertToAsmXMMReg(SrcVar->getRegNum()), Condition);
1225 } else {
1226 x86::Address SrcStackAddr = static_cast<TargetX8632 *>(Func->getTarget())
1227 ->stackVarToAsmOperand(SrcVar);
1228 Asm->cmpps(convertToAsmXMMReg(getDest()->getRegNum()), SrcStackAddr,
1229 Condition);
1230 }
1231 emitIASBytes(Str, Asm, StartPosition);
1232 }
1233
748 void InstX8632Cmpps::dump(const Cfg *Func) const { 1234 void InstX8632Cmpps::dump(const Cfg *Func) const {
749 Ostream &Str = Func->getContext()->getStrDump(); 1235 Ostream &Str = Func->getContext()->getStrDump();
750 assert(Condition < Cmpps_Invalid); 1236 assert(Condition < Cmpps_Invalid);
751 dumpDest(Func); 1237 dumpDest(Func);
752 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps" 1238 Str << " = cmp" << InstX8632CmppsAttributes[Condition].EmitString << "ps"
753 << "\t"; 1239 << "\t";
754 dumpSources(Func); 1240 dumpSources(Func);
755 } 1241 }
756 1242
757 void InstX8632Cmpxchg::emit(const Cfg *Func) const { 1243 void InstX8632Cmpxchg::emit(const Cfg *Func) const {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 void InstX8632Icmp::emit(const Cfg *Func) const { 1310 void InstX8632Icmp::emit(const Cfg *Func) const {
825 Ostream &Str = Func->getContext()->getStrEmit(); 1311 Ostream &Str = Func->getContext()->getStrEmit();
826 assert(getSrcSize() == 2); 1312 assert(getSrcSize() == 2);
827 Str << "\tcmp\t"; 1313 Str << "\tcmp\t";
828 getSrc(0)->emit(Func); 1314 getSrc(0)->emit(Func);
829 Str << ", "; 1315 Str << ", ";
830 getSrc(1)->emit(Func); 1316 getSrc(1)->emit(Func);
831 Str << "\n"; 1317 Str << "\n";
832 } 1318 }
833 1319
1320 void InstX8632Icmp::emitIAS(const Cfg *Func) const {
1321 assert(getSrcSize() == 2);
1322 emitIASTwoOperandGPR(Func, getSrc(0), getSrc(1), &x86::AssemblerX86::cmp,
1323 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp,
1324 &x86::AssemblerX86::cmp, &x86::AssemblerX86::cmp);
1325 }
1326
834 void InstX8632Icmp::dump(const Cfg *Func) const { 1327 void InstX8632Icmp::dump(const Cfg *Func) const {
835 Ostream &Str = Func->getContext()->getStrDump(); 1328 Ostream &Str = Func->getContext()->getStrDump();
836 Str << "cmp." << getSrc(0)->getType() << " "; 1329 Str << "cmp." << getSrc(0)->getType() << " ";
837 dumpSources(Func); 1330 dumpSources(Func);
838 } 1331 }
839 1332
840 void InstX8632Ucomiss::emit(const Cfg *Func) const { 1333 void InstX8632Ucomiss::emit(const Cfg *Func) const {
841 Ostream &Str = Func->getContext()->getStrEmit(); 1334 Ostream &Str = Func->getContext()->getStrEmit();
842 assert(getSrcSize() == 2); 1335 assert(getSrcSize() == 2);
843 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString 1336 Str << "\tucomi" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString
844 << "\t"; 1337 << "\t";
845 getSrc(0)->emit(Func); 1338 getSrc(0)->emit(Func);
846 Str << ", "; 1339 Str << ", ";
847 getSrc(1)->emit(Func); 1340 getSrc(1)->emit(Func);
848 Str << "\n"; 1341 Str << "\n";
849 } 1342 }
850 1343
1344 void InstX8632Ucomiss::emitIAS(const Cfg *Func) const {
1345 assert(getSrcSize() == 2);
1346 // Currently src0 is always a variable by convention, to avoid having
1347 // two memory operands.
1348 assert(llvm::isa<Variable>(getSrc(0)));
1349 const Variable *Src0 = llvm::cast<Variable>(getSrc(0));
1350 Type Ty = Src0->getType();
1351 if (Ty == IceType_f64) {
1352 emitIASVarOperandXMM(Func, Src0, getSrc(1), &x86::AssemblerX86::ucomisd,
1353 &x86::AssemblerX86::ucomisd);
1354 } else {
1355 emitIASVarOperandXMM(Func, Src0, getSrc(1), &x86::AssemblerX86::ucomiss,
1356 &x86::AssemblerX86::ucomiss);
1357 }
1358 }
1359
851 void InstX8632Ucomiss::dump(const Cfg *Func) const { 1360 void InstX8632Ucomiss::dump(const Cfg *Func) const {
852 Ostream &Str = Func->getContext()->getStrDump(); 1361 Ostream &Str = Func->getContext()->getStrDump();
853 Str << "ucomiss." << getSrc(0)->getType() << " "; 1362 Str << "ucomiss." << getSrc(0)->getType() << " ";
854 dumpSources(Func); 1363 dumpSources(Func);
855 } 1364 }
856 1365
857 void InstX8632UD2::emit(const Cfg *Func) const { 1366 void InstX8632UD2::emit(const Cfg *Func) const {
858 Ostream &Str = Func->getContext()->getStrEmit(); 1367 Ostream &Str = Func->getContext()->getStrEmit();
859 assert(getSrcSize() == 0); 1368 assert(getSrcSize() == 0);
860 Str << "\tud2\n"; 1369 Str << "\tud2\n";
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 Str << "\n"; 1520 Str << "\n";
1012 Str << ".intel_syntax\n"; 1521 Str << ".intel_syntax\n";
1013 } else { 1522 } else {
1014 getDest()->asType(Src->getType()).emit(Func); 1523 getDest()->asType(Src->getType()).emit(Func);
1015 Str << ", "; 1524 Str << ", ";
1016 Src->emit(Func); 1525 Src->emit(Func);
1017 Str << "\n"; 1526 Str << "\n";
1018 } 1527 }
1019 } 1528 }
1020 1529
1530 template <> void InstX8632Mov::emitIAS(const Cfg *Func) const {
1531 // Could be movss/sd, or movb/movw/movl.
1532 emit(Func);
1533 }
1534
1021 template <> void InstX8632Movp::emit(const Cfg *Func) const { 1535 template <> void InstX8632Movp::emit(const Cfg *Func) const {
1022 // TODO(wala,stichnot): movups works with all vector operands, but 1536 // TODO(wala,stichnot): movups works with all vector operands, but
1023 // there exist other instructions (movaps, movdqa, movdqu) that may 1537 // there exist other instructions (movaps, movdqa, movdqu) that may
1024 // perform better, depending on the data type and alignment of the 1538 // perform better, depending on the data type and alignment of the
1025 // operands. 1539 // operands.
1026 Ostream &Str = Func->getContext()->getStrEmit(); 1540 Ostream &Str = Func->getContext()->getStrEmit();
1027 assert(getSrcSize() == 1); 1541 assert(getSrcSize() == 1);
1028 Str << "\tmovups\t"; 1542 Str << "\tmovups\t";
1029 getDest()->emit(Func); 1543 getDest()->emit(Func);
1030 Str << ", "; 1544 Str << ", ";
1031 getSrc(0)->emit(Func); 1545 getSrc(0)->emit(Func);
1032 Str << "\n"; 1546 Str << "\n";
1033 } 1547 }
1034 1548
1035 template <> void InstX8632Movq::emit(const Cfg *Func) const { 1549 template <> void InstX8632Movq::emit(const Cfg *Func) const {
1036 Ostream &Str = Func->getContext()->getStrEmit(); 1550 Ostream &Str = Func->getContext()->getStrEmit();
1037 assert(getSrcSize() == 1); 1551 assert(getSrcSize() == 1);
1038 assert(getDest()->getType() == IceType_i64 || 1552 assert(getDest()->getType() == IceType_i64 ||
1039 getDest()->getType() == IceType_f64); 1553 getDest()->getType() == IceType_f64);
1040 Str << "\tmovq\t"; 1554 Str << "\tmovq\t";
1041 getDest()->emit(Func); 1555 getDest()->emit(Func);
1042 Str << ", "; 1556 Str << ", ";
1043 getSrc(0)->emit(Func); 1557 getSrc(0)->emit(Func);
1044 Str << "\n"; 1558 Str << "\n";
1045 } 1559 }
1046 1560
1561 static void emitIASSignZeroExt(const Cfg *Func, const Variable *Dest,
1562 const Operand *Src0,
1563 x86::AssemblerX86::EmitRegByteR EmitByte,
1564 x86::AssemblerX86::EmitRegReg EmitWord,
1565 x86::AssemblerX86::EmitRegAddr EmitAddress) {
1566 Ostream &Str = Func->getContext()->getStrEmit();
1567 assert(Dest->hasReg());
1568 x86::Register DestReg = convertToAsmGPR(Dest->getRegNum());
1569 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1570 intptr_t StartPosition = Asm->GetPosition();
1571 Type SrcType = Src0->getType();
1572 // Source is ByteReg, WordReg, or stack slot, or other memory operand.
1573 if (const Variable *SrcVar = llvm::dyn_cast<Variable>(Src0)) {
1574 if (SrcVar->hasReg()) {
1575 if (SrcType == IceType_i8 || SrcType == IceType_i1) {
1576 (Asm->*EmitByte)(DestReg,
1577 convertToAsmByteRegister(SrcVar->getRegNum()));
1578 } else {
1579 assert(SrcType == IceType_i16);
1580 (Asm->*EmitWord)(DestReg, convertToAsmGPR(SrcVar->getRegNum()));
1581 }
1582 } else {
1583 x86::Address StackAddr = static_cast<TargetX8632 *>(Func->getTarget())
1584 ->stackVarToAsmOperand(SrcVar);
1585 (Asm->*EmitAddress)(DestReg, StackAddr);
1586 }
1587 } else if (const OperandX8632Mem *Mem =
1588 llvm::dyn_cast<OperandX8632Mem>(Src0)) {
1589 x86::Address SrcAddr = Mem->convertToAsmAddress(Asm);
1590 (Asm->*EmitAddress)(DestReg, SrcAddr);
1591 } else {
1592 llvm_unreachable("Unexpected operand type for Movzx");
1593 }
1594 emitIASBytes(Str, Asm, StartPosition);
1595 }
1596
1047 void InstX8632Movsx::emit(const Cfg *Func) const { 1597 void InstX8632Movsx::emit(const Cfg *Func) const {
1048 Ostream &Str = Func->getContext()->getStrEmit(); 1598 Ostream &Str = Func->getContext()->getStrEmit();
1049 assert(getSrcSize() == 1); 1599 assert(getSrcSize() == 1);
1050 Str << "\tmovsx\t"; 1600 Str << "\tmovsx\t";
1051 getDest()->emit(Func); 1601 getDest()->emit(Func);
1052 Str << ", "; 1602 Str << ", ";
1053 getSrc(0)->emit(Func); 1603 getSrc(0)->emit(Func);
1054 Str << "\n"; 1604 Str << "\n";
1055 } 1605 }
1056 1606
1607 void InstX8632Movsx::emitIAS(const Cfg *Func) const {
1608 assert(getSrcSize() == 1);
1609 const Operand *Src0 = getSrc(0);
1610 Type SrcType = Src0->getType();
1611 if (SrcType == IceType_i8 || SrcType == IceType_i1) {
1612 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movsxb,
1613 &x86::AssemblerX86::movsxw, &x86::AssemblerX86::movsxb);
1614 } else {
1615 assert(SrcType == IceType_i16);
1616 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movsxb,
1617 &x86::AssemblerX86::movsxw, &x86::AssemblerX86::movsxw);
1618 }
1619 }
1620
1057 void InstX8632Movsx::dump(const Cfg *Func) const { 1621 void InstX8632Movsx::dump(const Cfg *Func) const {
1058 Ostream &Str = Func->getContext()->getStrDump(); 1622 Ostream &Str = Func->getContext()->getStrDump();
1059 Str << "movsx." << getDest()->getType() << "." << getSrc(0)->getType(); 1623 Str << "movsx." << getDest()->getType() << "." << getSrc(0)->getType();
1060 Str << " "; 1624 Str << " ";
1061 dumpDest(Func); 1625 dumpDest(Func);
1062 Str << ", "; 1626 Str << ", ";
1063 dumpSources(Func); 1627 dumpSources(Func);
1064 } 1628 }
1065 1629
1066 void InstX8632Movzx::emit(const Cfg *Func) const { 1630 void InstX8632Movzx::emit(const Cfg *Func) const {
1067 Ostream &Str = Func->getContext()->getStrEmit(); 1631 Ostream &Str = Func->getContext()->getStrEmit();
1068 assert(getSrcSize() == 1); 1632 assert(getSrcSize() == 1);
1069 Str << "\tmovzx\t"; 1633 Str << "\tmovzx\t";
1070 getDest()->emit(Func); 1634 getDest()->emit(Func);
1071 Str << ", "; 1635 Str << ", ";
1072 getSrc(0)->emit(Func); 1636 getSrc(0)->emit(Func);
1073 Str << "\n"; 1637 Str << "\n";
1074 } 1638 }
1075 1639
1640 void InstX8632Movzx::emitIAS(const Cfg *Func) const {
1641 assert(getSrcSize() == 1);
1642 const Operand *Src0 = getSrc(0);
1643 Type SrcType = Src0->getType();
1644 if (SrcType == IceType_i8 || SrcType == IceType_i1) {
1645 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movzxb,
1646 &x86::AssemblerX86::movzxw, &x86::AssemblerX86::movzxb);
1647 } else {
1648 assert(SrcType == IceType_i16);
1649 emitIASSignZeroExt(Func, getDest(), Src0, &x86::AssemblerX86::movzxb,
1650 &x86::AssemblerX86::movzxw, &x86::AssemblerX86::movzxw);
1651 }
1652 }
1653
1076 void InstX8632Movzx::dump(const Cfg *Func) const { 1654 void InstX8632Movzx::dump(const Cfg *Func) const {
1077 Ostream &Str = Func->getContext()->getStrDump(); 1655 Ostream &Str = Func->getContext()->getStrDump();
1078 Str << "movzx." << getDest()->getType() << "." << getSrc(0)->getType(); 1656 Str << "movzx." << getDest()->getType() << "." << getSrc(0)->getType();
1079 Str << " "; 1657 Str << " ";
1080 dumpDest(Func); 1658 dumpDest(Func);
1081 Str << ", "; 1659 Str << ", ";
1082 dumpSources(Func); 1660 dumpSources(Func);
1083 } 1661 }
1084 1662
1085 void InstX8632Nop::emit(const Cfg *Func) const { 1663 void InstX8632Nop::emit(const Cfg *Func) const {
1086 Ostream &Str = Func->getContext()->getStrEmit(); 1664 Ostream &Str = Func->getContext()->getStrEmit();
1087 // TODO: Emit the right code for each variant. 1665 // TODO: Emit the right code for each variant.
1088 Str << "\tnop\t# variant = " << Variant << "\n"; 1666 Str << "\tnop\t# variant = " << Variant << "\n";
1089 } 1667 }
1090 1668
1669 void InstX8632Nop::emitIAS(const Cfg *Func) const {
1670 Ostream &Str = Func->getContext()->getStrEmit();
1671 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1672 intptr_t StartPosition = Asm->GetPosition();
1673 // TODO: Emit the right code for the variant.
1674 Asm->nop();
1675 emitIASBytes(Str, Asm, StartPosition);
1676 }
1677
1091 void InstX8632Nop::dump(const Cfg *Func) const { 1678 void InstX8632Nop::dump(const Cfg *Func) const {
1092 Ostream &Str = Func->getContext()->getStrDump(); 1679 Ostream &Str = Func->getContext()->getStrDump();
1093 Str << "nop (variant = " << Variant << ")"; 1680 Str << "nop (variant = " << Variant << ")";
1094 } 1681 }
1095 1682
1683 template <> void InstX8632Or::emitIAS(const Cfg *Func) const {
1684 assert(getSrcSize() == 2);
1685 emitIASTwoOperandGPR(Func, getDest(), getSrc(1), &x86::AssemblerX86::_or,
1686 &x86::AssemblerX86::_or, &x86::AssemblerX86::_or);
1687 }
1688
1096 void InstX8632Fld::emit(const Cfg *Func) const { 1689 void InstX8632Fld::emit(const Cfg *Func) const {
1097 Ostream &Str = Func->getContext()->getStrEmit(); 1690 Ostream &Str = Func->getContext()->getStrEmit();
1098 assert(getSrcSize() == 1); 1691 assert(getSrcSize() == 1);
1099 Type Ty = getSrc(0)->getType(); 1692 Type Ty = getSrc(0)->getType();
1100 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); 1693 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0));
1101 if (Var && Var->hasReg()) { 1694 if (Var && Var->hasReg()) {
1102 // This is a physical xmm register, so we need to spill it to a 1695 // This is a physical xmm register, so we need to spill it to a
1103 // temporary stack slot. 1696 // temporary stack slot.
1104 SizeT Width = typeWidthInBytes(Ty); 1697 SizeT Width = typeWidthInBytes(Ty);
1105 Str << "\tsub\tesp, " << Width << "\n"; 1698 Str << "\tsub\tesp, " << Width << "\n";
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 Src1->emit(Func); 1808 Src1->emit(Func);
1216 } 1809 }
1217 Str << ", "; 1810 Str << ", ";
1218 getSrc(2)->emit(Func); 1811 getSrc(2)->emit(Func);
1219 Str << "\n"; 1812 Str << "\n";
1220 } 1813 }
1221 1814
1222 void InstX8632Pop::emit(const Cfg *Func) const { 1815 void InstX8632Pop::emit(const Cfg *Func) const {
1223 Ostream &Str = Func->getContext()->getStrEmit(); 1816 Ostream &Str = Func->getContext()->getStrEmit();
1224 assert(getSrcSize() == 0); 1817 assert(getSrcSize() == 0);
1818 assert(getDest()->getType() == IceType_i32);
1225 Str << "\tpop\t"; 1819 Str << "\tpop\t";
1226 getDest()->emit(Func); 1820 getDest()->emit(Func);
1227 Str << "\n"; 1821 Str << "\n";
1228 } 1822 }
1229 1823
1824 void InstX8632Pop::emitIAS(const Cfg *Func) const {
1825 Ostream &Str = Func->getContext()->getStrEmit();
1826 assert(getSrcSize() == 0);
1827 assert(getDest()->getType() == IceType_i32);
1828 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1829 intptr_t StartPosition = Asm->GetPosition();
1830 if (getDest()->hasReg()) {
1831 Asm->popl(convertToAsmGPR(getDest()->getRegNum()));
1832 } else {
1833 Asm->popl(static_cast<TargetX8632 *>(Func->getTarget())
1834 ->stackVarToAsmOperand(getDest()));
1835 }
1836 emitIASBytes(Str, Asm, StartPosition);
1837 }
1838
1230 void InstX8632Pop::dump(const Cfg *Func) const { 1839 void InstX8632Pop::dump(const Cfg *Func) const {
1231 Ostream &Str = Func->getContext()->getStrDump(); 1840 Ostream &Str = Func->getContext()->getStrDump();
1232 dumpDest(Func); 1841 dumpDest(Func);
1233 Str << " = pop." << getDest()->getType() << " "; 1842 Str << " = pop." << getDest()->getType() << " ";
1234 } 1843 }
1235 1844
1236 void InstX8632AdjustStack::emit(const Cfg *Func) const { 1845 void InstX8632AdjustStack::emit(const Cfg *Func) const {
1237 Ostream &Str = Func->getContext()->getStrEmit(); 1846 Ostream &Str = Func->getContext()->getStrEmit();
1238 Str << "\tsub\tesp, " << Amount << "\n"; 1847 Str << "\tsub\tesp, " << Amount << "\n";
1239 Func->getTarget()->updateStackAdjustment(Amount); 1848 Func->getTarget()->updateStackAdjustment(Amount);
1240 } 1849 }
1241 1850
1851 void InstX8632AdjustStack::emitIAS(const Cfg *Func) const {
1852 Ostream &Str = Func->getContext()->getStrEmit();
1853 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1854 intptr_t StartPosition = Asm->GetPosition();
1855 Asm->sub(IceType_i32, convertToAsmGPR(TargetX8632::Reg_esp),
1856 x86::Immediate(Amount));
1857 emitIASBytes(Str, Asm, StartPosition);
1858 Func->getTarget()->updateStackAdjustment(Amount);
1859 }
1860
1242 void InstX8632AdjustStack::dump(const Cfg *Func) const { 1861 void InstX8632AdjustStack::dump(const Cfg *Func) const {
1243 Ostream &Str = Func->getContext()->getStrDump(); 1862 Ostream &Str = Func->getContext()->getStrDump();
1244 Str << "esp = sub.i32 esp, " << Amount; 1863 Str << "esp = sub.i32 esp, " << Amount;
1245 } 1864 }
1246 1865
1247 void InstX8632Push::emit(const Cfg *Func) const { 1866 void InstX8632Push::emit(const Cfg *Func) const {
1248 Ostream &Str = Func->getContext()->getStrEmit(); 1867 Ostream &Str = Func->getContext()->getStrEmit();
1249 assert(getSrcSize() == 1); 1868 assert(getSrcSize() == 1);
1250 Type Ty = getSrc(0)->getType(); 1869 Type Ty = getSrc(0)->getType();
1251 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0)); 1870 Variable *Var = llvm::dyn_cast<Variable>(getSrc(0));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 snprintf(buf, llvm::array_lengthof(buf), "psra%s", 1923 snprintf(buf, llvm::array_lengthof(buf), "psra%s",
1305 TypeX8632Attributes[getDest()->getType()].PackString); 1924 TypeX8632Attributes[getDest()->getType()].PackString);
1306 emitTwoAddress(buf, this, Func); 1925 emitTwoAddress(buf, this, Func);
1307 } 1926 }
1308 1927
1309 void InstX8632Ret::emit(const Cfg *Func) const { 1928 void InstX8632Ret::emit(const Cfg *Func) const {
1310 Ostream &Str = Func->getContext()->getStrEmit(); 1929 Ostream &Str = Func->getContext()->getStrEmit();
1311 Str << "\tret\n"; 1930 Str << "\tret\n";
1312 } 1931 }
1313 1932
1933 void InstX8632Ret::emitIAS(const Cfg *Func) const {
1934 Ostream &Str = Func->getContext()->getStrEmit();
1935 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>();
1936 intptr_t StartPosition = Asm->GetPosition();
1937 Asm->ret();
1938 emitIASBytes(Str, Asm, StartPosition);
1939 }
1940
1314 void InstX8632Ret::dump(const Cfg *Func) const { 1941 void InstX8632Ret::dump(const Cfg *Func) const {
1315 Ostream &Str = Func->getContext()->getStrDump(); 1942 Ostream &Str = Func->getContext()->getStrDump();
1316 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); 1943 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType());
1317 Str << "ret." << Ty << " "; 1944 Str << "ret." << Ty << " ";
1318 dumpSources(Func); 1945 dumpSources(Func);
1319 } 1946 }
1320 1947
1321 void InstX8632Xadd::emit(const Cfg *Func) const { 1948 void InstX8632Xadd::emit(const Cfg *Func) const {
1322 Ostream &Str = Func->getContext()->getStrEmit(); 1949 Ostream &Str = Func->getContext()->getStrEmit();
1323 if (Locked) { 1950 if (Locked) {
(...skipping 25 matching lines...) Expand all
1349 Str << "\n"; 1976 Str << "\n";
1350 } 1977 }
1351 1978
1352 void InstX8632Xchg::dump(const Cfg *Func) const { 1979 void InstX8632Xchg::dump(const Cfg *Func) const {
1353 Ostream &Str = Func->getContext()->getStrDump(); 1980 Ostream &Str = Func->getContext()->getStrDump();
1354 Type Ty = getSrc(0)->getType(); 1981 Type Ty = getSrc(0)->getType();
1355 Str << "xchg." << Ty << " "; 1982 Str << "xchg." << Ty << " ";
1356 dumpSources(Func); 1983 dumpSources(Func);
1357 } 1984 }
1358 1985
1986 template <> void InstX8632Xor::emitIAS(const Cfg *Func) const {
1987 assert(getSrcSize() == 2);
1988 emitIASTwoOperandGPR(Func, getDest(), getSrc(1), &x86::AssemblerX86::_xor,
1989 &x86::AssemblerX86::_xor, &x86::AssemblerX86::_xor);
1990 }
1991
1359 void OperandX8632::dump(const Cfg *Func) const { 1992 void OperandX8632::dump(const Cfg *Func) const {
1360 Ostream &Str = Func->getContext()->getStrDump(); 1993 Ostream &Str = Func->getContext()->getStrDump();
1361 Str << "<OperandX8632>"; 1994 Str << "<OperandX8632>";
1362 } 1995 }
1363 1996
1364 void OperandX8632Mem::emit(const Cfg *Func) const { 1997 void OperandX8632Mem::emit(const Cfg *Func) const {
1365 Ostream &Str = Func->getContext()->getStrEmit(); 1998 Ostream &Str = Func->getContext()->getStrEmit();
1366 Str << TypeX8632Attributes[getType()].WidthString << " "; 1999 Str << TypeX8632Attributes[getType()].WidthString << " ";
1367 if (SegmentReg != DefaultSegment) { 2000 if (SegmentReg != DefaultSegment) {
1368 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM); 2001 assert(SegmentReg >= 0 && SegmentReg < SegReg_NUM);
(...skipping 12 matching lines...) Expand all
1381 if (Shift > 0) 2014 if (Shift > 0)
1382 Str << (1u << Shift) << "*"; 2015 Str << (1u << Shift) << "*";
1383 Index->emit(Func); 2016 Index->emit(Func);
1384 Dumped = true; 2017 Dumped = true;
1385 } 2018 }
1386 // Pretty-print the Offset. 2019 // Pretty-print the Offset.
1387 bool OffsetIsZero = false; 2020 bool OffsetIsZero = false;
1388 bool OffsetIsNegative = false; 2021 bool OffsetIsNegative = false;
1389 if (Offset == NULL) { 2022 if (Offset == NULL) {
1390 OffsetIsZero = true; 2023 OffsetIsZero = true;
1391 } else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) { 2024 } else if (ConstantInteger32 *CI =
2025 llvm::dyn_cast<ConstantInteger32>(Offset)) {
1392 OffsetIsZero = (CI->getValue() == 0); 2026 OffsetIsZero = (CI->getValue() == 0);
1393 OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0); 2027 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
2028 } else if (llvm::isa<ConstantInteger64>(Offset)) {
2029 llvm_unreachable("Unexpected offset type (64-bit)");
1394 } 2030 }
1395 if (Dumped) { 2031 if (Dumped) {
1396 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 2032 if (!OffsetIsZero) { // Suppress if Offset is known to be 0
1397 if (!OffsetIsNegative) // Suppress if Offset is known to be negative 2033 if (!OffsetIsNegative) // Suppress if Offset is known to be negative
1398 Str << "+"; 2034 Str << "+";
1399 Offset->emit(Func); 2035 Offset->emit(Func);
1400 } 2036 }
1401 } else { 2037 } else {
1402 // There is only the offset. 2038 // There is only the offset.
1403 Offset->emit(Func); 2039 Offset->emit(Func);
(...skipping 19 matching lines...) Expand all
1423 if (Shift > 0) 2059 if (Shift > 0)
1424 Str << (1u << Shift) << "*"; 2060 Str << (1u << Shift) << "*";
1425 Index->dump(Func); 2061 Index->dump(Func);
1426 Dumped = true; 2062 Dumped = true;
1427 } 2063 }
1428 // Pretty-print the Offset. 2064 // Pretty-print the Offset.
1429 bool OffsetIsZero = false; 2065 bool OffsetIsZero = false;
1430 bool OffsetIsNegative = false; 2066 bool OffsetIsNegative = false;
1431 if (Offset == NULL) { 2067 if (Offset == NULL) {
1432 OffsetIsZero = true; 2068 OffsetIsZero = true;
1433 } else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) { 2069 } else if (ConstantInteger32 *CI =
2070 llvm::dyn_cast<ConstantInteger32>(Offset)) {
1434 OffsetIsZero = (CI->getValue() == 0); 2071 OffsetIsZero = (CI->getValue() == 0);
1435 OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0); 2072 OffsetIsNegative = (static_cast<int32_t>(CI->getValue()) < 0);
2073 } else if (llvm::isa<ConstantInteger64>(Offset)) {
2074 llvm_unreachable("Unexpected offset type (64-bit)");
1436 } 2075 }
1437 if (Dumped) { 2076 if (Dumped) {
1438 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 2077 if (!OffsetIsZero) { // Suppress if Offset is known to be 0
1439 if (!OffsetIsNegative) // Suppress if Offset is known to be negative 2078 if (!OffsetIsNegative) // Suppress if Offset is known to be negative
1440 Str << "+"; 2079 Str << "+";
1441 Offset->dump(Func); 2080 Offset->dump(Func);
1442 } 2081 }
1443 } else { 2082 } else {
1444 // There is only the offset. 2083 // There is only the offset.
1445 Offset->dump(Func); 2084 Offset->dump(Func);
1446 } 2085 }
1447 Str << "]"; 2086 Str << "]";
1448 } 2087 }
1449 2088
2089 x86::Address OperandX8632Mem::convertToAsmAddress(Assembler *Asm) const {
2090 int32_t Disp = 0;
2091 AssemblerFixup *Fixup = NULL;
2092 // Determine the offset (is it relocatable?)
2093 if (getOffset()) {
2094 if (ConstantInteger32 *CI =
2095 llvm::dyn_cast<ConstantInteger32>(getOffset())) {
2096 Disp = static_cast<int32_t>(CI->getValue());
2097 } else if (ConstantRelocatable *CR =
2098 llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
2099 // TODO(jvoung): CR + non-zero-offset isn't really tested yet,
2100 // since the addressing mode optimization doesn't try to combine
2101 // ConstantRelocatable with something else.
2102 assert(CR->getOffset() == 0);
2103 Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR);
2104 } else {
2105 llvm_unreachable("Unexpected offset type");
2106 }
2107 }
2108
2109 // Now convert to the various possible forms.
2110 if (getBase() && getIndex()) {
2111 return x86::Address(convertToAsmGPR(getBase()->getRegNum()),
2112 convertToAsmGPR(getIndex()->getRegNum()),
2113 x86::ScaleFactor(getShift()), Disp);
2114 } else if (getBase()) {
2115 return x86::Address(convertToAsmGPR(getBase()->getRegNum()), Disp);
2116 } else if (getIndex()) {
2117 return x86::Address(convertToAsmGPR(getIndex()->getRegNum()),
2118 x86::ScaleFactor(getShift()), Disp);
2119 } else {
2120 return x86::Address::Absolute(Disp, Fixup);
2121 }
2122 }
2123
1450 void VariableSplit::emit(const Cfg *Func) const { 2124 void VariableSplit::emit(const Cfg *Func) const {
1451 Ostream &Str = Func->getContext()->getStrEmit(); 2125 Ostream &Str = Func->getContext()->getStrEmit();
1452 assert(Var->getLocalUseNode() == NULL || 2126 assert(Var->getLocalUseNode() == NULL ||
1453 Var->getLocalUseNode() == Func->getCurrentNode()); 2127 Var->getLocalUseNode() == Func->getCurrentNode());
1454 assert(!Var->hasReg()); 2128 assert(!Var->hasReg());
1455 // The following is copied/adapted from TargetX8632::emitVariable(). 2129 // The following is copied/adapted from TargetX8632::emitVariable().
1456 const TargetLowering *Target = Func->getTarget(); 2130 const TargetLowering *Target = Func->getTarget();
1457 const Type Ty = IceType_i32; 2131 const Type Ty = IceType_i32;
1458 Str << TypeX8632Attributes[Ty].WidthString << " [" 2132 Str << TypeX8632Attributes[Ty].WidthString << " ["
1459 << Target->getRegName(Target->getFrameOrStackReg(), Ty); 2133 << Target->getRegName(Target->getFrameOrStackReg(), Ty);
(...skipping 20 matching lines...) Expand all
1480 default: 2154 default:
1481 Str << "???"; 2155 Str << "???";
1482 break; 2156 break;
1483 } 2157 }
1484 Str << "("; 2158 Str << "(";
1485 Var->dump(Func); 2159 Var->dump(Func);
1486 Str << ")"; 2160 Str << ")";
1487 } 2161 }
1488 2162
1489 } // end of namespace Ice 2163 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceInstX8632.h ('k') | src/IceInstX8632.def » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698