bfd_vma delta = target - md_pcrel_from (fixP);
bfd_putl32 (bfd_getl32 (buf) | ENCODE_JTYPE_IMM (delta), buf);
if (!riscv_opts.relax && S_IS_LOCAL (fixP->fx_addsy))
- fixP->fx_done = 1;
+ {
+ if (!VALID_JTYPE_IMM (delta))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid J-type offset (%+lld)"),
+ (long long) delta);
+ fixP->fx_done = 1;
+ }
}
break;
bfd_vma delta = target - md_pcrel_from (fixP);
bfd_putl32 (bfd_getl32 (buf) | ENCODE_BTYPE_IMM (delta), buf);
if (!riscv_opts.relax && S_IS_LOCAL (fixP->fx_addsy))
- fixP->fx_done = 1;
+ {
+ if (!VALID_BTYPE_IMM (delta))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid B-type offset (%+lld)"),
+ (long long) delta);
+ fixP->fx_done = 1;
+ }
}
break;
bfd_vma delta = target - md_pcrel_from (fixP);
bfd_putl16 (bfd_getl16 (buf) | ENCODE_CBTYPE_IMM (delta), buf);
if (!riscv_opts.relax && S_IS_LOCAL (fixP->fx_addsy))
- fixP->fx_done = 1;
+ {
+ if (!VALID_CBTYPE_IMM (delta))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid CB-type offset (%+lld)"),
+ (long long) delta);
+ fixP->fx_done = 1;
+ }
}
break;
bfd_vma delta = target - md_pcrel_from (fixP);
bfd_putl16 (bfd_getl16 (buf) | ENCODE_CJTYPE_IMM (delta), buf);
if (!riscv_opts.relax && S_IS_LOCAL (fixP->fx_addsy))
- fixP->fx_done = 1;
+ {
+ if (!VALID_CJTYPE_IMM (delta))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid CJ-type offset (%+lld)"),
+ (long long) delta);
+ fixP->fx_done = 1;
+ }
}
break;
| ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)),
buf);
if (!riscv_opts.relax)
- fixP->fx_done = 1;
+ {
+ if (xlen > 32
+ && !VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("invalid pcrel_hi offset (%+lld)"),
+ (long long) value);
+ fixP->fx_done = 1;
+ }
}
relaxable = true;
break;
bfd_putl32 (bfd_getl32 (buf) | ENCODE_STYPE_IMM (value), buf);
else
bfd_putl32 (bfd_getl32 (buf) | ENCODE_ITYPE_IMM (value), buf);
- /* Relaxations should never be enabled by `.option relax'. */
+ /* Relaxations should never be enabled by `.option relax'.
+ The offset is checked by corresponding %pcrel_hi entry. */
if (!riscv_opts.relax)
fixP->fx_done = 1;
}
--- /dev/null
+#as: -march=rv32ic
+#error_output: no-relax-branch-offset-fail.l
--- /dev/null
+.*Assembler messages:
+.*:4: Error: invalid J-type offset \(\+1048576\)
+.*:5: Error: invalid J-type offset \(-1048578\)
+.*:8: Error: invalid J-type offset \(\+1048576\)
+.*:10: Error: invalid J-type offset \(-1048578\)
+.*:14: Error: invalid J-type offset \(\+1048576\)
+.*:17: Error: invalid J-type offset \(-1048578\)
+.*:20: Error: invalid CJ-type offset \(\+1\)
--- /dev/null
+ .option norelax
+
+ # Relative to the current instruction.
+ j .+0x0ffffe+2
+ j .-0x100000-2
+
+ # Relative to local labels (make sure that all instructions except "c.j" occupy 4-bytes).
+ j 1f+0x0ffffe-4+2
+1:
+ j 2f-0x100000-4-2
+2:
+3:
+ lui t0, 0x12345
+ j 3b+0x0ffffe+4+2
+4:
+ lui t0, 0x2abcd
+ j 4b-0x100000+4-2
+
+ # Jump to odd address (violates instruction alignment).
+ c.j .+1
--- /dev/null
+#as: -march=rv32ic
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+0+ <\.text>:
+[ ]+0:[ ]+7ffff06f[ ]+j[ ][0-9a-f]+.*
+[ ]+4:[ ]+8000006f[ ]+j[ ][0-9a-f]+.*
+[ ]+8:[ ]+7ffff06f[ ]+j[ ][0-9a-f]+.*
+[ ]+c:[ ]+8000006f[ ]+j[ ][0-9a-f]+.*
+[ ]+10:[ ]+123452b7[ ]+lui[ ]t0,0x12345
+[ ]+14:[ ]+7ffff06f[ ]+j[ ][0-9a-f]+.*
+[ ]+18:[ ]+2abcd2b7[ ]+lui[ ]t0,0x2abcd
+[ ]+1c:[ ]+8000006f[ ]+j[ ][0-9a-f]+.*
--- /dev/null
+ .option norelax
+
+ # Relative to the current instruction.
+ j .+0x0ffffe
+ j .-0x100000
+
+ # Relative to local labels (make sure that all instructions occupy 4-bytes).
+ j 1f+0x0ffffe-4
+1:
+ j 2f-0x100000-4
+2:
+3:
+ lui t0, 0x12345
+ j 3b+0x0ffffe+4
+4:
+ lui t0, 0x2abcd
+ j 4b-0x100000+4
--- /dev/null
+#as: -march=rv64i
+#error_output: no-relax-pcrel-offset-fail-64.l
--- /dev/null
+.*Assembler messages:
+.*:8: Error: invalid pcrel_hi offset \(\+2147481600\)
+.*:11: Error: invalid pcrel_hi offset \(-2147485697\)
+.*:17: Error: invalid pcrel_hi offset \(\+2147481600\)
+.*:21: Error: invalid pcrel_hi offset \(-2147485697\)
+.*:26: Error: invalid pcrel_hi offset \(\+2147481600\)
+.*:30: Error: invalid pcrel_hi offset \(-2147485697\)
--- /dev/null
+ .option norelax
+
+ ## Fail on RV64, wrap without errors on RV32.
+
+ # Relative to the current instruction.
+
+1:
+ auipc a0, %pcrel_hi(.+0x7ffff7ff+1)
+ addi a0, a0, %pcrel_lo(1b)
+2:
+ auipc a0, %pcrel_hi(.-0x80000800-1)
+ addi a0, a0, %pcrel_lo(2b)
+
+ # Relative to local labels (all instructions occupy 4-bytes).
+
+3:
+ auipc a0, %pcrel_hi(4f+0x7ffff7ff-4+1)
+4:
+ addi a0, a0, %pcrel_lo(3b)
+5:
+ auipc a0, %pcrel_hi(6f-0x80000800-4-1)
+6:
+ addi a0, a0, %pcrel_lo(5b)
+
+7:
+ auipc a0, %pcrel_hi(6b+0x7ffff7ff+4+1)
+8:
+ addi a0, a0, %pcrel_lo(7b)
+9:
+ auipc a0, %pcrel_hi(8b-0x80000800+4-1)
+ addi a0, a0, %pcrel_lo(9b)
--- /dev/null
+#as: -march=rv32i
+#source: no-relax-pcrel-offset-fail-64.s
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+0+ <\.text>:
+[ ]+0:[ ]+80000517[ ]+auipc[ ]a0,0x80000
+[ ]+4:[ ]+80050513[ ]+addi[ ]a0,a0,-2048([^0-9].*)?
+[ ]+8:[ ]+7ffff517[ ]+auipc[ ]a0,0x7ffff
+[ ]+c:[ ]+7ff50513[ ]+addi[ ]a0,a0,2047([^0-9].*)?
+[ ]+10:[ ]+80000517[ ]+auipc[ ]a0,0x80000
+[ ]+14:[ ]+80050513[ ]+addi[ ]a0,a0,-2048([^0-9].*)?
+[ ]+18:[ ]+7ffff517[ ]+auipc[ ]a0,0x7ffff
+[ ]+1c:[ ]+7ff50513[ ]+addi[ ]a0,a0,2047([^0-9].*)?
+[ ]+20:[ ]+80000517[ ]+auipc[ ]a0,0x80000
+[ ]+24:[ ]+80050513[ ]+addi[ ]a0,a0,-2048([^0-9].*)?
+[ ]+28:[ ]+7ffff517[ ]+auipc[ ]a0,0x7ffff
+[ ]+2c:[ ]+7ff50513[ ]+addi[ ]a0,a0,2047([^0-9].*)?
--- /dev/null
+#as: -march=rv64i
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+0+ <\.text>:
+[ ]+0:[ ]+7ffff517[ ]+auipc[ ]a0,0x7ffff
+[ ]+4:[ ]+7ff50513[ ]+addi[ ]a0,a0,2047([^0-9].*)?
+[ ]+8:[ ]+80000517[ ]+auipc[ ]a0,0x80000
+[ ]+c:[ ]+80050513[ ]+addi[ ]a0,a0,-2048([^0-9].*)?
+[ ]+10:[ ]+7ffff517[ ]+auipc[ ]a0,0x7ffff
+[ ]+14:[ ]+7ff50513[ ]+addi[ ]a0,a0,2047([^0-9].*)?
+[ ]+18:[ ]+80000517[ ]+auipc[ ]a0,0x80000
+[ ]+1c:[ ]+80050513[ ]+addi[ ]a0,a0,-2048([^0-9].*)?
+[ ]+20:[ ]+7ffff517[ ]+auipc[ ]a0,0x7ffff
+[ ]+24:[ ]+7ff50513[ ]+addi[ ]a0,a0,2047([^0-9].*)?
+[ ]+28:[ ]+80000517[ ]+auipc[ ]a0,0x80000
+[ ]+2c:[ ]+80050513[ ]+addi[ ]a0,a0,-2048([^0-9].*)?
--- /dev/null
+ .option norelax
+
+ # Relative to the current instruction.
+
+1:
+ auipc a0, %pcrel_hi(.+0x7ffff7ff)
+ addi a0, a0, %pcrel_lo(1b)
+2:
+ auipc a0, %pcrel_hi(.-0x80000800)
+ addi a0, a0, %pcrel_lo(2b)
+
+ # Relative to local labels (all instructions occupy 4-bytes).
+
+3:
+ auipc a0, %pcrel_hi(4f+0x7ffff7ff-4)
+4:
+ addi a0, a0, %pcrel_lo(3b)
+5:
+ auipc a0, %pcrel_hi(6f-0x80000800-4)
+6:
+ addi a0, a0, %pcrel_lo(5b)
+
+7:
+ auipc a0, %pcrel_hi(6b+0x7ffff7ff+4)
+8:
+ addi a0, a0, %pcrel_lo(7b)
+9:
+ auipc a0, %pcrel_hi(8b-0x80000800+4)
+ addi a0, a0, %pcrel_lo(9b)