# RUN: split-file %s %t # RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+xqcilb %t/pass.s -o - \ # RUN: | llvm-objdump -dr -M no-aliases - --mattr=+xqcilb | FileCheck %s # RUN: not llvm-mc -filetype=obj -triple riscv32 -mattr=+xqcilb %t/fail.s \ # RUN: 2>&1 | FileCheck %t/fail.s --check-prefix=ERROR ## This testcase shows how `c.j`, `c.jal` and `jal` can be relaxed to `qc.e.j` and `qc.e.jal` ## with Xqcilb, when the branches are out of range, but also that these can be compressed ## when referencing close labels. ## The only problem we have here is when `jal` references an out-of-range label, and `rd` is ## not `x0` or `x1` - for which we have no equivalent sequence, so we just fail to relax, and ## emit a fixup-value-out-of-range error. #--- pass.s EXT_JUMP_NEGATIVE: c.nop .space 0x100000 FAR_JUMP_NEGATIVE: c.nop .space 0x1000 NEAR_NEGATIVE: c.nop start: c.j NEAR # CHECK: c.j {{0x[0-9a-f]+}} c.j NEAR_NEGATIVE # CHECK: c.j {{0x[0-9a-f]+}} c.j FAR_JUMP # CHECK: jal zero, {{0x[0-9a-f]+}} c.j FAR_JUMP_NEGATIVE # CHECK: jal zero, {{0x[0-9a-f]+}} c.j EXT_JUMP # CHECK: qc.e.j {{0x[0-9a-f]+}} c.j EXT_JUMP_NEGATIVE # CHECK: qc.e.j {{0x[0-9a-f]+}} c.j undef # CHECK: qc.e.j {{0x[0-9a-f]+}} # CHECK: R_RISCV_QC_E_CALL_PLT undef c.jal NEAR # CHECK: c.jal {{0x[0-9a-f]+}} c.jal NEAR_NEGATIVE # CHECK: c.jal {{0x[0-9a-f]+}} c.jal FAR_JUMP # CHECK: jal ra, {{0x[0-9a-f]+}} c.jal FAR_JUMP_NEGATIVE # CHECK: jal ra, {{0x[0-9a-f]+}} c.jal EXT_JUMP # CHECK: qc.e.jal {{0x[0-9a-f]+}} c.jal EXT_JUMP_NEGATIVE # CHECK: qc.e.jal {{0x[0-9a-f]+}} c.jal undef # CHECK: qc.e.jal {{0x[0-9a-f]+}} # CHECK: R_RISCV_QC_E_CALL_PLT undef jal zero, NEAR # CHECK: c.j {{0x[0-9a-f]+}} jal zero, NEAR_NEGATIVE # CHECK: c.j {{0x[0-9a-f]+}} jal zero, FAR_JUMP # CHECK: jal zero, {{0x[0-9a-f]+}} jal zero, FAR_JUMP_NEGATIVE # CHECK: jal zero, {{0x[0-9a-f]+}} jal zero, EXT_JUMP # CHECK: qc.e.j {{0x[0-9a-f]+}} jal zero, EXT_JUMP_NEGATIVE # CHECK: qc.e.j {{0x[0-9a-f]+}} jal zero, undef # CHECK: qc.e.j {{0x[0-9a-f]+}} # CHECK: R_RISCV_QC_E_CALL_PLT undef jal ra, NEAR # CHECK: c.jal {{0x[0-9a-f]+}} jal ra, NEAR_NEGATIVE # CHECK: c.jal {{0x[0-9a-f]+}} jal ra, FAR_JUMP # CHECK: jal ra, {{0x[0-9a-f]+}} jal ra, FAR_JUMP_NEGATIVE # CHECK: jal ra, {{0x[0-9a-f]+}} jal ra, EXT_JUMP # CHECK: qc.e.jal {{0x[0-9a-f]+}} jal ra, EXT_JUMP_NEGATIVE # CHECK: qc.e.jal {{0x[0-9a-f]+}} jal ra, undef # CHECK: qc.e.jal {{0x[0-9a-f]+}} # CHECK: R_RISCV_QC_E_CALL_PLT undef qc.e.j NEAR # CHECK: c.j {{0x[0-9a-f]+}} qc.e.j NEAR_NEGATIVE # CHECK: c.j {{0x[0-9a-f]+}} qc.e.j FAR_JUMP # CHECK: jal zero, {{0x[0-9a-f]+}} qc.e.j FAR_JUMP_NEGATIVE # CHECK: jal zero, {{0x[0-9a-f]+}} qc.e.j EXT_JUMP # CHECK: qc.e.j {{0x[0-9a-f]+}} qc.e.j EXT_JUMP_NEGATIVE # CHECK: qc.e.j {{0x[0-9a-f]+}} qc.e.j undef # CHECK: qc.e.j {{0x[0-9a-f]+}} # CHECK: R_RISCV_QC_E_CALL_PLT undef qc.e.jal NEAR # CHECK: c.jal {{0x[0-9a-f]+}} qc.e.jal NEAR_NEGATIVE # CHECK: c.jal {{0x[0-9a-f]+}} qc.e.jal FAR_JUMP # CHECK: jal ra, {{0x[0-9a-f]+}} qc.e.jal FAR_JUMP_NEGATIVE # CHECK: jal ra, {{0x[0-9a-f]+}} qc.e.jal EXT_JUMP # CHECK: qc.e.jal {{0x[0-9a-f]+}} qc.e.jal EXT_JUMP_NEGATIVE # CHECK: qc.e.jal {{0x[0-9a-f]+}} qc.e.jal undef # CHECK: qc.e.jal {{0x[0-9a-f]+}} # CHECK: R_RISCV_QC_E_CALL_PLT undef jal t1, NEAR # CHECK: jal t1, {{0x[0-9a-f]+}} jal t1, NEAR_NEGATIVE # CHECK: jal t1, {{0x[0-9a-f]+}} jal t1, FAR_JUMP # CHECK: jal t1, {{0x[0-9a-f]+}} jal t1, FAR_JUMP_NEGATIVE # CHECK: jal t1, {{0x[0-9a-f]+}} ## The two cases with EXT_JUMP and EXT_JUMP_NEGATIVE are ## in fail.s, below. jal t1, undef # CHECK: jal t1, {{0x[0-9a-f]+}} # CHECK: R_RISCV_JAL undef NEAR: c.nop .space 0x1000 FAR_JUMP: c.nop .space 0x100000 EXT_JUMP: c.nop #--- fail.s EXT_JUMP_NEGATIVE: c.nop .space 0x100000 .space 0x1000 jal t1, EXT_JUMP # ERROR: [[@LINE-1]]:11: error: fixup value out of range jal t1, EXT_JUMP_NEGATIVE # ERROR: [[@LINE-1]]:11: error: fixup value out of range .space 0x1000 .space 0x100000 EXT_JUMP: c.nop