xref: /kernel/linux/linux-6.6/arch/arm64/net/bpf_jit.h (revision 62306a36)
162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * BPF JIT compiler for ARM64
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#ifndef _BPF_JIT_H
862306a36Sopenharmony_ci#define _BPF_JIT_H
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <asm/insn.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/* 5-bit Register Operand */
1362306a36Sopenharmony_ci#define A64_R(x)	AARCH64_INSN_REG_##x
1462306a36Sopenharmony_ci#define A64_FP		AARCH64_INSN_REG_FP
1562306a36Sopenharmony_ci#define A64_LR		AARCH64_INSN_REG_LR
1662306a36Sopenharmony_ci#define A64_ZR		AARCH64_INSN_REG_ZR
1762306a36Sopenharmony_ci#define A64_SP		AARCH64_INSN_REG_SP
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define A64_VARIANT(sf) \
2062306a36Sopenharmony_ci	((sf) ? AARCH64_INSN_VARIANT_64BIT : AARCH64_INSN_VARIANT_32BIT)
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/* Compare & branch (immediate) */
2362306a36Sopenharmony_ci#define A64_COMP_BRANCH(sf, Rt, offset, type) \
2462306a36Sopenharmony_ci	aarch64_insn_gen_comp_branch_imm(0, offset, Rt, A64_VARIANT(sf), \
2562306a36Sopenharmony_ci		AARCH64_INSN_BRANCH_COMP_##type)
2662306a36Sopenharmony_ci#define A64_CBZ(sf, Rt, imm19) A64_COMP_BRANCH(sf, Rt, (imm19) << 2, ZERO)
2762306a36Sopenharmony_ci#define A64_CBNZ(sf, Rt, imm19) A64_COMP_BRANCH(sf, Rt, (imm19) << 2, NONZERO)
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/* Conditional branch (immediate) */
3062306a36Sopenharmony_ci#define A64_COND_BRANCH(cond, offset) \
3162306a36Sopenharmony_ci	aarch64_insn_gen_cond_branch_imm(0, offset, cond)
3262306a36Sopenharmony_ci#define A64_COND_EQ	AARCH64_INSN_COND_EQ /* == */
3362306a36Sopenharmony_ci#define A64_COND_NE	AARCH64_INSN_COND_NE /* != */
3462306a36Sopenharmony_ci#define A64_COND_CS	AARCH64_INSN_COND_CS /* unsigned >= */
3562306a36Sopenharmony_ci#define A64_COND_HI	AARCH64_INSN_COND_HI /* unsigned > */
3662306a36Sopenharmony_ci#define A64_COND_LS	AARCH64_INSN_COND_LS /* unsigned <= */
3762306a36Sopenharmony_ci#define A64_COND_CC	AARCH64_INSN_COND_CC /* unsigned < */
3862306a36Sopenharmony_ci#define A64_COND_GE	AARCH64_INSN_COND_GE /* signed >= */
3962306a36Sopenharmony_ci#define A64_COND_GT	AARCH64_INSN_COND_GT /* signed > */
4062306a36Sopenharmony_ci#define A64_COND_LE	AARCH64_INSN_COND_LE /* signed <= */
4162306a36Sopenharmony_ci#define A64_COND_LT	AARCH64_INSN_COND_LT /* signed < */
4262306a36Sopenharmony_ci#define A64_B_(cond, imm19) A64_COND_BRANCH(cond, (imm19) << 2)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/* Unconditional branch (immediate) */
4562306a36Sopenharmony_ci#define A64_BRANCH(offset, type) aarch64_insn_gen_branch_imm(0, offset, \
4662306a36Sopenharmony_ci	AARCH64_INSN_BRANCH_##type)
4762306a36Sopenharmony_ci#define A64_B(imm26)  A64_BRANCH((imm26) << 2, NOLINK)
4862306a36Sopenharmony_ci#define A64_BL(imm26) A64_BRANCH((imm26) << 2, LINK)
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/* Unconditional branch (register) */
5162306a36Sopenharmony_ci#define A64_BR(Rn)  aarch64_insn_gen_branch_reg(Rn, AARCH64_INSN_BRANCH_NOLINK)
5262306a36Sopenharmony_ci#define A64_BLR(Rn) aarch64_insn_gen_branch_reg(Rn, AARCH64_INSN_BRANCH_LINK)
5362306a36Sopenharmony_ci#define A64_RET(Rn) aarch64_insn_gen_branch_reg(Rn, AARCH64_INSN_BRANCH_RETURN)
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/* Load/store register (register offset) */
5662306a36Sopenharmony_ci#define A64_LS_REG(Rt, Rn, Rm, size, type) \
5762306a36Sopenharmony_ci	aarch64_insn_gen_load_store_reg(Rt, Rn, Rm, \
5862306a36Sopenharmony_ci		AARCH64_INSN_SIZE_##size, \
5962306a36Sopenharmony_ci		AARCH64_INSN_LDST_##type##_REG_OFFSET)
6062306a36Sopenharmony_ci#define A64_STRB(Wt, Xn, Xm)  A64_LS_REG(Wt, Xn, Xm, 8, STORE)
6162306a36Sopenharmony_ci#define A64_LDRB(Wt, Xn, Xm)  A64_LS_REG(Wt, Xn, Xm, 8, LOAD)
6262306a36Sopenharmony_ci#define A64_LDRSB(Xt, Xn, Xm) A64_LS_REG(Xt, Xn, Xm, 8, SIGNED_LOAD)
6362306a36Sopenharmony_ci#define A64_STRH(Wt, Xn, Xm)  A64_LS_REG(Wt, Xn, Xm, 16, STORE)
6462306a36Sopenharmony_ci#define A64_LDRH(Wt, Xn, Xm)  A64_LS_REG(Wt, Xn, Xm, 16, LOAD)
6562306a36Sopenharmony_ci#define A64_LDRSH(Xt, Xn, Xm) A64_LS_REG(Xt, Xn, Xm, 16, SIGNED_LOAD)
6662306a36Sopenharmony_ci#define A64_STR32(Wt, Xn, Xm) A64_LS_REG(Wt, Xn, Xm, 32, STORE)
6762306a36Sopenharmony_ci#define A64_LDR32(Wt, Xn, Xm) A64_LS_REG(Wt, Xn, Xm, 32, LOAD)
6862306a36Sopenharmony_ci#define A64_LDRSW(Xt, Xn, Xm) A64_LS_REG(Xt, Xn, Xm, 32, SIGNED_LOAD)
6962306a36Sopenharmony_ci#define A64_STR64(Xt, Xn, Xm) A64_LS_REG(Xt, Xn, Xm, 64, STORE)
7062306a36Sopenharmony_ci#define A64_LDR64(Xt, Xn, Xm) A64_LS_REG(Xt, Xn, Xm, 64, LOAD)
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/* Load/store register (immediate offset) */
7362306a36Sopenharmony_ci#define A64_LS_IMM(Rt, Rn, imm, size, type) \
7462306a36Sopenharmony_ci	aarch64_insn_gen_load_store_imm(Rt, Rn, imm, \
7562306a36Sopenharmony_ci		AARCH64_INSN_SIZE_##size, \
7662306a36Sopenharmony_ci		AARCH64_INSN_LDST_##type##_IMM_OFFSET)
7762306a36Sopenharmony_ci#define A64_STRBI(Wt, Xn, imm)  A64_LS_IMM(Wt, Xn, imm, 8, STORE)
7862306a36Sopenharmony_ci#define A64_LDRBI(Wt, Xn, imm)  A64_LS_IMM(Wt, Xn, imm, 8, LOAD)
7962306a36Sopenharmony_ci#define A64_LDRSBI(Xt, Xn, imm) A64_LS_IMM(Xt, Xn, imm, 8, SIGNED_LOAD)
8062306a36Sopenharmony_ci#define A64_STRHI(Wt, Xn, imm)  A64_LS_IMM(Wt, Xn, imm, 16, STORE)
8162306a36Sopenharmony_ci#define A64_LDRHI(Wt, Xn, imm)  A64_LS_IMM(Wt, Xn, imm, 16, LOAD)
8262306a36Sopenharmony_ci#define A64_LDRSHI(Xt, Xn, imm) A64_LS_IMM(Xt, Xn, imm, 16, SIGNED_LOAD)
8362306a36Sopenharmony_ci#define A64_STR32I(Wt, Xn, imm) A64_LS_IMM(Wt, Xn, imm, 32, STORE)
8462306a36Sopenharmony_ci#define A64_LDR32I(Wt, Xn, imm) A64_LS_IMM(Wt, Xn, imm, 32, LOAD)
8562306a36Sopenharmony_ci#define A64_LDRSWI(Xt, Xn, imm) A64_LS_IMM(Xt, Xn, imm, 32, SIGNED_LOAD)
8662306a36Sopenharmony_ci#define A64_STR64I(Xt, Xn, imm) A64_LS_IMM(Xt, Xn, imm, 64, STORE)
8762306a36Sopenharmony_ci#define A64_LDR64I(Xt, Xn, imm) A64_LS_IMM(Xt, Xn, imm, 64, LOAD)
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/* LDR (literal) */
9062306a36Sopenharmony_ci#define A64_LDR32LIT(Wt, offset) \
9162306a36Sopenharmony_ci	aarch64_insn_gen_load_literal(0, offset, Wt, false)
9262306a36Sopenharmony_ci#define A64_LDR64LIT(Xt, offset) \
9362306a36Sopenharmony_ci	aarch64_insn_gen_load_literal(0, offset, Xt, true)
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/* Load/store register pair */
9662306a36Sopenharmony_ci#define A64_LS_PAIR(Rt, Rt2, Rn, offset, ls, type) \
9762306a36Sopenharmony_ci	aarch64_insn_gen_load_store_pair(Rt, Rt2, Rn, offset, \
9862306a36Sopenharmony_ci		AARCH64_INSN_VARIANT_64BIT, \
9962306a36Sopenharmony_ci		AARCH64_INSN_LDST_##ls##_PAIR_##type)
10062306a36Sopenharmony_ci/* Rn -= 16; Rn[0] = Rt; Rn[8] = Rt2; */
10162306a36Sopenharmony_ci#define A64_PUSH(Rt, Rt2, Rn) A64_LS_PAIR(Rt, Rt2, Rn, -16, STORE, PRE_INDEX)
10262306a36Sopenharmony_ci/* Rt = Rn[0]; Rt2 = Rn[8]; Rn += 16; */
10362306a36Sopenharmony_ci#define A64_POP(Rt, Rt2, Rn)  A64_LS_PAIR(Rt, Rt2, Rn, 16, LOAD, POST_INDEX)
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci/* Load/store exclusive */
10662306a36Sopenharmony_ci#define A64_SIZE(sf) \
10762306a36Sopenharmony_ci	((sf) ? AARCH64_INSN_SIZE_64 : AARCH64_INSN_SIZE_32)
10862306a36Sopenharmony_ci#define A64_LSX(sf, Rt, Rn, Rs, type) \
10962306a36Sopenharmony_ci	aarch64_insn_gen_load_store_ex(Rt, Rn, Rs, A64_SIZE(sf), \
11062306a36Sopenharmony_ci				       AARCH64_INSN_LDST_##type)
11162306a36Sopenharmony_ci/* Rt = [Rn]; (atomic) */
11262306a36Sopenharmony_ci#define A64_LDXR(sf, Rt, Rn) \
11362306a36Sopenharmony_ci	A64_LSX(sf, Rt, Rn, A64_ZR, LOAD_EX)
11462306a36Sopenharmony_ci/* [Rn] = Rt; (atomic) Rs = [state] */
11562306a36Sopenharmony_ci#define A64_STXR(sf, Rt, Rn, Rs) \
11662306a36Sopenharmony_ci	A64_LSX(sf, Rt, Rn, Rs, STORE_EX)
11762306a36Sopenharmony_ci/* [Rn] = Rt (store release); (atomic) Rs = [state] */
11862306a36Sopenharmony_ci#define A64_STLXR(sf, Rt, Rn, Rs) \
11962306a36Sopenharmony_ci	aarch64_insn_gen_load_store_ex(Rt, Rn, Rs, A64_SIZE(sf), \
12062306a36Sopenharmony_ci				       AARCH64_INSN_LDST_STORE_REL_EX)
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci/*
12362306a36Sopenharmony_ci * LSE atomics
12462306a36Sopenharmony_ci *
12562306a36Sopenharmony_ci * ST{ADD,CLR,SET,EOR} is simply encoded as an alias for
12662306a36Sopenharmony_ci * LDD{ADD,CLR,SET,EOR} with XZR as the destination register.
12762306a36Sopenharmony_ci */
12862306a36Sopenharmony_ci#define A64_ST_OP(sf, Rn, Rs, op) \
12962306a36Sopenharmony_ci	aarch64_insn_gen_atomic_ld_op(A64_ZR, Rn, Rs, \
13062306a36Sopenharmony_ci		A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_##op, \
13162306a36Sopenharmony_ci		AARCH64_INSN_MEM_ORDER_NONE)
13262306a36Sopenharmony_ci/* [Rn] <op>= Rs */
13362306a36Sopenharmony_ci#define A64_STADD(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, ADD)
13462306a36Sopenharmony_ci#define A64_STCLR(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, CLR)
13562306a36Sopenharmony_ci#define A64_STEOR(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, EOR)
13662306a36Sopenharmony_ci#define A64_STSET(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, SET)
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci#define A64_LD_OP_AL(sf, Rt, Rn, Rs, op) \
13962306a36Sopenharmony_ci	aarch64_insn_gen_atomic_ld_op(Rt, Rn, Rs, \
14062306a36Sopenharmony_ci		A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_##op, \
14162306a36Sopenharmony_ci		AARCH64_INSN_MEM_ORDER_ACQREL)
14262306a36Sopenharmony_ci/* Rt = [Rn] (load acquire); [Rn] <op>= Rs (store release) */
14362306a36Sopenharmony_ci#define A64_LDADDAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, ADD)
14462306a36Sopenharmony_ci#define A64_LDCLRAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, CLR)
14562306a36Sopenharmony_ci#define A64_LDEORAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, EOR)
14662306a36Sopenharmony_ci#define A64_LDSETAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, SET)
14762306a36Sopenharmony_ci/* Rt = [Rn] (load acquire); [Rn] = Rs (store release) */
14862306a36Sopenharmony_ci#define A64_SWPAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, SWP)
14962306a36Sopenharmony_ci/* Rs = CAS(Rn, Rs, Rt) (load acquire & store release) */
15062306a36Sopenharmony_ci#define A64_CASAL(sf, Rt, Rn, Rs) \
15162306a36Sopenharmony_ci	aarch64_insn_gen_cas(Rt, Rn, Rs, A64_SIZE(sf), \
15262306a36Sopenharmony_ci		AARCH64_INSN_MEM_ORDER_ACQREL)
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci/* Add/subtract (immediate) */
15562306a36Sopenharmony_ci#define A64_ADDSUB_IMM(sf, Rd, Rn, imm12, type) \
15662306a36Sopenharmony_ci	aarch64_insn_gen_add_sub_imm(Rd, Rn, imm12, \
15762306a36Sopenharmony_ci		A64_VARIANT(sf), AARCH64_INSN_ADSB_##type)
15862306a36Sopenharmony_ci/* Rd = Rn OP imm12 */
15962306a36Sopenharmony_ci#define A64_ADD_I(sf, Rd, Rn, imm12) A64_ADDSUB_IMM(sf, Rd, Rn, imm12, ADD)
16062306a36Sopenharmony_ci#define A64_SUB_I(sf, Rd, Rn, imm12) A64_ADDSUB_IMM(sf, Rd, Rn, imm12, SUB)
16162306a36Sopenharmony_ci#define A64_ADDS_I(sf, Rd, Rn, imm12) \
16262306a36Sopenharmony_ci	A64_ADDSUB_IMM(sf, Rd, Rn, imm12, ADD_SETFLAGS)
16362306a36Sopenharmony_ci#define A64_SUBS_I(sf, Rd, Rn, imm12) \
16462306a36Sopenharmony_ci	A64_ADDSUB_IMM(sf, Rd, Rn, imm12, SUB_SETFLAGS)
16562306a36Sopenharmony_ci/* Rn + imm12; set condition flags */
16662306a36Sopenharmony_ci#define A64_CMN_I(sf, Rn, imm12) A64_ADDS_I(sf, A64_ZR, Rn, imm12)
16762306a36Sopenharmony_ci/* Rn - imm12; set condition flags */
16862306a36Sopenharmony_ci#define A64_CMP_I(sf, Rn, imm12) A64_SUBS_I(sf, A64_ZR, Rn, imm12)
16962306a36Sopenharmony_ci/* Rd = Rn */
17062306a36Sopenharmony_ci#define A64_MOV(sf, Rd, Rn) A64_ADD_I(sf, Rd, Rn, 0)
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci/* Bitfield move */
17362306a36Sopenharmony_ci#define A64_BITFIELD(sf, Rd, Rn, immr, imms, type) \
17462306a36Sopenharmony_ci	aarch64_insn_gen_bitfield(Rd, Rn, immr, imms, \
17562306a36Sopenharmony_ci		A64_VARIANT(sf), AARCH64_INSN_BITFIELD_MOVE_##type)
17662306a36Sopenharmony_ci/* Signed, with sign replication to left and zeros to right */
17762306a36Sopenharmony_ci#define A64_SBFM(sf, Rd, Rn, ir, is) A64_BITFIELD(sf, Rd, Rn, ir, is, SIGNED)
17862306a36Sopenharmony_ci/* Unsigned, with zeros to left and right */
17962306a36Sopenharmony_ci#define A64_UBFM(sf, Rd, Rn, ir, is) A64_BITFIELD(sf, Rd, Rn, ir, is, UNSIGNED)
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci/* Rd = Rn << shift */
18262306a36Sopenharmony_ci#define A64_LSL(sf, Rd, Rn, shift) ({	\
18362306a36Sopenharmony_ci	int sz = (sf) ? 64 : 32;	\
18462306a36Sopenharmony_ci	A64_UBFM(sf, Rd, Rn, (unsigned)-(shift) % sz, sz - 1 - (shift)); \
18562306a36Sopenharmony_ci})
18662306a36Sopenharmony_ci/* Rd = Rn >> shift */
18762306a36Sopenharmony_ci#define A64_LSR(sf, Rd, Rn, shift) A64_UBFM(sf, Rd, Rn, shift, (sf) ? 63 : 31)
18862306a36Sopenharmony_ci/* Rd = Rn >> shift; signed */
18962306a36Sopenharmony_ci#define A64_ASR(sf, Rd, Rn, shift) A64_SBFM(sf, Rd, Rn, shift, (sf) ? 63 : 31)
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci/* Zero extend */
19262306a36Sopenharmony_ci#define A64_UXTH(sf, Rd, Rn) A64_UBFM(sf, Rd, Rn, 0, 15)
19362306a36Sopenharmony_ci#define A64_UXTW(sf, Rd, Rn) A64_UBFM(sf, Rd, Rn, 0, 31)
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci/* Sign extend */
19662306a36Sopenharmony_ci#define A64_SXTB(sf, Rd, Rn) A64_SBFM(sf, Rd, Rn, 0, 7)
19762306a36Sopenharmony_ci#define A64_SXTH(sf, Rd, Rn) A64_SBFM(sf, Rd, Rn, 0, 15)
19862306a36Sopenharmony_ci#define A64_SXTW(sf, Rd, Rn) A64_SBFM(sf, Rd, Rn, 0, 31)
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci/* Move wide (immediate) */
20162306a36Sopenharmony_ci#define A64_MOVEW(sf, Rd, imm16, shift, type) \
20262306a36Sopenharmony_ci	aarch64_insn_gen_movewide(Rd, imm16, shift, \
20362306a36Sopenharmony_ci		A64_VARIANT(sf), AARCH64_INSN_MOVEWIDE_##type)
20462306a36Sopenharmony_ci/* Rd = Zeros (for MOVZ);
20562306a36Sopenharmony_ci * Rd |= imm16 << shift (where shift is {0, 16, 32, 48});
20662306a36Sopenharmony_ci * Rd = ~Rd; (for MOVN); */
20762306a36Sopenharmony_ci#define A64_MOVN(sf, Rd, imm16, shift) A64_MOVEW(sf, Rd, imm16, shift, INVERSE)
20862306a36Sopenharmony_ci#define A64_MOVZ(sf, Rd, imm16, shift) A64_MOVEW(sf, Rd, imm16, shift, ZERO)
20962306a36Sopenharmony_ci#define A64_MOVK(sf, Rd, imm16, shift) A64_MOVEW(sf, Rd, imm16, shift, KEEP)
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci/* Add/subtract (shifted register) */
21262306a36Sopenharmony_ci#define A64_ADDSUB_SREG(sf, Rd, Rn, Rm, type) \
21362306a36Sopenharmony_ci	aarch64_insn_gen_add_sub_shifted_reg(Rd, Rn, Rm, 0, \
21462306a36Sopenharmony_ci		A64_VARIANT(sf), AARCH64_INSN_ADSB_##type)
21562306a36Sopenharmony_ci/* Rd = Rn OP Rm */
21662306a36Sopenharmony_ci#define A64_ADD(sf, Rd, Rn, Rm)  A64_ADDSUB_SREG(sf, Rd, Rn, Rm, ADD)
21762306a36Sopenharmony_ci#define A64_SUB(sf, Rd, Rn, Rm)  A64_ADDSUB_SREG(sf, Rd, Rn, Rm, SUB)
21862306a36Sopenharmony_ci#define A64_SUBS(sf, Rd, Rn, Rm) A64_ADDSUB_SREG(sf, Rd, Rn, Rm, SUB_SETFLAGS)
21962306a36Sopenharmony_ci/* Rd = -Rm */
22062306a36Sopenharmony_ci#define A64_NEG(sf, Rd, Rm) A64_SUB(sf, Rd, A64_ZR, Rm)
22162306a36Sopenharmony_ci/* Rn - Rm; set condition flags */
22262306a36Sopenharmony_ci#define A64_CMP(sf, Rn, Rm) A64_SUBS(sf, A64_ZR, Rn, Rm)
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci/* Data-processing (1 source) */
22562306a36Sopenharmony_ci#define A64_DATA1(sf, Rd, Rn, type) aarch64_insn_gen_data1(Rd, Rn, \
22662306a36Sopenharmony_ci	A64_VARIANT(sf), AARCH64_INSN_DATA1_##type)
22762306a36Sopenharmony_ci/* Rd = BSWAPx(Rn) */
22862306a36Sopenharmony_ci#define A64_REV16(sf, Rd, Rn) A64_DATA1(sf, Rd, Rn, REVERSE_16)
22962306a36Sopenharmony_ci#define A64_REV32(sf, Rd, Rn) A64_DATA1(sf, Rd, Rn, REVERSE_32)
23062306a36Sopenharmony_ci#define A64_REV64(Rd, Rn)     A64_DATA1(1, Rd, Rn, REVERSE_64)
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci/* Data-processing (2 source) */
23362306a36Sopenharmony_ci/* Rd = Rn OP Rm */
23462306a36Sopenharmony_ci#define A64_DATA2(sf, Rd, Rn, Rm, type) aarch64_insn_gen_data2(Rd, Rn, Rm, \
23562306a36Sopenharmony_ci	A64_VARIANT(sf), AARCH64_INSN_DATA2_##type)
23662306a36Sopenharmony_ci#define A64_UDIV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, UDIV)
23762306a36Sopenharmony_ci#define A64_SDIV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, SDIV)
23862306a36Sopenharmony_ci#define A64_LSLV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, LSLV)
23962306a36Sopenharmony_ci#define A64_LSRV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, LSRV)
24062306a36Sopenharmony_ci#define A64_ASRV(sf, Rd, Rn, Rm) A64_DATA2(sf, Rd, Rn, Rm, ASRV)
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci/* Data-processing (3 source) */
24362306a36Sopenharmony_ci/* Rd = Ra + Rn * Rm */
24462306a36Sopenharmony_ci#define A64_MADD(sf, Rd, Ra, Rn, Rm) aarch64_insn_gen_data3(Rd, Ra, Rn, Rm, \
24562306a36Sopenharmony_ci	A64_VARIANT(sf), AARCH64_INSN_DATA3_MADD)
24662306a36Sopenharmony_ci/* Rd = Ra - Rn * Rm */
24762306a36Sopenharmony_ci#define A64_MSUB(sf, Rd, Ra, Rn, Rm) aarch64_insn_gen_data3(Rd, Ra, Rn, Rm, \
24862306a36Sopenharmony_ci	A64_VARIANT(sf), AARCH64_INSN_DATA3_MSUB)
24962306a36Sopenharmony_ci/* Rd = Rn * Rm */
25062306a36Sopenharmony_ci#define A64_MUL(sf, Rd, Rn, Rm) A64_MADD(sf, Rd, A64_ZR, Rn, Rm)
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci/* Logical (shifted register) */
25362306a36Sopenharmony_ci#define A64_LOGIC_SREG(sf, Rd, Rn, Rm, type) \
25462306a36Sopenharmony_ci	aarch64_insn_gen_logical_shifted_reg(Rd, Rn, Rm, 0, \
25562306a36Sopenharmony_ci		A64_VARIANT(sf), AARCH64_INSN_LOGIC_##type)
25662306a36Sopenharmony_ci/* Rd = Rn OP Rm */
25762306a36Sopenharmony_ci#define A64_AND(sf, Rd, Rn, Rm)  A64_LOGIC_SREG(sf, Rd, Rn, Rm, AND)
25862306a36Sopenharmony_ci#define A64_ORR(sf, Rd, Rn, Rm)  A64_LOGIC_SREG(sf, Rd, Rn, Rm, ORR)
25962306a36Sopenharmony_ci#define A64_EOR(sf, Rd, Rn, Rm)  A64_LOGIC_SREG(sf, Rd, Rn, Rm, EOR)
26062306a36Sopenharmony_ci#define A64_ANDS(sf, Rd, Rn, Rm) A64_LOGIC_SREG(sf, Rd, Rn, Rm, AND_SETFLAGS)
26162306a36Sopenharmony_ci/* Rn & Rm; set condition flags */
26262306a36Sopenharmony_ci#define A64_TST(sf, Rn, Rm) A64_ANDS(sf, A64_ZR, Rn, Rm)
26362306a36Sopenharmony_ci/* Rd = ~Rm (alias of ORN with A64_ZR as Rn) */
26462306a36Sopenharmony_ci#define A64_MVN(sf, Rd, Rm)  \
26562306a36Sopenharmony_ci	A64_LOGIC_SREG(sf, Rd, A64_ZR, Rm, ORN)
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci/* Logical (immediate) */
26862306a36Sopenharmony_ci#define A64_LOGIC_IMM(sf, Rd, Rn, imm, type) ({ \
26962306a36Sopenharmony_ci	u64 imm64 = (sf) ? (u64)imm : (u64)(u32)imm; \
27062306a36Sopenharmony_ci	aarch64_insn_gen_logical_immediate(AARCH64_INSN_LOGIC_##type, \
27162306a36Sopenharmony_ci		A64_VARIANT(sf), Rn, Rd, imm64); \
27262306a36Sopenharmony_ci})
27362306a36Sopenharmony_ci/* Rd = Rn OP imm */
27462306a36Sopenharmony_ci#define A64_AND_I(sf, Rd, Rn, imm) A64_LOGIC_IMM(sf, Rd, Rn, imm, AND)
27562306a36Sopenharmony_ci#define A64_ORR_I(sf, Rd, Rn, imm) A64_LOGIC_IMM(sf, Rd, Rn, imm, ORR)
27662306a36Sopenharmony_ci#define A64_EOR_I(sf, Rd, Rn, imm) A64_LOGIC_IMM(sf, Rd, Rn, imm, EOR)
27762306a36Sopenharmony_ci#define A64_ANDS_I(sf, Rd, Rn, imm) A64_LOGIC_IMM(sf, Rd, Rn, imm, AND_SETFLAGS)
27862306a36Sopenharmony_ci/* Rn & imm; set condition flags */
27962306a36Sopenharmony_ci#define A64_TST_I(sf, Rn, imm) A64_ANDS_I(sf, A64_ZR, Rn, imm)
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci/* HINTs */
28262306a36Sopenharmony_ci#define A64_HINT(x) aarch64_insn_gen_hint(x)
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci#define A64_PACIASP A64_HINT(AARCH64_INSN_HINT_PACIASP)
28562306a36Sopenharmony_ci#define A64_AUTIASP A64_HINT(AARCH64_INSN_HINT_AUTIASP)
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci/* BTI */
28862306a36Sopenharmony_ci#define A64_BTI_C  A64_HINT(AARCH64_INSN_HINT_BTIC)
28962306a36Sopenharmony_ci#define A64_BTI_J  A64_HINT(AARCH64_INSN_HINT_BTIJ)
29062306a36Sopenharmony_ci#define A64_BTI_JC A64_HINT(AARCH64_INSN_HINT_BTIJC)
29162306a36Sopenharmony_ci#define A64_NOP    A64_HINT(AARCH64_INSN_HINT_NOP)
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci/* DMB */
29462306a36Sopenharmony_ci#define A64_DMB_ISH aarch64_insn_gen_dmb(AARCH64_INSN_MB_ISH)
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci/* ADR */
29762306a36Sopenharmony_ci#define A64_ADR(Rd, offset) \
29862306a36Sopenharmony_ci	aarch64_insn_gen_adr(0, offset, Rd, AARCH64_INSN_ADR_TYPE_ADR)
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci#endif /* _BPF_JIT_H */
301