OLD | NEW |
1 //=== X86MCNaCl.cpp - Expansion of NaCl pseudo-instructions --*- C++ -*-=// | 1 //=== X86MCNaCl.cpp - Expansion of NaCl pseudo-instructions --*- C++ -*-=// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
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 //===----------------------------------------------------------------------===// | 10 //===----------------------------------------------------------------------===// |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 assert(!Is64Bit); | 270 assert(!Is64Bit); |
271 MCInst ADDInst; | 271 MCInst ADDInst; |
272 unsigned ADDReg = X86::ESP; | 272 unsigned ADDReg = X86::ESP; |
273 ADDInst.setOpcode(X86::ADD32ri); | 273 ADDInst.setOpcode(X86::ADD32ri); |
274 ADDInst.addOperand(MCOperand::CreateReg(ADDReg)); | 274 ADDInst.addOperand(MCOperand::CreateReg(ADDReg)); |
275 ADDInst.addOperand(MCOperand::CreateReg(ADDReg)); | 275 ADDInst.addOperand(MCOperand::CreateReg(ADDReg)); |
276 ADDInst.addOperand(*AmtOp); | 276 ADDInst.addOperand(*AmtOp); |
277 Out.EmitInstruction(ADDInst); | 277 Out.EmitInstruction(ADDInst); |
278 } | 278 } |
279 | 279 |
280 MCInst JMPInst; | 280 EmitIndirectBranch(MCOperand::CreateReg(RegTarget), Is64Bit, false, Out); |
281 JMPInst.setOpcode(Is64Bit ? X86::NACL_JMP64r : X86::NACL_JMP32r); | |
282 JMPInst.addOperand(MCOperand::CreateReg(RegTarget)); | |
283 Out.EmitInstruction(JMPInst); | |
284 } | 281 } |
285 | 282 |
286 // Fix a register after being truncated to 32-bits. | 283 // Fix a register after being truncated to 32-bits. |
287 static void EmitRegFix(unsigned Reg64, MCStreamer &Out) { | 284 static void EmitRegFix(unsigned Reg64, MCStreamer &Out) { |
288 // lea (%rsp, %r15, 1), %rsp | 285 // lea (%rsp, %r15, 1), %rsp |
289 // We do not need to add the R15 base for the zero-based sandbox model | 286 // We do not need to add the R15 base for the zero-based sandbox model |
290 if (!FlagUseZeroBasedSandbox) { | 287 if (!FlagUseZeroBasedSandbox) { |
291 MCInst Tmp; | 288 MCInst Tmp; |
292 Tmp.setOpcode(X86::LEA64r); | 289 Tmp.setOpcode(X86::LEA64r); |
293 Tmp.addOperand(MCOperand::CreateReg(Reg64)); // DestReg | 290 Tmp.addOperand(MCOperand::CreateReg(Reg64)); // DestReg |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 SandboxedInst.getOperand(3).getImm(), // Offset | 471 SandboxedInst.getOperand(3).getImm(), // Offset |
475 SandboxedInst.getOperand(4).getReg(), // SegmentReg | 472 SandboxedInst.getOperand(4).getReg(), // SegmentReg |
476 Out); | 473 Out); |
477 } | 474 } |
478 | 475 |
479 EmitRegFix(Reg64, Out); | 476 EmitRegFix(Reg64, Out); |
480 Out.EmitBundleUnlock(); | 477 Out.EmitBundleUnlock(); |
481 } | 478 } |
482 | 479 |
483 | 480 |
| 481 namespace { |
| 482 // RAII holder for the recursion guard. |
| 483 class EmitRawState { |
| 484 public: |
| 485 EmitRawState(X86MCNaClSFIState &S) : State(S) { |
| 486 State.EmitRaw = true; |
| 487 } |
| 488 ~EmitRawState() { |
| 489 State.EmitRaw = false; |
| 490 } |
| 491 private: |
| 492 X86MCNaClSFIState &State; |
| 493 }; |
| 494 } |
| 495 |
484 namespace llvm { | 496 namespace llvm { |
485 // CustomExpandInstNaClX86 - | 497 // CustomExpandInstNaClX86 - |
486 // If Inst is a NaCl pseudo instruction, emits the substitute | 498 // If Inst is a NaCl pseudo instruction, emits the substitute |
487 // expansion to the MCStreamer and returns true. | 499 // expansion to the MCStreamer and returns true. |
488 // Otherwise, returns false. | 500 // Otherwise, returns false. |
489 // | 501 // |
490 // NOTE: Each time this function calls Out.EmitInstruction(), it will be | 502 // NOTE: Each time this function calls Out.EmitInstruction(), it will be |
491 // called again recursively to rewrite the new instruction being emitted. | 503 // called again recursively to rewrite the new instruction being emitted. |
492 // Care must be taken to ensure that this does not result in an infinite | 504 // Care must be taken to ensure that this does not result in an infinite |
493 // loop. Also, global state must be managed carefully so that it is | 505 // loop. Also, global state must be managed carefully so that it is |
494 // consistent during recursive calls. | 506 // consistent during recursive calls. |
495 // | 507 // |
496 // We need global state to keep track of the explicit prefix (PREFIX_*) | 508 // We need global state to keep track of the explicit prefix (PREFIX_*) |
497 // instructions. Unfortunately, the assembly parser prefers to generate | 509 // instructions. Unfortunately, the assembly parser prefers to generate |
498 // these instead of combined instructions. At this time, having only | 510 // these instead of combined instructions. At this time, having only |
499 // one explicit prefix is supported. | 511 // one explicit prefix is supported. |
500 bool CustomExpandInstNaClX86(const MCInst &Inst, MCStreamer &Out, | 512 bool CustomExpandInstNaClX86(const MCInst &Inst, MCStreamer &Out, |
501 X86MCNaClSFIState &State) { | 513 X86MCNaClSFIState &State) { |
502 // If we are emitting to .s, just emit all pseudo-instructions directly. | 514 // If we are emitting to .s, just emit all pseudo-instructions directly. |
503 if (Out.hasRawTextSupport()) { | 515 if (Out.hasRawTextSupport()) { |
504 return false; | 516 return false; |
505 } | 517 } |
| 518 // If we make a call to EmitInstruction, we will be called recursively. In |
| 519 // this case we just want the raw instruction to be emitted instead of |
| 520 // handling the insruction here. |
| 521 if (State.EmitRaw == true && !State.PrefixPass) { |
| 522 return false; |
| 523 } |
| 524 EmitRawState E(State); |
506 unsigned Opc = Inst.getOpcode(); | 525 unsigned Opc = Inst.getOpcode(); |
507 DEBUG(dbgs() << "CustomExpandInstNaClX86("; Inst.dump(); dbgs() << ")\n"); | 526 DEBUG(dbgs() << "CustomExpandInstNaClX86("; Inst.dump(); dbgs() << ")\n"); |
508 switch (Opc) { | 527 switch (Opc) { |
509 case X86::LOCK_PREFIX: | 528 case X86::LOCK_PREFIX: |
510 case X86::REP_PREFIX: | 529 case X86::REP_PREFIX: |
511 case X86::REPNE_PREFIX: | 530 case X86::REPNE_PREFIX: |
512 case X86::REX64_PREFIX: | 531 case X86::REX64_PREFIX: |
513 // Ugly hack because LLVM AsmParser is not smart enough to combine | 532 // Ugly hack because LLVM AsmParser is not smart enough to combine |
514 // prefixes back into the instruction they modify. | 533 // prefixes back into the instruction they modify. |
515 if (State.PrefixPass) { | 534 if (State.PrefixPass) { |
516 State.PrefixPass = false; | 535 State.PrefixPass = false; |
517 State.PrefixSaved = 0; | 536 State.PrefixSaved = 0; |
518 return false; | 537 return false; |
519 } | 538 } |
520 assert(State.PrefixSaved == 0); | 539 assert(State.PrefixSaved == 0); |
521 State.PrefixSaved = Opc; | 540 State.PrefixSaved = Opc; |
522 return true; | 541 return true; |
523 case X86::NACL_CALL32d: | 542 case X86::CALLpcrel32: |
524 assert(State.PrefixSaved == 0); | 543 assert(State.PrefixSaved == 0); |
525 EmitDirectCall(Inst.getOperand(0), false, Out); | 544 EmitDirectCall(Inst.getOperand(0), false, Out); |
526 return true; | 545 return true; |
| 546 case X86::CALL64pcrel32: |
527 case X86::NACL_CALL64d: | 547 case X86::NACL_CALL64d: |
528 assert(State.PrefixSaved == 0); | 548 assert(State.PrefixSaved == 0); |
529 EmitDirectCall(Inst.getOperand(0), true, Out); | 549 EmitDirectCall(Inst.getOperand(0), true, Out); |
530 return true; | 550 return true; |
531 case X86::NACL_CALL32r: | 551 case X86::NACL_CALL32r: |
532 assert(State.PrefixSaved == 0); | 552 assert(State.PrefixSaved == 0); |
533 EmitIndirectBranch(Inst.getOperand(0), false, true, Out); | 553 EmitIndirectBranch(Inst.getOperand(0), false, true, Out); |
534 return true; | 554 return true; |
535 case X86::NACL_CALL64r: | 555 case X86::NACL_CALL64r: |
536 assert(State.PrefixSaved == 0); | 556 assert(State.PrefixSaved == 0); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 | 854 |
835 unsigned DemoteRegTo32_(unsigned RegIn) { | 855 unsigned DemoteRegTo32_(unsigned RegIn) { |
836 if (RegIn == 0) | 856 if (RegIn == 0) |
837 return 0; | 857 return 0; |
838 unsigned RegOut = getX86SubSuperRegister_(RegIn, MVT::i32, false); | 858 unsigned RegOut = getX86SubSuperRegister_(RegIn, MVT::i32, false); |
839 assert(RegOut != 0); | 859 assert(RegOut != 0); |
840 return RegOut; | 860 return RegOut; |
841 } | 861 } |
842 } //namespace | 862 } //namespace |
843 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | 863 // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
OLD | NEW |