| Index: lib/Target/X86/MCTargetDesc/X86MCNaCl.cpp
|
| diff --git a/lib/Target/X86/MCTargetDesc/X86MCNaCl.cpp b/lib/Target/X86/MCTargetDesc/X86MCNaCl.cpp
|
| index 9b14395add44f447c4bc85cbe8fcb25466be0071..f814ca4be0db5aba85260192e0341343eaf054d4 100644
|
| --- a/lib/Target/X86/MCTargetDesc/X86MCNaCl.cpp
|
| +++ b/lib/Target/X86/MCTargetDesc/X86MCNaCl.cpp
|
| @@ -277,10 +277,7 @@ static void EmitRet(const MCOperand *AmtOp, bool Is64Bit, MCStreamer &Out) {
|
| Out.EmitInstruction(ADDInst);
|
| }
|
|
|
| - MCInst JMPInst;
|
| - JMPInst.setOpcode(Is64Bit ? X86::NACL_JMP64r : X86::NACL_JMP32r);
|
| - JMPInst.addOperand(MCOperand::CreateReg(RegTarget));
|
| - Out.EmitInstruction(JMPInst);
|
| + EmitIndirectBranch(MCOperand::CreateReg(RegTarget), Is64Bit, false, Out);
|
| }
|
|
|
| // Fix a register after being truncated to 32-bits.
|
| @@ -481,6 +478,21 @@ static void EmitREST(const MCInst &Inst, unsigned Reg32,
|
| }
|
|
|
|
|
| +namespace {
|
| +// RAII holder for the recursion guard.
|
| +class EmitRawState {
|
| + public:
|
| + EmitRawState(X86MCNaClSFIState &S) : State(S) {
|
| + State.EmitRaw = true;
|
| + }
|
| + ~EmitRawState() {
|
| + State.EmitRaw = false;
|
| + }
|
| + private:
|
| + X86MCNaClSFIState &State;
|
| +};
|
| +}
|
| +
|
| namespace llvm {
|
| // CustomExpandInstNaClX86 -
|
| // If Inst is a NaCl pseudo instruction, emits the substitute
|
| @@ -503,6 +515,13 @@ bool CustomExpandInstNaClX86(const MCInst &Inst, MCStreamer &Out,
|
| if (Out.hasRawTextSupport()) {
|
| return false;
|
| }
|
| + // If we make a call to EmitInstruction, we will be called recursively. In
|
| + // this case we just want the raw instruction to be emitted instead of
|
| + // handling the insruction here.
|
| + if (State.EmitRaw == true && !State.PrefixPass) {
|
| + return false;
|
| + }
|
| + EmitRawState E(State);
|
| unsigned Opc = Inst.getOpcode();
|
| DEBUG(dbgs() << "CustomExpandInstNaClX86("; Inst.dump(); dbgs() << ")\n");
|
| switch (Opc) {
|
| @@ -520,10 +539,11 @@ bool CustomExpandInstNaClX86(const MCInst &Inst, MCStreamer &Out,
|
| assert(State.PrefixSaved == 0);
|
| State.PrefixSaved = Opc;
|
| return true;
|
| - case X86::NACL_CALL32d:
|
| + case X86::CALLpcrel32:
|
| assert(State.PrefixSaved == 0);
|
| EmitDirectCall(Inst.getOperand(0), false, Out);
|
| return true;
|
| + case X86::CALL64pcrel32:
|
| case X86::NACL_CALL64d:
|
| assert(State.PrefixSaved == 0);
|
| EmitDirectCall(Inst.getOperand(0), true, Out);
|
|
|