| OLD | NEW | 
|    1 //===- ARMMCNaClExpander.cpp ------------------------------------*- C++ -*-===// |    1 //===- ARMMCNaClExpander.cpp ------------------------------------*- 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 // This file implements the ARMMCNaClExpander class, the ARM specific |   10 // This file implements the ARMMCNaClExpander class, the ARM specific | 
|   11 // subclass of MCNaClExpander. |   11 // subclass of MCNaClExpander. | 
|   12 // |   12 // | 
|   13 //===----------------------------------------------------------------------===// |   13 //===----------------------------------------------------------------------===// | 
|   14 #include "ARMMCNaClExpander.h" |   14 #include "ARMMCNaClExpander.h" | 
 |   15 #include "ARMAddressingModes.h" | 
 |   16 #include "MCTargetDesc/ARMBaseInfo.h" | 
|   15  |   17  | 
|   16 #include "llvm/MC/MCInst.h" |   18 #include "llvm/MC/MCInst.h" | 
|   17 #include "llvm/MC/MCInstrDesc.h" |   19 #include "llvm/MC/MCInstrDesc.h" | 
|   18 #include "llvm/MC/MCInstrInfo.h" |   20 #include "llvm/MC/MCInstrInfo.h" | 
|   19 #include "llvm/MC/MCNaClExpander.h" |   21 #include "llvm/MC/MCNaClExpander.h" | 
|   20 #include "llvm/MC/MCObjectFileInfo.h" |   22 #include "llvm/MC/MCObjectFileInfo.h" | 
|   21 #include "llvm/MC/MCRegisterInfo.h" |   23 #include "llvm/MC/MCRegisterInfo.h" | 
|   22 #include "llvm/MC/MCStreamer.h" |   24 #include "llvm/MC/MCStreamer.h" | 
|   23  |   25  | 
|   24 using namespace llvm; |   26 using namespace llvm; | 
|   25  |   27  | 
 |   28 const unsigned kBranchTargetMask = 0xC000000F; | 
 |   29 const unsigned kAlwaysPredicate = 14; | 
 |   30  | 
 |   31 static void emitBicMask(unsigned Mask, unsigned Reg, int64_t Pred, | 
 |   32                         MCStreamer &Out, const MCSubtargetInfo &STI) { | 
 |   33   MCInst Bic; | 
 |   34   const int32_t EncodedMask = ARM_AM::getSOImmVal(Mask); | 
 |   35   Bic.setOpcode(ARM::BICri); | 
 |   36   Bic.addOperand(MCOperand::CreateReg(Reg)); | 
 |   37   Bic.addOperand(MCOperand::CreateReg(Reg)); | 
 |   38   Bic.addOperand(MCOperand::CreateImm(EncodedMask)); | 
 |   39   Bic.addOperand(MCOperand::CreateImm(Pred)); | 
 |   40   Bic.addOperand(MCOperand::CreateReg(ARM::CPSR)); | 
 |   41   Bic.addOperand(MCOperand::CreateReg(0)); | 
 |   42   Out.EmitInstruction(Bic, STI); | 
 |   43 } | 
 |   44  | 
 |   45 void ARM::ARMMCNaClExpander::expandIndirectBranch(const MCInst &Inst, | 
 |   46                                                   MCStreamer &Out, | 
 |   47                                                   const MCSubtargetInfo &STI, | 
 |   48                                                   bool isCall) { | 
 |   49   assert(Inst.getOperand(0).isReg()); | 
 |   50   // No need to sandbox branch through pc | 
 |   51   if (Inst.getOperand(0).getReg() == ARM::PC || | 
 |   52       Inst.getOperand(0).getReg() == ARM::SP) | 
 |   53     return Out.EmitInstruction(Inst, STI); | 
 |   54  | 
 |   55   // Otherwise, mask target and branch through | 
 |   56   Out.EmitBundleLock(isCall); | 
 |   57  | 
 |   58   unsigned Reg = Inst.getOperand(0).getReg(); | 
 |   59   int64_t Pred = Inst.getNumOperands() > 1 ? Inst.getOperand(1).getImm() | 
 |   60                                            : kAlwaysPredicate; | 
 |   61   emitBicMask(kBranchTargetMask, Reg, Pred, Out, STI); | 
 |   62  | 
 |   63   Out.EmitInstruction(Inst, STI); | 
 |   64  | 
 |   65   Out.EmitBundleUnlock(); | 
 |   66 } | 
 |   67  | 
 |   68 void ARM::ARMMCNaClExpander::expandCall(const MCInst &Inst, MCStreamer &Out, | 
 |   69                                         const MCSubtargetInfo &STI) { | 
 |   70   // Test for indirect call | 
 |   71   if (Inst.getOperand(0).isReg()) { | 
 |   72     expandIndirectBranch(Inst, Out, STI, true); | 
 |   73   } | 
 |   74  | 
 |   75   // Otherwise, we are a direct call, so just emit | 
 |   76   else { | 
 |   77     Out.EmitInstruction(Inst, STI); | 
 |   78   } | 
 |   79 } | 
 |   80  | 
