| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Format of an instruction in memory. | 
 | 3 |  * | 
 | 4 |  * This file is subject to the terms and conditions of the GNU General Public | 
 | 5 |  * License.  See the file "COPYING" in the main directory of this archive | 
 | 6 |  * for more details. | 
 | 7 |  * | 
 | 8 |  * Copyright (C) 1996, 2000 by Ralf Baechle | 
| Thiemo Seufer | ca30225 | 2006-05-15 18:27:03 +0100 | [diff] [blame] | 9 |  * Copyright (C) 2006 by Thiemo Seufer | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 10 |  */ | 
 | 11 | #ifndef _ASM_INST_H | 
 | 12 | #define _ASM_INST_H | 
 | 13 |  | 
 | 14 | /* | 
 | 15 |  * Major opcodes; before MIPS IV cop1x was called cop3. | 
 | 16 |  */ | 
 | 17 | enum major_op { | 
 | 18 | 	spec_op, bcond_op, j_op, jal_op, | 
 | 19 | 	beq_op, bne_op, blez_op, bgtz_op, | 
 | 20 | 	addi_op, addiu_op, slti_op, sltiu_op, | 
 | 21 | 	andi_op, ori_op, xori_op, lui_op, | 
 | 22 | 	cop0_op, cop1_op, cop2_op, cop1x_op, | 
 | 23 | 	beql_op, bnel_op, blezl_op, bgtzl_op, | 
 | 24 | 	daddi_op, daddiu_op, ldl_op, ldr_op, | 
| Thiemo Seufer | ca30225 | 2006-05-15 18:27:03 +0100 | [diff] [blame] | 25 | 	spec2_op, jalx_op, mdmx_op, spec3_op, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 26 | 	lb_op, lh_op, lwl_op, lw_op, | 
 | 27 | 	lbu_op, lhu_op, lwr_op, lwu_op, | 
 | 28 | 	sb_op, sh_op, swl_op, sw_op, | 
 | 29 | 	sdl_op, sdr_op, swr_op, cache_op, | 
 | 30 | 	ll_op, lwc1_op, lwc2_op, pref_op, | 
 | 31 | 	lld_op, ldc1_op, ldc2_op, ld_op, | 
| Thiemo Seufer | ca30225 | 2006-05-15 18:27:03 +0100 | [diff] [blame] | 32 | 	sc_op, swc1_op, swc2_op, major_3b_op, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 33 | 	scd_op, sdc1_op, sdc2_op, sd_op | 
 | 34 | }; | 
 | 35 |  | 
 | 36 | /* | 
 | 37 |  * func field of spec opcode. | 
 | 38 |  */ | 
 | 39 | enum spec_op { | 
 | 40 | 	sll_op, movc_op, srl_op, sra_op, | 
| Thiemo Seufer | ca30225 | 2006-05-15 18:27:03 +0100 | [diff] [blame] | 41 | 	sllv_op, pmon_op, srlv_op, srav_op, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 42 | 	jr_op, jalr_op, movz_op, movn_op, | 
 | 43 | 	syscall_op, break_op, spim_op, sync_op, | 
 | 44 | 	mfhi_op, mthi_op, mflo_op, mtlo_op, | 
 | 45 | 	dsllv_op, spec2_unused_op, dsrlv_op, dsrav_op, | 
 | 46 | 	mult_op, multu_op, div_op, divu_op, | 
 | 47 | 	dmult_op, dmultu_op, ddiv_op, ddivu_op, | 
 | 48 | 	add_op, addu_op, sub_op, subu_op, | 
 | 49 | 	and_op, or_op, xor_op, nor_op, | 
 | 50 | 	spec3_unused_op, spec4_unused_op, slt_op, sltu_op, | 
 | 51 | 	dadd_op, daddu_op, dsub_op, dsubu_op, | 
 | 52 | 	tge_op, tgeu_op, tlt_op, tltu_op, | 
 | 53 | 	teq_op, spec5_unused_op, tne_op, spec6_unused_op, | 
 | 54 | 	dsll_op, spec7_unused_op, dsrl_op, dsra_op, | 
 | 55 | 	dsll32_op, spec8_unused_op, dsrl32_op, dsra32_op | 
 | 56 | }; | 
 | 57 |  | 
 | 58 | /* | 
| Thiemo Seufer | ca30225 | 2006-05-15 18:27:03 +0100 | [diff] [blame] | 59 |  * func field of spec2 opcode. | 
 | 60 |  */ | 
 | 61 | enum spec2_op { | 
 | 62 | 	madd_op, maddu_op, mul_op, spec2_3_unused_op, | 
 | 63 | 	msub_op, msubu_op, /* more unused ops */ | 
 | 64 | 	clz_op = 0x20, clo_op, | 
 | 65 | 	dclz_op = 0x24, dclo_op, | 
 | 66 | 	sdbpp_op = 0x3f | 
 | 67 | }; | 
 | 68 |  | 
 | 69 | /* | 
 | 70 |  * func field of spec3 opcode. | 
 | 71 |  */ | 
 | 72 | enum spec3_op { | 
 | 73 | 	ext_op, dextm_op, dextu_op, dext_op, | 
 | 74 | 	ins_op, dinsm_op, dinsu_op, dins_op, | 
 | 75 | 	bshfl_op = 0x20, | 
 | 76 | 	dbshfl_op = 0x24, | 
| Atsushi Nemoto | 8d197f3 | 2006-07-07 14:26:41 +0900 | [diff] [blame] | 77 | 	rdhwr_op = 0x3b | 
| Thiemo Seufer | ca30225 | 2006-05-15 18:27:03 +0100 | [diff] [blame] | 78 | }; | 
 | 79 |  | 
 | 80 | /* | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 81 |  * rt field of bcond opcodes. | 
 | 82 |  */ | 
 | 83 | enum rt_op { | 
 | 84 | 	bltz_op, bgez_op, bltzl_op, bgezl_op, | 
 | 85 | 	spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07, | 
 | 86 | 	tgei_op, tgeiu_op, tlti_op, tltiu_op, | 
 | 87 | 	teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op, | 
| Ralf Baechle | e50c0a8f | 2005-05-31 11:49:19 +0000 | [diff] [blame] | 88 | 	bltzal_op, bgezal_op, bltzall_op, bgezall_op, | 
 | 89 | 	rt_op_0x14, rt_op_0x15, rt_op_0x16, rt_op_0x17, | 
 | 90 | 	rt_op_0x18, rt_op_0x19, rt_op_0x1a, rt_op_0x1b, | 
 | 91 | 	bposge32_op, rt_op_0x1d, rt_op_0x1e, rt_op_0x1f | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 92 | }; | 
 | 93 |  | 
 | 94 | /* | 
 | 95 |  * rs field of cop opcodes. | 
 | 96 |  */ | 
 | 97 | enum cop_op { | 
 | 98 | 	mfc_op        = 0x00, dmfc_op       = 0x01, | 
 | 99 | 	cfc_op        = 0x02, mtc_op        = 0x04, | 
 | 100 | 	dmtc_op       = 0x05, ctc_op        = 0x06, | 
 | 101 | 	bc_op         = 0x08, cop_op        = 0x10, | 
 | 102 | 	copm_op       = 0x18 | 
 | 103 | }; | 
 | 104 |  | 
 | 105 | /* | 
 | 106 |  * rt field of cop.bc_op opcodes | 
 | 107 |  */ | 
 | 108 | enum bcop_op { | 
 | 109 | 	bcf_op, bct_op, bcfl_op, bctl_op | 
 | 110 | }; | 
 | 111 |  | 
 | 112 | /* | 
 | 113 |  * func field of cop0 coi opcodes. | 
 | 114 |  */ | 
 | 115 | enum cop0_coi_func { | 
 | 116 | 	tlbr_op       = 0x01, tlbwi_op      = 0x02, | 
 | 117 | 	tlbwr_op      = 0x06, tlbp_op       = 0x08, | 
 | 118 | 	rfe_op        = 0x10, eret_op       = 0x18 | 
 | 119 | }; | 
 | 120 |  | 
 | 121 | /* | 
 | 122 |  * func field of cop0 com opcodes. | 
 | 123 |  */ | 
 | 124 | enum cop0_com_func { | 
 | 125 | 	tlbr1_op      = 0x01, tlbw_op       = 0x02, | 
 | 126 | 	tlbp1_op      = 0x08, dctr_op       = 0x09, | 
 | 127 | 	dctw_op       = 0x0a | 
 | 128 | }; | 
 | 129 |  | 
 | 130 | /* | 
 | 131 |  * fmt field of cop1 opcodes. | 
 | 132 |  */ | 
 | 133 | enum cop1_fmt { | 
 | 134 | 	s_fmt, d_fmt, e_fmt, q_fmt, | 
 | 135 | 	w_fmt, l_fmt | 
 | 136 | }; | 
 | 137 |  | 
 | 138 | /* | 
 | 139 |  * func field of cop1 instructions using d, s or w format. | 
 | 140 |  */ | 
 | 141 | enum cop1_sdw_func { | 
 | 142 | 	fadd_op      =  0x00, fsub_op      =  0x01, | 
 | 143 | 	fmul_op      =  0x02, fdiv_op      =  0x03, | 
 | 144 | 	fsqrt_op     =  0x04, fabs_op      =  0x05, | 
 | 145 | 	fmov_op      =  0x06, fneg_op      =  0x07, | 
 | 146 | 	froundl_op   =  0x08, ftruncl_op   =  0x09, | 
 | 147 | 	fceill_op    =  0x0a, ffloorl_op   =  0x0b, | 
 | 148 | 	fround_op    =  0x0c, ftrunc_op    =  0x0d, | 
 | 149 | 	fceil_op     =  0x0e, ffloor_op    =  0x0f, | 
 | 150 | 	fmovc_op     =  0x11, fmovz_op     =  0x12, | 
 | 151 | 	fmovn_op     =  0x13, frecip_op    =  0x15, | 
 | 152 | 	frsqrt_op    =  0x16, fcvts_op     =  0x20, | 
 | 153 | 	fcvtd_op     =  0x21, fcvte_op     =  0x22, | 
 | 154 | 	fcvtw_op     =  0x24, fcvtl_op     =  0x25, | 
 | 155 | 	fcmp_op      =  0x30 | 
 | 156 | }; | 
 | 157 |  | 
 | 158 | /* | 
 | 159 |  * func field of cop1x opcodes (MIPS IV). | 
 | 160 |  */ | 
 | 161 | enum cop1x_func { | 
 | 162 | 	lwxc1_op     =  0x00, ldxc1_op     =  0x01, | 
 | 163 | 	pfetch_op    =  0x07, swxc1_op     =  0x08, | 
 | 164 | 	sdxc1_op     =  0x09, madd_s_op    =  0x20, | 
 | 165 | 	madd_d_op    =  0x21, madd_e_op    =  0x22, | 
 | 166 | 	msub_s_op    =  0x28, msub_d_op    =  0x29, | 
 | 167 | 	msub_e_op    =  0x2a, nmadd_s_op   =  0x30, | 
 | 168 | 	nmadd_d_op   =  0x31, nmadd_e_op   =  0x32, | 
 | 169 | 	nmsub_s_op   =  0x38, nmsub_d_op   =  0x39, | 
 | 170 | 	nmsub_e_op   =  0x3a | 
 | 171 | }; | 
 | 172 |  | 
 | 173 | /* | 
 | 174 |  * func field for mad opcodes (MIPS IV). | 
 | 175 |  */ | 
 | 176 | enum mad_func { | 
| Thiemo Seufer | ca30225 | 2006-05-15 18:27:03 +0100 | [diff] [blame] | 177 | 	madd_fp_op      = 0x08, msub_fp_op      = 0x0a, | 
 | 178 | 	nmadd_fp_op     = 0x0c, nmsub_fp_op     = 0x0e | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 179 | }; | 
 | 180 |  | 
 | 181 | /* | 
 | 182 |  * Damn ...  bitfields depend from byteorder :-( | 
 | 183 |  */ | 
 | 184 | #ifdef __MIPSEB__ | 
 | 185 | struct j_format {	/* Jump format */ | 
 | 186 | 	unsigned int opcode : 6; | 
 | 187 | 	unsigned int target : 26; | 
 | 188 | }; | 
 | 189 |  | 
 | 190 | struct i_format {	/* Immediate format (addi, lw, ...) */ | 
 | 191 | 	unsigned int opcode : 6; | 
 | 192 | 	unsigned int rs : 5; | 
 | 193 | 	unsigned int rt : 5; | 
 | 194 | 	signed int simmediate : 16; | 
 | 195 | }; | 
 | 196 |  | 
 | 197 | struct u_format {	/* Unsigned immediate format (ori, xori, ...) */ | 
 | 198 | 	unsigned int opcode : 6; | 
 | 199 | 	unsigned int rs : 5; | 
 | 200 | 	unsigned int rt : 5; | 
 | 201 | 	unsigned int uimmediate : 16; | 
 | 202 | }; | 
 | 203 |  | 
 | 204 | struct c_format {	/* Cache (>= R6000) format */ | 
 | 205 | 	unsigned int opcode : 6; | 
 | 206 | 	unsigned int rs : 5; | 
 | 207 | 	unsigned int c_op : 3; | 
 | 208 | 	unsigned int cache : 2; | 
 | 209 | 	unsigned int simmediate : 16; | 
 | 210 | }; | 
 | 211 |  | 
 | 212 | struct r_format {	/* Register format */ | 
 | 213 | 	unsigned int opcode : 6; | 
 | 214 | 	unsigned int rs : 5; | 
 | 215 | 	unsigned int rt : 5; | 
 | 216 | 	unsigned int rd : 5; | 
 | 217 | 	unsigned int re : 5; | 
 | 218 | 	unsigned int func : 6; | 
 | 219 | }; | 
 | 220 |  | 
 | 221 | struct p_format {	/* Performance counter format (R10000) */ | 
 | 222 | 	unsigned int opcode : 6; | 
 | 223 | 	unsigned int rs : 5; | 
 | 224 | 	unsigned int rt : 5; | 
 | 225 | 	unsigned int rd : 5; | 
 | 226 | 	unsigned int re : 5; | 
 | 227 | 	unsigned int func : 6; | 
 | 228 | }; | 
 | 229 |  | 
 | 230 | struct f_format {	/* FPU register format */ | 
 | 231 | 	unsigned int opcode : 6; | 
 | 232 | 	unsigned int : 1; | 
 | 233 | 	unsigned int fmt : 4; | 
 | 234 | 	unsigned int rt : 5; | 
 | 235 | 	unsigned int rd : 5; | 
 | 236 | 	unsigned int re : 5; | 
 | 237 | 	unsigned int func : 6; | 
 | 238 | }; | 
 | 239 |  | 
 | 240 | struct ma_format {	/* FPU multipy and add format (MIPS IV) */ | 
 | 241 | 	unsigned int opcode : 6; | 
 | 242 | 	unsigned int fr : 5; | 
 | 243 | 	unsigned int ft : 5; | 
 | 244 | 	unsigned int fs : 5; | 
 | 245 | 	unsigned int fd : 5; | 
 | 246 | 	unsigned int func : 4; | 
 | 247 | 	unsigned int fmt : 2; | 
 | 248 | }; | 
 | 249 |  | 
 | 250 | #elif defined(__MIPSEL__) | 
 | 251 |  | 
 | 252 | struct j_format {	/* Jump format */ | 
 | 253 | 	unsigned int target : 26; | 
 | 254 | 	unsigned int opcode : 6; | 
 | 255 | }; | 
 | 256 |  | 
 | 257 | struct i_format {	/* Immediate format */ | 
 | 258 | 	signed int simmediate : 16; | 
 | 259 | 	unsigned int rt : 5; | 
 | 260 | 	unsigned int rs : 5; | 
 | 261 | 	unsigned int opcode : 6; | 
 | 262 | }; | 
 | 263 |  | 
 | 264 | struct u_format {	/* Unsigned immediate format */ | 
 | 265 | 	unsigned int uimmediate : 16; | 
 | 266 | 	unsigned int rt : 5; | 
 | 267 | 	unsigned int rs : 5; | 
 | 268 | 	unsigned int opcode : 6; | 
 | 269 | }; | 
 | 270 |  | 
 | 271 | struct c_format {	/* Cache (>= R6000) format */ | 
 | 272 | 	unsigned int simmediate : 16; | 
 | 273 | 	unsigned int cache : 2; | 
 | 274 | 	unsigned int c_op : 3; | 
 | 275 | 	unsigned int rs : 5; | 
 | 276 | 	unsigned int opcode : 6; | 
 | 277 | }; | 
 | 278 |  | 
 | 279 | struct r_format {	/* Register format */ | 
 | 280 | 	unsigned int func : 6; | 
 | 281 | 	unsigned int re : 5; | 
 | 282 | 	unsigned int rd : 5; | 
 | 283 | 	unsigned int rt : 5; | 
 | 284 | 	unsigned int rs : 5; | 
 | 285 | 	unsigned int opcode : 6; | 
 | 286 | }; | 
 | 287 |  | 
 | 288 | struct p_format {	/* Performance counter format (R10000) */ | 
 | 289 | 	unsigned int func : 6; | 
 | 290 | 	unsigned int re : 5; | 
 | 291 | 	unsigned int rd : 5; | 
 | 292 | 	unsigned int rt : 5; | 
 | 293 | 	unsigned int rs : 5; | 
 | 294 | 	unsigned int opcode : 6; | 
 | 295 | }; | 
 | 296 |  | 
 | 297 | struct f_format {	/* FPU register format */ | 
 | 298 | 	unsigned int func : 6; | 
 | 299 | 	unsigned int re : 5; | 
 | 300 | 	unsigned int rd : 5; | 
 | 301 | 	unsigned int rt : 5; | 
 | 302 | 	unsigned int fmt : 4; | 
 | 303 | 	unsigned int : 1; | 
 | 304 | 	unsigned int opcode : 6; | 
 | 305 | }; | 
 | 306 |  | 
 | 307 | struct ma_format {	/* FPU multipy and add format (MIPS IV) */ | 
 | 308 | 	unsigned int fmt : 2; | 
 | 309 | 	unsigned int func : 4; | 
 | 310 | 	unsigned int fd : 5; | 
 | 311 | 	unsigned int fs : 5; | 
 | 312 | 	unsigned int ft : 5; | 
 | 313 | 	unsigned int fr : 5; | 
 | 314 | 	unsigned int opcode : 6; | 
 | 315 | }; | 
 | 316 |  | 
 | 317 | #else /* !defined (__MIPSEB__) && !defined (__MIPSEL__) */ | 
 | 318 | #error "MIPS but neither __MIPSEL__ nor __MIPSEB__?" | 
 | 319 | #endif | 
 | 320 |  | 
 | 321 | union mips_instruction { | 
 | 322 | 	unsigned int word; | 
 | 323 | 	unsigned short halfword[2]; | 
 | 324 | 	unsigned char byte[4]; | 
 | 325 | 	struct j_format j_format; | 
 | 326 | 	struct i_format i_format; | 
 | 327 | 	struct u_format u_format; | 
 | 328 | 	struct c_format c_format; | 
 | 329 | 	struct r_format r_format; | 
 | 330 | 	struct f_format f_format; | 
 | 331 |         struct ma_format ma_format; | 
 | 332 | }; | 
 | 333 |  | 
 | 334 | /* HACHACHAHCAHC ...  */ | 
 | 335 |  | 
 | 336 | /* In case some other massaging is needed, keep MIPSInst as wrapper */ | 
 | 337 |  | 
 | 338 | #define MIPSInst(x) x | 
 | 339 |  | 
 | 340 | #define I_OPCODE_SFT	26 | 
 | 341 | #define MIPSInst_OPCODE(x) (MIPSInst(x) >> I_OPCODE_SFT) | 
 | 342 |  | 
 | 343 | #define I_JTARGET_SFT	0 | 
 | 344 | #define MIPSInst_JTARGET(x) (MIPSInst(x) & 0x03ffffff) | 
 | 345 |  | 
 | 346 | #define I_RS_SFT	21 | 
 | 347 | #define MIPSInst_RS(x) ((MIPSInst(x) & 0x03e00000) >> I_RS_SFT) | 
 | 348 |  | 
 | 349 | #define I_RT_SFT	16 | 
 | 350 | #define MIPSInst_RT(x) ((MIPSInst(x) & 0x001f0000) >> I_RT_SFT) | 
 | 351 |  | 
 | 352 | #define I_IMM_SFT	0 | 
 | 353 | #define MIPSInst_SIMM(x) ((int)((short)(MIPSInst(x) & 0xffff))) | 
 | 354 | #define MIPSInst_UIMM(x) (MIPSInst(x) & 0xffff) | 
 | 355 |  | 
 | 356 | #define I_CACHEOP_SFT	18 | 
 | 357 | #define MIPSInst_CACHEOP(x) ((MIPSInst(x) & 0x001c0000) >> I_CACHEOP_SFT) | 
 | 358 |  | 
 | 359 | #define I_CACHESEL_SFT	16 | 
 | 360 | #define MIPSInst_CACHESEL(x) ((MIPSInst(x) & 0x00030000) >> I_CACHESEL_SFT) | 
 | 361 |  | 
 | 362 | #define I_RD_SFT	11 | 
 | 363 | #define MIPSInst_RD(x) ((MIPSInst(x) & 0x0000f800) >> I_RD_SFT) | 
 | 364 |  | 
 | 365 | #define I_RE_SFT	6 | 
 | 366 | #define MIPSInst_RE(x) ((MIPSInst(x) & 0x000007c0) >> I_RE_SFT) | 
 | 367 |  | 
 | 368 | #define I_FUNC_SFT	0 | 
 | 369 | #define MIPSInst_FUNC(x) (MIPSInst(x) & 0x0000003f) | 
 | 370 |  | 
 | 371 | #define I_FFMT_SFT	21 | 
 | 372 | #define MIPSInst_FFMT(x) ((MIPSInst(x) & 0x01e00000) >> I_FFMT_SFT) | 
 | 373 |  | 
 | 374 | #define I_FT_SFT	16 | 
 | 375 | #define MIPSInst_FT(x) ((MIPSInst(x) & 0x001f0000) >> I_FT_SFT) | 
 | 376 |  | 
 | 377 | #define I_FS_SFT	11 | 
 | 378 | #define MIPSInst_FS(x) ((MIPSInst(x) & 0x0000f800) >> I_FS_SFT) | 
 | 379 |  | 
 | 380 | #define I_FD_SFT	6 | 
 | 381 | #define MIPSInst_FD(x) ((MIPSInst(x) & 0x000007c0) >> I_FD_SFT) | 
 | 382 |  | 
 | 383 | #define I_FR_SFT	21 | 
 | 384 | #define MIPSInst_FR(x) ((MIPSInst(x) & 0x03e00000) >> I_FR_SFT) | 
 | 385 |  | 
 | 386 | #define I_FMA_FUNC_SFT	2 | 
 | 387 | #define MIPSInst_FMA_FUNC(x) ((MIPSInst(x) & 0x0000003c) >> I_FMA_FUNC_SFT) | 
 | 388 |  | 
 | 389 | #define I_FMA_FFMT_SFT	0 | 
 | 390 | #define MIPSInst_FMA_FFMT(x) (MIPSInst(x) & 0x00000003) | 
 | 391 |  | 
 | 392 | typedef unsigned int mips_instruction; | 
 | 393 |  | 
 | 394 | #endif /* _ASM_INST_H */ |