head	1.2;
access;
symbols
	perseant-exfatfs-base-20250801:1.2
	netbsd-10-1-RELEASE:1.1.1.1
	perseant-exfatfs-base-20240630:1.2
	perseant-exfatfs:1.1.1.2.0.2
	perseant-exfatfs-base:1.1.1.2
	netbsd-10-0-RELEASE:1.1.1.1
	netbsd-10-0-RC6:1.1.1.1
	netbsd-10-0-RC5:1.1.1.1
	netbsd-10-0-RC4:1.1.1.1
	netbsd-10-0-RC3:1.1.1.1
	netbsd-10-0-RC2:1.1.1.1
	netbsd-10-0-RC1:1.1.1.1
	binutils-2-39:1.1.1.2
	netbsd-10:1.1.1.1.0.8
	netbsd-10-base:1.1.1.1
	cjep_sun2x-base1:1.1.1.1
	cjep_sun2x:1.1.1.1.0.6
	cjep_sun2x-base:1.1.1.1
	cjep_staticlib_x-base1:1.1.1.1
	cjep_staticlib_x:1.1.1.1.0.4
	cjep_staticlib_x-base:1.1.1.1
	phil-wifi-20200421:1.1.1.1
	phil-wifi-20200411:1.1.1.1
	phil-wifi:1.1.1.1.0.2
	phil-wifi-20200406:1.1.1.1
	binutils-2-34:1.1.1.1
	FSF:1.1.1;
locks; strict;
comment	@# @;


1.2
date	2024.06.30.16.10.17;	author christos;	state dead;
branches;
next	1.1;
commitid	YLzDDRlomJFmz1gF;

1.1
date	2020.04.03.23.40.05;	author christos;	state Exp;
branches
	1.1.1.1;
next	;
commitid	qJOWzDWs5P5cQZ2C;

1.1.1.1
date	2020.04.03.23.40.05;	author christos;	state Exp;
branches
	1.1.1.1.2.1;
next	1.1.1.2;
commitid	qJOWzDWs5P5cQZ2C;

1.1.1.2
date	2022.12.23.19.01.15;	author christos;	state Exp;
branches
	1.1.1.2.2.1;
next	;
commitid	AaAP7ITTx5JnmI6E;

1.1.1.1.2.1
date	2020.04.03.23.40.05;	author martin;	state dead;
branches;
next	1.1.1.1.2.2;
commitid	Qli2aW9E74UFuA3C;

1.1.1.1.2.2
date	2020.04.08.14.04.33;	author martin;	state Exp;
branches;
next	;
commitid	Qli2aW9E74UFuA3C;

1.1.1.2.2.1
date	2024.07.01.01.00.02;	author perseant;	state dead;
branches;
next	;
commitid	NkoYLLCQWWw9v4gF;


desc
@@


1.2
log
@Merge conflicts between 2.39 and 2.42
@
text
@;; Linux BPF CPU description  -*- Scheme -*-
;; Copyright (C) 2019 Free Software Foundation, Inc.
;;
;; Contributed by Oracle Inc.
;;
;; This file is part of the GNU Binutils and of GDB.
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 3 of the
;; License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, write to the Free Software
;; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
;; 02110-1301, USA.

;; This file contains a CGEN CPU description for the Linux kernel eBPF
;; instruction set.  eBPF is documented in the linux kernel source
;; tree.  See linux/Documentation/networking/filter.txt, and also the
;; sources in the networking subsystem, notably
;; linux/net/core/filter.c.

(include "simplify.inc")

(define-arch
  (name bpf)
  (comment "Linux kernel BPF")
  (insn-lsb0? #t)
  (machs bpf)
  (isas ebpfle ebpfbe))

;;;; The ISAs

;; Logically, eBPF comforms a single instruction set featuring two
;; kind of instructions: 64-bit instructions and 128-bit instructions.
;;
;; The 64-bit instructions have the form:
;;
;;      code:8 regs:8 offset:16 imm:32
;;
;; Whereas the 128-bit instructions (at the moment there is only one
;; of such instructions, lddw) have the form:
;;
;;      code:8 regs:8 offset:16 imm:32 unused:32 imm:32 
;;
;; In both formats `regs' is itself composed by two fields:
;;
;;      dst:4 src:4
;;
;; The ISA is supposed to be orthogonal to endianness: the endianness
;; of the instruction fields follow the endianness of the host running
;; the eBPF program, and that's all.  However, this is not entirely
;; true.  The definition of an eBPF code in the Linux kernel is:
;;
;; struct bpf_insn {
;;	__u8	code;		/* opcode */
;;	__u8	dst_reg:4;	/* dest register */
;;	__u8	src_reg:4;	/* source register */
;;	__s16	off;		/* signed offset */
;;	__s32	imm;		/* signed immediate constant */
;; };
;;
;; Since the ordering of fields in C bitmaps is defined by the
;; implementation, the impact of endianness in the encoding of eBPF
;; instructions is effectively defined by GCC.  In particular, GCC
;; places dst_reg before src_reg in little-endian code, and the other
;; way around in big-endian code.
;;
;; So, in reality, eBPF comprises two instruction sets: one for
;; little-endian with instructions like:
;;
;;   code:8 src:4 dst:4 offset:16 imm:32 [unused:32 imm:32]
;;
;; and another for big-endian with instructions like:
;;
;;   code:8 dst:4 src:4 offset:16 imm:32 [unused:32 imm:32]
;;
;; where `offset' and the immediate fields are encoded in
;; little-endian and big-endian byte-order, respectively.

(define-pmacro (define-bpf-isa x-endian)
  (define-isa
    (name (.sym ebpf x-endian))
    (comment "The eBPF instruction set")
    ;; Default length to record in ifields.  This is used in
    ;; calculations involving bit numbers.
    (default-insn-word-bitsize 64)
    ;; Length of an unknown instruction.  Used by disassembly and by the
    ;; simulator's invalid insn handler.
    (default-insn-bitsize 64)
    ;; Number of bits of insn that can be initially fetched.  XXX this
    ;; should be 64 (the size of the smallest insn) but until CGEN
    ;; gets fixed to place constant fields in their own words, we have
    ;; to use this workaround to avoid the opcode byte to be placed at
    ;; the wrong side of the instruction when assembling in
    ;; big-endian.
    (base-insn-bitsize 8)))

(define-bpf-isa le)
(define-bpf-isa be)

(define-pmacro all-isas () (ISA ebpfle,ebpfbe))

;;;; Hardware Hierarchy

;;
;;     bpf         architecture
;;      |
;;    bpfbf        cpu-family
;;      |
;;     bpf         machine
;;      |
;;   bpf-def       model

(define-cpu
  (name bpfbf)
  (comment "Linux kernel eBPF virtual CPU")
  (word-bitsize 32))

(define-mach
  (name bpf)
  (comment "Linux eBPF")
  (cpu bpfbf)
  (isas ebpfle ebpfbe))

(define-model
  (name bpf-def)
  (comment "Linux eBPF default model")
  (mach bpf)
  (unit u-exec "execution unit" ()
    1 ; issue
    1 ; done
    () ; state
    () ; inputs
    () ; outputs
    () ; profile action (default)
    ))

;;;; Hardware Elements

;; eBPF programs can access 10 general-purpose registers which are
;; 64-bit.

(define-hardware
  (name h-gpr)
  (comment "General Purpose Registers")
  (attrs all-isas (MACH bpf))
  (type register DI (16))
  (indices keyword "%"
           ;; XXX the frame pointer fp is read-only, so it should
           ;; go in a different hardware.
           (;; ABI names.  Take priority when disassembling.
            (r0 0) (r1 1) (r2 2) (r3 3) (r4 4) (r5 5) (r6 6)
            (r7 7) (r8 8) (r9 9) (fp 10)
            ;; Additional names recognized when assembling.
            (a 0) (ctx 6) (r10 10))))

;; The program counter.  CGEN requires it, even if it is not visible
;; to eBPF programs.

(dnh h-pc "program counter" (PC PROFILE) (pc) () () ())

;; A 64-bit h-sint to be used by the imm64 operand below.  XXX this
;; shouldn't be needed, as h-sint is supposed to be able to hold
;; 64-bit values.  However, in practice CGEN limits h-sint to 32 bits
;; in 32-bit hosts.  To be fixed in CGEN.

(dnh h-sint64 "signed 64-bit integer" (all-isas) (immediate DI)
     () () ())

;;;; The Instruction Sets

;;; Fields and Opcodes

;; Convenience macro to shorten the definition of the fields below.
(define-pmacro (dwf x-name x-comment x-attrs
                    x-word-offset x-word-length x-start x-length
                    x-mode)
  "Define a field including its containing word."
  (define-ifield
    (name x-name)
    (comment x-comment)
    (.splice attrs (.unsplice x-attrs))
    (word-offset x-word-offset)
    (word-length x-word-length)
    (start x-start)
    (length x-length)
    (mode x-mode)))

;; For arithmetic and jump instructions the 8-bit code field is
;; subdivided in:
;;
;;  op-code:4 op-src:1 op-class:3

(dwf f-op-code "eBPF opcode code" (all-isas) 0 8 7 4 UINT)
(dwf f-op-src "eBPF opcode source" (all-isas) 0 8 3 1 UINT)
(dwf f-op-class "eBPF opcode instruction class" (all-isas) 0 8 2 3 UINT)

(define-normal-insn-enum insn-op-code-alu "eBPF instruction codes"
  (all-isas) OP_CODE_ f-op-code
  (;; Codes for OP_CLASS_ALU and OP_CLASS_ALU64
   (ADD #x0) (SUB #x1) (MUL #x2) (DIV #x3) (OR #x4) (AND #x5)
   (LSH #x6) (RSH #x7) (NEG #x8) (MOD #x9) (XOR #xa) (MOV #xb)
   (ARSH #xc) (END #xd)
   ;; Codes for OP_CLASS_JMP
   (JA #x0) (JEQ #x1) (JGT #x2) (JGE #x3) (JSET #x4)
   (JNE #x5) (JSGT #x6) (JSGE #x7) (CALL #x8) (EXIT #x9)
   (JLT #xa) (JLE #xb) (JSLT #xc) (JSLE #xd)))

(define-normal-insn-enum insn-op-src "eBPF instruction source"
  (all-isas) OP_SRC_ f-op-src
  ;; X => use `src' as source operand.
  ;; K => use `imm32' as source operand.
  ((K #b0) (X #b1)))

(define-normal-insn-enum insn-op-class "eBPF instruction class"
  (all-isas) OP_CLASS_ f-op-class
  ((LD    #b000) (LDX   #b001) (ST    #b010) (STX   #b011)
   (ALU   #b100) (JMP   #b101) (ALU64 #b111)))

;; For load/store instructions, the 8-bit code field is subdivided in:
;;
;; op-mode:3 op-size:2 op-class:3

(dwf f-op-mode "eBPF opcode mode" (all-isas) 0 8 7 3 UINT)
(dwf f-op-size "eBPF opcode size" (all-isas) 0 8 4 2 UINT)

(define-normal-insn-enum insn-op-mode "eBPF load/store instruction modes"
  (all-isas) OP_MODE_ f-op-mode
  ((IMM #b000) (ABS #b001) (IND #b010) (MEM #b011)
   ;; #b100 and #b101 are used in classic BPF only, reserved in eBPF.
   (XADD #b110)))

(define-normal-insn-enum insn-op-size "eBPF load/store instruction sizes"
  (all-isas) OP_SIZE_ f-op-size
  ((W  #b00)   ;; Word:        4 byte
   (H  #b01)   ;; Half-word:   2 byte
   (B  #b10)   ;; Byte:        1 byte
   (DW #b11))) ;; Double-word: 8 byte

;; The fields for the source and destination registers are a bit
;; tricky.  Due to the bizarre nibble swap between little-endian and
;; big-endian ISAs we need to keep different variants of the fields.
;;
;; Note that f-regs is used in the format spec of instructions that do
;; NOT use registers, where endianness is irrelevant i.e. f-regs is a
;; constant 0 opcode.

(dwf f-dstle "eBPF dst register field" ((ISA ebpfle)) 8 8 3 4 UINT)
(dwf f-srcle "eBPF source register field" ((ISA ebpfle)) 8 8 7 4 UINT)

(dwf f-dstbe "eBPF dst register field" ((ISA ebpfbe)) 8 8 7 4 UINT)
(dwf f-srcbe "eBPF source register field" ((ISA ebpfbe)) 8 8 3 4 UINT)

(dwf f-regs "eBPF registers field" (all-isas) 8 8 7 8 UINT)

;; Finally, the fields for the immediates.
;;
;; The 16-bit offsets and 32-bit immediates do not present any special
;; difficulty: we put them in their own instruction word so the
;; byte-endianness will be properly applied.

(dwf f-offset16 "eBPF offset field" (all-isas) 16 16 15 16 INT)
(dwf f-imm32 "eBPF 32-bit immediate field" (all-isas) 32 32 31 32 INT)

;; For the disjoint 64-bit signed immediate, however, we need to use a
;; multi-ifield.

(dwf f-imm64-a "eBPF 64-bit immediate a" (all-isas) 32 32 31 32 UINT)
(dwf f-imm64-b "eBPF 64-bit immediate b" (all-isas) 64 32 31 32 UINT)
(dwf f-imm64-c "eBPF 64-bit immediate c" (all-isas) 96 32 31 32 UINT)

(define-multi-ifield
  (name f-imm64)
  (comment "eBPF 64-bit immediate field")
  (attrs all-isas)
  (mode DI)
  (subfields f-imm64-a f-imm64-b f-imm64-c)
  (insert (sequence ()
                    (set (ifield f-imm64-b) (const 0))
                    (set (ifield f-imm64-c) (srl (ifield f-imm64) (const 32)))
                    (set (ifield f-imm64-a) (and (ifield f-imm64) (const #xffffffff)))))
  (extract (sequence ()
                     (set (ifield f-imm64)
                          (or (sll UDI (zext UDI (ifield f-imm64-c)) (const 32))
                              (zext UDI (ifield f-imm64-a)))))))

;;; Operands

;; A couple of source and destination register operands are defined
;; for each ISA: ebpfle and ebpfbe.

(dno dstle "destination register" ((ISA ebpfle)) h-gpr f-dstle)
(dno srcle "source register" ((ISA ebpfle)) h-gpr f-srcle)

(dno dstbe "destination register" ((ISA ebpfbe)) h-gpr f-dstbe)
(dno srcbe "source register" ((ISA ebpfbe)) h-gpr f-srcbe)

;; Jump instructions have a 16-bit PC-relative address.
;; CALL instructions have a 32-bit PC-relative address.

(dno disp16 "16-bit PC-relative address" (all-isas PCREL-ADDR) h-sint
     f-offset16)
(dno disp32 "32-bit PC-relative address" (all-isas PCREL-ADDR) h-sint
     f-imm32)

;; Immediate operands in eBPF are signed, and we want the disassembler
;; to print negative values in a sane way.  Therefore we use the macro
;; below to register a printer, which is itself defined as a C
;; function in bpf.opc.

;; define-normal-signed-immediate-operand
(define-pmacro (dnsio x-name x-comment x-attrs x-type x-index)
  (define-operand
    (name x-name)
    (comment x-comment)
    (.splice attrs (.unsplice x-attrs))
    (type x-type)
    (index x-index)
    (handlers (print "immediate"))))

(dnsio imm32 "32-bit immediate" (all-isas) h-sint f-imm32)
(dnsio offset16 "16-bit offset" (all-isas) h-sint f-offset16)

;; The 64-bit immediate cannot use the default
;; cgen_parse_signed_integer, because it assumes operands are at much
;; 32-bit wide.  Use our own.

(define-operand
  (name imm64)
  (comment "64-bit immediate")
  (attrs all-isas)
  (type h-sint64)
  (index f-imm64)
  (handlers (parse "imm64") (print "immediate")))

;; The endle/endbe instructions take an operand to specify the word
;; width in endianness conversions.  We use both a parser and printer,
;; which are defined as C functions in bpf.opc.

(define-operand
  (name endsize)
  (comment "endianness size immediate: 16, 32 or 64")
  (attrs all-isas)
  (type h-uint)
  (index f-imm32)
  (handlers (parse "endsize") (print "endsize")))

;;; ALU instructions

;; For each opcode in insn-op-code-alu representing and integer
;; arithmetic instruction (ADD, SUB, etc) we define a bunch of
;; instruction variants:
;;
;;   ADD[32]{i,r}le for the little-endian ISA
;;   ADD[32]{i,r}be for the big-endian ISA
;;
;; The `i' variants perform `src OP dst -> dst' operations.
;; The `r' variants perform `dst OP imm32 -> dst' operations.
;;
;; The variants with 32 in their name are of ALU class.  Otherwise
;; they are ALU64 class.

(define-pmacro (define-alu-insn-un x-basename x-suffix x-op-class x-op-code x-endian)
  (dni (.sym x-basename x-suffix x-endian)
       (.str x-basename x-suffix)
       ((ISA (.sym ebpf 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)
          x-op-class OP_SRC_X x-op-code) () ()))

(define-pmacro (define-alu-insn-bin x-basename x-suffix x-op-class x-op-code x-endian)
  (begin
    (dni (.sym x-basename x-suffix "i" x-endian)
         (.str x-basename x-suffix " immediate")
         ((ISA (.sym ebpf x-endian)))
         (.str x-basename x-suffix " $dst" x-endian ",$imm32")
         (+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
            x-op-class OP_SRC_K x-op-code) () ())
    (dni (.sym x-basename x-suffix "r" x-endian)
         (.str x-basename x-suffix " register")
         ((ISA (.sym ebpf 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)
            x-op-class OP_SRC_X x-op-code) () ())))

(define-pmacro (daiu x-basename x-op-code x-endian)
  (begin
    (define-alu-insn-un x-basename "" OP_CLASS_ALU64 x-op-code x-endian)
    (define-alu-insn-un x-basename "32" OP_CLASS_ALU x-op-code x-endian)))

(define-pmacro (daib x-basename x-op-code x-endian)
  (begin
    (define-alu-insn-bin x-basename "" OP_CLASS_ALU64 x-op-code x-endian)
    (define-alu-insn-bin x-basename "32" OP_CLASS_ALU x-op-code x-endian)))

(define-pmacro (define-alu-instructions x-endian)
  (begin
    (daib add OP_CODE_ADD x-endian)
    (daib sub OP_CODE_SUB x-endian)
    (daib mul OP_CODE_MUL x-endian)
    (daib div OP_CODE_DIV x-endian)
    (daib or  OP_CODE_OR x-endian)
    (daib and OP_CODE_AND x-endian)
    (daib lsh OP_CODE_LSH x-endian)
    (daib rsh OP_CODE_RSH x-endian)
    (daib mod OP_CODE_MOD x-endian)
    (daib xor OP_CODE_XOR x-endian)
    (daib mov OP_CODE_MOV x-endian)
    (daib arsh OP_CODE_ARSH x-endian)
    (daiu neg OP_CODE_NEG x-endian)))

(define-alu-instructions le)
(define-alu-instructions be)

;;; Endianness conversion instructions

;; The endianness conversion instructions come in several variants:
;;
;;  END{le,be}le for the little-endian ISA
;;  END{le,be}be for the big-endian ISA
;;
;; Please do not be confused by the repeated `be' and `le' here.  Each
;; ISA has both endle and endbe instructions.  It is the disposition
;; of the source and destination register fields that change between
;; ISAs, not the semantics of the instructions themselves (see section
;; "The ISAs" above in this very file.)

(define-pmacro (define-endian-insn x-suffix x-op-src x-endian)
  (dni (.sym "end" x-suffix x-endian)
       (.str "end" x-suffix " register")
       ((ISA (.sym ebpf x-endian)))
       (.str "end" x-suffix " $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) () ()))

(define-endian-insn "le" OP_SRC_K le)
(define-endian-insn "be" OP_SRC_X le)
(define-endian-insn "le" OP_SRC_K be)
(define-endian-insn "be" OP_SRC_X be)

;;; Load/Store instructions

;; The lddw instruction takes a 64-bit immediate as an operand.  Since
;; this instruction also takes a `dst' operand, we need to define a
;; variant for each ISA:
;;
;;  LDDWle for the little-endian ISA
;;  LDDWbe for the big-endian ISA  

(define-pmacro (define-lddw x-endian)
  (dni (.sym lddw x-endian)
       (.str "lddw" x-endian)
       ((ISA (.sym ebpf x-endian)))
       (.str "lddw $dst" x-endian ",$imm64")
       (+ imm64 (f-offset16 0) ((.sym f-src x-endian) 0)
          (.sym dst x-endian)
          OP_CLASS_LD OP_SIZE_DW OP_MODE_IMM) () ()))

(define-lddw le)
(define-lddw be)

;; The absolute load instructions are non-generic loads designed to be
;; used in socket filters.  They come in several variants:
;;
;; LDABS{w,h,b,dw}

(define-pmacro (dlabs x-suffix x-size)
  (dni (.sym "ldabs" x-suffix)
       (.str "ldabs" x-suffix)
       (all-isas)
       (.str "ldabs" x-suffix " $imm32")
       (+ imm32 (f-offset16 0) (f-regs 0)
          OP_CLASS_LD OP_MODE_ABS (.sym OP_SIZE_ x-size))
       () ()))

(dlabs "w" W)
(dlabs "h" H)
(dlabs "b" B)
(dlabs "dw" DW)

;; The indirect load instructions are non-generic loads designed to be
;; used in socket filters.  They come in several variants:
;;
;; LDIND{w,h,b,dw}le for the little-endian ISA
;; LDIND[w,h,b,dw}be for the big-endian ISA

(define-pmacro (dlind x-suffix x-size x-endian)
  (dni (.sym "ldind" x-suffix x-endian)
       (.str "ldind" x-suffix)
       ((ISA (.sym ebpf x-endian)))
       (.str "ldind" x-suffix " $src" x-endian ",$imm32")
       (+ 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))
       () ()))

(define-pmacro (define-ldind x-endian)
  (begin    
    (dlind "w" W x-endian)
    (dlind "h" H x-endian)
    (dlind "b" B x-endian)
    (dlind "dw" DW x-endian)))

(define-ldind le)
(define-ldind be)

;; Generic load and store instructions are provided for several word
;; sizes.  They come in several variants:
;;
;;  LDX{b,h,w,dw}le, STX{b,h,w,dw}le for the little-endian ISA
;;
;;  LDX{b,h,w,dw}be, STX{b,h,w,dw}be for the big-endian ISA
;;
;; Loads operate on [$SRC+-OFFSET] -> $DST
;; Stores operate on $SRC -> [$DST+-OFFSET]

(define-pmacro (dxli x-basename x-suffix x-size x-endian)
  (dni (.sym x-basename x-suffix x-endian)
       (.str x-basename x-suffix)
       ((ISA (.sym ebpf x-endian)))
       (.str x-basename x-suffix " $dst" x-endian ",[$src" x-endian "+$offset16]")
       (+ (f-imm32 0) offset16 (.sym src x-endian) (.sym dst x-endian)
          OP_CLASS_LDX (.sym OP_SIZE_ x-size) OP_MODE_MEM)
       () ()))

(define-pmacro (dxsi x-basename x-suffix x-size x-endian)
  (dni (.sym x-basename x-suffix x-endian)
       (.str x-basename x-suffix)
       ((ISA (.sym ebpf 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)
          OP_CLASS_STX (.sym OP_SIZE_ x-size) OP_MODE_MEM)
       () ()))

(define-pmacro (define-ldstx-insns x-endian)
  (begin
    (dxli "ldx" "w" W x-endian)
    (dxli "ldx" "h" H x-endian)
    (dxli "ldx" "b" B x-endian)
    (dxli "ldx" "dw" DW x-endian)

    (dxsi "stx" "w" W x-endian)
    (dxsi "stx" "h" H x-endian)
    (dxsi "stx" "b" B x-endian)
    (dxsi "stx" "dw" DW x-endian)))

(define-ldstx-insns le)
(define-ldstx-insns be)

;; Generic store instructions of the form IMM32 -> [$DST+OFFSET] are
;; provided in several variants:
;;
;;  ST{b,h,w,dw}le for the little-endian ISA
;;  ST{b,h,w,dw}be for the big-endian ISA

(define-pmacro (dsti x-suffix x-size x-endian)
  (dni (.sym "st" x-suffix x-endian)
       (.str "st" x-suffix)
       ((ISA (.sym ebpf x-endian)))
       (.str "st" x-suffix " [$dst" x-endian "+$offset16],$imm32")
       (+ imm32 offset16 ((.sym f-src x-endian) 0) (.sym dst x-endian)
          OP_CLASS_ST (.sym OP_SIZE_ x-size) OP_MODE_MEM) () ()))

(define-pmacro (define-st-insns x-endian)
  (begin
    (dsti "b" B x-endian)
    (dsti "h" H x-endian)
    (dsti "w" W x-endian)
    (dsti "dw" DW x-endian)))

(define-st-insns le)
(define-st-insns be)

;;; Jump instructions

;; Compare-and-jump instructions, on the other hand, make use of
;; registers.  Therefore, we need to define several variants in both
;; ISAs:
;;
;;   J{eq,gt,ge,lt,le,set,ne,sgt,sge,slt,sle}{i,r}le for the
;;   little-endian ISA.
;;   J{eq,gt,ge,lt,le,set,ne.sgt,sge,slt,sle}{i,r}be for the
;;   big-endian ISA.

(define-pmacro (dcji x-cond x-op-code x-endian)
  (begin
    (dni (.sym j x-cond i x-endian)
         (.str j x-cond "i")
         ((ISA (.sym ebpf x-endian)))
         (.str "j" x-cond " $dst" x-endian ",$imm32,$disp16")
         (+ imm32 disp16 ((.sym f-src x-endian) 0) (.sym dst x-endian)
            OP_CLASS_JMP OP_SRC_K (.sym OP_CODE_ x-op-code)) () ())
    (dni (.sym j x-cond r x-endian)
         (.str j x-cond "r")
         ((ISA (.sym ebpf x-endian)))
         (.str "j" x-cond " $dst" x-endian ",$src" x-endian ",$disp16")
         (+ (f-imm32 0) disp16 (.sym src x-endian) (.sym dst x-endian)
            OP_CLASS_JMP OP_SRC_X (.sym OP_CODE_ x-op-code)) () ())))

(define-pmacro (define-condjump-insns x-endian)
  (begin
    (dcji "eq" JEQ x-endian)
    (dcji "gt" JGT x-endian)
    (dcji "ge" JGE x-endian)
    (dcji "lt" JLT x-endian)
    (dcji "le" JLE x-endian)
    (dcji "set" JSET x-endian)
    (dcji "ne" JNE x-endian)
    (dcji "sgt" JSGT x-endian)
    (dcji "sge" JSGE x-endian)
    (dcji "slt" JSLT x-endian)
    (dcji "sle" JSLE x-endian)))

(define-condjump-insns le)
(define-condjump-insns be)

;; The jump-always, `call' and `exit' instructions dont make use of
;; either source nor destination registers, so only one variant per
;; instruction is defined.

(dni ja "ja" (all-isas) "ja $disp16"
     (+ (f-imm32 0) disp16 (f-regs 0)
        OP_CLASS_JMP OP_SRC_K OP_CODE_JA) () ())

(dni call "call" (all-isas) "call $disp32"
     (+ disp32 (f-offset16 0) (f-regs 0)
        OP_CLASS_JMP OP_SRC_K OP_CODE_CALL) () ())

(dni "exit" "exit" (all-isas) "exit"
     (+ (f-imm32 0) (f-offset16 0) (f-regs 0)
        OP_CLASS_JMP (f-op-src 0) OP_CODE_EXIT) () ())

;;; Atomic instructions

;; The atomic exchange-and-add instructions come in two flavors: one
;; for swapping 64-bit quantities and another for 32-bit quantities.

(define-pmacro (define-atomic-insns x-endian)
  (begin
    (dni (.str "xadddw" x-endian)
         "xadddw"
         ((ISA (.sym ebpf x-endian)))
         (.str "xadddw [$dst" x-endian "+$offset16],$src" x-endian)
         (+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian)
            offset16 OP_MODE_XADD OP_SIZE_DW OP_CLASS_STX) () ())
    (dni (.str "xaddw" x-endian)
         "xaddw"
         ((ISA (.sym ebpf x-endian)))
         (.str "xaddw [$dst" x-endian "+$offset16],$src" x-endian)
         (+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian)
            offset16 OP_MODE_XADD OP_SIZE_W OP_CLASS_STX) () ())))

(define-atomic-insns le)
(define-atomic-insns be)
@


1.1
log
@Initial revision
@
text
@@


1.1.1.1
log
@Import binutils-2.34

2020-01-18  Nick Clifton  <nickc@@redhat.com>

	Binutils 2.34 branch created.

2020-01-18  Nick Clifton  <nickc@@redhat.com>

	Synchronize top level configure files with master version:

	2020-01-01  Ben Elliston  <bje@@gnu.org>

	* config.guess: Update copyright years.
	* config.sub: Likewise.

	2019-12-21  Ben Elliston  <bje@@gnu.org>

	* config.guess (set_cc_for_build): Prevent multiple calls by
	checking if $tmp is already set. We can't check CC_FOR_BUILD as
	the user may set it externally. Thanks to Torbjörn Granlund for
	the bug report.

	2019-12-21  Torbjörn Granlund  <tg@@gmplib.org>

	* config.guess (alpha:Linux:*:*): Guard against missing
	/proc/cpuinfo by redirecting standard error to /dev/null.

	2019-09-12  Daniel Bittman  <danielbittman1@@gmail.com>

	* config.guess (*:Twizzler:*:*): New.
	* config.sub (-twizzler*): New.

	2019-07-24  Ben Elliston  <bje@@gnu.org>

	* config.guess (mips:OSF1:*.*): Whitespace cleanup.

	2019-06-30  Ben Elliston  <bje@@gnu.org>

	* config.sub (case $os): Match nsk* and powerunix. Don't later
	match nsk* and set os=nsk which removes the OS version number.

	2019-06-30  Ben Elliston  <bje@@gnu.org>

	* config.sub: Recognise os108*.

	2019-06-26  Ben Elliston  <bje@@gnu.org>

	* config.sub (hp300): Set $os to hpux.

	2019-06-26  Ben Elliston  <bje@@gnu.org>

	* config.sub (vsta): Move into alphabetical order.

	2019-06-10  Ben Elliston  <bje@@gnu.org>

	* config.guess (*:OS108:*:*): Recognise new OS.

	2019-05-28  Ben Elliston  <bje@@gnu.org>

	* config.guess (*:Darwin:*:*): Run xcode-select to determine if a
	system compiler is installed. If not, do not run set_cc_for_build,
	as the default cc will open a dialog box asking to install
	Xcode. If no C compiler is available, guess based on uname -p and
	uname -m.

	2019-05-28  Ben Elliston  <bje@@gnu.org>

	* config.guess (*:Darwin:*:*): Simplify UNAME_PROCESSOR.

2020-01-17  Simon Marchi  <simon.marchi@@efficios.com>

	* Makefile.def: Add dependencies of all-gdbsupport on all-bfd.
	* Makefile.in: Re-generate.

2020-01-14  Tom Tromey  <tom@@tromey.com>

	* src-release.sh (GDB_SUPPORT_DIRS): Add gdbsupport.
	* MAINTAINERS: Add gdbsupport.
	* configure: Rebuild.
	* configure.ac (configdirs): Add gdbsupport.
	* gdbsupport: New directory, move from gdb/gdbsupport.
	* Makefile.def (host_modules, dependencies): Add gnulib.
	* Makefile.in: Rebuild.

2020-01-09  Aaron Merey  <amerey@@redhat.com>

        * config/debuginfod.m4: New file. Add macro AC_DEBUGINFOD. Adds
        new configure option --with-debuginfod.
        * configure: Regenerate.
        * configure.ac: Call AC_DEBUGINFOD.

2019-12-26  Christian Biesinger  <cbiesinger@@google.com>

	* .gitignore: Add perf.data and perf.data.old.

2019-10-17  Sergio Durigan Junior  <sergiodj@@redhat.com>

	* src-release.sh (GDB_SUPPORT_DIRS): Add libctf.

2019-10-17  Alan Modra  <amodra@@gmail.com>

	PR 29
	* src-release.sh (getver): Replace "head -1" with "head -n 1".

2019-07-30  Nick Alcock  <nick.alcock@@oracle.com>

	* Makefile.def (host_modules): libctf is no longer no_install.
	* Makefile.in: Regenerated.

2019-07-13  Nick Alcock  <nick.alcock@@oracle.com>

	* Makefile.def (dependencies): all-ld depends on all-libctf.
	* Makefile.in: Regenerated.

2019-09-09  Phil Blundell  <pb@@pbcl.net>

	binutils 2.33 branch created

2019-08-19  Tom Tromey  <tom@@tromey.com>

	* configure: Rebuild.
	* configure.ac: Add --with-static-standard-libraries.

2019-08-09  Nick Clifton  <nickc@@redhat.com>

	* libiberty: Sync with gcc.  Bring in:
	2019-08-08  Martin Liska  <mliska@@suse.cz>

	PR bootstrap/91352
	* lrealpath.c (is_valid_fd): New function.

	2019-07-24  Martin Liska  <mliska@@suse.cz>

	PR lto/91228
	* simple-object-elf.c (simple_object_elf_copy_lto_debug_sections):
	Find first '\0' starting from gnu_lto + 1.

	2019-07-12  Ren Kimura  <rkx1209dev@@gmail.com>

	* simple-object-elf.c (simple_object_elf_match): Check zero value shstrndx.
	This fixes a Bug 90924.

	2019-07-22  Martin Liska  <mliska@@suse.cz>

	* simple-object-elf.c (simple_object_elf_copy_lto_debug_sections):
	Do not search for gnu_lto_v1, but search for first '\0'.

	2019-07-18  Eduard-Mihai Burtescu  <eddyb@@lyken.rs>

	* cplus-dem.c: Include rust-demangle.h.
	* rust-demangle.c: Include rust-demangle.h.
	* rust-demangle.h: New file.

	2019-05-31  Michael Forney  <mforney@@mforney.org>

	* cp-demangle.c: Don't define CP_DYNAMIC_ARRAYS if __STDC_NO_VLA__
	is non-zero.

	2019-04-30  Ben L  <bobsayshilol@@live.co.uk>

	* d-demangle.c (dlang_parse_assocarray): Correctly handle error result.
	* testsuite/d-demangle-expected: Add testcase.

	* d-demangle.c (dlang_parse_tuple): Correctly handle error result.
	* testsuite/d-demangle-expected: Add testcase.

	* d-demangle.c (dlang_parse_structlit): Correctly handle error result.
	* testsuite/d-demangle-expected: Add testcase.

	* d-demangle.c (dlang_parse_arrayliteral): Correctly handle error result.
	* testsuite/d-demangle-expected: Add testcase.

	* d-demangle.c (dlang_parse_integer): Fix stack underflow.
	* testsuite/d-demangle-expected: Add testcase.

	* cp-demangle (d_print_comp_inner): Guard against a NULL 'typed_name'.
	* testsuite/demangle-expected: Add testcase.

	* cp-demangle.c (d_encoding): Guard against NULL return values from
	d_right (dc).
	* testsuite/demangle-expected: Add testcase.

	2019-04-29  Ben L  <bobsayshilol@@live.co.uk>

	* cp-demangle.c (d_expression_1): Don't peek ahead unless the current
	char is valid.
	* testsuite/demangle-expected: Add testcase.

	2019-04-10  Nick Clifton  <nickc@@redhat.com>

	PR 89394
	* cp-demangle.c (cplus_demangle_fill_name): Reject negative
	lengths.
	(d_count_templates_scopes): Replace num_templates and num_scopes
	parameters with a struct d_print_info pointer parameter.  Adjust
	body of the function accordingly.  Add recursion counter and check
	that the recursion limit is not reached.
	(d_print_init): Pass dpi parameter to d_count_templates_scopes.
	Reset recursion counter afterwards, unless the recursion limit was
	reached.

2019-07-13  Joel Brobecker  <brobecker@@adacore.com>

	* src-release (getver): If $tool/gdbsupport/create-version.sh
	exists, use that to determine the version number.

2019-06-21  Andreas Schwab  <schwab@@linux-m68k.org>

	* src-release.sh (GDB_SUPPORT_DIRS): Add gnulib.

2019-06-14  Tom Tromey  <tom@@tromey.com>

	* MAINTAINERS: Add gnulib.
	* gnulib: New directory, move from gdb/gnulib.
	* configure.ac (host_libs): Add gnulib.
	* configure: Rebuild.
	* Makefile.def (host_modules, dependencies): Add gnulib.
	* Makefile.in: Rebuild.

2019-06-03  Nick Clifton  <nickc@@redhat.com>

	Revert:
	2019-05-29  Nick Clifton  <nickc@@redhat.com>

	* configure.ac (noconfigdirs): Add libctf if the target does not use
	the ELF file format.
	* configure: Regenerate.

2019-05-29  Nick Clifton  <nickc@@redhat.com>

	* src-release.sh (do_proto_toplev): Add libctf to list of
	directories that can be disabled.

2019-05-29  Nick Clifton  <nickc@@redhat.com>

	* configure.ac (noconfigdirs): Add libctf if the target does not use
	the ELF file format.
	* configure: Regenerate.

2019-05-28  Nick Alcock  <nick.alcock@@oracle.com>

	* Makefile.def (dependencies): configure-libctf depends on all-bfd
	and all its deps.
	* Makefile.in: Regenerated.

2019-05-28  Nick Alcock  <nick.alcock@@oracle.com>

	* MAINTAINERS: Add libctf.

2019-05-28  Nick Alcock  <nick.alcock@@oracle.com>

	* Makefile.def (host_modules): Add libctf.
	* Makefile.def (dependencies): Likewise.
	libctf depends on zlib, libiberty, and bfd.
	* Makefile.in: Regenerated.
	* configure.ac (host_libs): Add libctf.
	* configure: Regenerated.

2019-05-23  Jose E. Marchesi  <jose.marchesi@@oracle.com>

	* config.guess: Synchronize with config project master sources.
	* config.sub: Likewise.
	* readline/support/config.guess: Likewise.
	* readline/support/config.sub: Likewise.

2019-04-10  Nick Clifton  <nickc@@redhat.com>

	* libiberty: Sync with gcc.  Bring in:
	2019-04-10  Nick Clifton  <nickc@@redhat.com>

	PR 89394
	* cp-demangle.c (cplus_demangle_fill_name): Reject negative
	lengths.
	(d_count_templates_scopes): Replace num_templates and num_scopes
	parameters with a struct d_print_info pointer parameter.  Adjust
	body of the function accordingly.  Add recursion counter and check
	that the recursion limit is not reached.
	(d_print_init): Pass dpi parameter to d_count_templates_scopes.
	Reset recursion counter afterwards, unless the recursion limit was
	reached.

2018-06-24  Nick Clifton  <nickc@@redhat.com>

	2.32 branch created.

2019-01-14  Rainer Orth  <ro@@CeBiTec.Uni-Bielefeld.DE>

	Merge from GCC:
	PR target/88535
	* config.guess: Import upstream version 2019-01-03.
	* config.sub: Import upstream version 2019-01-01.

2019-01-10  Nick Clifton  <nickc@@redhat.com>

	* libiberty: Sync with gcc.  Bring in:
	2019-01-09  Sandra Loosemore  <sandra@@codesourcery.com>

	PR other/16615

	* cp-demangle.c: Mechanically replace "can not" with "cannot".
	* floatformat.c: Likewise.
	* strerror.c: Likewise.

	2018-12-22  Jason Merrill  <jason@@redhat.com>

	Remove support for demangling GCC 2.x era mangling schemes.
	* cplus-dem.c: Remove cplus_mangle_opname, cplus_demangle_opname,
	internal_cplus_demangle, and all subroutines.
	(libiberty_demanglers): Remove entries for ancient GNU (pre-3.0),
	Lucid, ARM, HP, and EDG demangling styles.
	(cplus_demangle): Remove 'work' variable.  Don't call
	internal_cplus_demangle.

2019-01-03  Дилян Палаузов  <dilyan.palauzov@@aegee.org>

	* configure.ac: Don't configure readline if --with-system-readline is
	used.
	* configure: Re-generate.

2018-10-31  Joseph Myers  <joseph@@codesourcery.com>

	Merge from GCC:
	PR bootstrap/82856
	* multilib.am: New file.  From automake.

2018-09-12  Sergio Durigan Junior  <sergiodj@@redhat.com>

	* src-release.sh (GDB_SUPPORT_DIRS): Add "contrib".

2018-07-16  Nick Clifton  <nickc@@redhat.com>

@@ -20,6 +338,18 @@@@
	* config.guess: Sync with upstream version 2018-06-26.
	* config.sub: Sync with upstream version 2018-07-02.

2018-06-29  Alexandre Oliva <oliva@@adacore.com>

	* configure.ac: Introduce support for @@unless/@@endunless.
	* Makefile.tpl (dep-kind): Rewrite with cond; return
	postbootstrap in some cases.
	(make-postboot-dep, postboot-targets): New.
	(dependencies): Do not output postbootstrap dependencies at
	first.  Output non-target ones changed for configure to depend
	on stage_last @@if gcc-bootstrap, and the original deps @@unless
	gcc-bootstrap.
	* configure.in, Makefile.in: Rebuilt.

2018-06-24  Nick Clifton  <nickc@@redhat.com>

	* configure: Regenerate.
@
text
@@


1.1.1.2
log
@Update binutils from 2.34 to 2.39

2022-07-08  Nick Clifton  <nickc@@redhat.com>

	* 2.39 branch created.

2022-07-04  Nick Clifton  <nickc@@redhat.com>

	* libiberty: Synchronize with GCC.  Bring in:
	2022-07-01  Nick Clifton  <nickc@@redhat.com>

	PR demangler/105039
	* rust-demangle.c (demangle_const): Add recursion limit.

	2022-06-26  Simon Marchi  <simon.marchi@@efficios.com>

	* configure.ac: Add AC_CONFIG_MACRO_DIRS call.
	* configure: Re-generate.

2022-04-12  Nick Clifton  <nickc@@redhat.com>

	* zlib: Rebase to the 1.2.12 release.

2022-04-08  Simon Marchi  <simon.marchi@@efficios.com>

	* configure.ac: Add AC_SUBST(PKG_CONFIG_PATH).
	* configure: Re-generate.
	* Makefile.tpl (HOST_EXPORTS): Pass PKG_CONFIG_PATH.
	(PKG_CONFIG_PATH): New.
	* Makefile.in: Re-generate.

2022-03-15  Jose E. Marchesi  <jose.marchesi@@oracle.com>

	* gprofng/src/gp-collect-app.cc (collect::check_args): Use
	fallthrough comment instead of attribute.

2022-03-11  Vladimir Mezentsev  <vladimir.mezentsev@@oracle.com>

	* Makefile.def: Add gprofng module.
	* configure.ac: Add --enable-gprofng option.
	* src-release.sh: Add gprofng.
	* Makefile.in: Regenerate.
	* configure: Regenerate.
	* gprofng: New directory.

2022-01-22  Nick Clifton  <nickc@@redhat.com>

	* 2.38 release branch created.

2022-01-17  Nick Clifton  <nickc@@redhat.com>

	Update config.[guess|sub] from upstream:

	2022-01-09  Idan Horowitz  <idan.horowitz@@gmail.com>

	config.guess: recognize SerenityOS
	* config.guess (*:SerenityOS:*:*): Recognize.
	(timestamp): Update.

	2022-01-03  Bernhard Voelker  <mail@@bernhard-voelker.de>

	Fix GPLv3 license headers to use a comma instead of semicolon
	See: https://www.gnu.org/licenses/gpl-3.0.html#howto

	Update license headers automatically using the following script:

	  $ git grep -l 'Foundation; either version 3' \
	    | xargs sed -i '/Foundation; either version 3/ s/n; e/n, e/'

	* config.guess: Adjust via the above command.
	(timestamp): Update.
	* config.sub: Likewise.
	* doc/config.guess.1: Regenerate.
	* doc/config.sub.1: Likewise.

	2022-01-01  Dmitry V. Levin  <ldv@@altlinux.org>

	Update copyright years
	* config.guess: Update copyright years.
	* config.sub: Likewise.

	2021-12-25  Dmitry V. Levin  <ldv@@altlinux.org>

	config.sub: alias armh to armv7l
	ALT uses armh as an alias for armv7l-alt-linux-gnueabihf since 2012.

	* config.sub (armh-unknown|armh-alt): Set cpu, vendor, and basic_os.
	(timestamp): Update.

	2021-12-24  Dmitry V. Levin  <ldv@@altlinux.org>

	config.sub: alias aarch64le to aarch64
	Apparently, QNX reports aarch64 as aarch64le on little-endian machines.

	* config.sub (aarch64le-*): Set cpu to aarch64.
	(timestamp): Update.

	2021-12-13  Dmitry V. Levin  <ldv@@altlinux.org>

	config.sub: fix typo in timestamp
	* config.sub: Fix timestamp.

	2021-11-30  Andreas F. Borchert  <github@@andreas-borchert.de>

	config.guess: x86_64-pc-solaris2.11 is not properly recognized
	config.guess guesses Solaris 11 to run on a 32-bit platform
	despite Solaris 11 no longer supporting any 32-bit platform.

	See the following code at lines 434 to 445:

	| SUN_ARCH=i386
	| # If there is a compiler, see if it is configured for 64-bit objects.
	| # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
	| # This test works for both compilers.
	| if test "$CC_FOR_BUILD" != no_compiler_found; then
	|     if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
	|         (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
	|         grep IS_64BIT_ARCH >/dev/null
	|     then
	|         SUN_ARCH=x86_64
	|     fi
	| fi

	If "cc" is installed, i.e. the Oracle Studio compiler, this one is
	chosen for $CC_FOR_BUILD.  This compiler, the gcc provided by Oracle
	and also gcc bootstrapped from sources on that platform with a default
	configuration will by default generate 32-bit binaries -- even on
	a 64-bit platform.  And __amd64 will not be defined for compilations
	targeting a 32-bit platform.  This is different from the corresponding
	behaviour on GNU/Linux systems where the local platform is targeted by
	default.

	Thus, as long as you do not add "-m64" or if you have a custom-built
	gcc which defaults to 64 bit, you will get 32-bit binaries on Solaris
	despite living on a 64-bit platform.

	* config.guess (i86pc:SunOS:5.*:* || i86xen:SunOS:5.*:*): Adapt the
	test by adding the "-m64" flag.  This will work properly for Solaris
	10 as well (the last Solaris release that supported x86 32-bit
	platforms).

	2021-10-27  Jordi Sanfeliu  <jordi@@fibranet.cat>

	Recognize Fiwix
	$ make check
	cd testsuite && bash config-guess.sh && rm uname
	PASS: config.guess checks (137 tests)
	cd testsuite && bash config-sub.sh
	PASS: config.sub checks (882 tests)
	PASS: config.sub idempotency checks (819 tests)
	PASS: config.sub canonicalise each config.guess testcase (137 tests)

	* config.guess (i*86:Fiwix:*:*): Recognize.
	* config.sub (fiwix*): Likewise.

	2021-10-18  Kinshuk Dua  <kinshukdua@@gmail.com>

	config.sub: Fix typo in comment
	Fixes: 5e531d391852a54e7fab2d8ff55625fca514b305

	2021-08-14  Nick Bowler  <nbowler@@draconx.ca>

	config.sub: work around command assignment bug in some shells
	When combining variable assignments with a shell command, some older
	shells (notably heirloom-sh and presumably also Solaris 10 /bin/sh)
	have a bug which causes the assignment to alter the current execution
	environment whenever the command is a shell built-in.  For example:

	  % dash -c 'x=good; x=bad echo >/dev/null; echo $x'
	  good

	  % jsh -c 'x=good; x=bad echo >/dev/null; echo $x'
	  bad

	The config.sub script contains a few commands of the form:

	  IFS=- read ...

	which triggers this bug, causing the IFS assignment to persist for the
	remainder of the script.  This can cause misbehaviour in certain cases,
	for example:

	  % jsh config.sub i386-linux-gnu
	  config.sub: test: unknown operator gnu

	  % jsh config.sub i386-gnu/linux
	  sed: can't read s|gnu/linux|gnu|: No such file or directory
	  Invalid configuration `i386-gnu/linux': OS `' not recognized

	* config.sub: Save and restore IFS explicitly to avoid shell bugs.
	* doc/config.sub.1: Regenerate.

	2021-08-04  Jeremy Soller  <jackpot51@@gmail.com>

	config.sub: add Linux Relibc Target
	$ make check
	cd testsuite && bash config-guess.sh && rm uname
	PASS: config.guess checks (136 tests)
	cd testsuite && bash config-sub.sh
	PASS: config.sub checks (881 tests)
	PASS: config.sub idempotency checks (818 tests)
	PASS: config.sub canonicalise each config.guess testcase (136 tests)

	* config.sub (relibc*): Recognize.
	* doc/config.sub.1: Regenerate.
	* testsuite/config-sub.data (x86_64-linux-relibc): New test.

	2021-07-06  Stephanos Ioannidis  <root@@stephanos.io>

	config.sub: add Zephyr RTOS support
	This adds the Zephyr RTOS targets in preparation for implementing the
	Zephyr RTOS-specific toolchain support.

	$ make check
	cd testsuite && bash config-guess.sh && rm uname
	PASS: config.guess checks (136 tests)
	cd testsuite && bash config-sub.sh
	PASS: config.sub checks (880 tests)
	PASS: config.sub idempotency checks (817 tests)
	PASS: config.sub canonicalise each config.guess testcase (136 tests)

	* config.sub (zephyr*): Recognize.
	* doc/config.sub.1: Regenerate.
	* testsuite/config-sub.data: Add testcases for *-zephyr.

	2021-07-03  Ozkan Sezer  <sezero@@users.sourceforge.net>

	config.sub: disable shellcheck SC2006 / SC2268 warnings
	This is in line with the recent config.guess change in commit
	12fcf67c9108f4c4b581eaa302088782f0ee40ea

	* config.sub (shellcheck disable): Add SC2006,SC2268.

	Suggested-by: Jacob Bachmeyer <jcb@@gnu.org>

	2021-07-03  Ozkan Sezer  <sezero@@users.sourceforge.net>

	config.sub: normalize the quoting in the `echo FOO | sed ...`
	Some cases quote the argument to echo and some do not.  At runtime
	it probably does not matter because the substituted values will never
	contain whitespace, but quoting them all would make shellcheck more
	useful.

	* config.sub: Consistently quote the argument of echo.
	* doc/config.sub.1: Regenerate.

	Suggested-by: Jacob Bachmeyer <jcb@@gnu.org>

	2021-07-02  Ozkan Sezer  <sezero@@users.sourceforge.net>

	config.sub: replace POSIX $( ) with classic ` ` throughout
	This is in line with the recent config.guess change in commit
	d70c4fa934de164178054c3a60aaa0024ed07c91.

	The patch was generated using patch-6.gawk script introduced in that
	commit.

	* config.sub: Revert POSIX command substitutions to classic form.

	2021-06-04  Vineet Gupta  <Vineet.Gupta1@@synopsys.com>

	Recognize arc32
	This is the 32-bit variant of ARCv3 ISA (which is not compatible with the
	32-bit ARCv2 ISA)

	| make check
	| cd testsuite && bash config-guess.sh && rm uname
	| PASS: config.guess checks (136 tests)
	| cd testsuite && bash config-sub.sh
	| PASS: config.sub checks (864 tests)
	| PASS: config.sub idempotency checks (801 tests)
	| PASS: config.sub canonicalise each config.guess testcase (136 tests)

	* config.guess (arc32:Linux:*:*): Recognize.
	* config.sub (arc32): Likewise.

	2021-05-27  Jacob Bachmeyer  <jcb@@gnu.org>

	Remove automatic patch generators
	These tools have served their purposes and need not be kept outside of
	the repository history any longer.  This patch as a diff also collects
	the contents of the various tools in one convenient place.

	* patch-1.gawk: Remove.
	* patch-3.gawk: Likewise.
	* patch-6.gawk: Likewise.

	2021-05-26  Jacob Bachmeyer  <jcb@@gnu.org>

	config.guess: manual fixups after previous automatic patch
	The tool could not handle command substitutions that span lines, but
	fortunately there were only two such substitutions in the script.

	The test for which universe is active on Pyramid is rewritten into a
	case block because it was the only use of a command substitution as an
	argument to the test command, which would require quoting.

	* config.guess: Rewrite "if" for Pyramid systems to "case".

	2021-05-26  Jacob Bachmeyer  <jcb@@gnu.org>

	config.guess: replace POSIX $( ) with classic ` ` throughout
	The previous replacement of backticks with POSIX command substitutions
	was ill-considered and illogical: this script recognizes many archaic
	machine types that probably never had POSIX shells, therefore it needs
	to be able to run successfully under pre-POSIX shells.

	This patch was generated using the included GNU Awk program.

	* config.guess: Revert POSIX command substitutions to classic form.
	* patch-6.gawk: Store the tool that produced the automated patch.

	2021-05-26  Jacob Bachmeyer  <jcb@@gnu.org>

	config.guess: manual fixup after previous automated patches
	This patch provides the special handling for the GNU system.  As these
	were two small and unique edits, they were not included in the scripts.

	This patch also cleans up other minor issues that must be addressed
	before reverting to classic command substitutions and updates
	"shellcheck" directives to account for changes in this script and the
	change in "shellcheck" towards reporting individual portability issues.

	2021-05-26  Jacob Bachmeyer  <jcb@@gnu.org>

	config.guess: automatic fixups after previous automated patch
	This patch was generated using the following command:

	  sed -i config.guess \
	      -e '/="[^"]\+"\(-\|$\)/s/="\([^"([:space:])]\+\)"/=\1/' \
	      -e '/="[^"]\+"[[:alnum:]]/s/="\$\([^([:space:])]\+\)"/=${\1}/' \
	      -e \
	'/\$(echo[^|]\+|/s/\([^[:space:]]\)[[:space:]]*|[[:space:]]*sed/\1 | sed/g'

	* config.guess: Remove unneeded quotes in other variable assignments,
	standardize spacing for "echo ... | sed" substitutions.

	2021-05-26  Jacob Bachmeyer  <jcb@@gnu.org>

	config.guess: remove unneeded quotes and factor command substitutions
	This is further cleanup and simplifies some constructs that can confuse
	Emacs' syntax highlighting while generally reducing required quoting.

	This patch was generated using the included GNU Awk program.

	* config.guess: Remove unneeded variable quotes and factor out command
	substitutions when setting GUESS.
	* patch-3.gawk: Store the tool that produced the automated patch.

	2021-05-25  Jacob Bachmeyer  <jcb@@gnu.org>

	config.guess: manual fixups after previous automatic patch
	* config.guess: Adjust a few "leftover" cases that the tool could not
	easily recognize and fixes comment indentation in a few other special
	cases.

	2021-05-25  Jacob Bachmeyer  <jcb@@gnu.org>

	config.guess: use intermediate variable with uname results
	This will allow quoting to be significantly simplified in another
	pass through the file.

	This patch was generated using the included GNU Awk program.

	* config.guess: Use GUESS variable to hold results of uname analysis.
	* patch-1.gawk: Store the tool that produced the automated patch.

	2021-05-25  Jacob Bachmeyer  <jcb@@gnu.org>

	config.guess: introduce intermediate variable with uname results
	This will allow quoting to be significantly simplified in another
	pass through the file.

	* config.guess: Introduce GUESS variable to hold results of uname analysis.

	2021-05-24  Dmitry V. Levin  <ldv@@altlinux.org>

	config.guess: fix shellcheck warning SC2154
	While, according to Plan 9 documentation, the environment variable
	$cputype is set to the name of the kernel's CPU's architecture,
	shellcheck warns that cputype is referenced but not assigned.
	Be on the safe side and do not use cputype if it is not defined
	or empty.

	* config.guess (*:Plan9:*:*): Fix shellcheck warning SC2154.

	2021-05-24  Dmitry V. Levin  <ldv@@altlinux.org>

	config.guess: remove redundant quotes in case commands
	According to the GNU Autoconf Portable Shell Programming manual,
	the Bourne shell does not systematically split variables and back-quoted
	expressions, in particular on the right-hand side of assignments and in
	the argument of 'case'.

	The change is made automatically using the following command:
	$ sed -E -i 's/(\<case )"(\$[^"]+)"( in\>)/\1\2\3/' config.guess

	* config.guess: Simplify case commands by removing quotes around the
	argument.

	Suggested-by: Jacob Bachmeyer <jcb@@gnu.org>

	2021-05-24  Dmitry V. Levin  <ldv@@altlinux.org>

	config.guess: simplify exit status workaround on alphaev67-dec-osf5.1
	Commit 29865ea8a5622cdd80b7a69a0afa78004b4cd311 introduced an exit trap
	reset before exiting to avoid a spurious non-zero exit status on
	alphaev67-dec-osf5.1.  Simplify that code a bit by moving the exit trap
	reset around.

	* config.guess (alpha:OSF1:*:*): Reset exit trap earlier.
	* doc/config.guess.1: Regenerate.

2021-10-29  Eli Zaretskii  <eliz@@gnu.org>

	* gdb/doc/gdb.texinfo (Command Options): (Data): Document
	'-memory-tag-violations'.  Update the example.

2021-09-28  Andrew Burgess  <andrew.burgess@@embecosm.com>

	* src-release.sh (GDB_SUPPPORT_DIRS): Add libbacktrace.

2021-09-27  Nick Alcock  <nick.alcock@@oracle.com>

	PR libctf/27967
	* libtool.m4 (LT_PATH_NM): Try BSDization flags with a user-provided
	NM, if there is one.  Run nm on itself, not on /dev/null, to avoid
	errors from nms that refuse to work on non-regular files.  Remove
	other workarounds for this problem.  Strip out blank lines from the
	nm output.

2021-09-27  Nick Alcock  <nick.alcock@@oracle.com>

	PR libctf/27967
	* libtool.m4 (lt_cv_sys_global_symbol_pipe): Augment symcode for
	Solaris 11.

2021-07-03  Nick Clifton  <nickc@@redhat.com>

	* 2.37 release branch created.

2021-07-03  Nick Clifton  <nickc@@redhat.com>

	* libiberty: Sync with gcc.  Bring in:
	2021-06-30  Gerald Pfeifer  <gerald@@pfeifer.com>

	* make-temp-file.c (usrtmp): Remove.
	(choose_tmpdir): Remove use of usrtmp.

	2021-06-28  Indu Bhagat  <indu.bhagat@@oracle.com>

	* simple-object.c (handle_lto_debug_sections): Copy over .BTF section.

	2021-06-28  Indu Bhagat  <indu.bhagat@@oracle.com>
	    David Faust  <david.faust@@oracle.com>
	    Jose E. Marchesi  <jose.marchesi@@oracle.com>
	    Weimin Pan  <weimin.pan@@oracle.com>

	* simple-object.c (handle_lto_debug_sections): Copy over .ctf
	sections.

	2021-06-05  John David Anglin  <danglin@@gcc.gnu.org>

	PR target/100734
	* configure.ac: Use libiberty snprintf and vsnprintf on
	hppa*-*-hpux*.
	* configure: Regenerate.

	2021-05-06  Tom Tromey  <tom@@tromey.com>

	* hashtab.c (htab_eq_string): New function.

	2021-05-04  Eric Botcazou  <ebotcazou@@adacore.com>

	* configure.ac: Make test for variables more robust.
	* configure: Regenerate.

	2021-05-03  H.J. Lu  <hjl.tools@@gmail.com>

	PR bootstrap/99703
	* configure: Regenerated.

	2021-04-21  Andreas Schwab  <schwab@@linux-m68k.org>

	PR demangler/100177
	* rust-demangle.c (demangle_const_char): Properly print the
	character value.

	2021-03-31  Patrick Palka  <ppalka@@redhat.com>

	PR c++/88115
	* cp-demangle.c (d_dump, d_make_comp, d_expression_1)
	(d_count_templates_scopes): Handle DEMANGLE_COMPONENT_VENDOR_EXPR.
	(d_print_comp_inner): Likewise.
	<case DEMANGLE_COMPONENT_EXTENDED_OPERATOR>: Revert r11-4926
	change.
	<case DEMANGLE_COMPONENT_UNARY>: Likewise.
	* testsuite/demangle-expected: Adjust __alignof__ tests.

	2021-03-16  Nick Clifton  <nickc@@redhat.com>

	* sha1.c (sha1_process_bytes): Use memmove in place of memcpy.

	2021-02-20  Mike Frysinger  <vapier@@gentoo.org>

	* Makefile.in (ACLOCAL, ACLOCAL_AMFLAGS, $(srcdir)/aclocal.m4): Define.
	(configure_deps): Rename to ...
	(aclocal_deps): ... this.  Replace aclocal.m4 with acinclude.m4.
	($(srcdir)/configure): Replace $(configure_deps) with
	$(srcdir)/aclocal.m4.
	* aclocal.m4: Move libiberty macros to acinclude.m4, then regenerate.
	* acinclude.m4: New file.
	* configure: Regenerate.

	2021-02-19  Ayush Mittal  <ayush.m@@samsung.com>

	* argv.c (expandargv): free allocated buffer if read fails.

	2021-02-01  Martin Sebor  <msebor@@redhat.com>

	* dyn-string.c (dyn_string_insert_cstr): Use memcpy instead of strncpy
	to avoid -Wstringop-truncation.

2021-05-29  Mike Frysinger  <vapier@@gentoo.org>

	* configure.ac: Add gnulib to configdirs for sim.
	* configure: Regenerate.

2021-05-24  Maciej W. Rozycki  <macro@@orcam.me.uk>

	* MAINTAINERS: Update path to readline config.{sub,guess} files.

2021-05-24  Maciej W. Rozycki  <macro@@orcam.me.uk>

	* config.guess: Import from upstream.
	* config.sub: Likewise.

2021-05-18  Mike Frysinger  <vapier@@gentoo.org>

	* Makefile.def: Add configure-sim dependency on all-gnulib.
	* Makefile.in: Regenerated.

2021-05-04  Nick Clifton  <nickc@@redhat.com>

	* configure.ac (AC_PROG_CC): Replace with AC_PROG_CC_C99.
	* configure: Regenerate.

2021-03-18  Nick Alcock  <nick.alcock@@oracle.com>

	PR libctf/27482
	* Makefile.def: Add install-bfd dependencies for install-libctf and
	install-ld, and install-strip-bfd dependencies for
	install-strip-libctf and install-strip-ld; move the install-ld
	dependency on install-libctf to join it.
	* Makefile.in: Regenerated.

2021-03-12  Mike Frysinger  <vapier@@gentoo.org>

	* Makefile.def: Remove all-sim dependency on configure-gdb.
	* Makefile.in: Regenerated.

2021-02-28  H.J. Lu  <hongjiu.lu@@intel.com>

	PR binutils/26766
	* Makefile.tpl (PGO_BUILD_TRAINING_FLAGS_TO_PASS): Add
	PGO_BUILD_TRAINING=yes.
	(PGO_BUILD_TRAINING_MFLAGS): New.
	(all): Pass $(PGO_BUILD_TRAINING_MFLAGS) to the PGO build.

2021-02-09  Alan Modra  <amodra@@gmail.com>

	* configure.ac: Delete arm*-*-symbianelf* entry.
	* configure: Regenerate.

2021-01-26  Nick Alcock  <nick.alcock@@oracle.com>

	* Makefile.def: Add install-libctf dependency to install-ld.
	* Makefile.in: Regenerated.

2021-01-12  Mike Frysinger  <vapier@@gentoo.org>

	* src-release.sh (do_proto_toplev): Rewrite indentation.

2021-01-11  H.J. Lu  <hongjiu.lu@@intel.com>

	PR binutils/26766
	* configure.ac:
	* configure: Regenerated.

2021-01-11  H.J. Lu  <hongjiu.lu@@intel.com>

	PR ld/27173
	* configure: Regenerated.
	* libtool.m4 (_LT_CMD_OLD_ARCHIVE): Check if AR works with
	--plugin and rc before enabling --plugin.

2021-01-09  H.J. Lu  <hongjiu.lu@@intel.com>

	PR binutils/26766
	* Makefile.tpl (BUILD_CFLAGS): New.
	(CFLAGS): Append $(BUILD_CFLAGS).
	(CXXFLAGS): Likewise.
	(PGO_BUILD_GEN_FLAGS_TO_PASS): New.
	(PGO_BUILD_TRAINING_CFLAGS): Likewise.
	(PGO_BUILD_TRAINING_CXXFLAGS): Likewise.
	(PGO_BUILD_TRAINING_FLAGS_TO_PASS): Likewise.
	(PGO_BUILD_TRAINING_MFLAGS): Likewise.
	(PGO_BUILD_USE_FLAGS_TO_PASS): Likewise.
	(PGO-TRAINING-TARGETS): Likewise.
	(PGO_BUILD_TRAINING): Likewise.
	(all): Add '+' to the command line for recursive make.  Support
	the PGO build.
	* configure.ac: Add --enable-pgo-build[=lto].
	AC_SUBST PGO_BUILD_GEN_CFLAGS, PGO_BUILD_USE_CFLAGS and
	PGO_BUILD_LTO_CFLAGS.  Enable the PGO build in Makefile.
	* Makefile.in: Regenerated.
	* configure: Likewise.

2021-01-09  H.J. Lu  <hongjiu.lu@@intel.com>

	* Makefile.tpl (AR): Add @@AR_PLUGIN_OPTION@@
	(RANLIB): Add @@RANLIB_PLUGIN_OPTION@@.
	* configure.ac: Include config/gcc-plugin.m4.
	AC_SUBST AR_PLUGIN_OPTION and RANLIB_PLUGIN_OPTION.
	* libtool.m4 (_LT_CMD_OLD_ARCHIVE): Pass --plugin to AR and
	RANLIB if possible.
	* Makefile.in: Regenerated.
	* configure: Likewise.

2021-01-09  Nick Clifton  <nickc@@redhat.com>

	* 2.36 release branch crated.

2021-01-07  Samuel Thibault  <samuel.thibault@@gnu.org>

	* libtool.m4: Match gnu* along with other GNU systems.

2021-01-07  Alan Modra  <amodra@@gmail.com>

	* config.sub: Accept OS of eabi* and gnueabi*.

2021-01-05  Nick Alcock  <nick.alcock@@oracle.com>

	* Makefile.def (libctf): No longer no_check.  Checking depends on
	all-ld.
	* Makefile.in: Regenerated.

2021-01-05  Nick Clifton  <nickc@@redhat.com>

	* libiberty: Sync with gcc.  Bring in:
	2021-01-04  Martin Liska  <mliska@@suse.cz>

	* strverscmp.c: Convert to utf8 from iso8859.

	2020-12-22  Jason Merrill  <jason@@redhat.com>

	PR c++/67343
	* cp-demangle.h (struct d_info): Add unresolved_name_state.
	* cp-demangle.c (d_prefix): Add subst parm.
	(d_nested_name): Pass it.
	(d_unresolved_name): Split out from...
	(d_expression_1): ...here.
	(d_demangle_callback): Maybe retry with old sr mangling.
	* testsuite/demangle-expected: Add test.

	2020-12-21  Jason Merrill  <jason@@redhat.com>

	* cp-demangle.c (d_expression_1): Recognize qualified-id
	on RHS of dt/pt.
	* testsuite/demangle-expected: Add test.

	2020-12-21  Jason Merrill  <jason@@redhat.com>

	* cp-demangle.c (d_unqualified_name): Clear is_expression.
	* testsuite/demangle-expected: Add tests.

	2020-11-25  Matthew Malcomson  <matthew.malcomson@@arm.com>

	* configure: Regenerate.
	* configure.ac: Avoid using sanitizer.

	2020-11-13  Eduard-Mihai Burtescu  <eddyb@@lyken.rs>

	* rust-demangle.c (struct rust_demangler): Add
	skipping_printing and bound_lifetime_depth fields.
	(eat): Add (v0-only).
	(parse_integer_62): Add (v0-only).
	(parse_opt_integer_62): Add (v0-only).
	(parse_disambiguator): Add (v0-only).
	(struct rust_mangled_ident): Add punycode{,_len} fields.
	(parse_ident): Support v0 identifiers.
	(print_str): Respect skipping_printing.
	(print_uint64): Add (v0-only).
	(print_uint64_hex): Add (v0-only).
	(print_ident): Respect skipping_printing,
	Support v0 identifiers.
	(print_lifetime_from_index): Add (v0-only).
	(demangle_binder): Add (v0-only).
	(demangle_path): Add (v0-only).
	(demangle_generic_arg): Add (v0-only).
	(demangle_type): Add (v0-only).
	(demangle_path_maybe_open_generics): Add (v0-only).
	(demangle_dyn_trait): Add (v0-only).
	(demangle_const): Add (v0-only).
	(demangle_const_uint): Add (v0-only).
	(basic_type): Add (v0-only).
	(rust_demangle_callback): Support v0 symbols.
	* testsuite/rust-demangle-expected: Add v0 testcases.

	2020-11-13  Seija Kijin  <doremylover456@@gmail.com>

	* strstr.c (strstr): Make implementation ANSI/POSIX compliant.

	2020-11-11  Patrick Palka  <ppalka@@redhat.com>

	PR c++/88115
	* cp-demangle.c (d_print_comp_inner)
	<case DEMANGLE_COMPONENT_EXTENDED_OPERATOR>: Don't print the
	"operator " prefix for __alignof__.
	<case DEMANGLE_COMPONENT_UNARY>: Always print parens around the
	operand of __alignof__.
	* testsuite/demangle-expected: Test demangling for __alignof__.

	2020-11-09  Christophe Lyon  <christophe.lyon@@linaro.org>

	* pex-win32.c (pex_win32_exec_child): Initialize orig_err.

	2020-10-06  Martin Liska  <mliska@@suse.cz>

	PR lto/97290
	* simple-object-elf.c (simple_object_elf_copy_lto_debug_sections):
	Use sh_link of a .symtab_shndx section.

2021-01-05  Alan Modra  <amodra@@gmail.com>

	* config.guess: Import from upstream.
	* config.sub: Likewise.

2020-12-16  Martin Liska  <mliska@@suse.cz>
	    Tom de Vries  <tdevries@@suse.de>

	* gdb/debuginfod-support.c (struct user_data): Remove has_printed
	field.  Add meter field.
	(progressfn): Print progress using meter.

2020-12-02  Enze Li  <lienze2010@@hotmail.com>

	* .gitignore: Add gnu global outputs.

2020-12-02  Simon Marchi  <simon.marchi@@polymtl.ca>

	* .gitignore: Sync with gcc.

2020-10-26  Andreas Rammhold <andreas@@rammhold.de>

	* src-release.sh: Use sha256sum instead of md5sum.

2020-10-14  Andrew Burgess  <andrew.burgess@@embecosm.com>

	* Makefile.in: Rebuild.
	* Makefile.def: Make distclean-gnulib depend on distclean-gdb and
	distclean-gdbserver.

2020-07-24  Aaron Merey  <amerey@@redhat.com>

	* configure: Rebuild.
	* configure.ac: Remove AC_DEBUGINFOD.

2020-07-04  Nick Clifton  <nickc@@redhat.com>

	Binutils 2.35 branch created.

2020-04-21  Stephen Casner  <casner@@acm.org>

	PR 25830
	* configure.ac (noconfigdirs): Exclude gdb & gprof for pdp11.
	* configure: Rebuild.

2020-03-12  Tom Tromey  <tom@@tromey.com>

	* Makefile.in: Rebuild.
	* Makefile.def (gdbserver): Depend on gdbsupport.

2020-03-12  Tom Tromey  <tom@@tromey.com>

	* Makefile.in: Rebuild.
	* Makefile.def (gdbsupport): Don't depend on bfd.

2020-03-12  Tom Tromey  <tom@@tromey.com>

	* Makefile.in: Rebuild.
	* Makefile.def (gdbsupport): Depend on intl.

2020-02-17  Tom Tromey  <tom@@tromey.com>

	* configure: Rebuild.
	* configure.ac (configdirs): Add gnulib and gdbsupport when building
	gdbserver.

2020-02-14  Tom Tromey  <tom@@tromey.com>

	* Makefile.in: Rebuild.
	* Makefile.def: Make gdbserver require gnulib and libiberty.

2020-02-07  Tom Tromey  <tom@@tromey.com>
	    Pedro Alves  <palves@@redhat.com>

	* src-release.sh (GDB_SUPPORT_DIRS): Add gdbserver.
	* gdbserver: New directory, moved from gdb/gdbserver.
	* configure.ac (host_tools): Add gdbserver.
	Only build gdbserver on certain systems.
	* Makefile.in, configure: Rebuild.
	* Makefile.def (host_modules, dependencies): Add gdbserver.
	* MAINTAINERS: Add gdbserver.

2020-01-28  Sergio Durigan Junior  <sergiodj@@redhat.com>

	* src-release.sh (getver): Look for gdbsupport's
	create-version.sh script at the current directory if tool is
	"gdb".

2020-01-19  Simon Marchi  <simon.marchi@@polymtl.ca>

	* remote-sim.c (gdbsim_target::wait): Return
	sim_data->remote_sim_ptid instead of inferior_ptid.
@
text
@d35 2
a36 6
  ;; XXX explain the default-alignment setting is for the simulator.
  ;; It is confusing that the simulator follows the emulated memory
  ;; access conventions for fetching instructions by pieces...
  (default-alignment unaligned)
  (machs bpf xbpf)
  (isas ebpfle ebpfbe xbpfle xbpfbe))
d97 7
a103 3
    ;; Number of bits of insn that can be initially fetched.  This is
    ;; the size of the smallest insn.
    (base-insn-bitsize 64)))
d108 1
a108 16
(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))))
d113 7
a119 7
;;         bpf            architecture
;;          |
;;        bpfbf           cpu-family
;;      /       \
;;     bpf     xbpf       machine
;;      |       |
;;   bpf-def  xbpf-def    model
d124 1
a124 2
  (insn-endian big)
  (word-bitsize 64))
a144 19
(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)
    ))

d153 1
a153 1
  (attrs all-isas (MACH bpf xbpf))
d162 1
a162 1
            (r0 0) (r6 6) (r10 10))))
d167 2
a168 8
(define-hardware
  (name h-pc)
  (comment "program counter")
  (attrs PC PROFILE all-isas)
  (type pc UDI)
  (get () (raw-reg h-pc))
  (set (newval) (set (raw-reg h-pc) newval)))
  
a210 2
   ;; xBPF-only: signed div, signed mod
   (SDIV #xe) (SMOD #xf)
d225 1
a225 1
   (ALU   #b100) (JMP   #b101) (JMP32 #b110) (ALU64 #b111)))
d255 2
a256 2
(dwf f-dstle "eBPF dst register field" ((ISA ebpfle xbpfle)) 8 8 3 4 UINT)
(dwf f-srcle "eBPF source register field" ((ISA ebpfle xbpfle)) 8 8 7 4 UINT)
d258 2
a259 2
(dwf f-dstbe "eBPF dst register field" ((ISA ebpfbe xbpfbe)) 8 8 7 4 UINT)
(dwf f-srcbe "eBPF source register field" ((ISA ebpfbe xbpfbe)) 8 8 3 4 UINT)
d269 1
a269 1
(dwf f-offset16 "eBPF offset field" (all-isas) 16 16 15 16 HI)
d299 2
a300 2
(dno dstle "destination register" ((ISA ebpfle xbpfle)) h-gpr f-dstle)
(dno srcle "source register" ((ISA ebpfle xbpfle)) h-gpr f-srcle)
d302 2
a303 2
(dno dstbe "destination register" ((ISA ebpfbe xbpfbe)) h-gpr f-dstbe)
(dno srcbe "source register" ((ISA ebpfbe xbpfbe)) h-gpr f-srcbe)
d364 2
a365 2
;; The `i' variants perform `dst OP imm32 -> dst' operations.
;; The `r' variants perform `dst OP src -> dst' operations.
d370 1
a370 2
(define-pmacro (define-alu-insn-un x-basename x-suffix x-op-class x-op-code
                 x-endian x-mode x-semop)
d373 1
a373 1
       (endian-isas x-endian)
d376 1
a376 3
          x-op-class OP_SRC_K x-op-code)
       (set x-mode (.sym dst x-endian) (x-semop x-mode (.sym dst x-endian)))
       ()))
d378 1
a378 2
(define-pmacro (define-alu-insn-bin x-basename x-suffix x-op-class x-op-code
                 x-endian x-mode x-semop x-isas)
a379 1
    ;; dst = dst OP immediate
d382 1
a382 1
         (.splice (.unsplice x-isas))
d385 1
a385 4
            x-op-class OP_SRC_K x-op-code)
         (set x-mode (.sym dst x-endian) (x-semop x-mode (.sym dst x-endian) imm32))
         ())
    ;; dst = dst OP src
d388 1
a388 1
         (.splice (.unsplice x-isas))
d391 1
a391 4
            x-op-class OP_SRC_X x-op-code)
         (set x-mode (.sym dst x-endian)
                      (x-semop x-mode (.sym dst x-endian) (.sym src x-endian)))
         ())))
d393 1
a393 2
(define-pmacro (define-alu-insn-mov x-basename x-suffix x-op-class x-op-code
                 x-endian x-mode)
d395 2
a396 17
    (dni (.sym mov x-suffix "i" x-endian)
         (.str mov x-suffix " immediate")
         (endian-isas x-endian)
         (.str x-basename x-suffix " $dst" x-endian ",$imm32")
         (+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
            x-op-class OP_SRC_K x-op-code)
         (set x-mode (.sym dst x-endian) imm32)
         ())
    (dni (.sym mov x-suffix "r" x-endian)
         (.str mov x-suffix " register")
         (endian-isas 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)
            x-op-class OP_SRC_X x-op-code)
         (set x-mode (.sym dst x-endian) (.sym src x-endian))
         ())))

d398 1
a398 2
;; Unary ALU instructions (neg)
(define-pmacro (daiu x-basename x-op-code x-endian x-semop)
d400 2
a401 15
    (define-alu-insn-un x-basename "" OP_CLASS_ALU64 x-op-code x-endian DI x-semop)
    (define-alu-insn-un x-basename "32" OP_CLASS_ALU x-op-code x-endian USI x-semop)))

;; Binary ALU instructions (all the others)
;; For ALU32: DST = (u32) DST OP (u32) SRC is correct semantics
(define-pmacro (daib x-basename x-op-code x-endian x-semop x-isas)
  (begin
    (define-alu-insn-bin x-basename "" OP_CLASS_ALU64 x-op-code x-endian DI x-semop x-isas)
    (define-alu-insn-bin x-basename "32" OP_CLASS_ALU x-op-code x-endian USI x-semop x-isas)))

;; Move ALU instructions (mov)
(define-pmacro (daim x-basename x-op-code x-endian)
  (begin
    (define-alu-insn-mov x-basename "" OP_CLASS_ALU64 x-op-code x-endian DI)
    (define-alu-insn-mov x-basename "32" OP_CLASS_ALU x-op-code x-endian USI)))
d405 13
a417 15
    (daib add OP_CODE_ADD x-endian add (endian-isas x-endian))
    (daib sub OP_CODE_SUB x-endian sub (endian-isas x-endian))
    (daib mul OP_CODE_MUL x-endian mul (endian-isas x-endian))
    (daib div OP_CODE_DIV x-endian udiv (endian-isas x-endian))
    (daib or  OP_CODE_OR x-endian or (endian-isas x-endian))
    (daib and OP_CODE_AND x-endian and (endian-isas x-endian))
    (daib lsh OP_CODE_LSH x-endian sll (endian-isas x-endian))
    (daib rsh OP_CODE_RSH x-endian srl (endian-isas x-endian))
    (daib mod OP_CODE_MOD x-endian umod (endian-isas x-endian))
    (daib xor OP_CODE_XOR x-endian xor (endian-isas x-endian))
    (daib arsh OP_CODE_ARSH x-endian sra (endian-isas x-endian))
    (daib sdiv OP_CODE_SDIV x-endian div ((ISA (.sym xbpf x-endian))))
    (daib smod OP_CODE_SMOD x-endian mod ((ISA (.sym xbpf x-endian))))
    (daiu neg OP_CODE_NEG x-endian neg)
    (daim mov OP_CODE_MOV x-endian)))
d438 1
a438 1
       (endian-isas x-endian)
d441 1
a441 4
           OP_CLASS_ALU x-op-src OP_CODE_END)
       (set (.sym dst x-endian)
            (c-call DI (.str "bpfbf_end" x-suffix) (.sym dst x-endian) endsize))
       ()))
d460 1
a460 1
       (endian-isas x-endian)
d464 1
a464 3
          OP_CLASS_LD OP_SIZE_DW OP_MODE_IMM)
       (set DI (.sym dst x-endian) imm64)
       ()))
d474 1
a474 1
(define-pmacro (dlabs x-suffix x-size x-smode)
d481 6
a486 16
       (set x-smode
            (reg x-smode h-gpr 0)
            (mem x-smode
                 (add DI
                      (mem DI
                           (add DI
                                (reg DI h-gpr 6) ;; Pointer to struct sk_buff
                                (c-call "bpfbf_skb_data_offset")))
                      imm32)))
       ;; XXX this clobbers R1-R5
       ()))

(dlabs "w" W SI)
(dlabs "h" H HI)
(dlabs "b" B QI)
(dlabs "dw" DW DI)
d494 1
a494 1
(define-pmacro (dlind x-suffix x-size x-endian x-smode)
d497 1
a497 1
       (endian-isas x-endian)
d501 1
a501 13
       (set x-smode
            (reg x-smode h-gpr 0)
            (mem x-smode
                 (add DI
                      (mem DI
                           (add DI
                                (reg DI h-gpr 6) ;; Pointer to struct sk_buff
                                (c-call "bpfbf_skb_data_offset")))
                      (add DI
                           (.sym src x-endian)
                           imm32))))
       ;; XXX this clobbers R1-R5
       ()))
d505 4
a508 4
    (dlind "w" W x-endian SI)
    (dlind "h" H x-endian HI)
    (dlind "b" B x-endian QI)
    (dlind "dw" DW x-endian DI)))
d523 1
a523 1
(define-pmacro (dxli x-basename x-suffix x-size x-endian x-mode)
d526 1
a526 1
       (endian-isas x-endian)
d530 1
a530 4
       (set x-mode
            (.sym dst x-endian)
            (mem x-mode (add DI (.sym src x-endian) offset16)))
       ()))
d532 1
a532 1
(define-pmacro (dxsi x-basename x-suffix x-size x-endian x-mode)
d535 1
a535 1
       (endian-isas x-endian)
d539 1
a539 4
       (set x-mode
            (mem x-mode (add DI (.sym dst x-endian) offset16))
            (.sym src x-endian)) ;; XXX address is section-relative
       ()))
d543 9
a551 9
    (dxli "ldx" "w" W x-endian SI)
    (dxli "ldx" "h" H x-endian HI)
    (dxli "ldx" "b" B x-endian QI)
    (dxli "ldx" "dw" DW x-endian DI)

    (dxsi "stx" "w" W x-endian SI)
    (dxsi "stx" "h" H x-endian HI)
    (dxsi "stx" "b" B x-endian QI)
    (dxsi "stx" "dw" DW x-endian DI)))
