bpf: add xBPF ISA

This patch adds support for xBPF, another ISA targetting the BPF
virtual architecture. For now, the primary difference between eBPF
and xBPF is that xBPF supports indirect calls through the
'call %reg' form of the call instruction.

bfd/
	* archures.c (bfd_mach_xbpf): Define.
	* bfd-in2.h: Regenerate.
	* cpu-bpf.c (bfd_xbpf_arch) New.
	(bfd_bpf_arch) Update next in list field to point to xbpf arch.

cpu/
	* bpf.cpu (arch bpf): Add xbpf mach and isas.
	(define-xbpf-isa) New pmacro.
	(all-isas) Add xbpfle,xbpfbe.
	(endian-isas): New pmacro.
	(mach xbpf): New.
	(model xbpf-def): Likewise.
	(h-gpr): Add xbpf mach.
	(f-dstle, f-srcle, dstle, srcle): Add xbpfle isa.
	(f-dstbe, f-srcbe, dstbe, srcbe): Add xbpfbe isa.
	(define-alu-insn-un): Use new endian-isas pmacro.
	(define-alu-insn-bin, define-alu-insn-mov): Likewise.
	(define-endian-insn, define-lddw): Likewise.
	(dlind, dxli, dxsi, dsti): Likewise.
	(define-cond-jump-insn, define-call-insn): Likewise.
	(define-atomic-insns): Likewise.

gas/
	* config/tc-bpf.c: Add option -mxbpf to select xbpf isa.
	* testsuite/gas/bpf/indcall-1.d: New file.
	* testsuite/gas/bpf/indcall-1.s: Likewise.
	* testsuite/gas/bpf/indcall-bad-1.l: Likewise.
	* testsuite/gas/bpf/indcall-bad-1.s: Likewise.
	* testsuite/gas/bpf/bpf.exp: Run new tests.

opcodes/
	* bpf-desc.c: Regenerate.
	* bpf-desc.h: Likewise.
	* bpf-opc.c: Likewise.
	* bpf-opc.h: Likewise.
	* disassemble.c (disassemble_init_for_target): Set bits for xBPF
	ISA when appropriate.
This commit is contained in:
David Faust
2020-08-26 15:39:00 +02:00
committed by Jose E. Marchesi
parent 37f628c34d
commit 4449c81a85
19 changed files with 543 additions and 323 deletions

View File

@ -1,3 +1,10 @@
2020-08-26 David Faust <david.faust@oracle.com>
* archures.c (bfd_mach_xbpf): Define.
* bfd-in2.h: Regenerate.
* cpu-bpf.c (bfd_xbpf_arch) New.
(bfd_bpf_arch) Update next in list field to point to xbpf arch.
2020-08-26 Alan Modra <amodra@gmail.com> 2020-08-26 Alan Modra <amodra@gmail.com>
* archures.c (bfd_mach_ck860): Define. * archures.c (bfd_mach_ck860): Define.

View File

@ -411,6 +411,7 @@ DESCRIPTION
.#define bfd_mach_iq10 2 .#define bfd_mach_iq10 2
. bfd_arch_bpf, {* Linux eBPF. *} . bfd_arch_bpf, {* Linux eBPF. *}
.#define bfd_mach_bpf 1 .#define bfd_mach_bpf 1
.#define bfd_mach_xbpf 2
. bfd_arch_epiphany, {* Adapteva EPIPHANY. *} . bfd_arch_epiphany, {* Adapteva EPIPHANY. *}
.#define bfd_mach_epiphany16 1 .#define bfd_mach_epiphany16 1
.#define bfd_mach_epiphany32 2 .#define bfd_mach_epiphany32 2

View File

@ -1811,6 +1811,7 @@ enum bfd_architecture
#define bfd_mach_iq10 2 #define bfd_mach_iq10 2
bfd_arch_bpf, /* Linux eBPF. */ bfd_arch_bpf, /* Linux eBPF. */
#define bfd_mach_bpf 1 #define bfd_mach_bpf 1
#define bfd_mach_xbpf 2
bfd_arch_epiphany, /* Adapteva EPIPHANY. */ bfd_arch_epiphany, /* Adapteva EPIPHANY. */
#define bfd_mach_epiphany16 1 #define bfd_mach_epiphany16 1
#define bfd_mach_epiphany32 2 #define bfd_mach_epiphany32 2

View File

