1 1.1 christos // -*- C -*- 2 1.1 christos 3 1.1 christos // Simulator definition for the MIPS DSP ASE. 4 1.1.1.11 christos // Copyright (C) 2005-2025 Free Software Foundation, Inc. 5 1.1 christos // Contributed by MIPS Technologies, Inc. Written by Chao-ying Fu. 6 1.1 christos // 7 1.1.1.5 christos // This file is part of the MIPS sim 8 1.1 christos // 9 1.1 christos // This program is free software; you can redistribute it and/or modify 10 1.1 christos // it under the terms of the GNU General Public License as published by 11 1.1 christos // the Free Software Foundation; either version 3 of the License, or 12 1.1 christos // (at your option) any later version. 13 1.1 christos // 14 1.1 christos // This program is distributed in the hope that it will be useful, 15 1.1 christos // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 1.1 christos // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 1.1 christos // GNU General Public License for more details. 18 1.1 christos // 19 1.1 christos // You should have received a copy of the GNU General Public License 20 1.1 christos // along with this program. If not, see <http://www.gnu.org/licenses/>. 21 1.1 christos 22 1.1 christos 23 1.1 christos // op: 0 = ADD, 1 = SUB, 2 = MUL 24 1.1 christos // sat: 0 = no saturation, 1 = saturation 25 1.1 christos :function:::void:do_ph_op:int rd, int rs, int rt, int op, int sat 26 1.1 christos { 27 1.1 christos int i; 28 1.1.1.9 christos int32_t h0 = 0; 29 1.1.1.9 christos int16_t h1, h2; 30 1.1.1.9 christos uint32_t v1 = GPR[rs]; 31 1.1.1.9 christos uint32_t v2 = GPR[rt]; 32 1.1.1.9 christos uint32_t result = 0; 33 1.1 christos for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 34 1.1 christos { 35 1.1.1.9 christos h1 = (int16_t)(v1 & 0xffff); 36 1.1.1.9 christos h2 = (int16_t)(v2 & 0xffff); 37 1.1 christos if (op == 0) // ADD 38 1.1.1.9 christos h0 = (int32_t)h1 + (int32_t)h2; 39 1.1 christos else if (op == 1) // SUB 40 1.1.1.9 christos h0 = (int32_t)h1 - (int32_t)h2; 41 1.1 christos else // MUL 42 1.1.1.9 christos h0 = (int32_t)h1 * (int32_t)h2; 43 1.1.1.9 christos if (h0 > (int32_t)0x7fff || h0 < (int32_t)0xffff8000) 44 1.1 christos { 45 1.1 christos if (op == 0 || op == 1) // ADD, SUB 46 1.1 christos DSPCR |= DSPCR_OUFLAG4; 47 1.1 christos else if (op == 2) // MUL 48 1.1 christos DSPCR |= DSPCR_OUFLAG5; 49 1.1 christos if (sat == 1) 50 1.1 christos { 51 1.1.1.9 christos if (h0 > (int32_t)0x7fff) 52 1.1 christos h0 = 0x7fff; 53 1.1 christos else 54 1.1 christos h0 = 0x8000; 55 1.1 christos } 56 1.1 christos } 57 1.1.1.9 christos result |= ((uint32_t)((uint16_t)h0) << i); 58 1.1 christos } 59 1.1 christos GPR[rd] = EXTEND32 (result); 60 1.1 christos } 61 1.1 christos 62 1.1 christos // op: 0 = ADD, 1 = SUB 63 1.1 christos :function:::void:do_w_op:int rd, int rs, int rt, int op 64 1.1 christos { 65 1.1.1.9 christos int64_t h0; 66 1.1.1.9 christos int32_t h1, h2; 67 1.1.1.9 christos uint32_t v1 = GPR[rs]; 68 1.1.1.9 christos uint32_t v2 = GPR[rt]; 69 1.1.1.9 christos h1 = (int32_t)v1; 70 1.1.1.9 christos h2 = (int32_t)v2; 71 1.1 christos if (op == 0) // ADD 72 1.1.1.9 christos h0 = (int64_t)h1 + (int64_t)h2; 73 1.1 christos else // SUB 74 1.1.1.9 christos h0 = (int64_t)h1 - (int64_t)h2; 75 1.1 christos if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000)) 76 1.1 christos { 77 1.1 christos DSPCR |= DSPCR_OUFLAG4; 78 1.1 christos if (h0 & 0x100000000LL) 79 1.1 christos h0 = 0x80000000; 80 1.1 christos else 81 1.1 christos h0 = 0x7fffffff; 82 1.1 christos } 83 1.1 christos GPR[rd] = EXTEND32 (h0); 84 1.1 christos } 85 1.1 christos 86 1.1 christos // op: 0 = ADD, 1 = SUB 87 1.1 christos // sat: 0 = no saturation, 1 = saturation 88 1.1 christos :function:::void:do_qb_op:int rd, int rs, int rt, int op, int sat 89 1.1 christos { 90 1.1 christos int i; 91 1.1.1.9 christos uint32_t h0; 92 1.1.1.9 christos uint8_t h1, h2; 93 1.1.1.9 christos uint32_t v1 = GPR[rs]; 94 1.1.1.9 christos uint32_t v2 = GPR[rt]; 95 1.1.1.9 christos uint32_t result = 0; 96 1.1 christos for (i = 0; i < 32; i += 8, v1 >>= 8, v2 >>= 8) 97 1.1 christos { 98 1.1.1.9 christos h1 = (uint8_t)(v1 & 0xff); 99 1.1.1.9 christos h2 = (uint8_t)(v2 & 0xff); 100 1.1 christos if (op == 0) // ADD 101 1.1.1.9 christos h0 = (uint32_t)h1 + (uint32_t)h2; 102 1.1 christos else // SUB 103 1.1.1.9 christos h0 = (uint32_t)h1 - (uint32_t)h2; 104 1.1 christos if (h0 & 0x100) 105 1.1 christos { 106 1.1 christos DSPCR |= DSPCR_OUFLAG4; 107 1.1 christos if (sat == 1) 108 1.1 christos { 109 1.1 christos if (op == 0) // ADD 110 1.1 christos h0 = 0xff; 111 1.1 christos else // SUB 112 1.1 christos h0 = 0; 113 1.1 christos } 114 1.1 christos } 115 1.1.1.9 christos result |= ((uint32_t)((uint8_t)h0) << i); 116 1.1 christos } 117 1.1 christos GPR[rd] = EXTEND32 (result); 118 1.1 christos } 119 1.1 christos 120 1.1 christos // op: 0 = left, 1 = right 121 1.1 christos :function:::void:do_qb_shift:int rd, int rt, int shift, int op 122 1.1 christos { 123 1.1 christos int i, j; 124 1.1.1.9 christos uint8_t h0; 125 1.1.1.9 christos uint32_t v1 = GPR[rt]; 126 1.1.1.9 christos uint32_t result = 0; 127 1.1 christos for (i = 0; i < 32; i += 8, v1 >>= 8) 128 1.1 christos { 129 1.1.1.9 christos h0 = (uint8_t)(v1 & 0xff); 130 1.1 christos if (op == 0) // left 131 1.1 christos { 132 1.1 christos for (j = 7; j >= 8 - shift; j--) 133 1.1 christos { 134 1.1 christos if (h0 & (1<<j)) 135 1.1 christos { 136 1.1 christos DSPCR |= DSPCR_OUFLAG6; 137 1.1 christos break; 138 1.1 christos } 139 1.1 christos } 140 1.1 christos h0 = h0 << shift; 141 1.1 christos } 142 1.1 christos else // right 143 1.1 christos h0 = h0 >> shift; 144 1.1.1.9 christos result |= ((uint32_t)h0 << i); 145 1.1 christos } 146 1.1 christos GPR[rd] = EXTEND32 (result); 147 1.1 christos } 148 1.1 christos 149 1.1 christos // op: 0 = left, 1 = right 150 1.1 christos // sat: 0 = no saturation/rounding, 1 = saturation/rounding 151 1.1 christos :function:::void:do_ph_shift:int rd, int rt, int shift, int op, int sat 152 1.1 christos { 153 1.1 christos int i, j; 154 1.1.1.9 christos int16_t h0; 155 1.1.1.9 christos uint32_t v1 = GPR[rt]; 156 1.1.1.9 christos uint32_t result = 0; 157 1.1 christos int setcond; 158 1.1 christos for (i = 0; i < 32; i += 16, v1 >>= 16) 159 1.1 christos { 160 1.1.1.9 christos h0 = (int16_t)(v1 & 0xffff); 161 1.1 christos if (op == 0) // left 162 1.1 christos { 163 1.1 christos setcond = 0; 164 1.1 christos if (h0 & (1<<15)) 165 1.1 christos { 166 1.1 christos for (j = 14; j >= 15 - shift; j--) 167 1.1 christos { 168 1.1 christos if (!(h0 & (1 << j))) 169 1.1 christos { 170 1.1 christos DSPCR |= DSPCR_OUFLAG6; 171 1.1 christos setcond = 1; 172 1.1 christos break; 173 1.1 christos } 174 1.1 christos } 175 1.1 christos } 176 1.1 christos else 177 1.1 christos { 178 1.1 christos for (j = 14; j >= 15 - shift; j--) 179 1.1 christos { 180 1.1 christos if (h0 & (1 << j)) 181 1.1 christos { 182 1.1 christos DSPCR |= DSPCR_OUFLAG6; 183 1.1 christos setcond = 2; 184 1.1 christos break; 185 1.1 christos } 186 1.1 christos } 187 1.1 christos } 188 1.1 christos h0 = h0 << shift; 189 1.1 christos if (sat == 1) 190 1.1 christos { 191 1.1 christos if (setcond == 2) 192 1.1.1.9 christos h0 = 0x7fff; 193 1.1 christos else if (setcond == 1) 194 1.1 christos h0 = 0x8000; 195 1.1 christos } 196 1.1 christos } 197 1.1 christos else // right 198 1.1 christos { 199 1.1 christos if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1)))) 200 1.1 christos h0 = (h0 >> shift) + 1; 201 1.1 christos else 202 1.1 christos h0 = h0 >> shift; 203 1.1 christos } 204 1.1 christos 205 1.1.1.9 christos result |= ((uint32_t)((uint16_t)h0) << i); 206 1.1 christos } 207 1.1 christos GPR[rd] = EXTEND32 (result); 208 1.1 christos } 209 1.1 christos 210 1.1 christos :function:::void:do_w_shll:int rd, int rt, int shift 211 1.1 christos { 212 1.1 christos int i; 213 1.1.1.9 christos uint32_t v1 = GPR[rt]; 214 1.1.1.9 christos uint32_t result = 0; 215 1.1 christos int setcond = 0; 216 1.1 christos if (v1 & (1 << 31)) 217 1.1 christos { 218 1.1 christos for (i = 30; i >= 31 - shift; i--) 219 1.1 christos { 220 1.1 christos if (!(v1 & (1 << i))) 221 1.1 christos { 222 1.1 christos DSPCR |= DSPCR_OUFLAG6; 223 1.1 christos setcond = 1; 224 1.1 christos break; 225 1.1 christos } 226 1.1 christos } 227 1.1 christos } 228 1.1 christos else 229 1.1 christos { 230 1.1 christos for (i = 30; i >= 31 - shift; i--) 231 1.1 christos { 232 1.1 christos if (v1 & (1 << i)) 233 1.1 christos { 234 1.1 christos DSPCR |= DSPCR_OUFLAG6; 235 1.1 christos setcond = 2; 236 1.1 christos break; 237 1.1 christos } 238 1.1 christos } 239 1.1 christos } 240 1.1 christos if (setcond == 2) 241 1.1.1.9 christos result = 0x7fffffff; 242 1.1 christos else if (setcond == 1) 243 1.1 christos result = 0x80000000; 244 1.1 christos else 245 1.1.1.9 christos result = v1 << shift; 246 1.1 christos GPR[rd] = EXTEND32 (result); 247 1.1 christos } 248 1.1 christos 249 1.1.1.5 christos :function:::void:do_ph_s_absq:int rd, int rt 250 1.1.1.5 christos { 251 1.1.1.5 christos int i; 252 1.1.1.9 christos int16_t h0; 253 1.1.1.9 christos uint32_t v1 = GPR[rt]; 254 1.1.1.9 christos uint32_t result = 0; 255 1.1.1.5 christos for (i = 0; i < 32; i += 16, v1 >>= 16) 256 1.1.1.5 christos { 257 1.1.1.9 christos h0 = (int16_t)(v1 & 0xffff); 258 1.1.1.9 christos if (h0 == (int16_t)0x8000) 259 1.1.1.5 christos { 260 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG4; 261 1.1.1.5 christos h0 = 0x7fff; 262 1.1.1.5 christos } 263 1.1.1.5 christos else if (h0 & 0x8000) 264 1.1.1.5 christos h0 = -h0; 265 1.1.1.9 christos result |= ((uint32_t)((uint16_t)h0) << i); 266 1.1.1.5 christos } 267 1.1.1.5 christos GPR[rd] = EXTEND32 (result); 268 1.1.1.5 christos } 269 1.1.1.5 christos 270 1.1.1.5 christos :function:::void:do_w_s_absq:int rd, int rt 271 1.1.1.5 christos { 272 1.1.1.9 christos uint32_t v1 = GPR[rt]; 273 1.1.1.9 christos int32_t h0 = (int32_t)v1; 274 1.1.1.9 christos if (h0 == (int32_t)0x80000000) 275 1.1.1.5 christos { 276 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG4; 277 1.1.1.5 christos h0 = 0x7fffffff; 278 1.1.1.5 christos } 279 1.1.1.5 christos else if (h0 & 0x80000000) 280 1.1.1.5 christos h0 = -h0; 281 1.1.1.5 christos GPR[rd] = EXTEND32 (h0); 282 1.1.1.5 christos } 283 1.1.1.5 christos 284 1.1.1.5 christos :function:::void:do_qb_s_absq:int rd, int rt 285 1.1.1.5 christos { 286 1.1.1.5 christos int i; 287 1.1.1.9 christos int8_t q0; 288 1.1.1.9 christos uint32_t v1 = GPR[rt]; 289 1.1.1.9 christos uint32_t result = 0; 290 1.1.1.5 christos for (i = 0; i < 32; i += 8, v1 >>= 8) 291 1.1.1.5 christos { 292 1.1.1.9 christos q0 = (int8_t)(v1 & 0xff); 293 1.1.1.9 christos if (q0 == (int8_t)0x80) 294 1.1.1.5 christos { 295 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG4; 296 1.1.1.5 christos q0 = 0x7f; 297 1.1.1.5 christos } 298 1.1.1.5 christos else if (q0 & 0x80) 299 1.1.1.5 christos q0 = -q0; 300 1.1.1.9 christos result |= ((uint32_t)((uint8_t)q0) << i); 301 1.1.1.5 christos } 302 1.1.1.5 christos GPR[rd] = EXTEND32 (result); 303 1.1.1.5 christos } 304 1.1.1.5 christos 305 1.1.1.5 christos :function:::void:do_addsc:int rd, int rs, int rt 306 1.1.1.5 christos { 307 1.1.1.9 christos uint32_t v1 = GPR[rs]; 308 1.1.1.9 christos uint32_t v2 = GPR[rt]; 309 1.1.1.9 christos uint64_t h0; 310 1.1.1.9 christos h0 = (uint64_t)v1 + (uint64_t)v2; 311 1.1.1.5 christos if (h0 & 0x100000000LL) 312 1.1.1.5 christos DSPCR |= DSPCR_CARRY; 313 1.1.1.5 christos GPR[rd] = EXTEND32 (h0); 314 1.1.1.5 christos } 315 1.1.1.5 christos 316 1.1.1.5 christos :function:::void:do_addwc:int rd, int rs, int rt 317 1.1.1.5 christos { 318 1.1.1.9 christos uint32_t v1 = GPR[rs]; 319 1.1.1.9 christos uint32_t v2 = GPR[rt]; 320 1.1.1.9 christos uint64_t h0; 321 1.1.1.9 christos int32_t h1 = (int32_t) v1; 322 1.1.1.9 christos int32_t h2 = (int32_t) v2; 323 1.1.1.9 christos h0 = (int64_t)h1 + (int64_t)h2 324 1.1.1.9 christos + (int64_t)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK); 325 1.1.1.5 christos if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000)) 326 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG4; 327 1.1.1.5 christos GPR[rd] = EXTEND32 (h0); 328 1.1.1.5 christos } 329 1.1.1.5 christos 330 1.1.1.5 christos :function:::void:do_bitrev:int rd, int rt 331 1.1.1.5 christos { 332 1.1.1.5 christos int i; 333 1.1.1.9 christos uint32_t v1 = GPR[rt]; 334 1.1.1.9 christos uint32_t h1 = 0; 335 1.1.1.5 christos for (i = 0; i < 16; i++) 336 1.1.1.5 christos { 337 1.1.1.5 christos if (v1 & (1 << i)) 338 1.1.1.5 christos h1 |= (1 << (15 - i)); 339 1.1.1.5 christos } 340 1.1.1.5 christos GPR[rd] = EXTEND32 (h1); 341 1.1.1.5 christos } 342 1.1.1.5 christos 343 1.1.1.5 christos // op: 0 = EXTPV, 1 = EXTPDPV 344 1.1.1.5 christos :function:::void:do_extpv:int rt, int ac, int rs, int op 345 1.1.1.5 christos { 346 1.1.1.9 christos uint32_t size = GPR[rs] & 0x1f; 347 1.1.1.5 christos do_extp (SD_, rt, ac, size, op); 348 1.1.1.5 christos } 349 1.1.1.5 christos 350 1.1.1.5 christos // op: 0 = EXTRV, 1 = EXTRV_R, 2 = EXTRV_RS 351 1.1.1.5 christos :function:::void:do_extrv:int rt, int ac, int rs, int op 352 1.1.1.5 christos { 353 1.1.1.9 christos uint32_t shift = GPR[rs] & 0x1f; 354 1.1.1.5 christos do_w_extr (SD_, rt, ac, shift, op); 355 1.1.1.5 christos } 356 1.1.1.5 christos 357 1.1.1.5 christos :function:::void:do_extrv_s_h:int rt, int ac, int rs 358 1.1.1.5 christos { 359 1.1.1.9 christos uint32_t shift = GPR[rs] & 0x1f; 360 1.1.1.5 christos do_h_extr (SD_, rt, ac, shift); 361 1.1.1.5 christos } 362 1.1.1.5 christos 363 1.1.1.5 christos :function:::void:do_insv:int rt, int rs 364 1.1.1.5 christos { 365 1.1.1.9 christos uint32_t v1 = GPR[rs]; 366 1.1.1.9 christos uint32_t v2 = GPR[rt]; 367 1.1.1.9 christos uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 368 1.1.1.9 christos uint32_t size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK; 369 1.1.1.9 christos uint32_t mask1, mask2, mask3, result; 370 1.1.1.5 christos if (size < 32) 371 1.1.1.5 christos mask1 = (1 << size) - 1; 372 1.1.1.5 christos else 373 1.1.1.5 christos mask1 = 0xffffffff; 374 1.1.1.5 christos mask2 = (1 << pos) - 1; 375 1.1.1.5 christos if (pos + size < 32) 376 1.1.1.5 christos mask3 = ~((1 << (pos + size)) - 1); 377 1.1.1.5 christos else 378 1.1.1.5 christos mask3 = 0; 379 1.1.1.5 christos result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2); 380 1.1.1.5 christos GPR[rt] = EXTEND32 (result); 381 1.1.1.5 christos } 382 1.1.1.5 christos 383 1.1.1.5 christos // op: 0 = NORMAL, 1 = EXTEND16, 2 = EXTEND32 384 1.1.1.5 christos :function:::void:do_lxx:int rd, int base, int index, int op 385 1.1.1.5 christos { 386 1.1.1.5 christos if (op == 0) 387 1.1.1.5 christos GPR[rd] = do_load (SD_, AccessLength_BYTE, GPR[base], GPR[index]); 388 1.1.1.5 christos else if (op == 1) 389 1.1.1.5 christos GPR[rd] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base], GPR[index])); 390 1.1.1.5 christos else if (op == 2) 391 1.1.1.5 christos GPR[rd] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base], GPR[index])); 392 1.1.1.5 christos } 393 1.1.1.5 christos 394 1.1.1.5 christos :function:::void:do_modsub:int rd, int rs, int rt 395 1.1.1.5 christos { 396 1.1.1.9 christos uint32_t result = 0; 397 1.1.1.9 christos uint32_t v1 = GPR[rs]; 398 1.1.1.9 christos uint32_t v2 = GPR[rt]; 399 1.1.1.9 christos uint32_t decr = v2 & 0xff; 400 1.1.1.9 christos uint32_t lastindex = (v2 & 0xffff00) >> 8; 401 1.1.1.5 christos if (v1 == 0) 402 1.1.1.5 christos result = lastindex; 403 1.1.1.5 christos else 404 1.1.1.5 christos result = v1 - decr; 405 1.1.1.5 christos GPR[rd] = EXTEND32 (result); 406 1.1.1.5 christos } 407 1.1.1.5 christos 408 1.1.1.5 christos :function:::void:do_mthlip:int rs, int ac 409 1.1.1.5 christos { 410 1.1.1.9 christos uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 411 1.1.1.5 christos DSPHI(ac) = DSPLO(ac); 412 1.1.1.5 christos DSPLO(ac) = GPR[rs]; 413 1.1.1.5 christos if (pos >= 32) 414 1.1.1.5 christos Unpredictable (); 415 1.1.1.5 christos else 416 1.1.1.5 christos pos += 32; 417 1.1.1.5 christos DSPCR &= (~DSPCR_POS_SMASK); 418 1.1.1.5 christos DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT; 419 1.1.1.5 christos } 420 1.1.1.5 christos 421 1.1.1.5 christos :function:::void:do_mulsaq_s_w_ph:int ac, int rs, int rt 422 1.1.1.5 christos { 423 1.1.1.5 christos int i; 424 1.1.1.9 christos uint32_t v1 = GPR[rs]; 425 1.1.1.9 christos uint32_t v2 = GPR[rt]; 426 1.1.1.9 christos int16_t h1, h2; 427 1.1.1.9 christos int32_t result; 428 1.1.1.9 christos uint32_t lo = DSPLO(ac); 429 1.1.1.9 christos uint32_t hi = DSPHI(ac); 430 1.1.1.9 christos int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo); 431 1.1.1.5 christos for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 432 1.1.1.5 christos { 433 1.1.1.9 christos h1 = (int16_t)(v1 & 0xffff); 434 1.1.1.9 christos h2 = (int16_t)(v2 & 0xffff); 435 1.1.1.9 christos if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000) 436 1.1.1.5 christos { 437 1.1.1.5 christos DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 438 1.1.1.9 christos result = (int32_t) 0x7fffffff; 439 1.1.1.5 christos } 440 1.1.1.5 christos else 441 1.1.1.9 christos result = ((int32_t)h1 * (int32_t)h2) << 1; 442 1.1.1.5 christos 443 1.1.1.5 christos if (i == 0) 444 1.1.1.9 christos prod -= (int64_t) result; 445 1.1.1.5 christos else 446 1.1.1.9 christos prod += (int64_t) result; 447 1.1.1.5 christos } 448 1.1.1.5 christos DSPLO(ac) = EXTEND32 (prod); 449 1.1.1.5 christos DSPHI(ac) = EXTEND32 (prod >> 32); 450 1.1.1.5 christos } 451 1.1.1.5 christos 452 1.1.1.5 christos :function:::void:do_ph_packrl:int rd, int rs, int rt 453 1.1.1.5 christos { 454 1.1.1.5 christos 455 1.1.1.9 christos uint32_t v1 = GPR[rs]; 456 1.1.1.9 christos uint32_t v2 = GPR[rt]; 457 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 << 16) + (v2 >> 16)); 458 1.1.1.5 christos } 459 1.1.1.5 christos 460 1.1.1.5 christos :function:::void:do_qb_pick:int rd, int rs, int rt 461 1.1.1.5 christos { 462 1.1.1.5 christos int i, j; 463 1.1.1.9 christos uint32_t v1 = GPR[rs]; 464 1.1.1.9 christos uint32_t v2 = GPR[rt]; 465 1.1.1.9 christos uint8_t h1, h2; 466 1.1.1.9 christos uint32_t result = 0; 467 1.1.1.5 christos for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8) 468 1.1.1.5 christos { 469 1.1.1.9 christos h1 = (uint8_t)(v1 & 0xff); 470 1.1.1.9 christos h2 = (uint8_t)(v2 & 0xff); 471 1.1.1.5 christos if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j))) 472 1.1.1.9 christos result |= (uint32_t)(h1 << i); 473 1.1.1.5 christos else 474 1.1.1.9 christos result |= (uint32_t)(h2 << i); 475 1.1.1.5 christos } 476 1.1.1.5 christos GPR[rd] = EXTEND32 (result); 477 1.1.1.5 christos } 478 1.1.1.5 christos 479 1.1.1.5 christos :function:::void:do_ph_pick:int rd, int rs, int rt 480 1.1.1.5 christos { 481 1.1.1.5 christos int i, j; 482 1.1.1.9 christos uint32_t v1 = GPR[rs]; 483 1.1.1.9 christos uint32_t v2 = GPR[rt]; 484 1.1.1.9 christos uint16_t h1, h2; 485 1.1.1.9 christos uint32_t result = 0; 486 1.1.1.5 christos for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16) 487 1.1.1.5 christos { 488 1.1.1.9 christos h1 = (uint16_t)(v1 & 0xffff); 489 1.1.1.9 christos h2 = (uint16_t)(v2 & 0xffff); 490 1.1.1.5 christos if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j))) 491 1.1.1.9 christos result |= (uint32_t)(h1 << i); 492 1.1.1.5 christos else 493 1.1.1.9 christos result |= (uint32_t)(h2 << i); 494 1.1.1.5 christos } 495 1.1.1.5 christos GPR[rd] = EXTEND32 (result); 496 1.1.1.5 christos } 497 1.1.1.5 christos 498 1.1.1.5 christos // op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA 499 1.1.1.5 christos :function:::void:do_qb_ph_precequ:int rd, int rt, int op 500 1.1.1.5 christos { 501 1.1.1.9 christos uint32_t v1 = GPR[rt]; 502 1.1.1.5 christos if (op == 0) 503 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7); 504 1.1.1.5 christos else if (op == 1) 505 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7); 506 1.1.1.5 christos else if (op == 2) 507 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9); 508 1.1.1.5 christos else if (op == 3) 509 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1); 510 1.1.1.5 christos } 511 1.1.1.5 christos 512 1.1.1.5 christos // op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA 513 1.1.1.5 christos :function:::void:do_qb_ph_preceu:int rd, int rt, int op 514 1.1.1.5 christos { 515 1.1.1.9 christos uint32_t v1 = GPR[rt]; 516 1.1.1.5 christos if (op == 0) 517 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff); 518 1.1.1.5 christos else if (op == 1) 519 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff)); 520 1.1.1.5 christos else if (op == 2) 521 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16); 522 1.1.1.5 christos else if (op == 3) 523 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8); 524 1.1.1.5 christos } 525 1.1.1.5 christos 526 1.1.1.5 christos // op: 0 = .PHL, 1 = PHR 527 1.1.1.5 christos :function:::void:do_w_preceq:int rd, int rt, int op 528 1.1.1.5 christos { 529 1.1.1.9 christos uint32_t v1 = GPR[rt]; 530 1.1.1.5 christos if (op == 0) 531 1.1.1.5 christos GPR[rd] = EXTEND32 (v1 & 0xffff0000); 532 1.1.1.5 christos else if (op == 1) 533 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 & 0xffff) << 16); 534 1.1.1.5 christos } 535 1.1.1.5 christos 536 1.1.1.5 christos :function:::void:do_w_ph_precrq:int rd, int rs, int rt 537 1.1.1.5 christos { 538 1.1.1.9 christos uint32_t v1 = GPR[rs]; 539 1.1.1.9 christos uint32_t v2 = GPR[rt]; 540 1.1.1.9 christos uint32_t tempu = (v1 & 0xffff0000) >> 16; 541 1.1.1.9 christos uint32_t tempv = (v2 & 0xffff0000) >> 16; 542 1.1.1.5 christos GPR[rd] = EXTEND32 ((tempu << 16) | tempv); 543 1.1.1.5 christos } 544 1.1.1.5 christos 545 1.1.1.5 christos // sat: 0 = PRECRQ.QB.PH, 1 = PRECRQU_S.QB.PH 546 1.1.1.5 christos :function:::void:do_ph_qb_precrq:int rd, int rs, int rt, int sat 547 1.1.1.5 christos { 548 1.1.1.9 christos uint32_t v1 = GPR[rs]; 549 1.1.1.9 christos uint32_t v2 = GPR[rt]; 550 1.1.1.9 christos uint32_t tempu = 0, tempv = 0, tempw = 0, tempx = 0; 551 1.1.1.5 christos if (sat == 0) 552 1.1.1.5 christos { 553 1.1.1.5 christos tempu = (v1 & 0xff000000) >> 24; 554 1.1.1.5 christos tempv = (v1 & 0xff00) >> 8; 555 1.1.1.5 christos tempw = (v2 & 0xff000000) >> 24; 556 1.1.1.5 christos tempx = (v2 & 0xff00) >> 8; 557 1.1.1.5 christos } 558 1.1.1.5 christos else if (sat == 1) 559 1.1.1.5 christos { 560 1.1.1.5 christos if (v1 & 0x80000000) 561 1.1.1.5 christos { 562 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG6; 563 1.1.1.5 christos tempu = 0; 564 1.1.1.5 christos } 565 1.1.1.9 christos else if (!(v1 & 0x80000000) && ((v1 >> 16) > (uint32_t)0x7f80)) 566 1.1.1.5 christos { 567 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG6; 568 1.1.1.5 christos tempu = 0xff; 569 1.1.1.5 christos } 570 1.1.1.5 christos else 571 1.1.1.5 christos tempu = (v1 & 0x7f800000) >> 23; 572 1.1.1.5 christos if (v1 & 0x8000) 573 1.1.1.5 christos { 574 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG6; 575 1.1.1.5 christos tempv = 0; 576 1.1.1.5 christos } 577 1.1.1.9 christos else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (uint32_t)0x7f80)) 578 1.1.1.5 christos { 579 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG6; 580 1.1.1.5 christos tempv = 0xff; 581 1.1.1.5 christos } 582 1.1.1.5 christos else 583 1.1.1.5 christos tempv = (v1 & 0x7f80) >> 7; 584 1.1.1.5 christos if (v2 & 0x80000000) 585 1.1.1.5 christos { 586 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG6; 587 1.1.1.5 christos tempw = 0; 588 1.1.1.5 christos } 589 1.1.1.9 christos else if (!(v2 & 0x80000000) && ((v2 >> 16) > (uint32_t)0x7f80)) 590 1.1.1.5 christos { 591 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG6; 592 1.1.1.5 christos tempw = 0xff; 593 1.1.1.5 christos } 594 1.1.1.5 christos else 595 1.1.1.5 christos tempw = (v2 & 0x7f800000) >> 23; 596 1.1.1.5 christos if (v2 & 0x8000) 597 1.1.1.5 christos { 598 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG6; 599 1.1.1.5 christos tempx = 0; 600 1.1.1.5 christos } 601 1.1.1.9 christos else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (uint32_t)0x7f80)) 602 1.1.1.5 christos { 603 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG6; 604 1.1.1.5 christos tempx = 0xff; 605 1.1.1.5 christos } 606 1.1.1.5 christos else 607 1.1.1.5 christos tempx = (v2 & 0x7f80) >> 7; 608 1.1.1.5 christos } 609 1.1.1.5 christos GPR[rd] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx); 610 1.1.1.5 christos } 611 1.1.1.5 christos 612 1.1.1.5 christos :function:::void:do_w_ph_rs_precrq:int rd, int rs, int rt 613 1.1.1.5 christos { 614 1.1.1.9 christos uint32_t v1 = GPR[rs]; 615 1.1.1.9 christos uint32_t v2 = GPR[rt]; 616 1.1.1.9 christos int32_t h1 = (int32_t)v1; 617 1.1.1.9 christos int32_t h2 = (int32_t)v2; 618 1.1.1.9 christos int64_t temp1 = (int64_t)h1 + (int64_t)0x8000; 619 1.1.1.9 christos int32_t temp2; 620 1.1.1.9 christos int64_t temp3 = (int64_t)h2 + (int64_t)0x8000; 621 1.1.1.9 christos int32_t temp4; 622 1.1.1.5 christos if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000)) 623 1.1.1.5 christos { 624 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG6; 625 1.1.1.5 christos temp2 = 0x7fff; 626 1.1.1.5 christos } 627 1.1.1.5 christos else 628 1.1.1.9 christos temp2 = (int32_t)((temp1 & 0xffff0000) >> 16); 629 1.1.1.5 christos if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000)) 630 1.1.1.5 christos { 631 1.1.1.5 christos DSPCR |= DSPCR_OUFLAG6; 632 1.1.1.5 christos temp4 = 0x7fff; 633 1.1.1.5 christos } 634 1.1.1.5 christos else 635 1.1.1.9 christos temp4 = (int32_t)((temp3 & 0xffff0000) >> 16); 636 1.1.1.5 christos GPR[rd] = EXTEND32 ((temp2 << 16) | temp4); 637 1.1.1.5 christos } 638 1.1.1.5 christos 639 1.1.1.5 christos :function:::void:do_qb_w_raddu:int rd, int rs 640 1.1.1.5 christos { 641 1.1.1.5 christos int i; 642 1.1.1.9 christos uint8_t h0; 643 1.1.1.9 christos uint32_t v1 = GPR[rs]; 644 1.1.1.9 christos uint32_t result = 0; 645 1.1.1.5 christos for (i = 0; i < 32; i += 8, v1 >>= 8) 646 1.1.1.5 christos { 647 1.1.1.9 christos h0 = (uint8_t)(v1 & 0xff); 648 1.1.1.9 christos result += (uint32_t)h0; 649 1.1.1.5 christos } 650 1.1.1.5 christos GPR[rd] = EXTEND32 (result); 651 1.1.1.5 christos } 652 1.1.1.5 christos 653 1.1.1.5 christos :function:::void:do_rddsp:int rd, int mask 654 1.1.1.5 christos { 655 1.1.1.9 christos uint32_t result = 0; 656 1.1.1.5 christos if (mask & 0x1) 657 1.1.1.5 christos { 658 1.1.1.5 christos result &= (~DSPCR_POS_SMASK); 659 1.1.1.5 christos result |= (DSPCR & DSPCR_POS_SMASK); 660 1.1.1.5 christos } 661 1.1.1.5 christos if (mask & 0x2) 662 1.1.1.5 christos { 663 1.1.1.5 christos result &= (~DSPCR_SCOUNT_SMASK); 664 1.1.1.5 christos result |= (DSPCR & DSPCR_SCOUNT_SMASK); 665 1.1.1.5 christos } 666 1.1.1.5 christos if (mask & 0x4) 667 1.1.1.5 christos { 668 1.1.1.5 christos result &= (~DSPCR_CARRY_SMASK); 669 1.1.1.5 christos result |= (DSPCR & DSPCR_CARRY_SMASK); 670 1.1.1.5 christos } 671 1.1.1.5 christos if (mask & 0x8) 672 1.1.1.5 christos { 673 1.1.1.5 christos result &= (~DSPCR_OUFLAG_SMASK); 674 1.1.1.5 christos result |= (DSPCR & DSPCR_OUFLAG_SMASK); 675 1.1.1.5 christos } 676 1.1.1.5 christos if (mask & 0x10) 677 1.1.1.5 christos { 678 1.1.1.5 christos result &= (~DSPCR_CCOND_SMASK); 679 1.1.1.5 christos result |= (DSPCR & DSPCR_CCOND_SMASK); 680 1.1.1.5 christos } 681 1.1.1.5 christos if (mask & 0x20) 682 1.1.1.5 christos { 683 1.1.1.5 christos result &= (~DSPCR_EFI_SMASK); 684 1.1.1.5 christos result |= (DSPCR & DSPCR_EFI_SMASK); 685 1.1.1.5 christos } 686 1.1.1.5 christos GPR[rd] = EXTEND32 (result); 687 1.1.1.5 christos } 688 1.1.1.5 christos 689 1.1.1.5 christos // op: 0 = REPL.QB, 1 = REPLV.QB, 2 = REPL.PH, 3 = REPLV.PH 690 1.1.1.5 christos :function:::void:do_repl:int rd, int p2, int op 691 1.1.1.5 christos { 692 1.1.1.5 christos if (op == 0) 693 1.1.1.5 christos GPR[rd] = EXTEND32 ((p2 << 24) | (p2 << 16) | (p2 << 8) | p2); 694 1.1.1.5 christos else if (op == 1) 695 1.1.1.5 christos { 696 1.1.1.9 christos uint32_t v1 = GPR[p2] & 0xff; 697 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1); 698 1.1.1.5 christos } 699 1.1.1.5 christos else if (op == 2) 700 1.1.1.5 christos { 701 1.1.1.9 christos int32_t v1 = p2; 702 1.1.1.5 christos if (v1 & 0x200) 703 1.1.1.5 christos v1 |= 0xfffffc00; 704 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 << 16) | (v1 & 0xffff)); 705 1.1.1.5 christos } 706 1.1.1.5 christos else if (op == 3) 707 1.1.1.5 christos { 708 1.1.1.9 christos uint32_t v1 = GPR[p2]; 709 1.1.1.5 christos v1 = v1 & 0xffff; 710 1.1.1.5 christos GPR[rd] = EXTEND32 ((v1 << 16) | v1); 711 1.1.1.5 christos } 712 1.1.1.5 christos } 713 1.1.1.5 christos 714 1.1.1.5 christos :function:::void:do_shilov:int ac, int rs 715 1.1.1.5 christos { 716 1.1.1.9 christos int32_t shift = GPR[rs] & 0x3f; 717 1.1.1.5 christos do_shilo (SD_, ac, shift); 718 1.1.1.5 christos } 719 1.1.1.5 christos 720 1.1.1.5 christos // op: 0 = SHLLV, 1 = SHRAV 721 1.1.1.5 christos // sat: 0 = normal, 1 = saturate/rounding 722 1.1.1.5 christos :function:::void:do_ph_shl:int rd, int rt, int rs, int op, int sat 723 1.1.1.5 christos { 724 1.1.1.9 christos uint32_t shift = GPR[rs] & 0xf; 725 1.1.1.5 christos do_ph_shift (SD_, rd, rt, shift, op, sat); 726 1.1.1.5 christos } 727 1.1.1.5 christos 728 1.1.1.5 christos // op: 0 = SHLLV, 1 = SHRLV 729 1.1.1.5 christos :function:::void:do_qb_shl:int rd, int rt, int rs, int op 730 1.1.1.5 christos { 731 1.1.1.9 christos uint32_t shift = GPR[rs] & 0x7; 732 1.1.1.5 christos do_qb_shift (SD_, rd, rt, shift, op); 733 1.1.1.5 christos } 734 1.1.1.5 christos 735 1.1.1.5 christos :function:::void:do_w_s_shllv:int rd, int rt, int rs 736 1.1.1.5 christos { 737 1.1.1.9 christos uint32_t shift = GPR[rs] & 0x1f; 738 1.1.1.5 christos do_w_shll (SD_, rd, rt, shift); 739 1.1.1.5 christos } 740 1.1.1.5 christos 741 1.1.1.5 christos :function:::void:do_ph_shrlv:int rd, int rt, int rs 742 1.1.1.5 christos { 743 1.1.1.9 christos uint32_t shift = GPR[rs] & 0xf; 744 1.1.1.5 christos do_ph_shrl (SD_, rd, rt, shift); 745 1.1.1.5 christos } 746 1.1.1.5 christos 747 1.1.1.5 christos :function:::void:do_w_r_shrav:int rd, int rt, int rs 748 1.1.1.5 christos { 749 1.1.1.9 christos uint32_t shift = GPR[rs] & 0x1f; 750 1.1.1.5 christos do_w_shra (SD_, rd, rt, shift); 751 1.1.1.5 christos } 752 1.1.1.5 christos 753 1.1.1.5 christos :function:::void:do_wrdsp:int rs, int mask 754 1.1.1.5 christos { 755 1.1.1.9 christos uint32_t v1 = GPR[rs]; 756 1.1.1.5 christos if (mask & 0x1) 757 1.1.1.5 christos { 758 1.1.1.5 christos DSPCR &= (~DSPCR_POS_SMASK); 759 1.1.1.5 christos DSPCR |= (v1 & DSPCR_POS_SMASK); 760 1.1.1.5 christos } 761 1.1.1.5 christos if (mask & 0x2) 762 1.1.1.5 christos { 763 1.1.1.5 christos DSPCR &= (~DSPCR_SCOUNT_SMASK); 764 1.1.1.5 christos DSPCR |= (v1 & DSPCR_SCOUNT_SMASK); 765 1.1.1.5 christos } 766 1.1.1.5 christos if (mask & 0x4) 767 1.1.1.5 christos { 768 1.1.1.5 christos DSPCR &= (~DSPCR_CARRY_SMASK); 769 1.1.1.5 christos DSPCR |= (v1 & DSPCR_CARRY_SMASK); 770 1.1.1.5 christos } 771 1.1.1.5 christos if (mask & 0x8) 772 1.1.1.5 christos { 773 1.1.1.5 christos DSPCR &= (~DSPCR_OUFLAG_SMASK); 774 1.1.1.5 christos DSPCR |= (v1 & DSPCR_OUFLAG_SMASK); 775 1.1.1.5 christos } 776 1.1.1.5 christos if (mask & 0x10) 777 1.1.1.5 christos { 778 1.1.1.5 christos DSPCR &= (~DSPCR_CCOND_SMASK); 779 1.1.1.5 christos DSPCR |= (v1 & DSPCR_CCOND_SMASK); 780 1.1.1.5 christos } 781 1.1.1.5 christos if (mask & 0x20) 782 1.1.1.5 christos { 783 1.1.1.5 christos DSPCR &= (~DSPCR_EFI_SMASK); 784 1.1.1.5 christos DSPCR |= (v1 & DSPCR_EFI_SMASK); 785 1.1.1.5 christos } 786 1.1.1.5 christos } 787 1.1.1.5 christos 788 1.1.1.5 christos // round: 0 = no rounding, 1 = rounding 789 1.1.1.5 christos :function:::void:do_qb_shrav:int rd, int rt, int rs, int round 790 1.1.1.5 christos { 791 1.1.1.9 christos uint32_t shift = GPR[rs] & 0x7; 792 1.1.1.5 christos do_qb_shra (SD_, rd, rt, shift, round); 793 1.1.1.5 christos } 794 1.1.1.5 christos 795 1.1.1.5 christos :function:::void:do_append:int rt, int rs, int sa 796 1.1.1.5 christos { 797 1.1.1.9 christos uint32_t v0 = GPR[rs]; 798 1.1.1.9 christos uint32_t v1 = GPR[rt]; 799 1.1.1.9 christos uint32_t result; 800 1.1.1.9 christos uint32_t mask = (1 << sa) - 1; 801 1.1.1.5 christos result = (v1 << sa) | (v0 & mask); 802 1.1.1.5 christos GPR[rt] = EXTEND32 (result); 803 1.1.1.5 christos } 804 1.1.1.5 christos 805 1.1.1.5 christos :function:::void:do_balign:int rt, int rs, int bp 806 1.1.1.5 christos { 807 1.1.1.9 christos uint32_t v0 = GPR[rs]; 808 1.1.1.9 christos uint32_t v1 = GPR[rt]; 809 1.1.1.9 christos uint32_t result; 810 1.1.1.5 christos if (bp == 0) 811 1.1.1.5 christos result = v1; 812 1.1.1.5 christos else 813 1.1.1.5 christos result = (v1 << 8 * bp) | (v0 >> 8 * (4 - bp)); 814 1.1.1.5 christos GPR[rt] = EXTEND32 (result); 815 1.1.1.5 christos } 816 1.1.1.5 christos 817 1.1.1.5 christos :function:::void:do_ph_w_mulsa:int ac, int rs, int rt 818 1.1.1.5 christos { 819 1.1.1.5 christos int i; 820 1.1.1.9 christos uint32_t v1 = GPR[rs]; 821 1.1.1.9 christos uint32_t v2 = GPR[rt]; 822 1.1.1.9 christos int16_t h1, h2; 823 1.1.1.9 christos int32_t result; 824 1.1.1.9 christos uint32_t lo = DSPLO(ac); 825 1.1.1.9 christos uint32_t hi = DSPHI(ac); 826 1.1.1.9 christos int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo); 827 1.1.1.5 christos for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 828 1.1.1.5 christos { 829 1.1.1.9 christos h1 = (int16_t)(v1 & 0xffff); 830 1.1.1.9 christos h2 = (int16_t)(v2 & 0xffff); 831 1.1.1.9 christos result = (int32_t)h1 * (int32_t)h2; 832 1.1.1.5 christos 833 1.1.1.5 christos if (i == 0) 834 1.1.1.9 christos prod -= (int64_t) result; 835 1.1.1.5 christos else 836 1.1.1.9 christos prod += (int64_t) result; 837 1.1.1.5 christos } 838 1.1.1.5 christos DSPLO(ac) = EXTEND32 (prod); 839 1.1.1.5 christos DSPHI(ac) = EXTEND32 (prod >> 32); 840 1.1.1.5 christos } 841 1.1.1.5 christos 842 1.1.1.5 christos :function:::void:do_ph_qb_precr:int rd, int rs, int rt 843 1.1.1.5 christos { 844 1.1.1.9 christos uint32_t v1 = GPR[rs]; 845 1.1.1.9 christos uint32_t v2 = GPR[rt]; 846 1.1.1.9 christos uint32_t tempu = (v1 & 0xff0000) >> 16; 847 1.1.1.9 christos uint32_t tempv = (v1 & 0xff); 848 1.1.1.9 christos uint32_t tempw = (v2 & 0xff0000) >> 16; 849 1.1.1.9 christos uint32_t tempx = (v2 & 0xff); 850 1.1.1.5 christos GPR[rd] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx); 851 1.1.1.5 christos } 852 1.1.1.5 christos 853 1.1.1.5 christos :function:::void:do_prepend:int rt, int rs, int sa 854 1.1.1.5 christos { 855 1.1.1.9 christos uint32_t v0 = GPR[rs]; 856 1.1.1.9 christos uint32_t v1 = GPR[rt]; 857 1.1.1.9 christos uint32_t result; 858 1.1.1.5 christos if (sa == 0) 859 1.1.1.5 christos result = v1; 860 1.1.1.5 christos else 861 1.1.1.5 christos result = (v0 << (32 - sa)) | (v1 >> sa); 862 1.1.1.5 christos GPR[rt] = EXTEND32 (result); 863 1.1.1.5 christos } 864 1.1.1.5 christos 865 1.1 christos :function:::void:do_w_shra:int rd, int rt, int shift 866 1.1 christos { 867 1.1.1.9 christos uint32_t result = GPR[rt]; 868 1.1.1.9 christos int32_t h0 = (int32_t)result; 869 1.1 christos if (shift != 0 && (h0 & (1 << (shift-1)))) 870 1.1 christos h0 = (h0 >> shift) + 1; 871 1.1 christos else 872 1.1 christos h0 = h0 >> shift; 873 1.1 christos GPR[rd] = EXTEND32 (h0); 874 1.1 christos } 875 1.1 christos 876 1.1 christos 011111,5.RS,5.RT,5.RD,01010,010000:SPECIAL3:32::ADDQ.PH 877 1.1 christos "addq.ph r<RD>, r<RS>, r<RT>" 878 1.1 christos *dsp: 879 1.1 christos { 880 1.1 christos do_ph_op (SD_, RD, RS, RT, 0, 0); 881 1.1 christos } 882 1.1 christos 883 1.1 christos 011111,5.RS,5.RT,5.RD,01110,010000:SPECIAL3:32::ADDQ_S.PH 884 1.1 christos "addq_s.ph r<RD>, r<RS>, r<RT>" 885 1.1 christos *dsp: 886 1.1 christos { 887 1.1 christos do_ph_op (SD_, RD, RS, RT, 0, 1); 888 1.1 christos } 889 1.1 christos 890 1.1 christos 011111,5.RS,5.RT,5.RD,10110,010000:SPECIAL3:32::ADDQ_S.W 891 1.1 christos "addq_s.w r<RD>, r<RS>, r<RT>" 892 1.1 christos *dsp: 893 1.1 christos { 894 1.1 christos do_w_op (SD_, RD, RS, RT, 0); 895 1.1 christos } 896 1.1 christos 897 1.1 christos 011111,5.RS,5.RT,5.RD,00000,010000:SPECIAL3:32::ADDU.QB 898 1.1 christos "addu.qb r<RD>, r<RS>, r<RT>" 899 1.1 christos *dsp: 900 1.1 christos { 901 1.1 christos do_qb_op (SD_, RD, RS, RT, 0, 0); 902 1.1 christos } 903 1.1 christos 904 1.1 christos 011111,5.RS,5.RT,5.RD,00100,010000:SPECIAL3:32::ADDU_S.QB 905 1.1 christos "addu_s.qb r<RD>, r<RS>, r<RT>" 906 1.1 christos *dsp: 907 1.1 christos { 908 1.1 christos do_qb_op (SD_, RD, RS, RT, 0, 1); 909 1.1 christos } 910 1.1 christos 911 1.1 christos 011111,5.RS,5.RT,5.RD,01011,010000:SPECIAL3:32::SUBQ.PH 912 1.1 christos "subq.ph r<RD>, r<RS>, r<RT>" 913 1.1 christos *dsp: 914 1.1 christos { 915 1.1 christos do_ph_op (SD_, RD, RS, RT, 1, 0); 916 1.1 christos } 917 1.1 christos 918 1.1 christos 011111,5.RS,5.RT,5.RD,01111,010000:SPECIAL3:32::SUBQ_S.PH 919 1.1 christos "subq_s.ph r<RD>, r<RS>, r<RT>" 920 1.1 christos *dsp: 921 1.1 christos { 922 1.1 christos do_ph_op (SD_, RD, RS, RT, 1, 1); 923 1.1 christos } 924 1.1 christos 925 1.1 christos 011111,5.RS,5.RT,5.RD,10111,010000:SPECIAL3:32::SUBQ_S.W 926 1.1 christos "subq_s.w r<RD>, r<RS>, r<RT>" 927 1.1 christos *dsp: 928 1.1 christos { 929 1.1 christos do_w_op (SD_, RD, RS, RT, 1); 930 1.1 christos } 931 1.1 christos 932 1.1 christos 011111,5.RS,5.RT,5.RD,00001,010000:SPECIAL3:32::SUBU.QB 933 1.1 christos "subu.qb r<RD>, r<RS>, r<RT>" 934 1.1 christos *dsp: 935 1.1 christos { 936 1.1 christos do_qb_op (SD_, RD, RS, RT, 1, 0); 937 1.1 christos } 938 1.1 christos 939 1.1 christos 011111,5.RS,5.RT,5.RD,00101,010000:SPECIAL3:32::SUBU_S.QB 940 1.1 christos "subu_s.qb r<RD>, r<RS>, r<RT>" 941 1.1 christos *dsp: 942 1.1 christos { 943 1.1 christos do_qb_op (SD_, RD, RS, RT, 1, 1); 944 1.1 christos } 945 1.1 christos 946 1.1 christos 011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC 947 1.1 christos "addsc r<RD>, r<RS>, r<RT>" 948 1.1 christos *dsp: 949 1.1 christos { 950 1.1.1.5 christos do_addsc (SD_, RD, RS, RT); 951 1.1 christos } 952 1.1 christos 953 1.1 christos 011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC 954 1.1 christos "addwc r<RD>, r<RS>, r<RT>" 955 1.1 christos *dsp: 956 1.1 christos { 957 1.1.1.5 christos do_addwc (SD_, RD, RS, RT); 958 1.1 christos } 959 1.1 christos 960 1.1 christos 011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB 961 1.1 christos "modsub r<RD>, r<RS>, r<RT>" 962 1.1 christos *dsp: 963 1.1 christos { 964 1.1.1.5 christos do_modsub (SD_, RD, RS, RT); 965 1.1 christos } 966 1.1 christos 967 1.1 christos 011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB 968 1.1 christos "raddu.w.qb r<RD>, r<RS>" 969 1.1 christos *dsp: 970 1.1 christos { 971 1.1.1.5 christos do_qb_w_raddu (SD_, RD, RS); 972 1.1 christos } 973 1.1 christos 974 1.1 christos 011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH 975 1.1 christos "absq_s.ph r<RD>, r<RT>" 976 1.1 christos *dsp: 977 1.1 christos { 978 1.1.1.5 christos do_ph_s_absq (SD_, RD, RT); 979 1.1 christos } 980 1.1 christos 981 1.1 christos 011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W 982 1.1 christos "absq_s.w r<RD>, r<RT>" 983 1.1 christos *dsp: 984 1.1 christos { 985 1.1.1.5 christos do_w_s_absq (SD_, RD, RT); 986 1.1 christos } 987 1.1 christos 988 1.1 christos 011111,5.RS,5.RT,5.RD,01100,010001:SPECIAL3:32::PRECRQ.QB.PH 989 1.1 christos "precrq.qb.ph r<RD>, r<RS>, r<RT>" 990 1.1 christos *dsp: 991 1.1 christos { 992 1.1.1.5 christos do_ph_qb_precrq (SD_, RD, RS, RT, 0); 993 1.1 christos } 994 1.1 christos 995 1.1 christos 011111,5.RS,5.RT,5.RD,10100,010001:SPECIAL3:32::PRECRQ.PH.W 996 1.1 christos "precrq.ph.w r<RD>, r<RS>, r<RT>" 997 1.1 christos *dsp: 998 1.1 christos { 999 1.1.1.5 christos do_w_ph_precrq (SD_, RD, RS, RT); 1000 1.1 christos } 1001 1.1 christos 1002 1.1 christos 011111,5.RS,5.RT,5.RD,10101,010001:SPECIAL3:32::PRECRQ_RS.PH.W 1003 1.1 christos "precrq_rs.ph.w r<RD>, r<RS>, r<RT>" 1004 1.1 christos *dsp: 1005 1.1 christos { 1006 1.1.1.5 christos do_w_ph_rs_precrq (SD_, RD, RS, RT); 1007 1.1 christos } 1008 1.1 christos 1009 1.1 christos 011111,5.RS,5.RT,5.RD,01111,010001:SPECIAL3:32::PRECRQU_S.QB.PH 1010 1.1 christos "precrqu_s.qb.ph r<RD>, r<RS>, r<RT>" 1011 1.1 christos *dsp: 1012 1.1 christos { 1013 1.1.1.5 christos do_ph_qb_precrq (SD_, RD, RS, RT, 1); 1014 1.1 christos } 1015 1.1 christos 1016 1.1 christos 011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL 1017 1.1 christos "preceq.w.phl r<RD>, r<RT>" 1018 1.1 christos *dsp: 1019 1.1 christos { 1020 1.1.1.5 christos do_w_preceq (SD_, RD, RT, 0); 1021 1.1 christos } 1022 1.1 christos 1023 1.1 christos 011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR 1024 1.1 christos "preceq.w.phr r<RD>, r<RT>" 1025 1.1 christos *dsp: 1026 1.1 christos { 1027 1.1.1.5 christos do_w_preceq (SD_, RD, RT, 1); 1028 1.1 christos } 1029 1.1 christos 1030 1.1 christos 011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL 1031 1.1 christos "precequ.ph.qbl r<RD>, r<RT>" 1032 1.1 christos *dsp: 1033 1.1 christos { 1034 1.1.1.5 christos do_qb_ph_precequ (SD_, RD, RT, 2); 1035 1.1 christos } 1036 1.1 christos 1037 1.1 christos 011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR 1038 1.1 christos "precequ.ph.qbr r<RD>, r<RT>" 1039 1.1 christos *dsp: 1040 1.1 christos { 1041 1.1.1.5 christos do_qb_ph_precequ (SD_, RD, RT, 0); 1042 1.1 christos } 1043 1.1 christos 1044 1.1 christos 011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA 1045 1.1 christos "precequ.ph.qbla r<RD>, r<RT>" 1046 1.1 christos *dsp: 1047 1.1 christos { 1048 1.1.1.5 christos do_qb_ph_precequ (SD_, RD, RT, 3); 1049 1.1 christos } 1050 1.1 christos 1051 1.1 christos 011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA 1052 1.1 christos "precequ.ph.qbra r<RD>, r<RT>" 1053 1.1 christos *dsp: 1054 1.1 christos { 1055 1.1.1.5 christos do_qb_ph_precequ (SD_, RD, RT, 1); 1056 1.1 christos } 1057 1.1 christos 1058 1.1 christos 011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL 1059 1.1 christos "preceu.ph.qbl r<RD>, r<RT>" 1060 1.1 christos *dsp: 1061 1.1 christos { 1062 1.1.1.5 christos do_qb_ph_preceu (SD_, RD, RT, 2); 1063 1.1 christos } 1064 1.1 christos 1065 1.1 christos 011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR 1066 1.1 christos "preceu.ph.qbr r<RD>, r<RT>" 1067 1.1 christos *dsp: 1068 1.1 christos { 1069 1.1.1.5 christos do_qb_ph_preceu (SD_, RD, RT, 0); 1070 1.1 christos } 1071 1.1 christos 1072 1.1 christos 011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA 1073 1.1 christos "preceu.ph.qbla r<RD>, r<RT>" 1074 1.1 christos *dsp: 1075 1.1 christos { 1076 1.1.1.5 christos do_qb_ph_preceu (SD_, RD, RT, 3); 1077 1.1 christos } 1078 1.1 christos 1079 1.1 christos 011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA 1080 1.1 christos "preceu.ph.qbra r<RD>, r<RT>" 1081 1.1 christos *dsp: 1082 1.1 christos { 1083 1.1.1.5 christos do_qb_ph_preceu (SD_, RD, RT, 1); 1084 1.1 christos } 1085 1.1 christos 1086 1.1 christos 011111,00,3.SHIFT3,5.RT,5.RD,00000,010011:SPECIAL3:32::SHLL.QB 1087 1.1 christos "shll.qb r<RD>, r<RT>, <SHIFT3>" 1088 1.1 christos *dsp: 1089 1.1 christos { 1090 1.1 christos do_qb_shift (SD_, RD, RT, SHIFT3, 0); 1091 1.1 christos } 1092 1.1 christos 1093 1.1 christos 011111,5.RS,5.RT,5.RD,00010,010011:SPECIAL3:32::SHLLV.QB 1094 1.1 christos "shllv.qb r<RD>, r<RT>, r<RS>" 1095 1.1 christos *dsp: 1096 1.1 christos { 1097 1.1.1.5 christos do_qb_shl (SD_, RD, RT, RS, 0); 1098 1.1 christos } 1099 1.1 christos 1100 1.1 christos 011111,0,4.SHIFT4,5.RT,5.RD,01000,010011:SPECIAL3:32::SHLL.PH 1101 1.1 christos "shll.ph r<RD>, r<RT>, <SHIFT4>" 1102 1.1 christos *dsp: 1103 1.1 christos { 1104 1.1 christos do_ph_shift (SD_, RD, RT, SHIFT4, 0, 0); 1105 1.1 christos } 1106 1.1 christos 1107 1.1 christos 011111,5.RS,5.RT,5.RD,01010,010011:SPECIAL3:32::SHLLV.PH 1108 1.1 christos "shllv.ph r<RD>, r<RT>, r<RS>" 1109 1.1 christos *dsp: 1110 1.1 christos { 1111 1.1.1.5 christos do_ph_shl (SD_, RD, RT, RS, 0, 0); 1112 1.1 christos } 1113 1.1 christos 1114 1.1 christos 011111,0,4.SHIFT4,5.RT,5.RD,01100,010011:SPECIAL3:32::SHLL_S.PH 1115 1.1 christos "shll_s.ph r<RD>, r<RT>, <SHIFT4>" 1116 1.1 christos *dsp: 1117 1.1 christos { 1118 1.1 christos do_ph_shift (SD_, RD, RT, SHIFT4, 0, 1); 1119 1.1 christos } 1120 1.1 christos 1121 1.1 christos 011111,5.RS,5.RT,5.RD,01110,010011:SPECIAL3:32::SHLLV_S.PH 1122 1.1 christos "shllv_s.ph r<RD>, r<RT>, r<RS>" 1123 1.1 christos *dsp: 1124 1.1 christos { 1125 1.1.1.5 christos do_ph_shl (SD_, RD, RT, RS, 0, 1); 1126 1.1 christos } 1127 1.1 christos 1128 1.1 christos 011111,5.SHIFT5,5.RT,5.RD,10100,010011:SPECIAL3:32::SHLL_S.W 1129 1.1 christos "shll_s.w r<RD>, r<RT>, <SHIFT5>" 1130 1.1 christos *dsp: 1131 1.1 christos { 1132 1.1 christos do_w_shll (SD_, RD, RT, SHIFT5); 1133 1.1 christos } 1134 1.1 christos 1135 1.1 christos 011111,5.RS,5.RT,5.RD,10110,010011:SPECIAL3:32::SHLLV_S.W 1136 1.1 christos "shllv_s.w r<RD>, r<RT>, r<RS>" 1137 1.1 christos *dsp: 1138 1.1 christos { 1139 1.1.1.5 christos do_w_s_shllv (SD_, RD, RT, RS); 1140 1.1 christos } 1141 1.1 christos 1142 1.1 christos 011111,00,3.SHIFT3,5.RT,5.RD,00001,010011:SPECIAL3:32::SHRL.QB 1143 1.1 christos "shrl.qb r<RD>, r<RT>, <SHIFT3>" 1144 1.1 christos *dsp: 1145 1.1 christos { 1146 1.1 christos do_qb_shift (SD_, RD, RT, SHIFT3, 1); 1147 1.1 christos } 1148 1.1 christos 1149 1.1 christos 011111,5.RS,5.RT,5.RD,00011,010011:SPECIAL3:32::SHRLV.QB 1150 1.1 christos "shrlv.qb r<RD>, r<RT>, r<RS>" 1151 1.1 christos *dsp: 1152 1.1 christos { 1153 1.1.1.5 christos do_qb_shl (SD_, RD, RT, RS, 1); 1154 1.1 christos } 1155 1.1 christos 1156 1.1 christos 011111,0,4.SHIFT4,5.RT,5.RD,01001,010011:SPECIAL3:32::SHRA.PH 1157 1.1 christos "shra.ph r<RD>, r<RT>, <SHIFT4>" 1158 1.1 christos *dsp: 1159 1.1 christos { 1160 1.1 christos do_ph_shift (SD_, RD, RT, SHIFT4, 1, 0); 1161 1.1 christos } 1162 1.1 christos 1163 1.1 christos 011111,5.RS,5.RT,5.RD,01011,010011:SPECIAL3:32::SHRAV.PH 1164 1.1 christos "shrav.ph r<RD>, r<RT>, r<RS>" 1165 1.1 christos *dsp: 1166 1.1 christos { 1167 1.1.1.5 christos do_ph_shl (SD_, RD, RT, RS, 1, 0); 1168 1.1 christos } 1169 1.1 christos 1170 1.1 christos 011111,0,4.SHIFT4,5.RT,5.RD,01101,010011:SPECIAL3:32::SHRA_R.PH 1171 1.1 christos "shra_r.ph r<RD>, r<RT>, <SHIFT4>" 1172 1.1 christos *dsp: 1173 1.1 christos { 1174 1.1 christos do_ph_shift (SD_, RD, RT, SHIFT4, 1, 1); 1175 1.1 christos } 1176 1.1 christos 1177 1.1 christos 011111,5.RS,5.RT,5.RD,01111,010011:SPECIAL3:32::SHRAV_R.PH 1178 1.1 christos "shrav_r.ph r<RD>, r<RT>, r<RS>" 1179 1.1 christos *dsp: 1180 1.1 christos { 1181 1.1.1.5 christos do_ph_shl (SD_, RD, RT, RS, 1, 1); 1182 1.1 christos } 1183 1.1 christos 1184 1.1 christos 011111,5.SHIFT5,5.RT,5.RD,10101,010011:SPECIAL3:32::SHRA_R.W 1185 1.1 christos "shra_r.w r<RD>, r<RT>, <SHIFT5>" 1186 1.1 christos *dsp: 1187 1.1 christos { 1188 1.1 christos do_w_shra (SD_, RD, RT, SHIFT5); 1189 1.1 christos } 1190 1.1 christos 1191 1.1 christos 011111,5.RS,5.RT,5.RD,10111,010011:SPECIAL3:32::SHRAV_R.W 1192 1.1 christos "shrav_r.w r<RD>, r<RT>, r<RS>" 1193 1.1 christos *dsp: 1194 1.1 christos { 1195 1.1.1.5 christos do_w_r_shrav (SD_, RD, RT, RS); 1196 1.1 christos } 1197 1.1 christos 1198 1.1 christos // loc: 0 = qhl, 1 = qhr 1199 1.1 christos :function:::void:do_qb_muleu:int rd, int rs, int rt, int loc 1200 1.1 christos { 1201 1.1 christos int i; 1202 1.1.1.9 christos uint32_t result = 0; 1203 1.1.1.9 christos uint32_t v1 = GPR[rs]; 1204 1.1.1.9 christos uint32_t v2 = GPR[rt]; 1205 1.1.1.9 christos uint16_t h1, h2; 1206 1.1.1.9 christos uint32_t prod; 1207 1.1 christos if (loc == 0) 1208 1.1 christos v1 >>= 16; 1209 1.1 christos for (i = 0; i < 32; i += 16, v1 >>= 8, v2 >>= 16) 1210 1.1 christos { 1211 1.1.1.9 christos h1 = (uint16_t)(v1 & 0xff); 1212 1.1.1.9 christos h2 = (uint16_t)(v2 & 0xffff); 1213 1.1.1.9 christos prod = (uint32_t)h1 * (uint32_t)h2; 1214 1.1 christos if (prod > 0xffff) 1215 1.1 christos { 1216 1.1 christos DSPCR |= DSPCR_OUFLAG5; 1217 1.1 christos prod = 0xffff; 1218 1.1 christos } 1219 1.1.1.9 christos result |= ((uint32_t)prod << i); 1220 1.1 christos } 1221 1.1 christos GPR[rd] = EXTEND32 (result); 1222 1.1 christos } 1223 1.1 christos 1224 1.1 christos 011111,5.RS,5.RT,5.RD,00110,010000:SPECIAL3:32::MULEU_S.PH.QBL 1225 1.1 christos "muleu_s.ph.qbl r<RD>, r<RS>, r<RT>" 1226 1.1 christos *dsp: 1227 1.1 christos { 1228 1.1 christos do_qb_muleu (SD_, RD, RS, RT, 0); 1229 1.1 christos } 1230 1.1 christos 1231 1.1 christos 011111,5.RS,5.RT,5.RD,00111,010000:SPECIAL3:32::MULEU_S.PH.QBR 1232 1.1 christos "muleu_s.ph.qbr r<RD>, r<RS>, r<RT>" 1233 1.1 christos *dsp: 1234 1.1 christos { 1235 1.1 christos do_qb_muleu (SD_, RD, RS, RT, 1); 1236 1.1 christos } 1237 1.1 christos 1238 1.1 christos // round: 0 = no rounding, 1 = rounding 1239 1.1 christos :function:::void:do_ph_mulq:int rd, int rs, int rt, int round 1240 1.1 christos { 1241 1.1 christos int i; 1242 1.1.1.9 christos uint32_t result = 0; 1243 1.1.1.9 christos uint32_t v1 = GPR[rs]; 1244 1.1.1.9 christos uint32_t v2 = GPR[rt]; 1245 1.1.1.9 christos int16_t h1, h2; 1246 1.1.1.9 christos int32_t prod; 1247 1.1 christos for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 1248 1.1 christos { 1249 1.1.1.9 christos h1 = (int16_t)(v1 & 0xffff); 1250 1.1.1.9 christos h2 = (int16_t)(v2 & 0xffff); 1251 1.1.1.9 christos if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000) 1252 1.1 christos { 1253 1.1 christos DSPCR |= DSPCR_OUFLAG5; 1254 1.1 christos prod = 0x7fffffff; 1255 1.1 christos } 1256 1.1 christos else 1257 1.1 christos { 1258 1.1.1.9 christos prod = ((int32_t)h1 * (int32_t)h2) << 1; 1259 1.1 christos if (round == 1) 1260 1.1.1.9 christos prod += (int32_t)0x8000; 1261 1.1 christos } 1262 1.1.1.9 christos result |= (((uint32_t)prod >> 16) << i); 1263 1.1 christos } 1264 1.1 christos GPR[rd] = EXTEND32 (result); 1265 1.1 christos } 1266 1.1 christos 1267 1.1 christos 011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH 1268 1.1 christos "mulq_rs.ph r<RD>, r<RS>, r<RT>" 1269 1.1 christos *dsp: 1270 1.1 christos { 1271 1.1 christos do_ph_mulq (SD_, RD, RS, RT, 1); 1272 1.1 christos } 1273 1.1 christos 1274 1.1 christos // loc: 0 = phl, 1 = phr 1275 1.1 christos :function:::void:do_ph_muleq:int rd, int rs, int rt, int loc 1276 1.1 christos { 1277 1.1.1.9 christos uint32_t v1 = GPR[rs]; 1278 1.1.1.9 christos uint32_t v2 = GPR[rt]; 1279 1.1.1.9 christos int16_t h1, h2; 1280 1.1.1.9 christos int32_t prod; 1281 1.1 christos if (loc == 0) 1282 1.1 christos { 1283 1.1.1.9 christos h1 = (int16_t)(v1 >> 16); 1284 1.1.1.9 christos h2 = (int16_t)(v2 >> 16); 1285 1.1 christos } 1286 1.1 christos else 1287 1.1 christos { 1288 1.1.1.9 christos h1 = (int16_t)(v1 & 0xffff); 1289 1.1.1.9 christos h2 = (int16_t)(v2 & 0xffff); 1290 1.1 christos } 1291 1.1.1.9 christos if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000) 1292 1.1 christos { 1293 1.1 christos DSPCR |= DSPCR_OUFLAG5; 1294 1.1 christos prod = 0x7fffffff; 1295 1.1 christos } 1296 1.1 christos else 1297 1.1.1.9 christos prod = ((int32_t)h1 * (int32_t)h2) << 1; 1298 1.1 christos GPR[rd] = EXTEND32 (prod); 1299 1.1 christos } 1300 1.1 christos 1301 1.1 christos 011111,5.RS,5.RT,5.RD,11100,010000:SPECIAL3:32::MULEQ_S.W.PHL 1302 1.1 christos "muleq_s.w.phl r<RD>, r<RS>, r<RT>" 1303 1.1 christos *dsp: 1304 1.1 christos { 1305 1.1 christos do_ph_muleq (SD_, RD, RS, RT, 0); 1306 1.1 christos } 1307 1.1 christos 1308 1.1 christos 011111,5.RS,5.RT,5.RD,11101,010000:SPECIAL3:32::MULEQ_S.W.PHR 1309 1.1 christos "muleq_s.w.phr r<RD>, r<RS>, r<RT>" 1310 1.1 christos *dsp: 1311 1.1 christos { 1312 1.1 christos do_ph_muleq (SD_, RD, RS, RT, 1); 1313 1.1 christos } 1314 1.1 christos 1315 1.1 christos // op: 0 = DPAU 1 = DPSU 1316 1.1 christos // loc: 0 = qbl, 1 = qbr 1317 1.1 christos :function:::void:do_qb_dot_product:int ac, int rs, int rt, int op, int loc 1318 1.1 christos { 1319 1.1 christos int i; 1320 1.1.1.9 christos uint32_t v1 = GPR[rs]; 1321 1.1.1.9 christos uint32_t v2 = GPR[rt]; 1322 1.1.1.9 christos uint8_t h1, h2; 1323 1.1.1.9 christos uint32_t lo = DSPLO(ac); 1324 1.1.1.9 christos uint32_t hi = DSPHI(ac); 1325 1.1.1.9 christos uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo; 1326 1.1 christos if (loc == 0) 1327 1.1 christos { 1328 1.1 christos v1 >>= 16; 1329 1.1 christos v2 >>= 16; 1330 1.1 christos } 1331 1.1 christos for (i = 0; i < 16; i += 8, v1 >>= 8, v2 >>= 8) 1332 1.1 christos { 1333 1.1.1.9 christos h1 = (uint8_t)(v1 & 0xff); 1334 1.1.1.9 christos h2 = (uint8_t)(v2 & 0xff); 1335 1.1 christos if (op == 0) // DPAU 1336 1.1.1.9 christos prod += (uint64_t)h1 * (uint64_t)h2; 1337 1.1 christos else // DPSU 1338 1.1.1.9 christos prod -= (uint64_t)h1 * (uint64_t)h2; 1339 1.1 christos } 1340 1.1 christos DSPLO(ac) = EXTEND32 (prod); 1341 1.1 christos DSPHI(ac) = EXTEND32 (prod >> 32); 1342 1.1 christos } 1343 1.1 christos 1344 1.1 christos 011111,5.RS,5.RT,000,2.AC,00011,110000:SPECIAL3:32::DPAU.H.QBL 1345 1.1 christos "dpau.h.qbl ac<AC>, r<RS>, r<RT>" 1346 1.1 christos *dsp: 1347 1.1 christos { 1348 1.1 christos do_qb_dot_product (SD_, AC, RS, RT, 0, 0); 1349 1.1 christos } 1350 1.1 christos 1351 1.1 christos 011111,5.RS,5.RT,000,2.AC,00111,110000:SPECIAL3:32::DPAU.H.QBR 1352 1.1 christos "dpau.h.qbr ac<AC>, r<RS>, r<RT>" 1353 1.1 christos *dsp: 1354 1.1 christos { 1355 1.1 christos do_qb_dot_product (SD_, AC, RS, RT, 0, 1); 1356 1.1 christos } 1357 1.1 christos 1358 1.1 christos 011111,5.RS,5.RT,000,2.AC,01011,110000:SPECIAL3:32::DPSU.H.QBL 1359 1.1 christos "dpsu.h.qbl ac<AC>, r<RS>, r<RT>" 1360 1.1 christos *dsp: 1361 1.1 christos { 1362 1.1 christos do_qb_dot_product (SD_, AC, RS, RT, 1, 0); 1363 1.1 christos } 1364 1.1 christos 1365 1.1 christos 011111,5.RS,5.RT,000,2.AC,01111,110000:SPECIAL3:32::DPSU.H.QBR 1366 1.1 christos "dpsu.h.qbr ac<AC>, r<RS>, r<RT>" 1367 1.1 christos *dsp: 1368 1.1 christos { 1369 1.1 christos do_qb_dot_product (SD_, AC, RS, RT, 1, 1); 1370 1.1 christos } 1371 1.1 christos 1372 1.1 christos // op: 0 = DPAQ 1 = DPSQ 1373 1.1 christos :function:::void:do_ph_dot_product:int ac, int rs, int rt, int op 1374 1.1 christos { 1375 1.1 christos int i; 1376 1.1.1.9 christos uint32_t v1 = GPR[rs]; 1377 1.1.1.9 christos uint32_t v2 = GPR[rt]; 1378 1.1.1.9 christos int16_t h1, h2; 1379 1.1.1.9 christos int32_t result; 1380 1.1.1.9 christos uint32_t lo = DSPLO(ac); 1381 1.1.1.9 christos uint32_t hi = DSPHI(ac); 1382 1.1.1.9 christos int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo); 1383 1.1 christos for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 1384 1.1 christos { 1385 1.1.1.9 christos h1 = (int16_t)(v1 & 0xffff); 1386 1.1.1.9 christos h2 = (int16_t)(v2 & 0xffff); 1387 1.1.1.9 christos if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000) 1388 1.1 christos { 1389 1.1 christos DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1390 1.1.1.9 christos result = (int32_t)0x7fffffff; 1391 1.1 christos } 1392 1.1 christos else 1393 1.1.1.9 christos result = ((int32_t)h1 * (int32_t)h2) << 1; 1394 1.1 christos 1395 1.1 christos if (op == 0) // DPAQ 1396 1.1.1.9 christos prod += (int64_t)result; 1397 1.1 christos else // DPSQ 1398 1.1.1.9 christos prod -= (int64_t)result; 1399 1.1 christos } 1400 1.1 christos DSPLO(ac) = EXTEND32 (prod); 1401 1.1 christos DSPHI(ac) = EXTEND32 (prod >> 32); 1402 1.1 christos } 1403 1.1 christos 1404 1.1 christos 011111,5.RS,5.RT,000,2.AC,00100,110000:SPECIAL3:32::DPAQ_S.W.PH 1405 1.1 christos "dpaq_s.w.ph ac<AC>, r<RS>, r<RT>" 1406 1.1 christos *dsp: 1407 1.1 christos { 1408 1.1 christos do_ph_dot_product (SD_, AC, RS, RT, 0); 1409 1.1 christos } 1410 1.1 christos 1411 1.1 christos 011111,5.RS,5.RT,000,2.AC,00101,110000:SPECIAL3:32::DPSQ_S.W.PH 1412 1.1 christos "dpsq_s.w.ph ac<AC>, r<RS>, r<RT>" 1413 1.1 christos *dsp: 1414 1.1 christos { 1415 1.1 christos do_ph_dot_product (SD_, AC, RS, RT, 1); 1416 1.1 christos } 1417 1.1 christos 1418 1.1 christos 011111,5.RS,5.RT,000,2.AC,00110,110000:SPECIAL3:32::MULSAQ_S.W.PH 1419 1.1 christos "mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>" 1420 1.1 christos *dsp: 1421 1.1 christos { 1422 1.1.1.5 christos do_mulsaq_s_w_ph (SD_, AC, RS, RT); 1423 1.1 christos } 1424 1.1 christos 1425 1.1 christos // op: 0 = DPAQ 1 = DPSQ 1426 1.1 christos :function:::void:do_w_dot_product:int ac, int rs, int rt, int op 1427 1.1 christos { 1428 1.1.1.9 christos uint32_t v1 = GPR[rs]; 1429 1.1.1.9 christos uint32_t v2 = GPR[rt]; 1430 1.1.1.9 christos int32_t h1, h2; 1431 1.1.1.9 christos int64_t result; 1432 1.1.1.9 christos uint32_t lo = DSPLO(ac); 1433 1.1.1.9 christos uint32_t hi = DSPHI(ac); 1434 1.1.1.9 christos uint32_t resultlo; 1435 1.1.1.9 christos uint32_t resulthi; 1436 1.1.1.9 christos uint32_t carry; 1437 1.1.1.9 christos uint64_t temp1; 1438 1.1.1.9 christos int64_t temp2; 1439 1.1.1.9 christos h1 = (int32_t) v1; 1440 1.1.1.9 christos h2 = (int32_t) v2; 1441 1.1 christos if (h1 == 0x80000000 && h2 == 0x80000000) 1442 1.1 christos { 1443 1.1 christos DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1444 1.1.1.9 christos result = (int64_t) 0x7fffffffffffffffLL; 1445 1.1 christos } 1446 1.1 christos else 1447 1.1.1.9 christos result = ((int64_t)h1 * (int64_t)h2) << 1; 1448 1.1.1.9 christos resultlo = (uint32_t)(result); 1449 1.1.1.9 christos resulthi = (uint32_t)(result >> 32); 1450 1.1 christos if (op ==0) // DPAQ 1451 1.1 christos { 1452 1.1.1.9 christos temp1 = (uint64_t)lo + (uint64_t)resultlo; 1453 1.1.1.9 christos carry = (uint32_t)((temp1 >> 32) & 1); 1454 1.1.1.9 christos temp2 = (int64_t)((int32_t)hi) + (int64_t)((int32_t)resulthi) + 1455 1.1.1.9 christos (int64_t)((int32_t)carry); 1456 1.1 christos } 1457 1.1 christos else // DPSQ 1458 1.1 christos { 1459 1.1.1.9 christos temp1 = (uint64_t)lo - (uint64_t)resultlo; 1460 1.1.1.9 christos carry = (uint32_t)((temp1 >> 32) & 1); 1461 1.1.1.9 christos temp2 = (int64_t)((int32_t)hi) - (int64_t)((int32_t)resulthi) - 1462 1.1.1.9 christos (int64_t)((int32_t)carry); 1463 1.1 christos } 1464 1.1 christos if (((temp2 & 0x100000000LL) >> 1) != (temp2 & 0x80000000LL)) 1465 1.1 christos { 1466 1.1 christos DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1467 1.1 christos if (temp2 & 0x100000000LL) 1468 1.1 christos { 1469 1.1 christos DSPLO(ac) = EXTEND32 (0x00000000); 1470 1.1 christos DSPHI(ac) = EXTEND32 (0x80000000); 1471 1.1 christos } 1472 1.1 christos else 1473 1.1 christos { 1474 1.1 christos DSPLO(ac) = EXTEND32 (0xffffffff); 1475 1.1 christos DSPHI(ac) = EXTEND32 (0x7fffffff); 1476 1.1 christos } 1477 1.1 christos } 1478 1.1 christos else 1479 1.1 christos { 1480 1.1 christos DSPLO(ac) = EXTEND32 (temp1); 1481 1.1 christos DSPHI(ac) = EXTEND32 (temp2); 1482 1.1 christos } 1483 1.1 christos } 1484 1.1 christos 1485 1.1 christos 011111,5.RS,5.RT,000,2.AC,01100,110000:SPECIAL3:32::DPAQ_SA.L.W 1486 1.1 christos "dpaq_sa.l.w ac<AC>, r<RS>, r<RT>" 1487 1.1 christos *dsp: 1488 1.1 christos { 1489 1.1 christos do_w_dot_product (SD_, AC, RS, RT, 0); 1490 1.1 christos } 1491 1.1 christos 1492 1.1 christos 011111,5.RS,5.RT,000,2.AC,01101,110000:SPECIAL3:32::DPSQ_SA.L.W 1493 1.1 christos "dpsq_sa.l.w ac<AC>, r<RS>, r<RT>" 1494 1.1 christos *dsp: 1495 1.1 christos { 1496 1.1 christos do_w_dot_product (SD_, AC, RS, RT, 1); 1497 1.1 christos } 1498 1.1 christos 1499 1.1 christos // op: 0 = MAQ_S 1 = MAQ_SA 1500 1.1 christos // loc: 0 = phl, 1 = phr 1501 1.1 christos :function:::void:do_ph_maq:int ac, int rs, int rt, int op, int loc 1502 1.1 christos { 1503 1.1 christos int i; 1504 1.1.1.9 christos uint32_t v1 = GPR[rs]; 1505 1.1.1.9 christos uint32_t v2 = GPR[rt]; 1506 1.1.1.9 christos int16_t h1, h2; 1507 1.1.1.9 christos int32_t result; 1508 1.1.1.9 christos uint32_t lo = DSPLO(ac); 1509 1.1.1.9 christos uint32_t hi = DSPHI(ac); 1510 1.1.1.9 christos int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo); 1511 1.1 christos if (loc == 0) 1512 1.1 christos { 1513 1.1.1.9 christos h1 = (int16_t)(v1 >> 16); 1514 1.1.1.9 christos h2 = (int16_t)(v2 >> 16); 1515 1.1 christos } 1516 1.1 christos else 1517 1.1 christos { 1518 1.1.1.9 christos h1 = (int16_t)(v1 & 0xffff); 1519 1.1.1.9 christos h2 = (int16_t)(v2 & 0xffff); 1520 1.1 christos } 1521 1.1.1.9 christos if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000) 1522 1.1 christos { 1523 1.1 christos DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1524 1.1.1.9 christos result = (int32_t)0x7fffffff; 1525 1.1 christos } 1526 1.1 christos else 1527 1.1.1.9 christos result = ((int32_t)h1 * (int32_t)h2) << 1; 1528 1.1.1.9 christos prod += (int64_t)result; 1529 1.1 christos if (op == 1) // MAQ_SA 1530 1.1 christos { 1531 1.1 christos if (prod & 0x8000000000000000LL) 1532 1.1 christos { 1533 1.1 christos for (i = 62; i >= 31; i--) 1534 1.1 christos { 1535 1.1.1.9 christos if (!(prod & ((int64_t)1 << i))) 1536 1.1 christos { 1537 1.1 christos DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1538 1.1 christos prod = 0xffffffff80000000LL; 1539 1.1 christos break; 1540 1.1 christos } 1541 1.1 christos } 1542 1.1 christos } 1543 1.1 christos else 1544 1.1 christos { 1545 1.1 christos for (i = 62; i >= 31; i--) 1546 1.1 christos { 1547 1.1.1.9 christos if (prod & ((int64_t)1 << i)) 1548 1.1 christos { 1549 1.1 christos DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1550 1.1 christos prod = 0x7fffffff; 1551 1.1 christos break; 1552 1.1 christos } 1553 1.1 christos } 1554 1.1 christos } 1555 1.1 christos } 1556 1.1 christos DSPLO(ac) = EXTEND32 (prod); 1557 1.1 christos DSPHI(ac) = EXTEND32 (prod >> 32); 1558 1.1 christos } 1559 1.1 christos 1560 1.1 christos 011111,5.RS,5.RT,000,2.AC,10100,110000:SPECIAL3:32::MAQ_S.W.PHL 1561 1.1 christos "maq_s.w.phl ac<AC>, r<RS>, r<RT>" 1562 1.1 christos *dsp: 1563 1.1 christos { 1564 1.1 christos do_ph_maq (SD_, AC, RS, RT, 0, 0); 1565 1.1 christos } 1566 1.1 christos 1567 1.1 christos 011111,5.RS,5.RT,000,2.AC,10110,110000:SPECIAL3:32::MAQ_S.W.PHR 1568 1.1 christos "maq_s.w.phr ac<AC>, r<RS>, r<RT>" 1569 1.1 christos *dsp: 1570 1.1 christos { 1571 1.1 christos do_ph_maq (SD_, AC, RS, RT, 0, 1); 1572 1.1 christos } 1573 1.1 christos 1574 1.1 christos 011111,5.RS,5.RT,000,2.AC,10000,110000:SPECIAL3:32::MAQ_SA.W.PHL 1575 1.1 christos "maq_sa.w.phl ac<AC>, r<RS>, r<RT>" 1576 1.1 christos *dsp: 1577 1.1 christos { 1578 1.1 christos do_ph_maq (SD_, AC, RS, RT, 1, 0); 1579 1.1 christos } 1580 1.1 christos 1581 1.1 christos 011111,5.RS,5.RT,000,2.AC,10010,110000:SPECIAL3:32::MAQ_SA.W.PHR 1582 1.1 christos "maq_sa.w.phr ac<AC>, r<RS>, r<RT>" 1583 1.1 christos *dsp: 1584 1.1 christos { 1585 1.1 christos do_ph_maq (SD_, AC, RS, RT, 1, 1); 1586 1.1 christos } 1587 1.1 christos 1588 1.1 christos 011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV 1589 1.1 christos "bitrev r<RD>, r<RT>" 1590 1.1 christos *dsp: 1591 1.1 christos { 1592 1.1.1.5 christos do_bitrev (SD_, RD, RT); 1593 1.1 christos } 1594 1.1 christos 1595 1.1 christos 011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV 1596 1.1 christos "insv r<RT>, r<RS>" 1597 1.1 christos *dsp: 1598 1.1 christos { 1599 1.1.1.5 christos do_insv (SD_, RT, RS); 1600 1.1 christos } 1601 1.1 christos 1602 1.1 christos 011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB 1603 1.1 christos "repl.qb r<RD>, <IMM8>" 1604 1.1 christos *dsp: 1605 1.1 christos { 1606 1.1.1.5 christos do_repl (SD_, RD, IMM8, 0); 1607 1.1 christos } 1608 1.1 christos 1609 1.1 christos 011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB 1610 1.1 christos "replv.qb r<RD>, r<RT>" 1611 1.1 christos *dsp: 1612 1.1 christos { 1613 1.1.1.5 christos do_repl (SD_, RD, RT, 1); 1614 1.1 christos } 1615 1.1 christos 1616 1.1 christos 011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH 1617 1.1 christos "repl.ph r<RD>, <IMM10>" 1618 1.1 christos *dsp: 1619 1.1 christos { 1620 1.1.1.5 christos do_repl (SD_, RD, IMM10, 2); 1621 1.1 christos } 1622 1.1 christos 1623 1.1 christos 011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH 1624 1.1 christos "replv.ph r<RD>, r<RT>" 1625 1.1 christos *dsp: 1626 1.1 christos { 1627 1.1.1.5 christos do_repl (SD_, RD, RT, 3); 1628 1.1 christos } 1629 1.1 christos 1630 1.1 christos // op: 0 = EQ, 1 = LT, 2 = LE 1631 1.1 christos :function:::void:do_qb_cmpu:int rs, int rt, int op 1632 1.1 christos { 1633 1.1 christos int i, j; 1634 1.1.1.9 christos uint32_t v1 = GPR[rs]; 1635 1.1.1.9 christos uint32_t v2 = GPR[rt]; 1636 1.1.1.9 christos uint8_t h1, h2; 1637 1.1.1.9 christos uint32_t mask; 1638 1.1 christos for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8) 1639 1.1 christos { 1640 1.1.1.9 christos h1 = (uint8_t)(v1 & 0xff); 1641 1.1.1.9 christos h2 = (uint8_t)(v2 & 0xff); 1642 1.1 christos mask = ~(1 << (DSPCR_CCOND_SHIFT + j)); 1643 1.1 christos DSPCR &= mask; 1644 1.1 christos if (op == 0) // EQ 1645 1.1 christos DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j)); 1646 1.1 christos else if (op == 1) // LT 1647 1.1 christos DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j)); 1648 1.1 christos else // LE 1649 1.1 christos DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j)); 1650 1.1 christos } 1651 1.1 christos } 1652 1.1 christos 1653 1.1 christos 011111,5.RS,5.RT,00000,00000,010001:SPECIAL3:32::CMPU.EQ.QB 1654 1.1 christos "cmpu.eq.qb r<RS>, r<RT>" 1655 1.1 christos *dsp: 1656 1.1 christos { 1657 1.1 christos do_qb_cmpu (SD_, RS, RT, 0); 1658 1.1 christos } 1659 1.1 christos 1660 1.1 christos 011111,5.RS,5.RT,00000,00001,010001:SPECIAL3:32::CMPU.LT.QB 1661 1.1 christos "cmpu.lt.qb r<RS>, r<RT>" 1662 1.1 christos *dsp: 1663 1.1 christos { 1664 1.1 christos do_qb_cmpu (SD_, RS, RT, 1); 1665 1.1 christos } 1666 1.1 christos 1667 1.1 christos 011111,5.RS,5.RT,00000,00010,010001:SPECIAL3:32::CMPU.LE.QB 1668 1.1 christos "cmpu.le.qb r<RS>, r<RT>" 1669 1.1 christos *dsp: 1670 1.1 christos { 1671 1.1 christos do_qb_cmpu (SD_, RS, RT, 2); 1672 1.1 christos } 1673 1.1 christos 1674 1.1 christos // op: 0 = EQ, 1 = LT, 2 = LE 1675 1.1 christos :function:::void:do_qb_cmpgu:int rd, int rs, int rt, int op 1676 1.1 christos { 1677 1.1 christos int i, j; 1678 1.1.1.9 christos uint32_t v1 = GPR[rs]; 1679 1.1.1.9 christos uint32_t v2 = GPR[rt]; 1680 1.1.1.9 christos uint8_t h1, h2; 1681 1.1.1.9 christos uint32_t result = 0; 1682 1.1 christos for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8) 1683 1.1 christos { 1684 1.1.1.9 christos h1 = (uint8_t)(v1 & 0xff); 1685 1.1.1.9 christos h2 = (uint8_t)(v2 & 0xff); 1686 1.1 christos if (op == 0) // EQ 1687 1.1 christos result |= ((h1 == h2) << j); 1688 1.1 christos else if (op == 1) // LT 1689 1.1 christos result |= ((h1 < h2) << j); 1690 1.1 christos else // LE 1691 1.1 christos result |= ((h1 <= h2) << j); 1692 1.1 christos } 1693 1.1 christos GPR[rd] = EXTEND32 (result); 1694 1.1 christos } 1695 1.1 christos 1696 1.1 christos 011111,5.RS,5.RT,5.RD,00100,010001:SPECIAL3:32::CMPGU.EQ.QB 1697 1.1 christos "cmpgu.eq.qb r<RD>, r<RS>, r<RT>" 1698 1.1 christos *dsp: 1699 1.1 christos { 1700 1.1 christos do_qb_cmpgu (SD_, RD, RS, RT, 0); 1701 1.1 christos } 1702 1.1 christos 1703 1.1 christos 011111,5.RS,5.RT,5.RD,00101,010001:SPECIAL3:32::CMPGU.LT.QB 1704 1.1 christos "cmpgu.lt.qb r<RD>, r<RS>, r<RT>" 1705 1.1 christos *dsp: 1706 1.1 christos { 1707 1.1 christos do_qb_cmpgu (SD_, RD, RS, RT, 1); 1708 1.1 christos } 1709 1.1 christos 1710 1.1 christos 011111,5.RS,5.RT,5.RD,00110,010001:SPECIAL3:32::CMPGU.LE.QB 1711 1.1 christos "cmpgu.le.qb r<RD>, r<RS>, r<RT>" 1712 1.1 christos *dsp: 1713 1.1 christos { 1714 1.1 christos do_qb_cmpgu (SD_, RD, RS, RT, 2); 1715 1.1 christos } 1716 1.1 christos 1717 1.1 christos // op: 0 = EQ, 1 = LT, 2 = LE 1718 1.1 christos :function:::void:do_ph_cmpu:int rs, int rt, int op 1719 1.1 christos { 1720 1.1 christos int i, j; 1721 1.1.1.9 christos uint32_t v1 = GPR[rs]; 1722 1.1.1.9 christos uint32_t v2 = GPR[rt]; 1723 1.1.1.9 christos int16_t h1, h2; 1724 1.1.1.9 christos uint32_t mask; 1725 1.1 christos for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16) 1726 1.1 christos { 1727 1.1.1.9 christos h1 = (int16_t)(v1 & 0xffff); 1728 1.1.1.9 christos h2 = (int16_t)(v2 & 0xffff); 1729 1.1 christos mask = ~(1 << (DSPCR_CCOND_SHIFT + j)); 1730 1.1 christos DSPCR &= mask; 1731 1.1 christos if (op == 0) // EQ 1732 1.1 christos DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j)); 1733 1.1 christos else if (op == 1) // LT 1734 1.1 christos DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j)); 1735 1.1 christos else // LE 1736 1.1 christos DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j)); 1737 1.1 christos } 1738 1.1 christos } 1739 1.1 christos 1740 1.1 christos 011111,5.RS,5.RT,00000,01000,010001:SPECIAL3:32::CMP.EQ.PH 1741 1.1 christos "cmp.eq.ph r<RS>, r<RT>" 1742 1.1 christos *dsp: 1743 1.1 christos { 1744 1.1 christos do_ph_cmpu (SD_, RS, RT, 0); 1745 1.1 christos } 1746 1.1 christos 1747 1.1 christos 011111,5.RS,5.RT,00000,01001,010001:SPECIAL3:32::CMP.LT.PH 1748 1.1 christos "cmp.lt.ph r<RS>, r<RT>" 1749 1.1 christos *dsp: 1750 1.1 christos { 1751 1.1 christos do_ph_cmpu (SD_, RS, RT, 1); 1752 1.1 christos } 1753 1.1 christos 1754 1.1 christos 011111,5.RS,5.RT,00000,01010,010001:SPECIAL3:32::CMP.LE.PH 1755 1.1 christos "cmp.le.ph r<RS>, r<RT>" 1756 1.1 christos *dsp: 1757 1.1 christos { 1758 1.1 christos do_ph_cmpu (SD_, RS, RT, 2); 1759 1.1 christos } 1760 1.1 christos 1761 1.1 christos 011111,5.RS,5.RT,5.RD,00011,010001:SPECIAL3:32::PICK.QB 1762 1.1 christos "pick.qb r<RD>, r<RS>, r<RT>" 1763 1.1 christos *dsp: 1764 1.1 christos { 1765 1.1.1.5 christos do_qb_pick (SD_, RD, RS, RT); 1766 1.1 christos } 1767 1.1 christos 1768 1.1 christos 011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH 1769 1.1 christos "pick.ph r<RD>, r<RS>, r<RT>" 1770 1.1 christos *dsp: 1771 1.1 christos { 1772 1.1.1.5 christos do_ph_pick (SD_, RD, RS, RT); 1773 1.1 christos } 1774 1.1 christos 1775 1.1 christos 011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH 1776 1.1 christos "packrl.ph r<RD>, r<RS>, r<RT>" 1777 1.1 christos *dsp: 1778 1.1 christos { 1779 1.1.1.5 christos do_ph_packrl (SD_, RD, RS, RT); 1780 1.1 christos } 1781 1.1 christos 1782 1.1 christos // op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS 1783 1.1 christos :function:::void:do_w_extr:int rt, int ac, int shift, int op 1784 1.1 christos { 1785 1.1 christos int i; 1786 1.1.1.9 christos uint32_t lo = DSPLO(ac); 1787 1.1.1.9 christos uint32_t hi = DSPHI(ac); 1788 1.1.1.9 christos uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo; 1789 1.1.1.9 christos int64_t result = (int64_t)prod; 1790 1.1 christos int setcond = 0; 1791 1.1 christos if (!(prod & 0x8000000000000000LL)) 1792 1.1 christos { 1793 1.1 christos for (i = 62; i >= (shift + 31); i--) 1794 1.1 christos { 1795 1.1.1.9 christos if (prod & ((uint64_t)1 << i)) 1796 1.1 christos { 1797 1.1 christos DSPCR |= DSPCR_OUFLAG7; 1798 1.1 christos setcond = 1; 1799 1.1 christos break; 1800 1.1 christos } 1801 1.1 christos } 1802 1.1 christos if (((prod >> (shift - 1)) & 0xffffffffLL) == 0xffffffffLL) 1803 1.1 christos { 1804 1.1 christos DSPCR |= DSPCR_OUFLAG7; 1805 1.1 christos setcond = 1; 1806 1.1 christos } 1807 1.1 christos } 1808 1.1 christos else 1809 1.1 christos { 1810 1.1 christos for (i = 62; i >= (shift + 31); i--) 1811 1.1 christos { 1812 1.1.1.9 christos if (!(prod & ((uint64_t)1 << i))) 1813 1.1 christos { 1814 1.1 christos DSPCR |= DSPCR_OUFLAG7; 1815 1.1 christos setcond = 2; 1816 1.1 christos break; 1817 1.1 christos } 1818 1.1 christos } 1819 1.1 christos } 1820 1.1 christos if (op == 0) // EXTR 1821 1.1 christos result = result >> shift; 1822 1.1 christos else if (op == 1) // EXTR_R 1823 1.1 christos { 1824 1.1 christos if (shift != 0) 1825 1.1 christos result = ((result >> (shift - 1)) + 1) >> 1; 1826 1.1 christos else 1827 1.1 christos result = result >> shift; 1828 1.1 christos } 1829 1.1 christos else // EXTR_RS 1830 1.1 christos { 1831 1.1 christos if (setcond == 1) 1832 1.1 christos result = 0x7fffffff; 1833 1.1 christos else if (setcond == 2) 1834 1.1 christos result = 0x80000000; 1835 1.1.1.9 christos else 1836 1.1 christos { 1837 1.1 christos if (shift != 0) 1838 1.1 christos result = ((result >> (shift - 1)) + 1) >> 1; 1839 1.1 christos else 1840 1.1 christos result = result >> shift; 1841 1.1 christos } 1842 1.1 christos } 1843 1.1 christos GPR[rt] = EXTEND32 (result); 1844 1.1 christos } 1845 1.1 christos 1846 1.1 christos 011111,5.SHIFT,5.RT,000,2.AC,00000,111000:SPECIAL3:32::EXTR.W 1847 1.1 christos "extr.w r<RT>, ac<AC>, <SHIFT>" 1848 1.1 christos *dsp: 1849 1.1 christos { 1850 1.1 christos do_w_extr (SD_, RT, AC, SHIFT, 0); 1851 1.1 christos } 1852 1.1 christos 1853 1.1 christos 011111,5.RS,5.RT,000,2.AC,00001,111000:SPECIAL3:32::EXTRV.W 1854 1.1 christos "extrv.w r<RT>, ac<AC>, r<RS>" 1855 1.1 christos *dsp: 1856 1.1 christos { 1857 1.1.1.5 christos do_extrv (SD_, RT, AC, RS, 0); 1858 1.1 christos } 1859 1.1 christos 1860 1.1 christos 011111,5.SHIFT,5.RT,000,2.AC,00100,111000:SPECIAL3:32::EXTR_R.W 1861 1.1 christos "extr_r.w r<RT>, ac<AC>, <SHIFT>" 1862 1.1 christos *dsp: 1863 1.1 christos { 1864 1.1 christos do_w_extr (SD_, RT, AC, SHIFT, 1); 1865 1.1 christos } 1866 1.1 christos 1867 1.1 christos 011111,5.RS,5.RT,000,2.AC,00101,111000:SPECIAL3:32::EXTRV_R.W 1868 1.1 christos "extrv_r.w r<RT>, ac<AC>, r<RS>" 1869 1.1 christos *dsp: 1870 1.1 christos { 1871 1.1.1.5 christos do_extrv (SD_, RT, AC, RS, 1); 1872 1.1 christos } 1873 1.1 christos 1874 1.1 christos 011111,5.SHIFT,5.RT,000,2.AC,00110,111000:SPECIAL3:32::EXTR_RS.W 1875 1.1 christos "extr_rs.w r<RT>, ac<AC>, <SHIFT>" 1876 1.1 christos *dsp: 1877 1.1 christos { 1878 1.1 christos do_w_extr (SD_, RT, AC, SHIFT, 2); 1879 1.1 christos } 1880 1.1 christos 1881 1.1 christos 011111,5.RS,5.RT,000,2.AC,00111,111000:SPECIAL3:32::EXTRV_RS.W 1882 1.1 christos "extrv_rs.w r<RT>, ac<AC>, r<RS>" 1883 1.1 christos *dsp: 1884 1.1 christos { 1885 1.1.1.5 christos do_extrv (SD_, RT, AC, RS, 2); 1886 1.1 christos } 1887 1.1 christos 1888 1.1 christos :function:::void:do_h_extr:int rt, int ac, int shift 1889 1.1 christos { 1890 1.1.1.9 christos uint32_t lo = DSPLO(ac); 1891 1.1.1.9 christos uint32_t hi = DSPHI(ac); 1892 1.1.1.9 christos uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo; 1893 1.1.1.9 christos int64_t result = (int64_t)prod; 1894 1.1.1.9 christos int64_t value = 0xffffffffffff8000LL; 1895 1.1 christos result >>= shift; 1896 1.1 christos if (result > 0x7fff) 1897 1.1 christos { 1898 1.1 christos result = 0x7fff; 1899 1.1 christos DSPCR |= DSPCR_OUFLAG7; 1900 1.1 christos } 1901 1.1 christos else if (result < value) 1902 1.1 christos { 1903 1.1 christos result = value; 1904 1.1 christos DSPCR |= DSPCR_OUFLAG7; 1905 1.1 christos } 1906 1.1 christos GPR[rt] = EXTEND32 (result); 1907 1.1 christos } 1908 1.1 christos 1909 1.1 christos 011111,5.SHIFT,5.RT,000,2.AC,01110,111000:SPECIAL3:32::EXTR_S.H 1910 1.1 christos "extr_s.h r<RT>, ac<AC>, <SHIFT>" 1911 1.1 christos *dsp: 1912 1.1 christos { 1913 1.1 christos do_h_extr (SD_, RT, AC, SHIFT); 1914 1.1 christos } 1915 1.1 christos 1916 1.1 christos 011111,5.RS,5.RT,000,2.AC,01111,111000:SPECIAL3:32::EXTRV_S.H 1917 1.1 christos "extrv_s.h r<RT>, ac<AC>, r<RS>" 1918 1.1 christos *dsp: 1919 1.1 christos { 1920 1.1.1.5 christos do_extrv_s_h (SD_, RT, AC, RS); 1921 1.1 christos } 1922 1.1 christos 1923 1.1 christos // op: 0 = EXTP, 1 = EXTPDP 1924 1.1 christos :function:::void:do_extp:int rt, int ac, int size, int op 1925 1.1 christos { 1926 1.1.1.9 christos int32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 1927 1.1.1.9 christos uint32_t lo = DSPLO(ac); 1928 1.1.1.9 christos uint32_t hi = DSPHI(ac); 1929 1.1.1.9 christos uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo; 1930 1.1.1.9 christos uint64_t result = 0; 1931 1.1 christos if (pos - (size + 1) >= -1) 1932 1.1 christos { 1933 1.1 christos prod >>= (pos - size); 1934 1.1.1.9 christos result = prod & (((uint64_t)1 << (size + 1)) - 1); 1935 1.1 christos DSPCR &= (~DSPCR_EFI_SMASK); 1936 1.1 christos if (op == 1) // EXTPDP 1937 1.1 christos { 1938 1.1 christos if (pos - (size + 1) >= 0) 1939 1.1 christos { 1940 1.1 christos DSPCR &= (~DSPCR_POS_SMASK); 1941 1.1 christos DSPCR |= ((pos - (size + 1)) & DSPCR_POS_MASK) << DSPCR_POS_SHIFT; 1942 1.1 christos } 1943 1.1 christos else if (pos - (size + 1) == -1) 1944 1.1 christos { 1945 1.1 christos DSPCR |= DSPCR_POS_SMASK; 1946 1.1 christos } 1947 1.1 christos } 1948 1.1 christos } 1949 1.1 christos else 1950 1.1 christos { 1951 1.1 christos DSPCR |= DSPCR_EFI; 1952 1.1 christos Unpredictable (); 1953 1.1 christos } 1954 1.1 christos GPR[rt] = EXTEND32 (result); 1955 1.1 christos } 1956 1.1 christos 1957 1.1 christos 011111,5.SIZE,5.RT,000,2.AC,00010,111000:SPECIAL3:32::EXTP 1958 1.1 christos "extp r<RT>, ac<AC>, <SIZE>" 1959 1.1 christos *dsp: 1960 1.1 christos { 1961 1.1 christos do_extp (SD_, RT, AC, SIZE, 0); 1962 1.1 christos } 1963 1.1 christos 1964 1.1 christos 011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV 1965 1.1 christos "extpv r<RT>, ac<AC>, r<RS>" 1966 1.1 christos *dsp: 1967 1.1 christos { 1968 1.1.1.5 christos do_extpv (SD_, RT, AC, RS, 0); 1969 1.1 christos } 1970 1.1 christos 1971 1.1 christos 011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP 1972 1.1 christos "extpdp r<RT>, ac<AC>, <SIZE>" 1973 1.1 christos *dsp: 1974 1.1 christos { 1975 1.1 christos do_extp (SD_, RT, AC, SIZE, 1); 1976 1.1 christos } 1977 1.1 christos 1978 1.1 christos 011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV 1979 1.1 christos "extpdpv r<RT>, ac<AC>, r<RS>" 1980 1.1 christos *dsp: 1981 1.1 christos { 1982 1.1.1.5 christos do_extpv (SD_, RT, AC, RS, 1); 1983 1.1 christos } 1984 1.1 christos 1985 1.1 christos :function:::void:do_shilo:int ac, int shift 1986 1.1 christos { 1987 1.1.1.9 christos uint32_t lo = DSPLO(ac); 1988 1.1.1.9 christos uint32_t hi = DSPHI(ac); 1989 1.1.1.9 christos uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo; 1990 1.1 christos if (shift > 31) 1991 1.1 christos shift = shift - 64; 1992 1.1 christos if (shift >= 0) 1993 1.1 christos prod >>= shift; 1994 1.1 christos else 1995 1.1 christos prod <<= (-shift); 1996 1.1 christos DSPLO(ac) = EXTEND32 (prod); 1997 1.1 christos DSPHI(ac) = EXTEND32 (prod >> 32); 1998 1.1 christos } 1999 1.1 christos 2000 1.1 christos 011111,6.SHIFT6,0000,000,2.AC,11010,111000:SPECIAL3:32::SHILO 2001 1.1 christos "shilo ac<AC>, <SHIFT6>" 2002 1.1 christos *dsp: 2003 1.1 christos { 2004 1.1 christos do_shilo (SD_, AC, SHIFT6); 2005 1.1 christos } 2006 1.1 christos 2007 1.1 christos 011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV 2008 1.1 christos "shilov ac<AC>, r<RS>" 2009 1.1 christos *dsp: 2010 1.1 christos { 2011 1.1.1.5 christos do_shilov (SD_, AC, RS); 2012 1.1 christos } 2013 1.1 christos 2014 1.1 christos 011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP 2015 1.1 christos "mthlip r<RS>, ac<AC>" 2016 1.1 christos *dsp: 2017 1.1 christos { 2018 1.1.1.5 christos do_mthlip (SD_, RS, AC); 2019 1.1 christos } 2020 1.1 christos 2021 1.1 christos 011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP 2022 1.1 christos "wrdsp r<RS>":MASK10 == 1111111111 2023 1.1 christos "wrdsp r<RS>, <MASK10>" 2024 1.1 christos *dsp: 2025 1.1 christos { 2026 1.1.1.5 christos do_wrdsp (SD_, RS, MASK10); 2027 1.1 christos } 2028 1.1 christos 2029 1.1 christos 011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP 2030 1.1 christos "rddsp r<RD>":MASK10 == 1111111111 2031 1.1 christos "rddsp r<RD>, <MASK10>" 2032 1.1 christos *dsp: 2033 1.1 christos { 2034 1.1.1.5 christos do_rddsp (SD_, RD, MASK10); 2035 1.1 christos } 2036 1.1 christos 2037 1.1 christos 011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX 2038 1.1 christos "lbux r<RD>, r<INDEX>(r<BASE>)" 2039 1.1 christos *dsp: 2040 1.1 christos { 2041 1.1.1.5 christos do_lxx (SD_, RD, BASE, INDEX, 0); 2042 1.1 christos } 2043 1.1 christos 2044 1.1 christos 011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX 2045 1.1 christos "lhx r<RD>, r<INDEX>(r<BASE>)" 2046 1.1 christos *dsp: 2047 1.1 christos { 2048 1.1.1.5 christos do_lxx (SD_, RD, BASE, INDEX, 1); 2049 1.1 christos } 2050 1.1 christos 2051 1.1 christos 011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX 2052 1.1 christos "lwx r<RD>, r<INDEX>(r<BASE>)" 2053 1.1 christos *dsp: 2054 1.1 christos { 2055 1.1.1.5 christos do_lxx (SD_, RD, BASE, INDEX, 2); 2056 1.1 christos } 2057 1.1 christos 2058 1.1 christos 000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32 2059 1.1 christos "bposge32 <OFFSET>" 2060 1.1 christos *dsp: 2061 1.1 christos { 2062 1.1.1.9 christos uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 2063 1.1 christos address_word offset = EXTEND16 (OFFSET) << 2; 2064 1.1 christos if (pos >= 32) 2065 1.1 christos { 2066 1.1 christos DELAY_SLOT (NIA + offset); 2067 1.1 christos } 2068 1.1 christos } 2069