33#define DEBUG_TYPE "mips-mc-nacl"
37const unsigned IndirectBranchMaskReg = Mips::T6;
38const unsigned LoadStoreStackMaskReg = Mips::T7;
45 MipsNaClELFStreamer(
MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
46 std::unique_ptr<MCObjectWriter> OW,
47 std::unique_ptr<MCCodeEmitter>
Emitter)
51 ~MipsNaClELFStreamer()
override =
default;
56 bool PendingCall =
false;
58 bool isIndirectJump(
const MCInst &
MI) {
59 if (
MI.getOpcode() == Mips::JALR) {
63 return MI.getOperand(0).getReg() == Mips::ZERO;
65 return MI.getOpcode() == Mips::JR;
68 bool isStackPointerFirstOperand(
const MCInst &
MI) {
69 return (
MI.getNumOperands() > 0 &&
MI.getOperand(0).isReg()
70 &&
MI.getOperand(0).getReg() == Mips::SP);
73 bool isCall(
const MCInst &
MI,
bool *IsIndirectCall) {
74 unsigned Opcode =
MI.getOpcode();
76 *IsIndirectCall =
false;
93 if (
MI.getOperand(0).getReg() == Mips::ZERO)
96 *IsIndirectCall =
true;
101 void emitMask(
unsigned AddrReg,
unsigned MaskReg,
114 unsigned AddrReg =
MI.getOperand(0).getReg();
117 emitMask(AddrReg, IndirectBranchMaskReg, STI);
124 void sandboxLoadStoreStackChange(
const MCInst &
MI,
unsigned AddrIdx,
130 unsigned BaseReg =
MI.getOperand(AddrIdx).getReg();
131 emitMask(BaseReg, LoadStoreStackMaskReg, STI);
136 unsigned SPReg =
MI.getOperand(0).getReg();
137 assert((Mips::SP == SPReg) &&
"Unexpected stack-pointer register.");
138 emitMask(SPReg, LoadStoreStackMaskReg, STI);
149 if (isIndirectJump(Inst)) {
152 sandboxIndirectJump(Inst, STI);
157 unsigned AddrIdx = 0;
158 bool IsStore =
false;
161 bool IsSPFirstOperand = isStackPointerFirstOperand(Inst);
162 if (IsMemAccess || IsSPFirstOperand) {
163 bool MaskBefore = (IsMemAccess
166 bool MaskAfter = IsSPFirstOperand && !IsStore;
167 if (MaskBefore || MaskAfter) {
170 sandboxLoadStoreStackChange(Inst, AddrIdx, STI, MaskBefore, MaskAfter);
179 if (isCall(Inst, &IsIndirectCall)) {
185 if (IsIndirectCall) {
187 emitMask(TargetReg, IndirectBranchMaskReg, STI);
259 return Reg != Mips::SP && Reg != Mips::T8;
264 std::unique_ptr<MCObjectWriter> OW,
265 std::unique_ptr<MCCodeEmitter>
Emitter) {
266 MipsNaClELFStreamer *S =
new MipsNaClELFStreamer(
267 Context, std::move(TAB), std::move(OW), std::move(
Emitter));
dxil DXContainer Global Emitter
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Context object for machine code objects.
void emitBundleLock(bool AlignToEnd) override
The following instructions are a bundle-locked group.
void emitBundleUnlock() override
Ends a bundle-locked group.
Instances of this class represent a single low-level machine instruction.
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
static MCOperand createReg(unsigned Reg)
unsigned getReg() const
Returns the register number.
Generic base class for all target subtargets.
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Overriding this function allows us to add arbitrary behaviour before the Inst is actually emitted.
This is an optimization pass for GlobalISel generic memory operations.
bool isBasePlusOffsetMemoryAccess(unsigned Opcode, unsigned *AddrIdx, bool *IsStore=nullptr)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
static const Align MIPS_NACL_BUNDLE_ALIGN
bool baseRegNeedsLoadStoreMask(unsigned Reg)
MCELFStreamer * createMipsNaClELFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > TAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter)