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 @@ -111,6 +111,7 @@ {"zbr", RISCVExtensionVersion{0, 93}}, {"zbt", RISCVExtensionVersion{0, 93}}, {"zvfh", RISCVExtensionVersion{0, 1}}, + {"zca", RISCVExtensionVersion{0, 70}}, }; static bool stripExperimentalPrefix(StringRef &Ext) { diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -340,6 +340,19 @@ FeatureStdExtZkr, FeatureStdExtZkt]>; +def FeatureExtZca + : SubtargetFeature<"experimental-zca", "HasStdExtZca", "true", + "'Zca' (part of the C extension, excluding compressed floating point loads/stores)">; +def HasStdExtZca : Predicate<"Subtarget->hasStdExtZca()">, + AssemblerPredicate<(all_of FeatureExtZca), + "'Zca' (part of the C extension, excluding compressed floating point loads/stores)">; + +def HasStdExtCOrZca + : Predicate<"Subtarget->hasStdExtC() || Subtarget->hasStdExtZca()">, + AssemblerPredicate<(any_of FeatureStdExtC, FeatureExtZca), + "'C' (Compressed Instructions) or " + "'Zca' (part of the C extension, excluding compressed floating point loads/stores)">; + def FeatureNoRVCHints : SubtargetFeature<"no-rvc-hints", "EnableRVCHintInstrs", "false", "Disable RVC Hint Instructions.">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td @@ -281,7 +281,7 @@ // Instructions //===----------------------------------------------------------------------===// -let Predicates = [HasStdExtC] in { +let Predicates = [HasStdExtCOrZca] in { let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Uses = [X2] in def C_ADDI4SPN : RVInst16CIW<0b000, 0b00, (outs GPRC:$rd), @@ -321,7 +321,7 @@ let Inst{5} = imm{6}; } -let Predicates = [HasStdExtC, IsRV64] in +let Predicates = [HasStdExtCOrZca, IsRV64] in def C_LD : CLoad_ri<0b011, "c.ld", GPRC, uimm8_lsb000>, Sched<[WriteLDD, ReadMemBase]> { bits<8> imm; @@ -355,7 +355,7 @@ let Inst{5} = imm{6}; } -let Predicates = [HasStdExtC, IsRV64] in +let Predicates = [HasStdExtCOrZca, IsRV64] in def C_SD : CStore_rri<0b111, "c.sd", GPRC, uimm8_lsb000>, Sched<[WriteSTD, ReadStoreData, ReadMemBase]> { bits<8> imm; @@ -391,12 +391,12 @@ let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCall = 1, DecoderNamespace = "RISCV32Only_", Defs = [X1], - Predicates = [HasStdExtC, IsRV32] in + Predicates = [HasStdExtCOrZca, IsRV32] in def C_JAL : RVInst16CJ<0b001, 0b01, (outs), (ins simm12_lsb0:$offset), "c.jal", "$offset">, Sched<[WriteJal]>; let hasSideEffects = 0, mayLoad = 0, mayStore = 0, - Predicates = [HasStdExtC, IsRV64] in + Predicates = [HasStdExtCOrZca, IsRV64] in def C_ADDIW : RVInst16CI<0b001, 0b01, (outs GPRNoX0:$rd_wb), (ins GPRNoX0:$rd, simm6:$imm), "c.addiw", "$rd, $imm">, @@ -458,7 +458,7 @@ def C_AND : CS_ALU<0b100011, 0b11, "c.and", GPRC>, Sched<[WriteIALU, ReadIALU, ReadIALU]>; -let Predicates = [HasStdExtC, IsRV64] in { +let Predicates = [HasStdExtCOrZca, IsRV64] in { def C_SUBW : CS_ALU<0b100111, 0b00, "c.subw", GPRC>, Sched<[WriteIALU32, ReadIALU32, ReadIALU32]>; def C_ADDW : CS_ALU<0b100111, 0b01, "c.addw", GPRC>, @@ -506,7 +506,7 @@ let Inst{3-2} = imm{7-6}; } -let Predicates = [HasStdExtC, IsRV64] in +let Predicates = [HasStdExtCOrZca, IsRV64] in def C_LDSP : CStackLoad<0b011, "c.ldsp", GPRNoX0, uimm9_lsb000>, Sched<[WriteLDD, ReadMemBase]> { let Inst{6-5} = imm{4-3}; @@ -566,7 +566,7 @@ let Inst{8-7} = imm{7-6}; } -let Predicates = [HasStdExtC, IsRV64] in +let Predicates = [HasStdExtCOrZca, IsRV64] in def C_SDSP : CStackStore<0b111, "c.sdsp", GPR, uimm9_lsb000>, Sched<[WriteSTD, ReadStoreData, ReadMemBase]> { let Inst{12-10} = imm{5-3}; @@ -581,13 +581,13 @@ let Inst{15-0} = 0; } -} // Predicates = [HasStdExtC] +} // Predicates = [HasStdExtCOrZca] //===----------------------------------------------------------------------===// // HINT Instructions //===----------------------------------------------------------------------===// -let Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0, +let Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { @@ -688,7 +688,7 @@ let Inst{12} = 0; } -} // Predicates = [HasStdExtC, HasRVCHints], hasSideEffects = 0, mayLoad = 0, +} // Predicates = [HasStdExtCOrZca, HasRVCHints], hasSideEffects = 0, mayLoad = 0, // mayStore = 0 //===----------------------------------------------------------------------===// @@ -696,14 +696,14 @@ //===----------------------------------------------------------------------===// let EmitPriority = 0 in { -let Predicates = [HasStdExtC] in { +let Predicates = [HasStdExtCOrZca] in { def : InstAlias<"c.lw $rd, (${rs1})", (C_LW GPRC:$rd, GPRC:$rs1, 0)>; def : InstAlias<"c.sw $rs2, (${rs1})", (C_SW GPRC:$rs2, GPRC:$rs1, 0)>; def : InstAlias<"c.lwsp $rd, (${rs1})", (C_LWSP GPRC:$rd, SP:$rs1, 0)>; def : InstAlias<"c.swsp $rs2, (${rs1})", (C_SWSP GPRC:$rs2, SP:$rs1, 0)>; } -let Predicates = [HasStdExtC, IsRV64] in { +let Predicates = [HasStdExtCOrZca, IsRV64] in { def : InstAlias<"c.ld $rd, (${rs1})", (C_LD GPRC:$rd, GPRC:$rs1, 0)>; def : InstAlias<"c.sd $rs2, (${rs1})", (C_SD GPRC:$rs2, GPRC:$rs1, 0)>; def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SP:$rs1, 0)>; diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h --- a/llvm/lib/Target/RISCV/RISCVSubtarget.h +++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h @@ -60,6 +60,7 @@ bool HasStdExtZbr = false; bool HasStdExtZbs = false; bool HasStdExtZbt = false; + bool HasStdExtZca = false; bool HasStdExtV = false; bool HasStdExtZve32x = false; bool HasStdExtZve32f = false; @@ -167,6 +168,7 @@ bool hasStdExtZbt() const { return HasStdExtZbt; } bool hasStdExtZvl() const { return ZvlLen != 0; } bool hasStdExtZvfh() const { return HasStdExtZvfh; } + bool hasStdExtZca() const { return HasStdExtZca; } bool hasStdExtZfhmin() const { return HasStdExtZfhmin; } bool hasStdExtZfh() const { return HasStdExtZfh; } bool hasStdExtZfinx() const { return HasStdExtZfinx; } 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 @@ -187,3 +187,6 @@ .attribute arch, "rv32if_zkt1p0_zve32f1p0_zve32x1p0_zvl32b1p0" # CHECK: attribute 5, "rv32i2p0_f2p0_zkt1p0_zve32f1p0_zve32x1p0_zvl32b1p0" + +.attribute arch, "rv32izca0p70" +# CHECK: attribute 5, "rv32i2p0_zca0p70" diff --git a/llvm/test/MC/RISCV/rv32c-only-valid.s b/llvm/test/MC/RISCV/rv32c-only-valid.s --- a/llvm/test/MC/RISCV/rv32c-only-valid.s +++ b/llvm/test/MC/RISCV/rv32c-only-valid.s @@ -19,5 +19,5 @@ # CHECK-ASM: encoding: [0xfd,0x2f] # CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) # CHECK-NO-RV32: error: instruction requires the following: RV32I Base Instruction Set -# CHECK-NO-RV32-AND-EXT: error: instruction requires the following: 'C' (Compressed Instructions), RV32I Base Instruction Set +# CHECK-NO-RV32-AND-EXT: error: instruction requires the following: 'C' (Compressed Instructions) or 'Zca' (part of the C extension, excluding compressed floating point loads/stores), RV32I Base Instruction Set c.jal 2046 diff --git a/llvm/test/MC/RISCV/rv32zca-invalid.s b/llvm/test/MC/RISCV/rv32zca-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zca-invalid.s @@ -0,0 +1,93 @@ +# RUN: not llvm-mc -triple=riscv32 -mattr=+experimental-zca -mattr=+no-rvc-hints < %s 2>&1 \ +# RUN: | FileCheck %s + +## GPRC +.LBB: +c.lw ra, 4(sp) # CHECK: :[[@LINE]]:7: error: invalid operand for instruction +c.sw sp, 4(sp) # CHECK: :[[@LINE]]:7: error: invalid operand for instruction +c.beqz t0, .LBB # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +c.bnez s8, .LBB # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +c.addi4spn s4, sp, 12 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction +c.srli s7, 12 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +c.srai t0, 12 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +c.andi t1, 12 # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +c.and t1, a0 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction +c.or a0, s8 # CHECK: :[[@LINE]]:12: error: invalid operand for instruction +c.xor t2, a0 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction +c.sub a0, s8 # CHECK: :[[@LINE]]:12: error: invalid operand for instruction + +## GPRNoX0 +c.lwsp x0, 4(sp) # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +c.lwsp zero, 4(sp) # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +c.jr x0 # CHECK: :[[@LINE]]:7: error: invalid operand for instruction +c.jalr zero # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +c.addi x0, x0, 1 # CHECK: :[[@LINE]]:13: error: immediate must be zero +c.li zero, 2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RVC Hint Instructions +c.slli zero, zero, 4 # CHECK: :[[@LINE]]:15: error: invalid operand for instruction +c.mv zero, s0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RVC Hint Instructions +c.mv ra, x0 # CHECK: :[[@LINE]]:11: error: invalid operand for instruction +c.add ra, ra, x0 # CHECK: :[[@LINE]]:16: error: invalid operand for instruction +c.add zero, zero, sp # CHECK: :[[@LINE]]:14: error: invalid operand for instruction + +## GPRNoX0X2 +c.lui x0, 4 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RVC Hint Instructions +c.lui x2, 4 # CHECK: :[[@LINE]]:7: error: invalid operand for instruction + +## SP +c.addi4spn a0, a0, 12 # CHECK: :[[@LINE]]:17: error: invalid operand for instruction +c.addi16sp t0, 16 # CHECK: :[[@LINE]]:13: error: invalid operand for instruction + +# Out of range immediates + +## uimmlog2xlennonzero +c.slli t0, 64 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [1, 31] +c.srli a0, 32 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [1, 31] +c.srai a0, 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [1, 31] + +## simm6 +c.li t0, 128 # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-32, 31] +c.li t0, foo # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-32, 31] +c.li t0, %lo(foo) # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-32, 31] +c.li t0, %hi(foo) # CHECK: :[[@LINE]]:10: error: immediate must be an integer in the range [-32, 31] +c.andi a0, -33 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-32, 31] +c.andi a0, foo # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-32, 31] +c.andi a0, %lo(foo) # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-32, 31] +c.andi a0, %hi(foo) # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [-32, 31] + +## simm6nonzero +c.addi t0, 0 # CHECK: :[[@LINE]]:1: error: instruction requires the following: RVC Hint Instructions +c.addi t0, -33 # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the range [-32, 31] +c.addi t0, 32 # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the range [-32, 31] +c.addi t0, foo # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the range [-32, 31] +c.addi t0, %lo(foo) # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the range [-32, 31] +c.addi t0, %hi(foo) # CHECK: :[[@LINE]]:12: error: immediate must be non-zero in the range [-32, 31] + +## c_lui_imm +c.lui t0, 0 # CHECK: :[[@LINE]]:11: error: immediate must be in [0xfffe0, 0xfffff] or [1, 31] +c.lui t0, 32 # CHECK: :[[@LINE]]:11: error: immediate must be in [0xfffe0, 0xfffff] or [1, 31] +c.lui t0, 0xffffdf # CHECK: :[[@LINE]]:11: error: immediate must be in [0xfffe0, 0xfffff] or [1, 31] +c.lui t0, 0x1000000 # CHECK: :[[@LINE]]:11: error: immediate must be in [0xfffe0, 0xfffff] or [1, 31] + +## uimm8_lsb00 +c.lwsp ra, 256(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 252] +c.swsp ra, -4(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 4 bytes in the range [0, 252] +## uimm7_lsb00 +c.lw s0, -4(sp) # CHECK: :[[@LINE]]:11: error: immediate must be a multiple of 4 bytes in the range [0, 124] +c.sw s0, 128(sp) # CHECK: :[[@LINE]]:11: error: immediate must be a multiple of 4 bytes in the range [0, 124] + +## simm9_lsb0 +c.bnez s1, -258 # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 2 bytes in the range [-256, 254] +c.beqz a0, 256 # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 2 bytes in the range [-256, 254] + +## simm12_lsb0 +c.j 2048 # CHECK: :[[@LINE]]:5: error: immediate must be a multiple of 2 bytes in the range [-2048, 2046] +c.jal -2050 # CHECK: :[[@LINE]]:7: error: immediate must be a multiple of 2 bytes in the range [-2048, 2046] + +## uimm10_lsb00nonzero +c.addi4spn a0, sp, 0 # CHECK: :[[@LINE]]:21: error: immediate must be a multiple of 4 bytes in the range [4, 1020] +c.addi4spn a0, sp, 1024 # CHECK: :[[@LINE]]:21: error: immediate must be a multiple of 4 bytes in the range [4, 1020] + +## simm10_lsb0000nonzero +c.addi16sp sp, -528 # CHECK: :[[@LINE]]:17: error: immediate must be a multiple of 16 bytes and non-zero in the range [-512, 496] +c.addi16sp sp, 512 # CHECK: :[[@LINE]]:17: error: immediate must be a multiple of 16 bytes and non-zero in the range [-512, 496] +c.addi16sp sp, 0 # CHECK: :[[@LINE]]:17: error: immediate must be a multiple of 16 bytes and non-zero in the range [-512, 496] diff --git a/llvm/test/MC/RISCV/rv32zca-valid.s b/llvm/test/MC/RISCV/rv32zca-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv32zca-valid.s @@ -0,0 +1,111 @@ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zca -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-zca < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zca -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zca -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zca < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zca -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# TODO: more exhaustive testing of immediate encoding. + +# CHECK-ASM-AND-OBJ: c.lwsp ra, 0(sp) +# CHECK-ASM: encoding: [0x82,0x40] +c.lwsp ra, 0(sp) +# CHECK-ASM-AND-OBJ: c.swsp ra, 252(sp) +# CHECK-ASM: encoding: [0x86,0xdf] +c.swsp ra, 252(sp) +# CHECK-ASM-AND-OBJ: c.lw a2, 0(a0) +# CHECK-ASM: encoding: [0x10,0x41] +c.lw a2, 0(a0) +# CHECK-ASM-AND-OBJ: c.sw a5, 124(a3) +# CHECK-ASM: encoding: [0xfc,0xde] +c.sw a5, 124(a3) + +# CHECK-OBJ: c.j 0xfffff808 +# CHECK-ASM: c.j -2048 +# CHECK-ASM: encoding: [0x01,0xb0] +c.j -2048 +# CHECK-ASM-AND-OBJ: c.jr a7 +# CHECK-ASM: encoding: [0x82,0x88] +c.jr a7 +# CHECK-ASM-AND-OBJ: c.jalr a1 +# CHECK-ASM: encoding: [0x82,0x95] +c.jalr a1 +# CHECK-OBJ: c.beqz a3, 0xffffff0e +# CHECK-ASM: c.beqz a3, -256 +# CHECK-ASM: encoding: [0x81,0xd2] +c.beqz a3, -256 +# CHECK-OBJ: c.bnez a5, 0x10e +# CHECK-ASM: c.bnez a5, 254 +# CHECK-ASM: encoding: [0xfd,0xef] +c.bnez a5, 254 + +# CHECK-ASM-AND-OBJ: c.li a7, 31 +# CHECK-ASM: encoding: [0xfd,0x48] +c.li a7, 31 +# CHECK-ASM-AND-OBJ: c.addi a3, -32 +# CHECK-ASM: encoding: [0x81,0x16] +c.addi a3, -32 +# CHECK-ASM-AND-OBJ: c.addi16sp sp, -512 +# CHECK-ASM: encoding: [0x01,0x71] +c.addi16sp sp, -512 +# CHECK-ASM-AND-OBJ: c.addi16sp sp, 496 +# CHECK-ASM: encoding: [0x7d,0x61] +c.addi16sp sp, 496 +# CHECK-ASM-AND-OBJ: c.addi4spn a3, sp, 1020 +# CHECK-ASM: encoding: [0xf4,0x1f] +c.addi4spn a3, sp, 1020 +# CHECK-ASM-AND-OBJ: c.addi4spn a3, sp, 4 +# CHECK-ASM: encoding: [0x54,0x00] +c.addi4spn a3, sp, 4 +# CHECK-ASM-AND-OBJ: c.slli a1, 1 +# CHECK-ASM: encoding: [0x86,0x05] +c.slli a1, 1 +# CHECK-ASM-AND-OBJ: c.srli a3, 31 +# CHECK-ASM: encoding: [0xfd,0x82] +c.srli a3, 31 +# CHECK-ASM-AND-OBJ: c.srai a4, 2 +# CHECK-ASM: encoding: [0x09,0x87] +c.srai a4, 2 +# CHECK-ASM-AND-OBJ: c.andi a5, 15 +# CHECK-ASM: encoding: [0xbd,0x8b] +c.andi a5, 15 +# CHECK-ASM-AND-OBJ: c.mv a7, s0 +# CHECK-ASM: encoding: [0xa2,0x88] +c.mv a7, s0 +# CHECK-ASM-AND-OBJ: c.and a1, a2 +# CHECK-ASM: encoding: [0xf1,0x8d] +c.and a1, a2 +# CHECK-ASM-AND-OBJ: c.or a2, a3 +# CHECK-ASM: encoding: [0x55,0x8e] +c.or a2, a3 +# CHECK-ASM-AND-OBJ: c.xor a3, a4 +# CHECK-ASM: encoding: [0xb9,0x8e] +c.xor a3, a4 +# CHECK-ASM-AND-OBJ: c.sub a4, a5 +# CHECK-ASM: encoding: [0x1d,0x8f] +c.sub a4, a5 +# CHECK-ASM-AND-OBJ: c.nop +# CHECK-ASM: encoding: [0x01,0x00] +c.nop +# CHECK-ASM-AND-OBJ: c.ebreak +# CHECK-ASM: encoding: [0x02,0x90] +c.ebreak +# CHECK-ASM-AND-OBJ: c.lui s0, 1 +# CHECK-ASM: encoding: [0x05,0x64] +c.lui s0, 1 +# CHECK-ASM-AND-OBJ: c.lui s0, 31 +# CHECK-ASM: encoding: [0x7d,0x64] +c.lui s0, 31 +# CHECK-ASM-AND-OBJ: c.lui s0, 1048544 +# CHECK-ASM: encoding: [0x01,0x74] +c.lui s0, 0xfffe0 +# CHECK-ASM-AND-OBJ: c.lui s0, 1048575 +# CHECK-ASM: encoding: [0x7d,0x74] +c.lui s0, 0xfffff +# CHECK-ASM-AND-OBJ: c.unimp +# CHECK-ASM: encoding: [0x00,0x00] +c.unimp diff --git a/llvm/test/MC/RISCV/rv64zca-hints-valid.s b/llvm/test/MC/RISCV/rv64zca-hints-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zca-hints-valid.s @@ -0,0 +1,9 @@ +# RUN: llvm-mc %s -triple riscv64 -mattr=+experimental-zca -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zca < %s \ +# RUN: | llvm-objdump --mattr=+experimental-zca -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s + +# CHECK-ASM-AND-OBJ: c.slli zero, 63 +# CHECK-ASM: encoding: [0x7e,0x10] +c.slli x0, 63 diff --git a/llvm/test/MC/RISCV/rv64zca-invalid.s b/llvm/test/MC/RISCV/rv64zca-invalid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zca-invalid.s @@ -0,0 +1,32 @@ +# RUN: not llvm-mc -triple=riscv64 -mattr=+experimental-zca < %s 2>&1 | FileCheck %s + +## GPRC +c.ld ra, 4(sp) # CHECK: :[[@LINE]]:6: error: invalid operand for instruction +c.sd sp, 4(sp) # CHECK: :[[@LINE]]:6: error: invalid operand for instruction +c.addw a0, a7 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction +c.subw a0, a6 # CHECK: :[[@LINE]]:14: error: invalid operand for instruction + +## GPRNoX0 +c.ldsp x0, 4(sp) # CHECK: :[[@LINE]]:9: error: invalid operand for instruction +c.ldsp zero, 4(sp) # CHECK: :[[@LINE]]:9: error: invalid operand for instruction + +# Out of range immediates + +## uimmlog2xlennonzero +c.slli t0, 64 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [1, 63] +c.srli a0, -1 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [1, 63] +c.srai a0, 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [1, 63] + +## simm6 +c.addiw t0, -33 # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-32, 31] +c.addiw t0, 32 # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-32, 31] +c.addiw t0, foo # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-32, 31] +c.addiw t0, %lo(foo) # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-32, 31] +c.addiw t0, %hi(foo) # CHECK: :[[@LINE]]:13: error: immediate must be an integer in the range [-32, 31] + +## uimm9_lsb000 +c.ldsp ra, 512(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 8 bytes in the range [0, 504] +c.sdsp ra, -8(sp) # CHECK: :[[@LINE]]:13: error: immediate must be a multiple of 8 bytes in the range [0, 504] +## uimm8_lsb000 +c.ld s0, -8(sp) # CHECK: :[[@LINE]]:11: error: immediate must be a multiple of 8 bytes in the range [0, 248] +c.sd s0, 256(sp) # CHECK: :[[@LINE]]:11: error: immediate must be a multiple of 8 bytes in the range [0, 248] diff --git a/llvm/test/MC/RISCV/rv64zca-valid.s b/llvm/test/MC/RISCV/rv64zca-valid.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/rv64zca-valid.s @@ -0,0 +1,68 @@ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zca -riscv-no-aliases -show-encoding \ +# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s +# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+c < %s \ +# RUN: | llvm-objdump --mattr=+c -M no-aliases -d -r - \ +# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# +# +# RUN: not llvm-mc -triple riscv64 \ +# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK-NO-EXT %s +# RUN: not llvm-mc -triple riscv32 -mattr=+c \ +# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \ +# RUN: | FileCheck -check-prefixes=CHECK-NO-RV64 %s + +# TODO: more exhaustive testing of immediate encoding. + +# CHECK-ASM-AND-OBJ: c.ldsp ra, 0(sp) +# CHECK-ASM: encoding: [0x82,0x60] +# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) +# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set +c.ldsp ra, 0(sp) +# CHECK-ASM-AND-OBJ: c.sdsp ra, 504(sp) +# CHECK-ASM: encoding: [0x86,0xff] +# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) +# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set +c.sdsp ra, 504(sp) +# CHECK-ASM-AND-OBJ: c.ld a4, 0(a3) +# CHECK-ASM: encoding: [0x98,0x62] +# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) +# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set +c.ld a4, 0(a3) +# CHECK-ASM-AND-OBJ: c.sd a5, 248(a3) +# CHECK-ASM: encoding: [0xfc,0xfe] +# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) +# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set +c.sd a5, 248(a3) + +# CHECK-ASM-AND-OBJ: c.subw a3, a4 +# CHECK-ASM: encoding: [0x99,0x9e] +c.subw a3, a4 +# CHECK-ASM-AND-OBJ: c.addw a0, a2 +# CHECK-ASM: encoding: [0x31,0x9d] +# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) +# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set +c.addw a0, a2 + +# CHECK-ASM-AND-OBJ: c.addiw a3, -32 +# CHECK-ASM: encoding: [0x81,0x36] +# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) +# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set +c.addiw a3, -32 +# CHECK-ASM-AND-OBJ: c.addiw a3, 31 +# CHECK-ASM: encoding: [0xfd,0x26] +# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) +# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set +c.addiw a3, 31 + +# CHECK-ASM-AND-OBJ: c.slli s0, 1 +# CHECK-ASM: encoding: [0x06,0x04] +# CHECK-NO-EXT: error: instruction requires the following: 'C' (Compressed Instructions) +# CHECK-NO-RV64: error: instruction requires the following: RV64I Base Instruction Set +c.slli s0, 1 +# CHECK-ASM-AND-OBJ: c.srli a3, 63 +# CHECK-ASM: encoding: [0xfd,0x92] +c.srli a3, 63 +# CHECK-ASM-AND-OBJ: c.srai a2, 63 +# CHECK-ASM: encoding: [0x7d,0x96] +c.srai a2, 63