37#define DEBUG_TYPE "mccodeemitter"
39#define GET_INSTRMAP_INFO
40#include "MipsGenInstrInfo.inc"
41#undef GET_INSTRMAP_INFO
91void MipsMCCodeEmitter::LowerCompactBranch(
MCInst& Inst)
const {
102 assert(Reg0 != Reg1 &&
"Instruction has bad operands ($rs == $rt)!");
108 }
else if (Inst.
getOpcode() == Mips::BNVC_MMR6 ||
120 return STI.
hasFeature(Mips::FeatureMicroMips);
142 switch (
MI.getOpcode()) {
156 case Mips::BOVC_MMR6:
158 case Mips::BNVC_MMR6:
159 LowerCompactBranch(TmpInst);
162 size_t N = Fixups.size();
168 const unsigned Opcode = TmpInst.
getOpcode();
169 if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) &&
170 (Opcode != Mips::SLL_MM) && (Opcode != Mips::SLL_MMR6) && !Binary)
174 if (isMicroMips(STI)) {
175 if (isMips32r6(STI)) {
176 NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
178 NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
181 NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips);
185 NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp);
187 if (NewOpcode != -1) {
188 if (Fixups.size() >
N)
195 if (((
MI.getOpcode() == Mips::MOVEP_MM) ||
196 (
MI.getOpcode() == Mips::MOVEP_MMR6))) {
198 Binary = (Binary & 0xFFFFFC7F) | (RegPair << 7);
211 support::endian::write<uint16_t>(CB, Binary,
Endian);
212 }
else if (IsLittleEndian && isMicroMips(STI)) {
213 support::endian::write<uint16_t>(CB, Binary >> 16,
Endian);
214 support::endian::write<uint16_t>(CB, Binary & 0xffff,
Endian);
216 support::endian::write<uint32_t>(CB, Binary,
Endian);
233 "getBranchTargetOpValue expects only expressions or immediates");
255 "getBranchTargetOpValue expects only expressions or immediates");
278 "getBranchTargetOpValueMMR6 expects only expressions or immediates");
301 "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates");
323 "getBranchTargetOpValueMM expects only expressions or immediates");
344 "getBranchTargetOpValuePC10 expects only expressions or immediates");
365 "getBranchTargetOpValueMM expects only expressions or immediates");
370 fixup_MICROMIPS_PC16_S1)));
387 "getBranchTarget21OpValue expects only expressions or immediates");
409 "getBranchTarget21OpValueMM expects only expressions or immediates");
431 "getBranchTarget26OpValue expects only expressions or immediates");
453 "getBranchTarget26OpValueMM expects only expressions or immediates");
474 "getJumpOffset16OpValue expects only expressions or an immediate");
495 "getJumpTargetOpValue expects only expressions or an immediate");
512 "getJumpTargetOpValueMM expects only expressions or an immediate");
533 "getUImm5Lsl2Encoding expects only expressions or an immediate");
570 unsigned Binary = (MO.
getImm() >> 2) & 0x0000ffff;
571 return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff));
582 if (Expr->evaluateAsAbsolute(Res))
587 return cast<MCConstantExpr>(Expr)->getValue();
593 Res +=
getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
598 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
726 unsigned Reg = MO.
getReg();
729 }
else if (MO.
isImm()) {
730 return static_cast<unsigned>(MO.
getImm());
732 return static_cast<unsigned>(bit_cast<double>(MO.
getDFPImm()));
741template <
unsigned ShiftAmount>
746 assert(
MI.getOperand(OpNo).isReg());
752 OffBits >>= ShiftAmount;
754 return (OffBits & 0xFFFF) | RegBits;
762 assert(
MI.getOperand(OpNo).isReg());
768 return (OffBits & 0xF) | RegBits;
776 assert(
MI.getOperand(OpNo).isReg());
782 return (OffBits & 0xF) | RegBits;
790 assert(
MI.getOperand(OpNo).isReg());
796 return (OffBits & 0xF) | RegBits;
804 assert(
MI.getOperand(OpNo).isReg() &&
805 (
MI.getOperand(OpNo).getReg() == Mips::SP ||
806 MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
807 "Unexpected base register!");
811 return OffBits & 0x1F;
819 assert(
MI.getOperand(OpNo).isReg() &&
820 MI.getOperand(OpNo).getReg() == Mips::GP &&
821 "Unexpected base register!");
826 return OffBits & 0x7F;
834 assert(
MI.getOperand(OpNo).isReg());
840 return (OffBits & 0x1FF) | RegBits;
848 assert(
MI.getOperand(OpNo).isReg());
853 return (OffBits & 0x07FF) | RegBits;
862 switch (
MI.getOpcode()) {
867 OpNo =
MI.getNumOperands() - 2;
872 assert(
MI.getOperand(OpNo).isReg());
877 return (OffBits & 0x0FFF) | RegBits;
885 assert(
MI.getOperand(OpNo).isReg());
890 return (OffBits & 0xFFFF) | RegBits;
899 switch (
MI.getOpcode()) {
903 case Mips::SWM16_MMR6:
905 case Mips::LWM16_MMR6:
906 OpNo =
MI.getNumOperands() - 2;
911 assert(
MI.getOperand(OpNo).isReg());
913 assert(
MI.getOperand(OpNo+1).isImm());
916 return ((OffBits >> 2) & 0x0F);
925 assert(
MI.getOperand(OpNo-1).isImm());
926 assert(
MI.getOperand(OpNo).isImm());
930 return Position +
Size - 1;
933template <
unsigned Bits,
int Offset>
938 assert(
MI.getOperand(OpNo).isImm());
957 "getSimm19Lsl2Encoding expects only expressions or an immediate");
979 "getSimm18Lsl2Encoding expects only expressions or an immediate");
992 assert(
MI.getOperand(OpNo).isImm());
1001 assert(
MI.getOperand(OpNo).isImm());
1005 case 128:
return 0x0;
1012 case 15:
return 0x7;
1013 case 16:
return 0x8;
1014 case 31:
return 0x9;
1015 case 32:
return 0xa;
1016 case 63:
return 0xb;
1017 case 64:
return 0xc;
1018 case 255:
return 0xd;
1019 case 32768:
return 0xe;
1020 case 65535:
return 0xf;
1034 for (
unsigned I = OpNo,
E =
MI.getNumOperands() - 2;
I <
E; ++
I) {
1035 unsigned Reg =
MI.getOperand(
I).getReg();
1049 return (
MI.getNumOperands() - 4);
1058 if (
MI.getOperand(0).getReg() == Mips::A1 &&
1059 MI.getOperand(1).getReg() == Mips::A2)
1061 else if (
MI.getOperand(0).getReg() == Mips::A1 &&
1062 MI.getOperand(1).getReg() == Mips::A3)
1064 else if (
MI.getOperand(0).getReg() == Mips::A2 &&
1065 MI.getOperand(1).getReg() == Mips::A3)
1067 else if (
MI.getOperand(0).getReg() == Mips::A0 &&
1068 MI.getOperand(1).getReg() == Mips::S5)
1070 else if (
MI.getOperand(0).getReg() == Mips::A0 &&
1071 MI.getOperand(1).getReg() == Mips::S6)
1073 else if (
MI.getOperand(0).getReg() == Mips::A0 &&
1074 MI.getOperand(1).getReg() == Mips::A1)
1076 else if (
MI.getOperand(0).getReg() == Mips::A0 &&
1077 MI.getOperand(1).getReg() == Mips::A2)
1079 else if (
MI.getOperand(0).getReg() == Mips::A0 &&
1080 MI.getOperand(1).getReg() == Mips::A3)
1090 assert(((OpNo == 2) || (OpNo == 3)) &&
1091 "Unexpected OpNo for movep operand encoding!");
1094 assert(
Op.isReg() &&
"Operand of movep is not a register!");
1095 switch (
Op.getReg()) {
1098 case Mips::ZERO:
return 0;
1099 case Mips::S1:
return 1;
1100 case Mips::V0:
return 2;
1101 case Mips::V1:
return 3;
1102 case Mips::S0:
return 4;
1103 case Mips::S2:
return 5;
1104 case Mips::S3:
return 6;
1105 case Mips::S4:
return 7;
1114 assert(MO.
isImm() &&
"getSimm23Lsl2Encoding expects only an immediate");
1116 unsigned Res =
static_cast<unsigned>(MO.
getImm());
1121#include "MipsGenMCCodeEmitter.inc"
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void LowerLargeShift(MCInst &Inst)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This class represents an Operation in the Expression.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
MCCodeEmitter - Generic instruction encoding interface.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCRegisterInfo * getRegisterInfo() const
void reportError(SMLoc L, const Twine &Msg)
Base class for the full range of assembler expressions which are needed for parsing.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Instances of this class represent operands of the MCInst class.
void setReg(unsigned Reg)
Set the register number.
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
uint64_t getDFPImm() const
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
unsigned getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch target operand.
unsigned getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTarget21OpValue - Return binary encoding of the branch target operand.
uint64_t getBinaryCodeForInstr(const MCInst &MI, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getMachineOpValue - Return binary encoding of operand.
unsigned getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Subtract Offset then encode as a N-bit unsigned integer.
unsigned getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTargetOpValueMMR6 - Return binary encoding of the branch target operand.
unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTargetOpValue - Return binary encoding of the branch target operand.
unsigned getRegisterListOpValue16(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getMemEncoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Return binary encoding of memory related operand.
unsigned getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTarget26OpValue - Return binary encoding of the branch target operand.
unsigned getBranchTarget26OpValueMM(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTarget26OpValueMM - Return binary encoding of the branch target operand.
unsigned getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTargetOpValue1SImm16 - Return binary encoding of the branch target operand.
unsigned getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getJumpOffset16OpValue - Return binary encoding of the jump target operand.
unsigned getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS 10-bit branch target operand.
unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getJumpTargetOpValue - Return binary encoding of the jump target operand.
unsigned getUImm4AndValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getRegisterListOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getExprOpValue(const MCExpr *Expr, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTargetOpValue - Return binary encoding of the microMIPS branch target operand.
unsigned getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
void encodeInstruction(const MCInst &MI, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const override
encodeInstruction - Emit the instruction.
unsigned getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTarget21OpValueMM - Return binary encoding of the branch target operand for microMIPS.
unsigned getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch target operand.
unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
unsigned getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
void EmitByte(unsigned char C, raw_ostream &OS) const
unsigned getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
const MCExpr * getSubExpr() const
Get the child of this expression.
MipsExprKind getKind() const
Get the kind of this expression.
bool isGpOff(MipsExprKind &Kind) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ fixup_MICROMIPS_TLS_TPREL_LO16
@ fixup_MICROMIPS_GOT_PAGE
@ fixup_MICROMIPS_TLS_TPREL_HI16
@ fixup_MICROMIPS_PC21_S1
@ fixup_MICROMIPS_GPOFF_LO
@ fixup_MICROMIPS_PC19_S2
@ fixup_MICROMIPS_TLS_LDM
@ fixup_MICROMIPS_GOT_OFST
@ fixup_MICROMIPS_TLS_DTPREL_HI16
@ fixup_MICROMIPS_PC10_S1
@ fixup_MICROMIPS_HIGHEST
@ fixup_MICROMIPS_GOT_DISP
@ fixup_MICROMIPS_PC18_S3
@ fixup_MICROMIPS_PC26_S1
@ fixup_MICROMIPS_GOTTPREL
@ fixup_MICROMIPS_TLS_DTPREL_LO16
@ fixup_MICROMIPS_GPOFF_HI
This is an optimization pass for GlobalISel generic memory operations.
MCCodeEmitter * createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, MCContext &Ctx)
MCCodeEmitter * createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, MCContext &Ctx)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Description of the encoding of one expression Op.