14 #define DEBUG_TYPE "mccodeemitter"
29 #define GET_INSTRMAP_INFO
30 #include "MipsGenInstrInfo.inc"
47 MCII(mcii), Ctx(Ctx_), STI (sti), IsLittleEndian(IsLittle) {
48 IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
51 ~MipsMCCodeEmitter() {}
57 void EmitInstruction(uint64_t Val,
unsigned Size,
raw_ostream &OS)
const {
62 if (IsLittleEndian && Size == 4 && IsMicroMips) {
63 EmitInstruction(Val>>16, 2, OS);
64 EmitInstruction(Val, 2, OS);
66 for (
unsigned i = 0; i < Size; ++i) {
67 unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
68 EmitByte((Val >> Shift) & 0xff, OS);
78 uint64_t getBinaryCodeForInstr(
const MCInst &MI,
84 unsigned getJumpTargetOpValue(
const MCInst &MI,
unsigned OpNo,
90 unsigned getJumpTargetOpValueMM(
const MCInst &MI,
unsigned OpNo,
102 unsigned getBranchTargetOpValueMM(
const MCInst &MI,
unsigned OpNo,
110 unsigned getMemEncoding(
const MCInst &MI,
unsigned OpNo,
112 unsigned getMemEncodingMMImm12(
const MCInst &MI,
unsigned OpNo,
114 unsigned getSizeExtEncoding(
const MCInst &MI,
unsigned OpNo,
116 unsigned getSizeInsEncoding(
const MCInst &MI,
unsigned OpNo,
120 unsigned getLSAImmEncoding(
const MCInst &MI,
unsigned OpNo,
134 return new MipsMCCodeEmitter(MCII, Ctx, STI,
false);
142 return new MipsMCCodeEmitter(MCII, Ctx, STI,
true);
150 assert(Inst.
getNumOperands() == 3 &&
"Invalid no. of operands for shift!");
184 if (Opcode == Mips::DEXT)
186 "Invalid no. of machine operands for DEXT!");
189 "Invalid no. of machine operands for DINS!");
201 InstIn.
setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
205 assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32
");
206 InstIn.getOperand(3).setImm(size - 32);
207 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
213 void MipsMCCodeEmitter::
214 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
215 SmallVectorImpl<MCFixup> &Fixups) const
218 // Non-pseudo instructions that get changed for direct object
219 // only based on operand values.
220 // If this list of instructions get much longer we will move
221 // the check to a function call. Until then, this is more efficient.
223 switch (MI.getOpcode()) {
224 // If shift amount is >= 32 it the inst needs to be lowered further
229 LowerLargeShift(TmpInst);
231 // Double extract instruction is chosen by pos and size operands
234 LowerDextDins(TmpInst);
237 unsigned long N = Fixups.size();
238 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups);
240 // Check for unimplemented opcodes.
241 // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
242 // so we have to special check for them.
243 unsigned Opcode = TmpInst.getOpcode();
244 if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
245 llvm_unreachable("unimplemented opcode in EncodeInstruction()
");
247 if (STI.getFeatureBits() & Mips::FeatureMicroMips) {
248 int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips);
249 if (NewOpcode != -1) {
250 if (Fixups.size() > N)
253 TmpInst.setOpcode (NewOpcode);
254 Binary = getBinaryCodeForInstr(TmpInst, Fixups);
258 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
260 // Get byte count of instruction
261 unsigned Size = Desc.getSize();
263 llvm_unreachable("Desc.getSize() returns 0
");
265 EmitInstruction(Binary, Size, OS);
271 unsigned MipsMCCodeEmitter::
272 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
273 SmallVectorImpl<MCFixup> &Fixups) const {
275 const MCOperand &MO = MI.getOperand(OpNo);
277 // If the destination is an immediate, divide by 4.
278 if (MO.isImm()) return MO.getImm() >> 2;
280 assert(MO.isExpr() &&
283 const MCExpr *Expr = MO.getExpr();
284 Fixups.push_back(MCFixup::Create(0, Expr,
285 MCFixupKind(Mips::fixup_Mips_PC16)));
292 unsigned MipsMCCodeEmitter::
293 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
294 SmallVectorImpl<MCFixup> &Fixups) const {
296 const MCOperand &MO = MI.getOperand(OpNo);
298 // If the destination is an immediate, divide by 2.
299 if (MO.isImm()) return MO.getImm() >> 1;
301 assert(MO.isExpr() &&
302 "getBranchTargetOpValueMM expects only expressions or immediates
");
304 const MCExpr *Expr = MO.getExpr();
305 Fixups.push_back(MCFixup::Create(0, Expr,
307 fixup_MICROMIPS_PC16_S1)));
314 unsigned MipsMCCodeEmitter::
315 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
316 SmallVectorImpl<MCFixup> &Fixups) const {
318 const MCOperand &MO = MI.getOperand(OpNo);
319 // If the destination is an immediate, divide by 4.
320 if (MO.isImm()) return MO.getImm()>>2;
322 assert(MO.isExpr() &&
323 "getJumpTargetOpValue expects only expressions or an immediate
");
325 const MCExpr *Expr = MO.getExpr();
326 Fixups.push_back(MCFixup::Create(0, Expr,
327 MCFixupKind(Mips::fixup_Mips_26)));
331 unsigned MipsMCCodeEmitter::
332 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
333 SmallVectorImpl<MCFixup> &Fixups) const {
335 const MCOperand &MO = MI.getOperand(OpNo);
336 // If the destination is an immediate, divide by 2.
337 if (MO.isImm()) return MO.getImm() >> 1;
339 assert(MO.isExpr() &&
340 "getJumpTargetOpValueMM expects only expressions or an immediate
");
342 const MCExpr *Expr = MO.getExpr();
343 Fixups.push_back(MCFixup::Create(0, Expr,
344 MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
348 unsigned MipsMCCodeEmitter::
349 getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups) const {
352 if (Expr->EvaluateAsAbsolute(Res))
355 MCExpr::ExprKind Kind = Expr->getKind();
356 if (Kind == MCExpr::Constant) {
357 return cast<MCConstantExpr>(Expr)->getValue();
360 if (Kind == MCExpr::Binary) {
361 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups);
362 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups);
365 if (Kind == MCExpr::SymbolRef) {
366 Mips::Fixups FixupKind = Mips::Fixups(0);
368 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
369 default: llvm_unreachable("Unknown fixup kind!
");
371 case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
372 FixupKind = Mips::fixup_Mips_GPOFF_HI;
374 case MCSymbolRefExpr::VK_Mips_GPOFF_LO :
375 FixupKind = Mips::fixup_Mips_GPOFF_LO;
377 case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
378 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_PAGE
379 : Mips::fixup_Mips_GOT_PAGE;
381 case MCSymbolRefExpr::VK_Mips_GOT_OFST :
382 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_OFST
383 : Mips::fixup_Mips_GOT_OFST;
385 case MCSymbolRefExpr::VK_Mips_GOT_DISP :
386 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT_DISP
387 : Mips::fixup_Mips_GOT_DISP;
389 case MCSymbolRefExpr::VK_Mips_GPREL:
390 FixupKind = Mips::fixup_Mips_GPREL16;
392 case MCSymbolRefExpr::VK_Mips_GOT_CALL:
393 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_CALL16
394 : Mips::fixup_Mips_CALL16;
396 case MCSymbolRefExpr::VK_Mips_GOT16:
397 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT16
398 : Mips::fixup_Mips_GOT_Global;
400 case MCSymbolRefExpr::VK_Mips_GOT:
401 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_GOT16
402 : Mips::fixup_Mips_GOT_Local;
404 case MCSymbolRefExpr::VK_Mips_ABS_HI:
405 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_HI16
406 : Mips::fixup_Mips_HI16;
408 case MCSymbolRefExpr::VK_Mips_ABS_LO:
409 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_LO16
410 : Mips::fixup_Mips_LO16;
412 case MCSymbolRefExpr::VK_Mips_TLSGD:
413 FixupKind = Mips::fixup_Mips_TLSGD;
415 case MCSymbolRefExpr::VK_Mips_TLSLDM:
416 FixupKind = Mips::fixup_Mips_TLSLDM;
418 case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
419 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
420 : Mips::fixup_Mips_DTPREL_HI;
422 case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
423 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
424 : Mips::fixup_Mips_DTPREL_LO;
426 case MCSymbolRefExpr::VK_Mips_GOTTPREL:
427 FixupKind = Mips::fixup_Mips_GOTTPREL;
429 case MCSymbolRefExpr::VK_Mips_TPREL_HI:
430 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
431 : Mips::fixup_Mips_TPREL_HI;
433 case MCSymbolRefExpr::VK_Mips_TPREL_LO:
434 FixupKind = IsMicroMips ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
435 : Mips::fixup_Mips_TPREL_LO;
437 case MCSymbolRefExpr::VK_Mips_HIGHER:
438 FixupKind = Mips::fixup_Mips_HIGHER;
440 case MCSymbolRefExpr::VK_Mips_HIGHEST:
441 FixupKind = Mips::fixup_Mips_HIGHEST;
443 case MCSymbolRefExpr::VK_Mips_GOT_HI16:
444 FixupKind = Mips::fixup_Mips_GOT_HI16;
446 case MCSymbolRefExpr::VK_Mips_GOT_LO16:
447 FixupKind = Mips::fixup_Mips_GOT_LO16;
449 case MCSymbolRefExpr::VK_Mips_CALL_HI16:
450 FixupKind = Mips::fixup_Mips_CALL_HI16;
452 case MCSymbolRefExpr::VK_Mips_CALL_LO16:
453 FixupKind = Mips::fixup_Mips_CALL_LO16;
457 Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
465 unsigned MipsMCCodeEmitter::
466 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
467 SmallVectorImpl<MCFixup> &Fixups) const {
469 unsigned Reg = MO.getReg();
470 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
472 } else if (MO.isImm()) {
473 return static_cast<unsigned>(MO.getImm());
474 } else if (MO.isFPImm()) {
475 return static_cast<unsigned>(APFloat(MO.getFPImm())
476 .bitcastToAPInt().getHiBits(32).getLimitedValue());
478 // MO must be an Expr.
480 return getExprOpValue(MO.getExpr(),Fixups);
486 MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
487 SmallVectorImpl<MCFixup> &Fixups) const {
488 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
489 assert(MI.getOperand(OpNo).isReg());
490 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups) << 16;
491 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
493 return (OffBits & 0xFFFF) | RegBits;
496 unsigned MipsMCCodeEmitter::
497 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
498 SmallVectorImpl<MCFixup> &Fixups) const {
499 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
500 assert(MI.getOperand(OpNo).isReg());
501 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups) << 16;
502 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups);
504 return (OffBits & 0x0FFF) | RegBits;
508 MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
509 SmallVectorImpl<MCFixup> &Fixups) const {
510 assert(MI.getOperand(OpNo).isImm());
511 unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
512 return SizeEncoding - 1;
515 // FIXME: should be called getMSBEncoding
518 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
519 SmallVectorImpl<MCFixup> &Fixups) const {
520 assert(MI.getOperand(OpNo-1).isImm());
521 assert(MI.getOperand(OpNo).isImm());
522 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups);
523 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups);
525 return Position + Size - 1;
529 MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
530 SmallVectorImpl<MCFixup> &Fixups) const {
531 assert(MI.getOperand(OpNo).isImm());
532 // The immediate is encoded as 'immediate - 1'.
533 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups) - 1;
536 #include "MipsGenMCCodeEmitter.inc
"
static void LowerDextDins(MCInst &InstIn)
MCCodeEmitter * createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, MCContext &Ctx)
#define llvm_unreachable(msg)
static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, unsigned FixupKind, SmallVectorImpl< MCFixup > &Fixups)
MCCodeEmitter - Generic instruction encoding interface.
This file declares a class to represent arbitrary precision floating point values and provide a varie...
void setOpcode(unsigned Op)
static void LowerLargeShift(MCInst &Inst)
#define LLVM_DELETED_FUNCTION
unsigned getOpcode() const
unsigned getNumOperands() const
MCCodeEmitter * createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, MCContext &Ctx)
const MCRegisterInfo & MRI
const MCOperand & getOperand(unsigned i) const