d562 1
a562 1
(define-pmacro (dsti x-suffix x-size x-endian x-mode)
d565 1
a565 1
       (endian-isas x-endian)
d568 1
a568 5
          OP_CLASS_ST (.sym OP_SIZE_ x-size) OP_MODE_MEM)
       (set x-mode
            (mem x-mode (add DI (.sym dst x-endian) offset16))
            imm32) ;; XXX address is section-relative
       ()))
d572 4
a575 4
    (dsti "b" B x-endian QI)
    (dsti "h" H x-endian HI)
    (dsti "w" W x-endian SI)
    (dsti "dw" DW x-endian DI)))
d586 1
a586 1
;;   J{eq,gt,ge,lt,le,set,ne,sgt,sge,slt,sle}[32]{i,r}le for the
d588 1
a588 1
;;   J{eq,gt,ge,lt,le,set,ne.sgt,sge,slt,sle}[32]{i,r}be for the
d591 1
a591 1
(define-pmacro (define-cond-jump-insn x-cond x-suffix x-op-class x-op-code x-endian x-mode x-semop)
d593 4
a596 4
    (dni (.sym j x-cond x-suffix i x-endian)
         (.str j x-cond x-suffix " i")
         (endian-isas x-endian)
         (.str "j" x-cond x-suffix " $dst" x-endian ",$imm32,$disp16")
d598 5
a602 10
            x-op-class OP_SRC_K (.sym OP_CODE_ x-op-code))
         (if VOID (x-semop x-mode (.sym dst x-endian) imm32)
             (set DI
                  (reg DI h-pc) (add DI (reg DI h-pc)
                                     (mul DI (add HI disp16 1) 8))))
         ())
    (dni (.sym j x-cond x-suffix r x-endian)
         (.str j x-cond x-suffix " r")
         (endian-isas x-endian)
         (.str "j" x-cond x-suffix " $dst" x-endian ",$src" x-endian ",$disp16")
d604 1
a604 11
            x-op-class OP_SRC_X (.sym OP_CODE_ x-op-code))
         (if VOID (x-semop x-mode (.sym dst x-endian) (.sym src x-endian))
             (set DI
                  (reg DI h-pc) (add DI (reg DI h-pc)
                                     (mul DI (add HI disp16 1) 8))))
         ())))

