On Sat, Jul 29, 2023 at 1:29 AM Jose E. Marchesi <jose.marchesi@xxxxxxxxxx> wrote: > > > > On Fri, Jul 28, 2023 at 11:01 AM Jose E. Marchesi > > <jose.marchesi@xxxxxxxxxx> wrote: > >> > >> > >> >> On 7/28/23 9:41 AM, Jose E. Marchesi wrote: > >> >>> Hello. > >> >>> Just a heads up regarding the new BPF V4 instructions and their > >> >>> support > >> >>> in the GNU Toolchain. > >> >>> V4 sdiv/smod instructions > >> >>> Binutils has been updated to use the V4 encoding of these > >> >>> instructions, which used to be part of the xbpf testing dialect used > >> >>> in GCC. GCC generates these instructions for signed division when > >> >>> -mcpu=v4 or higher. > >> >>> V4 sign-extending register move instructions > >> >>> V4 signed load instructions > >> >>> V4 byte swap instructions > >> >>> Supported in assembler, disassembler and linker. GCC generates > >> >>> these > >> >>> instructions when -mcpu=v4 or higher. > >> >>> V4 32-bit unconditional jump instruction > >> >>> Supported in assembler and disassembler. GCC doesn't generate > >> >>> that > >> >>> instruction. > >> >>> However, the assembler has been expanded in order to perform the > >> >>> following relaxations when the disp16 field of a jump instruction is > >> >>> known at assembly time, and is overflown, unless -mno-relax is > >> >>> specified: > >> >>> JA disp16 -> JAL disp32 > >> >>> Jxx disp16 -> Jxx +1; JA +1; JAL disp32 > >> >>> Where Jxx is one of the conditional jump instructions such as > >> >>> jeq, > >> >>> jlt, etc. > >> >> > >> >> Sounds great. The above 'JA/Jxx disp16' transformation matches > >> >> what llvm did as well. > >> > > >> > Not by chance ;) > >> > > >> > Now what is pending in binutils is to relax these jumps in the linker as > >> > well. But it is very low priority, compared to get these kernel > >> > selftests building and running. So it will happen, but probably not > >> > anytime soon. > >> > >> By the way, for doing things like that (further object transformations > >> by linkers and the like) we will need to have the ELF files annotated > >> with: > >> > >> - The BPF cpu version the object was compiled for: v1, v2, v3, v4, and > >> > >> - Individual flags specifying the BPF cpu capabilities (alu32, bswap, > >> jmp32, etc) required/expected by the code in the object. > >> > >> Note it is interesting to being able to denote both, for flexibility. > >> > >> There are 32 bits available for machine-specific flags in e_flags, which > >> are commonly used for this purpose by other arches. For BPF I would > >> suggest something like: > >> > >> #define EF_BPF_ALU32 0x00000001 > >> #define EF_BPF_JMP32 0x00000002 > >> #define EF_BPF_BSWAP 0x00000004 > >> #define EF_BPF_SDIV 0x00000008 > >> #define EF_BPF_CPUVER 0x00FF0000 > > > > Interesting idea. I don't mind, but what are we going to do with this info? > > I cannot think of anything useful libbpf could do with it. > > For other archs such flags make sense, since disasm of everything > > to discover properties is hard. For BPF we will parse all insns anyway, > > so additional info in ELF doesn't give any additional insight. > > I mainly had link-time relaxation in mind. The linker needs to know > what instructions are available (JMP32 or not) in order to decide what > to relax, and to what. But the assembler has little choice when the jump target is >16bits. It can use jmp32 or error. I guess you're proposing to encode this e_flags in the text of asm ? Special asm directive that will force asm to error or use jmp32? > Also as you mention the disassembler can look in the object to determine > which instructions shall be recognized and with insructions shall be > reported as <unknown>. Right now it is necessary to pass an explicit > option to the assembler, and the default is v4. Disambiguating between unknown and exact insn kinda makes sense for disasm. For assembler it's kinda weird. If text says 'sdiv' the asm should emit binary code for it regardless of asm directive. It seems e_flags can only be emitted by assembler. Like if it needs to use jmp32 it will add EF_BPF_JMP32. Still feels that we can live without these flags, but not a bad addition. As far as flag names, let's use EF_ prefix. I think it's more canonical. And single 0xF is probably enough for cpu ver.