diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp | 140 |
1 files changed, 119 insertions, 21 deletions
diff --git a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index a54a2eb..93925bf 100644 --- a/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/contrib/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -23,6 +23,7 @@ #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/raw_ostream.h" @@ -35,14 +36,12 @@ namespace llvm { MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, MCContext &Ctx) { return new MipsMCCodeEmitter(MCII, Ctx, false); } MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI, MCContext &Ctx) { return new MipsMCCodeEmitter(MCII, Ctx, true); } @@ -114,7 +113,11 @@ static void LowerDextDins(MCInst& InstIn) { } bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { - return STI.getFeatureBits() & Mips::FeatureMicroMips; + return STI.getFeatureBits()[Mips::FeatureMicroMips]; +} + +bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const { + return STI.getFeatureBits()[Mips::FeatureMips32r6]; } void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { @@ -139,10 +142,10 @@ void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, } } -/// EncodeInstruction - Emit the instruction. +/// encodeInstruction - Emit the instruction. /// Size the instruction with Desc.getSize(). void MipsMCCodeEmitter:: -EncodeInstruction(const MCInst &MI, raw_ostream &OS, +encodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { @@ -175,13 +178,22 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, unsigned Opcode = TmpInst.getOpcode(); if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && (Opcode != Mips::SLL_MM) && !Binary) - llvm_unreachable("unimplemented opcode in EncodeInstruction()"); + llvm_unreachable("unimplemented opcode in encodeInstruction()"); + + int NewOpcode = -1; + if (isMicroMips(STI)) { + if (isMips32r6(STI)) { + NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6); + if (NewOpcode == -1) + NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6); + } + else + NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips); - if (STI.getFeatureBits() & Mips::FeatureMicroMips) { - int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips); if (NewOpcode != -1) { if (Fixups.size() > N) Fixups.pop_back(); + Opcode = NewOpcode; TmpInst.setOpcode (NewOpcode); Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); @@ -215,7 +227,7 @@ getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, "getBranchTargetOpValue expects only expressions or immediates"); const MCExpr *Expr = MO.getExpr(); - Fixups.push_back(MCFixup::Create(0, Expr, + Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(Mips::fixup_Mips_PC16))); return 0; } @@ -237,11 +249,33 @@ getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo, "getBranchTargetOpValueMM expects only expressions or immediates"); const MCExpr *Expr = MO.getExpr(); - Fixups.push_back(MCFixup::Create(0, Expr, + 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. @@ -259,7 +293,7 @@ getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, "getBranchTargetOpValueMM expects only expressions or immediates"); const MCExpr *Expr = MO.getExpr(); - Fixups.push_back(MCFixup::Create(0, Expr, + Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(Mips:: fixup_MICROMIPS_PC16_S1))); return 0; @@ -282,7 +316,7 @@ getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, "getBranchTarget21OpValue expects only expressions or immediates"); const MCExpr *Expr = MO.getExpr(); - Fixups.push_back(MCFixup::Create(0, Expr, + Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(Mips::fixup_MIPS_PC21_S2))); return 0; } @@ -304,7 +338,7 @@ getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, "getBranchTarget26OpValue expects only expressions or immediates"); const MCExpr *Expr = MO.getExpr(); - Fixups.push_back(MCFixup::Create(0, Expr, + Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(Mips::fixup_MIPS_PC26_S2))); return 0; } @@ -344,7 +378,7 @@ getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, "getJumpTargetOpValue expects only expressions or an immediate"); const MCExpr *Expr = MO.getExpr(); - Fixups.push_back(MCFixup::Create(0, Expr, + Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(Mips::fixup_Mips_26))); return 0; } @@ -362,7 +396,7 @@ getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, "getJumpTargetOpValueMM expects only expressions or an immediate"); const MCExpr *Expr = MO.getExpr(); - Fixups.push_back(MCFixup::Create(0, Expr, + Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); return 0; } @@ -429,11 +463,11 @@ getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo, } unsigned MipsMCCodeEmitter:: -getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups, +getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { int64_t Res; - if (Expr->EvaluateAsAbsolute(Res)) + if (Expr->evaluateAsAbsolute(Res)) return Res; MCExpr::ExprKind Kind = Expr->getKind(); @@ -468,7 +502,7 @@ getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups, : Mips::fixup_Mips_LO16; break; } - Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind))); + Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind))); return 0; } @@ -478,6 +512,9 @@ getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups, switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { default: llvm_unreachable("Unknown fixup kind!"); break; + case MCSymbolRefExpr::VK_None: + FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64. + break; case MCSymbolRefExpr::VK_Mips_GPOFF_HI : FixupKind = Mips::fixup_Mips_GPOFF_HI; break; @@ -572,7 +609,7 @@ getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups, break; } // switch - Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind))); + Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind))); return 0; } return 0; @@ -714,6 +751,21 @@ getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo, } unsigned MipsMCCodeEmitter:: +getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + // Register is encoded in bits 9-7, offset is encoded in bits 6-0. + assert(MI.getOperand(OpNo).isReg() && + MI.getOperand(OpNo).getReg() == Mips::GP && + "Unexpected base register!"); + + unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), + Fixups, STI) >> 2; + + return OffBits & 0x7F; +} + +unsigned MipsMCCodeEmitter:: getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const { @@ -808,7 +860,7 @@ MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, "getSimm19Lsl2Encoding expects only expressions or an immediate"); const MCExpr *Expr = MO.getExpr(); - Fixups.push_back(MCFixup::Create(0, Expr, + Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(Mips::fixup_MIPS_PC19_S2))); return 0; } @@ -829,7 +881,7 @@ MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, "getSimm18Lsl2Encoding expects only expressions or an immediate"); const MCExpr *Expr = MO.getExpr(); - Fixups.push_back(MCFixup::Create(0, Expr, + Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(Mips::fixup_MIPS_PC18_S3))); return 0; } @@ -905,4 +957,50 @@ MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo, return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); } +unsigned +MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + unsigned res = 0; + + if (MI.getOperand(0).getReg() == Mips::A1 && + MI.getOperand(1).getReg() == Mips::A2) + res = 0; + else if (MI.getOperand(0).getReg() == Mips::A1 && + MI.getOperand(1).getReg() == Mips::A3) + res = 1; + else if (MI.getOperand(0).getReg() == Mips::A2 && + MI.getOperand(1).getReg() == Mips::A3) + res = 2; + else if (MI.getOperand(0).getReg() == Mips::A0 && + MI.getOperand(1).getReg() == Mips::S5) + res = 3; + else if (MI.getOperand(0).getReg() == Mips::A0 && + MI.getOperand(1).getReg() == Mips::S6) + res = 4; + else if (MI.getOperand(0).getReg() == Mips::A0 && + MI.getOperand(1).getReg() == Mips::A1) + res = 5; + else if (MI.getOperand(0).getReg() == Mips::A0 && + MI.getOperand(1).getReg() == Mips::A2) + res = 6; + else if (MI.getOperand(0).getReg() == Mips::A0 && + MI.getOperand(1).getReg() == Mips::A3) + res = 7; + + return res; +} + +unsigned +MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + const MCOperand &MO = MI.getOperand(OpNo); + assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate"); + // The immediate is encoded as 'immediate >> 2'. + unsigned Res = static_cast<unsigned>(MO.getImm()); + assert((Res & 3) == 0); + return Res >> 2; +} + #include "MipsGenMCCodeEmitter.inc" |