(define-pmacro (dcji x-cond x-op-code x-endian x-semop)
  (begin
    (define-cond-jump-insn x-cond "" OP_CLASS_JMP x-op-code x-endian DI x-semop)
    (define-cond-jump-insn x-cond "32" OP_CLASS_JMP32 x-op-code x-endian SI x-semop )))
d608 11
a618 11
    (dcji "eq" JEQ x-endian eq)
    (dcji "gt" JGT x-endian gtu)
    (dcji "ge" JGE x-endian geu)
    (dcji "lt" JLT x-endian ltu)
    (dcji "le" JLE x-endian leu)
    (dcji "set" JSET x-endian and)
    (dcji "ne" JNE x-endian ne)
    (dcji "sgt" JSGT x-endian gt)
    (dcji "sge" JSGE x-endian ge)
    (dcji "slt" JSLT x-endian lt)
    (dcji "sle" JSLE x-endian le)))
d623 2
a624 35
;; The `call' instruction doesn't make use of registers, but the
;; semantic routine should have access to the src register in order to
;; properly interpret the meaning of disp32.  Therefore we need one
;; version per ISA.

(define-pmacro (define-call-insn x-endian)
  (dni (.sym call x-endian)
       "call"
       (endian-isas x-endian)
       "call $disp32"
       (+ disp32 (f-offset16 0) (f-regs 0)
          OP_CLASS_JMP OP_SRC_K OP_CODE_CALL)
       (c-call VOID
               "bpfbf_call" disp32 (ifield (.sym f-src x-endian)))
       ()))

(define-call-insn le)
(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
;; source nor destination registers, so only one variant per
d629 5
a633 4
        OP_CLASS_JMP OP_SRC_K OP_CODE_JA)
     (set DI (reg DI h-pc) (add DI (reg DI h-pc)
                                (mul DI (add HI disp16 1) 8)))
     ())
d637 1
a637 3
        OP_CLASS_JMP (f-op-src 0) OP_CODE_EXIT)
     (c-call VOID "bpfbf_exit")
     ())
a643 8
(define-pmacro (sem-exchange-and-add x-endian x-mode)
  (sequence VOID ((x-mode tmp))
            ;; XXX acquire lock in simulator...  as a hardware element?
            (set x-mode tmp (mem x-mode (add DI (.sym dst x-endian) offset16)))
            (set x-mode
                 (mem x-mode (add DI (.sym dst x-endian) offset16))
                 (add x-mode tmp (.sym src x-endian)))))

d648 1
a648 1
         (endian-isas x-endian)
d651 1
a651 3
            offset16 OP_MODE_XADD OP_SIZE_DW OP_CLASS_STX)
         (sem-exchange-and-add x-endian DI)
         ())
d654 1
a654 1
         (endian-isas x-endian)
d657 1
a657 3
            offset16 OP_MODE_XADD OP_SIZE_W OP_CLASS_STX)
         (sem-exchange-and-add x-endian SI)
         ())))
a660 11

;;; Breakpoint instruction

;; The brkpt instruction is used by the BPF simulator and it doesn't
;; really belong to the eBPF instruction set.

(dni "brkpt" "brkpt" (all-isas)  "brkpt"
     (+ (f-imm32 0) (f-offset16 0) (f-regs 0)
        OP_CLASS_ALU OP_SRC_X OP_CODE_NEG)
     (c-call VOID "bpfbf_breakpoint")
     ())
@


1.1.1.2.2.1
log
@Sync with HEAD.
@
text
@@


1.1.1.1.2.1
log
@file bpf.cpu was added on branch phil-wifi on 2020-04-08 14:04:33 +0000
@
text
@d1 660
@


1.1.1.1.2.2
log
@Merge changes from current as of 20200406
@
text
@a0 660
;; Linux BPF CPU description  -*- Scheme -*-
;; Copyright (C) 2019 Free Software Foundation, Inc.
;;
;; Contributed by Oracle Inc.
;;
;; This file is part of the GNU Binutils and of GDB.
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License as
;; published by the Free Software Foundation; either version 3 of the
;; License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, write to the Free Software
;; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
;; 02110-1301, USA.

;; This file contains a CGEN CPU description for the Linux kernel eBPF
;; instruction set.  eBPF is documented in the linux kernel source
;; tree.  See linux/Documentation/networking/filter.txt, and also the
;; sources in the networking subsystem, notably
;; linux/net/core/filter.c.

(include "simplify.inc")

(define-arch
  (name bpf)
  (comment "Linux kernel BPF")
  (insn-lsb0? #t)
  (machs bpf)
  (isas ebpfle ebpfbe))

;;;; The ISAs

;; Logically, eBPF comforms a single instruction set featuring two
;; kind of instructions: 64-bit instructions and 128-bit instructions.
;;
;; The 64-bit instructions have the form:
;;
;;      code:8 regs:8 offset:16 imm:32
;;
;; Whereas the 128-bit instructions (at the moment there is only one
;; of such instructions, lddw) have the form:
;;
;;      code:8 regs:8 offset:16 imm:32 unused:32 imm:32 
;;
;; In both formats `regs' is itself composed by two fields:
;;
;;      dst:4 src:4
;;
;; The ISA is supposed to be orthogonal to endianness: the endianness
;; of the instruction fields follow the endianness of the host running
;; the eBPF program, and that's all.  However, this is not entirely
;; true.  The definition of an eBPF code in the Linux kernel is:
;;
;; struct bpf_insn {
;;	__u8	code;		/* opcode */
;;	__u8	dst_reg:4;	/* dest register */
;;	__u8	src_reg:4;	/* source register */
;;	__s16	off;		/* signed offset */
;;	__s32	imm;		/* signed immediate constant */
;; };
;;
;; Since the ordering of fields in C bitmaps is defined by the
;; implementation, the impact of endianness in the encoding of eBPF
;; instructions is effectively defined by GCC.  In particular, GCC
;; places dst_reg before src_reg in little-endian code, and the other
;; way around in big-endian code.
;;
;; So, in reality, eBPF comprises two instruction sets: one for
;; little-endian with instructions like:
;;
;;   code:8 src:4 dst:4 offset:16 imm:32 [unused:32 imm:32]
;;
;; and another for big-endian with instructions like:
;;
;;   code:8 dst:4 src:4 offset:16 imm:32 [unused:32 imm:32]
;;
;; where `offset' and the immediate fields are encoded in
;; little-endian and big-endian byte-order, respectively.

(define-pmacro (define-bpf-isa x-endian)
  (define-isa
    (name (.sym ebpf x-endian))
    (comment "The eBPF instruction set")
    ;; Default length to record in ifields.  This is used in
    ;; calculations involving bit numbers.
    (default-insn-word-bitsize 64)
    ;; Length of an unknown instruction.  Used by disassembly and by the
    ;; simulator's invalid insn handler.
    (default-insn-bitsize 64)
    ;; Number of bits of insn that can be initially fetched.  XXX this
    ;; should be 64 (the size of the smallest insn) but until CGEN
    ;; gets fixed to place constant fields in their own words, we have
    ;; to use this workaround to avoid the opcode byte to be placed at
    ;; the wrong side of the instruction when assembling in
    ;; big-endian.
    (base-insn-bitsize 8)))

(define-bpf-isa le)
(define-bpf-isa be)

(define-pmacro all-isas () (ISA ebpfle,ebpfbe))

;;;; Hardware Hierarchy

;;
;;     bpf         architecture
;;      |
;;    bpfbf        cpu-family
;;      |
;;     bpf         machine
;;      |
;;   bpf-def       model

(define-cpu
  (name bpfbf)
  (comment "Linux kernel eBPF virtual CPU")
  (word-bitsize 32))

(define-mach
  (name bpf)
  (comment "Linux eBPF")
  (cpu bpfbf)
  (isas ebpfle ebpfbe))

(define-model
  (name bpf-def)
  (comment "Linux eBPF default model")
  (mach bpf)
  (unit u-exec "execution unit" ()
    1 ; issue
    1 ; done
    () ; state
    () ; inputs
    () ; outputs
    () ; profile action (default)
    ))

;;;; Hardware Elements

;; eBPF programs can access 10 general-purpose registers which are
;; 64-bit.

(define-hardware
  (name h-gpr)
  (comment "General Purpose Registers")
  (attrs all-isas (MACH bpf))
  (type register DI (16))
  (indices keyword "%"
           ;; XXX the frame pointer fp is read-only, so it should
           ;; go in a different hardware.
           (;; ABI names.  Take priority when disassembling.
            (r0 0) (r1 1) (r2 2) (r3 3) (r4 4) (r5 5) (r6 6)
            (r7 7) (r8 8) (r9 9) (fp 10)
            ;; Additional names recognized when assembling.
            (a 0) (ctx 6) (r10 10))))

;; The program counter.  CGEN requires it, even if it is not visible
;; to eBPF programs.

(dnh h-pc "program counter" (PC PROFILE) (pc) () () ())

;; A 64-bit h-sint to be used by the imm64 operand below.  XXX this
;; shouldn't be needed, as h-sint is supposed to be able to hold
;; 64-bit values.  However, in practice CGEN limits h-sint to 32 bits
;; in 32-bit hosts.  To be fixed in CGEN.

(dnh h-sint64 "signed 64-bit integer" (all-isas) (immediate DI)
     () () ())

;;;; The Instruction Sets

;;; Fields and Opcodes

;; Convenience macro to shorten the definition of the fields below.
(define-pmacro (dwf x-name x-comment x-attrs
                    x-word-offset x-word-length x-start x-length
                    x-mode)
  "Define a field including its containing word."
  (define-ifield
    (name x-name)
    (comment x-comment)
    (.splice attrs (.unsplice x-attrs))
    (word-offset x-word-offset)
    (word-length x-word-length)
    (start x-start)
    (length x-length)
    (mode x-mode)))

;; For arithmetic and jump instructions the 8-bit code field is
;; subdivided in:
;;
;;  op-code:4 op-src:1 op-class:3

(dwf f-op-code "eBPF opcode code" (all-isas) 0 8 7 4 UINT)
(dwf f-op-src "eBPF opcode source" (all-isas) 0 8 3 1 UINT)
(dwf f-op-class "eBPF opcode instruction class" (all-isas) 0 8 2 3 UINT)

(define-normal-insn-enum insn-op-code-alu "eBPF instruction codes"
  (all-isas) OP_CODE_ f-op-code
  (;; Codes for OP_CLASS_ALU and OP_CLASS_ALU64
   (ADD #x0) (SUB #x1) (MUL #x2) (DIV #x3) (OR #x4) (AND #x5)
   (LSH #x6) (RSH #x7) (NEG #x8) (MOD #x9) (XOR #xa) (MOV #xb)
   (ARSH #xc) (END #xd)
   ;; Codes for OP_CLASS_JMP
   (JA #x0) (JEQ #x1) (JGT #x2) (JGE #x3) (JSET #x4)
   (JNE #x5) (JSGT #x6) (JSGE #x7) (CALL #x8) (EXIT #x9)
   (JLT #xa) (JLE #xb) (JSLT #xc) (JSLE #xd)))

(define-normal-insn-enum insn-op-src "eBPF instruction source"
  (all-isas) OP_SRC_ f-op-src
  ;; X => use `src' as source operand.
  ;; K => use `imm32' as source operand.
  ((K #b0) (X #b1)))

(define-normal-insn-enum insn-op-class "eBPF instruction class"
  (all-isas) OP_CLASS_ f-op-class
  ((LD    #b000) (LDX   #b001) (ST    #b010) (STX   #b011)
   (ALU   #b100) (JMP   #b101) (ALU64 #b111)))

;; For load/store instructions, the 8-bit code field is subdivided in:
;;
;; op-mode:3 op-size:2 op-class:3

(dwf f-op-mode "eBPF opcode mode" (all-isas) 0 8 7 3 UINT)
(dwf f-op-size "eBPF opcode size" (all-isas) 0 8 4 2 UINT)

(define-normal-insn-enum insn-op-mode "eBPF load/store instruction modes"
  (all-isas) OP_MODE_ f-op-mode
  ((IMM #b000) (ABS #b001) (IND #b010) (MEM #b011)
   ;; #b100 and #b101 are used in classic BPF only, reserved in eBPF.
   (XADD #b110)))

(define-normal-insn-enum insn-op-size "eBPF load/store instruction sizes"
  (all-isas) OP_SIZE_ f-op-size
  ((W  #b00)   ;; Word:        4 byte
   (H  #b01)   ;; Half-word:   2 byte
   (B  #b10)   ;; Byte:        1 byte
   (DW #b11))) ;; Double-word: 8 byte

;; The fields for the source and destination registers are a bit
;; tricky.  Due to the bizarre nibble swap between little-endian and
;; big-endian ISAs we need to keep different variants of the fields.
;;
;; Note that f-regs is used in the format spec of instructions that do
;; NOT use registers, where endianness is irrelevant i.e. f-regs is a
;; constant 0 opcode.

(dwf f-dstle "eBPF dst register field" ((ISA ebpfle)) 8 8 3 4 UINT)
(dwf f-srcle "eBPF source register field" ((ISA ebpfle)) 8 8 7 4 UINT)

(dwf f-dstbe "eBPF dst register field" ((ISA ebpfbe)) 8 8 7 4 UINT)
(dwf f-srcbe "eBPF source register field" ((ISA ebpfbe)) 8 8 3 4 UINT)

(dwf f-regs "eBPF registers field" (all-isas) 8 8 7 8 UINT)

;; Finally, the fields for the immediates.
;;
;; The 16-bit offsets and 32-bit immediates do not present any special
;; difficulty: we put them in their own instruction word so the
;; byte-endianness will be properly applied.

(dwf f-offset16 "eBPF offset field" (all-isas) 16 16 15 16 INT)
(dwf f-imm32 "eBPF 32-bit immediate field" (all-isas) 32 32 31 32 INT)

;; For the disjoint 64-bit signed immediate, however, we need to use a
;; multi-ifield.

(dwf f-imm64-a "eBPF 64-bit immediate a" (all-isas) 32 32 31 32 UINT)
(dwf f-imm64-b "eBPF 64-bit immediate b" (all-isas) 64 32 31 32 UINT)
(dwf f-imm64-c "eBPF 64-bit immediate c" (all-isas) 96 32 31 32 UINT)

(define-multi-ifield
  (name f-imm64)
  (comment "eBPF 64-bit immediate field")
  (attrs all-isas)
  (mode DI)
  (subfields f-imm64-a f-imm64-b f-imm64-c)
  (insert (sequence ()
                    (set (ifield f-imm64-b) (const 0))
                    (set (ifield f-imm64-c) (srl (ifield f-imm64) (const 32)))
                    (set (ifield f-imm64-a) (and (ifield f-imm64) (const #xffffffff)))))
  (extract (sequence ()
                     (set (ifield f-imm64)
                          (or (sll UDI (zext UDI (ifield f-imm64-c)) (const 32))
                              (zext UDI (ifield f-imm64-a)))))))

;;; Operands

;; A couple of source and destination register operands are defined
;; for each ISA: ebpfle and ebpfbe.

(dno dstle "destination register" ((ISA ebpfle)) h-gpr f-dstle)
(dno srcle "source register" ((ISA ebpfle)) h-gpr f-srcle)

(dno dstbe "destination register" ((ISA ebpfbe)) h-gpr f-dstbe)
(dno srcbe "source register" ((ISA ebpfbe)) h-gpr f-srcbe)

;; Jump instructions have a 16-bit PC-relative address.
;; CALL instructions have a 32-bit PC-relative address.

(dno disp16 "16-bit PC-relative address" (all-isas PCREL-ADDR) h-sint
     f-offset16)
(dno disp32 "32-bit PC-relative address" (all-isas PCREL-ADDR) h-sint
     f-imm32)

;; Immediate operands in eBPF are signed, and we want the disassembler
;; to print negative values in a sane way.  Therefore we use the macro
;; below to register a printer, which is itself defined as a C
;; function in bpf.opc.

;; define-normal-signed-immediate-operand
(define-pmacro (dnsio x-name x-comment x-attrs x-type x-index)
  (define-operand
    (name x-name)
    (comment x-comment)
    (.splice attrs (.unsplice x-attrs))
    (type x-type)
    (index x-index)
    (handlers (print "immediate"))))

(dnsio imm32 "32-bit immediate" (all-isas) h-sint f-imm32)
(dnsio offset16 "16-bit offset" (all-isas) h-sint f-offset16)

;; The 64-bit immediate cannot use the default
;; cgen_parse_signed_integer, because it assumes operands are at much
;; 32-bit wide.  Use our own.

(define-operand
  (name imm64)
  (comment "64-bit immediate")
  (attrs all-isas)
  (type h-sint64)
  (index f-imm64)
  (handlers (parse "imm64") (print "immediate")))

;; The endle/endbe instructions take an operand to specify the word
;; width in endianness conversions.  We use both a parser and printer,
;; which are defined as C functions in bpf.opc.

(define-operand
  (name endsize)
  (comment "endianness size immediate: 16, 32 or 64")
  (attrs all-isas)
  (type h-uint)
  (index f-imm32)
  (handlers (parse "endsize") (print "endsize")))

;;; ALU instructions

;; For each opcode in insn-op-code-alu representing and integer
;; arithmetic instruction (ADD, SUB, etc) we define a bunch of
;; instruction variants:
;;
;;   ADD[32]{i,r}le for the little-endian ISA
;;   ADD[32]{i,r}be for the big-endian ISA
;;
;; The `i' variants perform `src OP dst -> dst' operations.
;; The `r' variants perform `dst OP imm32 -> dst' operations.
;;
;; The variants with 32 in their name are of ALU class.  Otherwise
;; they are ALU64 class.

