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