@ -23,6 +23,26 @@
#include "bfd.h" #include "bfd.h"
#include "libbfd.h" #include "libbfd.h"
static const bfd_arch_info_type bfd_xbpf_arch =
{
64, /* Bits per word. */
64, /* Bits per address. */
8, /* Bits per byte. */
bfd_arch_bpf, /* Architecture. */
bfd_mach_xbpf, /* Machine. */
"bpf", /* Architecture name. */
"xbpf", /* Machine name. */
3, /* Section align power. */
FALSE, /* The default ? */
bfd_default_compatible, /* Architecture comparison fn. */
bfd_default_scan, /* String to architecture convert fn. */
bfd_arch_default_fill, /* Default fill. */
NULL, /* Next in list. */
0 /* Maximum offset of a reloc from the start of an insn. */
};
const bfd_arch_info_type bfd_bpf_arch = const bfd_arch_info_type bfd_bpf_arch =
{ {
64, /* Bits per word. */ 64, /* Bits per word. */
@ -37,6 +57,6 @@ const bfd_arch_info_type bfd_bpf_arch =
bfd_default_compatible, /* Architecture comparison fn. */ bfd_default_compatible, /* Architecture comparison fn. */
bfd_default_scan, /* String to architecture convert fn. */ bfd_default_scan, /* String to architecture convert fn. */
bfd_arch_default_fill, /* Default fill. */ bfd_arch_default_fill, /* Default fill. */
NULL, /* Next in list. */ &bfd_xbpf_arch, /* Next in list. */
0 /* Maximum offset of a reloc from the start of an insn. */ 0 /* Maximum offset of a reloc from the start of an insn. */
}; };

View File

@ -1,3 +1,21 @@
2020-08-26 David Faust <david.faust@oracle.com>
* bpf.cpu (arch bpf): Add xbpf mach and isas.
(define-xbpf-isa) New pmacro.
(all-isas) Add xbpfle,xbpfbe.
(endian-isas): New pmacro.
(mach xbpf): New.
(model xbpf-def): Likewise.
(h-gpr): Add xbpf mach.
(f-dstle, f-srcle, dstle, srcle): Add xbpfle isa.
(f-dstbe, f-srcbe, dstbe, srcbe): Add xbpfbe isa.
(define-alu-insn-un): Use new endian-isas pmacro.
(define-alu-insn-bin, define-alu-insn-mov): Likewise.
(define-endian-insn, define-lddw): Likewise.
(dlind, dxli, dxsi, dsti): Likewise.
(define-cond-jump-insn, define-call-insn): Likewise.
(define-atomic-insns): Likewise.
2020-07-04 Nick Clifton <nickc@redhat.com> 2020-07-04 Nick Clifton <nickc@redhat.com>
Binutils 2.35 branch created. Binutils 2.35 branch created.

View File

