1// -*- C -*- 2 3// Simulator definition for the MIPS 32/64 revision 2 instructions. 4// Copyright (C) 2004-2020 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 { unsigned64 d; unsigned16 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 unsigned64 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 { unsigned32 w; unsigned16 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{ 197 check_u64 (SD_, instruction_0); 198 do_dext (SD_, RT, RS, LSB, SIZE); 199} 200 201011111,5.RS,5.RT,5.SIZE,5.LSB,000001::64::DEXTM 202"dextm r<RT>, r<RS>, <LSB>, <SIZE+33>" 203*mips64r2: 204{ 205 check_u64 (SD_, instruction_0); 206 do_dextm (SD_, RT, RS, LSB, SIZE); 207} 208 209011111,5.RS,5.RT,5.SIZE,5.LSB,000010::64::DEXTU 210"dextu r<RT>, r<RS>, <LSB+32>, <SIZE+1>" 211*mips64r2: 212{ 213 check_u64 (SD_, instruction_0); 214 do_dextu (SD_, RT, RS, LSB, SIZE); 215} 216 217 218010000,01011,5.RT,01100,00000,0,00,000::32::DI 219"di":RT == 0 220"di r<RT>" 221*mips32r2: 222*mips64r2: 223{ 224 do_di (SD_, RT); 225} 226 227 228011111,5.RS,5.RT,5.MSB,5.LSB,000111::64::DINS 229"dins r<RT>, r<RS>, <LSB>, <MSB-LSB+1>" 230*mips64r2: 231{ 232 check_u64 (SD_, instruction_0); 233 do_dins (SD_, RT, RS, LSB, MSB); 234} 235 236011111,5.RS,5.RT,5.MSB,5.LSB,000101::64::DINSM 237"dinsm r<RT>, r<RS>, <LSB>, <MSB+32-LSB+1>" 238*mips64r2: 239{ 240 check_u64 (SD_, instruction_0); 241 do_dinsm (SD_, RT, RS, LSB, MSB); 242} 243 244011111,5.RS,5.RT,5.MSB,5.LSB,000110::64::DINSU 245"dinsu r<RT>, r<RS>, <LSB+32>, <MSB-LSB+1>" 246*mips64r2: 247{ 248 check_u64 (SD_, instruction_0); 249 do_dinsu (SD_, RT, RS, LSB, MSB); 250} 251 252 253011111,00000,5.RT,5.RD,00010,100100::64::DSBH 254"dsbh r<RD>, r<RT>" 255*mips64r2: 256{ 257 check_u64 (SD_, instruction_0); 258 do_dsbh (SD_, RD, RT); 259} 260 261011111,00000,5.RT,5.RD,00101,100100::64::DSHD 262"dshd r<RD>, r<RT>" 263*mips64r2: 264{ 265 check_u64 (SD_, instruction_0); 266 do_dshd (SD_, RD, RT); 267} 268 269010000,01011,5.RT,01100,00000,1,00,000::32::EI 270"ei":RT == 0 271"ei r<RT>" 272*mips32r2: 273*mips64r2: 274{ 275 do_ei (SD_, RT); 276} 277 278 279011111,5.RS,5.RT,5.SIZE,5.LSB,000000::32::EXT 280"ext r<RT>, r<RS>, <LSB>, <SIZE+1>" 281*mips32r2: 282*mips64r2: 283{ 284 do_ext (SD_, RT, RS, LSB, SIZE); 285} 286 287 288010001,00011,5.RT,5.FS,00000000000:COP1Sa:32,f::MFHC1 289"mfhc1 r<RT>, f<FS>" 290*mips32r2: 291*mips64r2: 292{ 293 do_mfhc1 (SD_, RT, FS); 294} 295 296010001,00111,5.RT,5.FS,00000000000:COP1Sa:32,f::MTHC1 297"mthc1 r<RT>, f<FS>" 298*mips32r2: 299*mips64r2: 300{ 301 do_mthc1 (SD_, RT, FS); 302} 303 304 305011111,5.RS,5.RT,5.MSB,5.LSB,000100::32::INS 306"ins r<RT>, r<RS>, <LSB>, <MSB-LSB+1>" 307*mips32r2: 308*mips64r2: 309{ 310 do_ins (SD_, RT, RS, LSB, MSB); 311} 312 313 314011111,00000,5.RT,5.RD,10000,100000::32::SEB 315"seb r<RD>, r<RT>" 316*mips32r2: 317*mips64r2: 318{ 319 do_seb (SD_, RD, RT); 320} 321 322011111,00000,5.RT,5.RD,11000,100000::32::SEH 323"seh r<RD>, r<RT>" 324*mips32r2: 325*mips64r2: 326{ 327 do_seh (SD_, RD, RT); 328} 329 330 331000001,5.BASE,11111,16.OFFSET::32::SYNCI 332"synci <OFFSET>(r<BASE>)" 333*mips32r2: 334*mips64r2: 335{ 336 // sync i-cache - nothing to do currently 337} 338 339 340011111,00000,5.RT,5.RD,00000,111011::32::RDHWR 341"rdhwr r<RT>, r<RD>" 342*mips32r2: 343*mips64r2: 344{ 345 do_rdhwr (SD_, RT, RD); 346} 347 348 349011111,00000,5.RT,5.RD,00010,100000::32::WSBH 350"wsbh r<RD>, r<RT>" 351*mips32r2: 352*mips64r2: 353{ 354 do_wsbh (SD_, RD, RT); 355} 356 357 358 359