brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.9 KiB · 455e6ad Raw
193 lines · cpp
1//=- LoongArchMCInstLower.cpp - Convert LoongArch MachineInstr to an 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 LoongArch MachineInstrs to their10// corresponding MCInst records.11//12//===----------------------------------------------------------------------===//13 14#include "LoongArch.h"15#include "MCTargetDesc/LoongArchBaseInfo.h"16#include "MCTargetDesc/LoongArchMCAsmInfo.h"17#include "llvm/BinaryFormat/ELF.h"18#include "llvm/CodeGen/AsmPrinter.h"19#include "llvm/CodeGen/MachineBasicBlock.h"20#include "llvm/CodeGen/MachineInstr.h"21#include "llvm/MC/MCAsmInfo.h"22#include "llvm/MC/MCContext.h"23 24using namespace llvm;25 26static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,27                                    const AsmPrinter &AP) {28  MCContext &Ctx = AP.OutContext;29  uint16_t Kind = 0;30 31  switch (LoongArchII::getDirectFlags(MO)) {32  default:33    llvm_unreachable("Unknown target flag on GV operand");34  case LoongArchII::MO_None:35    Kind = LoongArchMCExpr::VK_None;36    break;37  case LoongArchII::MO_CALL:38  case LoongArchII::MO_CALL_PLT:39    Kind = ELF::R_LARCH_B26;40    break;41  case LoongArchII::MO_PCREL_HI:42    Kind = ELF::R_LARCH_PCALA_HI20;43    break;44  case LoongArchII::MO_PCREL_LO:45    Kind = ELF::R_LARCH_PCALA_LO12;46    break;47  case LoongArchII::MO_PCREL64_LO:48    Kind = ELF::R_LARCH_PCALA64_LO20;49    break;50  case LoongArchII::MO_PCREL64_HI:51    Kind = ELF::R_LARCH_PCALA64_HI12;52    break;53  case LoongArchII::MO_GOT_PC_HI:54    Kind = ELF::R_LARCH_GOT_PC_HI20;55    break;56  case LoongArchII::MO_GOT_PC_LO:57    Kind = ELF::R_LARCH_GOT_PC_LO12;58    break;59  case LoongArchII::MO_GOT_PC64_LO:60    Kind = ELF::R_LARCH_GOT64_PC_LO20;61    break;62  case LoongArchII::MO_GOT_PC64_HI:63    Kind = ELF::R_LARCH_GOT64_PC_HI12;64    break;65  case LoongArchII::MO_LE_HI:66    Kind = ELF::R_LARCH_TLS_LE_HI20;67    break;68  case LoongArchII::MO_LE_LO:69    Kind = ELF::R_LARCH_TLS_LE_LO12;70    break;71  case LoongArchII::MO_LE64_LO:72    Kind = ELF::R_LARCH_TLS_LE64_LO20;73    break;74  case LoongArchII::MO_LE64_HI:75    Kind = ELF::R_LARCH_TLS_LE64_HI12;76    break;77  case LoongArchII::MO_IE_PC_HI:78    Kind = ELF::R_LARCH_TLS_IE_PC_HI20;79    break;80  case LoongArchII::MO_IE_PC_LO:81    Kind = ELF::R_LARCH_TLS_IE_PC_LO12;82    break;83  case LoongArchII::MO_IE_PC64_LO:84    Kind = ELF::R_LARCH_TLS_IE64_PC_LO20;85    break;86  case LoongArchII::MO_IE_PC64_HI:87    Kind = ELF::R_LARCH_TLS_IE64_PC_HI12;88    break;89  case LoongArchII::MO_LD_PC_HI:90    Kind = ELF::R_LARCH_TLS_LD_PC_HI20;91    break;92  case LoongArchII::MO_GD_PC_HI:93    Kind = ELF::R_LARCH_TLS_GD_PC_HI20;94    break;95  case LoongArchII::MO_CALL36:96    Kind = ELF::R_LARCH_CALL36;97    break;98  case LoongArchII::MO_DESC_PC_HI:99    Kind = ELF::R_LARCH_TLS_DESC_PC_HI20;100    break;101  case LoongArchII::MO_DESC_PC_LO:102    Kind = ELF::R_LARCH_TLS_DESC_PC_LO12;103    break;104  case LoongArchII::MO_DESC64_PC_LO:105    Kind = ELF::R_LARCH_TLS_DESC64_PC_LO20;106    break;107  case LoongArchII::MO_DESC64_PC_HI:108    Kind = ELF::R_LARCH_TLS_DESC64_PC_HI12;109    break;110  case LoongArchII::MO_DESC_LD:111    Kind = ELF::R_LARCH_TLS_DESC_LD;112    break;113  case LoongArchII::MO_DESC_CALL:114    Kind = ELF::R_LARCH_TLS_DESC_CALL;115    break;116  case LoongArchII::MO_LE_HI_R:117    Kind = ELF::R_LARCH_TLS_LE_HI20_R;118    break;119  case LoongArchII::MO_LE_ADD_R:120    Kind = ELF::R_LARCH_TLS_LE_ADD_R;121    break;122  case LoongArchII::MO_LE_LO_R:123    Kind = ELF::R_LARCH_TLS_LE_LO12_R;124    break;125    // TODO: Handle more target-flags.126  }127 128  const MCExpr *ME = MCSymbolRefExpr::create(Sym, Ctx);129 130  if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())131    ME = MCBinaryExpr::createAdd(132        ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);133 134  if (Kind != LoongArchMCExpr::VK_None)135    ME = LoongArchMCExpr::create(ME, Kind, Ctx, LoongArchII::hasRelaxFlag(MO));136  return MCOperand::createExpr(ME);137}138 139bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,140                                                   MCOperand &MCOp,141                                                   const AsmPrinter &AP) {142  switch (MO.getType()) {143  default:144    report_fatal_error(145        "lowerLoongArchMachineOperandToMCOperand: unknown operand type");146  case MachineOperand::MO_Register:147    // Ignore all implicit register operands.148    if (MO.isImplicit())149      return false;150    MCOp = MCOperand::createReg(MO.getReg());151    break;152  case MachineOperand::MO_RegisterMask:153    // Regmasks are like implicit defs.154    return false;155  case MachineOperand::MO_Immediate:156    MCOp = MCOperand::createImm(MO.getImm());157    break;158  case MachineOperand::MO_ConstantPoolIndex:159    MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP);160    break;161  case MachineOperand::MO_GlobalAddress:162    MCOp = lowerSymbolOperand(MO, AP.getSymbolPreferLocal(*MO.getGlobal()), AP);163    break;164  case MachineOperand::MO_MachineBasicBlock:165    MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), AP);166    break;167  case MachineOperand::MO_ExternalSymbol:168    MCOp = lowerSymbolOperand(169        MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);170    break;171  case MachineOperand::MO_BlockAddress:172    MCOp = lowerSymbolOperand(173        MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP);174    break;175  case MachineOperand::MO_JumpTableIndex:176    MCOp = lowerSymbolOperand(MO, AP.GetJTISymbol(MO.getIndex()), AP);177    break;178  }179  return true;180}181 182bool llvm::lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI,183                                              MCInst &OutMI, AsmPrinter &AP) {184  OutMI.setOpcode(MI->getOpcode());185 186  for (const MachineOperand &MO : MI->operands()) {187    MCOperand MCOp;188    if (lowerLoongArchMachineOperandToMCOperand(MO, MCOp, AP))189      OutMI.addOperand(MCOp);190  }191  return false;192}193