|   26 void ARM::ARMMCNaClExpander::doExpandInst(const MCInst &Inst, MCStreamer &Out, |   81 void ARM::ARMMCNaClExpander::doExpandInst(const MCInst &Inst, MCStreamer &Out, | 
|   27                                           const MCSubtargetInfo &STI) { |   82                                           const MCSubtargetInfo &STI) { | 
|   28   Out.EmitInstruction(Inst, STI); |   83   // This logic is to remain compatible with the existing pseudo instruction | 
 |   84   // expansion code in ARMMCNaCl.cpp | 
 |   85   if (SaveCount == 0) { | 
 |   86     switch (Inst.getOpcode()) { | 
 |   87     case ARM::SFI_NOP_IF_AT_BUNDLE_END: | 
 |   88       SaveCount = 3; | 
 |   89       break; | 
 |   90     case ARM::SFI_DATA_MASK: | 
 |   91       llvm_unreachable( | 
 |   92           "SFI_DATA_MASK found without preceding SFI_NOP_IF_AT_BUNDLE_END"); | 
 |   93       break; | 
 |   94     case ARM::SFI_GUARD_CALL: | 
 |   95     case ARM::SFI_GUARD_INDIRECT_CALL: | 
 |   96     case ARM::SFI_GUARD_INDIRECT_JMP: | 
 |   97     case ARM::SFI_GUARD_RETURN: | 
 |   98     case ARM::SFI_GUARD_LOADSTORE: | 
 |   99     case ARM::SFI_GUARD_LOADSTORE_TST: | 
 |  100       SaveCount = 2; | 
 |  101       break; | 
 |  102     case ARM::SFI_GUARD_SP_LOAD: | 
 |  103       SaveCount = 4; | 
 |  104       break; | 
 |  105     default: | 
 |  106       break; | 
 |  107     } | 
 |  108   } | 
 |  109  | 
 |  110   if (SaveCount == 0) { | 
 |  111     if (isIndirectBranch(Inst)) { | 
 |  112       return expandIndirectBranch(Inst, Out, STI, false); | 
 |  113     } else if (isCall(Inst)) { | 
 |  114       return expandCall(Inst, Out, STI); | 
 |  115     } else { | 
 |  116       return Out.EmitInstruction(Inst, STI); | 
 |  117     } | 
 |  118   } else { | 
 |  119     SaveCount--; | 
 |  120     Out.EmitInstruction(Inst, STI); | 
 |  121   } | 
|   29 } |  122 } | 
|   30  |  123  | 
|   31 bool ARM::ARMMCNaClExpander::expandInst(const MCInst &Inst, MCStreamer &Out, |  124 bool ARM::ARMMCNaClExpander::expandInst(const MCInst &Inst, MCStreamer &Out, | 
|   32                                         const MCSubtargetInfo &STI) { |  125                                         const MCSubtargetInfo &STI) { | 
|   33   if (Guard) |  126   if (Guard) | 
|   34     return false; |  127     return false; | 
|   35   Guard = true; |  128   Guard = true; | 
|   36  |  129  | 
|   37   doExpandInst(Inst, Out, STI); |  130   doExpandInst(Inst, Out, STI); | 
|   38  |  131  | 
|   39   Guard = false; |  132   Guard = false; | 
|   40   return true; |  133   return true; | 
|   41 } |  134 } | 
| OLD | NEW |