32#define DEBUG_TYPE "mips-mc-nacl"
36const unsigned IndirectBranchMaskReg = Mips::T6;
37const unsigned LoadStoreStackMaskReg = Mips::T7;
44 MipsNaClELFStreamer(
MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
45 std::unique_ptr<MCObjectWriter> OW,
46 std::unique_ptr<MCCodeEmitter>
Emitter)
50 ~MipsNaClELFStreamer()
override =
default;
55 bool PendingCall =
false;
57 bool isIndirectJump(
const MCInst &
MI) {
58 if (
MI.getOpcode() == Mips::JALR) {
62 return MI.getOperand(0).getReg() == Mips::ZERO;
64 return MI.getOpcode() == Mips::JR;
67 bool isStackPointerFirstOperand(
const MCInst &
MI) {
68 return (
MI.getNumOperands() > 0 &&
MI.getOperand(0).isReg()
69 &&
MI.getOperand(0).getReg() == Mips::SP);
72 bool isCall(
const MCInst &
MI,
bool *IsIndirectCall) {
73 unsigned Opcode =
MI.getOpcode();
75 *IsIndirectCall =
false;
92 if (
MI.getOperand(0).getReg() == Mips::ZERO)
95 *IsIndirectCall =
true;
100 void emitMask(
unsigned AddrReg,
unsigned MaskReg,
113 unsigned AddrReg =
MI.getOperand(0).getReg();
116 emitMask(AddrReg, IndirectBranchMaskReg, STI);
123 void sandboxLoadStoreStackChange(
const MCInst &
MI,
unsigned AddrIdx,
129 unsigned BaseReg =
MI.getOperand(AddrIdx).getReg();
130 emitMask(BaseReg, LoadStoreStackMaskReg, STI);
135 unsigned SPReg =
MI.getOperand(0).getReg();
136 assert((Mips::SP ==
SPReg) &&
"Unexpected stack-pointer register.");
137 emitMask(
SPReg, LoadStoreStackMaskReg, STI);
148 if (isIndirectJump(Inst)) {
151 sandboxIndirectJump(Inst, STI);
156 unsigned AddrIdx = 0;
157 bool IsStore =
false;
160 bool IsSPFirstOperand = isStackPointerFirstOperand(Inst);
161 if (IsMemAccess || IsSPFirstOperand) {
162 bool MaskBefore = (IsMemAccess
165 bool MaskAfter = IsSPFirstOperand && !IsStore;
166 if (MaskBefore || MaskAfter) {
169 sandboxLoadStoreStackChange(Inst, AddrIdx, STI, MaskBefore, MaskAfter);
178 if (isCall(Inst, &IsIndirectCall)) {
184 if (IsIndirectCall) {
186 emitMask(TargetReg, IndirectBranchMaskReg, STI);
258 return Reg != Mips::SP && Reg != Mips::T8;
263 std::unique_ptr<MCObjectWriter> OW,
264 std::unique_ptr<MCCodeEmitter>
Emitter) {
265 MipsNaClELFStreamer *S =
new MipsNaClELFStreamer(
266 Context, std::move(TAB), std::move(OW), std::move(
Emitter));
dxil DXContainer Global Emitter
static constexpr Register SPReg
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(MCRegister Reg)
MCRegister 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)