diff options
author | Jose E. Marchesi <jose.marchesi@oracle.com> | 2023-07-27 18:17:35 +0200 |
---|---|---|
committer | Jose E. Marchesi <jose.marchesi@oracle.com> | 2023-07-28 18:19:44 +0200 |
commit | 249d4715e41061b6bd2d26df20ae274e6478f972 (patch) | |
tree | ed3caa4b4c19c83c780084958869fadf6eb1a576 /gas/testsuite | |
parent | 07d8d4bd2ad213281be502d6e56c19e0269b8967 (diff) | |
download | gdb-249d4715e41061b6bd2d26df20ae274e6478f972.zip gdb-249d4715e41061b6bd2d26df20ae274e6478f972.tar.gz gdb-249d4715e41061b6bd2d26df20ae274e6478f972.tar.bz2 |
bpf: gas: support relaxation of V4 jump instructions
The BPF jump-always instruction (JA), like all other jump instructions
in the ISA, get a signed 16-bit displacement target argument denoted
in number of 64-bit words minus one. This can sometimes be overflown.
The BPF V4 ISA thus introduced support for a jump-always
instruction (JAL) that gets a signed 32-bit displacement instead.
This patch makes the BPF assembler to perform the following
relaxations when the disp16 field gets overflown, unless the option
-mno-relax is specified:
JA disp16 -> JAL disp32
Jxx disp16 -> Jxx +1; JA +1; JAL disp32
Documentation and tests added.
Tested in bpf-unknown-none.
gas/ChangeLog:
2023-07-28 Jose E. Marchesi <jose.marchesi@oracle.com>
PR gas/30690
* config/tc-bpf.c (struct bpf_insn): Add fields is_relaxable and
relaxed_exp.
(enum options): Add OPTION_NO_RELAX.
(md_longopts): Likewise for -mno-relax.
(do_relax): New global.
(md_parse_option): Handle OPTION_NO_RELAX.
(RELAX_BRANCH_ENCODE): Define.
(RELAX_BRANCH_P): Likewise.
(RELAX_BRANCH_LENGTH): Likewise.
(RELAX_BRANCH_CONST): Likewise.
(RELAX_BRANCH_UNCOND): Likewise.
(relaxed_branch_length): New function.
(md_estimate_size_before_relax): Likewise.
(read_insn_word): Likewise.
(encode_int16): Likewise.
(encode_int32): Likewise.
(write_insn_bytes): Likewise.
(md_convert_frag): Likewise.
(encode_insn): Likewise.
(install_insn_fixups): Likewise.
(add_fixed_insn): Likewise.
(add_relaxed_insn): Likewise.
(md_assemble): Move instruction encoding logic to the above
new functions.
* testsuite/gas/bpf/jump-relax-ja.d: New test.
* testsuite/gas/bpf/jump-relax-ja-be.d: Likewise.
* testsuite/gas/bpf/jump-relax-ja.s: And corresponding source.
* testsuite/gas/bpf/jump-relax-jump.d: New test.
* testsuite/gas/bpf/jump-relax-jump-be.d: Likewise.
* testsuite/gas/bpf/jump-relax-jump.s: And corresponding source.
* testsuite/gas/bpf/bpf.exp: Run new tests.
* doc/c-bpf.texi (BPF Options): Document -mno-relax.
Diffstat (limited to 'gas/testsuite')
-rw-r--r-- | gas/testsuite/gas/bpf/bpf.exp | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-ja-be.d | 19 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-ja.d | 19 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-ja.s | 20 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-jump.d | 25 | ||||
-rw-r--r-- | gas/testsuite/gas/bpf/jump-relax-jump.s | 17 |
6 files changed, 106 insertions, 0 deletions
diff --git a/gas/testsuite/gas/bpf/bpf.exp b/gas/testsuite/gas/bpf/bpf.exp index 1d683d5..6e6a000 100644 --- a/gas/testsuite/gas/bpf/bpf.exp +++ b/gas/testsuite/gas/bpf/bpf.exp @@ -40,6 +40,9 @@ if {[istarget bpf*-*-*]} { run_dump_test indcall-1 run_dump_test indcall-1-pseudoc + run_dump_test jump-relax-ja + run_dump_test jump-relax-jump + # Big-endian BPF tests run_dump_test call-be run_dump_test exit-be @@ -59,4 +62,7 @@ if {[istarget bpf*-*-*]} { run_dump_test atomic-v1-be run_dump_test atomic-be run_dump_test atomic-be-pseudoc + + run_dump_test jump-relax-ja-be + run_dump_test jump-relax-jump-be } diff --git a/gas/testsuite/gas/bpf/jump-relax-ja-be.d b/gas/testsuite/gas/bpf/jump-relax-ja-be.d new file mode 100644 index 0000000..08b85a9 --- /dev/null +++ b/gas/testsuite/gas/bpf/jump-relax-ja-be.d @@ -0,0 +1,19 @@ +#as: -EB -mdialect=normal +#objdump: -dr -M dec +#source: jump-relax-ja.s +#name: Relaxation of unconditional branch (JA) instructions, big-endian + +.*: +file format .*bpf.* + +Disassembly of section .text: + +0+ <.*>: + 0: 05 00 80 00 00 00 00 00 ja -32768 + 8: 05 00 7f ff 00 00 00 00 ja 32767 + 10: 05 00 ff fd 00 00 00 00 ja -3 + 18: 05 00 00 00 00 00 00 00 ja 0 + 18: R_BPF_GNU_64_16 undefined + 20: 06 00 00 00 ff ff 7f ff jal -32769 + 28: 06 00 00 00 00 00 80 00 jal 32768 + 30: 06 00 00 00 00 00 80 01 jal 32769 + 38: 06 00 00 00 00 00 80 01 jal 32769 diff --git a/gas/testsuite/gas/bpf/jump-relax-ja.d b/gas/testsuite/gas/bpf/jump-relax-ja.d new file mode 100644 index 0000000..6b50973 --- /dev/null +++ b/gas/testsuite/gas/bpf/jump-relax-ja.d @@ -0,0 +1,19 @@ +#as: -EL -mdialect=normal +#objdump: -dr -M dec +#source: jump-relax-ja.s +#name: Relaxation of unconditional branch (JA) instructions + +.*: +file format .*bpf.* + +Disassembly of section .text: + +0+ <.*>: + 0: 05 00 00 80 00 00 00 00 ja -32768 + 8: 05 00 ff 7f 00 00 00 00 ja 32767 + 10: 05 00 fd ff 00 00 00 00 ja -3 + 18: 05 00 00 00 00 00 00 00 ja 0 + 18: R_BPF_GNU_64_16 undefined + 20: 06 00 00 00 ff 7f ff ff jal -32769 + 28: 06 00 00 00 00 80 00 00 jal 32768 + 30: 06 00 00 00 01 80 00 00 jal 32769 + 38: 06 00 00 00 01 80 00 00 jal 32769 diff --git a/gas/testsuite/gas/bpf/jump-relax-ja.s b/gas/testsuite/gas/bpf/jump-relax-ja.s new file mode 100644 index 0000000..8be3d7a --- /dev/null +++ b/gas/testsuite/gas/bpf/jump-relax-ja.s @@ -0,0 +1,20 @@ + ;; The following two instructions have constant targets that + ;; fix in the JA 16-bit signed displacement operand. These + ;; are not relaxed. +1: ja -32768 + ja 32767 + ;; The following instruction refers to a defined symbol that + ;; is on reach, so it should not be relaxed. + ja 1b + ;; The following instruction has an undefined symbol as a + ;; target. It is not to be relaxed. + ja undefined + 10 + ;; The following instructions are relaxed to JAL instructions + ;; so they can fit their displacements. + ja -32769 + ja 32768 + ;; The following instructions refer to a defined symbol that + ;; is not on reach. They shall be relaxed to a JAL. + ja tail + tail = .text + 262160 + ja tail diff --git a/gas/testsuite/gas/bpf/jump-relax-jump.d b/gas/testsuite/gas/bpf/jump-relax-jump.d new file mode 100644 index 0000000..cd46ea7 --- /dev/null +++ b/gas/testsuite/gas/bpf/jump-relax-jump.d @@ -0,0 +1,25 @@ +#as: -EL -mdialect=normal +#objdump: -dr -M dec +#source: jump-relax-jump.s +#name: Relaxation of conditional branch instructions + +.*: +file format .*bpf.* + +Disassembly of section .text: + +0+ <.*>: + 0: 1d 21 00 80 00 00 00 00 jeq %r1,%r2,-32768 + 8: ad 21 ff 7f 00 00 00 00 jlt %r1,%r2,32767 + 10: bd 21 fd ff 00 00 00 00 jle %r1,%r2,-3 + 18: 3d 21 01 00 00 00 00 00 jge %r1,%r2,1 + 20: 05 00 01 00 00 00 00 00 ja 1 + 28: 06 00 00 00 ff 7f ff ff jal -32769 + 30: 2d 21 01 00 00 00 00 00 jgt %r1,%r2,1 + 38: 05 00 01 00 00 00 00 00 ja 1 + 40: 06 00 00 00 00 80 00 00 jal 32768 + 48: 1d 21 01 00 00 00 00 00 jeq %r1,%r2,1 + 50: 05 00 01 00 00 00 00 00 ja 1 + 58: 06 00 00 00 01 80 00 00 jal 32769 + 60: 2d 21 01 00 00 00 00 00 jgt %r1,%r2,1 + 68: 05 00 01 00 00 00 00 00 ja 1 + 70: 06 00 00 00 01 80 00 00 jal 32769 diff --git a/gas/testsuite/gas/bpf/jump-relax-jump.s b/gas/testsuite/gas/bpf/jump-relax-jump.s new file mode 100644 index 0000000..dabbab8 --- /dev/null +++ b/gas/testsuite/gas/bpf/jump-relax-jump.s @@ -0,0 +1,17 @@ + ;; The following two instructions have constant targets that + ;; fix in the jump 16-bit signed displacement operand. +1: jeq %r1, %r2, -32768 + jlt %r1, %r2, 32767 + ;; The following instruction refers to a defined symbol that + ;; is on reach, so it should not be relaxed. + jle %r1, %r2, 1b + ;; The following instructions are relaxed to sequences + ;; involving unconditional jumps, so they can fi their + ;; displacements. + jge %r1, %r2, -32769 + jgt %r1, %r2, 32768 + ;; The following instructions refer to a defined symbol that + ;; is not on reach. They shall be relaxed. + jeq %r1, %r2, tail + tail = .text + 262160 + jgt %r1, %r2, tail |