Index: llvm/docs/RISCVUsage.rst =================================================================== --- llvm/docs/RISCVUsage.rst +++ llvm/docs/RISCVUsage.rst @@ -145,6 +145,9 @@ ``experimental-zvfh`` LLVM implements `this draft text `_. +``experimental-zfa`` + LLVM implements the `0.1 draft specification `_ (see Chapter 25). + To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using. To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`. Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`. Vendor Extensions 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' (Additional 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,72 @@ +//===-- 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 0.1. +// This version is still experimental as the 'Zfa' extension hasn't been +// ratified yet. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// 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; + +//===----------------------------------------------------------------------===// +// Instructions +//===----------------------------------------------------------------------===// + +let Predicates = [HasStdExtZfa] in { +def FMINM_S: FPALU_rr<0b0010100, 0b010, "fminm.s", FPR32, /*Commutable*/ 1>; +def FMAXM_S: FPALU_rr<0b0010100, 0b011, "fmaxm.s", FPR32, /*Commutable*/ 1>; + +def FROUND_S : FPUnaryOp_r_frm<0b0100000, 0b00100, FPR32, FPR32, "fround.s">; +def FROUNDNX_S : FPUnaryOp_r_frm<0b0100000, 0b00101, FPR32, FPR32, "froundnx.s">; + +def FLTQ_S : FPCmp_rr<0b1010000, 0b101, "fltq.s", FPR16, /*Commutable*/ 1>; +def FLEQ_S : FPCmp_rr<0b1010000, 0b100, "fleq.s", FPR16, /*Commutable*/ 1>; +} // Predicates = [HasStdExtZfa] + +let Predicates = [HasStdExtZfa, HasStdExtD] in { +def FMINM_D: FPALU_rr<0b0010101, 0b010, "fminm.d", FPR64, /*Commutable*/ 1>; +def FMAXM_D: FPALU_rr<0b0010101, 0b011, "fmaxm.d", FPR64, /*Commutable*/ 1>; + +def FROUND_D : FPUnaryOp_r_frm<0b0100001, 0b00100, FPR64, FPR64, "fround.d">; +def FROUNDNX_D : FPUnaryOp_r_frm<0b0100001, 0b00101, FPR64, FPR64, "froundnx.d">; + +def FCVTMOD_W_D + : FPUnaryOp_r_frm<0b1100001, 0b01000, GPR, FPR64, "fcvtmod.w.d">, + Sched<[WriteFCvtF64ToI32, ReadFCvtF64ToI32]>; + +def FLTQ_D : FPCmp_rr<0b1010001, 0b101, "fltq.d", FPR64, /*Commutable*/ 1>; +def FLEQ_D : FPCmp_rr<0b1010001, 0b100, "fleq.d", FPR64, /*Commutable*/ 1>; +} // 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 FMINM_H: FPALU_rr<0b0010110, 0b010, "fminm.h", FPR16, /*Commutable*/ 1>; +def FMAXM_H: FPALU_rr<0b0010110, 0b011, "fmaxm.h", FPR16, /*Commutable*/ 1>; + +def FROUND_H : FPUnaryOp_r_frm<0b0100010, 0b00100, FPR16, FPR16, "fround.h">; +def FROUNDNX_H : FPUnaryOp_r_frm<0b0100010, 0b00101, FPR16, FPR16, "froundnx.h">; + +def FLTQ_H : FPCmp_rr<0b1010010, 0b101, "fltq.h", FPR16, /*Commutable*/ 1>; +def FLEQ_H : FPCmp_rr<0b1010010, 0b100, "fleq.h", FPR16, /*Commutable*/ 1>; +} // 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,86 @@ +# 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: 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