610 lines · cpp
1//===-- XtensaMCCodeEmitter.cpp - Convert Xtensa Code to Machine Code -----===//2//3// The LLVM Compiler Infrastructure4//5// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.6// See https://llvm.org/LICENSE.txt for license information.7// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception8//9//===----------------------------------------------------------------------===//10//11// This file implements the XtensaMCCodeEmitter class.12//13//===----------------------------------------------------------------------===//14 15#include "MCTargetDesc/XtensaFixupKinds.h"16#include "MCTargetDesc/XtensaMCAsmInfo.h"17#include "MCTargetDesc/XtensaMCTargetDesc.h"18#include "llvm/MC/MCCodeEmitter.h"19#include "llvm/MC/MCContext.h"20#include "llvm/MC/MCExpr.h"21#include "llvm/MC/MCInst.h"22#include "llvm/MC/MCInstrInfo.h"23#include "llvm/MC/MCRegisterInfo.h"24 25#define GET_INSTRMAP_INFO26#include "XtensaGenInstrInfo.inc"27#undef GET_INSTRMAP_INFO28 29using namespace llvm;30 31#define DEBUG_TYPE "mccodeemitter"32 33namespace {34class XtensaMCCodeEmitter : public MCCodeEmitter {35 const MCInstrInfo &MCII;36 MCContext &Ctx;37 bool IsLittleEndian;38 39public:40 XtensaMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx, bool isLE)41 : MCII(mcii), Ctx(ctx), IsLittleEndian(isLE) {}42 43 ~XtensaMCCodeEmitter() {}44 45 // OVerride MCCodeEmitter.46 void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,47 SmallVectorImpl<MCFixup> &Fixups,48 const MCSubtargetInfo &STI) const override;49 50private:51 // Automatically generated by TableGen.52 uint64_t getBinaryCodeForInstr(const MCInst &MI,53 SmallVectorImpl<MCFixup> &Fixups,54 const MCSubtargetInfo &STI) const;55 56 // Called by the TableGen code to get the binary encoding of operand57 // MO in MI. Fixups is the list of fixups against MI.58 uint32_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,59 SmallVectorImpl<MCFixup> &Fixups,60 const MCSubtargetInfo &STI) const;61 62 uint32_t getJumpTargetEncoding(const MCInst &MI, unsigned int OpNum,63 SmallVectorImpl<MCFixup> &Fixups,64 const MCSubtargetInfo &STI) const;65 66 uint32_t getBranchTargetEncoding(const MCInst &MI, unsigned int OpNum,67 SmallVectorImpl<MCFixup> &Fixups,68 const MCSubtargetInfo &STI) const;69 70 uint32_t getLoopTargetEncoding(const MCInst &MI, unsigned int OpNum,71 SmallVectorImpl<MCFixup> &Fixups,72 const MCSubtargetInfo &STI) const;73 74 uint32_t getCallEncoding(const MCInst &MI, unsigned int OpNum,75 SmallVectorImpl<MCFixup> &Fixups,76 const MCSubtargetInfo &STI) const;77 78 uint32_t getL32RTargetEncoding(const MCInst &MI, unsigned OpNum,79 SmallVectorImpl<MCFixup> &Fixups,80 const MCSubtargetInfo &STI) const;81 82 uint32_t getMemRegEncoding(const MCInst &MI, unsigned OpNo,83 SmallVectorImpl<MCFixup> &Fixups,84 const MCSubtargetInfo &STI) const;85 86 uint32_t getImm8OpValue(const MCInst &MI, unsigned OpNo,87 SmallVectorImpl<MCFixup> &Fixups,88 const MCSubtargetInfo &STI) const;89 90 uint32_t getImm8_sh8OpValue(const MCInst &MI, unsigned OpNo,91 SmallVectorImpl<MCFixup> &Fixups,92 const MCSubtargetInfo &STI) const;93 94 uint32_t getImm12OpValue(const MCInst &MI, unsigned OpNo,95 SmallVectorImpl<MCFixup> &Fixups,96 const MCSubtargetInfo &STI) const;97 98 uint32_t getUimm4OpValue(const MCInst &MI, unsigned OpNo,99 SmallVectorImpl<MCFixup> &Fixups,100 const MCSubtargetInfo &STI) const;101 102 uint32_t getUimm5OpValue(const MCInst &MI, unsigned OpNo,103 SmallVectorImpl<MCFixup> &Fixups,104 const MCSubtargetInfo &STI) const;105 106 uint32_t getImm1_16OpValue(const MCInst &MI, unsigned OpNo,107 SmallVectorImpl<MCFixup> &Fixups,108 const MCSubtargetInfo &STI) const;109 110 uint32_t getImm1n_15OpValue(const MCInst &MI, unsigned OpNo,111 SmallVectorImpl<MCFixup> &Fixups,112 const MCSubtargetInfo &STI) const;113 114 uint32_t getImm32n_95OpValue(const MCInst &MI, unsigned OpNo,115 SmallVectorImpl<MCFixup> &Fixups,116 const MCSubtargetInfo &STI) const;117 118 uint32_t getImm8n_7OpValue(const MCInst &MI, unsigned OpNo,119 SmallVectorImpl<MCFixup> &Fixups,120 const MCSubtargetInfo &STI) const;121 122 uint32_t getImm64n_4nOpValue(const MCInst &MI, unsigned OpNo,123 SmallVectorImpl<MCFixup> &Fixups,124 const MCSubtargetInfo &STI) const;125 126 uint32_t getEntry_Imm12OpValue(const MCInst &MI, unsigned OpNo,127 SmallVectorImpl<MCFixup> &Fixups,128 const MCSubtargetInfo &STI) const;129 130 uint32_t getShimm1_31OpValue(const MCInst &MI, unsigned OpNo,131 SmallVectorImpl<MCFixup> &Fixups,132 const MCSubtargetInfo &STI) const;133 134 uint32_t getB4constOpValue(const MCInst &MI, unsigned OpNo,135 SmallVectorImpl<MCFixup> &Fixups,136 const MCSubtargetInfo &STI) const;137 138 uint32_t getB4constuOpValue(const MCInst &MI, unsigned OpNo,139 SmallVectorImpl<MCFixup> &Fixups,140 const MCSubtargetInfo &STI) const;141 142 uint32_t getImm7_22OpValue(const MCInst &MI, unsigned OpNo,143 SmallVectorImpl<MCFixup> &Fixups,144 const MCSubtargetInfo &STI) const;145};146} // namespace147 148MCCodeEmitter *llvm::createXtensaMCCodeEmitter(const MCInstrInfo &MCII,149 MCContext &Ctx) {150 return new XtensaMCCodeEmitter(MCII, Ctx, true);151}152 153static void addFixup(SmallVectorImpl<MCFixup> &Fixups, uint32_t Offset,154 const MCExpr *Value, uint16_t Kind) {155 bool PCRel = false;156 switch (Kind) {157 case Xtensa::fixup_xtensa_branch_6:158 case Xtensa::fixup_xtensa_branch_8:159 case Xtensa::fixup_xtensa_branch_12:160 case Xtensa::fixup_xtensa_jump_18:161 case Xtensa::fixup_xtensa_call_18:162 case Xtensa::fixup_xtensa_l32r_16:163 case Xtensa::fixup_xtensa_loop_8:164 PCRel = true;165 }166 Fixups.push_back(MCFixup::create(Offset, Value, Kind, PCRel));167}168 169void XtensaMCCodeEmitter::encodeInstruction(const MCInst &MI,170 SmallVectorImpl<char> &CB,171 SmallVectorImpl<MCFixup> &Fixups,172 const MCSubtargetInfo &STI) const {173 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);174 unsigned Size = MCII.get(MI.getOpcode()).getSize();175 176 if (IsLittleEndian) {177 // Little-endian insertion of Size bytes.178 unsigned ShiftValue = 0;179 for (unsigned I = 0; I != Size; ++I) {180 CB.push_back(char(Bits >> ShiftValue));181 ShiftValue += 8;182 }183 } else {184 // TODO Big-endian insertion of Size bytes.185 report_fatal_error("Big-endian mode currently is not supported!");186 }187}188 189uint32_t190XtensaMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,191 SmallVectorImpl<MCFixup> &Fixups,192 const MCSubtargetInfo &STI) const {193 if (MO.isReg())194 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());195 if (MO.isImm()) {196 uint32_t Res = static_cast<uint32_t>(MO.getImm());197 return Res;198 }199 200 report_fatal_error("Unhandled expression!");201 return 0;202}203 204uint32_t205XtensaMCCodeEmitter::getJumpTargetEncoding(const MCInst &MI, unsigned int OpNum,206 SmallVectorImpl<MCFixup> &Fixups,207 const MCSubtargetInfo &STI) const {208 const MCOperand &MO = MI.getOperand(OpNum);209 210 if (MO.isImm())211 return MO.getImm();212 213 const MCExpr *Expr = MO.getExpr();214 addFixup(Fixups, 0, Expr, Xtensa::fixup_xtensa_jump_18);215 return 0;216}217 218uint32_t XtensaMCCodeEmitter::getBranchTargetEncoding(219 const MCInst &MI, unsigned int OpNum, SmallVectorImpl<MCFixup> &Fixups,220 const MCSubtargetInfo &STI) const {221 const MCOperand &MO = MI.getOperand(OpNum);222 if (MO.isImm())223 return static_cast<uint32_t>(MO.getImm());224 225 const MCExpr *Expr = MO.getExpr();226 switch (MI.getOpcode()) {227 case Xtensa::BEQZ:228 case Xtensa::BGEZ:229 case Xtensa::BLTZ:230 case Xtensa::BNEZ:231 addFixup(Fixups, 0, Expr, Xtensa::fixup_xtensa_branch_12);232 return 0;233 case Xtensa::BEQZ_N:234 case Xtensa::BNEZ_N:235 addFixup(Fixups, 0, Expr, Xtensa::fixup_xtensa_branch_6);236 return 0;237 default:238 addFixup(Fixups, 0, Expr, Xtensa::fixup_xtensa_branch_8);239 return 0;240 }241}242 243uint32_t244XtensaMCCodeEmitter::getLoopTargetEncoding(const MCInst &MI, unsigned int OpNum,245 SmallVectorImpl<MCFixup> &Fixups,246 const MCSubtargetInfo &STI) const {247 const MCOperand &MO = MI.getOperand(OpNum);248 if (MO.isImm())249 return static_cast<uint32_t>(MO.getImm());250 251 assert((MO.isExpr()) && "Unexpected operand value!");252 253 const MCExpr *Expr = MO.getExpr();254 255 addFixup(Fixups, 0, Expr, Xtensa::fixup_xtensa_loop_8);256 return 0;257}258 259uint32_t260XtensaMCCodeEmitter::getCallEncoding(const MCInst &MI, unsigned int OpNum,261 SmallVectorImpl<MCFixup> &Fixups,262 const MCSubtargetInfo &STI) const {263 const MCOperand &MO = MI.getOperand(OpNum);264 if (MO.isImm()) {265 int32_t Res = MO.getImm();266 if (Res & 0x3) {267 llvm_unreachable("Unexpected operand value!");268 }269 Res >>= 2;270 return Res;271 }272 273 assert((MO.isExpr()) && "Unexpected operand value!");274 const MCExpr *Expr = MO.getExpr();275 addFixup(Fixups, 0, Expr, Xtensa::fixup_xtensa_call_18);276 return 0;277}278 279uint32_t280XtensaMCCodeEmitter::getL32RTargetEncoding(const MCInst &MI, unsigned OpNum,281 SmallVectorImpl<MCFixup> &Fixups,282 const MCSubtargetInfo &STI) const {283 const MCOperand &MO = MI.getOperand(OpNum);284 if (MO.isImm()) {285 int32_t Res = MO.getImm();286 // We don't check first 2 bits, because in these bits we could store first 2287 // bits of instruction address288 Res >>= 2;289 return Res;290 }291 292 assert((MO.isExpr()) && "Unexpected operand value!");293 294 addFixup(Fixups, 0, MO.getExpr(), Xtensa::fixup_xtensa_l32r_16);295 return 0;296}297 298uint32_t299XtensaMCCodeEmitter::getMemRegEncoding(const MCInst &MI, unsigned OpNo,300 SmallVectorImpl<MCFixup> &Fixups,301 const MCSubtargetInfo &STI) const {302 assert(MI.getOperand(OpNo + 1).isImm());303 304 uint32_t Res = static_cast<uint32_t>(MI.getOperand(OpNo + 1).getImm());305 306 switch (MI.getOpcode()) {307 case Xtensa::S16I:308 case Xtensa::L16SI:309 case Xtensa::L16UI:310 if (Res & 0x1) {311 report_fatal_error("Unexpected operand value!");312 }313 Res >>= 1;314 break;315 case Xtensa::S32I:316 case Xtensa::L32I:317 case Xtensa::S32I_N:318 case Xtensa::L32I_N:319 case Xtensa::SSI:320 case Xtensa::SSIP:321 case Xtensa::LSI:322 case Xtensa::LSIP:323 case Xtensa::S32C1I:324 if (Res & 0x3) {325 report_fatal_error("Unexpected operand value!");326 }327 Res >>= 2;328 break;329 }330 331 switch (MI.getOpcode()) {332 case Xtensa::S32I_N:333 case Xtensa::L32I_N:334 assert((isUInt<4>(Res)) && "Unexpected operand value!");335 break;336 default:337 assert((isUInt<8>(Res)) && "Unexpected operand value!");338 break;339 }340 341 uint32_t OffBits = Res << 4;342 uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);343 344 return ((OffBits & 0xFF0) | RegBits);345}346 347uint32_t XtensaMCCodeEmitter::getImm8OpValue(const MCInst &MI, unsigned OpNo,348 SmallVectorImpl<MCFixup> &Fixups,349 const MCSubtargetInfo &STI) const {350 const MCOperand &MO = MI.getOperand(OpNo);351 int32_t Res = MO.getImm();352 353 assert(((Res >= -128) && (Res <= 127)) && "Unexpected operand value!");354 355 return (Res & 0xff);356}357 358uint32_t359XtensaMCCodeEmitter::getImm8_sh8OpValue(const MCInst &MI, unsigned OpNo,360 SmallVectorImpl<MCFixup> &Fixups,361 const MCSubtargetInfo &STI) const {362 const MCOperand &MO = MI.getOperand(OpNo);363 int32_t Res = MO.getImm();364 365 assert(((Res >= -32768) && (Res <= 32512) && ((Res & 0xff) == 0)) &&366 "Unexpected operand value!");367 368 return (Res & 0xffff);369}370 371uint32_t372XtensaMCCodeEmitter::getImm12OpValue(const MCInst &MI, unsigned OpNo,373 SmallVectorImpl<MCFixup> &Fixups,374 const MCSubtargetInfo &STI) const {375 const MCOperand &MO = MI.getOperand(OpNo);376 int32_t Res = MO.getImm();377 378 assert(((Res >= -2048) && (Res <= 2047)) && "Unexpected operand value!");379 380 return (Res & 0xfff);381}382 383uint32_t384XtensaMCCodeEmitter::getUimm4OpValue(const MCInst &MI, unsigned OpNo,385 SmallVectorImpl<MCFixup> &Fixups,386 const MCSubtargetInfo &STI) const {387 const MCOperand &MO = MI.getOperand(OpNo);388 uint32_t Res = static_cast<uint32_t>(MO.getImm());389 390 assert((Res <= 15) && "Unexpected operand value!");391 392 return Res & 0xf;393}394 395uint32_t396XtensaMCCodeEmitter::getUimm5OpValue(const MCInst &MI, unsigned OpNo,397 SmallVectorImpl<MCFixup> &Fixups,398 const MCSubtargetInfo &STI) const {399 const MCOperand &MO = MI.getOperand(OpNo);400 uint32_t Res = static_cast<uint32_t>(MO.getImm());401 402 assert((Res <= 31) && "Unexpected operand value!");403 404 return (Res & 0x1f);405}406 407uint32_t408XtensaMCCodeEmitter::getShimm1_31OpValue(const MCInst &MI, unsigned OpNo,409 SmallVectorImpl<MCFixup> &Fixups,410 const MCSubtargetInfo &STI) const {411 const MCOperand &MO = MI.getOperand(OpNo);412 uint32_t Res = static_cast<uint32_t>(MO.getImm());413 414 assert(((Res >= 1) && (Res <= 31)) && "Unexpected operand value!");415 416 return ((32 - Res) & 0x1f);417}418 419uint32_t420XtensaMCCodeEmitter::getImm1_16OpValue(const MCInst &MI, unsigned OpNo,421 SmallVectorImpl<MCFixup> &Fixups,422 const MCSubtargetInfo &STI) const {423 const MCOperand &MO = MI.getOperand(OpNo);424 uint32_t Res = static_cast<uint32_t>(MO.getImm());425 426 assert(((Res >= 1) && (Res <= 16)) && "Unexpected operand value!");427 428 return (Res - 1);429}430 431uint32_t432XtensaMCCodeEmitter::getImm1n_15OpValue(const MCInst &MI, unsigned OpNo,433 SmallVectorImpl<MCFixup> &Fixups,434 const MCSubtargetInfo &STI) const {435 const MCOperand &MO = MI.getOperand(OpNo);436 int32_t Res = static_cast<int32_t>(MO.getImm());437 438 assert(((Res >= -1) && (Res <= 15) && (Res != 0)) &&439 "Unexpected operand value!");440 441 if (Res < 0)442 Res = 0;443 444 return Res;445}446 447uint32_t448XtensaMCCodeEmitter::getImm32n_95OpValue(const MCInst &MI, unsigned OpNo,449 SmallVectorImpl<MCFixup> &Fixups,450 const MCSubtargetInfo &STI) const {451 const MCOperand &MO = MI.getOperand(OpNo);452 int32_t Res = static_cast<int32_t>(MO.getImm());453 454 assert(((Res >= -32) && (Res <= 95)) && "Unexpected operand value!");455 456 return Res;457}458 459uint32_t460XtensaMCCodeEmitter::getImm8n_7OpValue(const MCInst &MI, unsigned OpNo,461 SmallVectorImpl<MCFixup> &Fixups,462 const MCSubtargetInfo &STI) const {463 const MCOperand &MO = MI.getOperand(OpNo);464 int32_t Res = static_cast<int32_t>(MO.getImm());465 466 assert(((Res >= -8) && (Res <= 7)) && "Unexpected operand value!");467 468 if (Res < 0)469 return Res + 16;470 471 return Res;472}473 474uint32_t475XtensaMCCodeEmitter::getImm64n_4nOpValue(const MCInst &MI, unsigned OpNo,476 SmallVectorImpl<MCFixup> &Fixups,477 const MCSubtargetInfo &STI) const {478 const MCOperand &MO = MI.getOperand(OpNo);479 int32_t Res = static_cast<int32_t>(MO.getImm());480 481 assert(((Res >= -64) && (Res <= -4) && ((Res & 0x3) == 0)) &&482 "Unexpected operand value!");483 484 return Res & 0x3f;485}486 487uint32_t488XtensaMCCodeEmitter::getEntry_Imm12OpValue(const MCInst &MI, unsigned OpNo,489 SmallVectorImpl<MCFixup> &Fixups,490 const MCSubtargetInfo &STI) const {491 const MCOperand &MO = MI.getOperand(OpNo);492 uint32_t res = static_cast<uint32_t>(MO.getImm());493 494 assert(((res & 0x7) == 0) && "Unexpected operand value!");495 496 return res;497}498 499uint32_t500XtensaMCCodeEmitter::getB4constOpValue(const MCInst &MI, unsigned OpNo,501 SmallVectorImpl<MCFixup> &Fixups,502 const MCSubtargetInfo &STI) const {503 const MCOperand &MO = MI.getOperand(OpNo);504 uint32_t Res = static_cast<uint32_t>(MO.getImm());505 506 switch (Res) {507 case 0xffffffff:508 Res = 0;509 break;510 case 1:511 case 2:512 case 3:513 case 4:514 case 5:515 case 6:516 case 7:517 case 8:518 break;519 case 10:520 Res = 9;521 break;522 case 12:523 Res = 10;524 break;525 case 16:526 Res = 11;527 break;528 case 32:529 Res = 12;530 break;531 case 64:532 Res = 13;533 break;534 case 128:535 Res = 14;536 break;537 case 256:538 Res = 15;539 break;540 default:541 llvm_unreachable("Unexpected operand value!");542 }543 544 return Res;545}546 547uint32_t548XtensaMCCodeEmitter::getB4constuOpValue(const MCInst &MI, unsigned OpNo,549 SmallVectorImpl<MCFixup> &Fixups,550 const MCSubtargetInfo &STI) const {551 const MCOperand &MO = MI.getOperand(OpNo);552 uint32_t Res = static_cast<uint32_t>(MO.getImm());553 554 switch (Res) {555 case 32768:556 Res = 0;557 break;558 case 65536:559 Res = 1;560 break;561 case 2:562 case 3:563 case 4:564 case 5:565 case 6:566 case 7:567 case 8:568 break;569 case 10:570 Res = 9;571 break;572 case 12:573 Res = 10;574 break;575 case 16:576 Res = 11;577 break;578 case 32:579 Res = 12;580 break;581 case 64:582 Res = 13;583 break;584 case 128:585 Res = 14;586 break;587 case 256:588 Res = 15;589 break;590 default:591 llvm_unreachable("Unexpected operand value!");592 }593 594 return Res;595}596 597uint32_t598XtensaMCCodeEmitter::getImm7_22OpValue(const MCInst &MI, unsigned OpNo,599 SmallVectorImpl<MCFixup> &Fixups,600 const MCSubtargetInfo &STI) const {601 const MCOperand &MO = MI.getOperand(OpNo);602 uint32_t res = static_cast<uint32_t>(MO.getImm());603 604 res -= 7;605 assert(((res & 0xf) == res) && "Unexpected operand value!");606 607 return res;608}609#include "XtensaGenMCCodeEmitter.inc"610