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