1//===-- NVPTXMCExpr.cpp - NVPTX specific MC expression classes ------------===//
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#include "NVPTXMCExpr.h"
10#include "llvm/ADT/StringExtras.h"
11#include "llvm/MC/MCAssembler.h"
12#include "llvm/MC/MCContext.h"
13#include "llvm/Support/Format.h"
14using namespace llvm;
15
16#define DEBUG_TYPE "nvptx-mcexpr"
17
18const NVPTXFloatMCExpr *
19NVPTXFloatMCExpr::create(VariantKind Kind, const APFloat &Flt, MCContext &Ctx) {
20  return new (Ctx) NVPTXFloatMCExpr(Kind, Flt);
21}
22
23void NVPTXFloatMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
24  bool Ignored;
25  unsigned NumHex;
26  APFloat APF = getAPFloat();
27
28  switch (Kind) {
29  default: llvm_unreachable("Invalid kind!");
30  case VK_NVPTX_HALF_PREC_FLOAT:
31    // ptxas does not have a way to specify half-precision floats.
32    // Instead we have to print and load fp16 constants as .b16
33    OS << "0x";
34    NumHex = 4;
35    APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
36    break;
37  case VK_NVPTX_SINGLE_PREC_FLOAT:
38    OS << "0f";
39    NumHex = 8;
40    APF.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &Ignored);
41    break;
42  case VK_NVPTX_DOUBLE_PREC_FLOAT:
43    OS << "0d";
44    NumHex = 16;
45    APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Ignored);
46    break;
47  }
48
49  APInt API = APF.bitcastToAPInt();
50  OS << format_hex_no_prefix(API.getZExtValue(), NumHex, /*Upper=*/true);
51}
52
53const NVPTXGenericMCSymbolRefExpr*
54NVPTXGenericMCSymbolRefExpr::create(const MCSymbolRefExpr *SymExpr,
55                                    MCContext &Ctx) {
56  return new (Ctx) NVPTXGenericMCSymbolRefExpr(SymExpr);
57}
58
59void NVPTXGenericMCSymbolRefExpr::printImpl(raw_ostream &OS,
60                                            const MCAsmInfo *MAI) const {
61  OS << "generic(";
62  SymExpr->print(OS, MAI);
63  OS << ")";
64}
65