| OLD | NEW |
| 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { | 482 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { |
| 483 (void)Mem; | 483 (void)Mem; |
| 484 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 484 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 485 llvm::report_fatal_error("Assembler can't jmp to memory operand"); | 485 llvm::report_fatal_error("Assembler can't jmp to memory operand"); |
| 486 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { | 486 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { |
| 487 assert(CR->getOffset() == 0 && "We only support jumping to a function"); | 487 assert(CR->getOffset() == 0 && "We only support jumping to a function"); |
| 488 Asm->jmp(CR); | 488 Asm->jmp(CR); |
| 489 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { | 489 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { |
| 490 // NaCl trampoline calls refer to an address within the sandbox directly. | 490 // NaCl trampoline calls refer to an address within the sandbox directly. |
| 491 // This is usually only needed for non-IRT builds and otherwise not | 491 // This is usually only needed for non-IRT builds and otherwise not |
| 492 // very portable or stable. For this, we would use the 0xE8 opcode | 492 // very portable or stable. Usually this is only done for "calls" |
| 493 // (relative version of call) and there should be a PC32 reloc too. | 493 // and not jumps. |
| 494 // The PC32 reloc will have symbol index 0, and the absolute address | 494 // TODO(jvoung): Support this when there is a lowering that |
| 495 // would be encoded as an offset relative to the next instruction. | 495 // actually triggers this case. |
| 496 // TODO(jvoung): Do we need to support this? | |
| 497 (void)Imm; | 496 (void)Imm; |
| 498 llvm::report_fatal_error("Unexpected jmp to absolute address"); | 497 llvm::report_fatal_error("Unexpected jmp to absolute address"); |
| 499 } else { | 498 } else { |
| 500 llvm::report_fatal_error("Unexpected operand type"); | 499 llvm::report_fatal_error("Unexpected operand type"); |
| 501 } | 500 } |
| 502 } | 501 } |
| 503 | 502 |
| 504 void InstX8632Jmp::dump(const Cfg *Func) const { | 503 void InstX8632Jmp::dump(const Cfg *Func) const { |
| 505 if (!ALLOW_DUMP) | 504 if (!ALLOW_DUMP) |
| 506 return; | 505 return; |
| 507 Ostream &Str = Func->getContext()->getStrDump(); | 506 Ostream &Str = Func->getContext()->getStrDump(); |
| 508 Str << "jmp "; | 507 Str << "jmp "; |
| 509 getJmpTarget()->dump(Func); | 508 getJmpTarget()->dump(Func); |
| 510 } | 509 } |
| 511 | 510 |
| 512 void InstX8632Call::emit(const Cfg *Func) const { | 511 void InstX8632Call::emit(const Cfg *Func) const { |
| 513 if (!ALLOW_DUMP) | 512 if (!ALLOW_DUMP) |
| 514 return; | 513 return; |
| 515 Ostream &Str = Func->getContext()->getStrEmit(); | 514 Ostream &Str = Func->getContext()->getStrEmit(); |
| 516 assert(getSrcSize() == 1); | 515 assert(getSrcSize() == 1); |
| 517 Str << "\tcall\t"; | 516 Str << "\tcall\t"; |
| 518 if (const auto CallTarget = | 517 if (const auto CallTarget = llvm::dyn_cast<Constant>(getCallTarget())) { |
| 519 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { | |
| 520 // TODO(stichnot): All constant targets should suppress the '$', | |
| 521 // not just relocatables. | |
| 522 CallTarget->emitWithoutDollar(Func->getContext()); | 518 CallTarget->emitWithoutDollar(Func->getContext()); |
| 523 } else { | 519 } else { |
| 524 Str << "*"; | 520 Str << "*"; |
| 525 getCallTarget()->emit(Func); | 521 getCallTarget()->emit(Func); |
| 526 } | 522 } |
| 527 Func->getTarget()->resetStackAdjustment(); | 523 Func->getTarget()->resetStackAdjustment(); |
| 528 } | 524 } |
| 529 | 525 |
| 530 void InstX8632Call::emitIAS(const Cfg *Func) const { | 526 void InstX8632Call::emitIAS(const Cfg *Func) const { |
| 531 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); | 527 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 532 Operand *Target = getCallTarget(); | 528 Operand *Target = getCallTarget(); |
| 533 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { | 529 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { |
| 534 if (Var->hasReg()) { | 530 if (Var->hasReg()) { |
| 535 Asm->call(RegX8632::getEncodedGPR(Var->getRegNum())); | 531 Asm->call(RegX8632::getEncodedGPR(Var->getRegNum())); |
| 536 } else { | 532 } else { |
| 537 Asm->call(static_cast<TargetX8632 *>(Func->getTarget()) | 533 Asm->call(static_cast<TargetX8632 *>(Func->getTarget()) |
| 538 ->stackVarToAsmOperand(Var)); | 534 ->stackVarToAsmOperand(Var)); |
| 539 } | 535 } |
| 540 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { | 536 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { |
| 541 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); | 537 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 542 Asm->call(Mem->toAsmAddress(Asm)); | 538 Asm->call(Mem->toAsmAddress(Asm)); |
| 543 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { | 539 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { |
| 544 assert(CR->getOffset() == 0 && "We only support calling a function"); | 540 assert(CR->getOffset() == 0 && "We only support calling a function"); |
| 545 Asm->call(CR); | 541 Asm->call(CR); |
| 546 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { | 542 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { |
| 547 // NaCl trampoline calls refer to an address within the sandbox directly. | 543 Asm->call(x86::Immediate(Imm->getValue())); |
| 548 // This is usually only needed for non-IRT builds and otherwise not | |
| 549 // very portable or stable. For this, we would use the 0xE8 opcode | |
| 550 // (relative version of call) and there should be a PC32 reloc too. | |
| 551 // The PC32 reloc will have symbol index 0, and the absolute address | |
| 552 // would be encoded as an offset relative to the next instruction. | |
| 553 // TODO(jvoung): Do we need to support this? | |
| 554 (void)Imm; | |
| 555 llvm_unreachable("Unexpected call to absolute address"); | |
| 556 } else { | 544 } else { |
| 557 llvm_unreachable("Unexpected operand type"); | 545 llvm_unreachable("Unexpected operand type"); |
| 558 } | 546 } |
| 559 Func->getTarget()->resetStackAdjustment(); | 547 Func->getTarget()->resetStackAdjustment(); |
| 560 } | 548 } |
| 561 | 549 |
| 562 void InstX8632Call::dump(const Cfg *Func) const { | 550 void InstX8632Call::dump(const Cfg *Func) const { |
| 563 if (!ALLOW_DUMP) | 551 if (!ALLOW_DUMP) |
| 564 return; | 552 return; |
| 565 Ostream &Str = Func->getContext()->getStrDump(); | 553 Ostream &Str = Func->getContext()->getStrDump(); |
| (...skipping 2370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2936 } | 2924 } |
| 2937 Str << "("; | 2925 Str << "("; |
| 2938 if (Func) | 2926 if (Func) |
| 2939 Var->dump(Func); | 2927 Var->dump(Func); |
| 2940 else | 2928 else |
| 2941 Var->dump(Str); | 2929 Var->dump(Str); |
| 2942 Str << ")"; | 2930 Str << ")"; |
| 2943 } | 2931 } |
| 2944 | 2932 |
| 2945 } // end of namespace Ice | 2933 } // end of namespace Ice |
| OLD | NEW |