brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 301112c Raw
187 lines · cpp
1//===-- M68kMCInstLower.cpp - M68k MachineInstr to MCInst -------*- C++ -*-===//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/// \file10/// This file contains code to lower M68k MachineInstrs to their11/// corresponding MCInst records.12///13//===----------------------------------------------------------------------===//14 15#include "M68kMCInstLower.h"16 17#include "M68kAsmPrinter.h"18#include "M68kInstrInfo.h"19 20#include "MCTargetDesc/M68kBaseInfo.h"21#include "MCTargetDesc/M68kMCAsmInfo.h"22 23#include "llvm/CodeGen/MachineFunction.h"24#include "llvm/CodeGen/MachineInstr.h"25#include "llvm/CodeGen/MachineOperand.h"26#include "llvm/IR/Mangler.h"27#include "llvm/MC/MCContext.h"28#include "llvm/MC/MCExpr.h"29#include "llvm/MC/MCInst.h"30 31using namespace llvm;32 33#define DEBUG_TYPE "m68k-mc-inst-lower"34 35M68kMCInstLower::M68kMCInstLower(MachineFunction &MF, M68kAsmPrinter &AP)36    : Ctx(AP.OutContext), MF(MF), TM(MF.getTarget()), MAI(*TM.getMCAsmInfo()),37      AsmPrinter(AP) {}38 39MCSymbol *40M68kMCInstLower::GetSymbolFromOperand(const MachineOperand &MO) const {41  assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) &&42         "Isn't a symbol reference");43 44  const auto &TT = TM.getTargetTriple();45  if (MO.isGlobal() && TT.isOSBinFormatELF())46    return AsmPrinter.getSymbolPreferLocal(*MO.getGlobal());47 48  const DataLayout &DL = MF.getDataLayout();49 50  MCSymbol *Sym = nullptr;51  SmallString<128> Name;52  StringRef Suffix;53 54  if (!Suffix.empty())55    Name += DL.getPrivateGlobalPrefix();56 57  if (MO.isGlobal()) {58    const GlobalValue *GV = MO.getGlobal();59    AsmPrinter.getNameWithPrefix(Name, GV);60  } else if (MO.isSymbol()) {61    Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL);62  } else if (MO.isMBB()) {63    assert(Suffix.empty());64    Sym = MO.getMBB()->getSymbol();65  }66 67  Name += Suffix;68  if (!Sym)69    Sym = Ctx.getOrCreateSymbol(Name);70 71  return Sym;72}73 74MCOperand M68kMCInstLower::LowerSymbolOperand(const MachineOperand &MO,75                                              MCSymbol *Sym) const {76  // FIXME We would like an efficient form for this, so we don't have to do a77  // lot of extra uniquing. This fixme is originally from X8678  const MCExpr *Expr = nullptr;79  M68k::Specifier RefKind = M68k::S_None;80 81  switch (MO.getTargetFlags()) {82  default:83    llvm_unreachable("Unknown target flag on GV operand");84  case M68kII::MO_NO_FLAG:85  case M68kII::MO_ABSOLUTE_ADDRESS:86  case M68kII::MO_PC_RELATIVE_ADDRESS:87    break;88  case M68kII::MO_GOTPCREL:89    RefKind = M68k::S_GOTPCREL;90    break;91  case M68kII::MO_GOT:92    RefKind = M68k::S_GOT;93    break;94  case M68kII::MO_GOTOFF:95    RefKind = M68k::S_GOTOFF;96    break;97  case M68kII::MO_PLT:98    RefKind = M68k::S_PLT;99    break;100  case M68kII::MO_TLSGD:101    RefKind = M68k::S_TLSGD;102    break;103  case M68kII::MO_TLSLD:104    RefKind = M68k::S_TLSLD;105    break;106  case M68kII::MO_TLSLDM:107    RefKind = M68k::S_TLSLDM;108    break;109  case M68kII::MO_TLSIE:110    RefKind = M68k::S_GOTTPOFF;111    break;112  case M68kII::MO_TLSLE:113    RefKind = M68k::S_TPOFF;114    break;115  }116 117  if (!Expr) {118    Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);119  }120 121  if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) {122    Expr = MCBinaryExpr::createAdd(123        Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);124  }125 126  return MCOperand::createExpr(Expr);127}128 129std::optional<MCOperand>130M68kMCInstLower::LowerOperand(const MachineInstr *MI,131                              const MachineOperand &MO) const {132  switch (MO.getType()) {133  default:134    llvm_unreachable("unknown operand type");135  case MachineOperand::MO_Register:136    // Ignore all implicit register operands.137    if (MO.isImplicit())138      return std::nullopt;139    return MCOperand::createReg(MO.getReg());140  case MachineOperand::MO_Immediate:141    return MCOperand::createImm(MO.getImm());142  case MachineOperand::MO_MachineBasicBlock:143  case MachineOperand::MO_GlobalAddress:144  case MachineOperand::MO_ExternalSymbol:145    return LowerSymbolOperand(MO, GetSymbolFromOperand(MO));146  case MachineOperand::MO_MCSymbol:147    return LowerSymbolOperand(MO, MO.getMCSymbol());148  case MachineOperand::MO_JumpTableIndex:149    return LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));150  case MachineOperand::MO_ConstantPoolIndex:151    return LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));152  case MachineOperand::MO_BlockAddress:153    return LowerSymbolOperand(154        MO, AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));155  case MachineOperand::MO_RegisterMask:156    // Ignore call clobbers.157    return std::nullopt;158  }159}160 161void M68kMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {162  unsigned Opcode = MI->getOpcode();163  OutMI.setOpcode(Opcode);164 165  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {166    const MachineOperand &MO = MI->getOperand(i);167    std::optional<MCOperand> MCOp = LowerOperand(MI, MO);168 169    if (MCOp.has_value() && MCOp.value().isValid())170      OutMI.addOperand(MCOp.value());171  }172 173  // TAILJMPj, TAILJMPq - Lower to the correct jump instructions.174  if (Opcode == M68k::TAILJMPj || Opcode == M68k::TAILJMPq) {175    assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands");176    switch (Opcode) {177    case M68k::TAILJMPj:178      Opcode = M68k::JMP32j;179      break;180    case M68k::TAILJMPq:181      Opcode = M68k::BRA8;182      break;183    }184    OutMI.setOpcode(Opcode);185  }186}187