https://sourceware.org/bugzilla/show_bug.cgi?id=22598
--- Comment #8 from Jim Wilson <wilson at gcc dot gnu.org> --- Branches work the same way on RISC-V as they do on MIPS. Here is a mips example to show that. rohan:2123$ cat tmp.s _start: .skip 4096 beq $6, $7, 100 bne $4, $5, 4096 .skip 92 _end_label: rohan:2124$ ./as-new -o tmp.o tmp.s rohan:2125$ ../binutils/objdump -dr tmp.o tmp.o: file format elf32-ntradbigmips Disassembly of section .text: 00000000 <_start>: ... 1000: 10c70019 beq a2,a3,1068 <_start+0x1068> 1000: R_MIPS_PC16 *ABS*+0x60 1004: 00000000 nop 1008: 14850400 bne a0,a1,200c <_end_label+0xfa0> 1008: R_MIPS_PC16 *ABS*+0xffc 100c: 00000000 nop ... 0000106c <_end_label>: 106c: 00000000 nop rohan:2126$ ../ld-new/ld tmp.o bash: ../ld-new/ld: No such file or directory rohan:2127$ ../ld/ld-new tmp.o ../ld/ld-new: warning: cannot find entry symbol __start; defaulting to 00000000100000d0 tmp.o: In function `_start': (.text+0x1000): relocation truncated to fit: R_MIPS_PC16 against `*UND*' (.text+0x1008): relocation truncated to fit: R_MIPS_PC16 against `*UND*' rohan:2128$ Note that a branch to 100 is a request to branch to the absolute address 100, which gives a linker error because that ends up out-of-range. If I use the . +/- immediate syntax, I get the result you want: branches to offsets from the current address. rohan:2129$ cat tmp.s _start: .skip 4096 beq $6, $7, .+100 bne $4, $5, .-4096 .skip 92 _end_label: rohan:2130$ ./as-new -o tmp.o tmp.s rohan:2131$ ../ld/ld-new tmp.o ../ld/ld-new: warning: cannot find entry symbol __start; defaulting to 00000000100000d0 rohan:2132$ ../binutils/objdump -dr a.out a.out: file format elf32-ntradbigmips Disassembly of section .text: 100000d0 <_ftext>: ... 100010d0: 10c70018 beq a2,a3,10001134 <_ftext+0x1064> 100010d4: 00000000 nop 100010d8: 1485fbff bne a0,a1,100000d8 <_ftext+0x8> 100010dc: 00000000 nop ... 1000113c <_end_label>: 1000113c: 00000000 nop rohan:2133$ This handling of constant immediates is the same as how we handle labels. If you say bne a4, a5, _start+4 then _start+4 is an absolute address to branch to. It is not a value to add to the current PC to generate an address. It is not an offset to be inserted directly into the instruction. It is a value to be converted into an offset by subtracting the current PC. So immediates are being handled exactly the same as labels. The only difference with RISC-V is that we relax branches by default, and hence you get these branch sequences instead of a single branch instruction. If you provide an address that the assembler can detect is safe at assembly time, then you can get a single branch. You can do that by using the . +/- immediate syntax, or by using a label close to the branch instruction. Otherwise, the assembler must emit a branch sequence that may be relaxed at link time. -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils