Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -165,6 +165,7 @@ #include "RISCVGenAsmMatcher.inc" OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands); + OperandMatchResultTy parseFPImm(OperandVector &Operands); OperandMatchResultTy parseImmediate(OperandVector &Operands); OperandMatchResultTy parseRegister(OperandVector &Operands, bool AllowParens = false); @@ -289,6 +290,7 @@ Token, Register, Immediate, + FPImmediate, SystemRegister, VType, VTypeTHeadV, @@ -306,6 +308,10 @@ const MCExpr *Val; }; + struct FPImmOp { + unsigned Val; + }; + struct SysRegOp { const char *Data; unsigned Length; @@ -323,6 +329,7 @@ StringRef Tok; RegOp Reg; ImmOp Imm; + FPImmOp FPImm; struct SysRegOp SysReg; struct VTypeOp VType; }; @@ -342,6 +349,9 @@ case KindTy::Immediate: Imm = o.Imm; break; + case KindTy::FPImmediate: + FPImm = o.FPImm; + break; case KindTy::Token: Tok = o.Tok; break; @@ -534,6 +544,12 @@ return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; } + /// Return true if the operand is a valid fli.s/fli.d/fli.h floating-point immediate. + bool isLoadFPImm() const { + return Kind == KindTy::FPImmediate && + RISCVLoadFPImm::getLoadFPImm(APInt(32, getFPConst())) != -1; + } + bool isImmXLenLI() const { int64_t Imm; RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; @@ -823,6 +839,11 @@ return Imm.Val; } + unsigned getFPConst() const { + assert(Kind == KindTy::FPImmediate && "Invalid type access!"); + return FPImm.Val; + } + StringRef getToken() const { assert(Kind == KindTy::Token && "Invalid type access!"); return Tok; @@ -846,6 +867,8 @@ case KindTy::Immediate: OS << *getImm(); break; + case KindTy::FPImmediate: + break; case KindTy::Register: OS << ""; break; @@ -900,6 +923,16 @@ return Op; } + static std::unique_ptr createFPImm(unsigned Val, SMLoc S, + bool IsRV64) { + auto Op = std::make_unique(KindTy::FPImmediate); + Op->FPImm.Val = Val; + Op->StartLoc = S; + Op->EndLoc = S; + Op->IsRV64 = IsRV64; + return Op; + } + static std::unique_ptr createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) { auto Op = std::make_unique(KindTy::SystemRegister); @@ -1030,6 +1063,12 @@ Inst.addOperand(MCOperand::createImm(getRoundingMode())); } + void addFPImmOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + int Imm = RISCVLoadFPImm::getLoadFPImm(APInt(32, getFPConst())); + Inst.addOperand(MCOperand::createImm(Imm)); + } + #include "THEAD/THEADOperand.def" }; } // end anonymous namespace. @@ -1295,6 +1334,10 @@ ErrorLoc, "operand must be a valid floating point rounding mode mnemonic"); } + case Match_InvalidLoadFPImm: { + SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); + return Error(ErrorLoc, "expected floating-point constant"); + } case Match_InvalidBareSymbol: { SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); return Error(ErrorLoc, "operand must be a bare symbol name"); @@ -1570,6 +1613,66 @@ return MatchOperand_NoMatch; } +OperandMatchResultTy RISCVAsmParser::parseFPImm(OperandVector &Operands) { + SMLoc S = getLoc(); + + // Handle negation, as that still comes through as a separate token. + bool isNegative = parseOptionalToken(AsmToken::Minus); + + const AsmToken &Tok = getTok(); + if (!Tok.is(AsmToken::Real) && !Tok.is(AsmToken::Integer) && + !Tok.is(AsmToken::Identifier)) { + TokError("invalid floating point immediate"); + return MatchOperand_NoMatch; + } + + // Parse special floats (inf/nan/min) representation. + if (Tok.is(AsmToken::Identifier)) { + if (Tok.getString().compare_insensitive("inf") == 0) { + APFloat SpecialVal = APFloat::getInf(APFloat::IEEEsingle()); + Operands.push_back(RISCVOperand::createFPImm( + SpecialVal.bitcastToAPInt().getZExtValue(), S, isRV64())); + } else if (Tok.getString().compare_insensitive("nan") == 0) { + APFloat SpecialVal = APFloat::getNaN(APFloat::IEEEsingle()); + Operands.push_back(RISCVOperand::createFPImm( + SpecialVal.bitcastToAPInt().getZExtValue(), S, isRV64())); + } else if (Tok.getString().compare_insensitive("min") == 0) { + unsigned SpecialVal = RISCVLoadFPImm::getFPImm(1); + Operands.push_back(RISCVOperand::createFPImm(SpecialVal, S, isRV64())); + } else { + TokError("invalid floating point literal"); + return MatchOperand_ParseFail; + } + } else if (Tok.is(AsmToken::Integer)) { + // Parse integer representation. + if (Tok.getIntVal() > 31 || isNegative) { + TokError("encoded floating point value out of range"); + return MatchOperand_ParseFail; + } + unsigned F = RISCVLoadFPImm::getFPImm(Tok.getIntVal()); + Operands.push_back(RISCVOperand::createFPImm(F, S, isRV64())); + } else { + // Parse FP representation. + APFloat RealVal(APFloat::IEEEsingle()); + auto StatusOrErr = + RealVal.convertFromString(Tok.getString(), APFloat::rmTowardZero); + if (errorToBool(StatusOrErr.takeError())) { + TokError("invalid floating point representation"); + return MatchOperand_ParseFail; + } + + if (isNegative) + RealVal.changeSign(); + + Operands.push_back(RISCVOperand::createFPImm( + RealVal.bitcastToAPInt().getZExtValue(), S, isRV64())); + } + + Lex(); // Eat the token. + + return MatchOperand_Success; +} + OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { SMLoc S = getLoc(); SMLoc E; Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h =================================================================== --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h +++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h @@ -14,6 +14,8 @@ #define LLVM_LIB_TARGET_RISCV_MCTARGETDESC_RISCVBASEINFO_H #include "MCTargetDesc/RISCVMCTargetDesc.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCInstrDesc.h" @@ -333,6 +335,69 @@ } } // namespace RISCVFPRndMode +//===----------------------------------------------------------------------===// +// Floating-point Immediates +// + +// We expect an 5-bit binary encoding of a floating-point constant here. +static const std::pair LoadFPImmArr[] = { + {0b00000001, 0b000}, {0b01101111, 0b000}, {0b01110000, 0b000}, + {0b01110111, 0b000}, {0b01111000, 0b000}, {0b01111011, 0b000}, + {0b01111100, 0b000}, {0b01111101, 0b000}, {0b01111101, 0b010}, + {0b01111101, 0b100}, {0b01111101, 0b110}, {0b01111110, 0b000}, + {0b01111110, 0b010}, {0b01111110, 0b100}, {0b01111110, 0b110}, + {0b01111111, 0b000}, {0b01111111, 0b010}, {0b01111111, 0b100}, + {0b01111111, 0b110}, {0b10000000, 0b000}, {0b10000000, 0b010}, + {0b10000000, 0b100}, {0b10000001, 0b000}, {0b10000010, 0b000}, + {0b10000011, 0b000}, {0b10000110, 0b000}, {0b10000111, 0b000}, + {0b10001110, 0b000}, {0b10001111, 0b000}, {0b11111111, 0b000}, + {0b11111111, 0b100}, +}; + +namespace RISCVLoadFPImm { +inline static unsigned getFPImm(unsigned Imm) { + uint8_t Sign; + uint8_t Exp; + uint8_t Mantissa; + + if (Imm == 0) { + Sign = 0b1; + Exp = 0b01111111; + Mantissa = 0b000; + } else { + Sign = 0b0; + Exp = LoadFPImmArr[Imm - 1].first; + Mantissa = LoadFPImmArr[Imm - 1].second; + } + + return Sign << 31 | Exp << 23 | Mantissa << 20; +} + +/// getLoadFPImm - Return a 5-bit binary encoding of the 32-bit +/// floating-point immediate value. If the value cannot be represented as an +/// 5-bit binary encoding, then return -1. +static inline int getLoadFPImm(const APInt &Imm) { + uint8_t Sign = Imm.lshr(31).getZExtValue() & 1; + uint8_t Exp = Imm.lshr(23).getZExtValue() & 0xff; + uint8_t Mantissa = Imm.lshr(20).getZExtValue() & 0x7; + + if (Sign == 0b1 && Exp == 0b01111111 && Mantissa == 0b000) + return 0; + + if (Sign == 0b0) { + auto EMI = llvm::find(LoadFPImmArr, std::make_pair(Exp, Mantissa)); + if (EMI != std::end(LoadFPImmArr)) + return std::distance(std::begin(LoadFPImmArr), EMI) + 1; + } + + return -1; +} + +static inline int getLoadFPImm(const APFloat &FPImm) { + return getLoadFPImm(FPImm.bitcastToAPInt()); +} +} // namespace RISCVLoadFPImm + namespace RISCVSysReg { struct SysReg { const char *Name; Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h =================================================================== --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h +++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h @@ -40,6 +40,8 @@ const MCSubtargetInfo &STI, raw_ostream &O); void printFRMArg(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); + void printFPImmOperand(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, raw_ostream &O); void printZeroOffsetMemOp(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); void printVTypeI(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp =================================================================== --- llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp +++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.cpp @@ -156,6 +156,16 @@ O << RISCVFPRndMode::roundingModeToString(FRMArg); } +void RISCVInstPrinter::printFPImmOperand(const MCInst *MI, unsigned OpNo, + const MCSubtargetInfo &STI, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNo); + if (MO.getImm() == 1) + O << "min"; + else + O << bit_cast(RISCVLoadFPImm::getFPImm(MO.getImm())); +} + void RISCVInstPrinter::printZeroOffsetMemOp(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { Index: llvm/lib/Target/RISCV/RISCV.td =================================================================== --- llvm/lib/Target/RISCV/RISCV.td +++ llvm/lib/Target/RISCV/RISCV.td @@ -125,6 +125,14 @@ "'Zhinx' (Half Float in Integer) or " "'Zhinxmin' (Half Float in Integer Minimal)">; +def FeatureStdExtZfa + : SubtargetFeature<"experimental-zfa", "HasStdExtZfa", "true", + "'Zfa' (Half-Precision Floating-Point)", + [FeatureStdExtF]>; +def HasStdExtZfa : Predicate<"Subtarget->hasStdExtZfa()">, + AssemblerPredicate<(all_of FeatureStdExtZfa), + "'Zfa' (Additional Floating-Point)">; + def FeatureStdExtC : SubtargetFeature<"c", "HasStdExtC", "true", "'C' (Compressed Instructions)">; Index: llvm/lib/Target/RISCV/RISCVInstrInfo.td =================================================================== --- llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -1865,6 +1865,7 @@ include "RISCVInstrInfoZk.td" include "RISCVInstrInfoV.td" include "RISCVInstrInfoZfh.td" +include "RISCVInstrInfoZfa.td" include "RISCVInstrInfoZicbo.td" //===----------------------------------------------------------------------===// Index: llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td =================================================================== --- /dev/null +++ llvm/lib/Target/RISCV/RISCVInstrInfoZfa.td @@ -0,0 +1,121 @@ +//===-- RISCVInstrInfoZfa.td - RISC-V 'Zfa' instructions ---*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file describes the RISC-V instructions from the standard 'Zfa' +// additional floating-point extension, version 1.0. +// This version is still experimental as the 'Zfa' extension hasn't been +// ratified yet. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Operand and SDNode transformation definitions. +//===----------------------------------------------------------------------===// + +// 5-bit floating-point immediate encodings. +def LoadFPImmOperand : AsmOperandClass { + let Name = "LoadFPImm"; + let ParserMethod = "parseFPImm"; + let RenderMethod = "addFPImmOperands"; + let DiagnosticType = "InvalidLoadFPImm"; +} + +def loadfpimm : Operand { + let ParserMatchClass = LoadFPImmOperand; + let PrintMethod = "printFPImmOperand"; +} + +//===----------------------------------------------------------------------===// +// Instruction class templates +//===----------------------------------------------------------------------===// + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in +class FPBinaryOp_rr funct7, bits<3> funct3, DAGOperand rdty, + DAGOperand rsty, string opcodestr> + : RVInstR; + +let hasSideEffects = 0, mayLoad = 0, mayStore = 0, mayRaiseFPException = 1 in +class FPUnaryOp_imm funct7, bits<5> rs2val, bits<3> funct3, RISCVOpcode opcode, + dag outs, dag ins, string opcodestr, string argstr> + : RVInst { + bits<5> imm; + bits<5> rd; + + let Inst{31-25} = funct7; + let Inst{24-20} = rs2val; + let Inst{19-15} = imm; + let Inst{14-12} = funct3; + let Inst{11-7} = rd; + let Opcode = opcode.Value; +} + +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + +let Predicates = [HasStdExtZfa] in { +def FLI_S : FPUnaryOp_imm<0b1111000, 0b00001, 0b000, OPC_OP_FP, (outs FPR32:$rd), + (ins loadfpimm:$imm), "fli.s", "$rd, $imm">, + Sched<[WriteFMovI32ToF32, ReadFMovI32ToF32]>; + +defm FMINM_S : FPALU_rr_m<0b0010100, 0b010, "fminm.s", FINX, /*Commutable*/1>; +defm FMAXM_S : FPALU_rr_m<0b0010100, 0b011, "fmaxm.s", FINX, /*Commutable*/1>; + +defm FROUND_S : FPUnaryOp_r_frm_m<0b0100000, 0b00100, FDINX, "fround.s">, + Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>; +defm FROUNDNX_S : FPUnaryOp_r_frm_m<0b0100000, 0b00101, FDINX, "froundnx.s">, + Sched<[WriteFCvtF64ToF32, ReadFCvtF64ToF32]>; + +defm FLTQ_S : FPCmp_rr_m<0b1010000, 0b101, "fltq.s", FINX>; +defm FLEQ_S : FPCmp_rr_m<0b1010000, 0b100, "fleq.s", FINX>; +} // Predicates = [HasStdExtZfa] + +let Predicates = [HasStdExtZfa, HasStdExtD] in { +def FLI_D : FPUnaryOp_imm<0b1111001, 0b00001, 0b000, OPC_OP_FP, (outs FPR64:$rd), + (ins loadfpimm:$imm), "fli.d", "$rd, $imm">, + Sched<[WriteFMovI64ToF64, ReadFMovI64ToF64]>; + +defm FMINM_D : FPALU_rr_m<0b0010101, 0b010, "fminm.d", DINX, /*Commutable*/1>; +defm FMAXM_D : FPALU_rr_m<0b0010101, 0b011, "fmaxm.d", DINX, /*Commutable*/1>; + +defm FROUND_D : FPUnaryOp_r_frm_m<0b0100001, 0b00100, DFINX, "fround.d">, + Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>; +defm FROUNDNX_D : FPUnaryOp_r_frm_m<0b0100001, 0b00101, DFINX, "froundnx.d">, + Sched<[WriteFCvtF32ToF64, ReadFCvtF32ToF64]>; + +defm FCVTMOD_W_D : FPUnaryOp_r_frm_m<0b1100001, 0b01000, XDINX, "fcvtmod.w.d">, + Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>; + +defm FLTQ_D : FPCmp_rr_m<0b1010001, 0b101, "fltq.d", DINX>; +defm FLEQ_D : FPCmp_rr_m<0b1010001, 0b100, "fleq.d", DINX>; +} // Predicates = [HasStdExtZfa, HasStdExtD] + +let Predicates = [HasStdExtZfa, HasStdExtD, IsRV32] in { +def FMVH_X_D : FPUnaryOp_r<0b1110001, 0b00001, 0b000, GPR, FPR64, "fmvh.x.d">, + Sched<[WriteFMovF32ToI32, ReadFMovF32ToI32]>; +def FMVP_D_X : FPBinaryOp_rr<0b1011001, 0b000, FPR64, GPR, "fmvp.d.x">, + Sched<[WriteFMovI32ToF32, ReadFMovI32ToF32]>; +} // Predicates = [HasStdExtZfa, HasStdExtD, IsRV32] + +let Predicates = [HasStdExtZfa, HasStdExtZfh] in { +def FLI_H : FPUnaryOp_imm<0b1111010, 0b00001, 0b000, OPC_OP_FP, (outs FPR16:$rd), + (ins loadfpimm:$imm), "fli.h", "$rd, $imm">, + Sched<[WriteFMovI16ToF16, ReadFMovI16ToF16]>; + +defm FMINM_H : FPALU_rr_m<0b0010110, 0b010, "fminm.h", HINX, /*Commutable*/1>; +defm FMAXM_H : FPALU_rr_m<0b0010110, 0b011, "fmaxm.h", HINX, /*Commutable*/1>; + +defm FROUND_H : FPUnaryOp_r_frm_m<0b0100010, 0b00100, HFINXmin, "fround.h">, + Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>; +defm FROUNDNX_H : FPUnaryOp_r_frm_m<0b0100010, 0b00101, HFINXmin, "froundnx.h">, + Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>; + +defm FLTQ_H : FPCmp_rr_m<0b1010010, 0b101, "fltq.h", HINX>; +defm FLEQ_H : FPCmp_rr_m<0b1010010, 0b100, "fleq.h", HINX>; +} // Predicates = [HasStdExtZfa, HasStdExtZfh] Index: llvm/test/MC/RISCV/rv32zfa-only-valid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv32zfa-only-valid.s @@ -0,0 +1,13 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfa,+d,+zfh -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zfa,+d,+zfh < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfa,+d,+zfh -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: fmvh.x.d a1, fs1 +# CHECK-ASM: encoding: [0xd3,0x85,0x14,0xe2] +fmvh.x.d a1, fs1 + +# CHECK-ASM-AND-OBJ: fmvp.d.x fs1, a1, a2 +# CHECK-ASM: encoding: [0xd3,0x84,0xc5,0xb2] +fmvp.d.x fs1, a1, a2 \ No newline at end of file Index: llvm/test/MC/RISCV/rv32zfa-valid.s =================================================================== --- /dev/null +++ llvm/test/MC/RISCV/rv32zfa-valid.s @@ -0,0 +1,486 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfa,+d,+zfh -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfa,+d,+zfh -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zfa,+d,+zfh < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfa,+d,+zfh -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zfa,+d,+zfh < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zfa,+d,+zfh -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: fli.s ft1, -1.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x10,0xf0] +fli.s ft1, -1.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.s ft1, min +# CHECK-ASM: encoding: [0xd3,0x80,0x10,0xf0] +fli.s ft1, min + +# CHECK-ASM-AND-OBJ: fli.s ft1, 1.525879e-05 +# CHECK-ASM: encoding: [0xd3,0x00,0x11,0xf0] +fli.s ft1, 1.525879e-05 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 3.051758e-05 +# CHECK-ASM: encoding: [0xd3,0x80,0x11,0xf0] +fli.s ft1, 3.051758e-05 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 3.906250e-03 +# CHECK-ASM: encoding: [0xd3,0x00,0x12,0xf0] +fli.s ft1, 3.906250e-03 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 7.812500e-03 +# CHECK-ASM: encoding: [0xd3,0x80,0x12,0xf0] +fli.s ft1, 7.812500e-03 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 6.250000e-02 +# CHECK-ASM: encoding: [0xd3,0x00,0x13,0xf0] +fli.s ft1, 6.250000e-02 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 1.250000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x13,0xf0] +fli.s ft1, 1.250000e-01 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 2.500000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x14,0xf0] +fli.s ft1, 2.500000e-01 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 3.125000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x14,0xf0] +fli.s ft1, 3.125000e-01 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 3.750000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x15,0xf0] +fli.s ft1, 3.750000e-01 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 4.375000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x15,0xf0] +fli.s ft1, 4.375000e-01 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 5.000000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x16,0xf0] +fli.s ft1, 5.000000e-01 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 6.250000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x16,0xf0] +fli.s ft1, 6.250000e-01 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 7.500000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x17,0xf0] +fli.s ft1, 7.500000e-01 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 8.750000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x17,0xf0] +fli.s ft1, 8.750000e-01 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 1.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x18,0xf0] +fli.s ft1, 1.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 1.250000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x18,0xf0] +fli.s ft1, 1.250000e+00 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 1.500000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x19,0xf0] +fli.s ft1, 1.500000e+00 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 1.750000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x19,0xf0] +fli.s ft1, 1.750000e+00 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 2.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x1a,0xf0] +fli.s ft1, 2.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 2.500000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x1a,0xf0] +fli.s ft1, 2.500000e+00 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 3.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x1b,0xf0] +fli.s ft1, 3.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 4.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x1b,0xf0] +fli.s ft1, 4.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 8.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x1c,0xf0] +fli.s ft1, 8.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 1.600000e+01 +# CHECK-ASM: encoding: [0xd3,0x80,0x1c,0xf0] +fli.s ft1, 1.600000e+01 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 1.280000e+02 +# CHECK-ASM: encoding: [0xd3,0x00,0x1d,0xf0] +fli.s ft1, 1.280000e+02 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 2.560000e+02 +# CHECK-ASM: encoding: [0xd3,0x80,0x1d,0xf0] +fli.s ft1, 2.560000e+02 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 3.276800e+04 +# CHECK-ASM: encoding: [0xd3,0x00,0x1e,0xf0] +fli.s ft1, 3.276800e+04 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 6.553600e+04 +# CHECK-ASM: encoding: [0xd3,0x80,0x1e,0xf0] +fli.s ft1, 6.553600e+04 + +# CHECK-ASM-AND-OBJ: fli.s ft1, 6.553600e+04 +# CHECK-ASM: encoding: [0xd3,0x80,0x1e,0xf0] +fli.s ft1, 29 + +# CHECK-ASM-AND-OBJ: fli.s ft1, INF +# CHECK-ASM: encoding: [0xd3,0x00,0x1f,0xf0] +fli.s ft1, INF + +# CHECK-ASM-AND-OBJ: fli.s ft1, nan +# CHECK-ASM: encoding: [0xd3,0x80,0x1f,0xf0] +fli.s ft1, nan + +# CHECK-ASM-AND-OBJ: fli.d ft1, -1.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x10,0xf2] +fli.d ft1, -1.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.d ft1, min +# CHECK-ASM: encoding: [0xd3,0x80,0x10,0xf2] +fli.d ft1, min + +# CHECK-ASM-AND-OBJ: fli.d ft1, 1.525879e-05 +# CHECK-ASM: encoding: [0xd3,0x00,0x11,0xf2] +fli.d ft1, 1.525879e-05 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 3.051758e-05 +# CHECK-ASM: encoding: [0xd3,0x80,0x11,0xf2] +fli.d ft1, 3.051758e-05 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 3.906250e-03 +# CHECK-ASM: encoding: [0xd3,0x00,0x12,0xf2] +fli.d ft1, 3.906250e-03 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 7.812500e-03 +# CHECK-ASM: encoding: [0xd3,0x80,0x12,0xf2] +fli.d ft1, 7.812500e-03 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 6.250000e-02 +# CHECK-ASM: encoding: [0xd3,0x00,0x13,0xf2] +fli.d ft1, 6.250000e-02 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 1.250000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x13,0xf2] +fli.d ft1, 1.250000e-01 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 2.500000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x14,0xf2] +fli.d ft1, 2.500000e-01 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 2.500000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x14,0xf2] +fli.d ft1, 8 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 3.125000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x14,0xf2] +fli.d ft1, 3.125000e-01 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 3.750000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x15,0xf2] +fli.d ft1, 3.750000e-01 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 4.375000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x15,0xf2] +fli.d ft1, 4.375000e-01 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 5.000000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x16,0xf2] +fli.d ft1, 5.000000e-01 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 6.250000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x16,0xf2] +fli.d ft1, 6.250000e-01 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 7.500000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x17,0xf2] +fli.d ft1, 7.500000e-01 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 8.750000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x17,0xf2] +fli.d ft1, 8.750000e-01 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 1.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x18,0xf2] +fli.d ft1, 1.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 1.250000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x18,0xf2] +fli.d ft1, 1.250000e+00 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 1.500000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x19,0xf2] +fli.d ft1, 1.500000e+00 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 1.750000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x19,0xf2] +fli.d ft1, 1.750000e+00 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 2.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x1a,0xf2] +fli.d ft1, 2.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 2.500000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x1a,0xf2] +fli.d ft1, 2.500000e+00 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 3.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x1b,0xf2] +fli.d ft1, 3.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 4.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x1b,0xf2] +fli.d ft1, 4.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 8.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x1c,0xf2] +fli.d ft1, 8.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 1.600000e+01 +# CHECK-ASM: encoding: [0xd3,0x80,0x1c,0xf2] +fli.d ft1, 1.600000e+01 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 1.280000e+02 +# CHECK-ASM: encoding: [0xd3,0x00,0x1d,0xf2] +fli.d ft1, 1.280000e+02 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 2.560000e+02 +# CHECK-ASM: encoding: [0xd3,0x80,0x1d,0xf2] +fli.d ft1, 2.560000e+02 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 3.276800e+04 +# CHECK-ASM: encoding: [0xd3,0x00,0x1e,0xf2] +fli.d ft1, 3.276800e+04 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 6.553600e+04 +# CHECK-ASM: encoding: [0xd3,0x80,0x1e,0xf2] +fli.d ft1, 6.553600e+04 + +# CHECK-ASM-AND-OBJ: fli.d ft1, 6.553600e+04 +# CHECK-ASM: encoding: [0xd3,0x80,0x1e,0xf2] +fli.d ft1, 29 + +# CHECK-ASM-AND-OBJ: fli.d ft1, INF +# CHECK-ASM: encoding: [0xd3,0x00,0x1f,0xf2] +fli.d ft1, INF + +# CHECK-ASM-AND-OBJ: fli.d ft1, nan +# CHECK-ASM: encoding: [0xd3,0x80,0x1f,0xf2] +fli.d ft1, nan + +# CHECK-ASM-AND-OBJ: fli.h ft1, -1.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x10,0xf4] +fli.h ft1, -1.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.h ft1, min +# CHECK-ASM: encoding: [0xd3,0x80,0x10,0xf4] +fli.h ft1, min + +# CHECK-ASM-AND-OBJ: fli.h ft1, 1.525879e-05 +# CHECK-ASM: encoding: [0xd3,0x00,0x11,0xf4] +fli.h ft1, 1.525879e-05 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 3.051758e-05 +# CHECK-ASM: encoding: [0xd3,0x80,0x11,0xf4] +fli.h ft1, 3.051758e-05 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 3.906250e-03 +# CHECK-ASM: encoding: [0xd3,0x00,0x12,0xf4] +fli.h ft1, 3.906250e-03 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 7.812500e-03 +# CHECK-ASM: encoding: [0xd3,0x80,0x12,0xf4] +fli.h ft1, 7.812500e-03 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 6.250000e-02 +# CHECK-ASM: encoding: [0xd3,0x00,0x13,0xf4] +fli.h ft1, 6.250000e-02 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 1.250000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x13,0xf4] +fli.h ft1, 1.250000e-01 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 2.500000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x14,0xf4] +fli.h ft1, 2.500000e-01 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 3.125000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x14,0xf4] +fli.h ft1, 3.125000e-01 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 3.750000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x15,0xf4] +fli.h ft1, 3.750000e-01 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 4.375000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x15,0xf4] +fli.h ft1, 4.375000e-01 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 5.000000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x16,0xf4] +fli.h ft1, 5.000000e-01 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 6.250000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x16,0xf4] +fli.h ft1, 6.250000e-01 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 7.500000e-01 +# CHECK-ASM: encoding: [0xd3,0x00,0x17,0xf4] +fli.h ft1, 7.500000e-01 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 8.750000e-01 +# CHECK-ASM: encoding: [0xd3,0x80,0x17,0xf4] +fli.h ft1, 8.750000e-01 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 1.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x18,0xf4] +fli.h ft1, 1.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 1.250000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x18,0xf4] +fli.h ft1, 1.250000e+00 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 1.500000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x19,0xf4] +fli.h ft1, 1.500000e+00 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 1.750000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x19,0xf4] +fli.h ft1, 1.750000e+00 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 2.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x1a,0xf4] +fli.h ft1, 2.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 2.500000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x1a,0xf4] +fli.h ft1, 2.500000e+00 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 3.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x1b,0xf4] +fli.h ft1, 3.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 4.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x80,0x1b,0xf4] +fli.h ft1, 4.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 8.000000e+00 +# CHECK-ASM: encoding: [0xd3,0x00,0x1c,0xf4] +fli.h ft1, 8.000000e+00 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 1.600000e+01 +# CHECK-ASM: encoding: [0xd3,0x80,0x1c,0xf4] +fli.h ft1, 1.600000e+01 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 1.280000e+02 +# CHECK-ASM: encoding: [0xd3,0x00,0x1d,0xf4] +fli.h ft1, 1.280000e+02 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 2.560000e+02 +# CHECK-ASM: encoding: [0xd3,0x80,0x1d,0xf4] +fli.h ft1, 2.560000e+02 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 3.276800e+04 +# CHECK-ASM: encoding: [0xd3,0x00,0x1e,0xf4] +fli.h ft1, 3.276800e+04 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 6.553600e+04 +# CHECK-ASM: encoding: [0xd3,0x80,0x1e,0xf4] +fli.h ft1, 6.553600e+04 + +# CHECK-ASM-AND-OBJ: fli.h ft1, 6.553600e+04 +# CHECK-ASM: encoding: [0xd3,0x80,0x1e,0xf4] +fli.h ft1, 29 + +# CHECK-ASM-AND-OBJ: fli.h ft1, INF +# CHECK-ASM: encoding: [0xd3,0x00,0x1f,0xf4] +fli.h ft1, INF + +# CHECK-ASM-AND-OBJ: fli.h ft1, nan +# CHECK-ASM: encoding: [0xd3,0x80,0x1f,0xf4] +fli.h ft1, nan + +# CHECK-ASM-AND-OBJ: fminm.s fa0, fa1, fa2 +# CHECK-ASM: encoding: [0x53,0xa5,0xc5,0x28] +fminm.s fa0, fa1, fa2 + +# CHECK-ASM-AND-OBJ: fmaxm.s fs3, fs4, fs5 +# CHECK-ASM: encoding: [0xd3,0x39,0x5a,0x29] +fmaxm.s fs3, fs4, fs5 + +# CHECK-ASM-AND-OBJ: fminm.d fa0, fa1, fa2 +# CHECK-ASM: encoding: [0x53,0xa5,0xc5,0x2a] +fminm.d fa0, fa1, fa2 + +# CHECK-ASM-AND-OBJ: fmaxm.d fs3, fs4, fs5 +# CHECK-ASM: encoding: [0xd3,0x39,0x5a,0x2b] +fmaxm.d fs3, fs4, fs5 + +# CHECK-ASM-AND-OBJ: fminm.h fa0, fa1, fa2 +# CHECK-ASM: encoding: [0x53,0xa5,0xc5,0x2c] +fminm.h fa0, fa1, fa2 + +# CHECK-ASM-AND-OBJ: fmaxm.h fs3, fs4, fs5 +# CHECK-ASM: encoding: [0xd3,0x39,0x5a,0x2d] +fmaxm.h fs3, fs4, fs5 + +# CHECK-ASM-AND-OBJ: fround.s fs1, fs2, dyn +# CHECK-ASM: encoding: [0xd3,0x74,0x49,0x40] +fround.s fs1, fs2, dyn + +# CHECK-ASM-AND-OBJ: froundnx.s fs1, fs2, dyn +# CHECK-ASM: encoding: [0xd3,0x74,0x59,0x40] +froundnx.s fs1, fs2, dyn + +# CHECK-ASM-AND-OBJ: fround.d fs1, fs2, dyn +# CHECK-ASM: encoding: [0xd3,0x74,0x49,0x42] +fround.d fs1, fs2, dyn + +# CHECK-ASM-AND-OBJ: froundnx.d fs1, fs2, dyn +# CHECK-ASM: encoding: [0xd3,0x74,0x59,0x42] +froundnx.d fs1, fs2, dyn + +# CHECK-ASM-AND-OBJ: fround.h ft1, fa1, dyn +# CHECK-ASM: encoding: [0xd3,0xf0,0x45,0x44] +fround.h ft1, fa1, dyn + +# CHECK-ASM-AND-OBJ: froundnx.h ft1, fa1, dyn +# CHECK-ASM: encoding: [0xd3,0xf0,0x55,0x44] +froundnx.h ft1, fa1, dyn + +# CHECK-ASM-AND-OBJ: fcvtmod.w.d a1, ft1, rtz +# CHECK-ASM: encoding: [0xd3,0x95,0x80,0xc2] +fcvtmod.w.d a1, ft1, rtz + +# CHECK-ASM-AND-OBJ: fltq.s a1, fs1, fs2 +# CHECK-ASM: encoding: [0xd3,0xd5,0x24,0xa1] +fltq.s a1, fs1, fs2 + +# CHECK-ASM-AND-OBJ: fleq.s a1, ft1, ft1 +# CHECK-ASM: encoding: [0xd3,0xc5,0x10,0xa0] +fleq.s a1, ft1, ft1 + +# CHECK-ASM-AND-OBJ: fltq.d a1, fs1, fs2 +# CHECK-ASM: encoding: [0xd3,0xd5,0x24,0xa3] +fltq.d a1, fs1, fs2 + +# CHECK-ASM-AND-OBJ: fleq.d a1, ft1, ft2 +# CHECK-ASM: encoding: [0xd3,0xc5,0x20,0xa2] +fleq.d a1, ft1, ft2 + +# CHECK-ASM-AND-OBJ: fltq.h a1, fs1, fs2 +# CHECK-ASM: encoding: [0xd3,0xd5,0x24,0xa5] +fltq.h a1, fs1, fs2 + +# CHECK-ASM-AND-OBJ: fleq.h a1, ft1, ft2 +# CHECK-ASM: encoding: [0xd3,0xc5,0x20,0xa4] +fleq.h a1, ft1, ft2