#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/raw_ostream.h"
// Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
// so we have to special check for them.
unsigned Opcode = TmpInst.getOpcode();
- if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
+ if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) &&
+ (Opcode != Mips::SLL_MM) && !Binary)
llvm_unreachable("unimplemented opcode in EncodeInstruction()");
if (STI.getFeatureBits() & Mips::FeatureMicroMips) {
return 0;
}
+/// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch
+/// target operand. If the machine operand requires relocation,
+/// record the relocation and return zero.
+unsigned MipsMCCodeEmitter::
+getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+
+ const MCOperand &MO = MI.getOperand(OpNo);
+
+ // If the destination is an immediate, divide by 2.
+ if (MO.isImm()) return MO.getImm() >> 1;
+
+ assert(MO.isExpr() &&
+ "getBranchTargetOpValueMM expects only expressions or immediates");
+
+ const MCExpr *Expr = MO.getExpr();
+ Fixups.push_back(MCFixup::Create(0, Expr,
+ MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1)));
+ return 0;
+}
+
+/// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS
+/// 10-bit branch target operand. If the machine operand requires relocation,
+/// record the relocation and return zero.
+unsigned MipsMCCodeEmitter::
+getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+
+ const MCOperand &MO = MI.getOperand(OpNo);
+
+ // If the destination is an immediate, divide by 2.
+ if (MO.isImm()) return MO.getImm() >> 1;
+
+ assert(MO.isExpr() &&
+ "getBranchTargetOpValuePC10 expects only expressions or immediates");
+
+ const MCExpr *Expr = MO.getExpr();
+ Fixups.push_back(MCFixup::Create(0, Expr,
+ MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1)));
+ return 0;
+}
+
/// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
/// target operand. If the machine operand requires relocation,
/// record the relocation and return zero.
return (OffBits & 0xFFFF) | RegBits;
}
+unsigned MipsMCCodeEmitter::
+getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
+ assert(MI.getOperand(OpNo).isReg());
+ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
+ Fixups, STI) << 4;
+ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
+ Fixups, STI);
+
+ return (OffBits & 0xF) | RegBits;
+}
+
+unsigned MipsMCCodeEmitter::
+getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
+ assert(MI.getOperand(OpNo).isReg());
+ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
+ Fixups, STI) << 4;
+ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
+ Fixups, STI) >> 1;
+
+ return (OffBits & 0xF) | RegBits;
+}
+
+unsigned MipsMCCodeEmitter::
+getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
+ assert(MI.getOperand(OpNo).isReg());
+ unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
+ Fixups, STI) << 4;
+ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
+ Fixups, STI) >> 2;
+
+ return (OffBits & 0xF) | RegBits;
+}
+
+unsigned MipsMCCodeEmitter::
+getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
+ assert(MI.getOperand(OpNo).isReg() &&
+ MI.getOperand(OpNo).getReg() == Mips::SP &&
+ "Unexpected base register!");
+ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
+ Fixups, STI) >> 2;
+
+ return OffBits & 0x1F;
+}
+
unsigned MipsMCCodeEmitter::
getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
return (OffBits & 0x0FFF) | RegBits;
}
+unsigned MipsMCCodeEmitter::
+getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ // opNum can be invalid if instruction had reglist as operand
+ // MemOperand is always last operand of instruction (base + offset)
+ switch (MI.getOpcode()) {
+ default:
+ break;
+ case Mips::SWM16_MM:
+ case Mips::LWM16_MM:
+ OpNo = MI.getNumOperands() - 2;
+ break;
+ }
+
+ // Offset is encoded in bits 4-0.
+ assert(MI.getOperand(OpNo).isReg());
+ // Base register is always SP - thus it is not encoded.
+ assert(MI.getOperand(OpNo+1).isImm());
+ unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
+
+ return ((OffBits >> 2) & 0x0F);
+}
+
unsigned
MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
return res;
}
+unsigned
+MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ return (MI.getNumOperands() - 4);
+}
+
+unsigned
+MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
+}
+
#include "MipsGenMCCodeEmitter.inc"