On Sun, Feb 26, 2023 at 10:31 AM Yonghong Song <yhs@xxxxxxxx> wrote: > > Over the past, there are some discussions to extend bpf > instruction ISA to accommodate some new use cases or > fix some potential issues. These new instructions will > be included in new cpu flavor -mcpu=v4. > > The following are the proposal to add new instructions in 6 > different categories. The proposal is a little bit rough. > You can find bpf insn background information in > Documentation/bpf/instruction-set.rst. Compared to previous > proposal (v1) in > > https://lore.kernel.org/bpf/01515302-c37d-2ee5-c950-2f556a4caad0@xxxxxxxx/ > there are two changes: > . for sign extend load, removing alu32_mode differentiator > since alu32_mode is only a compiler asm syntax mechanism in > this case, and not involved in insn encoding. > . for sign extend mov, there is no support for sign extend > moving an imm to a register. > > The corresponding llvm implementation is at > https://reviews.llvm.org/D144829 > > The following is the proposal details. > > SDIV/SMOD (signed div and mod) > ============================== > > bpf already has unsigned DIV and MOD. They are encoded as > > insn code(4 bits) source(1 bit) instruction class(3 bit) off(16 bits) > DIV 0x3 0/1 BPF_ALU/BPF_ALU64 0 > MOD 0x9 0/1 BPF_ALU/BPF_ALU64 0 > > The current 'code' field only has two value left, 0xe and 0xf. > gcc used these two values (0xe and 0xf) for SDIV and SMOD. > But using these two values takes up all 'code' space and makes > future extension hard. > > Here, I propose to encode SDIV/SMOD like below: > > insn code(4 bits) source(1 bit) instruction class(3 bit) off(16 bits) > DIV 0x3 0/1 BPF_ALU/BPF_ALU64 1 > MOD 0x9 0/1 BPF_ALU/BPF_ALU64 1 > > Basically, we reuse the same 'code' value but changing 'off' from 0 to 1 > to indicate signed div/mod. > > Sign extend load > ================ > > Currently llvm generated normal load instructions are encoded like below. > > mode(3 bits) size(2 bits) instruction class(3 bits) > BPF_MEM (0x3) 8/16/32/64 BPF_LDX > > For mode, existing used values are 0x0, 0x1, 0x2, 0x3, 0x6. > The proposal is to use mod value 0x4 to encode sign extend loads. > > mode(3 bits) size(2 bits) instruction class(3 bits) > BPF_SMEM (0x4) 8/16/32 BPF_LDX can we define BPF_SMEM for 64-bit for completeness here? I can see some situations where, for example, libbpf needs to switch between BPF_MEM/BPF_SMEM based on CO-RE relocation and target type, and not having to special-case 64-bit case would be nice. It's minor, but so seems to be to support sign-extended 64-bit load (which would be equivalent to non-sign-extended, of course). > > Sign extend register mov > ======================== > > Current BPF_MOV insn is encoded as > insn code(4 bits) source(1 bit) instruction class(3 bit) off(16 bits) > MOV 0xb 0/1 BPF_ALU/BPF_ALU64 0 > > Let us support sign extended move insn as defined below: > > insn code(4 bits) source(1 bit) instruction class(3 bit) off(16 bits) > MOVS 0xb 1 BPF_ALU 8/16 > MOVS 0xb 1 BPF_ALU64 8/16/32 will this be literal 8, 16, 32 decimal values or similarly to BPF_{B,H,W,DW} we'll just have values 0, 1, 2, 3 to represent 8, 16, 32, 64? Also, a similar question about uniformly supporting 32 for BPF_ALU and 64 for BPF_ALU64? > > In the above sign extended mov instruction, 'off' represents the 'size'. > For example, if BPF_ALU class, and 'off' is 8, which means sign > extend a 8-bit value (in register) to a 32-bit value. If BPF_ALU64 class, > the same 8-bit value will sign extend to a 64-bit value. > [...]