cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

insn.c (41022B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2013 Huawei Ltd.
      4 * Author: Jiang Liu <liuj97@gmail.com>
      5 *
      6 * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com>
      7 */
      8#include <linux/bitops.h>
      9#include <linux/bug.h>
     10#include <linux/printk.h>
     11#include <linux/sizes.h>
     12#include <linux/types.h>
     13
     14#include <asm/debug-monitors.h>
     15#include <asm/errno.h>
     16#include <asm/insn.h>
     17#include <asm/kprobes.h>
     18
     19#define AARCH64_INSN_SF_BIT	BIT(31)
     20#define AARCH64_INSN_N_BIT	BIT(22)
     21#define AARCH64_INSN_LSL_12	BIT(22)
     22
     23static const int aarch64_insn_encoding_class[] = {
     24	AARCH64_INSN_CLS_UNKNOWN,
     25	AARCH64_INSN_CLS_UNKNOWN,
     26	AARCH64_INSN_CLS_SVE,
     27	AARCH64_INSN_CLS_UNKNOWN,
     28	AARCH64_INSN_CLS_LDST,
     29	AARCH64_INSN_CLS_DP_REG,
     30	AARCH64_INSN_CLS_LDST,
     31	AARCH64_INSN_CLS_DP_FPSIMD,
     32	AARCH64_INSN_CLS_DP_IMM,
     33	AARCH64_INSN_CLS_DP_IMM,
     34	AARCH64_INSN_CLS_BR_SYS,
     35	AARCH64_INSN_CLS_BR_SYS,
     36	AARCH64_INSN_CLS_LDST,
     37	AARCH64_INSN_CLS_DP_REG,
     38	AARCH64_INSN_CLS_LDST,
     39	AARCH64_INSN_CLS_DP_FPSIMD,
     40};
     41
     42enum aarch64_insn_encoding_class __kprobes aarch64_get_insn_class(u32 insn)
     43{
     44	return aarch64_insn_encoding_class[(insn >> 25) & 0xf];
     45}
     46
     47bool __kprobes aarch64_insn_is_steppable_hint(u32 insn)
     48{
     49	if (!aarch64_insn_is_hint(insn))
     50		return false;
     51
     52	switch (insn & 0xFE0) {
     53	case AARCH64_INSN_HINT_XPACLRI:
     54	case AARCH64_INSN_HINT_PACIA_1716:
     55	case AARCH64_INSN_HINT_PACIB_1716:
     56	case AARCH64_INSN_HINT_PACIAZ:
     57	case AARCH64_INSN_HINT_PACIASP:
     58	case AARCH64_INSN_HINT_PACIBZ:
     59	case AARCH64_INSN_HINT_PACIBSP:
     60	case AARCH64_INSN_HINT_BTI:
     61	case AARCH64_INSN_HINT_BTIC:
     62	case AARCH64_INSN_HINT_BTIJ:
     63	case AARCH64_INSN_HINT_BTIJC:
     64	case AARCH64_INSN_HINT_NOP:
     65		return true;
     66	default:
     67		return false;
     68	}
     69}
     70
     71bool aarch64_insn_is_branch_imm(u32 insn)
     72{
     73	return (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn) ||
     74		aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn) ||
     75		aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) ||
     76		aarch64_insn_is_bcond(insn));
     77}
     78
     79bool __kprobes aarch64_insn_uses_literal(u32 insn)
     80{
     81	/* ldr/ldrsw (literal), prfm */
     82
     83	return aarch64_insn_is_ldr_lit(insn) ||
     84		aarch64_insn_is_ldrsw_lit(insn) ||
     85		aarch64_insn_is_adr_adrp(insn) ||
     86		aarch64_insn_is_prfm_lit(insn);
     87}
     88
     89bool __kprobes aarch64_insn_is_branch(u32 insn)
     90{
     91	/* b, bl, cb*, tb*, ret*, b.cond, br*, blr* */
     92
     93	return aarch64_insn_is_b(insn) ||
     94		aarch64_insn_is_bl(insn) ||
     95		aarch64_insn_is_cbz(insn) ||
     96		aarch64_insn_is_cbnz(insn) ||
     97		aarch64_insn_is_tbz(insn) ||
     98		aarch64_insn_is_tbnz(insn) ||
     99		aarch64_insn_is_ret(insn) ||
    100		aarch64_insn_is_ret_auth(insn) ||
    101		aarch64_insn_is_br(insn) ||
    102		aarch64_insn_is_br_auth(insn) ||
    103		aarch64_insn_is_blr(insn) ||
    104		aarch64_insn_is_blr_auth(insn) ||
    105		aarch64_insn_is_bcond(insn);
    106}
    107
    108static int __kprobes aarch64_get_imm_shift_mask(enum aarch64_insn_imm_type type,
    109						u32 *maskp, int *shiftp)
    110{
    111	u32 mask;
    112	int shift;
    113
    114	switch (type) {
    115	case AARCH64_INSN_IMM_26:
    116		mask = BIT(26) - 1;
    117		shift = 0;
    118		break;
    119	case AARCH64_INSN_IMM_19:
    120		mask = BIT(19) - 1;
    121		shift = 5;
    122		break;
    123	case AARCH64_INSN_IMM_16:
    124		mask = BIT(16) - 1;
    125		shift = 5;
    126		break;
    127	case AARCH64_INSN_IMM_14:
    128		mask = BIT(14) - 1;
    129		shift = 5;
    130		break;
    131	case AARCH64_INSN_IMM_12:
    132		mask = BIT(12) - 1;
    133		shift = 10;
    134		break;
    135	case AARCH64_INSN_IMM_9:
    136		mask = BIT(9) - 1;
    137		shift = 12;
    138		break;
    139	case AARCH64_INSN_IMM_7:
    140		mask = BIT(7) - 1;
    141		shift = 15;
    142		break;
    143	case AARCH64_INSN_IMM_6:
    144	case AARCH64_INSN_IMM_S:
    145		mask = BIT(6) - 1;
    146		shift = 10;
    147		break;
    148	case AARCH64_INSN_IMM_R:
    149		mask = BIT(6) - 1;
    150		shift = 16;
    151		break;
    152	case AARCH64_INSN_IMM_N:
    153		mask = 1;
    154		shift = 22;
    155		break;
    156	default:
    157		return -EINVAL;
    158	}
    159
    160	*maskp = mask;
    161	*shiftp = shift;
    162
    163	return 0;
    164}
    165
    166#define ADR_IMM_HILOSPLIT	2
    167#define ADR_IMM_SIZE		SZ_2M
    168#define ADR_IMM_LOMASK		((1 << ADR_IMM_HILOSPLIT) - 1)
    169#define ADR_IMM_HIMASK		((ADR_IMM_SIZE >> ADR_IMM_HILOSPLIT) - 1)
    170#define ADR_IMM_LOSHIFT		29
    171#define ADR_IMM_HISHIFT		5
    172
    173u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn)
    174{
    175	u32 immlo, immhi, mask;
    176	int shift;
    177
    178	switch (type) {
    179	case AARCH64_INSN_IMM_ADR:
    180		shift = 0;
    181		immlo = (insn >> ADR_IMM_LOSHIFT) & ADR_IMM_LOMASK;
    182		immhi = (insn >> ADR_IMM_HISHIFT) & ADR_IMM_HIMASK;
    183		insn = (immhi << ADR_IMM_HILOSPLIT) | immlo;
    184		mask = ADR_IMM_SIZE - 1;
    185		break;
    186	default:
    187		if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) {
    188			pr_err("%s: unknown immediate encoding %d\n", __func__,
    189			       type);
    190			return 0;
    191		}
    192	}
    193
    194	return (insn >> shift) & mask;
    195}
    196
    197u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
    198				  u32 insn, u64 imm)
    199{
    200	u32 immlo, immhi, mask;
    201	int shift;
    202
    203	if (insn == AARCH64_BREAK_FAULT)
    204		return AARCH64_BREAK_FAULT;
    205
    206	switch (type) {
    207	case AARCH64_INSN_IMM_ADR:
    208		shift = 0;
    209		immlo = (imm & ADR_IMM_LOMASK) << ADR_IMM_LOSHIFT;
    210		imm >>= ADR_IMM_HILOSPLIT;
    211		immhi = (imm & ADR_IMM_HIMASK) << ADR_IMM_HISHIFT;
    212		imm = immlo | immhi;
    213		mask = ((ADR_IMM_LOMASK << ADR_IMM_LOSHIFT) |
    214			(ADR_IMM_HIMASK << ADR_IMM_HISHIFT));
    215		break;
    216	default:
    217		if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) {
    218			pr_err("%s: unknown immediate encoding %d\n", __func__,
    219			       type);
    220			return AARCH64_BREAK_FAULT;
    221		}
    222	}
    223
    224	/* Update the immediate field. */
    225	insn &= ~(mask << shift);
    226	insn |= (imm & mask) << shift;
    227
    228	return insn;
    229}
    230
    231u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type,
    232					u32 insn)
    233{
    234	int shift;
    235
    236	switch (type) {
    237	case AARCH64_INSN_REGTYPE_RT:
    238	case AARCH64_INSN_REGTYPE_RD:
    239		shift = 0;
    240		break;
    241	case AARCH64_INSN_REGTYPE_RN:
    242		shift = 5;
    243		break;
    244	case AARCH64_INSN_REGTYPE_RT2:
    245	case AARCH64_INSN_REGTYPE_RA:
    246		shift = 10;
    247		break;
    248	case AARCH64_INSN_REGTYPE_RM:
    249		shift = 16;
    250		break;
    251	default:
    252		pr_err("%s: unknown register type encoding %d\n", __func__,
    253		       type);
    254		return 0;
    255	}
    256
    257	return (insn >> shift) & GENMASK(4, 0);
    258}
    259
    260static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
    261					u32 insn,
    262					enum aarch64_insn_register reg)
    263{
    264	int shift;
    265
    266	if (insn == AARCH64_BREAK_FAULT)
    267		return AARCH64_BREAK_FAULT;
    268
    269	if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) {
    270		pr_err("%s: unknown register encoding %d\n", __func__, reg);
    271		return AARCH64_BREAK_FAULT;
    272	}
    273
    274	switch (type) {
    275	case AARCH64_INSN_REGTYPE_RT:
    276	case AARCH64_INSN_REGTYPE_RD:
    277		shift = 0;
    278		break;
    279	case AARCH64_INSN_REGTYPE_RN:
    280		shift = 5;
    281		break;
    282	case AARCH64_INSN_REGTYPE_RT2:
    283	case AARCH64_INSN_REGTYPE_RA:
    284		shift = 10;
    285		break;
    286	case AARCH64_INSN_REGTYPE_RM:
    287	case AARCH64_INSN_REGTYPE_RS:
    288		shift = 16;
    289		break;
    290	default:
    291		pr_err("%s: unknown register type encoding %d\n", __func__,
    292		       type);
    293		return AARCH64_BREAK_FAULT;
    294	}
    295
    296	insn &= ~(GENMASK(4, 0) << shift);
    297	insn |= reg << shift;
    298
    299	return insn;
    300}
    301
    302static const u32 aarch64_insn_ldst_size[] = {
    303	[AARCH64_INSN_SIZE_8] = 0,
    304	[AARCH64_INSN_SIZE_16] = 1,
    305	[AARCH64_INSN_SIZE_32] = 2,
    306	[AARCH64_INSN_SIZE_64] = 3,
    307};
    308
    309static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
    310					 u32 insn)
    311{
    312	u32 size;
    313
    314	if (type < AARCH64_INSN_SIZE_8 || type > AARCH64_INSN_SIZE_64) {
    315		pr_err("%s: unknown size encoding %d\n", __func__, type);
    316		return AARCH64_BREAK_FAULT;
    317	}
    318
    319	size = aarch64_insn_ldst_size[type];
    320	insn &= ~GENMASK(31, 30);
    321	insn |= size << 30;
    322
    323	return insn;
    324}
    325
    326static inline long branch_imm_common(unsigned long pc, unsigned long addr,
    327				     long range)
    328{
    329	long offset;
    330
    331	if ((pc & 0x3) || (addr & 0x3)) {
    332		pr_err("%s: A64 instructions must be word aligned\n", __func__);
    333		return range;
    334	}
    335
    336	offset = ((long)addr - (long)pc);
    337
    338	if (offset < -range || offset >= range) {
    339		pr_err("%s: offset out of range\n", __func__);
    340		return range;
    341	}
    342
    343	return offset;
    344}
    345
    346u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
    347					  enum aarch64_insn_branch_type type)
    348{
    349	u32 insn;
    350	long offset;
    351
    352	/*
    353	 * B/BL support [-128M, 128M) offset
    354	 * ARM64 virtual address arrangement guarantees all kernel and module
    355	 * texts are within +/-128M.
    356	 */
    357	offset = branch_imm_common(pc, addr, SZ_128M);
    358	if (offset >= SZ_128M)
    359		return AARCH64_BREAK_FAULT;
    360
    361	switch (type) {
    362	case AARCH64_INSN_BRANCH_LINK:
    363		insn = aarch64_insn_get_bl_value();
    364		break;
    365	case AARCH64_INSN_BRANCH_NOLINK:
    366		insn = aarch64_insn_get_b_value();
    367		break;
    368	default:
    369		pr_err("%s: unknown branch encoding %d\n", __func__, type);
    370		return AARCH64_BREAK_FAULT;
    371	}
    372
    373	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn,
    374					     offset >> 2);
    375}
    376
    377u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
    378				     enum aarch64_insn_register reg,
    379				     enum aarch64_insn_variant variant,
    380				     enum aarch64_insn_branch_type type)
    381{
    382	u32 insn;
    383	long offset;
    384
    385	offset = branch_imm_common(pc, addr, SZ_1M);
    386	if (offset >= SZ_1M)
    387		return AARCH64_BREAK_FAULT;
    388
    389	switch (type) {
    390	case AARCH64_INSN_BRANCH_COMP_ZERO:
    391		insn = aarch64_insn_get_cbz_value();
    392		break;
    393	case AARCH64_INSN_BRANCH_COMP_NONZERO:
    394		insn = aarch64_insn_get_cbnz_value();
    395		break;
    396	default:
    397		pr_err("%s: unknown branch encoding %d\n", __func__, type);
    398		return AARCH64_BREAK_FAULT;
    399	}
    400
    401	switch (variant) {
    402	case AARCH64_INSN_VARIANT_32BIT:
    403		break;
    404	case AARCH64_INSN_VARIANT_64BIT:
    405		insn |= AARCH64_INSN_SF_BIT;
    406		break;
    407	default:
    408		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
    409		return AARCH64_BREAK_FAULT;
    410	}
    411
    412	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
    413
    414	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
    415					     offset >> 2);
    416}
    417
    418u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr,
    419				     enum aarch64_insn_condition cond)
    420{
    421	u32 insn;
    422	long offset;
    423
    424	offset = branch_imm_common(pc, addr, SZ_1M);
    425
    426	insn = aarch64_insn_get_bcond_value();
    427
    428	if (cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL) {
    429		pr_err("%s: unknown condition encoding %d\n", __func__, cond);
    430		return AARCH64_BREAK_FAULT;
    431	}
    432	insn |= cond;
    433
    434	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
    435					     offset >> 2);
    436}
    437
    438u32 __kprobes aarch64_insn_gen_hint(enum aarch64_insn_hint_cr_op op)
    439{
    440	return aarch64_insn_get_hint_value() | op;
    441}
    442
    443u32 __kprobes aarch64_insn_gen_nop(void)
    444{
    445	return aarch64_insn_gen_hint(AARCH64_INSN_HINT_NOP);
    446}
    447
    448u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg,
    449				enum aarch64_insn_branch_type type)
    450{
    451	u32 insn;
    452
    453	switch (type) {
    454	case AARCH64_INSN_BRANCH_NOLINK:
    455		insn = aarch64_insn_get_br_value();
    456		break;
    457	case AARCH64_INSN_BRANCH_LINK:
    458		insn = aarch64_insn_get_blr_value();
    459		break;
    460	case AARCH64_INSN_BRANCH_RETURN:
    461		insn = aarch64_insn_get_ret_value();
    462		break;
    463	default:
    464		pr_err("%s: unknown branch encoding %d\n", __func__, type);
    465		return AARCH64_BREAK_FAULT;
    466	}
    467
    468	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, reg);
    469}
    470
    471u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg,
    472				    enum aarch64_insn_register base,
    473				    enum aarch64_insn_register offset,
    474				    enum aarch64_insn_size_type size,
    475				    enum aarch64_insn_ldst_type type)
    476{
    477	u32 insn;
    478
    479	switch (type) {
    480	case AARCH64_INSN_LDST_LOAD_REG_OFFSET:
    481		insn = aarch64_insn_get_ldr_reg_value();
    482		break;
    483	case AARCH64_INSN_LDST_STORE_REG_OFFSET:
    484		insn = aarch64_insn_get_str_reg_value();
    485		break;
    486	default:
    487		pr_err("%s: unknown load/store encoding %d\n", __func__, type);
    488		return AARCH64_BREAK_FAULT;
    489	}
    490
    491	insn = aarch64_insn_encode_ldst_size(size, insn);
    492
    493	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
    494
    495	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
    496					    base);
    497
    498	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn,
    499					    offset);
    500}
    501
    502u32 aarch64_insn_gen_load_store_imm(enum aarch64_insn_register reg,
    503				    enum aarch64_insn_register base,
    504				    unsigned int imm,
    505				    enum aarch64_insn_size_type size,
    506				    enum aarch64_insn_ldst_type type)
    507{
    508	u32 insn;
    509	u32 shift;
    510
    511	if (size < AARCH64_INSN_SIZE_8 || size > AARCH64_INSN_SIZE_64) {
    512		pr_err("%s: unknown size encoding %d\n", __func__, type);
    513		return AARCH64_BREAK_FAULT;
    514	}
    515
    516	shift = aarch64_insn_ldst_size[size];
    517	if (imm & ~(BIT(12 + shift) - BIT(shift))) {
    518		pr_err("%s: invalid imm: %d\n", __func__, imm);
    519		return AARCH64_BREAK_FAULT;
    520	}
    521
    522	imm >>= shift;
    523
    524	switch (type) {
    525	case AARCH64_INSN_LDST_LOAD_IMM_OFFSET:
    526		insn = aarch64_insn_get_ldr_imm_value();
    527		break;
    528	case AARCH64_INSN_LDST_STORE_IMM_OFFSET:
    529		insn = aarch64_insn_get_str_imm_value();
    530		break;
    531	default:
    532		pr_err("%s: unknown load/store encoding %d\n", __func__, type);
    533		return AARCH64_BREAK_FAULT;
    534	}
    535
    536	insn = aarch64_insn_encode_ldst_size(size, insn);
    537
    538	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
    539
    540	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
    541					    base);
    542
    543	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, imm);
    544}
    545
    546u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1,
    547				     enum aarch64_insn_register reg2,
    548				     enum aarch64_insn_register base,
    549				     int offset,
    550				     enum aarch64_insn_variant variant,
    551				     enum aarch64_insn_ldst_type type)
    552{
    553	u32 insn;
    554	int shift;
    555
    556	switch (type) {
    557	case AARCH64_INSN_LDST_LOAD_PAIR_PRE_INDEX:
    558		insn = aarch64_insn_get_ldp_pre_value();
    559		break;
    560	case AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX:
    561		insn = aarch64_insn_get_stp_pre_value();
    562		break;
    563	case AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX:
    564		insn = aarch64_insn_get_ldp_post_value();
    565		break;
    566	case AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX:
    567		insn = aarch64_insn_get_stp_post_value();
    568		break;
    569	default:
    570		pr_err("%s: unknown load/store encoding %d\n", __func__, type);
    571		return AARCH64_BREAK_FAULT;
    572	}
    573
    574	switch (variant) {
    575	case AARCH64_INSN_VARIANT_32BIT:
    576		if ((offset & 0x3) || (offset < -256) || (offset > 252)) {
    577			pr_err("%s: offset must be multiples of 4 in the range of [-256, 252] %d\n",
    578			       __func__, offset);
    579			return AARCH64_BREAK_FAULT;
    580		}
    581		shift = 2;
    582		break;
    583	case AARCH64_INSN_VARIANT_64BIT:
    584		if ((offset & 0x7) || (offset < -512) || (offset > 504)) {
    585			pr_err("%s: offset must be multiples of 8 in the range of [-512, 504] %d\n",
    586			       __func__, offset);
    587			return AARCH64_BREAK_FAULT;
    588		}
    589		shift = 3;
    590		insn |= AARCH64_INSN_SF_BIT;
    591		break;
    592	default:
    593		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
    594		return AARCH64_BREAK_FAULT;
    595	}
    596
    597	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
    598					    reg1);
    599
    600	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT2, insn,
    601					    reg2);
    602
    603	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
    604					    base);
    605
    606	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_7, insn,
    607					     offset >> shift);
    608}
    609
    610u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
    611				   enum aarch64_insn_register base,
    612				   enum aarch64_insn_register state,
    613				   enum aarch64_insn_size_type size,
    614				   enum aarch64_insn_ldst_type type)
    615{
    616	u32 insn;
    617
    618	switch (type) {
    619	case AARCH64_INSN_LDST_LOAD_EX:
    620	case AARCH64_INSN_LDST_LOAD_ACQ_EX:
    621		insn = aarch64_insn_get_load_ex_value();
    622		if (type == AARCH64_INSN_LDST_LOAD_ACQ_EX)
    623			insn |= BIT(15);
    624		break;
    625	case AARCH64_INSN_LDST_STORE_EX:
    626	case AARCH64_INSN_LDST_STORE_REL_EX:
    627		insn = aarch64_insn_get_store_ex_value();
    628		if (type == AARCH64_INSN_LDST_STORE_REL_EX)
    629			insn |= BIT(15);
    630		break;
    631	default:
    632		pr_err("%s: unknown load/store exclusive encoding %d\n", __func__, type);
    633		return AARCH64_BREAK_FAULT;
    634	}
    635
    636	insn = aarch64_insn_encode_ldst_size(size, insn);
    637
    638	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
    639					    reg);
    640
    641	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
    642					    base);
    643
    644	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT2, insn,
    645					    AARCH64_INSN_REG_ZR);
    646
    647	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
    648					    state);
    649}
    650
    651#ifdef CONFIG_ARM64_LSE_ATOMICS
    652static u32 aarch64_insn_encode_ldst_order(enum aarch64_insn_mem_order_type type,
    653					  u32 insn)
    654{
    655	u32 order;
    656
    657	switch (type) {
    658	case AARCH64_INSN_MEM_ORDER_NONE:
    659		order = 0;
    660		break;
    661	case AARCH64_INSN_MEM_ORDER_ACQ:
    662		order = 2;
    663		break;
    664	case AARCH64_INSN_MEM_ORDER_REL:
    665		order = 1;
    666		break;
    667	case AARCH64_INSN_MEM_ORDER_ACQREL:
    668		order = 3;
    669		break;
    670	default:
    671		pr_err("%s: unknown mem order %d\n", __func__, type);
    672		return AARCH64_BREAK_FAULT;
    673	}
    674
    675	insn &= ~GENMASK(23, 22);
    676	insn |= order << 22;
    677
    678	return insn;
    679}
    680
    681u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
    682				  enum aarch64_insn_register address,
    683				  enum aarch64_insn_register value,
    684				  enum aarch64_insn_size_type size,
    685				  enum aarch64_insn_mem_atomic_op op,
    686				  enum aarch64_insn_mem_order_type order)
    687{
    688	u32 insn;
    689
    690	switch (op) {
    691	case AARCH64_INSN_MEM_ATOMIC_ADD:
    692		insn = aarch64_insn_get_ldadd_value();
    693		break;
    694	case AARCH64_INSN_MEM_ATOMIC_CLR:
    695		insn = aarch64_insn_get_ldclr_value();
    696		break;
    697	case AARCH64_INSN_MEM_ATOMIC_EOR:
    698		insn = aarch64_insn_get_ldeor_value();
    699		break;
    700	case AARCH64_INSN_MEM_ATOMIC_SET:
    701		insn = aarch64_insn_get_ldset_value();
    702		break;
    703	case AARCH64_INSN_MEM_ATOMIC_SWP:
    704		insn = aarch64_insn_get_swp_value();
    705		break;
    706	default:
    707		pr_err("%s: unimplemented mem atomic op %d\n", __func__, op);
    708		return AARCH64_BREAK_FAULT;
    709	}
    710
    711	switch (size) {
    712	case AARCH64_INSN_SIZE_32:
    713	case AARCH64_INSN_SIZE_64:
    714		break;
    715	default:
    716		pr_err("%s: unimplemented size encoding %d\n", __func__, size);
    717		return AARCH64_BREAK_FAULT;
    718	}
    719
    720	insn = aarch64_insn_encode_ldst_size(size, insn);
    721
    722	insn = aarch64_insn_encode_ldst_order(order, insn);
    723
    724	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
    725					    result);
    726
    727	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
    728					    address);
    729
    730	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
    731					    value);
    732}
    733
    734static u32 aarch64_insn_encode_cas_order(enum aarch64_insn_mem_order_type type,
    735					 u32 insn)
    736{
    737	u32 order;
    738
    739	switch (type) {
    740	case AARCH64_INSN_MEM_ORDER_NONE:
    741		order = 0;
    742		break;
    743	case AARCH64_INSN_MEM_ORDER_ACQ:
    744		order = BIT(22);
    745		break;
    746	case AARCH64_INSN_MEM_ORDER_REL:
    747		order = BIT(15);
    748		break;
    749	case AARCH64_INSN_MEM_ORDER_ACQREL:
    750		order = BIT(15) | BIT(22);
    751		break;
    752	default:
    753		pr_err("%s: unknown mem order %d\n", __func__, type);
    754		return AARCH64_BREAK_FAULT;
    755	}
    756
    757	insn &= ~(BIT(15) | BIT(22));
    758	insn |= order;
    759
    760	return insn;
    761}
    762
    763u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
    764			 enum aarch64_insn_register address,
    765			 enum aarch64_insn_register value,
    766			 enum aarch64_insn_size_type size,
    767			 enum aarch64_insn_mem_order_type order)
    768{
    769	u32 insn;
    770
    771	switch (size) {
    772	case AARCH64_INSN_SIZE_32:
    773	case AARCH64_INSN_SIZE_64:
    774		break;
    775	default:
    776		pr_err("%s: unimplemented size encoding %d\n", __func__, size);
    777		return AARCH64_BREAK_FAULT;
    778	}
    779
    780	insn = aarch64_insn_get_cas_value();
    781
    782	insn = aarch64_insn_encode_ldst_size(size, insn);
    783
    784	insn = aarch64_insn_encode_cas_order(order, insn);
    785
    786	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
    787					    result);
    788
    789	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
    790					    address);
    791
    792	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
    793					    value);
    794}
    795#endif
    796
    797static u32 aarch64_insn_encode_prfm_imm(enum aarch64_insn_prfm_type type,
    798					enum aarch64_insn_prfm_target target,
    799					enum aarch64_insn_prfm_policy policy,
    800					u32 insn)
    801{
    802	u32 imm_type = 0, imm_target = 0, imm_policy = 0;
    803
    804	switch (type) {
    805	case AARCH64_INSN_PRFM_TYPE_PLD:
    806		break;
    807	case AARCH64_INSN_PRFM_TYPE_PLI:
    808		imm_type = BIT(0);
    809		break;
    810	case AARCH64_INSN_PRFM_TYPE_PST:
    811		imm_type = BIT(1);
    812		break;
    813	default:
    814		pr_err("%s: unknown prfm type encoding %d\n", __func__, type);
    815		return AARCH64_BREAK_FAULT;
    816	}
    817
    818	switch (target) {
    819	case AARCH64_INSN_PRFM_TARGET_L1:
    820		break;
    821	case AARCH64_INSN_PRFM_TARGET_L2:
    822		imm_target = BIT(0);
    823		break;
    824	case AARCH64_INSN_PRFM_TARGET_L3:
    825		imm_target = BIT(1);
    826		break;
    827	default:
    828		pr_err("%s: unknown prfm target encoding %d\n", __func__, target);
    829		return AARCH64_BREAK_FAULT;
    830	}
    831
    832	switch (policy) {
    833	case AARCH64_INSN_PRFM_POLICY_KEEP:
    834		break;
    835	case AARCH64_INSN_PRFM_POLICY_STRM:
    836		imm_policy = BIT(0);
    837		break;
    838	default:
    839		pr_err("%s: unknown prfm policy encoding %d\n", __func__, policy);
    840		return AARCH64_BREAK_FAULT;
    841	}
    842
    843	/* In this case, imm5 is encoded into Rt field. */
    844	insn &= ~GENMASK(4, 0);
    845	insn |= imm_policy | (imm_target << 1) | (imm_type << 3);
    846
    847	return insn;
    848}
    849
    850u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base,
    851			      enum aarch64_insn_prfm_type type,
    852			      enum aarch64_insn_prfm_target target,
    853			      enum aarch64_insn_prfm_policy policy)
    854{
    855	u32 insn = aarch64_insn_get_prfm_value();
    856
    857	insn = aarch64_insn_encode_ldst_size(AARCH64_INSN_SIZE_64, insn);
    858
    859	insn = aarch64_insn_encode_prfm_imm(type, target, policy, insn);
    860
    861	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
    862					    base);
    863
    864	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, 0);
    865}
    866
    867u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
    868				 enum aarch64_insn_register src,
    869				 int imm, enum aarch64_insn_variant variant,
    870				 enum aarch64_insn_adsb_type type)
    871{
    872	u32 insn;
    873
    874	switch (type) {
    875	case AARCH64_INSN_ADSB_ADD:
    876		insn = aarch64_insn_get_add_imm_value();
    877		break;
    878	case AARCH64_INSN_ADSB_SUB:
    879		insn = aarch64_insn_get_sub_imm_value();
    880		break;
    881	case AARCH64_INSN_ADSB_ADD_SETFLAGS:
    882		insn = aarch64_insn_get_adds_imm_value();
    883		break;
    884	case AARCH64_INSN_ADSB_SUB_SETFLAGS:
    885		insn = aarch64_insn_get_subs_imm_value();
    886		break;
    887	default:
    888		pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
    889		return AARCH64_BREAK_FAULT;
    890	}
    891
    892	switch (variant) {
    893	case AARCH64_INSN_VARIANT_32BIT:
    894		break;
    895	case AARCH64_INSN_VARIANT_64BIT:
    896		insn |= AARCH64_INSN_SF_BIT;
    897		break;
    898	default:
    899		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
    900		return AARCH64_BREAK_FAULT;
    901	}
    902
    903	/* We can't encode more than a 24bit value (12bit + 12bit shift) */
    904	if (imm & ~(BIT(24) - 1))
    905		goto out;
    906
    907	/* If we have something in the top 12 bits... */
    908	if (imm & ~(SZ_4K - 1)) {
    909		/* ... and in the low 12 bits -> error */
    910		if (imm & (SZ_4K - 1))
    911			goto out;
    912
    913		imm >>= 12;
    914		insn |= AARCH64_INSN_LSL_12;
    915	}
    916
    917	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
    918
    919	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
    920
    921	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, imm);
    922
    923out:
    924	pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
    925	return AARCH64_BREAK_FAULT;
    926}
    927
    928u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
    929			      enum aarch64_insn_register src,
    930			      int immr, int imms,
    931			      enum aarch64_insn_variant variant,
    932			      enum aarch64_insn_bitfield_type type)
    933{
    934	u32 insn;
    935	u32 mask;
    936
    937	switch (type) {
    938	case AARCH64_INSN_BITFIELD_MOVE:
    939		insn = aarch64_insn_get_bfm_value();
    940		break;
    941	case AARCH64_INSN_BITFIELD_MOVE_UNSIGNED:
    942		insn = aarch64_insn_get_ubfm_value();
    943		break;
    944	case AARCH64_INSN_BITFIELD_MOVE_SIGNED:
    945		insn = aarch64_insn_get_sbfm_value();
    946		break;
    947	default:
    948		pr_err("%s: unknown bitfield encoding %d\n", __func__, type);
    949		return AARCH64_BREAK_FAULT;
    950	}
    951
    952	switch (variant) {
    953	case AARCH64_INSN_VARIANT_32BIT:
    954		mask = GENMASK(4, 0);
    955		break;
    956	case AARCH64_INSN_VARIANT_64BIT:
    957		insn |= AARCH64_INSN_SF_BIT | AARCH64_INSN_N_BIT;
    958		mask = GENMASK(5, 0);
    959		break;
    960	default:
    961		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
    962		return AARCH64_BREAK_FAULT;
    963	}
    964
    965	if (immr & ~mask) {
    966		pr_err("%s: invalid immr encoding %d\n", __func__, immr);
    967		return AARCH64_BREAK_FAULT;
    968	}
    969	if (imms & ~mask) {
    970		pr_err("%s: invalid imms encoding %d\n", __func__, imms);
    971		return AARCH64_BREAK_FAULT;
    972	}
    973
    974	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
    975
    976	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
    977
    978	insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, immr);
    979
    980	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, imms);
    981}
    982
    983u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst,
    984			      int imm, int shift,
    985			      enum aarch64_insn_variant variant,
    986			      enum aarch64_insn_movewide_type type)
    987{
    988	u32 insn;
    989
    990	switch (type) {
    991	case AARCH64_INSN_MOVEWIDE_ZERO:
    992		insn = aarch64_insn_get_movz_value();
    993		break;
    994	case AARCH64_INSN_MOVEWIDE_KEEP:
    995		insn = aarch64_insn_get_movk_value();
    996		break;
    997	case AARCH64_INSN_MOVEWIDE_INVERSE:
    998		insn = aarch64_insn_get_movn_value();
    999		break;
   1000	default:
   1001		pr_err("%s: unknown movewide encoding %d\n", __func__, type);
   1002		return AARCH64_BREAK_FAULT;
   1003	}
   1004
   1005	if (imm & ~(SZ_64K - 1)) {
   1006		pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
   1007		return AARCH64_BREAK_FAULT;
   1008	}
   1009
   1010	switch (variant) {
   1011	case AARCH64_INSN_VARIANT_32BIT:
   1012		if (shift != 0 && shift != 16) {
   1013			pr_err("%s: invalid shift encoding %d\n", __func__,
   1014			       shift);
   1015			return AARCH64_BREAK_FAULT;
   1016		}
   1017		break;
   1018	case AARCH64_INSN_VARIANT_64BIT:
   1019		insn |= AARCH64_INSN_SF_BIT;
   1020		if (shift != 0 && shift != 16 && shift != 32 && shift != 48) {
   1021			pr_err("%s: invalid shift encoding %d\n", __func__,
   1022			       shift);
   1023			return AARCH64_BREAK_FAULT;
   1024		}
   1025		break;
   1026	default:
   1027		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
   1028		return AARCH64_BREAK_FAULT;
   1029	}
   1030
   1031	insn |= (shift >> 4) << 21;
   1032
   1033	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
   1034
   1035	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_16, insn, imm);
   1036}
   1037
   1038u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst,
   1039					 enum aarch64_insn_register src,
   1040					 enum aarch64_insn_register reg,
   1041					 int shift,
   1042					 enum aarch64_insn_variant variant,
   1043					 enum aarch64_insn_adsb_type type)
   1044{
   1045	u32 insn;
   1046
   1047	switch (type) {
   1048	case AARCH64_INSN_ADSB_ADD:
   1049		insn = aarch64_insn_get_add_value();
   1050		break;
   1051	case AARCH64_INSN_ADSB_SUB:
   1052		insn = aarch64_insn_get_sub_value();
   1053		break;
   1054	case AARCH64_INSN_ADSB_ADD_SETFLAGS:
   1055		insn = aarch64_insn_get_adds_value();
   1056		break;
   1057	case AARCH64_INSN_ADSB_SUB_SETFLAGS:
   1058		insn = aarch64_insn_get_subs_value();
   1059		break;
   1060	default:
   1061		pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
   1062		return AARCH64_BREAK_FAULT;
   1063	}
   1064
   1065	switch (variant) {
   1066	case AARCH64_INSN_VARIANT_32BIT:
   1067		if (shift & ~(SZ_32 - 1)) {
   1068			pr_err("%s: invalid shift encoding %d\n", __func__,
   1069			       shift);
   1070			return AARCH64_BREAK_FAULT;
   1071		}
   1072		break;
   1073	case AARCH64_INSN_VARIANT_64BIT:
   1074		insn |= AARCH64_INSN_SF_BIT;
   1075		if (shift & ~(SZ_64 - 1)) {
   1076			pr_err("%s: invalid shift encoding %d\n", __func__,
   1077			       shift);
   1078			return AARCH64_BREAK_FAULT;
   1079		}
   1080		break;
   1081	default:
   1082		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
   1083		return AARCH64_BREAK_FAULT;
   1084	}
   1085
   1086
   1087	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
   1088
   1089	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
   1090
   1091	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
   1092
   1093	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
   1094}
   1095
   1096u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst,
   1097			   enum aarch64_insn_register src,
   1098			   enum aarch64_insn_variant variant,
   1099			   enum aarch64_insn_data1_type type)
   1100{
   1101	u32 insn;
   1102
   1103	switch (type) {
   1104	case AARCH64_INSN_DATA1_REVERSE_16:
   1105		insn = aarch64_insn_get_rev16_value();
   1106		break;
   1107	case AARCH64_INSN_DATA1_REVERSE_32:
   1108		insn = aarch64_insn_get_rev32_value();
   1109		break;
   1110	case AARCH64_INSN_DATA1_REVERSE_64:
   1111		if (variant != AARCH64_INSN_VARIANT_64BIT) {
   1112			pr_err("%s: invalid variant for reverse64 %d\n",
   1113			       __func__, variant);
   1114			return AARCH64_BREAK_FAULT;
   1115		}
   1116		insn = aarch64_insn_get_rev64_value();
   1117		break;
   1118	default:
   1119		pr_err("%s: unknown data1 encoding %d\n", __func__, type);
   1120		return AARCH64_BREAK_FAULT;
   1121	}
   1122
   1123	switch (variant) {
   1124	case AARCH64_INSN_VARIANT_32BIT:
   1125		break;
   1126	case AARCH64_INSN_VARIANT_64BIT:
   1127		insn |= AARCH64_INSN_SF_BIT;
   1128		break;
   1129	default:
   1130		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
   1131		return AARCH64_BREAK_FAULT;
   1132	}
   1133
   1134	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
   1135
   1136	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
   1137}
   1138
   1139u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
   1140			   enum aarch64_insn_register src,
   1141			   enum aarch64_insn_register reg,
   1142			   enum aarch64_insn_variant variant,
   1143			   enum aarch64_insn_data2_type type)
   1144{
   1145	u32 insn;
   1146
   1147	switch (type) {
   1148	case AARCH64_INSN_DATA2_UDIV:
   1149		insn = aarch64_insn_get_udiv_value();
   1150		break;
   1151	case AARCH64_INSN_DATA2_SDIV:
   1152		insn = aarch64_insn_get_sdiv_value();
   1153		break;
   1154	case AARCH64_INSN_DATA2_LSLV:
   1155		insn = aarch64_insn_get_lslv_value();
   1156		break;
   1157	case AARCH64_INSN_DATA2_LSRV:
   1158		insn = aarch64_insn_get_lsrv_value();
   1159		break;
   1160	case AARCH64_INSN_DATA2_ASRV:
   1161		insn = aarch64_insn_get_asrv_value();
   1162		break;
   1163	case AARCH64_INSN_DATA2_RORV:
   1164		insn = aarch64_insn_get_rorv_value();
   1165		break;
   1166	default:
   1167		pr_err("%s: unknown data2 encoding %d\n", __func__, type);
   1168		return AARCH64_BREAK_FAULT;
   1169	}
   1170
   1171	switch (variant) {
   1172	case AARCH64_INSN_VARIANT_32BIT:
   1173		break;
   1174	case AARCH64_INSN_VARIANT_64BIT:
   1175		insn |= AARCH64_INSN_SF_BIT;
   1176		break;
   1177	default:
   1178		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
   1179		return AARCH64_BREAK_FAULT;
   1180	}
   1181
   1182	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
   1183
   1184	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
   1185
   1186	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
   1187}
   1188
   1189u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
   1190			   enum aarch64_insn_register src,
   1191			   enum aarch64_insn_register reg1,
   1192			   enum aarch64_insn_register reg2,
   1193			   enum aarch64_insn_variant variant,
   1194			   enum aarch64_insn_data3_type type)
   1195{
   1196	u32 insn;
   1197
   1198	switch (type) {
   1199	case AARCH64_INSN_DATA3_MADD:
   1200		insn = aarch64_insn_get_madd_value();
   1201		break;
   1202	case AARCH64_INSN_DATA3_MSUB:
   1203		insn = aarch64_insn_get_msub_value();
   1204		break;
   1205	default:
   1206		pr_err("%s: unknown data3 encoding %d\n", __func__, type);
   1207		return AARCH64_BREAK_FAULT;
   1208	}
   1209
   1210	switch (variant) {
   1211	case AARCH64_INSN_VARIANT_32BIT:
   1212		break;
   1213	case AARCH64_INSN_VARIANT_64BIT:
   1214		insn |= AARCH64_INSN_SF_BIT;
   1215		break;
   1216	default:
   1217		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
   1218		return AARCH64_BREAK_FAULT;
   1219	}
   1220
   1221	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
   1222
   1223	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RA, insn, src);
   1224
   1225	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
   1226					    reg1);
   1227
   1228	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn,
   1229					    reg2);
   1230}
   1231
   1232u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst,
   1233					 enum aarch64_insn_register src,
   1234					 enum aarch64_insn_register reg,
   1235					 int shift,
   1236					 enum aarch64_insn_variant variant,
   1237					 enum aarch64_insn_logic_type type)
   1238{
   1239	u32 insn;
   1240
   1241	switch (type) {
   1242	case AARCH64_INSN_LOGIC_AND:
   1243		insn = aarch64_insn_get_and_value();
   1244		break;
   1245	case AARCH64_INSN_LOGIC_BIC:
   1246		insn = aarch64_insn_get_bic_value();
   1247		break;
   1248	case AARCH64_INSN_LOGIC_ORR:
   1249		insn = aarch64_insn_get_orr_value();
   1250		break;
   1251	case AARCH64_INSN_LOGIC_ORN:
   1252		insn = aarch64_insn_get_orn_value();
   1253		break;
   1254	case AARCH64_INSN_LOGIC_EOR:
   1255		insn = aarch64_insn_get_eor_value();
   1256		break;
   1257	case AARCH64_INSN_LOGIC_EON:
   1258		insn = aarch64_insn_get_eon_value();
   1259		break;
   1260	case AARCH64_INSN_LOGIC_AND_SETFLAGS:
   1261		insn = aarch64_insn_get_ands_value();
   1262		break;
   1263	case AARCH64_INSN_LOGIC_BIC_SETFLAGS:
   1264		insn = aarch64_insn_get_bics_value();
   1265		break;
   1266	default:
   1267		pr_err("%s: unknown logical encoding %d\n", __func__, type);
   1268		return AARCH64_BREAK_FAULT;
   1269	}
   1270
   1271	switch (variant) {
   1272	case AARCH64_INSN_VARIANT_32BIT:
   1273		if (shift & ~(SZ_32 - 1)) {
   1274			pr_err("%s: invalid shift encoding %d\n", __func__,
   1275			       shift);
   1276			return AARCH64_BREAK_FAULT;
   1277		}
   1278		break;
   1279	case AARCH64_INSN_VARIANT_64BIT:
   1280		insn |= AARCH64_INSN_SF_BIT;
   1281		if (shift & ~(SZ_64 - 1)) {
   1282			pr_err("%s: invalid shift encoding %d\n", __func__,
   1283			       shift);
   1284			return AARCH64_BREAK_FAULT;
   1285		}
   1286		break;
   1287	default:
   1288		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
   1289		return AARCH64_BREAK_FAULT;
   1290	}
   1291
   1292
   1293	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
   1294
   1295	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
   1296
   1297	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
   1298
   1299	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
   1300}
   1301
   1302/*
   1303 * MOV (register) is architecturally an alias of ORR (shifted register) where
   1304 * MOV <*d>, <*m> is equivalent to ORR <*d>, <*ZR>, <*m>
   1305 */
   1306u32 aarch64_insn_gen_move_reg(enum aarch64_insn_register dst,
   1307			      enum aarch64_insn_register src,
   1308			      enum aarch64_insn_variant variant)
   1309{
   1310	return aarch64_insn_gen_logical_shifted_reg(dst, AARCH64_INSN_REG_ZR,
   1311						    src, 0, variant,
   1312						    AARCH64_INSN_LOGIC_ORR);
   1313}
   1314
   1315u32 aarch64_insn_gen_adr(unsigned long pc, unsigned long addr,
   1316			 enum aarch64_insn_register reg,
   1317			 enum aarch64_insn_adr_type type)
   1318{
   1319	u32 insn;
   1320	s32 offset;
   1321
   1322	switch (type) {
   1323	case AARCH64_INSN_ADR_TYPE_ADR:
   1324		insn = aarch64_insn_get_adr_value();
   1325		offset = addr - pc;
   1326		break;
   1327	case AARCH64_INSN_ADR_TYPE_ADRP:
   1328		insn = aarch64_insn_get_adrp_value();
   1329		offset = (addr - ALIGN_DOWN(pc, SZ_4K)) >> 12;
   1330		break;
   1331	default:
   1332		pr_err("%s: unknown adr encoding %d\n", __func__, type);
   1333		return AARCH64_BREAK_FAULT;
   1334	}
   1335
   1336	if (offset < -SZ_1M || offset >= SZ_1M)
   1337		return AARCH64_BREAK_FAULT;
   1338
   1339	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, reg);
   1340
   1341	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn, offset);
   1342}
   1343
   1344/*
   1345 * Decode the imm field of a branch, and return the byte offset as a
   1346 * signed value (so it can be used when computing a new branch
   1347 * target).
   1348 */
   1349s32 aarch64_get_branch_offset(u32 insn)
   1350{
   1351	s32 imm;
   1352
   1353	if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) {
   1354		imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn);
   1355		return (imm << 6) >> 4;
   1356	}
   1357
   1358	if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) ||
   1359	    aarch64_insn_is_bcond(insn)) {
   1360		imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_19, insn);
   1361		return (imm << 13) >> 11;
   1362	}
   1363
   1364	if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn)) {
   1365		imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_14, insn);
   1366		return (imm << 18) >> 16;
   1367	}
   1368
   1369	/* Unhandled instruction */
   1370	BUG();
   1371}
   1372
   1373/*
   1374 * Encode the displacement of a branch in the imm field and return the
   1375 * updated instruction.
   1376 */
   1377u32 aarch64_set_branch_offset(u32 insn, s32 offset)
   1378{
   1379	if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn))
   1380		return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn,
   1381						     offset >> 2);
   1382
   1383	if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) ||
   1384	    aarch64_insn_is_bcond(insn))
   1385		return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
   1386						     offset >> 2);
   1387
   1388	if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn))
   1389		return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_14, insn,
   1390						     offset >> 2);
   1391
   1392	/* Unhandled instruction */
   1393	BUG();
   1394}
   1395
   1396s32 aarch64_insn_adrp_get_offset(u32 insn)
   1397{
   1398	BUG_ON(!aarch64_insn_is_adrp(insn));
   1399	return aarch64_insn_decode_immediate(AARCH64_INSN_IMM_ADR, insn) << 12;
   1400}
   1401
   1402u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset)
   1403{
   1404	BUG_ON(!aarch64_insn_is_adrp(insn));
   1405	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn,
   1406						offset >> 12);
   1407}
   1408
   1409/*
   1410 * Extract the Op/CR data from a msr/mrs instruction.
   1411 */
   1412u32 aarch64_insn_extract_system_reg(u32 insn)
   1413{
   1414	return (insn & 0x1FFFE0) >> 5;
   1415}
   1416
   1417bool aarch32_insn_is_wide(u32 insn)
   1418{
   1419	return insn >= 0xe800;
   1420}
   1421
   1422/*
   1423 * Macros/defines for extracting register numbers from instruction.
   1424 */
   1425u32 aarch32_insn_extract_reg_num(u32 insn, int offset)
   1426{
   1427	return (insn & (0xf << offset)) >> offset;
   1428}
   1429
   1430#define OPC2_MASK	0x7
   1431#define OPC2_OFFSET	5
   1432u32 aarch32_insn_mcr_extract_opc2(u32 insn)
   1433{
   1434	return (insn & (OPC2_MASK << OPC2_OFFSET)) >> OPC2_OFFSET;
   1435}
   1436
   1437#define CRM_MASK	0xf
   1438u32 aarch32_insn_mcr_extract_crm(u32 insn)
   1439{
   1440	return insn & CRM_MASK;
   1441}
   1442
   1443static bool range_of_ones(u64 val)
   1444{
   1445	/* Doesn't handle full ones or full zeroes */
   1446	u64 sval = val >> __ffs64(val);
   1447
   1448	/* One of Sean Eron Anderson's bithack tricks */
   1449	return ((sval + 1) & (sval)) == 0;
   1450}
   1451
   1452static u32 aarch64_encode_immediate(u64 imm,
   1453				    enum aarch64_insn_variant variant,
   1454				    u32 insn)
   1455{
   1456	unsigned int immr, imms, n, ones, ror, esz, tmp;
   1457	u64 mask;
   1458
   1459	switch (variant) {
   1460	case AARCH64_INSN_VARIANT_32BIT:
   1461		esz = 32;
   1462		break;
   1463	case AARCH64_INSN_VARIANT_64BIT:
   1464		insn |= AARCH64_INSN_SF_BIT;
   1465		esz = 64;
   1466		break;
   1467	default:
   1468		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
   1469		return AARCH64_BREAK_FAULT;
   1470	}
   1471
   1472	mask = GENMASK(esz - 1, 0);
   1473
   1474	/* Can't encode full zeroes, full ones, or value wider than the mask */
   1475	if (!imm || imm == mask || imm & ~mask)
   1476		return AARCH64_BREAK_FAULT;
   1477
   1478	/*
   1479	 * Inverse of Replicate(). Try to spot a repeating pattern
   1480	 * with a pow2 stride.
   1481	 */
   1482	for (tmp = esz / 2; tmp >= 2; tmp /= 2) {
   1483		u64 emask = BIT(tmp) - 1;
   1484
   1485		if ((imm & emask) != ((imm >> tmp) & emask))
   1486			break;
   1487
   1488		esz = tmp;
   1489		mask = emask;
   1490	}
   1491
   1492	/* N is only set if we're encoding a 64bit value */
   1493	n = esz == 64;
   1494
   1495	/* Trim imm to the element size */
   1496	imm &= mask;
   1497
   1498	/* That's how many ones we need to encode */
   1499	ones = hweight64(imm);
   1500
   1501	/*
   1502	 * imms is set to (ones - 1), prefixed with a string of ones
   1503	 * and a zero if they fit. Cap it to 6 bits.
   1504	 */
   1505	imms  = ones - 1;
   1506	imms |= 0xf << ffs(esz);
   1507	imms &= BIT(6) - 1;
   1508
   1509	/* Compute the rotation */
   1510	if (range_of_ones(imm)) {
   1511		/*
   1512		 * Pattern: 0..01..10..0
   1513		 *
   1514		 * Compute how many rotate we need to align it right
   1515		 */
   1516		ror = __ffs64(imm);
   1517	} else {
   1518		/*
   1519		 * Pattern: 0..01..10..01..1
   1520		 *
   1521		 * Fill the unused top bits with ones, and check if
   1522		 * the result is a valid immediate (all ones with a
   1523		 * contiguous ranges of zeroes).
   1524		 */
   1525		imm |= ~mask;
   1526		if (!range_of_ones(~imm))
   1527			return AARCH64_BREAK_FAULT;
   1528
   1529		/*
   1530		 * Compute the rotation to get a continuous set of
   1531		 * ones, with the first bit set at position 0
   1532		 */
   1533		ror = fls64(~imm);
   1534	}
   1535
   1536	/*
   1537	 * immr is the number of bits we need to rotate back to the
   1538	 * original set of ones. Note that this is relative to the
   1539	 * element size...
   1540	 */
   1541	immr = (esz - ror) % esz;
   1542
   1543	insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_N, insn, n);
   1544	insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, immr);
   1545	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, imms);
   1546}
   1547
   1548u32 aarch64_insn_gen_logical_immediate(enum aarch64_insn_logic_type type,
   1549				       enum aarch64_insn_variant variant,
   1550				       enum aarch64_insn_register Rn,
   1551				       enum aarch64_insn_register Rd,
   1552				       u64 imm)
   1553{
   1554	u32 insn;
   1555
   1556	switch (type) {
   1557	case AARCH64_INSN_LOGIC_AND:
   1558		insn = aarch64_insn_get_and_imm_value();
   1559		break;
   1560	case AARCH64_INSN_LOGIC_ORR:
   1561		insn = aarch64_insn_get_orr_imm_value();
   1562		break;
   1563	case AARCH64_INSN_LOGIC_EOR:
   1564		insn = aarch64_insn_get_eor_imm_value();
   1565		break;
   1566	case AARCH64_INSN_LOGIC_AND_SETFLAGS:
   1567		insn = aarch64_insn_get_ands_imm_value();
   1568		break;
   1569	default:
   1570		pr_err("%s: unknown logical encoding %d\n", __func__, type);
   1571		return AARCH64_BREAK_FAULT;
   1572	}
   1573
   1574	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, Rd);
   1575	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
   1576	return aarch64_encode_immediate(imm, variant, insn);
   1577}
   1578
   1579u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
   1580			  enum aarch64_insn_register Rm,
   1581			  enum aarch64_insn_register Rn,
   1582			  enum aarch64_insn_register Rd,
   1583			  u8 lsb)
   1584{
   1585	u32 insn;
   1586
   1587	insn = aarch64_insn_get_extr_value();
   1588
   1589	switch (variant) {
   1590	case AARCH64_INSN_VARIANT_32BIT:
   1591		if (lsb > 31)
   1592			return AARCH64_BREAK_FAULT;
   1593		break;
   1594	case AARCH64_INSN_VARIANT_64BIT:
   1595		if (lsb > 63)
   1596			return AARCH64_BREAK_FAULT;
   1597		insn |= AARCH64_INSN_SF_BIT;
   1598		insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_N, insn, 1);
   1599		break;
   1600	default:
   1601		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
   1602		return AARCH64_BREAK_FAULT;
   1603	}
   1604
   1605	insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, lsb);
   1606	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, Rd);
   1607	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
   1608	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
   1609}
   1610
   1611u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
   1612{
   1613	u32 opt;
   1614	u32 insn;
   1615
   1616	switch (type) {
   1617	case AARCH64_INSN_MB_SY:
   1618		opt = 0xf;
   1619		break;
   1620	case AARCH64_INSN_MB_ST:
   1621		opt = 0xe;
   1622		break;
   1623	case AARCH64_INSN_MB_LD:
   1624		opt = 0xd;
   1625		break;
   1626	case AARCH64_INSN_MB_ISH:
   1627		opt = 0xb;
   1628		break;
   1629	case AARCH64_INSN_MB_ISHST:
   1630		opt = 0xa;
   1631		break;
   1632	case AARCH64_INSN_MB_ISHLD:
   1633		opt = 0x9;
   1634		break;
   1635	case AARCH64_INSN_MB_NSH:
   1636		opt = 0x7;
   1637		break;
   1638	case AARCH64_INSN_MB_NSHST:
   1639		opt = 0x6;
   1640		break;
   1641	case AARCH64_INSN_MB_NSHLD:
   1642		opt = 0x5;
   1643		break;
   1644	default:
   1645		pr_err("%s: unknown dmb type %d\n", __func__, type);
   1646		return AARCH64_BREAK_FAULT;
   1647	}
   1648
   1649	insn = aarch64_insn_get_dmb_value();
   1650	insn &= ~GENMASK(11, 8);
   1651	insn |= (opt << 8);
   1652
   1653	return insn;
   1654}