llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.47k stars 11.77k forks source link

[BPF] BPF Assembly Parser missing Instructions #55192

Open derkro99 opened 2 years ago

derkro99 commented 2 years ago

Hello,

Upon trying to assemble an extended version of the code found at https://qmonnet.github.io/whirl-offload/2020/04/12/llvm-ebpf-asm , i encountered:

instTest.s:8:8: error: invalid operand for instruction 
    r1 %=5 #BPF_MOD
       ^
instTest.s:9:9: error: unexpected token
    r1 =~r1 #BPF_NEG
        ^

I assembled the following code with llvm-mc -triple bpf -filetype=obj -o bpf.o instTest.s:

#file: instTest.s
    .text
    .globl  func                    # -- Begin function func
    .p2align    3
func:                                   # @func
# %bb.0:
    r1 = 0
    *(u32 *)(r10 - 4) = r1
        r1 %=5
        r1 =~r1
    r0 = r1
    exit
                                        # -- End function

    r0 = 3

I am using Debian LLVM version 13.0.1

Since all the other code i tested follows the contents of the description column at https://www.kernel.org/doc/html/latest/bpf/instruction-set.html i expected these two instruction to be the same. While looking for solutions to this problem, i noticed, that these two instructions are missing from https://github.com/llvm/llvm-project/blob/09c2b7c35af8c4bad39f03e9f60df8bd07323028/llvm/test/MC/BPF/insn-unit.s#L118

Please correct me if I am wrong, but I think, that the BPF_MOD and BPF_NEG are currently not supported by the instruction Parser.

yonghong-song commented 2 years ago

BPF backend actually supports BPF_NEG instruction.

let Constraints = "$dst = $src", isAsCheapAsAMove = 1 in {
  def NEG_64: NEG_RR<BPF_ALU64, BPF_NEG, (outs GPR:$dst), (ins GPR:$src),
                     "$dst = -$src",
                     [(set GPR:$dst, (ineg i64:$src))]>;
  def NEG_32: NEG_RR<BPF_ALU, BPF_NEG, (outs GPR32:$dst), (ins GPR32:$src),
                     "$dst = -$src",
                     [(set GPR32:$dst, (ineg i32:$src))]>;
}

The syntax is "r1 = -r1" instead of "r1 = ~r1". We may have documentation issue somewhere, I think.