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