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 182 matching lines...) Loading... |
193 if (TargetFalse == OldNode) { | 193 if (TargetFalse == OldNode) { |
194 TargetFalse = NewNode; | 194 TargetFalse = NewNode; |
195 return true; | 195 return true; |
196 } else if (TargetTrue == OldNode) { | 196 } else if (TargetTrue == OldNode) { |
197 TargetTrue = NewNode; | 197 TargetTrue = NewNode; |
198 return true; | 198 return true; |
199 } | 199 } |
200 return false; | 200 return false; |
201 } | 201 } |
202 | 202 |
| 203 InstX8632Jmp::InstX8632Jmp(Cfg *Func, Operand *Target) |
| 204 : InstX8632(Func, InstX8632::Jmp, 1, nullptr) { |
| 205 addSource(Target); |
| 206 } |
| 207 |
203 InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget) | 208 InstX8632Call::InstX8632Call(Cfg *Func, Variable *Dest, Operand *CallTarget) |
204 : InstX8632(Func, InstX8632::Call, 1, Dest) { | 209 : InstX8632(Func, InstX8632::Call, 1, Dest) { |
205 HasSideEffects = true; | 210 HasSideEffects = true; |
206 addSource(CallTarget); | 211 addSource(CallTarget); |
207 } | 212 } |
208 | 213 |
209 InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, | 214 InstX8632Cmov::InstX8632Cmov(Cfg *Func, Variable *Dest, Operand *Source, |
210 CondX86::BrCond Condition) | 215 CondX86::BrCond Condition) |
211 : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(Condition) { | 216 : InstX8632(Func, InstX8632::Cmov, 2, Dest), Condition(Condition) { |
212 // The final result is either the original Dest, or Source, so mark | 217 // The final result is either the original Dest, or Source, so mark |
(...skipping 230 matching lines...) Loading... |
443 if (Label) { | 448 if (Label) { |
444 Str << ", label %" << Label->getName(Func); | 449 Str << ", label %" << Label->getName(Func); |
445 } else { | 450 } else { |
446 Str << ", label %" << getTargetTrue()->getName(); | 451 Str << ", label %" << getTargetTrue()->getName(); |
447 if (getTargetFalse()) { | 452 if (getTargetFalse()) { |
448 Str << ", label %" << getTargetFalse()->getName(); | 453 Str << ", label %" << getTargetFalse()->getName(); |
449 } | 454 } |
450 } | 455 } |
451 } | 456 } |
452 | 457 |
| 458 void InstX8632Jmp::emit(const Cfg *Func) const { |
| 459 if (!ALLOW_DUMP) |
| 460 return; |
| 461 Ostream &Str = Func->getContext()->getStrEmit(); |
| 462 assert(getSrcSize() == 1); |
| 463 Str << "\tjmp\t*"; |
| 464 getSrc(0)->emit(Func); |
| 465 } |
| 466 |
| 467 void InstX8632Jmp::emitIAS(const Cfg *Func) const { |
| 468 // Note: Adapted (mostly copied) from InstX8632Call::emitIAS(). |
| 469 x86::AssemblerX86 *Asm = Func->getAssembler<x86::AssemblerX86>(); |
| 470 Operand *Target = getSrc(0); |
| 471 if (const auto Var = llvm::dyn_cast<Variable>(Target)) { |
| 472 if (Var->hasReg()) { |
| 473 Asm->jmp(RegX8632::getEncodedGPR(Var->getRegNum())); |
| 474 } else { |
| 475 // The jmp instruction with a memory operand should be possible |
| 476 // to encode, but it isn't a valid sandboxed instruction, and |
| 477 // there shouldn't be a register allocation issue to jump |
| 478 // through a scratch register, so we don't really need to bother |
| 479 // implementing it. |
| 480 llvm::report_fatal_error("Assembler can't jmp to memory operand"); |
| 481 } |
| 482 } else if (const auto Mem = llvm::dyn_cast<OperandX8632Mem>(Target)) { |
| 483 assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); |
| 484 llvm::report_fatal_error("Assembler can't jmp to memory operand"); |
| 485 } else if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(Target)) { |
| 486 assert(CR->getOffset() == 0 && "We only support jumping to a function"); |
| 487 Asm->jmp(CR); |
| 488 } else if (const auto Imm = llvm::dyn_cast<ConstantInteger32>(Target)) { |
| 489 // NaCl trampoline calls refer to an address within the sandbox directly. |
| 490 // This is usually only needed for non-IRT builds and otherwise not |
| 491 // very portable or stable. For this, we would use the 0xE8 opcode |
| 492 // (relative version of call) and there should be a PC32 reloc too. |
| 493 // The PC32 reloc will have symbol index 0, and the absolute address |
| 494 // would be encoded as an offset relative to the next instruction. |
| 495 // TODO(jvoung): Do we need to support this? |
| 496 (void)Imm; |
| 497 llvm::report_fatal_error("Unexpected jmp to absolute address"); |
| 498 } else { |
| 499 llvm::report_fatal_error("Unexpected operand type"); |
| 500 } |
| 501 } |
| 502 |
| 503 void InstX8632Jmp::dump(const Cfg *Func) const { |
| 504 if (!ALLOW_DUMP) |
| 505 return; |
| 506 Ostream &Str = Func->getContext()->getStrDump(); |
| 507 Str << "jmp "; |
| 508 getSrc(0)->dump(Func); |
| 509 } |
| 510 |
453 void InstX8632Call::emit(const Cfg *Func) const { | 511 void InstX8632Call::emit(const Cfg *Func) const { |
454 if (!ALLOW_DUMP) | 512 if (!ALLOW_DUMP) |
455 return; | 513 return; |
456 Ostream &Str = Func->getContext()->getStrEmit(); | 514 Ostream &Str = Func->getContext()->getStrEmit(); |
457 assert(getSrcSize() == 1); | 515 assert(getSrcSize() == 1); |
458 Str << "\tcall\t"; | 516 Str << "\tcall\t"; |
459 if (const auto CallTarget = | 517 if (const auto CallTarget = |
460 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { | 518 llvm::dyn_cast<ConstantRelocatable>(getCallTarget())) { |
461 // TODO(stichnot): All constant targets should suppress the '$', | 519 // TODO(stichnot): All constant targets should suppress the '$', |
462 // not just relocatables. | 520 // not just relocatables. |
(...skipping 2424 matching lines...) Loading... |
2887 } | 2945 } |
2888 Str << "("; | 2946 Str << "("; |
2889 if (Func) | 2947 if (Func) |
2890 Var->dump(Func); | 2948 Var->dump(Func); |
2891 else | 2949 else |
2892 Var->dump(Str); | 2950 Var->dump(Str); |
2893 Str << ")"; | 2951 Str << ")"; |
2894 } | 2952 } |
2895 | 2953 |
2896 } // end of namespace Ice | 2954 } // end of namespace Ice |
OLD | NEW |