// on page 82 of the ISA manual.
// Quadrant 0
-let Predicates = [HasStdExtC] in {
+let Predicates = [HasStdExtCOrZca] in {
def : CompressPat<(ADDI GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm),
(C_ADDI4SPN GPRC:$rd, SP:$rs1, uimm10_lsb00nonzero:$imm)>;
-} // Predicates = [HasStdExtC]
+} // Predicates = [HasStdExtCOrZca]
let Predicates = [HasStdExtC, HasStdExtD] in {
def : CompressPat<(FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
(C_FLD FPR64C:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
} // Predicates = [HasStdExtC, HasStdExtD]
-let Predicates = [HasStdExtC] in {
+let Predicates = [HasStdExtCOrZca] in {
def : CompressPat<(LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
(C_LW GPRC:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
-} // Predicates = [HasStdExtC]
+} // Predicates = [HasStdExtCOrZca]
let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
def : CompressPat<(FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm),
(C_FLW FPR32C:$rd, GPRC:$rs1, uimm7_lsb00:$imm)>;
} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
-let Predicates = [HasStdExtC, IsRV64] in {
+let Predicates = [HasStdExtCOrZca, IsRV64] in {
def : CompressPat<(LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm),
(C_LD GPRC:$rd, GPRC:$rs1, uimm8_lsb000:$imm)>;
-} // Predicates = [HasStdExtC, IsRV64]
+} // Predicates = [HasStdExtCOrZca, IsRV64]
let Predicates = [HasStdExtC, HasStdExtD] in {
def : CompressPat<(FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
(C_FSD FPR64C:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
} // Predicates = [HasStdExtC, HasStdExtD]
-let Predicates = [HasStdExtC] in {
+let Predicates = [HasStdExtCOrZca] in {
def : CompressPat<(SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
(C_SW GPRC:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
-} // Predicates = [HasStdExtC]
+} // Predicates = [HasStdExtCOrZca]
let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
def : CompressPat<(FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm),
(C_FSW FPR32C:$rs2, GPRC:$rs1, uimm7_lsb00:$imm)>;
} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
-let Predicates = [HasStdExtC, IsRV64] in {
+let Predicates = [HasStdExtCOrZca, IsRV64] in {
def : CompressPat<(SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm),
(C_SD GPRC:$rs2, GPRC:$rs1, uimm8_lsb000:$imm)>;
-} // Predicates = [HasStdExtC, IsRV64]
+} // Predicates = [HasStdExtCOrZca, IsRV64]
// Quadrant 1
-let Predicates = [HasStdExtC] in {
+let Predicates = [HasStdExtCOrZca] in {
def : CompressPat<(ADDI X0, X0, 0), (C_NOP)>;
def : CompressPat<(ADDI GPRNoX0:$rs1, GPRNoX0:$rs1, simm6nonzero:$imm),
(C_ADDI GPRNoX0:$rs1, simm6nonzero:$imm)>;
-} // Predicates = [HasStdExtC]
+} // Predicates = [HasStdExtCOrZca]
-let Predicates = [HasStdExtC, IsRV32] in {
+let Predicates = [HasStdExtCOrZca, IsRV32] in {
def : CompressPat<(JAL X1, simm12_lsb0:$offset),
(C_JAL simm12_lsb0:$offset)>;
-} // Predicates = [HasStdExtC, IsRV32]
+} // Predicates = [HasStdExtCOrZca, IsRV32]
-let Predicates = [HasStdExtC, IsRV64] in {
+let Predicates = [HasStdExtCOrZca, IsRV64] in {
def : CompressPat<(ADDIW GPRNoX0:$rs1, GPRNoX0:$rs1, simm6:$imm),
(C_ADDIW GPRNoX0:$rs1, simm6:$imm)>;
-} // Predicates = [HasStdExtC, IsRV64]
+} // Predicates = [HasStdExtCOrZca, IsRV64]
-let Predicates = [HasStdExtC] in {
+let Predicates = [HasStdExtCOrZca] in {
def : CompressPat<(ADDI GPRNoX0:$rd, X0, simm6:$imm),
(C_LI GPRNoX0:$rd, simm6:$imm)>;
def : CompressPat<(ADDI X2, X2, simm10_lsb0000nonzero:$imm),
let isCompressOnly = true in
def : CompressPat<(AND GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
(C_AND GPRC:$rs1, GPRC:$rs2)>;
-} // Predicates = [HasStdExtC]
+} // Predicates = [HasStdExtCOrZca]
-let Predicates = [HasStdExtC, IsRV64] in {
+let Predicates = [HasStdExtCOrZca, IsRV64] in {
let isCompressOnly = true in
def : CompressPat<(ADDIW GPRNoX0:$rd, X0, simm6:$imm),
(C_LI GPRNoX0:$rd, simm6:$imm)>;
let isCompressOnly = true in
def : CompressPat<(ADDW GPRC:$rs1, GPRC:$rs2, GPRC:$rs1),
(C_ADDW GPRC:$rs1, GPRC:$rs2)>;
-} // Predicates = [HasStdExtC, IsRV64]
+} // Predicates = [HasStdExtCOrZca, IsRV64]
-let Predicates = [HasStdExtC] in {
+let Predicates = [HasStdExtCOrZca] in {
def : CompressPat<(JAL X0, simm12_lsb0:$offset),
(C_J simm12_lsb0:$offset)>;
def : CompressPat<(BEQ GPRC:$rs1, X0, simm9_lsb0:$imm),
(C_BEQZ GPRC:$rs1, simm9_lsb0:$imm)>;
def : CompressPat<(BNE GPRC:$rs1, X0, simm9_lsb0:$imm),
(C_BNEZ GPRC:$rs1, simm9_lsb0:$imm)>;
-} // Predicates = [HasStdExtC]
+} // Predicates = [HasStdExtCOrZca]
// Quadrant 2
-let Predicates = [HasStdExtC] in {
+let Predicates = [HasStdExtCOrZca] in {
def : CompressPat<(SLLI GPRNoX0:$rs1, GPRNoX0:$rs1, uimmlog2xlennonzero:$imm),
(C_SLLI GPRNoX0:$rs1, uimmlog2xlennonzero:$imm)>;
-} // Predicates = [HasStdExtC]
+} // Predicates = [HasStdExtCOrZca]
let Predicates = [HasStdExtC, HasStdExtD] in {
def : CompressPat<(FLD FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm),
(C_FLDSP FPR64:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
} // Predicates = [HasStdExtC, HasStdExtD]
-let Predicates = [HasStdExtC] in {
+let Predicates = [HasStdExtCOrZca] in {
def : CompressPat<(LW GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm),
(C_LWSP GPRNoX0:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
-} // Predicates = [HasStdExtC]
+} // Predicates = [HasStdExtCOrZca]
let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
def : CompressPat<(FLW FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm),
(C_FLWSP FPR32:$rd, SP:$rs1, uimm8_lsb00:$imm)>;
} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
-let Predicates = [HasStdExtC, IsRV64] in {
+let Predicates = [HasStdExtCOrZca, IsRV64] in {
def : CompressPat<(LD GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm),
(C_LDSP GPRNoX0:$rd, SP:$rs1, uimm9_lsb000:$imm)>;
-} // Predicates = [HasStdExtC, IsRV64]
+} // Predicates = [HasStdExtCOrZca, IsRV64]
-let Predicates = [HasStdExtC] in {
+let Predicates = [HasStdExtCOrZca] in {
def : CompressPat<(JALR X0, GPRNoX0:$rs1, 0),
(C_JR GPRNoX0:$rs1)>;
let isCompressOnly = true in {
let isCompressOnly = true in
def : CompressPat<(ADD GPRNoX0:$rs1, GPRNoX0:$rs2, GPRNoX0:$rs1),
(C_ADD GPRNoX0:$rs1, GPRNoX0:$rs2)>;
-} // Predicates = [HasStdExtC]
+} // Predicates = [HasStdExtCOrZca]
let Predicates = [HasStdExtC, HasStdExtD] in {
def : CompressPat<(FSD FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm),
(C_FSDSP FPR64:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
} // Predicates = [HasStdExtC, HasStdExtD]
-let Predicates = [HasStdExtC] in {
+let Predicates = [HasStdExtCOrZca] in {
def : CompressPat<(SW GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm),
(C_SWSP GPR:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
-} // Predicates = [HasStdExtC]
+} // Predicates = [HasStdExtCOrZca]
let Predicates = [HasStdExtC, HasStdExtF, IsRV32] in {
def : CompressPat<(FSW FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm),
(C_FSWSP FPR32:$rs2, SP:$rs1, uimm8_lsb00:$imm)>;
} // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
-let Predicates = [HasStdExtC, IsRV64] in {
+let Predicates = [HasStdExtCOrZca, IsRV64] in {
def : CompressPat<(SD GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm),
(C_SDSP GPR:$rs2, SP:$rs1, uimm9_lsb000:$imm)>;
-} // Predicates = [HasStdExtC, IsRV64]
+} // Predicates = [HasStdExtCOrZca, IsRV64]
# Relaxation enabled with C extension:
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c,+relax < %s \
# RUN: | llvm-objdump -d -M no-aliases - \
-# RUN: | FileCheck -check-prefix=C-EXT-RELAX-INST %s
+# RUN: | FileCheck -check-prefix=C-OR-ZCA-EXT-RELAX-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c,+relax < %s \
-# RUN: | llvm-readobj -r - | FileCheck -check-prefix=C-EXT-RELAX-RELOC %s
+# RUN: | llvm-readobj -r - | FileCheck -check-prefix=C-OR-ZCA-EXT-RELAX-RELOC %s
+
+# Relaxation enabled with Zca extension:
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zca,+relax < %s \
+# RUN: | llvm-objdump --mattr=+experimental-zca -d -M no-aliases - \
+# RUN: | FileCheck -check-prefix=C-OR-ZCA-EXT-RELAX-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zca,+relax < %s \
+# RUN: | llvm-readobj -r - | FileCheck -check-prefix=C-OR-ZCA-EXT-RELAX-RELOC %s
# Relaxation disabled with C extension:
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c,-relax < %s \
# RUN: | llvm-objdump -d -M no-aliases - \
-# RUN: | FileCheck -check-prefix=C-EXT-NORELAX-INST %s
+# RUN: | FileCheck -check-prefix=C-OR-ZCA-EXT-NORELAX-INST %s
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+c,-relax < %s \
-# RUN: | llvm-readobj -r - | FileCheck -check-prefix=C-EXT-NORELAX-RELOC %s
+# RUN: | llvm-readobj -r - | FileCheck -check-prefix=C-OR-ZCA-EXT-NORELAX-RELOC %s
+
+# Relaxation disabled with ZCA extension:
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zca,-relax < %s \
+# RUN: | llvm-objdump --mattr=+experimental-zca -d -M no-aliases - \
+# RUN: | FileCheck -check-prefix=C-OR-ZCA-EXT-NORELAX-INST %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+experimental-zca,-relax < %s \
+# RUN: | llvm-readobj -r - | FileCheck -check-prefix=C-OR-ZCA-EXT-NORELAX-RELOC %s
# We need to insert N-MinNopSize bytes NOPs and R_RISCV_ALIGN relocation
# type for .align N directive when linker relaxation enabled.
# The first R_RISCV_ALIGN come from
# MCELFStreamer::InitSections() emitCodeAlignment(getTextSectionAligntment()).
-# C-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x2
-# C-EXT-RELAX-INST: c.nop
+# C-OR-ZCA-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x2
+# C-OR-ZCA-EXT-RELAX-INST: c.nop
test:
.p2align 2
# If the +c extension is enabled, the text section will be 2-byte aligned, so
# one c.nop instruction is sufficient.
-# C-EXT-RELAX-RELOC-NOT: R_RISCV_ALIGN - 0x2
-# C-EXT-RELAX-INST-NOT: c.nop
+# C-OR-ZCA-EXT-RELAX-RELOC-NOT: R_RISCV_ALIGN - 0x2
+# C-OR-ZCA-EXT-RELAX-INST-NOT: c.nop
bne zero, a0, .LBB0_2
mv a0, zero
.p2align 3
# RELAX-RELOC: R_RISCV_ALIGN - 0x4
# RELAX-INST: addi zero, zero, 0
-# C-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x6
-# C-EXT-RELAX-INST: c.nop
-# C-EXT-RELAX-INST: addi zero, zero, 0
-# C-EXT-NORELAX-INST: addi zero, zero, 0
+# C-OR-ZCA-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x6
+# C-OR-ZCA-EXT-RELAX-INST: c.nop
+# C-OR-ZCA-EXT-RELAX-INST: addi zero, zero, 0
+# C-OR-ZCA-EXT-NORELAX-INST: addi zero, zero, 0
add a0, a0, a1
.align 4
.LBB0_2:
# RELAX-INST: addi zero, zero, 0
# RELAX-INST: addi zero, zero, 0
# NORELAX-INST: addi zero, zero, 0
-# C-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0xE
-# C-EXT-RELAX-INST: addi zero, zero, 0
-# C-EXT-RELAX-INST: addi zero, zero, 0
-# C-EXT-RELAX-INST: addi zero, zero, 0
-# C-EXT-RELAX-INST: c.nop
+# C-OR-ZCA-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0xE
+# C-OR-ZCA-EXT-RELAX-INST: addi zero, zero, 0
+# C-OR-ZCA-EXT-RELAX-INST: addi zero, zero, 0
+# C-OR-ZCA-EXT-RELAX-INST: addi zero, zero, 0
+# C-OR-ZCA-EXT-RELAX-INST: c.nop
# C-EXT-INST: addi zero, zero, 0
# C-EXT-INST: c.nop
add a0, a0, a1
# RELAX-RELOC: R_RISCV_ALIGN - 0x4
# RELAX-INST: addi zero, zero, 0
# NORELAX-INST: addi zero, zero, 0
-# C-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x6
-# C-EXT-RELAX-INST: addi zero, zero, 0
-# C-EXT-RELAX-INST-NOT: c.nop
+# C-OR-ZCA-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x6
+# C-OR-ZCA-EXT-RELAX-INST: addi zero, zero, 0
+# C-OR-ZCA-EXT-RELAX-INST-NOT: c.nop
# C-EXT-INST: addi zero, zero, 0
# C-EXT-INST: c.nop
add a0, a0, a1
# RELAX-RELOC-NOT: R_RISCV_ALIGN - 0xC
# RELAX-INST: 01 01
# RELAX-INST: 01 01
-# C-EXT-RELAX-RELOC-NOT: R_RISCV_ALIGN - 0xE
-# C-EXT-RELAX-INST: 01 01
+# C-OR-ZCA-EXT-RELAX-RELOC-NOT: R_RISCV_ALIGN - 0xE
+# C-OR-ZCA-EXT-RELAX-INST: 01 01
# C-EXT-INST: 01 01
ret
# NORELAX-RELOC-NOT: R_RISCV
-# C-EXT-NORELAX-RELOC-NOT: R_RISCV
+# C-OR-ZCA-EXT-NORELAX-RELOC-NOT: R_RISCV
# Code alignment of a byte size less than the size of a nop must be treated
# as no alignment. This used to trigger a fatal error with relaxation enabled
# as the calculation to emit the worst-case sequence of nops would overflow.
.data
.p2align 3
# RELAX-RELOC-NOT: R_RISCV_ALIGN
-# C-EXT-RELAX-RELOC-NOT: R_RISCV_ALIGN
+# C-OR-ZCA-EXT-RELAX-RELOC-NOT: R_RISCV_ALIGN
data1:
.word 7
.p2align 4
# RELAX-RELOC-NOT: R_RISCV_ALIGN
-# C-EXT-RELAX-RELOC-NOT: R_RISCV_ALIGN
+# C-OR-ZCA-EXT-RELAX-RELOC-NOT: R_RISCV_ALIGN
data2:
.word 9
# Check that the initial alignment is properly handled when using .option to
# disable the C extension. This used to crash.
-# C-EXT-RELAX-INST: <.text2>:
-# C-EXT-RELAX-INST-NEXT: add a0, a0, a1
+# C-OR-ZCA-EXT-RELAX-INST: <.text2>:
+# C-OR-ZCA-EXT-RELAX-INST-NEXT: add a0, a0, a1
.section .text2, "x"
.option norvc
.balign 4