Skip to content

Commit

Permalink
[RISCV] Support Zfhmin extension
Browse files Browse the repository at this point in the history
According to RISC-V Unprivileged ISA 15.6.

Reviewed By: asb

Differential Revision: https://reviews.llvm.org/D111866
  • Loading branch information
Shao-Ce SUN committed Nov 5, 2021
1 parent 4f4c826 commit 5c3d718
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 21 deletions.
9 changes: 9 additions & 0 deletions clang/test/Driver/riscv-arch.c
Expand Up @@ -426,6 +426,15 @@
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZFH %s
// RV32-EXPERIMENTAL-ZFH: "-target-feature" "+experimental-zfh"

// RUN: %clang -target riscv32-unknown-elf -march=rv32izfhmin -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZFHMIN-NOFLAG %s
// RV32-EXPERIMENTAL-ZFHMIN-NOFLAG: error: invalid arch name 'rv32izfhmin'
// RV32-EXPERIMENTAL-ZFHMIN-NOFLAG: requires '-menable-experimental-extensions'

// RUN: %clang -target riscv32-unknown-elf -march=rv32izfhmin0p1 -menable-experimental-extensions -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZFHMIN %s
// RV32-EXPERIMENTAL-ZFHMIN: "-target-feature" "+experimental-zfhmin"

// RUN: %clang -target riscv32-unknown-elf -march=rv32izvamo -### %s -c 2>&1 | \
// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-ZVAMO-NOFLAG %s
// RV32-EXPERIMENTAL-ZVAMO-NOFLAG: error: invalid arch name 'rv32izvamo'
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Support/RISCVISAInfo.cpp
Expand Up @@ -64,6 +64,7 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
{"zvamo", RISCVExtensionVersion{0, 10}},
{"zvlsseg", RISCVExtensionVersion{0, 10}},

{"zfhmin", RISCVExtensionVersion{0, 1}},
{"zfh", RISCVExtensionVersion{0, 1}},
};

Expand Down
10 changes: 9 additions & 1 deletion llvm/lib/Target/RISCV/RISCV.td
Expand Up @@ -41,10 +41,18 @@ def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">,
AssemblerPredicate<(all_of FeatureStdExtD),
"'D' (Double-Precision Floating-Point)">;

def FeatureStdExtZfhmin
: SubtargetFeature<"experimental-zfhmin", "HasStdExtZfhmin", "true",
"'Zfhmin' (Half-Precision Floating-Point Minimal)",
[FeatureStdExtF]>;
def HasStdExtZfhmin : Predicate<"Subtarget->hasStdExtZfhmin()">,
AssemblerPredicate<(all_of FeatureStdExtZfhmin),
"'Zfhmin' (Half-Precision Floating-Point Minimal)">;

