mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
This commit is contained in:
		
							parent
							
								
									51eec48e12
								
							
						
					
					
						commit
						a168b8f1cd
					
				
					 2 changed files with 38 additions and 3 deletions
				
			
		| 
						 | 
					@ -83,9 +83,12 @@ enum spec3_op {
 | 
				
			||||||
	swe_op    = 0x1f, bshfl_op  = 0x20,
 | 
						swe_op    = 0x1f, bshfl_op  = 0x20,
 | 
				
			||||||
	swle_op   = 0x21, swre_op   = 0x22,
 | 
						swle_op   = 0x21, swre_op   = 0x22,
 | 
				
			||||||
	prefe_op  = 0x23, dbshfl_op = 0x24,
 | 
						prefe_op  = 0x23, dbshfl_op = 0x24,
 | 
				
			||||||
	lbue_op   = 0x28, lhue_op   = 0x29,
 | 
						cache6_op = 0x25, sc6_op    = 0x26,
 | 
				
			||||||
	lbe_op    = 0x2c, lhe_op    = 0x2d,
 | 
						scd6_op   = 0x27, lbue_op   = 0x28,
 | 
				
			||||||
	lle_op    = 0x2e, lwe_op    = 0x2f,
 | 
						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
 | 
						rdhwr_op  = 0x3b
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,14 @@
 | 
				
			||||||
	 | (e) << RE_SH						\
 | 
						 | (e) << RE_SH						\
 | 
				
			||||||
	 | (f) << FUNC_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. */
 | 
					/* Define these when we are not the ISA the kernel is being compiled with. */
 | 
				
			||||||
#ifdef CONFIG_CPU_MICROMIPS
 | 
					#ifdef CONFIG_CPU_MICROMIPS
 | 
				
			||||||
#define CL_uasm_i_b(buf, off) ISAOPC(_beq)(buf, 0, 0, off)
 | 
					#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_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_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 },
 | 
						{ 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 },
 | 
						{ 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_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_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 },
 | 
						{ 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_jal,  M(jal_op, 0, 0, 0, 0, 0),	JIMM },
 | 
				
			||||||
	{ insn_jalr,  M(spec_op, 0, 0, 0, 0, jalr_op), RS | RD },
 | 
						{ insn_jalr,  M(spec_op, 0, 0, 0, 0, jalr_op), RS | RD },
 | 
				
			||||||
	{ insn_j,  M(j_op, 0, 0, 0, 0, 0),  JIMM },
 | 
						{ 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 },
 | 
						{ 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_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_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_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 },
 | 
						{ 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_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 },
 | 
						{ 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_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_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 },
 | 
						{ 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_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_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 },
 | 
						{ 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 },
 | 
						{ 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_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 },
 | 
						{ 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_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 },
 | 
						{ 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_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_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 },
 | 
						{ 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));
 | 
							op |= build_set(va_arg(ap, u32));
 | 
				
			||||||
	if (ip->fields & SCIMM)
 | 
						if (ip->fields & SCIMM)
 | 
				
			||||||
		op |= build_scimm(va_arg(ap, u32));
 | 
							op |= build_scimm(va_arg(ap, u32));
 | 
				
			||||||
 | 
						if (ip->fields & SIMM9)
 | 
				
			||||||
 | 
							op |= build_scimm9(va_arg(ap, u32));
 | 
				
			||||||
	va_end(ap);
 | 
						va_end(ap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	**buf = op;
 | 
						**buf = op;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue