10b57cec5SDimitry Andric //===-- NVPTXMCExpr.cpp - NVPTX specific MC expression classes ------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "NVPTXMCExpr.h"
100b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
110b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h"
120b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
130b57cec5SDimitry Andric #include "llvm/Support/Format.h"
140b57cec5SDimitry Andric using namespace llvm;
150b57cec5SDimitry Andric
160b57cec5SDimitry Andric #define DEBUG_TYPE "nvptx-mcexpr"
170b57cec5SDimitry Andric
180b57cec5SDimitry Andric const NVPTXFloatMCExpr *
create(VariantKind Kind,const APFloat & Flt,MCContext & Ctx)190b57cec5SDimitry Andric NVPTXFloatMCExpr::create(VariantKind Kind, const APFloat &Flt, MCContext &Ctx) {
200b57cec5SDimitry Andric return new (Ctx) NVPTXFloatMCExpr(Kind, Flt);
210b57cec5SDimitry Andric }
220b57cec5SDimitry Andric
printImpl(raw_ostream & OS,const MCAsmInfo * MAI) const230b57cec5SDimitry Andric void NVPTXFloatMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
240b57cec5SDimitry Andric bool Ignored;
250b57cec5SDimitry Andric unsigned NumHex;
260b57cec5SDimitry Andric APFloat APF = getAPFloat();
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric switch (Kind) {
290b57cec5SDimitry Andric default: llvm_unreachable("Invalid kind!");
300b57cec5SDimitry Andric case VK_NVPTX_HALF_PREC_FLOAT:
310b57cec5SDimitry Andric // ptxas does not have a way to specify half-precision floats.
320b57cec5SDimitry Andric // Instead we have to print and load fp16 constants as .b16
330b57cec5SDimitry Andric OS << "0x";
340b57cec5SDimitry Andric NumHex = 4;
350b57cec5SDimitry Andric APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
360b57cec5SDimitry Andric break;
37*06c3fb27SDimitry Andric case VK_NVPTX_BFLOAT_PREC_FLOAT:
38*06c3fb27SDimitry Andric OS << "0x";
39*06c3fb27SDimitry Andric NumHex = 4;
40*06c3fb27SDimitry Andric APF.convert(APFloat::BFloat(), APFloat::rmNearestTiesToEven, &Ignored);
41*06c3fb27SDimitry Andric break;
420b57cec5SDimitry Andric case VK_NVPTX_SINGLE_PREC_FLOAT:
430b57cec5SDimitry Andric OS << "0f";
440b57cec5SDimitry Andric NumHex = 8;
450b57cec5SDimitry Andric APF.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, &Ignored);
460b57cec5SDimitry Andric break;
470b57cec5SDimitry Andric case VK_NVPTX_DOUBLE_PREC_FLOAT:
480b57cec5SDimitry Andric OS << "0d";
490b57cec5SDimitry Andric NumHex = 16;
500b57cec5SDimitry Andric APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, &Ignored);
510b57cec5SDimitry Andric break;
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric
540b57cec5SDimitry Andric APInt API = APF.bitcastToAPInt();
550b57cec5SDimitry Andric OS << format_hex_no_prefix(API.getZExtValue(), NumHex, /*Upper=*/true);
560b57cec5SDimitry Andric }
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric const NVPTXGenericMCSymbolRefExpr*
create(const MCSymbolRefExpr * SymExpr,MCContext & Ctx)590b57cec5SDimitry Andric NVPTXGenericMCSymbolRefExpr::create(const MCSymbolRefExpr *SymExpr,
600b57cec5SDimitry Andric MCContext &Ctx) {
610b57cec5SDimitry Andric return new (Ctx) NVPTXGenericMCSymbolRefExpr(SymExpr);
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric
printImpl(raw_ostream & OS,const MCAsmInfo * MAI) const640b57cec5SDimitry Andric void NVPTXGenericMCSymbolRefExpr::printImpl(raw_ostream &OS,
650b57cec5SDimitry Andric const MCAsmInfo *MAI) const {
660b57cec5SDimitry Andric OS << "generic(";
670b57cec5SDimitry Andric SymExpr->print(OS, MAI);
680b57cec5SDimitry Andric OS << ")";
690b57cec5SDimitry Andric }
70