(define-pmacro (define-alu-insn-un x-basename x-suffix x-op-class x-op-code x-endian)
  (dni (.sym x-basename x-suffix x-endian)
       (.str x-basename x-suffix)
       ((ISA (.sym ebpf 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)
          x-op-class OP_SRC_X x-op-code) () ()))

(define-pmacro (define-alu-insn-bin x-basename x-suffix x-op-class x-op-code x-endian)
  (begin
    (dni (.sym x-basename x-suffix "i" x-endian)
         (.str x-basename x-suffix " immediate")
         ((ISA (.sym ebpf x-endian)))
         (.str x-basename x-suffix " $dst" x-endian ",$imm32")
         (+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
            x-op-class OP_SRC_K x-op-code) () ())
    (dni (.sym x-basename x-suffix "r" x-endian)
         (.str x-basename x-suffix " register")
         ((ISA (.sym ebpf 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)
            x-op-class OP_SRC_X x-op-code) () ())))

(define-pmacro (daiu x-basename x-op-code x-endian)
  (begin
    (define-alu-insn-un x-basename "" OP_CLASS_ALU64 x-op-code x-endian)
    (define-alu-insn-un x-basename "32" OP_CLASS_ALU x-op-code x-endian)))

(define-pmacro (daib x-basename x-op-code x-endian)
  (begin
    (define-alu-insn-bin x-basename "" OP_CLASS_ALU64 x-op-code x-endian)
    (define-alu-insn-bin x-basename "32" OP_CLASS_ALU x-op-code x-endian)))

(define-pmacro (define-alu-instructions x-endian)
  (begin
    (daib add OP_CODE_ADD x-endian)
    (daib sub OP_CODE_SUB x-endian)
    (daib mul OP_CODE_MUL x-endian)
    (daib div OP_CODE_DIV x-endian)
    (daib or  OP_CODE_OR x-endian)
    (daib and OP_CODE_AND x-endian)
    (daib lsh OP_CODE_LSH x-endian)
    (daib rsh OP_CODE_RSH x-endian)
    (daib mod OP_CODE_MOD x-endian)
    (daib xor OP_CODE_XOR x-endian)
    (daib mov OP_CODE_MOV x-endian)
    (daib arsh OP_CODE_ARSH x-endian)
    (daiu neg OP_CODE_NEG x-endian)))

(define-alu-instructions le)
(define-alu-instructions be)

;;; Endianness conversion instructions

;; The endianness conversion instructions come in several variants:
;;
;;  END{le,be}le for the little-endian ISA
;;  END{le,be}be for the big-endian ISA
;;
;; Please do not be confused by the repeated `be' and `le' here.  Each
;; ISA has both endle and endbe instructions.  It is the disposition
;; of the source and destination register fields that change between
;; ISAs, not the semantics of the instructions themselves (see section
;; "The ISAs" above in this very file.)

(define-pmacro (define-endian-insn x-suffix x-op-src x-endian)
  (dni (.sym "end" x-suffix x-endian)
       (.str "end" x-suffix " register")
       ((ISA (.sym ebpf x-endian)))
       (.str "end" x-suffix " $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) () ()))

(define-endian-insn "le" OP_SRC_K le)
(define-endian-insn "be" OP_SRC_X le)
(define-endian-insn "le" OP_SRC_K be)
(define-endian-insn "be" OP_SRC_X be)

;;; Load/Store instructions

;; The lddw instruction takes a 64-bit immediate as an operand.  Since
;; this instruction also takes a `dst' operand, we need to define a
;; variant for each ISA:
;;
;;  LDDWle for the little-endian ISA
;;  LDDWbe for the big-endian ISA  

(define-pmacro (define-lddw x-endian)
  (dni (.sym lddw x-endian)
       (.str "lddw" x-endian)
       ((ISA (.sym ebpf x-endian)))
       (.str "lddw $dst" x-endian ",$imm64")
       (+ imm64 (f-offset16 0) ((.sym f-src x-endian) 0)
          (.sym dst x-endian)
          OP_CLASS_LD OP_SIZE_DW OP_MODE_IMM) () ()))

(define-lddw le)
(define-lddw be)

;; The absolute load instructions are non-generic loads designed to be
;; used in socket filters.  They come in several variants:
;;
;; LDABS{w,h,b,dw}

(define-pmacro (dlabs x-suffix x-size)
  (dni (.sym "ldabs" x-suffix)
       (.str "ldabs" x-suffix)
       (all-isas)
       (.str "ldabs" x-suffix " $imm32")
       (+ imm32 (f-offset16 0) (f-regs 0)
          OP_CLASS_LD OP_MODE_ABS (.sym OP_SIZE_ x-size))
       () ()))

(dlabs "w" W)
(dlabs "h" H)
(dlabs "b" B)
(dlabs "dw" DW)

;; The indirect load instructions are non-generic loads designed to be
;; used in socket filters.  They come in several variants:
;;
;; LDIND{w,h,b,dw}le for the little-endian ISA
;; LDIND[w,h,b,dw}be for the big-endian ISA

(define-pmacro (dlind x-suffix x-size x-endian)
  (dni (.sym "ldind" x-suffix x-endian)
       (.str "ldind" x-suffix)
       ((ISA (.sym ebpf x-endian)))
       (.str "ldind" x-suffix " $src" x-endian ",$imm32")
       (+ 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))
       () ()))

(define-pmacro (define-ldind x-endian)
  (begin    
    (dlind "w" W x-endian)
    (dlind "h" H x-endian)
    (dlind "b" B x-endian)
    (dlind "dw" DW x-endian)))

(define-ldind le)
(define-ldind be)

;; Generic load and store instructions are provided for several word
;; sizes.  They come in several variants:
;;
;;  LDX{b,h,w,dw}le, STX{b,h,w,dw}le for the little-endian ISA
;;
;;  LDX{b,h,w,dw}be, STX{b,h,w,dw}be for the big-endian ISA
;;
;; Loads operate on [$SRC+-OFFSET] -> $DST
;; Stores operate on $SRC -> [$DST+-OFFSET]

(define-pmacro (dxli x-basename x-suffix x-size x-endian)
  (dni (.sym x-basename x-suffix x-endian)
       (.str x-basename x-suffix)
       ((ISA (.sym ebpf x-endian)))
       (.str x-basename x-suffix " $dst" x-endian ",[$src" x-endian "+$offset16]")
       (+ (f-imm32 0) offset16 (.sym src x-endian) (.sym dst x-endian)
          OP_CLASS_LDX (.sym OP_SIZE_ x-size) OP_MODE_MEM)
       () ()))

(define-pmacro (dxsi x-basename x-suffix x-size x-endian)
  (dni (.sym x-basename x-suffix x-endian)
       (.str x-basename x-suffix)
       ((ISA (.sym ebpf 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)
          OP_CLASS_STX (.sym OP_SIZE_ x-size) OP_MODE_MEM)
       () ()))

(define-pmacro (define-ldstx-insns x-endian)
  (begin
    (dxli "ldx" "w" W x-endian)
    (dxli "ldx" "h" H x-endian)
    (dxli "ldx" "b" B x-endian)
    (dxli "ldx" "dw" DW x-endian)

    (dxsi "stx" "w" W x-endian)
    (dxsi "stx" "h" H x-endian)
    (dxsi "stx" "b" B x-endian)
    (dxsi "stx" "dw" DW x-endian)))

(define-ldstx-insns le)
(define-ldstx-insns be)

;; Generic store instructions of the form IMM32 -> [$DST+OFFSET] are
;; provided in several variants:
;;
;;  ST{b,h,w,dw}le for the little-endian ISA
;;  ST{b,h,w,dw}be for the big-endian ISA

(define-pmacro (dsti x-suffix x-size x-endian)
  (dni (.sym "st" x-suffix x-endian)
       (.str "st" x-suffix)
       ((ISA (.sym ebpf x-endian)))
       (.str "st" x-suffix " [$dst" x-endian "+$offset16],$imm32")
       (+ imm32 offset16 ((.sym f-src x-endian) 0) (.sym dst x-endian)
          OP_CLASS_ST (.sym OP_SIZE_ x-size) OP_MODE_MEM) () ()))

(define-pmacro (define-st-insns x-endian)
  (begin
    (dsti "b" B x-endian)
    (dsti "h" H x-endian)
    (dsti "w" W x-endian)
    (dsti "dw" DW x-endian)))

(define-st-insns le)
(define-st-insns be)

;;; Jump instructions

;; Compare-and-jump instructions, on the other hand, make use of
;; registers.  Therefore, we need to define several variants in both
;; ISAs:
;;
;;   J{eq,gt,ge,lt,le,set,ne,sgt,sge,slt,sle}{i,r}le for the
;;   little-endian ISA.
;;   J{eq,gt,ge,lt,le,set,ne.sgt,sge,slt,sle}{i,r}be for the
;;   big-endian ISA.

(define-pmacro (dcji x-cond x-op-code x-endian)
  (begin
    (dni (.sym j x-cond i x-endian)
         (.str j x-cond "i")
         ((ISA (.sym ebpf x-endian)))
         (.str "j" x-cond " $dst" x-endian ",$imm32,$disp16")
         (+ imm32 disp16 ((.sym f-src x-endian) 0) (.sym dst x-endian)
            OP_CLASS_JMP OP_SRC_K (.sym OP_CODE_ x-op-code)) () ())
    (dni (.sym j x-cond r x-endian)
         (.str j x-cond "r")
         ((ISA (.sym ebpf x-endian)))
         (.str "j" x-cond " $dst" x-endian ",$src" x-endian ",$disp16")
         (+ (f-imm32 0) disp16 (.sym src x-endian) (.sym dst x-endian)
            OP_CLASS_JMP OP_SRC_X (.sym OP_CODE_ x-op-code)) () ())))

(define-pmacro (define-condjump-insns x-endian)
  (begin
    (dcji "eq" JEQ x-endian)
    (dcji "gt" JGT x-endian)
    (dcji "ge" JGE x-endian)
    (dcji "lt" JLT x-endian)
    (dcji "le" JLE x-endian)
    (dcji "set" JSET x-endian)
    (dcji "ne" JNE x-endian)
    (dcji "sgt" JSGT x-endian)
    (dcji "sge" JSGE x-endian)
    (dcji "slt" JSLT x-endian)
    (dcji "sle" JSLE x-endian)))

(define-condjump-insns le)
(define-condjump-insns be)

;; The jump-always, `call' and `exit' instructions dont make use of
;; either source nor destination registers, so only one variant per
;; instruction is defined.

(dni ja "ja" (all-isas) "ja $disp16"
     (+ (f-imm32 0) disp16 (f-regs 0)
        OP_CLASS_JMP OP_SRC_K OP_CODE_JA) () ())

(dni call "call" (all-isas) "call $disp32"
     (+ disp32 (f-offset16 0) (f-regs 0)
        OP_CLASS_JMP OP_SRC_K OP_CODE_CALL) () ())

(dni "exit" "exit" (all-isas) "exit"
     (+ (f-imm32 0) (f-offset16 0) (f-regs 0)
        OP_CLASS_JMP (f-op-src 0) OP_CODE_EXIT) () ())

;;; Atomic instructions

;; The atomic exchange-and-add instructions come in two flavors: one
;; for swapping 64-bit quantities and another for 32-bit quantities.

(define-pmacro (define-atomic-insns x-endian)
  (begin
    (dni (.str "xadddw" x-endian)
         "xadddw"
         ((ISA (.sym ebpf x-endian)))
         (.str "xadddw [$dst" x-endian "+$offset16],$src" x-endian)
         (+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian)
            offset16 OP_MODE_XADD OP_SIZE_DW OP_CLASS_STX) () ())
    (dni (.str "xaddw" x-endian)
         "xaddw"
         ((ISA (.sym ebpf x-endian)))
         (.str "xaddw [$dst" x-endian "+$offset16],$src" x-endian)
         (+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian)
            offset16 OP_MODE_XADD OP_SIZE_W OP_CLASS_STX) () ())))

(define-atomic-insns le)
(define-atomic-insns be)
@


