LLVM API Documentation
00001 //===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the MipsMCCodeEmitter class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 // 00014 00015 #include "MipsMCCodeEmitter.h" 00016 #include "MCTargetDesc/MipsFixupKinds.h" 00017 #include "MCTargetDesc/MipsMCExpr.h" 00018 #include "MCTargetDesc/MipsMCTargetDesc.h" 00019 #include "llvm/ADT/APFloat.h" 00020 #include "llvm/ADT/SmallVector.h" 00021 #include "llvm/MC/MCContext.h" 00022 #include "llvm/MC/MCExpr.h" 00023 #include "llvm/MC/MCInst.h" 00024 #include "llvm/MC/MCInstrInfo.h" 00025 #include "llvm/MC/MCFixup.h" 00026 #include "llvm/MC/MCSubtargetInfo.h" 00027 #include "llvm/Support/raw_ostream.h" 00028 00029 #define DEBUG_TYPE "mccodeemitter" 00030 00031 #define GET_INSTRMAP_INFO 00032 #include "MipsGenInstrInfo.inc" 00033 #undef GET_INSTRMAP_INFO 00034 00035 namespace llvm { 00036 MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII, 00037 const MCRegisterInfo &MRI, 00038 const MCSubtargetInfo &STI, 00039 MCContext &Ctx) { 00040 return new MipsMCCodeEmitter(MCII, Ctx, false); 00041 } 00042 00043 MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII, 00044 const MCRegisterInfo &MRI, 00045 const MCSubtargetInfo &STI, 00046 MCContext &Ctx) { 00047 return new MipsMCCodeEmitter(MCII, Ctx, true); 00048 } 00049 } // End of namespace llvm. 00050 00051 // If the D<shift> instruction has a shift amount that is greater 00052 // than 31 (checked in calling routine), lower it to a D<shift>32 instruction 00053 static void LowerLargeShift(MCInst& Inst) { 00054 00055 assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!"); 00056 assert(Inst.getOperand(2).isImm()); 00057 00058 int64_t Shift = Inst.getOperand(2).getImm(); 00059 if (Shift <= 31) 00060 return; // Do nothing 00061 Shift -= 32; 00062 00063 // saminus32 00064 Inst.getOperand(2).setImm(Shift); 00065 00066 switch (Inst.getOpcode()) { 00067 default: 00068 // Calling function is not synchronized 00069 llvm_unreachable("Unexpected shift instruction"); 00070 case Mips::DSLL: 00071 Inst.setOpcode(Mips::DSLL32); 00072 return; 00073 case Mips::DSRL: 00074 Inst.setOpcode(Mips::DSRL32); 00075 return; 00076 case Mips::DSRA: 00077 Inst.setOpcode(Mips::DSRA32); 00078 return; 00079 case Mips::DROTR: 00080 Inst.setOpcode(Mips::DROTR32); 00081 return; 00082 } 00083 } 00084 00085 // Pick a DEXT or DINS instruction variant based on the pos and size operands 00086 static void LowerDextDins(MCInst& InstIn) { 00087 int Opcode = InstIn.getOpcode(); 00088 00089 if (Opcode == Mips::DEXT) 00090 assert(InstIn.getNumOperands() == 4 && 00091 "Invalid no. of machine operands for DEXT!"); 00092 else // Only DEXT and DINS are possible 00093 assert(InstIn.getNumOperands() == 5 && 00094 "Invalid no. of machine operands for DINS!"); 00095 00096 assert(InstIn.getOperand(2).isImm()); 00097 int64_t pos = InstIn.getOperand(2).getImm(); 00098 assert(InstIn.getOperand(3).isImm()); 00099 int64_t size = InstIn.getOperand(3).getImm(); 00100 00101 if (size <= 32) { 00102 if (pos < 32) // DEXT/DINS, do nothing 00103 return; 00104 // DEXTU/DINSU 00105 InstIn.getOperand(2).setImm(pos - 32); 00106 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU); 00107 return; 00108 } 00109 // DEXTM/DINSM 00110 assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32"); 00111 InstIn.getOperand(3).setImm(size - 32); 00112 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM); 00113 return; 00114 } 00115 00116 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const { 00117 return STI.getFeatureBits() & Mips::FeatureMicroMips; 00118 } 00119 00120 void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const { 00121 OS << (char)C; 00122 } 00123 00124 void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size, 00125 const MCSubtargetInfo &STI, 00126 raw_ostream &OS) const { 00127 // Output the instruction encoding in little endian byte order. 00128 // Little-endian byte ordering: 00129 // mips32r2: 4 | 3 | 2 | 1 00130 // microMIPS: 2 | 1 | 4 | 3 00131 if (IsLittleEndian && Size == 4 && isMicroMips(STI)) { 00132 EmitInstruction(Val >> 16, 2, STI, OS); 00133 EmitInstruction(Val, 2, STI, OS); 00134 } else { 00135 for (unsigned i = 0; i < Size; ++i) { 00136 unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8; 00137 EmitByte((Val >> Shift) & 0xff, OS); 00138 } 00139 } 00140 } 00141 00142 /// EncodeInstruction - Emit the instruction. 00143 /// Size the instruction with Desc.getSize(). 00144 void MipsMCCodeEmitter:: 00145 EncodeInstruction(const MCInst &MI, raw_ostream &OS, 00146 SmallVectorImpl<MCFixup> &Fixups, 00147 const MCSubtargetInfo &STI) const 00148 { 00149 00150 // Non-pseudo instructions that get changed for direct object 00151 // only based on operand values. 00152 // If this list of instructions get much longer we will move 00153 // the check to a function call. Until then, this is more efficient. 00154 MCInst TmpInst = MI; 00155 switch (MI.getOpcode()) { 00156 // If shift amount is >= 32 it the inst needs to be lowered further 00157 case Mips::DSLL: 00158 case Mips::DSRL: 00159 case Mips::DSRA: 00160 case Mips::DROTR: 00161 LowerLargeShift(TmpInst); 00162 break; 00163 // Double extract instruction is chosen by pos and size operands 00164 case Mips::DEXT: 00165 case Mips::DINS: 00166 LowerDextDins(TmpInst); 00167 } 00168 00169 unsigned long N = Fixups.size(); 00170 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 00171 00172 // Check for unimplemented opcodes. 00173 // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0 00174 // so we have to special check for them. 00175 unsigned Opcode = TmpInst.getOpcode(); 00176 if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary) 00177 llvm_unreachable("unimplemented opcode in EncodeInstruction()"); 00178 00179 if (STI.getFeatureBits() & Mips::FeatureMicroMips) { 00180 int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips); 00181 if (NewOpcode != -1) { 00182 if (Fixups.size() > N) 00183 Fixups.pop_back(); 00184 Opcode = NewOpcode; 00185 TmpInst.setOpcode (NewOpcode); 00186 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI); 00187 } 00188 } 00189 00190 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode()); 00191 00192 // Get byte count of instruction 00193 unsigned Size = Desc.getSize(); 00194 if (!Size) 00195 llvm_unreachable("Desc.getSize() returns 0"); 00196 00197 EmitInstruction(Binary, Size, STI, OS); 00198 } 00199 00200 /// getBranchTargetOpValue - Return binary encoding of the branch 00201 /// target operand. If the machine operand requires relocation, 00202 /// record the relocation and return zero. 00203 unsigned MipsMCCodeEmitter:: 00204 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo, 00205 SmallVectorImpl<MCFixup> &Fixups, 00206 const MCSubtargetInfo &STI) const { 00207 00208 const MCOperand &MO = MI.getOperand(OpNo); 00209 00210 // If the destination is an immediate, divide by 4. 00211 if (MO.isImm()) return MO.getImm() >> 2; 00212 00213 assert(MO.isExpr() && 00214 "getBranchTargetOpValue expects only expressions or immediates"); 00215 00216 const MCExpr *Expr = MO.getExpr(); 00217 Fixups.push_back(MCFixup::Create(0, Expr, 00218 MCFixupKind(Mips::fixup_Mips_PC16))); 00219 return 0; 00220 } 00221 00222 /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch 00223 /// target operand. If the machine operand requires relocation, 00224 /// record the relocation and return zero. 00225 unsigned MipsMCCodeEmitter:: 00226 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo, 00227 SmallVectorImpl<MCFixup> &Fixups, 00228 const MCSubtargetInfo &STI) const { 00229 00230 const MCOperand &MO = MI.getOperand(OpNo); 00231 00232 // If the destination is an immediate, divide by 2. 00233 if (MO.isImm()) return MO.getImm() >> 1; 00234 00235 assert(MO.isExpr() && 00236 "getBranchTargetOpValueMM expects only expressions or immediates"); 00237 00238 const MCExpr *Expr = MO.getExpr(); 00239 Fixups.push_back(MCFixup::Create(0, Expr, 00240 MCFixupKind(Mips:: 00241 fixup_MICROMIPS_PC16_S1))); 00242 return 0; 00243 } 00244 00245 /// getBranchTarget21OpValue - Return binary encoding of the branch 00246 /// target operand. If the machine operand requires relocation, 00247 /// record the relocation and return zero. 00248 unsigned MipsMCCodeEmitter:: 00249 getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo, 00250 SmallVectorImpl<MCFixup> &Fixups, 00251 const MCSubtargetInfo &STI) const { 00252 00253 const MCOperand &MO = MI.getOperand(OpNo); 00254 00255 // If the destination is an immediate, divide by 4. 00256 if (MO.isImm()) return MO.getImm() >> 2; 00257 00258 assert(MO.isExpr() && 00259 "getBranchTarget21OpValue expects only expressions or immediates"); 00260 00261 const MCExpr *Expr = MO.getExpr(); 00262 Fixups.push_back(MCFixup::Create(0, Expr, 00263 MCFixupKind(Mips::fixup_MIPS_PC21_S2))); 00264 return 0; 00265 } 00266 00267 /// getBranchTarget26OpValue - Return binary encoding of the branch 00268 /// target operand. If the machine operand requires relocation, 00269 /// record the relocation and return zero. 00270 unsigned MipsMCCodeEmitter:: 00271 getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo, 00272 SmallVectorImpl<MCFixup> &Fixups, 00273 const MCSubtargetInfo &STI) const { 00274 00275 const MCOperand &MO = MI.getOperand(OpNo); 00276 00277 // If the destination is an immediate, divide by 4. 00278 if (MO.isImm()) return MO.getImm() >> 2; 00279 00280 assert(MO.isExpr() && 00281 "getBranchTarget26OpValue expects only expressions or immediates"); 00282 00283 const MCExpr *Expr = MO.getExpr(); 00284 Fixups.push_back(MCFixup::Create(0, Expr, 00285 MCFixupKind(Mips::fixup_MIPS_PC26_S2))); 00286 return 0; 00287 } 00288 00289 /// getJumpOffset16OpValue - Return binary encoding of the jump 00290 /// target operand. If the machine operand requires relocation, 00291 /// record the relocation and return zero. 00292 unsigned MipsMCCodeEmitter:: 00293 getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo, 00294 SmallVectorImpl<MCFixup> &Fixups, 00295 const MCSubtargetInfo &STI) const { 00296 00297 const MCOperand &MO = MI.getOperand(OpNo); 00298 00299 if (MO.isImm()) return MO.getImm(); 00300 00301 assert(MO.isExpr() && 00302 "getJumpOffset16OpValue expects only expressions or an immediate"); 00303 00304 // TODO: Push fixup. 00305 return 0; 00306 } 00307 00308 /// getJumpTargetOpValue - Return binary encoding of the jump 00309 /// target operand. If the machine operand requires relocation, 00310 /// record the relocation and return zero. 00311 unsigned MipsMCCodeEmitter:: 00312 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo, 00313 SmallVectorImpl<MCFixup> &Fixups, 00314 const MCSubtargetInfo &STI) const { 00315 00316 const MCOperand &MO = MI.getOperand(OpNo); 00317 // If the destination is an immediate, divide by 4. 00318 if (MO.isImm()) return MO.getImm()>>2; 00319 00320 assert(MO.isExpr() && 00321 "getJumpTargetOpValue expects only expressions or an immediate"); 00322 00323 const MCExpr *Expr = MO.getExpr(); 00324 Fixups.push_back(MCFixup::Create(0, Expr, 00325 MCFixupKind(Mips::fixup_Mips_26))); 00326 return 0; 00327 } 00328 00329 unsigned MipsMCCodeEmitter:: 00330 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo, 00331 SmallVectorImpl<MCFixup> &Fixups, 00332 const MCSubtargetInfo &STI) const { 00333 00334 const MCOperand &MO = MI.getOperand(OpNo); 00335 // If the destination is an immediate, divide by 2. 00336 if (MO.isImm()) return MO.getImm() >> 1; 00337 00338 assert(MO.isExpr() && 00339 "getJumpTargetOpValueMM expects only expressions or an immediate"); 00340 00341 const MCExpr *Expr = MO.getExpr(); 00342 Fixups.push_back(MCFixup::Create(0, Expr, 00343 MCFixupKind(Mips::fixup_MICROMIPS_26_S1))); 00344 return 0; 00345 } 00346 00347 unsigned MipsMCCodeEmitter:: 00348 getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo, 00349 SmallVectorImpl<MCFixup> &Fixups, 00350 const MCSubtargetInfo &STI) const { 00351 00352 const MCOperand &MO = MI.getOperand(OpNo); 00353 if (MO.isImm()) { 00354 // The immediate is encoded as 'immediate << 2'. 00355 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 00356 assert((Res & 3) == 0); 00357 return Res >> 2; 00358 } 00359 00360 assert(MO.isExpr() && 00361 "getUImm5Lsl2Encoding expects only expressions or an immediate"); 00362 00363 return 0; 00364 } 00365 00366 unsigned MipsMCCodeEmitter:: 00367 getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups, 00368 const MCSubtargetInfo &STI) const { 00369 int64_t Res; 00370 00371 if (Expr->EvaluateAsAbsolute(Res)) 00372 return Res; 00373 00374 MCExpr::ExprKind Kind = Expr->getKind(); 00375 if (Kind == MCExpr::Constant) { 00376 return cast<MCConstantExpr>(Expr)->getValue(); 00377 } 00378 00379 if (Kind == MCExpr::Binary) { 00380 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI); 00381 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI); 00382 return Res; 00383 } 00384 00385 if (Kind == MCExpr::Target) { 00386 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr); 00387 00388 Mips::Fixups FixupKind = Mips::Fixups(0); 00389 switch (MipsExpr->getKind()) { 00390 default: llvm_unreachable("Unsupported fixup kind for target expression!"); 00391 case MipsMCExpr::VK_Mips_HIGHEST: 00392 FixupKind = Mips::fixup_Mips_HIGHEST; 00393 break; 00394 case MipsMCExpr::VK_Mips_HIGHER: 00395 FixupKind = Mips::fixup_Mips_HIGHER; 00396 break; 00397 case MipsMCExpr::VK_Mips_HI: 00398 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 00399 : Mips::fixup_Mips_HI16; 00400 break; 00401 case MipsMCExpr::VK_Mips_LO: 00402 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 00403 : Mips::fixup_Mips_LO16; 00404 break; 00405 } 00406 Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind))); 00407 return 0; 00408 } 00409 00410 if (Kind == MCExpr::SymbolRef) { 00411 Mips::Fixups FixupKind = Mips::Fixups(0); 00412 00413 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) { 00414 default: llvm_unreachable("Unknown fixup kind!"); 00415 break; 00416 case MCSymbolRefExpr::VK_Mips_GPOFF_HI : 00417 FixupKind = Mips::fixup_Mips_GPOFF_HI; 00418 break; 00419 case MCSymbolRefExpr::VK_Mips_GPOFF_LO : 00420 FixupKind = Mips::fixup_Mips_GPOFF_LO; 00421 break; 00422 case MCSymbolRefExpr::VK_Mips_GOT_PAGE : 00423 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE 00424 : Mips::fixup_Mips_GOT_PAGE; 00425 break; 00426 case MCSymbolRefExpr::VK_Mips_GOT_OFST : 00427 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST 00428 : Mips::fixup_Mips_GOT_OFST; 00429 break; 00430 case MCSymbolRefExpr::VK_Mips_GOT_DISP : 00431 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP 00432 : Mips::fixup_Mips_GOT_DISP; 00433 break; 00434 case MCSymbolRefExpr::VK_Mips_GPREL: 00435 FixupKind = Mips::fixup_Mips_GPREL16; 00436 break; 00437 case MCSymbolRefExpr::VK_Mips_GOT_CALL: 00438 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16 00439 : Mips::fixup_Mips_CALL16; 00440 break; 00441 case MCSymbolRefExpr::VK_Mips_GOT16: 00442 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 00443 : Mips::fixup_Mips_GOT_Global; 00444 break; 00445 case MCSymbolRefExpr::VK_Mips_GOT: 00446 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16 00447 : Mips::fixup_Mips_GOT_Local; 00448 break; 00449 case MCSymbolRefExpr::VK_Mips_ABS_HI: 00450 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16 00451 : Mips::fixup_Mips_HI16; 00452 break; 00453 case MCSymbolRefExpr::VK_Mips_ABS_LO: 00454 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 00455 : Mips::fixup_Mips_LO16; 00456 break; 00457 case MCSymbolRefExpr::VK_Mips_TLSGD: 00458 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD 00459 : Mips::fixup_Mips_TLSGD; 00460 break; 00461 case MCSymbolRefExpr::VK_Mips_TLSLDM: 00462 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM 00463 : Mips::fixup_Mips_TLSLDM; 00464 break; 00465 case MCSymbolRefExpr::VK_Mips_DTPREL_HI: 00466 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16 00467 : Mips::fixup_Mips_DTPREL_HI; 00468 break; 00469 case MCSymbolRefExpr::VK_Mips_DTPREL_LO: 00470 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16 00471 : Mips::fixup_Mips_DTPREL_LO; 00472 break; 00473 case MCSymbolRefExpr::VK_Mips_GOTTPREL: 00474 FixupKind = Mips::fixup_Mips_GOTTPREL; 00475 break; 00476 case MCSymbolRefExpr::VK_Mips_TPREL_HI: 00477 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16 00478 : Mips::fixup_Mips_TPREL_HI; 00479 break; 00480 case MCSymbolRefExpr::VK_Mips_TPREL_LO: 00481 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16 00482 : Mips::fixup_Mips_TPREL_LO; 00483 break; 00484 case MCSymbolRefExpr::VK_Mips_HIGHER: 00485 FixupKind = Mips::fixup_Mips_HIGHER; 00486 break; 00487 case MCSymbolRefExpr::VK_Mips_HIGHEST: 00488 FixupKind = Mips::fixup_Mips_HIGHEST; 00489 break; 00490 case MCSymbolRefExpr::VK_Mips_GOT_HI16: 00491 FixupKind = Mips::fixup_Mips_GOT_HI16; 00492 break; 00493 case MCSymbolRefExpr::VK_Mips_GOT_LO16: 00494 FixupKind = Mips::fixup_Mips_GOT_LO16; 00495 break; 00496 case MCSymbolRefExpr::VK_Mips_CALL_HI16: 00497 FixupKind = Mips::fixup_Mips_CALL_HI16; 00498 break; 00499 case MCSymbolRefExpr::VK_Mips_CALL_LO16: 00500 FixupKind = Mips::fixup_Mips_CALL_LO16; 00501 break; 00502 case MCSymbolRefExpr::VK_Mips_PCREL_HI16: 00503 FixupKind = Mips::fixup_MIPS_PCHI16; 00504 break; 00505 case MCSymbolRefExpr::VK_Mips_PCREL_LO16: 00506 FixupKind = Mips::fixup_MIPS_PCLO16; 00507 break; 00508 } // switch 00509 00510 Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind))); 00511 return 0; 00512 } 00513 return 0; 00514 } 00515 00516 /// getMachineOpValue - Return binary encoding of operand. If the machine 00517 /// operand requires relocation, record the relocation and return zero. 00518 unsigned MipsMCCodeEmitter:: 00519 getMachineOpValue(const MCInst &MI, const MCOperand &MO, 00520 SmallVectorImpl<MCFixup> &Fixups, 00521 const MCSubtargetInfo &STI) const { 00522 if (MO.isReg()) { 00523 unsigned Reg = MO.getReg(); 00524 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg); 00525 return RegNo; 00526 } else if (MO.isImm()) { 00527 return static_cast<unsigned>(MO.getImm()); 00528 } else if (MO.isFPImm()) { 00529 return static_cast<unsigned>(APFloat(MO.getFPImm()) 00530 .bitcastToAPInt().getHiBits(32).getLimitedValue()); 00531 } 00532 // MO must be an Expr. 00533 assert(MO.isExpr()); 00534 return getExprOpValue(MO.getExpr(),Fixups, STI); 00535 } 00536 00537 /// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST 00538 /// instructions. 00539 unsigned 00540 MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo, 00541 SmallVectorImpl<MCFixup> &Fixups, 00542 const MCSubtargetInfo &STI) const { 00543 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 00544 assert(MI.getOperand(OpNo).isReg()); 00545 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 00546 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 00547 00548 // The immediate field of an LD/ST instruction is scaled which means it must 00549 // be divided (when encoding) by the size (in bytes) of the instructions' 00550 // data format. 00551 // .b - 1 byte 00552 // .h - 2 bytes 00553 // .w - 4 bytes 00554 // .d - 8 bytes 00555 switch(MI.getOpcode()) 00556 { 00557 default: 00558 assert (0 && "Unexpected instruction"); 00559 break; 00560 case Mips::LD_B: 00561 case Mips::ST_B: 00562 // We don't need to scale the offset in this case 00563 break; 00564 case Mips::LD_H: 00565 case Mips::ST_H: 00566 OffBits >>= 1; 00567 break; 00568 case Mips::LD_W: 00569 case Mips::ST_W: 00570 OffBits >>= 2; 00571 break; 00572 case Mips::LD_D: 00573 case Mips::ST_D: 00574 OffBits >>= 3; 00575 break; 00576 } 00577 00578 return (OffBits & 0xFFFF) | RegBits; 00579 } 00580 00581 /// getMemEncoding - Return binary encoding of memory related operand. 00582 /// If the offset operand requires relocation, record the relocation. 00583 unsigned 00584 MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo, 00585 SmallVectorImpl<MCFixup> &Fixups, 00586 const MCSubtargetInfo &STI) const { 00587 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 00588 assert(MI.getOperand(OpNo).isReg()); 00589 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16; 00590 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 00591 00592 return (OffBits & 0xFFFF) | RegBits; 00593 } 00594 00595 unsigned MipsMCCodeEmitter:: 00596 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo, 00597 SmallVectorImpl<MCFixup> &Fixups, 00598 const MCSubtargetInfo &STI) const { 00599 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0. 00600 assert(MI.getOperand(OpNo).isReg()); 00601 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16; 00602 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI); 00603 00604 return (OffBits & 0x0FFF) | RegBits; 00605 } 00606 00607 unsigned 00608 MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo, 00609 SmallVectorImpl<MCFixup> &Fixups, 00610 const MCSubtargetInfo &STI) const { 00611 assert(MI.getOperand(OpNo).isImm()); 00612 unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 00613 return SizeEncoding - 1; 00614 } 00615 00616 // FIXME: should be called getMSBEncoding 00617 // 00618 unsigned 00619 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo, 00620 SmallVectorImpl<MCFixup> &Fixups, 00621 const MCSubtargetInfo &STI) const { 00622 assert(MI.getOperand(OpNo-1).isImm()); 00623 assert(MI.getOperand(OpNo).isImm()); 00624 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI); 00625 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 00626 00627 return Position + Size - 1; 00628 } 00629 00630 unsigned 00631 MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo, 00632 SmallVectorImpl<MCFixup> &Fixups, 00633 const MCSubtargetInfo &STI) const { 00634 assert(MI.getOperand(OpNo).isImm()); 00635 // The immediate is encoded as 'immediate - 1'. 00636 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1; 00637 } 00638 00639 unsigned 00640 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo, 00641 SmallVectorImpl<MCFixup> &Fixups, 00642 const MCSubtargetInfo &STI) const { 00643 const MCOperand &MO = MI.getOperand(OpNo); 00644 if (MO.isImm()) { 00645 // The immediate is encoded as 'immediate << 2'. 00646 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI); 00647 assert((Res & 3) == 0); 00648 return Res >> 2; 00649 } 00650 00651 assert(MO.isExpr() && 00652 "getSimm19Lsl2Encoding expects only expressions or an immediate"); 00653 00654 const MCExpr *Expr = MO.getExpr(); 00655 Fixups.push_back(MCFixup::Create(0, Expr, 00656 MCFixupKind(Mips::fixup_MIPS_PC19_S2))); 00657 return 0; 00658 } 00659 00660 unsigned 00661 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo, 00662 SmallVectorImpl<MCFixup> &Fixups, 00663 const MCSubtargetInfo &STI) const { 00664 const MCOperand &MO = MI.getOperand(OpNo); 00665 if (MO.isImm()) { 00666 // The immediate is encoded as 'immediate << 3'. 00667 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI); 00668 assert((Res & 7) == 0); 00669 return Res >> 3; 00670 } 00671 00672 assert(MO.isExpr() && 00673 "getSimm18Lsl2Encoding expects only expressions or an immediate"); 00674 00675 const MCExpr *Expr = MO.getExpr(); 00676 Fixups.push_back(MCFixup::Create(0, Expr, 00677 MCFixupKind(Mips::fixup_MIPS_PC18_S3))); 00678 return 0; 00679 } 00680 00681 #include "MipsGenMCCodeEmitter.inc"