brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.7 KiB · f1c11d4 Raw
442 lines · cpp
1//===- XtensaInstPrinter.cpp - Convert Xtensa MCInst to asm syntax --------===//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 class prints an Xtensa MCInst to a .s file.12//13//===----------------------------------------------------------------------===//14 15#include "XtensaInstPrinter.h"16#include "MCTargetDesc/XtensaMCAsmInfo.h"17#include "llvm/CodeGen/MachineOperand.h"18#include "llvm/MC/MCAsmInfo.h"19#include "llvm/MC/MCExpr.h"20#include "llvm/MC/MCInstrInfo.h"21#include "llvm/MC/MCRegister.h"22#include "llvm/MC/MCSymbol.h"23#include "llvm/Support/Casting.h"24#include "llvm/Support/raw_ostream.h"25 26using namespace llvm;27 28#define DEBUG_TYPE "asm-printer"29 30#include "XtensaGenAsmWriter.inc"31 32static void printExpr(const MCExpr *Expr, raw_ostream &OS) {33  int Offset = 0;34  const MCSymbolRefExpr *SRE;35 36  if (!(SRE = cast<MCSymbolRefExpr>(Expr)))37    assert(false && "Unexpected MCExpr type.");38 39  assert(SRE->getSpecifier() == 0);40 41  OS << SRE->getSymbol();42 43  if (Offset) {44    if (Offset > 0)45      OS << '+';46    OS << Offset;47  }48}49 50void XtensaInstPrinter::printOperand(const MCOperand &MC, raw_ostream &O) {51  if (MC.isReg())52    O << getRegisterName(MC.getReg());53  else if (MC.isImm())54    O << MC.getImm();55  else if (MC.isExpr())56    printExpr(MC.getExpr(), O);57  else58    report_fatal_error("Invalid operand");59}60 61void XtensaInstPrinter::printInst(const MCInst *MI, uint64_t Address,62                                  StringRef Annot, const MCSubtargetInfo &STI,63                                  raw_ostream &O) {64  printInstruction(MI, Address, O);65  printAnnotation(O, Annot);66}67 68void XtensaInstPrinter::printRegName(raw_ostream &O, MCRegister Reg) {69  O << getRegisterName(Reg);70}71 72void XtensaInstPrinter::printOperand(const MCInst *MI, int OpNum,73                                     raw_ostream &O) {74  printOperand(MI->getOperand(OpNum), O);75}76 77void XtensaInstPrinter::printMemOperand(const MCInst *MI, int OpNum,78                                        raw_ostream &OS) {79  OS << getRegisterName(MI->getOperand(OpNum).getReg());80  OS << ", ";81  printOperand(MI, OpNum + 1, OS);82}83 84void XtensaInstPrinter::printBranchTarget(const MCInst *MI, uint64_t Address,85                                          int OpNum, raw_ostream &O) {86  const MCOperand &MC = MI->getOperand(OpNum);87  if (MI->getOperand(OpNum).isImm()) {88    int64_t Val = MC.getImm() + 4;89    printPCRelImm(Address, Val, O);90  } else if (MC.isExpr())91    MAI.printExpr(O, *MC.getExpr());92  else93    llvm_unreachable("Invalid operand");94}95 96void XtensaInstPrinter::printLoopTarget(const MCInst *MI, uint64_t Address,97                                        int OpNum, raw_ostream &O) {98  const MCOperand &MC = MI->getOperand(OpNum);99  if (MI->getOperand(OpNum).isImm()) {100    int64_t Val = MC.getImm() + 4;101    printPCRelImm(Address, Val, O);102  } else if (MC.isExpr())103    MAI.printExpr(O, *MC.getExpr());104  else105    llvm_unreachable("Invalid operand");106}107 108void XtensaInstPrinter::printJumpTarget(const MCInst *MI, uint64_t Address,109                                        int OpNum, raw_ostream &O) {110  const MCOperand &MC = MI->getOperand(OpNum);111  if (MC.isImm()) {112    int64_t Val = MC.getImm() + 4;113    printPCRelImm(Address, Val, O);114  } else if (MC.isExpr())115    MAI.printExpr(O, *MC.getExpr());116  else117    llvm_unreachable("Invalid operand");118  ;119}120 121void XtensaInstPrinter::printCallOperand(const MCInst *MI, uint64_t Address,122                                         int OpNum, raw_ostream &O) {123  const MCOperand &MC = MI->getOperand(OpNum);124  if (MC.isImm()) {125    int64_t Val = MC.getImm() + 4;126    if (PrintBranchImmAsAddress) {127      uint64_t Target = Address;128      Target &= ~0x3;129      Target += Val & (~0x3);130      O << formatHex(Target);131    } else {132      O << ". ";133      if (Val > 0)134        O << '+';135      O << Val;136    }137  } else if (MC.isExpr())138    MAI.printExpr(O, *MC.getExpr());139  else140    llvm_unreachable("Invalid operand");141}142 143void XtensaInstPrinter::printL32RTarget(const MCInst *MI, uint64_t Address,144                                        int OpNum, raw_ostream &O) {145  const MCOperand &MC = MI->getOperand(OpNum);146  if (MC.isImm()) {147    int64_t Value = MI->getOperand(OpNum).getImm();148    if (PrintBranchImmAsAddress) {149      uint64_t Target = (Address + 0x3) & (~0x3);150      Value &= ~0x3;151      Target += Value;152      O << formatHex(Target);153    } else {154      int64_t InstrOff = Value & 0x3;155      Value -= InstrOff;156      assert((Value >= -262144 && Value <= -4) &&157             "Invalid argument, value must be in ranges [-262144,-4]");158      Value += ((InstrOff + 0x3) & 0x4) - InstrOff;159      printPCRelImm(Address, Value, O);160    }161  } else if (MC.isExpr())162    MAI.printExpr(O, *MC.getExpr());163  else164    llvm_unreachable("Invalid operand");165}166 167void XtensaInstPrinter::printPCRelImm(uint64_t Address, int64_t Offset,168                                      raw_ostream &O) {169  if (PrintBranchImmAsAddress) {170    uint64_t Target = Address + Offset;171    Target &= 0xffffffff;172    O << formatHex(Target);173  } else {174    O << ". ";175    if (Offset > 0)176      O << '+';177    O << Offset;178  }179}180 181void XtensaInstPrinter::printImm8_AsmOperand(const MCInst *MI, int OpNum,182                                             raw_ostream &O) {183  if (MI->getOperand(OpNum).isImm()) {184    int64_t Value = MI->getOperand(OpNum).getImm();185    assert(isInt<8>(Value) &&186           "Invalid argument, value must be in ranges [-128,127]");187    O << Value;188  } else {189    printOperand(MI, OpNum, O);190  }191}192 193void XtensaInstPrinter::printImm8_sh8_AsmOperand(const MCInst *MI, int OpNum,194                                                 raw_ostream &O) {195  if (MI->getOperand(OpNum).isImm()) {196    int64_t Value = MI->getOperand(OpNum).getImm();197    assert((isInt<16>(Value) && ((Value & 0xFF) == 0)) &&198           "Invalid argument, value must be multiples of 256 in range "199           "[-32768,32512]");200    O << Value;201  } else202    printOperand(MI, OpNum, O);203}204 205void XtensaInstPrinter::printImm12_AsmOperand(const MCInst *MI, int OpNum,206                                              raw_ostream &O) {207  if (MI->getOperand(OpNum).isImm()) {208    int64_t Value = MI->getOperand(OpNum).getImm();209    assert((Value >= -2048 && Value <= 2047) &&210           "Invalid argument, value must be in ranges [-2048,2047]");211    O << Value;212  } else213    printOperand(MI, OpNum, O);214}215 216void XtensaInstPrinter::printImm12m_AsmOperand(const MCInst *MI, int OpNum,217                                               raw_ostream &O) {218  if (MI->getOperand(OpNum).isImm()) {219    int64_t Value = MI->getOperand(OpNum).getImm();220    assert((Value >= -2048 && Value <= 2047) &&221           "Invalid argument, value must be in ranges [-2048,2047]");222    O << Value;223  } else224    printOperand(MI, OpNum, O);225}226 227void XtensaInstPrinter::printUimm4_AsmOperand(const MCInst *MI, int OpNum,228                                              raw_ostream &O) {229  if (MI->getOperand(OpNum).isImm()) {230    int64_t Value = MI->getOperand(OpNum).getImm();231    assert((Value >= 0 && Value <= 15) && "Invalid argument");232    O << Value;233  } else234    printOperand(MI, OpNum, O);235}236 237void XtensaInstPrinter::printUimm5_AsmOperand(const MCInst *MI, int OpNum,238                                              raw_ostream &O) {239  if (MI->getOperand(OpNum).isImm()) {240    int64_t Value = MI->getOperand(OpNum).getImm();241    assert((Value >= 0 && Value <= 31) && "Invalid argument");242    O << Value;243  } else244    printOperand(MI, OpNum, O);245}246 247void XtensaInstPrinter::printShimm1_31_AsmOperand(const MCInst *MI, int OpNum,248                                                  raw_ostream &O) {249  if (MI->getOperand(OpNum).isImm()) {250    int64_t Value = MI->getOperand(OpNum).getImm();251    assert((Value >= 1 && Value <= 31) &&252           "Invalid argument, value must be in range [1,31]");253    O << Value;254  } else255    printOperand(MI, OpNum, O);256}257 258void XtensaInstPrinter::printImm1_16_AsmOperand(const MCInst *MI, int OpNum,259                                                raw_ostream &O) {260  if (MI->getOperand(OpNum).isImm()) {261    int64_t Value = MI->getOperand(OpNum).getImm();262    assert((Value >= 1 && Value <= 16) &&263           "Invalid argument, value must be in range [1,16]");264    O << Value;265  } else266    printOperand(MI, OpNum, O);267}268 269void XtensaInstPrinter::printImm1n_15_AsmOperand(const MCInst *MI, int OpNum,270                                                 raw_ostream &O) {271  if (MI->getOperand(OpNum).isImm()) {272    int64_t Value = MI->getOperand(OpNum).getImm();273    assert((Value >= -1 && (Value != 0) && Value <= 15) &&274           "Invalid argument, value must be in ranges <-1,-1> or <1,15>");275    O << Value;276  } else277    printOperand(MI, OpNum, O);278}279 280void XtensaInstPrinter::printImm32n_95_AsmOperand(const MCInst *MI, int OpNum,281                                                  raw_ostream &O) {282  if (MI->getOperand(OpNum).isImm()) {283    int64_t Value = MI->getOperand(OpNum).getImm();284    assert((Value >= -32 && Value <= 95) &&285           "Invalid argument, value must be in ranges <-32,95>");286    O << Value;287  } else288    printOperand(MI, OpNum, O);289}290 291void XtensaInstPrinter::printImm8n_7_AsmOperand(const MCInst *MI, int OpNum,292                                                raw_ostream &O) {293  if (MI->getOperand(OpNum).isImm()) {294    int64_t Value = MI->getOperand(OpNum).getImm();295    assert((Value >= -8 && Value <= 7) &&296           "Invalid argument, value must be in ranges <-8,7>");297    O << Value;298  } else299    printOperand(MI, OpNum, O);300}301 302void XtensaInstPrinter::printImm64n_4n_AsmOperand(const MCInst *MI, int OpNum,303                                                  raw_ostream &O) {304  if (MI->getOperand(OpNum).isImm()) {305    int64_t Value = MI->getOperand(OpNum).getImm();306    assert((Value >= -64 && Value <= -4) & ((Value & 0x3) == 0) &&307           "Invalid argument, value must be in ranges <-64,-4>");308    O << Value;309  } else310    printOperand(MI, OpNum, O);311}312 313void XtensaInstPrinter::printOffset8m8_AsmOperand(const MCInst *MI, int OpNum,314                                                  raw_ostream &O) {315  if (MI->getOperand(OpNum).isImm()) {316    int64_t Value = MI->getOperand(OpNum).getImm();317    assert((Value >= 0 && Value <= 255) &&318           "Invalid argument, value must be in range [0,255]");319    O << Value;320  } else321    printOperand(MI, OpNum, O);322}323 324void XtensaInstPrinter::printOffset8m16_AsmOperand(const MCInst *MI, int OpNum,325                                                   raw_ostream &O) {326  if (MI->getOperand(OpNum).isImm()) {327    int64_t Value = MI->getOperand(OpNum).getImm();328    assert((Value >= 0 && Value <= 510 && ((Value & 0x1) == 0)) &&329           "Invalid argument, value must be multiples of two in range [0,510]");330    O << Value;331  } else332    printOperand(MI, OpNum, O);333}334 335void XtensaInstPrinter::printOffset8m32_AsmOperand(const MCInst *MI, int OpNum,336                                                   raw_ostream &O) {337  if (MI->getOperand(OpNum).isImm()) {338    int64_t Value = MI->getOperand(OpNum).getImm();339    assert(340        (Value >= 0 && Value <= 1020 && ((Value & 0x3) == 0)) &&341        "Invalid argument, value must be multiples of four in range [0,1020]");342    O << Value;343  } else344    printOperand(MI, OpNum, O);345}346 347void XtensaInstPrinter::printOffset4m32_AsmOperand(const MCInst *MI, int OpNum,348                                                   raw_ostream &O) {349  if (MI->getOperand(OpNum).isImm()) {350    int64_t Value = MI->getOperand(OpNum).getImm();351    assert((Value >= 0 && Value <= 60 && ((Value & 0x3) == 0)) &&352           "Invalid argument, value must be multiples of four in range [0,60]");353    O << Value;354  } else355    printOperand(MI, OpNum, O);356}357 358void XtensaInstPrinter::printEntry_Imm12_AsmOperand(const MCInst *MI, int OpNum,359                                                    raw_ostream &O) {360  if (MI->getOperand(OpNum).isImm()) {361    int64_t Value = MI->getOperand(OpNum).getImm();362    assert((Value >= 0 && Value <= 32760) &&363           "Invalid argument, value must be multiples of eight in range "364           "<0,32760>");365    O << Value;366  } else367    printOperand(MI, OpNum, O);368}369 370void XtensaInstPrinter::printB4const_AsmOperand(const MCInst *MI, int OpNum,371                                                raw_ostream &O) {372  if (MI->getOperand(OpNum).isImm()) {373    int64_t Value = MI->getOperand(OpNum).getImm();374 375    switch (Value) {376    case -1:377    case 1:378    case 2:379    case 3:380    case 4:381    case 5:382    case 6:383    case 7:384    case 8:385    case 10:386    case 12:387    case 16:388    case 32:389    case 64:390    case 128:391    case 256:392      break;393    default:394      assert((0) && "Invalid B4const argument");395    }396    O << Value;397  } else398    printOperand(MI, OpNum, O);399}400 401void XtensaInstPrinter::printB4constu_AsmOperand(const MCInst *MI, int OpNum,402                                                 raw_ostream &O) {403  if (MI->getOperand(OpNum).isImm()) {404    int64_t Value = MI->getOperand(OpNum).getImm();405 406    switch (Value) {407    case 32768:408    case 65536:409    case 2:410    case 3:411    case 4:412    case 5:413    case 6:414    case 7:415    case 8:416    case 10:417    case 12:418    case 16:419    case 32:420    case 64:421    case 128:422    case 256:423      break;424    default:425      assert((0) && "Invalid B4constu argument");426    }427    O << Value;428  } else429    printOperand(MI, OpNum, O);430}431 432void XtensaInstPrinter::printImm7_22_AsmOperand(const MCInst *MI, int OpNum,433                                                raw_ostream &O) {434  if (MI->getOperand(OpNum).isImm()) {435    int64_t Value = MI->getOperand(OpNum).getImm();436    assert((Value >= 7 && Value <= 22) &&437           "Invalid argument, value must be in range <7,22>");438    O << Value;439  } else440    printOperand(MI, OpNum, O);441}442