diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -189,6 +189,9 @@ ``XTHeadCmo`` LLVM implements `the THeadCmo (cache management operations) vendor-defined instructions specified in `_ by T-HEAD of Alibaba. Instructions are prefixed with `th.` as described in the specification. +``XTHeadFMemIdx`` + LLVM implements `the THeadFMemIdx (indexed memory operations for floating point) vendor-defined instructions specified in `_ by T-HEAD of Alibaba. Instructions are prefixed with `th.` as described in the specification. + ``XTheadMac`` LLVM implements `the XTheadMac (multiply-accumulate instructions) vendor-defined instructions specified in `_ by T-HEAD of Alibaba. Instructions are prefixed with `th.` as described in the specification. diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -119,6 +119,7 @@ * Support for the now-ratified Zawrs extension is no longer experimental. * Adds support for the vendor-defined XTHeadCmo (cache management operations) extension. * Adds support for the vendor-defined XTHeadSync (multi-core synchronization instructions) extension. +* Added support for the vendor-defined XTHeadFMemIdx (indexed memory operations for floating point) extension. Changes to the WebAssembly Backend ---------------------------------- diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -117,6 +117,7 @@ {"xtheadbb", RISCVExtensionVersion{1, 0}}, {"xtheadbs", RISCVExtensionVersion{1, 0}}, {"xtheadcmo", RISCVExtensionVersion{1, 0}}, + {"xtheadfmemidx", RISCVExtensionVersion{1, 0}}, {"xtheadmac", RISCVExtensionVersion{1, 0}}, {"xtheadmemidx", RISCVExtensionVersion{1, 0}}, {"xtheadmempair", RISCVExtensionVersion{1, 0}}, diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -527,6 +527,13 @@ if (Result != MCDisassembler::Fail) return Result; } + if (STI.hasFeature(RISCV::FeatureVendorXTHeadFMemIdx)) { + LLVM_DEBUG(dbgs() << "Trying XTHeadFMemIdx custom opcode table:\n"); + Result = decodeInstruction(DecoderTableTHeadFMemIdx32, MI, Insn, Address, + this, STI); + if (Result != MCDisassembler::Fail) + return Result; + } if (STI.hasFeature(RISCV::FeatureVendorXTHeadMac)) { LLVM_DEBUG(dbgs() << "Trying XTHeadMac custom opcode table:\n"); Result = decodeInstruction(DecoderTableTHeadMac32, MI, Insn, Address, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -512,6 +512,14 @@ AssemblerPredicate<(all_of FeatureVendorXTHeadCmo), "'xtheadcmo' (T-Head cache management instructions)">; +def FeatureVendorXTHeadFMemIdx + : SubtargetFeature<"xtheadfmemidx", "HasVendorXTHeadFMemIdx", "true", + "'xtheadfmemidx' (T-Head FP Indexed Memory Operations)", + [FeatureStdExtF]>; +def HasVendorXTHeadFMemIdx : Predicate<"Subtarget->hasVendorXTHeadFMemIdx()">, + AssemblerPredicate<(all_of FeatureVendorXTHeadFMemIdx), + "'xtheadfmemidx' (T-Head FP Indexed Memory Operations)">; + def FeatureVendorXTHeadMac : SubtargetFeature<"xtheadmac", "HasVendorXTHeadMac", "true", "'xtheadmac' (T-Head Multiply-Accumulate Instructions)">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td @@ -164,8 +164,7 @@ let rs2 = funct5; } -let Predicates = [HasVendorXTHeadMemIdx], DecoderNamespace = "THeadMemIdx", - hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { +let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { class THLoadIndexed funct5, string opcodestr> : RVInstR funct5, string opcodestr> : RVInstR; } -let Predicates = [HasVendorXTHeadMemIdx] in { +let Predicates = [HasVendorXTHeadMemIdx], DecoderNamespace = "THeadMemIdx" in { // T-Head Load/Store + Update instructions. def TH_LBIA : THLoadUpdate<0b00011, "th.lbia">, Sched<[WriteLDB, ReadMemBase]>; @@ -364,7 +362,7 @@ Sched<[WriteLDB, ReadMemBase]>; } -let Predicates = [HasVendorXTHeadMemIdx, IsRV64] in { +let Predicates = [HasVendorXTHeadMemIdx, IsRV64], DecoderNamespace = "THeadMemIdx" in { // T-Head Load/Store + Update instructions. def TH_LWUIA : THLoadUpdate<0b11011, "th.lwuia">, Sched<[WriteLDH, ReadMemBase]>; @@ -398,6 +396,40 @@ Sched<[WriteLDB, ReadMemBase]>; } +// T-Head Load/Store Indexed instructions for floating point registers. + +let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF], + DecoderNamespace = "THeadFMemIdx" in { +def TH_FLRW : THLoadIndexed, + Sched<[WriteFLD32, ReadFMemBase]>; +def TH_FSRW : THStoreIndexed, + Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]>; +} + +let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD], + DecoderNamespace = "THeadFMemIdx" in { +def TH_FLRD : THLoadIndexed, + Sched<[WriteFLD64, ReadFMemBase]>; +def TH_FSRD : THStoreIndexed, + Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]>; +} + +let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV64], + DecoderNamespace = "THeadFMemIdx" in { +def TH_FLURW : THLoadIndexed, + Sched<[WriteFLD32, ReadFMemBase]>; +def TH_FSURW : THStoreIndexed, + Sched<[WriteFST32, ReadFStoreData, ReadFMemBase]>; +} + +let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV64], + DecoderNamespace = "THeadFMemIdx" in { +def TH_FLURD : THLoadIndexed, + Sched<[WriteFLD64, ReadFMemBase]>; +def TH_FSURD : THStoreIndexed, + Sched<[WriteFST64, ReadFStoreData, ReadFMemBase]>; +} + let Predicates = [HasVendorXTHeadVdot], Constraints = "@earlyclobber $vd", RVVConstraint = WidenV in { @@ -774,6 +806,30 @@ defm : StZextIdxPat; } +let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV32] in { +defm : LdIdxPat; +defm : StIdxPat; +} + +let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV32] in { +defm : LdIdxPat; +defm : StIdxPat; +} + +let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtF, IsRV64] in { +defm : LdIdxPat; +defm : LdZextIdxPat; +defm : StIdxPat; +defm : StZextIdxPat; +} + +let Predicates = [HasVendorXTHeadFMemIdx, HasStdExtD, IsRV64] in { +defm : LdIdxPat; +defm : LdZextIdxPat; +defm : StIdxPat; +defm : StZextIdxPat; +} + def simm5shl2 : ComplexPattern; multiclass StoreUpdatePat { 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 @@ -42,6 +42,7 @@ ; RUN: llc -mtriple=riscv32 -mattr=+svpbmt %s -o - | FileCheck --check-prefixes=CHECK,RV32SVPBMT %s ; RUN: llc -mtriple=riscv32 -mattr=+svinval %s -o - | FileCheck --check-prefixes=CHECK,RV32SVINVAL %s ; RUN: llc -mtriple=riscv32 -mattr=+xtheadcmo %s -o - | FileCheck --check-prefix=RV32XTHEADCMO %s +; RUN: llc -mtriple=riscv32 -mattr=+xtheadfmemidx %s -o - | FileCheck --check-prefix=RV32XTHEADFMEMIDX %s ; RUN: llc -mtriple=riscv32 -mattr=+xtheadmac %s -o - | FileCheck --check-prefixes=CHECK,RV32XTHEADMAC %s ; RUN: llc -mtriple=riscv32 -mattr=+xtheadmemidx %s -o - | FileCheck --check-prefix=RV32XTHEADMEMIDX %s ; RUN: llc -mtriple=riscv32 -mattr=+xtheadmempair %s -o - | FileCheck --check-prefix=RV32XTHEADMEMPAIR %s @@ -100,6 +101,7 @@ ; RUN: llc -mtriple=riscv64 -mattr=+xtheadbb %s -o - | FileCheck --check-prefixes=CHECK,RV64XTHEADBB %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadbs %s -o - | FileCheck --check-prefixes=CHECK,RV64XTHEADBS %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadcmo %s -o - | FileCheck --check-prefix=RV64XTHEADCMO %s +; RUN: llc -mtriple=riscv64 -mattr=+xtheadfmemidx %s -o - | FileCheck --check-prefix=RV64XTHEADFMEMIDX %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadmac %s -o - | FileCheck --check-prefixes=CHECK,RV64XTHEADMAC %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadmemidx %s -o - | FileCheck --check-prefix=RV64XTHEADMEMIDX %s ; RUN: llc -mtriple=riscv64 -mattr=+xtheadmempair %s -o - | FileCheck --check-prefix=RV64XTHEADMEMPAIR %s @@ -157,6 +159,7 @@ ; RV32SVPBMT: .attribute 5, "rv32i2p0_svpbmt1p0" ; RV32SVINVAL: .attribute 5, "rv32i2p0_svinval1p0" ; RV32XTHEADCMO: .attribute 5, "rv32i2p0_xtheadcmo1p0" +; RV32XTHEADFMEMIDX: .attribute 5, "rv32i2p0_f2p0_xtheadfmemidx1p0" ; RV32XTHEADMAC: .attribute 5, "rv32i2p0_xtheadmac1p0" ; RV32XTHEADMEMIDX: .attribute 5, "rv32i2p0_xtheadmemidx1p0" ; RV32XTHEADMEMPAIR: .attribute 5, "rv32i2p0_xtheadmempair1p0" @@ -215,6 +218,7 @@ ; RV64XTHEADBB: .attribute 5, "rv64i2p0_xtheadbb1p0" ; RV64XTHEADBS: .attribute 5, "rv64i2p0_xtheadbs1p0" ; RV64XTHEADCMO: .attribute 5, "rv64i2p0_xtheadcmo1p0" +; RV64XTHEADFMEMIDX: .attribute 5, "rv64i2p0_f2p0_xtheadfmemidx1p0" ; RV64XTHEADMAC: .attribute 5, "rv64i2p0_xtheadmac1p0" ; RV64XTHEADMEMIDX: .attribute 5, "rv64i2p0_xtheadmemidx1p0" ; RV64XTHEADMEMPAIR: .attribute 5, "rv64i2p0_xtheadmempair1p0" diff --git a/llvm/test/CodeGen/RISCV/xtheadfmemidx.ll b/llvm/test/CodeGen/RISCV/xtheadfmemidx.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/xtheadfmemidx.ll @@ -0,0 +1,153 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+d -mattr=+xtheadfmemidx -mattr=+m -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV32XTHEADMEMIDX +; RUN: llc -mtriple=riscv64 -mattr=+d -mattr=+xtheadfmemidx -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV64XTHEADFMEMIDX + +define float @flrw(float* %a, i64 %b) { +; RV32XTHEADMEMIDX-LABEL: flrw: +; RV32XTHEADMEMIDX: # %bb.0: +; RV32XTHEADMEMIDX-NEXT: th.flrw ft0, a0, a1, 2 +; RV32XTHEADMEMIDX-NEXT: fadd.s fa0, ft0, ft0 +; RV32XTHEADMEMIDX-NEXT: ret +; +; RV64XTHEADFMEMIDX-LABEL: flrw: +; RV64XTHEADFMEMIDX: # %bb.0: +; RV64XTHEADFMEMIDX-NEXT: th.flrw ft0, a0, a1, 2 +; RV64XTHEADFMEMIDX-NEXT: fadd.s fa0, ft0, ft0 +; RV64XTHEADFMEMIDX-NEXT: ret + %1 = getelementptr float, float* %a, i64 %b + %2 = load float, float* %1, align 4 + %3 = fadd float %2, %2 + ret float %3 +} + +define float @flurw(float* %a, i32 %b) { +; RV32XTHEADMEMIDX-LABEL: flurw: +; RV32XTHEADMEMIDX: # %bb.0: +; RV32XTHEADMEMIDX-NEXT: th.flrw ft0, a0, a1, 2 +; RV32XTHEADMEMIDX-NEXT: fadd.s fa0, ft0, ft0 +; RV32XTHEADMEMIDX-NEXT: ret +; +; RV64XTHEADFMEMIDX-LABEL: flurw: +; RV64XTHEADFMEMIDX: # %bb.0: +; RV64XTHEADFMEMIDX-NEXT: th.flurw ft0, a0, a1, 2 +; RV64XTHEADFMEMIDX-NEXT: fadd.s fa0, ft0, ft0 +; RV64XTHEADFMEMIDX-NEXT: ret + %1 = zext i32 %b to i64 + %2 = getelementptr float, float* %a, i64 %1 + %3 = load float, float* %2, align 4 + %4 = fadd float %3, %3 + ret float %4 +} + +define void @fsrw(float* %a, i64 %b, float %c) { +; RV32XTHEADMEMIDX-LABEL: fsrw: +; RV32XTHEADMEMIDX: # %bb.0: +; RV32XTHEADMEMIDX-NEXT: fadd.s ft0, fa0, fa0 +; RV32XTHEADMEMIDX-NEXT: th.fsrw ft0, a0, a1, 2 +; RV32XTHEADMEMIDX-NEXT: ret +; +; RV64XTHEADFMEMIDX-LABEL: fsrw: +; RV64XTHEADFMEMIDX: # %bb.0: +; RV64XTHEADFMEMIDX-NEXT: fadd.s ft0, fa0, fa0 +; RV64XTHEADFMEMIDX-NEXT: th.fsrw ft0, a0, a1, 2 +; RV64XTHEADFMEMIDX-NEXT: ret + %1 = fadd float %c, %c + %2 = getelementptr float, float* %a, i64 %b + store float %1, float* %2, align 4 + ret void +} + +define void @fsurw(float* %a, i32 %b, float %c) { +; RV32XTHEADMEMIDX-LABEL: fsurw: +; RV32XTHEADMEMIDX: # %bb.0: +; RV32XTHEADMEMIDX-NEXT: fadd.s ft0, fa0, fa0 +; RV32XTHEADMEMIDX-NEXT: th.fsrw ft0, a0, a1, 2 +; RV32XTHEADMEMIDX-NEXT: ret +; +; RV64XTHEADFMEMIDX-LABEL: fsurw: +; RV64XTHEADFMEMIDX: # %bb.0: +; RV64XTHEADFMEMIDX-NEXT: fadd.s ft0, fa0, fa0 +; RV64XTHEADFMEMIDX-NEXT: th.fsurw ft0, a0, a1, 2 +; RV64XTHEADFMEMIDX-NEXT: ret + %1 = zext i32 %b to i64 + %2 = fadd float %c, %c + %3 = getelementptr float, float* %a, i64 %1 + store float %2, float* %3, align 4 + ret void +} + +define double @flrd(double* %a, i64 %b) { +; RV32XTHEADMEMIDX-LABEL: flrd: +; RV32XTHEADMEMIDX: # %bb.0: +; RV32XTHEADMEMIDX-NEXT: th.flrd ft0, a0, a1, 3 +; RV32XTHEADMEMIDX-NEXT: fadd.d fa0, ft0, ft0 +; RV32XTHEADMEMIDX-NEXT: ret +; +; RV64XTHEADFMEMIDX-LABEL: flrd: +; RV64XTHEADFMEMIDX: # %bb.0: +; RV64XTHEADFMEMIDX-NEXT: th.flrd ft0, a0, a1, 3 +; RV64XTHEADFMEMIDX-NEXT: fadd.d fa0, ft0, ft0 +; RV64XTHEADFMEMIDX-NEXT: ret + %1 = getelementptr double, double* %a, i64 %b + %2 = load double, double* %1, align 8 + %3 = fadd double %2, %2 + ret double %3 +} + +define double @flurd(double* %a, i32 %b) { +; RV32XTHEADMEMIDX-LABEL: flurd: +; RV32XTHEADMEMIDX: # %bb.0: +; RV32XTHEADMEMIDX-NEXT: th.flrd ft0, a0, a1, 3 +; RV32XTHEADMEMIDX-NEXT: fadd.d fa0, ft0, ft0 +; RV32XTHEADMEMIDX-NEXT: ret +; +; RV64XTHEADFMEMIDX-LABEL: flurd: +; RV64XTHEADFMEMIDX: # %bb.0: +; RV64XTHEADFMEMIDX-NEXT: th.flurd ft0, a0, a1, 3 +; RV64XTHEADFMEMIDX-NEXT: fadd.d fa0, ft0, ft0 +; RV64XTHEADFMEMIDX-NEXT: ret + %1 = zext i32 %b to i64 + %2 = getelementptr double, double* %a, i64 %1 + %3 = load double, double* %2, align 8 + %4 = fadd double %3, %3 + ret double %4 +} + +define void @fsrd(double* %a, i64 %b, double %c) { +; RV32XTHEADMEMIDX-LABEL: fsrd: +; RV32XTHEADMEMIDX: # %bb.0: +; RV32XTHEADMEMIDX-NEXT: fadd.d ft0, fa0, fa0 +; RV32XTHEADMEMIDX-NEXT: th.fsrd ft0, a0, a1, 3 +; RV32XTHEADMEMIDX-NEXT: ret +; +; RV64XTHEADFMEMIDX-LABEL: fsrd: +; RV64XTHEADFMEMIDX: # %bb.0: +; RV64XTHEADFMEMIDX-NEXT: fadd.d ft0, fa0, fa0 +; RV64XTHEADFMEMIDX-NEXT: th.fsrd ft0, a0, a1, 3 +; RV64XTHEADFMEMIDX-NEXT: ret + %1 = fadd double %c, %c + %2 = getelementptr double, double* %a, i64 %b + store double %1, double* %2, align 8 + ret void +} + +define void @fsurd(double* %a, i32 %b, double %c) { +; RV32XTHEADMEMIDX-LABEL: fsurd: +; RV32XTHEADMEMIDX: # %bb.0: +; RV32XTHEADMEMIDX-NEXT: fadd.d ft0, fa0, fa0 +; RV32XTHEADMEMIDX-NEXT: th.fsrd ft0, a0, a1, 3 +; RV32XTHEADMEMIDX-NEXT: ret +; +; RV64XTHEADFMEMIDX-LABEL: fsurd: +; RV64XTHEADFMEMIDX: # %bb.0: +; RV64XTHEADFMEMIDX-NEXT: fadd.d ft0, fa0, fa0 +; RV64XTHEADFMEMIDX-NEXT: th.fsurd ft0, a0, a1, 3 +; RV64XTHEADFMEMIDX-NEXT: ret + %1 = zext i32 %b to i64 + %2 = fadd double %c, %c + %3 = getelementptr double, double* %a, i64 %1 + store double %2, double* %3, align 8 + ret void +} diff --git a/llvm/test/MC/RISCV/rv32xtheadfmemidx-d-invalid.s b/llvm/test/MC/RISCV/rv32xtheadfmemidx-d-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32xtheadfmemidx-d-invalid.s @@ -0,0 +1,6 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+d -mattr=+xtheadfmemidx < %s 2>&1 | FileCheck %s + +th.flurd fa0, a1, a2, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set{{$}} +th.flurw fa0, a1, a2, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set{{$}} +th.fsurd fa0, a1, a2, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set{{$}} +th.fsurw fa0, a1, a2, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set{{$}} diff --git a/llvm/test/MC/RISCV/rv32xtheadfmemidx-f-invalid.s b/llvm/test/MC/RISCV/rv32xtheadfmemidx-f-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32xtheadfmemidx-f-invalid.s @@ -0,0 +1,8 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+f -mattr=+xtheadfmemidx < %s 2>&1 | FileCheck %s + +th.flrd fa0, a1, a2, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'D' (Double-Precision Floating-Point){{$}} +th.fsrd fa0, a1, a2, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'D' (Double-Precision Floating-Point){{$}} +th.flurd fa0, a1, a2, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'D' (Double-Precision Floating-Point), RV64I Base Instruction Set{{$}} +th.flurw fa0, a1, a2, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set{{$}} +th.fsurd fa0, a1, a2, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'D' (Double-Precision Floating-Point), RV64I Base Instruction Set{{$}} +th.fsurw fa0, a1, a2, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RV64I Base Instruction Set{{$}} diff --git a/llvm/test/MC/RISCV/rv32xtheadfmemidx-valid.s b/llvm/test/MC/RISCV/rv32xtheadfmemidx-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32xtheadfmemidx-valid.s @@ -0,0 +1,37 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+d -mattr=+xtheadfmemidx -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+d -mattr=+xtheadfmemidx < %s \ +# RUN: | llvm-objdump --mattr=+d --mattr=+xtheadfmemidx -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: th.flrd fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x60] +th.flrd fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.flrd fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x66] +th.flrd fa0, a1, a2, 3 + +# CHECK-ASM-AND-OBJ: th.flrw fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x40] +th.flrw fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.flrw fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x46] +th.flrw fa0, a1, a2, 3 + +# CHECK-ASM-AND-OBJ: th.fsrd fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x60] +th.fsrd fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.fsrd fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x66] +th.fsrd fa0, a1, a2, 3 + +# CHECK-ASM-AND-OBJ: th.fsrw fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x40] +th.fsrw fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.fsrw fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x46] +th.fsrw fa0, a1, a2, 3 diff --git a/llvm/test/MC/RISCV/rv64xtheadfmemidx-invalid.s b/llvm/test/MC/RISCV/rv64xtheadfmemidx-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64xtheadfmemidx-invalid.s @@ -0,0 +1,9 @@ +# RUN: not llvm-mc -triple riscv32 -mattr=+d -mattr=+xtheadfmemidx < %s 2>&1 | FileCheck %s +# RUN: not llvm-mc -triple riscv64 -mattr=+d -mattr=+xtheadfmemidx < %s 2>&1 | FileCheck %s + +th.flrd fa0, a1, a2, 5 # CHECK: :[[@LINE]]:22: error: immediate must be an integer in the range [0, 3] +th.flrd a0, a1, a2, 3 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +th.flrw 0(fa0), a1, a2, 0 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +th.flrw fa0, 4(a1), a2, 3 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction +th.fsrd fa0, a1, -1(a2), 0 # CHECK: :[[@LINE]]:18: error: invalid operand for instruction +th.fsrd fa0, a1, a2, -3 # CHECK: :[[@LINE]]:22: error: immediate must be an integer in the range [0, 3] diff --git a/llvm/test/MC/RISCV/rv64xtheadfmemidx-valid.s b/llvm/test/MC/RISCV/rv64xtheadfmemidx-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64xtheadfmemidx-valid.s @@ -0,0 +1,69 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+d -mattr=+xtheadfmemidx -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+d -mattr=+xtheadfmemidx < %s \ +# RUN: | llvm-objdump --mattr=+d --mattr=+xtheadfmemidx -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: th.flrd fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x60] +th.flrd fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.flrd fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x66] +th.flrd fa0, a1, a2, 3 + +# CHECK-ASM-AND-OBJ: th.flrw fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x40] +th.flrw fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.flrw fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x46] +th.flrw fa0, a1, a2, 3 + +# CHECK-ASM-AND-OBJ: th.flurd fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x70] +th.flurd fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.flurd fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x76] +th.flurd fa0, a1, a2, 3 + +# CHECK-ASM-AND-OBJ: th.flurw fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x50] +th.flurw fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.flurw fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xe5,0xc5,0x56] +th.flurw fa0, a1, a2, 3 + +# CHECK-ASM-AND-OBJ: th.fsrd fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x60] +th.fsrd fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.fsrd fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x66] +th.fsrd fa0, a1, a2, 3 + +# CHECK-ASM-AND-OBJ: th.fsrw fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x40] +th.fsrw fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.fsrw fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x46] +th.fsrw fa0, a1, a2, 3 + +# CHECK-ASM-AND-OBJ: th.fsurd fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x70] +th.fsurd fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.fsurd fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x76] +th.fsurd fa0, a1, a2, 3 + +# CHECK-ASM-AND-OBJ: th.fsurw fa0, a1, a2, 0 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x50] +th.fsurw fa0, a1, a2, 0 + +# CHECK-ASM-AND-OBJ: th.fsurw fa0, a1, a2, 3 +# CHECK-ASM: encoding: [0x0b,0xf5,0xc5,0x56] +th.fsurw fa0, a1, a2, 3