Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a168b8f1 authored by Leonid Yegoshin's avatar Leonid Yegoshin Committed by Markos Chandras
Browse files

MIPS: mm: Add MIPS R6 instruction encodings



MIPS R6 defines new opcodes for ll, sc, cache and pref instructions
so we need to take these into consideration in the micro-assembler.

Signed-off-by: default avatarLeonid Yegoshin <Leonid.Yegoshin@imgtec.com>
Signed-off-by: default avatarMarkos Chandras <markos.chandras@imgtec.com>
parent 51eec48e
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -83,9 +83,12 @@ enum spec3_op {
	swe_op    = 0x1f, bshfl_op  = 0x20,
	swle_op   = 0x21, swre_op   = 0x22,
	prefe_op  = 0x23, dbshfl_op = 0x24,
	lbue_op   = 0x28, lhue_op   = 0x29,
	lbe_op    = 0x2c, lhe_op    = 0x2d,
	lle_op    = 0x2e, lwe_op    = 0x2f,
	cache6_op = 0x25, sc6_op    = 0x26,
	scd6_op   = 0x27, lbue_op   = 0x28,
	lhue_op   = 0x29, lbe_op    = 0x2c,
	lhe_op    = 0x2d, lle_op    = 0x2e,
	lwe_op    = 0x2f, pref6_op  = 0x35,
	ll6_op    = 0x36, lld6_op   = 0x37,
	rdhwr_op  = 0x3b
};

+32 −0
Original line number Diff line number Diff line
@@ -38,6 +38,14 @@
	 | (e) << RE_SH						\
	 | (f) << FUNC_SH)

/* This macro sets the non-variable bits of an R6 instruction. */
#define M6(a, b, c, d, e)					\
	((a) << OP_SH						\
	 | (b) << RS_SH						\
	 | (c) << RT_SH						\
	 | (d) << SIMM9_SH					\
	 | (e) << FUNC_SH)

/* Define these when we are not the ISA the kernel is being compiled with. */
#ifdef CONFIG_CPU_MICROMIPS
#define CL_uasm_i_b(buf, off) ISAOPC(_beq)(buf, 0, 0, off)
@@ -62,7 +70,11 @@ static struct insn insn_table[] = {
	{ insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM },
	{ insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM },
	{ insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
#ifndef CONFIG_CPU_MIPSR6
	{ insn_cache,  M(cache_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
#else
	{ insn_cache,  M6(cache_op, 0, 0, 0, cache6_op),  RS | RT | SIMM9 },
#endif
	{ insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
	{ insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
	{ insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE },
@@ -85,13 +97,22 @@ static struct insn insn_table[] = {
	{ insn_jal,  M(jal_op, 0, 0, 0, 0, 0),	JIMM },
	{ insn_jalr,  M(spec_op, 0, 0, 0, 0, jalr_op), RS | RD },
	{ insn_j,  M(j_op, 0, 0, 0, 0, 0),  JIMM },
#ifndef CONFIG_CPU_MIPSR6
	{ insn_jr,  M(spec_op, 0, 0, 0, 0, jr_op),  RS },
#else
	{ insn_jr,  M(spec_op, 0, 0, 0, 0, jalr_op),  RS },
#endif
	{ insn_lb, M(lb_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
	{ insn_ld,  M(ld_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
	{ insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD },
	{ insn_lh,  M(lh_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
#ifndef CONFIG_CPU_MIPSR6
	{ insn_lld,  M(lld_op, 0, 0, 0, 0, 0),	RS | RT | SIMM },
	{ insn_ll,  M(ll_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
#else
	{ insn_lld,  M6(spec3_op, 0, 0, 0, lld6_op),  RS | RT | SIMM9 },
	{ insn_ll,  M6(spec3_op, 0, 0, 0, ll6_op),  RS | RT | SIMM9 },
#endif
	{ insn_lui,  M(lui_op, 0, 0, 0, 0, 0),	RT | SIMM },
	{ insn_lw,  M(lw_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
	{ insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD },
@@ -104,11 +125,20 @@ static struct insn insn_table[] = {
	{ insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD},
	{ insn_ori,  M(ori_op, 0, 0, 0, 0, 0),	RS | RT | UIMM },
	{ insn_or,  M(spec_op, 0, 0, 0, 0, or_op),  RS | RT | RD },
#ifndef CONFIG_CPU_MIPSR6
	{ insn_pref,  M(pref_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
#else
	{ insn_pref,  M6(spec3_op, 0, 0, 0, pref6_op),  RS | RT | SIMM9 },
#endif
	{ insn_rfe,  M(cop0_op, cop_op, 0, 0, 0, rfe_op),  0 },
	{ insn_rotr,  M(spec_op, 1, 0, 0, 0, srl_op),  RT | RD | RE },
#ifndef CONFIG_CPU_MIPSR6
	{ insn_scd,  M(scd_op, 0, 0, 0, 0, 0),	RS | RT | SIMM },
	{ insn_sc,  M(sc_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
#else
	{ insn_scd,  M6(spec3_op, 0, 0, 0, scd6_op),  RS | RT | SIMM9 },
	{ insn_sc,  M6(spec3_op, 0, 0, 0, sc6_op),  RS | RT | SIMM9 },
#endif
	{ insn_sd,  M(sd_op, 0, 0, 0, 0, 0),  RS | RT | SIMM },
	{ insn_sll,  M(spec_op, 0, 0, 0, 0, sll_op),  RT | RD | RE },
	{ insn_sllv,  M(spec_op, 0, 0, 0, 0, sllv_op),  RS | RT | RD },
@@ -198,6 +228,8 @@ static void build_insn(u32 **buf, enum opcode opc, ...)
		op |= build_set(va_arg(ap, u32));
	if (ip->fields & SCIMM)
		op |= build_scimm(va_arg(ap, u32));
	if (ip->fields & SIMM9)
		op |= build_scimm9(va_arg(ap, u32));
	va_end(ap);

	**buf = op;