brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.5 KiB · cdf5838 Raw
336 lines · cpp
1//===- MipsMCInstLower.cpp - Convert Mips MachineInstr to MCInst ----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains code to lower Mips MachineInstrs to their corresponding10// MCInst records.11//12//===----------------------------------------------------------------------===//13 14#include "MipsMCInstLower.h"15#include "MCTargetDesc/MipsBaseInfo.h"16#include "MCTargetDesc/MipsMCAsmInfo.h"17#include "MipsAsmPrinter.h"18#include "llvm/CodeGen/MachineBasicBlock.h"19#include "llvm/CodeGen/MachineInstr.h"20#include "llvm/CodeGen/MachineOperand.h"21#include "llvm/MC/MCContext.h"22#include "llvm/MC/MCExpr.h"23#include "llvm/MC/MCInst.h"24#include "llvm/Support/ErrorHandling.h"25 26using namespace llvm;27 28MipsMCInstLower::MipsMCInstLower(MipsAsmPrinter &asmprinter)29  : AsmPrinter(asmprinter) {}30 31void MipsMCInstLower::Initialize(MCContext *C) {32  Ctx = C;33}34 35MCOperand MipsMCInstLower::LowerSymbolOperand(const MachineOperand &MO,36                                              MachineOperandType MOTy,37                                              int64_t Offset) const {38  Mips::Specifier TargetKind = Mips::S_None;39  bool IsGpOff = false;40  const MCSymbol *Symbol;41  SmallString<128> Name;42  unsigned TargetFlags = MO.getTargetFlags();43 44  if (TargetFlags & MipsII::MO_DLLIMPORT) {45    // Handle dllimport linkage46    Name += "__imp_";47    TargetFlags &= ~MipsII::MO_DLLIMPORT;48  }49 50  switch (TargetFlags) {51  default:52    llvm_unreachable("Invalid target flag!");53  case MipsII::MO_NO_FLAG:54    break;55  case MipsII::MO_GPREL:56    TargetKind = Mips::S_GPREL;57    break;58  case MipsII::MO_GOT_CALL:59    TargetKind = Mips::S_GOT_CALL;60    break;61  case MipsII::MO_GOT:62    TargetKind = Mips::S_GOT;63    break;64  case MipsII::MO_ABS_HI:65    TargetKind = Mips::S_HI;66    break;67  case MipsII::MO_ABS_LO:68    TargetKind = Mips::S_LO;69    break;70  case MipsII::MO_TLSGD:71    TargetKind = Mips::S_TLSGD;72    break;73  case MipsII::MO_TLSLDM:74    TargetKind = Mips::S_TLSLDM;75    break;76  case MipsII::MO_DTPREL_HI:77    TargetKind = Mips::S_DTPREL_HI;78    break;79  case MipsII::MO_DTPREL_LO:80    TargetKind = Mips::S_DTPREL_LO;81    break;82  case MipsII::MO_GOTTPREL:83    TargetKind = Mips::S_GOTTPREL;84    break;85  case MipsII::MO_TPREL_HI:86    TargetKind = Mips::S_TPREL_HI;87    break;88  case MipsII::MO_TPREL_LO:89    TargetKind = Mips::S_TPREL_LO;90    break;91  case MipsII::MO_GPOFF_HI:92    TargetKind = Mips::S_HI;93    IsGpOff = true;94    break;95  case MipsII::MO_GPOFF_LO:96    TargetKind = Mips::S_LO;97    IsGpOff = true;98    break;99  case MipsII::MO_GOT_DISP:100    TargetKind = Mips::S_GOT_DISP;101    break;102  case MipsII::MO_GOT_HI16:103    TargetKind = Mips::S_GOT_HI16;104    break;105  case MipsII::MO_GOT_LO16:106    TargetKind = Mips::S_GOT_LO16;107    break;108  case MipsII::MO_GOT_PAGE:109    TargetKind = Mips::S_GOT_PAGE;110    break;111  case MipsII::MO_GOT_OFST:112    TargetKind = Mips::S_GOT_OFST;113    break;114  case MipsII::MO_HIGHER:115    TargetKind = Mips::S_HIGHER;116    break;117  case MipsII::MO_HIGHEST:118    TargetKind = Mips::S_HIGHEST;119    break;120  case MipsII::MO_CALL_HI16:121    TargetKind = Mips::S_CALL_HI16;122    break;123  case MipsII::MO_CALL_LO16:124    TargetKind = Mips::S_CALL_LO16;125    break;126  case MipsII::MO_JALR:127    return MCOperand();128  }129 130  switch (MOTy) {131  case MachineOperand::MO_MachineBasicBlock:132    Symbol = MO.getMBB()->getSymbol();133    break;134 135  case MachineOperand::MO_GlobalAddress:136    AsmPrinter.getNameWithPrefix(Name, MO.getGlobal());137    Symbol = Ctx->getOrCreateSymbol(Name);138    Offset += MO.getOffset();139    break;140 141  case MachineOperand::MO_BlockAddress:142    Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());143    Offset += MO.getOffset();144    break;145 146  case MachineOperand::MO_ExternalSymbol:147    Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());148    Offset += MO.getOffset();149    break;150 151  case MachineOperand::MO_MCSymbol:152    Symbol = MO.getMCSymbol();153    Offset += MO.getOffset();154    break;155 156  case MachineOperand::MO_JumpTableIndex:157    Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());158    break;159 160  case MachineOperand::MO_ConstantPoolIndex:161    Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());162    Offset += MO.getOffset();163    break;164 165  default:166    llvm_unreachable("<unknown operand type>");167  }168 169  const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, *Ctx);170 171  if (Offset) {172    // Note: Offset can also be negative173    Expr = MCBinaryExpr::createAdd(Expr, MCConstantExpr::create(Offset, *Ctx),174                                   *Ctx);175  }176 177  if (IsGpOff)178    Expr = Mips::createGpOff(Expr, TargetKind, *Ctx);179  else if (TargetKind != Mips::S_None)180    Expr = MCSpecifierExpr::create(Expr, TargetKind, *Ctx);181 182  return MCOperand::createExpr(Expr);183}184 185MCOperand MipsMCInstLower::LowerOperand(const MachineOperand &MO,186                                        int64_t offset) const {187  MachineOperandType MOTy = MO.getType();188 189  switch (MOTy) {190  default: llvm_unreachable("unknown operand type");191  case MachineOperand::MO_Register:192    // Ignore all implicit register operands.193    if (MO.isImplicit()) break;194    return MCOperand::createReg(MO.getReg());195  case MachineOperand::MO_Immediate:196    return MCOperand::createImm(MO.getImm() + offset);197  case MachineOperand::MO_MachineBasicBlock:198  case MachineOperand::MO_GlobalAddress:199  case MachineOperand::MO_ExternalSymbol:200  case MachineOperand::MO_MCSymbol:201  case MachineOperand::MO_JumpTableIndex:202  case MachineOperand::MO_ConstantPoolIndex:203  case MachineOperand::MO_BlockAddress:204    return LowerSymbolOperand(MO, MOTy, offset);205  case MachineOperand::MO_RegisterMask:206    break;207 }208 209  return MCOperand();210}211 212MCOperand MipsMCInstLower::createSub(MachineBasicBlock *BB1,213                                     MachineBasicBlock *BB2,214                                     Mips::Specifier Kind) const {215  const MCSymbolRefExpr *Sym1 = MCSymbolRefExpr::create(BB1->getSymbol(), *Ctx);216  const MCSymbolRefExpr *Sym2 = MCSymbolRefExpr::create(BB2->getSymbol(), *Ctx);217  const MCBinaryExpr *Sub = MCBinaryExpr::createSub(Sym1, Sym2, *Ctx);218 219  return MCOperand::createExpr(MCSpecifierExpr::create(Sub, Kind, *Ctx));220}221 222void MipsMCInstLower::223lowerLongBranchLUi(const MachineInstr *MI, MCInst &OutMI) const {224  OutMI.setOpcode(Mips::LUi);225 226  // Lower register operand.227  OutMI.addOperand(LowerOperand(MI->getOperand(0)));228 229  Mips::Specifier Spec;230  unsigned TargetFlags = MI->getOperand(1).getTargetFlags();231  switch (TargetFlags) {232  case MipsII::MO_HIGHEST:233    Spec = Mips::S_HIGHEST;234    break;235  case MipsII::MO_HIGHER:236    Spec = Mips::S_HIGHER;237    break;238  case MipsII::MO_ABS_HI:239    Spec = Mips::S_HI;240    break;241  case MipsII::MO_ABS_LO:242    Spec = Mips::S_LO;243    break;244  default:245    report_fatal_error("Unexpected flags for lowerLongBranchLUi");246  }247 248  if (MI->getNumOperands() == 2) {249    const MCExpr *Expr =250        MCSymbolRefExpr::create(MI->getOperand(1).getMBB()->getSymbol(), *Ctx);251    const auto *MipsExpr = MCSpecifierExpr::create(Expr, Spec, *Ctx);252    OutMI.addOperand(MCOperand::createExpr(MipsExpr));253  } else if (MI->getNumOperands() == 3) {254    // Create %hi($tgt-$baltgt).255    OutMI.addOperand(createSub(MI->getOperand(1).getMBB(),256                               MI->getOperand(2).getMBB(), Spec));257  }258}259 260void MipsMCInstLower::lowerLongBranchADDiu(const MachineInstr *MI,261                                           MCInst &OutMI, int Opcode) const {262  OutMI.setOpcode(Opcode);263 264  Mips::Specifier Spec;265  unsigned TargetFlags = MI->getOperand(2).getTargetFlags();266  switch (TargetFlags) {267  case MipsII::MO_HIGHEST:268    Spec = Mips::S_HIGHEST;269    break;270  case MipsII::MO_HIGHER:271    Spec = Mips::S_HIGHER;272    break;273  case MipsII::MO_ABS_HI:274    Spec = Mips::S_HI;275    break;276  case MipsII::MO_ABS_LO:277    Spec = Mips::S_LO;278    break;279  default:280    report_fatal_error("Unexpected flags for lowerLongBranchADDiu");281  }282 283  // Lower two register operands.284  for (unsigned I = 0, E = 2; I != E; ++I) {285    const MachineOperand &MO = MI->getOperand(I);286    OutMI.addOperand(LowerOperand(MO));287  }288 289  if (MI->getNumOperands() == 3) {290    // Lower register operand.291    const MCExpr *Expr =292        MCSymbolRefExpr::create(MI->getOperand(2).getMBB()->getSymbol(), *Ctx);293    const auto *MipsExpr = MCSpecifierExpr::create(Expr, Spec, *Ctx);294    OutMI.addOperand(MCOperand::createExpr(MipsExpr));295  } else if (MI->getNumOperands() == 4) {296    // Create %lo($tgt-$baltgt) or %hi($tgt-$baltgt).297    OutMI.addOperand(createSub(MI->getOperand(2).getMBB(),298                               MI->getOperand(3).getMBB(), Spec));299  }300}301 302bool MipsMCInstLower::lowerLongBranch(const MachineInstr *MI,303                                      MCInst &OutMI) const {304  switch (MI->getOpcode()) {305  default:306    return false;307  case Mips::LONG_BRANCH_LUi:308  case Mips::LONG_BRANCH_LUi2Op:309  case Mips::LONG_BRANCH_LUi2Op_64:310    lowerLongBranchLUi(MI, OutMI);311    return true;312  case Mips::LONG_BRANCH_ADDiu:313  case Mips::LONG_BRANCH_ADDiu2Op:314    lowerLongBranchADDiu(MI, OutMI, Mips::ADDiu);315    return true;316  case Mips::LONG_BRANCH_DADDiu:317  case Mips::LONG_BRANCH_DADDiu2Op:318    lowerLongBranchADDiu(MI, OutMI, Mips::DADDiu);319    return true;320  }321}322 323void MipsMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {324  if (lowerLongBranch(MI, OutMI))325    return;326 327  OutMI.setOpcode(MI->getOpcode());328 329  for (const MachineOperand &MO : MI->operands()) {330    MCOperand MCOp = LowerOperand(MO);331 332    if (MCOp.isValid())333      OutMI.addOperand(MCOp);334  }335}336