diff --git a/llvm/lib/Object/ELFObjectFile.cpp b/llvm/lib/Object/ELFObjectFile.cpp --- a/llvm/lib/Object/ELFObjectFile.cpp +++ b/llvm/lib/Object/ELFObjectFile.cpp @@ -331,6 +331,12 @@ case 'c': Features.AddFeature(Arch.take_front()); break; + case 'z': + if (Arch.consume_front("zfh")) { + Features.AddFeature("experimental-zfh"); + Features.AddFeature("f"); // Zfh implies F extension. + } + break; } // FIXME: Handle version numbers. diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -2116,6 +2116,7 @@ else return Error(ValueExprLoc, "bad arch string " + Arch); + unsigned drop_char_num = 1; while (!Arch.empty()) { if (Arch[0] == 'i') clearFeatureBits(RISCV::FeatureRV32E, "e"); @@ -2138,10 +2139,13 @@ setFeatureBits(RISCV::FeatureStdExtD, "d"); } else if (Arch[0] == 'c') { setFeatureBits(RISCV::FeatureStdExtC, "c"); + } else if (Arch.consume_front("zfh")) { + setFeatureBits(RISCV::FeatureExtZfh, "experimental-zfh"); + drop_char_num = 3; } else return Error(ValueExprLoc, "bad arch string " + Arch); - Arch = Arch.drop_front(1); + Arch = Arch.drop_front(drop_char_num); int major = 0; int minor = 0; Arch.consumeInteger(10, major); @@ -2178,6 +2182,8 @@ formalArchStr = (Twine(formalArchStr) + "_d2p0").str(); if (getFeatureBits(RISCV::FeatureStdExtC)) formalArchStr = (Twine(formalArchStr) + "_c2p0").str(); + if (getFeatureBits(RISCV::FeatureExtZfh)) + formalArchStr = (Twine(formalArchStr) + "_zfh0p1").str(); getTargetStreamer().emitTextAttribute(Tag, formalArchStr); } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -60,6 +60,8 @@ Arch += "_d2p0"; if (STI.hasFeature(RISCV::FeatureStdExtC)) Arch += "_c2p0"; + if (STI.hasFeature(RISCV::FeatureExtZfh)) + Arch += "_zfh0p1"; emitTextAttribute(RISCVAttrs::ARCH, Arch); } diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll --- a/llvm/test/CodeGen/RISCV/attributes.ll +++ b/llvm/test/CodeGen/RISCV/attributes.ll @@ -5,22 +5,28 @@ ; RUN: llc -mtriple=riscv32 -mattr=+f %s -o - | FileCheck --check-prefix=RV32F %s ; RUN: llc -mtriple=riscv32 -mattr=+d %s -o - | FileCheck --check-prefix=RV32D %s ; RUN: llc -mtriple=riscv32 -mattr=+c %s -o - | FileCheck --check-prefix=RV32C %s +; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfh %s -o - \ +; RUN: | FileCheck --check-prefix=RV32ZFH %s ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefix=RV64M %s ; RUN: llc -mtriple=riscv64 -mattr=+a %s -o - | FileCheck --check-prefix=RV64A %s ; RUN: llc -mtriple=riscv64 -mattr=+f %s -o - | FileCheck --check-prefix=RV64F %s ; RUN: llc -mtriple=riscv64 -mattr=+d %s -o - | FileCheck --check-prefix=RV64D %s ; RUN: llc -mtriple=riscv64 -mattr=+c %s -o - | FileCheck --check-prefix=RV64C %s +; RUN: llc -mtriple=riscv64 -mattr=+experimental-zfh %s -o - \ +; RUN: | FileCheck --check-prefix=RV64ZFH %s ; RV32M: .attribute 5, "rv32i2p0_m2p0" ; RV32A: .attribute 5, "rv32i2p0_a2p0" ; RV32F: .attribute 5, "rv32i2p0_f2p0" ; RV32D: .attribute 5, "rv32i2p0_f2p0_d2p0" ; RV32C: .attribute 5, "rv32i2p0_c2p0" +; RV32ZFH: .attribute 5, "rv32i2p0_f2p0_zfh0p1" ; RV64M: .attribute 5, "rv64i2p0_m2p0" ; RV64A: .attribute 5, "rv64i2p0_a2p0" ; RV64F: .attribute 5, "rv64i2p0_f2p0" ; RV64D: .attribute 5, "rv64i2p0_f2p0_d2p0" ; RV64C: .attribute 5, "rv64i2p0_c2p0" +; RV64ZFH: .attribute 5, "rv64i2p0_f2p0_zfh0p1" define i32 @addi(i32 %a) { %1 = add i32 %a, 1 diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s --- a/llvm/test/MC/RISCV/attribute-arch.s +++ b/llvm/test/MC/RISCV/attribute-arch.s @@ -35,3 +35,6 @@ .attribute arch, "rv32ima2p_fdc" # CHECK: attribute 5, "rv32i2p0_m2p0_a2p0_f2p0_d2p0_c2p0" + +.attribute arch, "rv32ima2p_fdczfh0p1" +# CHECK: attribute 5, "rv32i2p0_m2p0_a2p0_f2p0_d2p0_c2p0_zfh0p1" diff --git a/llvm/test/MC/RISCV/attribute-with-insts.s b/llvm/test/MC/RISCV/attribute-with-insts.s --- a/llvm/test/MC/RISCV/attribute-with-insts.s +++ b/llvm/test/MC/RISCV/attribute-with-insts.s @@ -10,7 +10,7 @@ # RUN: | llvm-objdump --triple=riscv64 -d -M no-aliases - \ # RUN: | FileCheck -check-prefix=CHECK-INST %s -.attribute arch, "rv64i2p0_m2p0_a2p0_d2p0_c2p0" +.attribute arch, "rv64i2p0_m2p0_a2p0_d2p0_c2p0_zfh0p1" # CHECK-INST: lr.w t0, (t1) lr.w t0, (t1) @@ -24,6 +24,9 @@ # CHECK-INST: fmadd.s fa0, fa1, fa2, fa3, dyn fmadd.s f10, f11, f12, f13, dyn +# CHECK-INST: fmadd.h fa0, fa1, fa2, fa3, dyn +fmadd.h f10, f11, f12, f13, dyn + # CHECK-INST: addi ra, sp, 2 addi ra, sp, 2 diff --git a/llvm/test/MC/RISCV/attribute.s b/llvm/test/MC/RISCV/attribute.s --- a/llvm/test/MC/RISCV/attribute.s +++ b/llvm/test/MC/RISCV/attribute.s @@ -6,8 +6,8 @@ .attribute stack_align, 16 # CHECK: attribute 4, 16 -.attribute arch, "rv32i2p0_m2p0_a2p0_c2p0" -# CHECK: attribute 5, "rv32i2p0_m2p0_a2p0_c2p0" +.attribute arch, "rv32i2p0_m2p0_a2p0_c2p0_zfh0p1" +# CHECK: attribute 5, "rv32i2p0_m2p0_a2p0_f2p0_c2p0_zfh0p1" .attribute unaligned_access, 0 # CHECK: attribute 6, 0