xref: /openbmc/linux/arch/loongarch/include/asm/inst.h (revision f05643a0)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
4  */
5 #ifndef _ASM_INST_H
6 #define _ASM_INST_H
7 
8 #include <linux/types.h>
9 #include <asm/asm.h>
10 
11 #define ADDR_IMMMASK_LU52ID	0xFFF0000000000000
12 #define ADDR_IMMMASK_LU32ID	0x000FFFFF00000000
13 #define ADDR_IMMMASK_ADDU16ID	0x00000000FFFF0000
14 
15 #define ADDR_IMMSHIFT_LU52ID	52
16 #define ADDR_IMMSHIFT_LU32ID	32
17 #define ADDR_IMMSHIFT_ADDU16ID	16
18 
19 #define ADDR_IMM(addr, INSN)	((addr & ADDR_IMMMASK_##INSN) >> ADDR_IMMSHIFT_##INSN)
20 
21 enum reg1i20_op {
22 	lu12iw_op	= 0x0a,
23 	lu32id_op	= 0x0b,
24 };
25 
26 enum reg2i12_op {
27 	lu52id_op	= 0x0c,
28 };
29 
30 enum reg2i16_op {
31 	jirl_op		= 0x13,
32 };
33 
34 struct reg0i26_format {
35 	unsigned int immediate_h : 10;
36 	unsigned int immediate_l : 16;
37 	unsigned int opcode : 6;
38 };
39 
40 struct reg1i20_format {
41 	unsigned int rd : 5;
42 	unsigned int immediate : 20;
43 	unsigned int opcode : 7;
44 };
45 
46 struct reg1i21_format {
47 	unsigned int immediate_h  : 5;
48 	unsigned int rj : 5;
49 	unsigned int immediate_l : 16;
50 	unsigned int opcode : 6;
51 };
52 
53 struct reg2i12_format {
54 	unsigned int rd : 5;
55 	unsigned int rj : 5;
56 	unsigned int immediate : 12;
57 	unsigned int opcode : 10;
58 };
59 
60 struct reg2i16_format {
61 	unsigned int rd : 5;
62 	unsigned int rj : 5;
63 	unsigned int immediate : 16;
64 	unsigned int opcode : 6;
65 };
66 
67 union loongarch_instruction {
68 	unsigned int word;
69 	struct reg0i26_format reg0i26_format;
70 	struct reg1i20_format reg1i20_format;
71 	struct reg1i21_format reg1i21_format;
72 	struct reg2i12_format reg2i12_format;
73 	struct reg2i16_format reg2i16_format;
74 };
75 
76 #define LOONGARCH_INSN_SIZE	sizeof(union loongarch_instruction)
77 
78 enum loongarch_gpr {
79 	LOONGARCH_GPR_ZERO = 0,
80 	LOONGARCH_GPR_RA = 1,
81 	LOONGARCH_GPR_TP = 2,
82 	LOONGARCH_GPR_SP = 3,
83 	LOONGARCH_GPR_A0 = 4,	/* Reused as V0 for return value */
84 	LOONGARCH_GPR_A1,	/* Reused as V1 for return value */
85 	LOONGARCH_GPR_A2,
86 	LOONGARCH_GPR_A3,
87 	LOONGARCH_GPR_A4,
88 	LOONGARCH_GPR_A5,
89 	LOONGARCH_GPR_A6,
90 	LOONGARCH_GPR_A7,
91 	LOONGARCH_GPR_T0 = 12,
92 	LOONGARCH_GPR_T1,
93 	LOONGARCH_GPR_T2,
94 	LOONGARCH_GPR_T3,
95 	LOONGARCH_GPR_T4,
96 	LOONGARCH_GPR_T5,
97 	LOONGARCH_GPR_T6,
98 	LOONGARCH_GPR_T7,
99 	LOONGARCH_GPR_T8,
100 	LOONGARCH_GPR_FP = 22,
101 	LOONGARCH_GPR_S0 = 23,
102 	LOONGARCH_GPR_S1,
103 	LOONGARCH_GPR_S2,
104 	LOONGARCH_GPR_S3,
105 	LOONGARCH_GPR_S4,
106 	LOONGARCH_GPR_S5,
107 	LOONGARCH_GPR_S6,
108 	LOONGARCH_GPR_S7,
109 	LOONGARCH_GPR_S8,
110 	LOONGARCH_GPR_MAX
111 };
112 
113 u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm);
114 u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm);
115 u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, unsigned long pc, unsigned long dest);
116 
117 #endif /* _ASM_INST_H */
118