brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.1 KiB · 5977a27 Raw
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