1// -*- C -*- 2 3// Simulator definition for the MIPS 32/64 revision 2 instructions. 4// Copyright (C) 2004-2024 Free Software Foundation, Inc. 5// Contributed by David Ung, of MIPS Technologies. 6// 7// This file is part of the MIPS sim. 8// 9// This program is free software; you can redistribute it and/or modify 10// it under the terms of the GNU General Public License as published by 11// the Free Software Foundation; either version 3 of the License, or 12// (at your option) any later version. 13// 14// This program is distributed in the hope that it will be useful, 15// but WITHOUT ANY WARRANTY; without even the implied warranty of 16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17// GNU General Public License for more details. 18// 19// You should have received a copy of the GNU General Public License 20// along with this program. If not, see <http://www.gnu.org/licenses/>. 21 22:function:::void:do_dsbh:int rd, int rt 23{ 24 union { uint64_t d; uint16_t h[4]; } u; 25 TRACE_ALU_INPUT1 (GPR[rt]); 26 u.d = GPR[rt]; 27 u.h[0] = SWAP_2 (u.h[0]); 28 u.h[1] = SWAP_2 (u.h[1]); 29 u.h[2] = SWAP_2 (u.h[2]); 30 u.h[3] = SWAP_2 (u.h[3]); 31 GPR[rd] = u.d; 32 TRACE_ALU_RESULT1 (GPR[rd]); 33} 34 35:function:::void:do_dshd:int rd, int rt 36{ 37 uint64_t d; 38 TRACE_ALU_INPUT1 (GPR[rt]); 39 d = GPR[rt]; 40 GPR[rd] = ((d >> 48) 41 | (d << 48) 42 | ((d & 0x0000ffff00000000ULL) >> 16) 43 | ((d & 0x00000000ffff0000ULL) << 16)); 44 TRACE_ALU_RESULT1 (GPR[rd]); 45} 46 47:function:::void:do_dext:int rt, int rs, int lsb, int size 48{ 49 TRACE_ALU_INPUT3 (GPR[rs], lsb, size); 50 GPR[rt] = EXTRACTED64 (GPR[rs], lsb + size, lsb); 51 TRACE_ALU_RESULT1 (GPR[rt]); 52} 53 54:function:::void:do_dextm:int rt, int rs, int lsb, int size 55{ 56 TRACE_ALU_INPUT3 (GPR[rs], lsb, size); 57 GPR[rt] = EXTRACTED64 (GPR[rs], lsb + size + 32, lsb); 58 TRACE_ALU_RESULT1 (GPR[rt]); 59} 60 61:function:::void:do_dextu:int rt, int rs, int lsb, int size 62{ 63 TRACE_ALU_INPUT3 (GPR[rs], lsb, size); 64 GPR[rt] = EXTRACTED64 (GPR[rs], lsb + 32 + size, lsb + 32); 65 TRACE_ALU_RESULT1 (GPR[rt]); 66} 67 68:function:::void:do_di:int rt 69{ 70 TRACE_ALU_INPUT0 (); 71 GPR[rt] = EXTEND32 (SR); 72 SR &= ~status_IE; 73 TRACE_ALU_RESULT1 (GPR[rt]); 74} 75 76:function:::void:do_dins:int rt, int rs, int lsb, int msb 77{ 78 TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb); 79 if (lsb <= msb) 80 GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << lsb)) & MASK64 (msb, lsb); 81 TRACE_ALU_RESULT1 (GPR[rt]); 82} 83 84:function:::void:do_dinsm:int rt, int rs, int lsb, int msb 85{ 86 TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb); 87 if (lsb <= msb + 32) 88 GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << lsb)) & MASK64 (msb + 32, lsb); 89 TRACE_ALU_RESULT1 (GPR[rt]); 90} 91 92:function:::void:do_ei:int rt 93{ 94 TRACE_ALU_INPUT0 (); 95 GPR[rt] = EXTEND32 (SR); 96 SR |= status_IE; 97 TRACE_ALU_RESULT1 (GPR[rt]); 98} 99 100:function:::void:do_ext:int rt, int rs, int lsb, int size 101{ 102 TRACE_ALU_INPUT3 (GPR[rs], lsb, size); 103 GPR[rt] = EXTEND32 (EXTRACTED32 (GPR[rs], lsb + size, lsb)); 104 TRACE_ALU_RESULT1 (GPR[rt]); 105} 106 107:function:::void:do_mfhc1:int rt, int fs 108{ 109 check_fpu (SD_); 110 if (SizeFGR() == 64) 111 GPR[rt] = EXTEND32 (WORD64HI (FGR[fs])); 112 else if ((fs & 0x1) == 0) 113 GPR[rt] = EXTEND32 (FGR[fs + 1]); 114 else 115 { 116 if (STATE_VERBOSE_P(SD)) 117 sim_io_eprintf (SD, 118 "Warning: PC 0x%lx: MFHC1 32-bit use of odd FPR number\n", 119 (long) CIA); 120 GPR[rt] = EXTEND32 (0xBADF00D); 121 } 122 TRACE_ALU_RESULT (GPR[rt]); 123} 124 125:function:::void:do_mthc1:int rt, int fs 126{ 127 check_fpu (SD_); 128 if (SizeFGR() == 64) 129 StoreFPR (fs, fmt_uninterpreted_64, SET64HI (GPR[rt]) | VL4_8 (FGR[fs])); 130 else if ((fs & 0x1) == 0) 131 StoreFPR (fs + 1, fmt_uninterpreted_32, VL4_8 (GPR[rt])); 132 else 133 { 134 if (STATE_VERBOSE_P(SD)) 135 sim_io_eprintf (SD, 136 "Warning: PC 0x%lx: MTHC1 32-bit use of odd FPR number\n", 137 (long) CIA); 138 StoreFPR (fs, fmt_uninterpreted_32, 0xDEADC0DE); 139 } 140 TRACE_FP_RESULT (GPR[rt]); 141} 142 143:function:::void:do_ins:int rt, int rs, int lsb, int msb 144{ 145 TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb); 146 if (lsb <= msb) 147 GPR[rt] = EXTEND32 (GPR[rt] ^ 148 ((GPR[rt] ^ (GPR[rs] << lsb)) & MASK32 (msb, lsb))); 149 TRACE_ALU_RESULT1 (GPR[rt]); 150} 151 152:function:::void:do_dinsu:int rt, int rs, int lsb, int msb 153{ 154 TRACE_ALU_INPUT4 (GPR[rt], GPR[rs], lsb, msb); 155 if (lsb <= msb) 156 GPR[rt] ^= (GPR[rt] ^ (GPR[rs] << (lsb + 32))) 157 & MASK64 (msb + 32, lsb + 32); 158 TRACE_ALU_RESULT1 (GPR[rt]); 159} 160 161:function:::void:do_seb:int rd, int rt 162{ 163 TRACE_ALU_INPUT1 (GPR[rt]); 164 GPR[rd] = EXTEND8 (GPR[rt]); 165 TRACE_ALU_RESULT1 (GPR[rd]); 166} 167 168:function:::void:do_seh:int rd, int rt 169{ 170 TRACE_ALU_INPUT1 (GPR[rt]); 171 GPR[rd] = EXTEND16 (GPR[rt]); 172 TRACE_ALU_RESULT1 (GPR[rd]); 173} 174 175:function:::void:do_rdhwr:int rt, int rd 176{ 177 // Return 0 for all hardware registers currently 178 GPR[rt] = EXTEND32 (0); 179 TRACE_ALU_RESULT1 (GPR[rt]); 180} 181 182:function:::void:do_wsbh:int rd, int rt 183{ 184 union { uint32_t w; uint16_t h[2]; } u; 185 TRACE_ALU_INPUT1 (GPR[rt]); 186 u.w = GPR[rt]; 187 u.h[0] = SWAP_2 (u.h[0]); 188 u.h[1] = SWAP_2 (u.h[1]); 189 GPR[rd] = EXTEND32 (u.w); 190 TRACE_ALU_RESULT1 (GPR[rd]); 191} 192 193011111,5.RS,5.RT,5.SIZE,5.LSB,000011::64::DEXT 194"dext r<RT>, r<RS>, <LSB>, <SIZE+1>" 195*mips64r2: 196*mips64r6: 197{ 198 check_u64 (SD_, instruction_0); 199 do_dext (SD_, RT, RS, LSB, SIZE); 200} 201 202011111,5.RS,5.RT,5.SIZE,5.LSB,000001::64::DEXTM 203"dextm r<RT>, r<RS>, <LSB>, <SIZE+33>" 204*mips64r2: 205*mips64r6: 206{ 207 check_u64 (SD_, instruction_0); 208 do_dextm (SD_, RT, RS, LSB, SIZE); 209} 210 211011111,5.RS,5.RT,5.SIZE,5.LSB,000010::64::DEXTU 212"dextu r<RT>, r<RS>, <LSB+32>, <SIZE+1>" 213*mips64r2: 214*mips64r6: 215{ 216 check_u64 (SD_, instruction_0); 217 do_dextu (SD_, RT, RS, LSB, SIZE); 218} 219 220 221010000,01011,5.RT,01100,00000,0,00,000::32::DI 222"di":RT == 0 223"di r<RT>" 224*mips32r2: 225*mips32r6: 226*mips64r2: 227*mips64r6: 228{ 229 do_di (SD_, RT); 230} 231 232 233011111,5.RS,5.RT,5.MSB,5.LSB,000111::64::DINS 234"dins r<RT>, r<RS>, <LSB>, <MSB-LSB+1>" 235*mips64r2: 236*mips64r6: 237{ 238 check_u64 (SD_, instruction_0); 239 do_dins (SD_, RT, RS, LSB, MSB); 240} 241 242011111,5.RS,5.RT,5.MSB,5.LSB,000101::64::DINSM 243"dinsm r<RT>, r<RS>, <LSB>, <MSB+32-LSB+1>" 244*mips64r2: 245*mips64r6: 246{ 247 check_u64 (SD_, instruction_0); 248 do_dinsm (SD_, RT, RS, LSB, MSB); 249} 250 251011111,5.RS,5.RT,5.MSB,5.LSB,000110::64::DINSU 252"dinsu r<RT>, r<RS>, <LSB+32>, <MSB-LSB+1>" 253*mips64r2: 254*mips64r6: 255{ 256 check_u64 (SD_, instruction_0); 257 do_dinsu (SD_, RT, RS, LSB, MSB); 258} 259 260 261011111,00000,5.RT,5.RD,00010,100100::64::DSBH 262"dsbh r<RD>, r<RT>" 263*mips64r2: 264*mips64r6: 265{ 266 check_u64 (SD_, instruction_0); 267 do_dsbh (SD_, RD, RT); 268} 269 270011111,00000,5.RT,5.RD,00101,100100::64::DSHD 271"dshd r<RD>, r<RT>" 272*mips64r2: 273*mips64r6: 274{ 275 check_u64 (SD_, instruction_0); 276 do_dshd (SD_, RD, RT); 277} 278 279010000,01011,5.RT,01100,00000,1,00,000::32::EI 280"ei":RT == 0 281"ei r<RT>" 282*mips32r2: 283*mips32r6: 284*mips64r2: 285*mips64r6: 286{ 287 do_ei (SD_, RT); 288} 289 290 291011111,5.RS,5.RT,5.SIZE,5.LSB,000000::32::EXT 292"ext r<RT>, r<RS>, <LSB>, <SIZE+1>" 293*mips32r2: 294*mips32r6: 295*mips64r2: 296*mips64r6: 297{ 298 do_ext (SD_, RT, RS, LSB, SIZE); 299} 300 301 302010001,00011,5.RT,5.FS,00000000000:COP1Sa:32,f::MFHC1 303"mfhc1 r<RT>, f<FS>" 304*mips32r2: 305*mips32r6: 306*mips64r2: 307*mips64r6: 308{ 309 do_mfhc1 (SD_, RT, FS); 310} 311 312010001,00111,5.RT,5.FS,00000000000:COP1Sa:32,f::MTHC1 313"mthc1 r<RT>, f<FS>" 314*mips32r2: 315*mips32r6: 316*mips64r2: 317*mips64r6: 318{ 319 do_mthc1 (SD_, RT, FS); 320} 321 322 323011111,5.RS,5.RT,5.MSB,5.LSB,000100::32::INS 324"ins r<RT>, r<RS>, <LSB>, <MSB-LSB+1>" 325*mips32r2: 326*mips32r6: 327*mips64r2: 328*mips64r6: 329{ 330 do_ins (SD_, RT, RS, LSB, MSB); 331} 332 333 334011111,00000,5.RT,5.RD,10000,100000::32::SEB 335"seb r<RD>, r<RT>" 336*mips32r2: 337*mips32r6: 338*mips64r2: 339*mips64r6: 340{ 341 do_seb (SD_, RD, RT); 342} 343 344011111,00000,5.RT,5.RD,11000,100000::32::SEH 345"seh r<RD>, r<RT>" 346*mips32r2: 347*mips32r6: 348*mips64r2: 349*mips64r6: 350{ 351 do_seh (SD_, RD, RT); 352} 353 354 355000001,5.BASE,11111,16.OFFSET::32::SYNCI 356"synci <OFFSET>(r<BASE>)" 357*mips32r2: 358*mips32r6: 359*mips64r2: 360*mips64r6: 361{ 362 // sync i-cache - nothing to do currently 363} 364 365 366011111,00000,5.RT,5.RD,00000,111011::32::RDHWR 367"rdhwr r<RT>, r<RD>" 368*mips32r2: 369*mips32r6: 370*mips64r2: 371*mips64r6: 372{ 373 do_rdhwr (SD_, RT, RD); 374} 375 376 377011111,00000,5.RT,5.RD,00010,100000::32::WSBH 378"wsbh r<RD>, r<RT>" 379*mips32r2: 380*mips32r6: 381*mips64r2: 382*mips64r6: 383{ 384 do_wsbh (SD_, RD, RT); 385} 386 387 388 389