34 #define DEBUG_TYPE "mips-mc-nacl" 38 const unsigned IndirectBranchMaskReg = Mips::T6;
39 const unsigned LoadStoreStackMaskReg = Mips::T7;
47 std::unique_ptr<MCObjectWriter> OW,
48 std::unique_ptr<MCCodeEmitter> Emitter)
50 std::move(Emitter)) {}
52 ~MipsNaClELFStreamer()
override =
default;
57 bool PendingCall =
false;
59 bool isIndirectJump(
const MCInst &
MI) {
69 bool isStackPointerFirstOperand(
const MCInst &MI) {
74 bool isCall(
const MCInst &MI,
bool *IsIndirectCall) {
77 *IsIndirectCall =
false;
97 *IsIndirectCall =
true;
102 void emitMask(
unsigned AddrReg,
unsigned MaskReg,
117 EmitBundleLock(
false);
118 emitMask(AddrReg, IndirectBranchMaskReg, STI);
125 void sandboxLoadStoreStackChange(
const MCInst &MI,
unsigned AddrIdx,
128 EmitBundleLock(
false);
132 emitMask(BaseReg, LoadStoreStackMaskReg, STI);
138 assert((Mips::SP == SPReg) &&
"Unexpected stack-pointer register.");
139 emitMask(SPReg, LoadStoreStackMaskReg, STI);
150 if (isIndirectJump(Inst)) {
153 sandboxIndirectJump(Inst, STI);
162 bool IsSPFirstOperand = isStackPointerFirstOperand(Inst);
163 if (IsMemAccess || IsSPFirstOperand) {
164 bool MaskBefore = (IsMemAccess
167 bool MaskAfter = IsSPFirstOperand && !IsStore;
168 if (MaskBefore || MaskAfter) {
171 sandboxLoadStoreStackChange(Inst, AddrIdx, STI, MaskBefore, MaskAfter);
180 if (isCall(Inst, &IsIndirectCall)) {
185 EmitBundleLock(
true);
186 if (IsIndirectCall) {
188 emitMask(TargetReg, IndirectBranchMaskReg, STI);
260 return Reg != Mips::SP && Reg !=
Mips::T8;
264 std::unique_ptr<MCAsmBackend> TAB,
265 std::unique_ptr<MCObjectWriter> OW,
266 std::unique_ptr<MCCodeEmitter> Emitter,
268 MipsNaClELFStreamer *S =
new MipsNaClELFStreamer(
269 Context, std::move(TAB), std::move(OW), std::move(Emitter));
271 S->getAssembler().setRelaxAll(
true);
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
bool isBasePlusOffsetMemoryAccess(unsigned Opcode, unsigned *AddrIdx, bool *IsStore=nullptr)
static MCOperand createReg(unsigned Reg)
bool baseRegNeedsLoadStoreMask(unsigned Reg)
MCELFStreamer * createMipsNaClELFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > TAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter, bool RelaxAll)
unsigned getReg() const
Returns the register number.
Context object for machine code objects.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
CHAIN = SC CHAIN, Imm128 - System call.
static const unsigned MIPS_NACL_BUNDLE_ALIGN
Bitwise operators - logical and, logical or, logical xor.
Generic base class for all target subtargets.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void addOperand(const MCOperand &Op)
unsigned getOpcode() const
void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool=false) override
Overriding this function allows us to add arbitrary behaviour before the Inst is actually emitted...