/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2020-2022 Loongson Technology Corporation Limited */ #ifndef _ASM_INST_H #define _ASM_INST_H #include #define LOONGARCH_INSN_NOP 0x03400000 enum reg0i15_op { break_op = 0x54, }; enum reg0i26_op { b_op = 0x14, bl_op = 0x15, }; enum reg1i21_op { beqz_op = 0x10, bnez_op = 0x11, bceqz_op = 0x12, /* bits[9:8] = 0x00 */ bcnez_op = 0x12, /* bits[9:8] = 0x01 */ }; enum reg2_op { ertn_op = 0x1920e, }; enum reg2i12_op { addid_op = 0x0b, andi_op = 0x0d, ldd_op = 0xa3, std_op = 0xa7, }; enum reg2i14_op { ldptrd_op = 0x26, stptrd_op = 0x27, }; enum reg2i16_op { jirl_op = 0x13, beq_op = 0x16, bne_op = 0x17, blt_op = 0x18, bge_op = 0x19, bltu_op = 0x1a, bgeu_op = 0x1b, }; struct reg0i15_format { unsigned int immediate : 15; unsigned int opcode : 17; }; struct reg0i26_format { unsigned int immediate_h : 10; unsigned int immediate_l : 16; unsigned int opcode : 6; }; struct reg1i21_format { unsigned int immediate_h : 5; unsigned int rj : 5; unsigned int immediate_l : 16; unsigned int opcode : 6; }; struct reg2_format { unsigned int rd : 5; unsigned int rj : 5; unsigned int opcode : 22; }; struct reg2i12_format { unsigned int rd : 5; unsigned int rj : 5; unsigned int immediate : 12; unsigned int opcode : 10; }; struct reg2i14_format { unsigned int rd : 5; unsigned int rj : 5; unsigned int immediate : 14; unsigned int opcode : 8; }; struct reg2i16_format { unsigned int rd : 5; unsigned int rj : 5; unsigned int immediate : 16; unsigned int opcode : 6; }; union loongarch_instruction { unsigned int word; struct reg0i15_format reg0i15_format; struct reg0i26_format reg0i26_format; struct reg1i21_format reg1i21_format; struct reg2_format reg2_format; struct reg2i12_format reg2i12_format; struct reg2i14_format reg2i14_format; struct reg2i16_format reg2i16_format; }; #define LOONGARCH_INSN_SIZE sizeof(union loongarch_instruction) enum loongarch_gpr { LOONGARCH_GPR_ZERO = 0, LOONGARCH_GPR_RA = 1, LOONGARCH_GPR_TP = 2, LOONGARCH_GPR_SP = 3, LOONGARCH_GPR_A0 = 4, /* Reused as V0 for return value */ LOONGARCH_GPR_A1, /* Reused as V1 for return value */ LOONGARCH_GPR_A2, LOONGARCH_GPR_A3, LOONGARCH_GPR_A4, LOONGARCH_GPR_A5, LOONGARCH_GPR_A6, LOONGARCH_GPR_A7, LOONGARCH_GPR_T0 = 12, LOONGARCH_GPR_T1, LOONGARCH_GPR_T2, LOONGARCH_GPR_T3, LOONGARCH_GPR_T4, LOONGARCH_GPR_T5, LOONGARCH_GPR_T6, LOONGARCH_GPR_T7, LOONGARCH_GPR_T8, LOONGARCH_GPR_FP = 22, LOONGARCH_GPR_S0 = 23, LOONGARCH_GPR_S1, LOONGARCH_GPR_S2, LOONGARCH_GPR_S3, LOONGARCH_GPR_S4, LOONGARCH_GPR_S5, LOONGARCH_GPR_S6, LOONGARCH_GPR_S7, LOONGARCH_GPR_S8, LOONGARCH_GPR_MAX }; #define DEF_EMIT_REG2I16_FORMAT(NAME, OP) \ static inline void emit_##NAME(union loongarch_instruction *insn, \ enum loongarch_gpr rj, \ enum loongarch_gpr rd, \ int offset) \ { \ insn->reg2i16_format.opcode = OP; \ insn->reg2i16_format.immediate = offset; \ insn->reg2i16_format.rj = rj; \ insn->reg2i16_format.rd = rd; \ } DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op) #endif /* _ASM_INST_H */