def FeatureStdExtZfh
: SubtargetFeature<"experimental-zfh", "HasStdExtZfh", "true",
"'Zfh' (Half-Precision Floating-Point)",
[FeatureStdExtF]>;
[FeatureStdExtZfhmin, FeatureStdExtF]>;
def HasStdExtZfh : Predicate<"Subtarget->hasStdExtZfh()">,
AssemblerPredicate<(all_of FeatureStdExtZfh),
"'Zfh' (Half-Precision Floating-Point)">;
Expand Down
14 changes: 7 additions & 7 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Expand Up @@ -1166,7 +1166,7 @@ bool RISCVTargetLowering::shouldSinkOperands(

bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const {
if (VT == MVT::f16 && !Subtarget.hasStdExtZfh())
if (VT == MVT::f16 && !Subtarget.hasStdExtZfhmin())
return false;
if (VT == MVT::f32 && !Subtarget.hasStdExtF())
return false;
Expand All @@ -1186,9 +1186,9 @@ bool RISCVTargetLowering::hasBitPreservingFPLogic(EVT VT) const {
MVT RISCVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
CallingConv::ID CC,
EVT VT) const {
// Use f32 to pass f16 if it is legal and Zfh is not enabled. We might still
// end up using a GPR but that will be decided based on ABI.
if (VT == MVT::f16 && Subtarget.hasStdExtF() && !Subtarget.hasStdExtZfh())
// Use f32 to pass f16 if it is legal and Zfhmin/Zfh is not enabled.
// We might still end up using a GPR but that will be decided based on ABI.
if (VT == MVT::f16 && Subtarget.hasStdExtF() && !Subtarget.hasStdExtZfhmin())
return MVT::f32;

return TargetLowering::getRegisterTypeForCallingConv(Context, CC, VT);
Expand All @@ -1197,9 +1197,9 @@ MVT RISCVTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,
unsigned RISCVTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,
CallingConv::ID CC,
EVT VT) const {
// Use f32 to pass f16 if it is legal and Zfh is not enabled. We might still
// end up using a GPR but that will be decided based on ABI.
if (VT == MVT::f16 && Subtarget.hasStdExtF() && !Subtarget.hasStdExtZfh())
// Use f32 to pass f16 if it is legal and Zfhmin/Zfh is not enabled.
// We might still end up using a GPR but that will be decided based on ABI.
if (VT == MVT::f16 && Subtarget.hasStdExtF() && !Subtarget.hasStdExtZfhmin())
return 1;

return TargetLowering::getNumRegistersForCallingConv(Context, CC, VT);
Expand Down
28 changes: 20 additions & 8 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
Expand Up @@ -66,7 +66,7 @@ class FPCmpH_rr<bits<3> funct3, string opcodestr>
// Instructions
//===----------------------------------------------------------------------===//

let Predicates = [HasStdExtZfh] in {
let Predicates = [HasStdExtZfhmin] in {
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
def FLH : RVInstI<0b001, OPC_LOAD_FP, (outs FPR16:$rd),
(ins GPR:$rs1, simm12:$imm12),
Expand All @@ -81,7 +81,9 @@ def FSH : RVInstS<0b001, OPC_STORE_FP, (outs),
(ins FPR16:$rs2, GPR:$rs1, simm12:$imm12),
"fsh", "$rs2, ${imm12}(${rs1})">,
Sched<[WriteFST16, ReadStoreData, ReadFMemBase]>;
} // Predicates = [HasStdExtZfhmin]

let Predicates = [HasStdExtZfh] in {
def FMADD_H : FPFMAH_rrr_frm<OPC_MADD, "fmadd.h">,
Sched<[WriteFMA16, ReadFMA16, ReadFMA16, ReadFMA16]>;
def : FPFMAHDynFrmAlias<FMADD_H, "fmadd.h">;
Expand Down Expand Up @@ -148,7 +150,9 @@ def FCVT_H_WU : FPUnaryOp_r_frm<0b1101010, FPR16, GPR, "fcvt.h.wu">,
let rs2 = 0b00001;
}
def : FPUnaryOpDynFrmAlias<FCVT_H_WU, "fcvt.h.wu", FPR16, GPR>;
} // Predicates = [HasStdExtZfh]

let Predicates = [HasStdExtZfhmin] in {
def FCVT_H_S : FPUnaryOp_r_frm<0b0100010, FPR16, FPR32, "fcvt.h.s">,
Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]> {
let rs2 = 0b00000;
Expand All @@ -169,7 +173,9 @@ def FMV_H_X : FPUnaryOp_r<0b1111010, 0b000, FPR16, GPR, "fmv.h.x">,
Sched<[WriteFMovI16ToF16, ReadFMovI16ToF16]> {
let rs2 = 0b00000;
}
} // Predicates = [HasStdExtZfhmin]

let Predicates = [HasStdExtZfh] in {
def FEQ_H : FPCmpH_rr<0b010, "feq.h">;
def FLT_H : FPCmpH_rr<0b001, "flt.h">;
def FLE_H : FPCmpH_rr<0b000, "fle.h">;
Expand Down Expand Up @@ -206,7 +212,7 @@ def FCVT_H_LU : FPUnaryOp_r_frm<0b1101010, FPR16, GPR, "fcvt.h.lu">,
def : FPUnaryOpDynFrmAlias<FCVT_H_LU, "fcvt.h.lu", FPR16, GPR>;
} // Predicates = [HasStdExtZfh, IsRV64]

let Predicates = [HasStdExtZfh, HasStdExtD] in {
let Predicates = [HasStdExtZfhmin, HasStdExtD] in {
def FCVT_H_D : FPUnaryOp_r_frm<0b0100010, FPR16, FPR64, "fcvt.h.d">,
Sched<[WriteFCvtF64ToF16, ReadFCvtF64ToF16]> {
let rs2 = 0b00001;
Expand All @@ -217,16 +223,18 @@ def FCVT_D_H : FPUnaryOp_r<0b0100001, 0b000, FPR64, FPR16, "fcvt.d.h">,
Sched<[WriteFCvtF16ToF64, ReadFCvtF16ToF64]> {
let rs2 = 0b00010;
}
} // Predicates = [HasStdExtZfh, HasStdExtD]
} // Predicates = [HasStdExtZfhmin, HasStdExtD]

//===----------------------------------------------------------------------===//
// Assembler Pseudo Instructions (User-Level ISA, Version 2.2, Chapter 20)
//===----------------------------------------------------------------------===//

let Predicates = [HasStdExtZfh] in {
let Predicates = [HasStdExtZfhmin] in {
def : InstAlias<"flh $rd, (${rs1})", (FLH FPR16:$rd, GPR:$rs1, 0), 0>;
def : InstAlias<"fsh $rs2, (${rs1})", (FSH FPR16:$rs2, GPR:$rs1, 0), 0>;
} // Predicates = [HasStdExtZfhmin]

let Predicates = [HasStdExtZfh] in {
def : InstAlias<"fmv.h $rd, $rs", (FSGNJ_H FPR16:$rd, FPR16:$rs, FPR16:$rs)>;
def : InstAlias<"fabs.h $rd, $rs", (FSGNJX_H FPR16:$rd, FPR16:$rs, FPR16:$rs)>;
def : InstAlias<"fneg.h $rd, $rs", (FSGNJN_H FPR16:$rd, FPR16:$rs, FPR16:$rs)>;
Expand All @@ -237,10 +245,12 @@ def : InstAlias<"fgt.h $rd, $rs, $rt",
(FLT_H GPR:$rd, FPR16:$rt, FPR16:$rs), 0>;
def : InstAlias<"fge.h $rd, $rs, $rt",
(FLE_H GPR:$rd, FPR16:$rt, FPR16:$rs), 0>;
} // Predicates = [HasStdExtZfh]

let Predicates = [HasStdExtZfhmin] in {
def PseudoFLH : PseudoFloatLoad<"flh", FPR16>;
def PseudoFSH : PseudoStore<"fsh", FPR16>;
} // Predicates = [HasStdExtZfh]
} // Predicates = [HasStdExtZfhmin]

//===----------------------------------------------------------------------===//
// Pseudo-instructions and codegen patterns
Expand Down Expand Up @@ -313,7 +323,9 @@ def : PatFpr16Fpr16<setle, FLE_H>;
def : PatFpr16Fpr16<setole, FLE_H>;

def Select_FPR16_Using_CC_GPR : SelectCC_rrirr<FPR16, GPR>;
} // Predicates = [HasStdExtZfh]

let Predicates = [HasStdExtZfhmin] in {
/// Loads

defm : LdPat<load, FLH, f16>;
Expand All @@ -331,7 +343,7 @@ def : Pat<(fpextend FPR16:$rs1), (FCVT_S_H FPR16:$rs1)>;
// Moves (no conversion)
def : Pat<(riscv_fmv_h_x GPR:$src), (FMV_H_X GPR:$src)>;
def : Pat<(riscv_fmv_x_anyexth FPR16:$src), (FMV_X_H FPR16:$src)>;
} // Predicates = [HasStdExtZfh]
} // Predicates = [HasStdExtZfhmin]

let Predicates = [HasStdExtZfh, IsRV32] in {
// half->[u]int. Round-to-zero must be used.
Expand Down Expand Up @@ -383,7 +395,7 @@ def : Pat<(sint_to_fp (i64 GPR:$rs1)), (FCVT_H_L $rs1, 0b111)>;
def : Pat<(uint_to_fp (i64 GPR:$rs1)), (FCVT_H_LU $rs1, 0b111)>;
} // Predicates = [HasStdExtZfh, IsRV64]

let Predicates = [HasStdExtZfh, HasStdExtD] in {
let Predicates = [HasStdExtZfhmin, HasStdExtD] in {
/// Float conversion operations
// f64 -> f16, f16 -> f64
def : Pat<(fpround FPR64:$rs1), (FCVT_H_D FPR64:$rs1, 0b111)>;
Expand All @@ -393,4 +405,4 @@ def : Pat<(fpextend FPR16:$rs1), (FCVT_D_H FPR16:$rs1)>;
def : Pat<(fcopysign FPR16:$rs1, FPR64:$rs2),
(FSGNJ_H $rs1, (FCVT_H_D $rs2, 0b111))>;
def : Pat<(fcopysign FPR64:$rs1, FPR16:$rs2), (FSGNJ_D $rs1, (FCVT_D_H $rs2))>;
}
} // Predicates = [HasStdExtZfhmin, HasStdExtD]
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/RISCVSubtarget.h
Expand Up @@ -52,6 +52,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
bool HasStdExtV = false;
bool HasStdExtZvlsseg = false;
bool HasStdExtZvamo = false;
bool HasStdExtZfhmin = false;
bool HasStdExtZfh = false;
bool HasRV64 = false;
bool IsRV32E = false;
Expand Down Expand Up @@ -118,6 +119,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
bool hasStdExtV() const { return HasStdExtV; }
bool hasStdExtZvlsseg() const { return HasStdExtZvlsseg; }
bool hasStdExtZvamo() const { return HasStdExtZvamo; }
bool hasStdExtZfhmin() const { return HasStdExtZfhmin; }
bool hasStdExtZfh() const { return HasStdExtZfh; }
bool is64Bit() const { return HasRV64; }
bool isRV32E() const { return IsRV32E; }
Expand Down
12 changes: 8 additions & 4 deletions llvm/test/CodeGen/RISCV/attributes.ll
Expand Up @@ -6,6 +6,7 @@
; 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-v,+experimental-zvamo,+experimental-zvlsseg %s -o - | FileCheck --check-prefix=RV32V %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfhmin %s -o - | FileCheck --check-prefix=RV32ZFHMIN %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfh %s -o - | FileCheck --check-prefix=RV32ZFH %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zba %s -o - | FileCheck --check-prefix=RV32ZBA %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zbb %s -o - | FileCheck --check-prefix=RV32ZBB %s
Expand All @@ -24,6 +25,7 @@
; 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-v,+experimental-zvamo,+experimental-zvlsseg %s -o - | FileCheck --check-prefix=RV64V %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zfhmin %s -o - | FileCheck --check-prefix=RV64ZFHMIN %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zfh %s -o - | FileCheck --check-prefix=RV64ZFH %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zba %s -o - | FileCheck --check-prefix=RV64ZBA %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zbb %s -o - | FileCheck --check-prefix=RV64ZBB %s
Expand All @@ -43,7 +45,8 @@
; RV32D: .attribute 5, "rv32i2p0_f2p0_d2p0"
; RV32C: .attribute 5, "rv32i2p0_c2p0"
; RV32V: .attribute 5, "rv32i2p0_v0p10_zvamo0p10_zvlsseg0p10"
; RV32ZFH: .attribute 5, "rv32i2p0_f2p0_zfh0p1"
; RV32ZFHMIN: .attribute 5, "rv32i2p0_f2p0_zfhmin0p1"
; RV32ZFH: .attribute 5, "rv32i2p0_f2p0_zfh0p1_zfhmin0p1"
; RV32ZBA: .attribute 5, "rv32i2p0_zba1p0"
; RV32ZBB: .attribute 5, "rv32i2p0_zbb1p0"
; RV32ZBC: .attribute 5, "rv32i2p0_zbc1p0"
Expand All @@ -54,14 +57,15 @@
; RV32ZBR: .attribute 5, "rv32i2p0_zbr0p93"
; RV32ZBS: .attribute 5, "rv32i2p0_zbs1p0"
; RV32ZBT: .attribute 5, "rv32i2p0_zbt0p93"
; RV32COMBINED: .attribute 5, "rv32i2p0_f2p0_v0p10_zfh0p1_zbb1p0_zvamo0p10_zvlsseg0p10"
; RV32COMBINED: .attribute 5, "rv32i2p0_f2p0_v0p10_zfh0p1_zfhmin0p1_zbb1p0_zvamo0p10_zvlsseg0p10"

; 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"
; RV64ZFHMIN: .attribute 5, "rv64i2p0_f2p0_zfhmin0p1"
; RV64ZFH: .attribute 5, "rv64i2p0_f2p0_zfh0p1_zfhmin0p1"
; RV64ZBA: .attribute 5, "rv64i2p0_zba1p0"
; RV64ZBB: .attribute 5, "rv64i2p0_zbb1p0"
; RV64ZBC: .attribute 5, "rv64i2p0_zbc1p0"
Expand All @@ -73,7 +77,7 @@
; RV64ZBS: .attribute 5, "rv64i2p0_zbs1p0"
; RV64ZBT: .attribute 5, "rv64i2p0_zbt0p93"
; RV64V: .attribute 5, "rv64i2p0_v0p10_zvamo0p10_zvlsseg0p10"
; RV64COMBINED: .attribute 5, "rv64i2p0_f2p0_v0p10_zfh0p1_zbb1p0_zvamo0p10_zvlsseg0p10"
; RV64COMBINED: .attribute 5, "rv64i2p0_f2p0_v0p10_zfh0p1_zfhmin0p1_zbb1p0_zvamo0p10_zvlsseg0p10"


define i32 @addi(i32 %a) {
Expand Down
5 changes: 4 additions & 1 deletion llvm/test/MC/RISCV/attribute-arch.s
Expand Up @@ -66,8 +66,11 @@
.attribute arch, "rv32izbt"
# CHECK: attribute 5, "rv32i2p0_zbt0p93"

.attribute arch, "rv32ifzfhmin"
# CHECK: attribute 5, "rv32i2p0_f2p0_zfhmin0p1"

.attribute arch, "rv32ifzfh"
# CHECK: attribute 5, "rv32i2p0_f2p0_zfh0p1"
# CHECK: attribute 5, "rv32i2p0_f2p0_zfh0p1_zfhmin0p1"

.attribute arch, "rv32ivzvamo_zvlsseg"
# CHECK: attribute 5, "rv32i2p0_v0p10_zvamo0p10_zvlsseg0p10"
Expand Down
23 changes: 23 additions & 0 deletions llvm/test/MC/RISCV/rv32zfhmin-invalid.s
@@ -0,0 +1,23 @@
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zfhmin < %s 2>&1 | \
# RUN: FileCheck %s

# Out of range immediates
## simm12
flh ft1, -2049(a0) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]
fsh ft2, 2048(a1) # CHECK: :[[@LINE]]:10: error: operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an integer in the range [-2048, 2047]

# Memory operand not formatted correctly
flh ft1, a0, -200 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction

# Invalid register names
flh ft15, 100(a0) # CHECK: :[[@LINE]]:5: error: invalid operand for instruction
flh ft1, 100(a10) # CHECK: :[[@LINE]]:14: error: expected register

# Integer registers where FP regs are expected
fmv.x.h fs7, a2 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction

# FP registers where integer regs are expected
fmv.h.x a8, ft2 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction

# Zfh instructions
fmadd.h f10, f11, f12, f13, dyn # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zfh' (Half-Precision Floating-Point)
62 changes: 62 additions & 0 deletions llvm/test/MC/RISCV/rv32zfhmin-valid.s
@@ -0,0 +1,62 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zfhmin,+d -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zfhmin,+d -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-zfhmin,+d < %s \
# RUN: | llvm-objdump --mattr=+experimental-zfhmin,+d -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zfhmin,+d < %s \
# RUN: | llvm-objdump --mattr=+experimental-zfhmin,+d -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s

# CHECK-ASM-AND-OBJ: flh ft0, 12(a0)
# CHECK-ASM: encoding: [0x07,0x10,0xc5,0x00]
flh f0, 12(a0)
# CHECK-ASM-AND-OBJ: flh ft1, 4(ra)
# CHECK-ASM: encoding: [0x87,0x90,0x40,0x00]
flh f1, +4(ra)
# CHECK-ASM-AND-OBJ: flh ft2, -2048(a3)
# CHECK-ASM: encoding: [0x07,0x91,0x06,0x80]
flh f2, -2048(x13)
# CHECK-ASM-AND-OBJ: flh ft3, -2048(s1)
# CHECK-ASM: encoding: [0x87,0x91,0x04,0x80]
flh f3, %lo(2048)(s1)
# CHECK-ASM-AND-OBJ: flh ft4, 2047(s2)
# CHECK-ASM: encoding: [0x07,0x12,0xf9,0x7f]
flh f4, 2047(s2)
# CHECK-ASM-AND-OBJ: flh ft5, 0(s3)
# CHECK-ASM: encoding: [0x87,0x92,0x09,0x00]
flh f5, 0(s3)

# CHECK-ASM-AND-OBJ: fsh ft6, 2047(s4)
# CHECK-ASM: encoding: [0xa7,0x1f,0x6a,0x7e]
fsh f6, 2047(s4)
# CHECK-ASM-AND-OBJ: fsh ft7, -2048(s5)
# CHECK-ASM: encoding: [0x27,0x90,0x7a,0x80]
fsh f7, -2048(s5)
# CHECK-ASM-AND-OBJ: fsh fs0, -2048(s6)
# CHECK-ASM: encoding: [0x27,0x10,0x8b,0x80]
fsh f8, %lo(2048)(s6)
# CHECK-ASM-AND-OBJ: fsh fs1, 999(s7)
# CHECK-ASM: encoding: [0xa7,0x93,0x9b,0x3e]
fsh f9, 999(s7)

# CHECK-ASM-AND-OBJ: fmv.x.h a2, fs7
# CHECK-ASM: encoding: [0x53,0x86,0x0b,0xe4]
fmv.x.h a2, fs7
# CHECK-ASM-AND-OBJ: fmv.h.x ft1, a6
# CHECK-ASM: encoding: [0xd3,0x00,0x08,0xf4]
fmv.h.x ft1, a6

# CHECK-ASM-AND-OBJ: fcvt.s.h fa0, ft0
# CHECK-ASM: encoding: [0x53,0x05,0x20,0x40]
fcvt.s.h fa0, ft0
# CHECK-ASM-AND-OBJ: fcvt.h.s ft2, fa2
# CHECK-ASM: encoding: [0x53,0x71,0x06,0x44]
fcvt.h.s ft2, fa2
# CHECK-ASM-AND-OBJ: fcvt.d.h fa0, ft0
# CHECK-ASM: encoding: [0x53,0x05,0x20,0x42]
fcvt.d.h fa0, ft0
# CHECK-ASM-AND-OBJ: fcvt.h.d ft2, fa2
# CHECK-ASM: encoding: [0x53,0x71,0x16,0x44]
fcvt.h.d ft2, fa2

0 comments on commit 5c3d718

Please sign in to comment.