225 lines · cpp
1//===-- MipsMCAsmInfo.cpp - Mips Asm Properties ---------------------------===//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 the declarations of the MipsMCAsmInfo properties.10//11//===----------------------------------------------------------------------===//12 13#include "MipsMCAsmInfo.h"14#include "MipsABIInfo.h"15#include "llvm/MC/MCValue.h"16#include "llvm/Support/Casting.h"17#include "llvm/TargetParser/Triple.h"18 19using namespace llvm;20 21void MipsELFMCAsmInfo::anchor() {}22 23MipsELFMCAsmInfo::MipsELFMCAsmInfo(const Triple &TheTriple,24 const MCTargetOptions &Options) {25 IsLittleEndian = TheTriple.isLittleEndian();26 27 MipsABIInfo ABI =28 MipsABIInfo::computeTargetABI(TheTriple, Options.getABIName());29 30 if (TheTriple.isMIPS64() && !ABI.IsN32())31 CodePointerSize = CalleeSaveStackSlotSize = 8;32 33 if (ABI.IsO32())34 PrivateGlobalPrefix = "$";35 else if (ABI.IsN32() || ABI.IsN64())36 PrivateGlobalPrefix = ".L";37 PrivateLabelPrefix = PrivateGlobalPrefix;38 39 AlignmentIsInBytes = false;40 Data16bitsDirective = "\t.2byte\t";41 Data32bitsDirective = "\t.4byte\t";42 Data64bitsDirective = "\t.8byte\t";43 CommentString = "#";44 AllowDollarAtStartOfIdentifier = false;45 ZeroDirective = "\t.space\t";46 UseAssignmentForEHBegin = true;47 SupportsDebugInformation = true;48 ExceptionsType = ExceptionHandling::DwarfCFI;49 DwarfRegNumForCFI = true;50}51 52void MipsCOFFMCAsmInfo::anchor() {}53 54MipsCOFFMCAsmInfo::MipsCOFFMCAsmInfo() {55 HasSingleParameterDotFile = true;56 WinEHEncodingType = WinEH::EncodingType::Itanium;57 58 ExceptionsType = ExceptionHandling::WinEH;59 60 PrivateGlobalPrefix = ".L";61 PrivateLabelPrefix = ".L";62 AllowAtInName = true;63}64 65const MCSpecifierExpr *Mips::createGpOff(const MCExpr *Expr, Mips::Specifier S,66 MCContext &Ctx) {67 Expr = MCSpecifierExpr::create(Expr, Mips::S_GPREL, Ctx);68 Expr = MCSpecifierExpr::create(Expr, Mips::S_NEG, Ctx);69 return MCSpecifierExpr::create(Expr, S, Ctx);70}71 72static void printImpl(const MCAsmInfo &MAI, raw_ostream &OS,73 const MCSpecifierExpr &Expr) {74 int64_t AbsVal;75 76 switch (Expr.getSpecifier()) {77 case Mips::S_None:78 case Mips::S_Special:79 llvm_unreachable("Mips::S_None and MEK_Special are invalid");80 break;81 case Mips::S_DTPREL:82 // Mips::S_DTPREL is used for marking TLS DIEExpr only83 // and contains a regular sub-expression.84 MAI.printExpr(OS, *Expr.getSubExpr());85 return;86 case Mips::S_CALL_HI16:87 OS << "%call_hi";88 break;89 case Mips::S_CALL_LO16:90 OS << "%call_lo";91 break;92 case Mips::S_DTPREL_HI:93 OS << "%dtprel_hi";94 break;95 case Mips::S_DTPREL_LO:96 OS << "%dtprel_lo";97 break;98 case Mips::S_GOT:99 OS << "%got";100 break;101 case Mips::S_GOTTPREL:102 OS << "%gottprel";103 break;104 case Mips::S_GOT_CALL:105 OS << "%call16";106 break;107 case Mips::S_GOT_DISP:108 OS << "%got_disp";109 break;110 case Mips::S_GOT_HI16:111 OS << "%got_hi";112 break;113 case Mips::S_GOT_LO16:114 OS << "%got_lo";115 break;116 case Mips::S_GOT_PAGE:117 OS << "%got_page";118 break;119 case Mips::S_GOT_OFST:120 OS << "%got_ofst";121 break;122 case Mips::S_GPREL:123 OS << "%gp_rel";124 break;125 case Mips::S_HI:126 OS << "%hi";127 break;128 case Mips::S_HIGHER:129 OS << "%higher";130 break;131 case Mips::S_HIGHEST:132 OS << "%highest";133 break;134 case Mips::S_LO:135 OS << "%lo";136 break;137 case Mips::S_NEG:138 OS << "%neg";139 break;140 case Mips::S_PCREL_HI16:141 OS << "%pcrel_hi";142 break;143 case Mips::S_PCREL_LO16:144 OS << "%pcrel_lo";145 break;146 case Mips::S_TLSGD:147 OS << "%tlsgd";148 break;149 case Mips::S_TLSLDM:150 OS << "%tlsldm";151 break;152 case Mips::S_TPREL_HI:153 OS << "%tprel_hi";154 break;155 case Mips::S_TPREL_LO:156 OS << "%tprel_lo";157 break;158 }159 160 OS << '(';161 if (Expr.evaluateAsAbsolute(AbsVal))162 OS << AbsVal;163 else164 MAI.printExpr(OS, *Expr.getSubExpr());165 OS << ')';166}167 168bool Mips::isGpOff(const MCSpecifierExpr &E) {169 if (E.getSpecifier() == Mips::S_HI || E.getSpecifier() == Mips::S_LO) {170 if (const auto *S1 = dyn_cast<const MCSpecifierExpr>(E.getSubExpr())) {171 if (const auto *S2 = dyn_cast<const MCSpecifierExpr>(S1->getSubExpr())) {172 if (S1->getSpecifier() == Mips::S_NEG &&173 S2->getSpecifier() == Mips::S_GPREL) {174 // S = E.getSpecifier();175 return true;176 }177 }178 }179 }180 return false;181}182 183static bool evaluate(const MCSpecifierExpr &Expr, MCValue &Res,184 const MCAssembler *Asm) {185 // Look for the %hi(%neg(%gp_rel(X))) and %lo(%neg(%gp_rel(X)))186 // special cases.187 if (Mips::isGpOff(Expr)) {188 const MCExpr *SubExpr =189 cast<MCSpecifierExpr>(190 cast<MCSpecifierExpr>(Expr.getSubExpr())->getSubExpr())191 ->getSubExpr();192 if (!SubExpr->evaluateAsRelocatable(Res, Asm))193 return false;194 195 Res.setSpecifier(Mips::S_Special);196 return true;197 }198 199 if (!Expr.getSubExpr()->evaluateAsRelocatable(Res, Asm))200 return false;201 Res.setSpecifier(Expr.getSpecifier());202 return !Res.getSubSym();203}204 205void MipsELFMCAsmInfo::printSpecifierExpr(raw_ostream &OS,206 const MCSpecifierExpr &Expr) const {207 printImpl(*this, OS, Expr);208}209 210bool MipsELFMCAsmInfo::evaluateAsRelocatableImpl(const MCSpecifierExpr &Expr,211 MCValue &Res,212 const MCAssembler *Asm) const {213 return evaluate(Expr, Res, Asm);214}215 216void MipsCOFFMCAsmInfo::printSpecifierExpr(raw_ostream &OS,217 const MCSpecifierExpr &Expr) const {218 printImpl(*this, OS, Expr);219}220 221bool MipsCOFFMCAsmInfo::evaluateAsRelocatableImpl(222 const MCSpecifierExpr &Expr, MCValue &Res, const MCAssembler *Asm) const {223 return evaluate(Expr, Res, Asm);224}225