@ -36,8 +36,8 @@
;; It is confusing that the simulator follows the emulated memory ;; It is confusing that the simulator follows the emulated memory
;; access conventions for fetching instructions by pieces... ;; access conventions for fetching instructions by pieces...
(default-alignment unaligned) (default-alignment unaligned)
(machs bpf) (machs bpf xbpf)
(isas ebpfle ebpfbe)) (isas ebpfle ebpfbe xbpfle xbpfbe))
;;;; The ISAs ;;;; The ISAs
@ -105,7 +105,22 @@
(define-bpf-isa le) (define-bpf-isa le)
(define-bpf-isa be) (define-bpf-isa be)
(define-pmacro all-isas () (ISA ebpfle,ebpfbe)) (define-pmacro (define-xbpf-isa x-endian)
(define-isa
(name (.sym xbpf x-endian))
(comment "The xBPF instruction set")
(default-insn-word-bitsize 64)
(default-insn-bitsize 64)
(base-insn-bitsize 64)))
(define-xbpf-isa le)
(define-xbpf-isa be)
(define-pmacro all-isas () (ISA ebpfle,ebpfbe,xbpfle,xbpfbe))
(define-pmacro xbpf-isas () (ISA xbpfle,xbpfbe))
(define-pmacro (endian-isas x-endian)
((ISA (.sym ebpf x-endian) (.sym xbpf x-endian))))
;;;; Hardware Hierarchy ;;;; Hardware Hierarchy
@ -113,10 +128,10 @@
;; bpf architecture ;; bpf architecture
;; | ;; |
;; bpfbf cpu-family ;; bpfbf cpu-family
;; | ;; / \
;; bpf machine ;; bpf xbpf machine
;; | ;; | |
;; bpf-def model ;; bpf-def xbpf-def model
(define-cpu (define-cpu
(name bpfbf) (name bpfbf)
@ -143,6 +158,25 @@
() ; profile action (default) () ; profile action (default)
)) ))
(define-mach
(name xbpf)
(comment "Experimental BPF")
(cpu bpfbf)
(isas ebpfle ebpfbe xbpfle xbpfbe))
(define-model
(name xbpf-def)
(comment "xBPF default model")
(mach xbpf)
(unit u-exec "execution unit" ()
1 ; issue
1 ; done
() ; state
() ; inputs
() ; outputs
() ; profile action (default)
))
;;;; Hardware Elements ;;;; Hardware Elements
;; eBPF programs can access 10 general-purpose registers which are ;; eBPF programs can access 10 general-purpose registers which are
@ -151,7 +185,7 @@
(define-hardware (define-hardware
(name h-gpr) (name h-gpr)
(comment "General Purpose Registers") (comment "General Purpose Registers")
(attrs all-isas (MACH bpf)) (attrs all-isas (MACH bpf xbpf))
(type register DI (16)) (type register DI (16))
(indices keyword "%" (indices keyword "%"
;; XXX the frame pointer fp is read-only, so it should ;; XXX the frame pointer fp is read-only, so it should
@ -259,11 +293,11 @@
;; NOT use registers, where endianness is irrelevant i.e. f-regs is a ;; NOT use registers, where endianness is irrelevant i.e. f-regs is a
;; constant 0 opcode. ;; constant 0 opcode.
(dwf f-dstle "eBPF dst register field" ((ISA ebpfle)) 8 8 3 4 UINT) (dwf f-dstle "eBPF dst register field" ((ISA ebpfle xbpfle)) 8 8 3 4 UINT)
(dwf f-srcle "eBPF source register field" ((ISA ebpfle)) 8 8 7 4 UINT) (dwf f-srcle "eBPF source register field" ((ISA ebpfle xbpfle)) 8 8 7 4 UINT)
(dwf f-dstbe "eBPF dst register field" ((ISA ebpfbe)) 8 8 7 4 UINT) (dwf f-dstbe "eBPF dst register field" ((ISA ebpfbe xbpfbe)) 8 8 7 4 UINT)
(dwf f-srcbe "eBPF source register field" ((ISA ebpfbe)) 8 8 3 4 UINT) (dwf f-srcbe "eBPF source register field" ((ISA ebpfbe xbpfbe)) 8 8 3 4 UINT)
(dwf f-regs "eBPF registers field" (all-isas) 8 8 7 8 UINT) (dwf f-regs "eBPF registers field" (all-isas) 8 8 7 8 UINT)
@ -303,11 +337,11 @@
;; A couple of source and destination register operands are defined ;; A couple of source and destination register operands are defined
;; for each ISA: ebpfle and ebpfbe. ;; for each ISA: ebpfle and ebpfbe.
(dno dstle "destination register" ((ISA ebpfle)) h-gpr f-dstle) (dno dstle "destination register" ((ISA ebpfle xbpfle)) h-gpr f-dstle)
(dno srcle "source register" ((ISA ebpfle)) h-gpr f-srcle) (dno srcle "source register" ((ISA ebpfle xbpfle)) h-gpr f-srcle)
(dno dstbe "destination register" ((ISA ebpfbe)) h-gpr f-dstbe) (dno dstbe "destination register" ((ISA ebpfbe xbpfbe)) h-gpr f-dstbe)
(dno srcbe "source register" ((ISA ebpfbe)) h-gpr f-srcbe) (dno srcbe "source register" ((ISA ebpfbe xbpfbe)) h-gpr f-srcbe)
;; Jump instructions have a 16-bit PC-relative address. ;; Jump instructions have a 16-bit PC-relative address.
;; CALL instructions have a 32-bit PC-relative address. ;; CALL instructions have a 32-bit PC-relative address.
@ -378,7 +412,7 @@
x-endian x-mode x-semop) x-endian x-mode x-semop)
(dni (.sym x-basename x-suffix x-endian) (dni (.sym x-basename x-suffix x-endian)
(.str x-basename x-suffix) (.str x-basename x-suffix)
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str x-basename x-suffix " $dst" x-endian) (.str x-basename x-suffix " $dst" x-endian)
(+ (f-imm32 0) (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) (+ (f-imm32 0) (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
x-op-class OP_SRC_K x-op-code) x-op-class OP_SRC_K x-op-code)
@ -391,7 +425,7 @@
;; dst = dst OP immediate ;; dst = dst OP immediate
(dni (.sym x-basename x-suffix "i" x-endian) (dni (.sym x-basename x-suffix "i" x-endian)
(.str x-basename x-suffix " immediate") (.str x-basename x-suffix " immediate")
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str x-basename x-suffix " $dst" x-endian ",$imm32") (.str x-basename x-suffix " $dst" x-endian ",$imm32")
(+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) (+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
x-op-class OP_SRC_K x-op-code) x-op-class OP_SRC_K x-op-code)
@ -400,7 +434,7 @@
;; dst = dst OP src ;; dst = dst OP src
(dni (.sym x-basename x-suffix "r" x-endian) (dni (.sym x-basename x-suffix "r" x-endian)
(.str x-basename x-suffix " register") (.str x-basename x-suffix " register")
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str x-basename x-suffix " $dst" x-endian ",$src" x-endian) (.str x-basename x-suffix " $dst" x-endian ",$src" x-endian)
(+ (f-imm32 0) (f-offset16 0) (.sym src x-endian) (.sym dst x-endian) (+ (f-imm32 0) (f-offset16 0) (.sym src x-endian) (.sym dst x-endian)
x-op-class OP_SRC_X x-op-code) x-op-class OP_SRC_X x-op-code)
@ -413,7 +447,7 @@
(begin (begin
(dni (.sym mov x-suffix "i" x-endian) (dni (.sym mov x-suffix "i" x-endian)
(.str mov x-suffix " immediate") (.str mov x-suffix " immediate")
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str x-basename x-suffix " $dst" x-endian ",$imm32") (.str x-basename x-suffix " $dst" x-endian ",$imm32")
(+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) (+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
x-op-class OP_SRC_K x-op-code) x-op-class OP_SRC_K x-op-code)
@ -421,7 +455,7 @@
()) ())
(dni (.sym mov x-suffix "r" x-endian) (dni (.sym mov x-suffix "r" x-endian)
(.str mov x-suffix " register") (.str mov x-suffix " register")
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str x-basename x-suffix " $dst" x-endian ",$src" x-endian) (.str x-basename x-suffix " $dst" x-endian ",$src" x-endian)
(+ (f-imm32 0) (f-offset16 0) (.sym src x-endian) (.sym dst x-endian) (+ (f-imm32 0) (f-offset16 0) (.sym src x-endian) (.sym dst x-endian)
x-op-class OP_SRC_X x-op-code) x-op-class OP_SRC_X x-op-code)
@ -483,7 +517,7 @@
(define-pmacro (define-endian-insn x-suffix x-op-src x-endian) (define-pmacro (define-endian-insn x-suffix x-op-src x-endian)
(dni (.sym "end" x-suffix x-endian) (dni (.sym "end" x-suffix x-endian)
(.str "end" x-suffix " register") (.str "end" x-suffix " register")
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str "end" x-suffix " $dst" x-endian ",$endsize") (.str "end" x-suffix " $dst" x-endian ",$endsize")
(+ (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) endsize (+ (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) endsize
OP_CLASS_ALU x-op-src OP_CODE_END) OP_CLASS_ALU x-op-src OP_CODE_END)
@ -508,7 +542,7 @@
(define-pmacro (define-lddw x-endian) (define-pmacro (define-lddw x-endian)
(dni (.sym lddw x-endian) (dni (.sym lddw x-endian)
(.str "lddw" x-endian) (.str "lddw" x-endian)
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str "lddw $dst" x-endian ",$imm64") (.str "lddw $dst" x-endian ",$imm64")
(+ imm64 (f-offset16 0) ((.sym f-src x-endian) 0) (+ imm64 (f-offset16 0) ((.sym f-src x-endian) 0)
(.sym dst x-endian) (.sym dst x-endian)
@ -557,7 +591,7 @@
(define-pmacro (dlind x-suffix x-size x-endian x-smode) (define-pmacro (dlind x-suffix x-size x-endian x-smode)
(dni (.sym "ldind" x-suffix x-endian) (dni (.sym "ldind" x-suffix x-endian)
(.str "ldind" x-suffix) (.str "ldind" x-suffix)
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str "ldind" x-suffix " $src" x-endian ",$imm32") (.str "ldind" x-suffix " $src" x-endian ",$imm32")
(+ imm32 (f-offset16 0) ((.sym f-dst x-endian) 0) (.sym src x-endian) (+ imm32 (f-offset16 0) ((.sym f-dst x-endian) 0) (.sym src x-endian)
OP_CLASS_LD OP_MODE_IND (.sym OP_SIZE_ x-size)) OP_CLASS_LD OP_MODE_IND (.sym OP_SIZE_ x-size))
@ -598,7 +632,7 @@
(define-pmacro (dxli x-basename x-suffix x-size x-endian x-mode) (define-pmacro (dxli x-basename x-suffix x-size x-endian x-mode)
(dni (.sym x-basename x-suffix x-endian) (dni (.sym x-basename x-suffix x-endian)
(.str x-basename x-suffix) (.str x-basename x-suffix)
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str x-basename x-suffix " $dst" x-endian ",[$src" x-endian "+$offset16]") (.str x-basename x-suffix " $dst" x-endian ",[$src" x-endian "+$offset16]")
(+ (f-imm32 0) offset16 (.sym src x-endian) (.sym dst x-endian) (+ (f-imm32 0) offset16 (.sym src x-endian) (.sym dst x-endian)
OP_CLASS_LDX (.sym OP_SIZE_ x-size) OP_MODE_MEM) OP_CLASS_LDX (.sym OP_SIZE_ x-size) OP_MODE_MEM)
@ -610,7 +644,7 @@
(define-pmacro (dxsi x-basename x-suffix x-size x-endian x-mode) (define-pmacro (dxsi x-basename x-suffix x-size x-endian x-mode)
(dni (.sym x-basename x-suffix x-endian) (dni (.sym x-basename x-suffix x-endian)
(.str x-basename x-suffix) (.str x-basename x-suffix)
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str x-basename x-suffix " [$dst" x-endian "+$offset16],$src" x-endian) (.str x-basename x-suffix " [$dst" x-endian "+$offset16],$src" x-endian)
(+ (f-imm32 0) offset16 (.sym src x-endian) (.sym dst x-endian) (+ (f-imm32 0) offset16 (.sym src x-endian) (.sym dst x-endian)
OP_CLASS_STX (.sym OP_SIZE_ x-size) OP_MODE_MEM) OP_CLASS_STX (.sym OP_SIZE_ x-size) OP_MODE_MEM)
@ -643,7 +677,7 @@
(define-pmacro (dsti x-suffix x-size x-endian x-mode) (define-pmacro (dsti x-suffix x-size x-endian x-mode)
(dni (.sym "st" x-suffix x-endian) (dni (.sym "st" x-suffix x-endian)
(.str "st" x-suffix) (.str "st" x-suffix)
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str "st" x-suffix " [$dst" x-endian "+$offset16],$imm32") (.str "st" x-suffix " [$dst" x-endian "+$offset16],$imm32")
(+ imm32 offset16 ((.sym f-src x-endian) 0) (.sym dst x-endian) (+ imm32 offset16 ((.sym f-src x-endian) 0) (.sym dst x-endian)
OP_CLASS_ST (.sym OP_SIZE_ x-size) OP_MODE_MEM) OP_CLASS_ST (.sym OP_SIZE_ x-size) OP_MODE_MEM)
@ -677,7 +711,7 @@
(begin (begin
(dni (.sym j x-cond x-suffix i x-endian) (dni (.sym j x-cond x-suffix i x-endian)
(.str j x-cond x-suffix " i") (.str j x-cond x-suffix " i")
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str "j" x-cond x-suffix " $dst" x-endian ",$imm32,$disp16") (.str "j" x-cond x-suffix " $dst" x-endian ",$imm32,$disp16")
(+ imm32 disp16 ((.sym f-src x-endian) 0) (.sym dst x-endian) (+ imm32 disp16 ((.sym f-src x-endian) 0) (.sym dst x-endian)
x-op-class OP_SRC_K (.sym OP_CODE_ x-op-code)) x-op-class OP_SRC_K (.sym OP_CODE_ x-op-code))
@ -688,7 +722,7 @@
()) ())
(dni (.sym j x-cond x-suffix r x-endian) (dni (.sym j x-cond x-suffix r x-endian)
(.str j x-cond x-suffix " r") (.str j x-cond x-suffix " r")
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str "j" x-cond x-suffix " $dst" x-endian ",$src" x-endian ",$disp16") (.str "j" x-cond x-suffix " $dst" x-endian ",$src" x-endian ",$disp16")
(+ (f-imm32 0) disp16 (.sym src x-endian) (.sym dst x-endian) (+ (f-imm32 0) disp16 (.sym src x-endian) (.sym dst x-endian)
x-op-class OP_SRC_X (.sym OP_CODE_ x-op-code)) x-op-class OP_SRC_X (.sym OP_CODE_ x-op-code))
@ -728,7 +762,7 @@
(define-pmacro (define-call-insn x-endian) (define-pmacro (define-call-insn x-endian)
(dni (.sym call x-endian) (dni (.sym call x-endian)
"call" "call"
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
"call $disp32" "call $disp32"
(+ disp32 (f-offset16 0) (f-regs 0) (+ disp32 (f-offset16 0) (f-regs 0)
OP_CLASS_JMP OP_SRC_K OP_CODE_CALL) OP_CLASS_JMP OP_SRC_K OP_CODE_CALL)
@ -739,6 +773,20 @@
(define-call-insn le) (define-call-insn le)
(define-call-insn be) (define-call-insn be)
(define-pmacro (define-callr-insn x-endian)
(dni (.sym callr x-endian)
"callr"
((ISA (.sym xbpf x-endian)))
(.str "call $dst" x-endian)
(+ (f-imm32 0) (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
OP_CLASS_JMP OP_SRC_X OP_CODE_CALL)
(c-call VOID
"bpfbf_callr" (ifield (.sym f-dst x-endian)))
()))
(define-callr-insn le)
(define-callr-insn be)
;; The jump-always and `exit' instructions dont make use of either ;; The jump-always and `exit' instructions dont make use of either
;; source nor destination registers, so only one variant per ;; source nor destination registers, so only one variant per
;; instruction is defined. ;; instruction is defined.
@ -773,7 +821,7 @@
(begin (begin
(dni (.str "xadddw" x-endian) (dni (.str "xadddw" x-endian)
"xadddw" "xadddw"
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str "xadddw [$dst" x-endian "+$offset16],$src" x-endian) (.str "xadddw [$dst" x-endian "+$offset16],$src" x-endian)
(+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian) (+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian)
offset16 OP_MODE_XADD OP_SIZE_DW OP_CLASS_STX) offset16 OP_MODE_XADD OP_SIZE_DW OP_CLASS_STX)
@ -781,7 +829,7 @@
()) ())
(dni (.str "xaddw" x-endian) (dni (.str "xaddw" x-endian)
"xaddw" "xaddw"
((ISA (.sym ebpf x-endian))) (endian-isas x-endian)
(.str "xaddw [$dst" x-endian "+$offset16],$src" x-endian) (.str "xaddw [$dst" x-endian "+$offset16],$src" x-endian)
(+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian) (+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian)
offset16 OP_MODE_XADD OP_SIZE_W OP_CLASS_STX) offset16 OP_MODE_XADD OP_SIZE_W OP_CLASS_STX)

View File

@ -1,3 +1,12 @@
2020-08-26 David Faust <david.faust@oracle.com>
* config/tc-bpf.c: Add option -mxbpf to select xbpf isa.
* testsuite/gas/bpf/indcall-1.d: New file.
* testsuite/gas/bpf/indcall-1.s: Likewise.
* testsuite/gas/bpf/indcall-bad-1.l: Likewise.
* testsuite/gas/bpf/indcall-bad-1.s: Likewise.
* testsuite/gas/bpf/bpf.exp: Run new tests.
2020-08-25 Alan Modra <amodra@gmail.com> 2020-08-25 Alan Modra <amodra@gmail.com>
PR26501 PR26501

View File

@ -97,13 +97,15 @@ static CGEN_BITSET *bpf_isa;
enum options enum options
{ {
OPTION_LITTLE_ENDIAN = OPTION_MD_BASE, OPTION_LITTLE_ENDIAN = OPTION_MD_BASE,
OPTION_BIG_ENDIAN OPTION_BIG_ENDIAN,
OPTION_XBPF
}; };
struct option md_longopts[] = struct option md_longopts[] =
{ {
{ "EL", no_argument, NULL, OPTION_LITTLE_ENDIAN }, { "EL", no_argument, NULL, OPTION_LITTLE_ENDIAN },
{ "EB", no_argument, NULL, OPTION_BIG_ENDIAN }, { "EB", no_argument, NULL, OPTION_BIG_ENDIAN },
{ "mxbpf", no_argument, NULL, OPTION_XBPF },
{ NULL, no_argument, NULL, 0 }, { NULL, no_argument, NULL, 0 },
}; };
@ -117,6 +119,10 @@ extern int target_big_endian;
arguments. */ arguments. */
static int set_target_endian = 0; static int set_target_endian = 0;
static int target_xbpf = 0;
static int set_xbpf = 0;
int int
md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED) md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
{ {
@ -130,6 +136,10 @@ md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
set_target_endian = 1; set_target_endian = 1;
target_big_endian = 0; target_big_endian = 0;
break; break;
case OPTION_XBPF:
set_xbpf = 1;
target_xbpf = 1;
break;
default: default:
return 0; return 0;
} }
@ -143,7 +153,8 @@ md_show_usage (FILE * stream)
fprintf (stream, _("\nBPF options:\n")); fprintf (stream, _("\nBPF options:\n"));
fprintf (stream, _("\ fprintf (stream, _("\
--EL generate code for a little endian machine\n\ --EL generate code for a little endian machine\n\
--EB generate code for a big endian machine\n")); --EB generate code for a big endian machine\n\
-mxbpf generate xBPF instructions\n"));
} }
@ -163,12 +174,27 @@ md_begin (void)
#endif #endif
} }
/* If not specified in the command line, use eBPF rather
than xBPF. */
if (!set_xbpf)
target_xbpf = 0;
/* Set the ISA, which depends on the target endianness. */ /* Set the ISA, which depends on the target endianness. */
bpf_isa = cgen_bitset_create (ISA_MAX); bpf_isa = cgen_bitset_create (ISA_MAX);
if (target_big_endian) if (target_big_endian)
{
if (target_xbpf)
cgen_bitset_set (bpf_isa, ISA_XBPFBE);
else
cgen_bitset_set (bpf_isa, ISA_EBPFBE); cgen_bitset_set (bpf_isa, ISA_EBPFBE);
}
else
{
if (target_xbpf)
cgen_bitset_set (bpf_isa, ISA_XBPFLE);
else else
cgen_bitset_set (bpf_isa, ISA_EBPFLE); cgen_bitset_set (bpf_isa, ISA_EBPFLE);
}
/* Set the machine number and endian. */ /* Set the machine number and endian. */
gas_cgen_cpu_desc = bpf_cgen_cpu_open (CGEN_CPU_OPEN_ENDIAN, gas_cgen_cpu_desc = bpf_cgen_cpu_open (CGEN_CPU_OPEN_ENDIAN,

View File

@ -38,4 +38,7 @@ if {[istarget bpf*-*-*]} {
run_dump_test exit-be run_dump_test exit-be
run_dump_test atomic-be run_dump_test atomic-be
run_dump_test data-be run_dump_test data-be
run_dump_test indcall-1
run_list_test indcall-bad-1
} }

View File

@ -0,0 +1,22 @@
#as: -mxbpf --EL
#objdump: -mxbpf -dr
#name: BPF indirect call 1
.*: +file format .*bpf.*
Disassembly of section \.text:
0000000000000000 <main>:
0: b7 00 00 00 01 00 00 00 mov %r0,1
8: b7 01 00 00 01 00 00 00 mov %r1,1
10: b7 02 00 00 02 00 00 00 mov %r2,2
18: 18 06 00 00 38 00 00 00 lddw %r6,0x38
20: 00 00 00 00 00 00 00 00[ ]*
18: R_BPF_INSN_64 .text
28: 8d 06 00 00 00 00 00 00 call %r6
30: 95 00 00 00 00 00 00 00 exit
0000000000000038 <bar>:
38: b7 00 00 00 00 00 00 00 mov %r0,0
40: 95 00 00 00 00 00 00 00 exit
#pass

View File

@ -0,0 +1,14 @@
.text
.align 4
main:
mov %r0, 1
mov %r1, 1
mov %r2, 2
lddw %r6, bar
call %r6
exit
bar:
mov %r0, 0
exit

View File

@ -0,0 +1,3 @@
.*: Assembler messages:
.* Error: illegal operand `call %r6'
#pass

View File

@ -0,0 +1 @@
call %r6

View File

@ -1,3 +1,12 @@
2020-08-26 David Faust <david.faust@oracle.com>
* bpf-desc.c: Regenerate.
* bpf-desc.h: Likewise.
* bpf-opc.c: Likewise.
* bpf-opc.h: Likewise.
* disassemble.c (disassemble_init_for_target): Set bits for xBPF
ISA when appropriate.
2020-08-25 Alan Modra <amodra@gmail.com> 2020-08-25 Alan Modra <amodra@gmail.com>
PR 26504 PR 26504

File diff suppressed because it is too large Load Diff

View File

@ -99,12 +99,13 @@ typedef enum insn_op_size {
/* Enum declaration for machine type selection. */ /* Enum declaration for machine type selection. */
typedef enum mach_attr { typedef enum mach_attr {
MACH_BASE, MACH_BPF, MACH_MAX MACH_BASE, MACH_BPF, MACH_XBPF, MACH_MAX
} MACH_ATTR; } MACH_ATTR;
/* Enum declaration for instruction set selection. */ /* Enum declaration for instruction set selection. */
typedef enum isa_attr { typedef enum isa_attr {
ISA_EBPFLE, ISA_EBPFBE, ISA_MAX ISA_EBPFLE, ISA_EBPFBE, ISA_XBPFLE, ISA_XBPFBE
, ISA_MAX
} ISA_ATTR; } ISA_ATTR;
/* Number of architecture variants. */ /* Number of architecture variants. */

View File

@ -1552,6 +1552,18 @@ static const CGEN_OPCODE bpf_cgen_insn_opcode_table[MAX_INSNS] =
{ { MNEM, ' ', OP (DISP32), 0 } }, { { MNEM, ' ', OP (DISP32), 0 } },
& ifmt_callle, { 0x85 } & ifmt_callle, { 0x85 }
}, },
/* call $dstle */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (DSTLE), 0 } },
& ifmt_negle, { 0x8d }
},
/* call $dstbe */
{
{ 0, 0, 0, 0 },
{ { MNEM, ' ', OP (DSTBE), 0 } },
& ifmt_negbe, { 0x8d }
},
/* ja $disp16 */ /* ja $disp16 */
{ {
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 },

View File

@ -106,8 +106,9 @@ typedef enum cgen_insn_type {
, BPF_INSN_JSGERBE, BPF_INSN_JSGE32IBE, BPF_INSN_JSGE32RBE, BPF_INSN_JSLTIBE , BPF_INSN_JSGERBE, BPF_INSN_JSGE32IBE, BPF_INSN_JSGE32RBE, BPF_INSN_JSLTIBE
, BPF_INSN_JSLTRBE, BPF_INSN_JSLT32IBE, BPF_INSN_JSLT32RBE, BPF_INSN_JSLEIBE , BPF_INSN_JSLTRBE, BPF_INSN_JSLT32IBE, BPF_INSN_JSLT32RBE, BPF_INSN_JSLEIBE
, BPF_INSN_JSLERBE, BPF_INSN_JSLE32IBE, BPF_INSN_JSLE32RBE, BPF_INSN_CALLLE , BPF_INSN_JSLERBE, BPF_INSN_JSLE32IBE, BPF_INSN_JSLE32RBE, BPF_INSN_CALLLE
, BPF_INSN_CALLBE, BPF_INSN_JA, BPF_INSN_EXIT, BPF_INSN_XADDDWLE , BPF_INSN_CALLBE, BPF_INSN_CALLRLE, BPF_INSN_CALLRBE, BPF_INSN_JA
, BPF_INSN_XADDWLE, BPF_INSN_XADDDWBE, BPF_INSN_XADDWBE, BPF_INSN_BRKPT , BPF_INSN_EXIT, BPF_INSN_XADDDWLE, BPF_INSN_XADDWLE, BPF_INSN_XADDDWBE
, BPF_INSN_XADDWBE, BPF_INSN_BRKPT
} CGEN_INSN_TYPE; } CGEN_INSN_TYPE;
/* Index of `invalid' insn place holder. */ /* Index of `invalid' insn place holder. */

View File

@ -663,11 +663,19 @@ disassemble_init_for_target (struct disassemble_info * info)
info->endian_code = BFD_ENDIAN_LITTLE; info->endian_code = BFD_ENDIAN_LITTLE;
if (!info->private_data) if (!info->private_data)
{ {
info->private_data = cgen_bitset_create (ISA_EBPFMAX); info->private_data = cgen_bitset_create (ISA_MAX);
if (info->endian == BFD_ENDIAN_BIG) if (info->endian == BFD_ENDIAN_BIG)
{
cgen_bitset_set (info->private_data, ISA_EBPFBE); cgen_bitset_set (info->private_data, ISA_EBPFBE);
if (info->mach == bfd_mach_xbpf)
cgen_bitset_set (info->private_data, ISA_XBPFBE);
}
else else
{
cgen_bitset_set (info->private_data, ISA_EBPFLE); cgen_bitset_set (info->private_data, ISA_EBPFLE);
if (info->mach == bfd_mach_xbpf)
cgen_bitset_set (info->private_data, ISA_XBPFLE);
}
} }
break; break;
#endif #endif