Editor for papermario-dx mods
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 940 lines 37 kB view raw
1// SPDX-FileCopyrightText: 2024 gopher64 contributors 2// SPDX-FileCopyrightText: 2026 Alex Bates <alex@bates64.com> 3// 4// SPDX-License-Identifier: GPL-3.0-or-later 5 6#[cfg(target_arch = "x86_64")] 7use std::arch::x86_64::*; 8 9use crate::su_instructions::{get_vpr16, modify_vpr16}; 10 11fn vt(opcode: u32) -> u32 { 12 (opcode >> 16) & 0x1F 13} 14 15fn ve(opcode: u32) -> u32 { 16 (opcode >> 21) & 0xF 17} 18 19fn vs(opcode: u32) -> u32 { 20 (opcode >> 11) & 0x1F 21} 22 23fn vd(opcode: u32) -> u32 { 24 (opcode >> 6) & 0x1F 25} 26 27fn de(opcode: u32) -> u32 { 28 (opcode >> 11) & 0x7 29} 30 31fn clamp_signed_32(value: i32) -> i16 { 32 value.clamp(-32768, 32767) as i16 33} 34 35fn clamp_signed_64(value: i64) -> i16 { 36 value.clamp(-32768, 32767) as i16 37} 38 39fn s_clip(x: i64, bits: u32) -> i64 { 40 let mask = (1i64 << bits) - 1; 41 let value = x & mask; 42 (value << (64 - bits)) >> (64 - bits) 43} 44 45fn compute_reciprocal(input: i32, reciprocals: &[u16]) -> u32 { 46 let mask = input >> 31; 47 let mut data = input ^ mask; 48 if input > -32768 { 49 data -= mask 50 } 51 if data == 0 { 52 0x7fffffff 53 } else if input == -32768 { 54 0xffff0000 55 } else { 56 let shift = (data as u32).leading_zeros(); 57 let index = (((data as u64) << shift) & 0x7fc00000) >> 22; 58 let mut result = reciprocals[index as usize] as u32; 59 result = (0x10000 | result) << 14; 60 (result >> (31 - shift)) ^ mask as u32 61 } 62} 63 64fn compute_inverse_sqrt(input: i32, inverse_square_roots: &[u16]) -> u32 { 65 let mask = input >> 31; 66 let mut data = input ^ mask; 67 if input > -32768 { 68 data -= mask 69 } 70 if data == 0 { 71 0x7fffffff 72 } else if input == -32768 { 73 0xffff0000 74 } else { 75 let shift = (data as u32).leading_zeros(); 76 let index = (((data as u64) << shift) & 0x7fc00000) as u32 >> 22; 77 let mut result = inverse_square_roots[((index & 0x1fe) | (shift & 1)) as usize] as u32; 78 result = (0x10000 | result) << 14; 79 (result >> ((31 - shift) >> 1)) ^ mask as u32 80 } 81} 82 83fn vte(device: &crate::Device, vt: u32, index: usize) -> __m128i { 84 unsafe { 85 _mm_shuffle_epi8( 86 device.rsp.cpu.vpr[vt as usize], 87 device.rsp.cpu.shuffle[index], 88 ) 89 } 90} 91 92pub fn vmulf(device: &mut crate::Device, opcode: u32) { 93 let vte = vte(device, vt(opcode), ve(opcode) as usize); 94 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 95 unsafe { 96 let lo = _mm_mullo_epi16(vs_reg, vte); 97 let hi = _mm_mulhi_epi16(vs_reg, vte); 98 99 let sign1 = _mm_srli_epi16(lo, 15); 100 let lo_doubled = _mm_add_epi16(lo, lo); 101 let sign2 = _mm_srli_epi16(lo_doubled, 15); 102 103 device.rsp.cpu.accl = _mm_add_epi16(_mm_set1_epi16(-32768_i16), lo_doubled); // round + lo 104 device.rsp.cpu.accm = _mm_add_epi16(_mm_slli_epi16(hi, 1), _mm_add_epi16(sign1, sign2)); 105 let neg = _mm_srai_epi16(device.rsp.cpu.accm, 15); 106 107 let neq = _mm_cmpeq_epi16(vs_reg, vte); 108 let eq = _mm_and_si128(neq, neg); 109 110 device.rsp.cpu.acch = _mm_andnot_si128(neq, neg); 111 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_add_epi16(device.rsp.cpu.accm, eq); 112 } 113} 114 115pub fn vmulu(device: &mut crate::Device, opcode: u32) { 116 let vte = vte(device, vt(opcode), ve(opcode) as usize); 117 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 118 unsafe { 119 let lo = _mm_mullo_epi16(vs_reg, vte); 120 let hi = _mm_mulhi_epi16(vs_reg, vte); 121 122 let sign1 = _mm_srli_epi16(lo, 15); 123 let lo_doubled = _mm_add_epi16(lo, lo); 124 let sign2 = _mm_srli_epi16(lo_doubled, 15); 125 126 device.rsp.cpu.accl = _mm_add_epi16(_mm_set1_epi16(-32768_i16), lo_doubled); // round + lo 127 device.rsp.cpu.accm = _mm_add_epi16(_mm_slli_epi16(hi, 1), _mm_add_epi16(sign1, sign2)); 128 let neg = _mm_srai_epi16(device.rsp.cpu.accm, 15); 129 130 let neq = _mm_cmpeq_epi16(vs_reg, vte); 131 132 device.rsp.cpu.acch = _mm_andnot_si128(neq, neg); 133 let result = _mm_or_si128(device.rsp.cpu.accm, neg); 134 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_andnot_si128(device.rsp.cpu.acch, result); 135 } 136} 137 138pub fn vrndp(device: &mut crate::Device, opcode: u32) { 139 let vte = vte(device, vt(opcode), ve(opcode) as usize); 140 let acch: &mut __m128i = &mut device.rsp.cpu.acch; 141 let accm: &mut __m128i = &mut device.rsp.cpu.accm; 142 let accl: &mut __m128i = &mut device.rsp.cpu.accl; 143 let vd_reg = &mut device.rsp.cpu.vpr[vd(opcode) as usize]; 144 let shift_amount = vs(opcode) & 1; 145 146 for n in 0..8 { 147 let mut product = get_vpr16(vte, n) as i16 as i32; 148 if shift_amount != 0 { 149 product <<= 16 150 } 151 let mut acc = 0; 152 acc |= get_vpr16(*acch, n) as i64; 153 acc <<= 16; 154 acc |= get_vpr16(*accm, n) as i64; 155 acc <<= 16; 156 acc |= get_vpr16(*accl, n) as i64; 157 acc <<= 16; 158 acc >>= 16; 159 if acc >= 0 { 160 acc = s_clip(acc + (product as i64), 48) 161 } 162 modify_vpr16(acch, n, (acc >> 32) as u16); 163 modify_vpr16(accm, n, (acc >> 16) as u16); 164 modify_vpr16(accl, n, acc as u16); 165 modify_vpr16(vd_reg, n, clamp_signed_64(acc >> 16) as u16); 166 } 167} 168 169pub fn vmulq(device: &mut crate::Device, opcode: u32) { 170 let vte = vte(device, vt(opcode), ve(opcode) as usize); 171 let acch: &mut __m128i = &mut device.rsp.cpu.acch; 172 let accm: &mut __m128i = &mut device.rsp.cpu.accm; 173 let accl: &mut __m128i = &mut device.rsp.cpu.accl; 174 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 175 let vd_reg = &mut device.rsp.cpu.vpr[vd(opcode) as usize]; 176 177 for n in 0..8 { 178 let mut product = 179 (get_vpr16(vs_reg, n) as i16 as i32).wrapping_mul(get_vpr16(vte, n) as i16 as i32); 180 if product < 0 { 181 product += 31; 182 } 183 modify_vpr16(acch, n, (product >> 16) as u16); 184 modify_vpr16(accm, n, product as u16); 185 modify_vpr16(accl, n, 0); 186 modify_vpr16(vd_reg, n, (clamp_signed_32(product >> 1) & !15) as u16); 187 } 188} 189 190pub fn vmudl(device: &mut crate::Device, opcode: u32) { 191 let vte = vte(device, vt(opcode), ve(opcode) as usize); 192 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 193 unsafe { 194 device.rsp.cpu.accl = _mm_mulhi_epu16(vs_reg, vte); 195 device.rsp.cpu.accm = _mm_setzero_si128(); 196 device.rsp.cpu.acch = _mm_setzero_si128(); 197 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 198 } 199} 200 201pub fn vmudm(device: &mut crate::Device, opcode: u32) { 202 let vte = vte(device, vt(opcode), ve(opcode) as usize); 203 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 204 unsafe { 205 device.rsp.cpu.accl = _mm_mullo_epi16(vs_reg, vte); 206 device.rsp.cpu.accm = _mm_mulhi_epu16(vs_reg, vte); 207 let sign = _mm_srai_epi16(vs_reg, 15); 208 let vta = _mm_and_si128(vte, sign); 209 device.rsp.cpu.accm = _mm_sub_epi16(device.rsp.cpu.accm, vta); 210 device.rsp.cpu.acch = _mm_srai_epi16(device.rsp.cpu.accm, 15); 211 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accm; 212 } 213} 214 215pub fn vmudn(device: &mut crate::Device, opcode: u32) { 216 let vte = vte(device, vt(opcode), ve(opcode) as usize); 217 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 218 unsafe { 219 device.rsp.cpu.accl = _mm_mullo_epi16(vs_reg, vte); 220 device.rsp.cpu.accm = _mm_mulhi_epu16(vs_reg, vte); 221 let sign = _mm_srai_epi16(vte, 15); 222 let vsa = _mm_and_si128(vs_reg, sign); 223 device.rsp.cpu.accm = _mm_sub_epi16(device.rsp.cpu.accm, vsa); 224 device.rsp.cpu.acch = _mm_srai_epi16(device.rsp.cpu.accm, 15); 225 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 226 } 227} 228 229pub fn vmudh(device: &mut crate::Device, opcode: u32) { 230 let vte = vte(device, vt(opcode), ve(opcode) as usize); 231 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 232 unsafe { 233 device.rsp.cpu.accl = _mm_setzero_si128(); 234 device.rsp.cpu.accm = _mm_mullo_epi16(vs_reg, vte); 235 device.rsp.cpu.acch = _mm_mulhi_epi16(vs_reg, vte); 236 let lo = _mm_unpacklo_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch); 237 let hi = _mm_unpackhi_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch); 238 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_packs_epi32(lo, hi); 239 } 240} 241 242pub fn vmacf(device: &mut crate::Device, opcode: u32) { 243 let vte = vte(device, vt(opcode), ve(opcode) as usize); 244 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 245 unsafe { 246 let lo = _mm_mullo_epi16(vs_reg, vte); 247 let hi = _mm_mulhi_epi16(vs_reg, vte); 248 249 let carry = _mm_srli_epi16(lo, 15); 250 let md = _mm_or_si128(_mm_slli_epi16(hi, 1), carry); 251 let lo_doubled = _mm_slli_epi16(lo, 1); 252 let hi_sign = _mm_srai_epi16(hi, 15); 253 254 let accl_old = device.rsp.cpu.accl; 255 device.rsp.cpu.accl = _mm_add_epi16(accl_old, lo_doubled); 256 let overflow_l = _mm_cmpeq_epi16(_mm_adds_epu16(accl_old, lo_doubled), device.rsp.cpu.accl); 257 let borrow_from_l = _mm_cmpeq_epi16(overflow_l, _mm_setzero_si128()); 258 259 let md_adjusted = _mm_sub_epi16(md, borrow_from_l); 260 let zero_md = _mm_cmpeq_epi16(md_adjusted, _mm_setzero_si128()); 261 let borrow_to_h = _mm_and_si128(zero_md, borrow_from_l); 262 let hi_adjusted = _mm_sub_epi16(hi_sign, borrow_to_h); 263 264 let accm_old = device.rsp.cpu.accm; 265 device.rsp.cpu.accm = _mm_add_epi16(accm_old, md_adjusted); 266 let overflow_m = 267 _mm_cmpeq_epi16(_mm_adds_epu16(accm_old, md_adjusted), device.rsp.cpu.accm); 268 let borrow_from_m = _mm_cmpeq_epi16(overflow_m, _mm_setzero_si128()); 269 270 device.rsp.cpu.acch = _mm_add_epi16(device.rsp.cpu.acch, hi_adjusted); 271 device.rsp.cpu.acch = _mm_sub_epi16(device.rsp.cpu.acch, borrow_from_m); 272 273 let lo_packed = _mm_unpacklo_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch); 274 let hi_packed = _mm_unpackhi_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch); 275 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_packs_epi32(lo_packed, hi_packed); 276 } 277} 278 279pub fn vmacu(device: &mut crate::Device, opcode: u32) { 280 let vte = vte(device, vt(opcode), ve(opcode) as usize); 281 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 282 unsafe { 283 let lo = _mm_mullo_epi16(vs_reg, vte); 284 let hi = _mm_mulhi_epi16(vs_reg, vte); 285 286 let carry = _mm_srli_epi16(lo, 15); 287 let md = _mm_or_si128(_mm_slli_epi16(hi, 1), carry); 288 let lo_doubled = _mm_slli_epi16(lo, 1); 289 let hi_sign = _mm_srai_epi16(hi, 15); 290 291 let accl_old = device.rsp.cpu.accl; 292 device.rsp.cpu.accl = _mm_add_epi16(accl_old, lo_doubled); 293 let overflow_l = _mm_cmpeq_epi16(_mm_adds_epu16(accl_old, lo_doubled), device.rsp.cpu.accl); 294 let borrow_from_l = _mm_cmpeq_epi16(overflow_l, _mm_setzero_si128()); 295 296 let md_adjusted = _mm_sub_epi16(md, borrow_from_l); 297 let zero_md = _mm_cmpeq_epi16(md_adjusted, _mm_setzero_si128()); 298 let borrow_to_h = _mm_and_si128(zero_md, borrow_from_l); 299 let hi_adjusted = _mm_sub_epi16(hi_sign, borrow_to_h); 300 301 let accm_old = device.rsp.cpu.accm; 302 device.rsp.cpu.accm = _mm_add_epi16(accm_old, md_adjusted); 303 let overflow_m = 304 _mm_cmpeq_epi16(_mm_adds_epu16(accm_old, md_adjusted), device.rsp.cpu.accm); 305 let borrow_from_m = _mm_cmpeq_epi16(overflow_m, _mm_setzero_si128()); 306 307 device.rsp.cpu.acch = _mm_add_epi16(device.rsp.cpu.acch, hi_adjusted); 308 device.rsp.cpu.acch = _mm_sub_epi16(device.rsp.cpu.acch, borrow_from_m); 309 310 let mmask = _mm_srai_epi16(device.rsp.cpu.accm, 15); 311 let hmask = _mm_srai_epi16(device.rsp.cpu.acch, 15); 312 let md_result = _mm_or_si128(mmask, device.rsp.cpu.accm); 313 let positive = _mm_cmpgt_epi16(device.rsp.cpu.acch, _mm_setzero_si128()); 314 let final_result = _mm_andnot_si128(hmask, md_result); 315 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_or_si128(positive, final_result); 316 } 317} 318 319pub fn vrndn(device: &mut crate::Device, opcode: u32) { 320 let vte = vte(device, vt(opcode), ve(opcode) as usize); 321 let acch: &mut __m128i = &mut device.rsp.cpu.acch; 322 let accm: &mut __m128i = &mut device.rsp.cpu.accm; 323 let accl: &mut __m128i = &mut device.rsp.cpu.accl; 324 let vd_reg = &mut device.rsp.cpu.vpr[vd(opcode) as usize]; 325 let shift_amount = vs(opcode) & 1; 326 327 for n in 0..8 { 328 let mut product = get_vpr16(vte, n) as i16 as i32; 329 if shift_amount != 0 { 330 product <<= 16 331 } 332 let mut acc = 0; 333 acc |= get_vpr16(*acch, n) as i64; 334 acc <<= 16; 335 acc |= get_vpr16(*accm, n) as i64; 336 acc <<= 16; 337 acc |= get_vpr16(*accl, n) as i64; 338 acc <<= 16; 339 acc >>= 16; 340 if acc < 0 { 341 acc = s_clip(acc + (product as i64), 48) 342 } 343 modify_vpr16(acch, n, (acc >> 32) as u16); 344 modify_vpr16(accm, n, (acc >> 16) as u16); 345 modify_vpr16(accl, n, acc as u16); 346 modify_vpr16(vd_reg, n, clamp_signed_64(acc >> 16) as u16); 347 } 348} 349 350pub fn vmacq(device: &mut crate::Device, opcode: u32) { 351 let acch: &mut __m128i = &mut device.rsp.cpu.acch; 352 let accm: &mut __m128i = &mut device.rsp.cpu.accm; 353 let vd_reg = &mut device.rsp.cpu.vpr[vd(opcode) as usize]; 354 355 for n in 0..8 { 356 let mut product = ((get_vpr16(*acch, n) as i32) << 16) | (get_vpr16(*accm, n) as i32); 357 if product < 0 && (product & (1 << 5)) == 0 { 358 product += 32 359 } else if product >= 32 && (product & (1 << 5)) == 0 { 360 product -= 32 361 } 362 modify_vpr16(acch, n, (product >> 16) as u16); 363 modify_vpr16(accm, n, product as u16); 364 modify_vpr16(vd_reg, n, (clamp_signed_32(product >> 1) & !15) as u16); 365 } 366} 367 368pub fn vmadl(device: &mut crate::Device, opcode: u32) { 369 let vte = vte(device, vt(opcode), ve(opcode) as usize); 370 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 371 unsafe { 372 let hi = _mm_mulhi_epu16(vs_reg, vte); 373 374 let accl_old = device.rsp.cpu.accl; 375 device.rsp.cpu.accl = _mm_add_epi16(accl_old, hi); 376 let overflow_l = _mm_cmpeq_epi16(_mm_adds_epu16(accl_old, hi), device.rsp.cpu.accl); 377 let borrow = _mm_cmpeq_epi16(overflow_l, _mm_setzero_si128()); 378 379 let accm_old = device.rsp.cpu.accm; 380 device.rsp.cpu.accm = _mm_sub_epi16(accm_old, borrow); 381 let overflow_m = _mm_cmpeq_epi16( 382 _mm_adds_epu16(accm_old, _mm_sub_epi16(_mm_setzero_si128(), borrow)), 383 device.rsp.cpu.accm, 384 ); 385 let borrow_h = _mm_cmpeq_epi16(overflow_m, _mm_setzero_si128()); 386 387 device.rsp.cpu.acch = _mm_sub_epi16(device.rsp.cpu.acch, borrow_h); 388 389 let nhi = _mm_srai_epi16(device.rsp.cpu.acch, 15); 390 let nmd = _mm_srai_epi16(device.rsp.cpu.accm, 15); 391 let shi = _mm_cmpeq_epi16(nhi, device.rsp.cpu.acch); 392 let smd = _mm_cmpeq_epi16(nhi, nmd); 393 let cmask = _mm_and_si128(smd, shi); 394 let cval = _mm_cmpeq_epi16(nhi, _mm_setzero_si128()); 395 396 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_blendv_epi8(cval, device.rsp.cpu.accl, cmask); 397 } 398} 399 400pub fn vmadm(device: &mut crate::Device, opcode: u32) { 401 let vte = vte(device, vt(opcode), ve(opcode) as usize); 402 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 403 unsafe { 404 let lo = _mm_mullo_epi16(vs_reg, vte); 405 let mut hi = _mm_mulhi_epu16(vs_reg, vte); 406 let sign = _mm_srai_epi16(vs_reg, 15); 407 let vta = _mm_and_si128(vte, sign); 408 hi = _mm_sub_epi16(hi, vta); 409 410 let accl_old = device.rsp.cpu.accl; 411 device.rsp.cpu.accl = _mm_add_epi16(accl_old, lo); 412 let overflow_l = _mm_cmpeq_epi16(_mm_adds_epu16(accl_old, lo), device.rsp.cpu.accl); 413 let borrow = _mm_cmpeq_epi16(overflow_l, _mm_setzero_si128()); 414 415 hi = _mm_sub_epi16(hi, borrow); 416 417 let accm_old = device.rsp.cpu.accm; 418 device.rsp.cpu.accm = _mm_add_epi16(accm_old, hi); 419 let overflow_m = _mm_cmpeq_epi16(_mm_adds_epu16(accm_old, hi), device.rsp.cpu.accm); 420 let borrow_h = _mm_cmpeq_epi16(overflow_m, _mm_setzero_si128()); 421 422 let hi_sign = _mm_srai_epi16(hi, 15); 423 device.rsp.cpu.acch = _mm_add_epi16(device.rsp.cpu.acch, hi_sign); 424 device.rsp.cpu.acch = _mm_sub_epi16(device.rsp.cpu.acch, borrow_h); 425 426 let lo_packed = _mm_unpacklo_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch); 427 let hi_packed = _mm_unpackhi_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch); 428 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_packs_epi32(lo_packed, hi_packed); 429 } 430} 431 432pub fn vmadn(device: &mut crate::Device, opcode: u32) { 433 let vte = vte(device, vt(opcode), ve(opcode) as usize); 434 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 435 unsafe { 436 let lo = _mm_mullo_epi16(vs_reg, vte); 437 let mut hi = _mm_mulhi_epu16(vs_reg, vte); 438 let sign = _mm_srai_epi16(vte, 15); 439 let vsa = _mm_and_si128(vs_reg, sign); 440 hi = _mm_sub_epi16(hi, vsa); 441 442 let accl_old = device.rsp.cpu.accl; 443 device.rsp.cpu.accl = _mm_add_epi16(accl_old, lo); 444 let overflow_l = _mm_cmpeq_epi16(_mm_adds_epu16(accl_old, lo), device.rsp.cpu.accl); 445 let borrow = _mm_cmpeq_epi16(overflow_l, _mm_setzero_si128()); 446 447 hi = _mm_sub_epi16(hi, borrow); 448 449 let accm_old = device.rsp.cpu.accm; 450 device.rsp.cpu.accm = _mm_add_epi16(accm_old, hi); 451 let overflow_m = _mm_cmpeq_epi16(_mm_adds_epu16(accm_old, hi), device.rsp.cpu.accm); 452 let borrow_h = _mm_cmpeq_epi16(overflow_m, _mm_setzero_si128()); 453 454 let hi_sign = _mm_srai_epi16(hi, 15); 455 device.rsp.cpu.acch = _mm_add_epi16(device.rsp.cpu.acch, hi_sign); 456 device.rsp.cpu.acch = _mm_sub_epi16(device.rsp.cpu.acch, borrow_h); 457 458 let nhi = _mm_srai_epi16(device.rsp.cpu.acch, 15); 459 let nmd = _mm_srai_epi16(device.rsp.cpu.accm, 15); 460 let shi = _mm_cmpeq_epi16(nhi, device.rsp.cpu.acch); 461 let smd = _mm_cmpeq_epi16(nhi, nmd); 462 let cmask = _mm_and_si128(smd, shi); 463 let cval = _mm_cmpeq_epi16(nhi, _mm_setzero_si128()); 464 465 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_blendv_epi8(cval, device.rsp.cpu.accl, cmask); 466 } 467} 468 469pub fn vmadh(device: &mut crate::Device, opcode: u32) { 470 let vte = vte(device, vt(opcode), ve(opcode) as usize); 471 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 472 unsafe { 473 let lo = _mm_mullo_epi16(vs_reg, vte); 474 let mut hi = _mm_mulhi_epi16(vs_reg, vte); 475 476 let accm_old = device.rsp.cpu.accm; 477 device.rsp.cpu.accm = _mm_add_epi16(accm_old, lo); 478 let overflow = _mm_cmpeq_epi16(_mm_adds_epu16(accm_old, lo), device.rsp.cpu.accm); 479 let borrow = _mm_cmpeq_epi16(overflow, _mm_setzero_si128()); 480 481 hi = _mm_sub_epi16(hi, borrow); 482 device.rsp.cpu.acch = _mm_add_epi16(device.rsp.cpu.acch, hi); 483 484 let lo_packed = _mm_unpacklo_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch); 485 let hi_packed = _mm_unpackhi_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch); 486 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_packs_epi32(lo_packed, hi_packed); 487 } 488} 489 490pub fn vadd(device: &mut crate::Device, opcode: u32) { 491 let vte = vte(device, vt(opcode), ve(opcode) as usize); 492 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 493 unsafe { 494 let sum = _mm_add_epi16(vs_reg, vte); 495 device.rsp.cpu.accl = _mm_sub_epi16(sum, device.rsp.cpu.vcol); 496 497 let min = _mm_min_epi16(vs_reg, vte); 498 let max = _mm_max_epi16(vs_reg, vte); 499 let min_adjusted = _mm_subs_epi16(min, device.rsp.cpu.vcol); 500 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_adds_epi16(min_adjusted, max); 501 502 device.rsp.cpu.vcol = _mm_setzero_si128(); 503 device.rsp.cpu.vcoh = _mm_setzero_si128(); 504 } 505} 506 507pub fn vsub(device: &mut crate::Device, opcode: u32) { 508 let vte = vte(device, vt(opcode), ve(opcode) as usize); 509 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 510 unsafe { 511 let udiff = _mm_sub_epi16(vte, device.rsp.cpu.vcol); 512 let sdiff = _mm_subs_epi16(vte, device.rsp.cpu.vcol); 513 device.rsp.cpu.accl = _mm_sub_epi16(vs_reg, udiff); 514 515 let ov = _mm_cmpgt_epi16(sdiff, udiff); 516 let sub_result = _mm_subs_epi16(vs_reg, sdiff); 517 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_adds_epi16(sub_result, ov); 518 519 device.rsp.cpu.vcol = _mm_setzero_si128(); 520 device.rsp.cpu.vcoh = _mm_setzero_si128(); 521 } 522} 523 524pub fn vzero(device: &mut crate::Device, opcode: u32) { 525 let vte = vte(device, vt(opcode), ve(opcode) as usize); 526 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 527 unsafe { 528 device.rsp.cpu.accl = _mm_add_epi16(vs_reg, vte); 529 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_setzero_si128(); 530 } 531} 532 533pub fn vabs(device: &mut crate::Device, opcode: u32) { 534 let vte = vte(device, vt(opcode), ve(opcode) as usize); 535 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 536 unsafe { 537 let vs0 = _mm_cmpeq_epi16(vs_reg, _mm_setzero_si128()); 538 let slt = _mm_srai_epi16(vs_reg, 15); 539 540 let mut result = _mm_andnot_si128(vs0, vte); 541 result = _mm_xor_si128(result, slt); 542 device.rsp.cpu.accl = _mm_sub_epi16(result, slt); 543 device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_subs_epi16(result, slt); 544 } 545} 546 547pub fn vaddc(device: &mut crate::Device, opcode: u32) { 548 let vte = vte(device, vt(opcode), ve(opcode) as usize); 549 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 550 unsafe { 551 let sum = _mm_adds_epu16(vs_reg, vte); 552 device.rsp.cpu.accl = _mm_add_epi16(vs_reg, vte); 553 device.rsp.cpu.vcol = _mm_cmpeq_epi16( 554 _mm_cmpeq_epi16(sum, device.rsp.cpu.accl), 555 _mm_setzero_si128(), 556 ); 557 device.rsp.cpu.vcoh = _mm_setzero_si128(); 558 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 559 } 560} 561 562pub fn vsubc(device: &mut crate::Device, opcode: u32) { 563 let vte = vte(device, vt(opcode), ve(opcode) as usize); 564 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 565 unsafe { 566 let udiff = _mm_subs_epu16(vs_reg, vte); 567 let equal = _mm_cmpeq_epi16(vs_reg, vte); 568 let diff0 = _mm_cmpeq_epi16(udiff, _mm_setzero_si128()); 569 570 device.rsp.cpu.vcoh = _mm_cmpeq_epi16(equal, _mm_setzero_si128()); 571 device.rsp.cpu.vcol = _mm_andnot_si128(equal, diff0); 572 device.rsp.cpu.accl = _mm_sub_epi16(vs_reg, vte); 573 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 574 } 575} 576 577pub fn vsar(device: &mut crate::Device, opcode: u32) { 578 let vd_reg = &mut device.rsp.cpu.vpr[vd(opcode) as usize]; 579 match ve(opcode) { 580 0x8 => { 581 *vd_reg = device.rsp.cpu.acch; 582 } 583 0x9 => { 584 *vd_reg = device.rsp.cpu.accm; 585 } 586 0xa => { 587 *vd_reg = device.rsp.cpu.accl; 588 } 589 _ => { 590 *vd_reg = unsafe { _mm_setzero_si128() }; 591 } 592 } 593} 594 595pub fn vlt(device: &mut crate::Device, opcode: u32) { 596 let vte = vte(device, vt(opcode), ve(opcode) as usize); 597 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 598 unsafe { 599 let eq = _mm_cmpeq_epi16(vs_reg, vte); 600 let lt = _mm_cmplt_epi16(vs_reg, vte); 601 let eq_and_carry = 602 _mm_and_si128(_mm_and_si128(device.rsp.cpu.vcoh, eq), device.rsp.cpu.vcol); 603 604 device.rsp.cpu.vccl = _mm_or_si128(lt, eq_and_carry); 605 device.rsp.cpu.accl = _mm_blendv_epi8(vte, vs_reg, device.rsp.cpu.vccl); 606 607 device.rsp.cpu.vcch = _mm_setzero_si128(); 608 device.rsp.cpu.vcoh = _mm_setzero_si128(); 609 device.rsp.cpu.vcol = _mm_setzero_si128(); 610 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 611 } 612} 613 614pub fn veq(device: &mut crate::Device, opcode: u32) { 615 let vte = vte(device, vt(opcode), ve(opcode) as usize); 616 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 617 unsafe { 618 let eq = _mm_cmpeq_epi16(vs_reg, vte); 619 device.rsp.cpu.vccl = _mm_andnot_si128(device.rsp.cpu.vcoh, eq); 620 device.rsp.cpu.accl = _mm_blendv_epi8(vte, vs_reg, device.rsp.cpu.vccl); 621 622 device.rsp.cpu.vcch = _mm_setzero_si128(); 623 device.rsp.cpu.vcoh = _mm_setzero_si128(); 624 device.rsp.cpu.vcol = _mm_setzero_si128(); 625 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 626 } 627} 628 629pub fn vne(device: &mut crate::Device, opcode: u32) { 630 let vte = vte(device, vt(opcode), ve(opcode) as usize); 631 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 632 unsafe { 633 let eq = _mm_cmpeq_epi16(vs_reg, vte); 634 let ne = _mm_cmpeq_epi16(eq, _mm_setzero_si128()); 635 device.rsp.cpu.vccl = _mm_or_si128(_mm_and_si128(device.rsp.cpu.vcoh, eq), ne); 636 device.rsp.cpu.accl = _mm_blendv_epi8(vte, vs_reg, device.rsp.cpu.vccl); 637 638 device.rsp.cpu.vcch = _mm_setzero_si128(); 639 device.rsp.cpu.vcoh = _mm_setzero_si128(); 640 device.rsp.cpu.vcol = _mm_setzero_si128(); 641 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 642 } 643} 644 645pub fn vge(device: &mut crate::Device, opcode: u32) { 646 let vte = vte(device, vt(opcode), ve(opcode) as usize); 647 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 648 unsafe { 649 let eq = _mm_cmpeq_epi16(vs_reg, vte); 650 let gt = _mm_cmpgt_epi16(vs_reg, vte); 651 let es = _mm_and_si128(device.rsp.cpu.vcoh, device.rsp.cpu.vcol); 652 let eq_filtered = _mm_andnot_si128(es, eq); 653 654 device.rsp.cpu.vccl = _mm_or_si128(gt, eq_filtered); 655 device.rsp.cpu.accl = _mm_blendv_epi8(vte, vs_reg, device.rsp.cpu.vccl); 656 657 device.rsp.cpu.vcch = _mm_setzero_si128(); 658 device.rsp.cpu.vcoh = _mm_setzero_si128(); 659 device.rsp.cpu.vcol = _mm_setzero_si128(); 660 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 661 } 662} 663 664pub fn vcl(device: &mut crate::Device, opcode: u32) { 665 let vte = vte(device, vt(opcode), ve(opcode) as usize); 666 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 667 unsafe { 668 let mut nvt = _mm_xor_si128(vte, device.rsp.cpu.vcol); 669 nvt = _mm_sub_epi16(nvt, device.rsp.cpu.vcol); 670 let diff = _mm_sub_epi16(vs_reg, nvt); 671 672 let ncarry = _mm_cmpeq_epi16(diff, _mm_adds_epu16(vs_reg, vte)); 673 let nvce = _mm_cmpeq_epi16(device.rsp.cpu.vce, _mm_setzero_si128()); 674 let diff0 = _mm_cmpeq_epi16(diff, _mm_setzero_si128()); 675 676 let lec1 = _mm_and_si128(_mm_and_si128(diff0, ncarry), nvce); 677 let lec2 = _mm_and_si128(_mm_or_si128(diff0, ncarry), device.rsp.cpu.vce); 678 let leeq = _mm_or_si128(lec1, lec2); 679 680 let geeq = _mm_cmpeq_epi16(_mm_subs_epu16(vte, vs_reg), _mm_setzero_si128()); 681 682 let le_sel = _mm_andnot_si128(device.rsp.cpu.vcoh, device.rsp.cpu.vcol); 683 let le = _mm_blendv_epi8(device.rsp.cpu.vccl, leeq, le_sel); 684 685 let ge_sel = _mm_or_si128(device.rsp.cpu.vcol, device.rsp.cpu.vcoh); 686 let ge = _mm_blendv_epi8(geeq, device.rsp.cpu.vcch, ge_sel); 687 688 let mask = _mm_blendv_epi8(ge, le, device.rsp.cpu.vcol); 689 device.rsp.cpu.accl = _mm_blendv_epi8(vs_reg, nvt, mask); 690 691 device.rsp.cpu.vcch = ge; 692 device.rsp.cpu.vccl = le; 693 device.rsp.cpu.vcoh = _mm_setzero_si128(); 694 device.rsp.cpu.vcol = _mm_setzero_si128(); 695 device.rsp.cpu.vce = _mm_setzero_si128(); 696 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 697 } 698} 699 700pub fn vch(device: &mut crate::Device, opcode: u32) { 701 let vte = vte(device, vt(opcode), ve(opcode) as usize); 702 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 703 unsafe { 704 device.rsp.cpu.vcol = _mm_cmplt_epi16(_mm_xor_si128(vs_reg, vte), _mm_setzero_si128()); 705 706 let mut nvt = _mm_xor_si128(vte, device.rsp.cpu.vcol); 707 nvt = _mm_sub_epi16(nvt, device.rsp.cpu.vcol); 708 let diff = _mm_sub_epi16(vs_reg, nvt); 709 let diff0 = _mm_cmpeq_epi16(diff, _mm_setzero_si128()); 710 let vtn = _mm_cmplt_epi16(vte, _mm_setzero_si128()); 711 712 let dlez = _mm_cmpeq_epi16( 713 _mm_setzero_si128(), 714 _mm_cmpgt_epi16(diff, _mm_setzero_si128()), 715 ); 716 let dgez = _mm_or_si128(_mm_cmpgt_epi16(diff, _mm_setzero_si128()), diff0); 717 718 device.rsp.cpu.vcch = _mm_blendv_epi8(dgez, vtn, device.rsp.cpu.vcol); 719 device.rsp.cpu.vccl = _mm_blendv_epi8(vtn, dlez, device.rsp.cpu.vcol); 720 device.rsp.cpu.vce = _mm_and_si128( 721 _mm_cmpeq_epi16(diff, device.rsp.cpu.vcol), 722 device.rsp.cpu.vcol, 723 ); 724 device.rsp.cpu.vcoh = 725 _mm_cmpeq_epi16(_mm_or_si128(diff0, device.rsp.cpu.vce), _mm_setzero_si128()); 726 727 let mask = _mm_blendv_epi8( 728 device.rsp.cpu.vcch, 729 device.rsp.cpu.vccl, 730 device.rsp.cpu.vcol, 731 ); 732 device.rsp.cpu.accl = _mm_blendv_epi8(vs_reg, nvt, mask); 733 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 734 } 735} 736 737pub fn vcr(device: &mut crate::Device, opcode: u32) { 738 let vte = vte(device, vt(opcode), ve(opcode) as usize); 739 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 740 unsafe { 741 let sign = _mm_srai_epi16(_mm_xor_si128(vs_reg, vte), 15); 742 let dlez = _mm_add_epi16(_mm_and_si128(vs_reg, sign), vte); 743 device.rsp.cpu.vccl = _mm_srai_epi16(dlez, 15); 744 745 let dgez = _mm_min_epi16(_mm_or_si128(vs_reg, sign), vte); 746 device.rsp.cpu.vcch = _mm_cmpeq_epi16(dgez, vte); 747 748 let nvt = _mm_xor_si128(vte, sign); 749 let mask = _mm_blendv_epi8(device.rsp.cpu.vcch, device.rsp.cpu.vccl, sign); 750 device.rsp.cpu.accl = _mm_blendv_epi8(vs_reg, nvt, mask); 751 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 752 753 device.rsp.cpu.vcol = _mm_setzero_si128(); 754 device.rsp.cpu.vcoh = _mm_setzero_si128(); 755 device.rsp.cpu.vce = _mm_setzero_si128(); 756 } 757} 758 759pub fn vmrg(device: &mut crate::Device, opcode: u32) { 760 let vte = vte(device, vt(opcode), ve(opcode) as usize); 761 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 762 unsafe { 763 device.rsp.cpu.accl = _mm_blendv_epi8(vte, vs_reg, device.rsp.cpu.vccl); 764 device.rsp.cpu.vcoh = _mm_setzero_si128(); 765 device.rsp.cpu.vcol = _mm_setzero_si128(); 766 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 767 } 768} 769 770pub fn vand(device: &mut crate::Device, opcode: u32) { 771 let vte = vte(device, vt(opcode), ve(opcode) as usize); 772 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 773 unsafe { 774 device.rsp.cpu.accl = _mm_and_si128(vs_reg, vte); 775 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 776 } 777} 778 779pub fn vnand(device: &mut crate::Device, opcode: u32) { 780 let vte = vte(device, vt(opcode), ve(opcode) as usize); 781 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 782 unsafe { 783 let and_result = _mm_and_si128(vs_reg, vte); 784 device.rsp.cpu.accl = _mm_xor_si128(and_result, _mm_set1_epi32(-1)); 785 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 786 } 787} 788 789pub fn vor(device: &mut crate::Device, opcode: u32) { 790 let vte = vte(device, vt(opcode), ve(opcode) as usize); 791 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 792 unsafe { 793 device.rsp.cpu.accl = _mm_or_si128(vs_reg, vte); 794 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 795 } 796} 797 798pub fn vnor(device: &mut crate::Device, opcode: u32) { 799 let vte = vte(device, vt(opcode), ve(opcode) as usize); 800 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 801 unsafe { 802 let or_result = _mm_or_si128(vs_reg, vte); 803 device.rsp.cpu.accl = _mm_xor_si128(or_result, _mm_set1_epi32(-1)); 804 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 805 } 806} 807 808pub fn vxor(device: &mut crate::Device, opcode: u32) { 809 let vte = vte(device, vt(opcode), ve(opcode) as usize); 810 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 811 unsafe { 812 device.rsp.cpu.accl = _mm_xor_si128(vs_reg, vte); 813 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 814 } 815} 816 817pub fn vnxor(device: &mut crate::Device, opcode: u32) { 818 let vte = vte(device, vt(opcode), ve(opcode) as usize); 819 let vs_reg = device.rsp.cpu.vpr[vs(opcode) as usize]; 820 unsafe { 821 let xor_result = _mm_xor_si128(vs_reg, vte); 822 device.rsp.cpu.accl = _mm_xor_si128(xor_result, _mm_set1_epi32(-1)); 823 device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl; 824 } 825} 826 827pub fn vrcp(device: &mut crate::Device, opcode: u32) { 828 let vte = vte(device, vt(opcode), ve(opcode) as usize); 829 let input = get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32; 830 let result = compute_reciprocal(input, &device.rsp.cpu.reciprocals); 831 832 device.rsp.cpu.divdp = false; 833 device.rsp.cpu.divout = (result >> 16) as i16; 834 device.rsp.cpu.accl = vte; 835 modify_vpr16( 836 &mut device.rsp.cpu.vpr[vd(opcode) as usize], 837 de(opcode) as u8, 838 result as u16, 839 ); 840} 841 842pub fn vrcpl(device: &mut crate::Device, opcode: u32) { 843 let vte = vte(device, vt(opcode), ve(opcode) as usize); 844 let input = if device.rsp.cpu.divdp { 845 ((device.rsp.cpu.divin as i32) << 16) 846 | get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as u16 as i32 847 } else { 848 get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32 849 }; 850 let result = compute_reciprocal(input, &device.rsp.cpu.reciprocals); 851 852 device.rsp.cpu.divdp = false; 853 device.rsp.cpu.divout = (result >> 16) as i16; 854 device.rsp.cpu.accl = vte; 855 modify_vpr16( 856 &mut device.rsp.cpu.vpr[vd(opcode) as usize], 857 de(opcode) as u8, 858 result as u16, 859 ); 860} 861 862pub fn vrcph(device: &mut crate::Device, opcode: u32) { 863 let vte = vte(device, vt(opcode), ve(opcode) as usize); 864 let vt_reg = device.rsp.cpu.vpr[vt(opcode) as usize]; 865 let vd_reg = &mut device.rsp.cpu.vpr[vd(opcode) as usize]; 866 867 device.rsp.cpu.accl = vte; 868 device.rsp.cpu.divdp = true; 869 device.rsp.cpu.divin = get_vpr16(vt_reg, ve(opcode) as u8) as i16; 870 871 modify_vpr16(vd_reg, de(opcode) as u8, device.rsp.cpu.divout as u16); 872} 873 874pub fn vmov(device: &mut crate::Device, opcode: u32) { 875 let vte = vte(device, vt(opcode), ve(opcode) as usize); 876 let vd_reg = &mut device.rsp.cpu.vpr[vd(opcode) as usize]; 877 let de_index = de(opcode) as u8; 878 879 let value = get_vpr16(vte, de_index); 880 modify_vpr16(vd_reg, de_index, value); 881 device.rsp.cpu.accl = vte; 882} 883 884pub fn vrsq(device: &mut crate::Device, opcode: u32) { 885 let vte = vte(device, vt(opcode), ve(opcode) as usize); 886 let input = get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32; 887 let result = compute_inverse_sqrt(input, &device.rsp.cpu.inverse_square_roots); 888 889 device.rsp.cpu.divdp = false; 890 device.rsp.cpu.divout = (result >> 16) as i16; 891 device.rsp.cpu.accl = vte; 892 modify_vpr16( 893 &mut device.rsp.cpu.vpr[vd(opcode) as usize], 894 de(opcode) as u8, 895 result as u16, 896 ); 897} 898 899pub fn vrsql(device: &mut crate::Device, opcode: u32) { 900 let vte = vte(device, vt(opcode), ve(opcode) as usize); 901 let input = if device.rsp.cpu.divdp { 902 ((device.rsp.cpu.divin as i32) << 16) 903 | get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as u16 as i32 904 } else { 905 get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32 906 }; 907 let result = compute_inverse_sqrt(input, &device.rsp.cpu.inverse_square_roots); 908 909 device.rsp.cpu.divdp = false; 910 device.rsp.cpu.divout = (result >> 16) as i16; 911 device.rsp.cpu.accl = vte; 912 modify_vpr16( 913 &mut device.rsp.cpu.vpr[vd(opcode) as usize], 914 de(opcode) as u8, 915 result as u16, 916 ); 917} 918 919pub fn vrsqh(device: &mut crate::Device, opcode: u32) { 920 let vte = vte(device, vt(opcode), ve(opcode) as usize); 921 let vt_reg = device.rsp.cpu.vpr[vt(opcode) as usize]; 922 let vd_reg = &mut device.rsp.cpu.vpr[vd(opcode) as usize]; 923 924 device.rsp.cpu.accl = vte; 925 device.rsp.cpu.divdp = true; 926 device.rsp.cpu.divin = get_vpr16(vt_reg, ve(opcode) as u8) as i16; 927 928 modify_vpr16(vd_reg, de(opcode) as u8, device.rsp.cpu.divout as u16); 929} 930 931pub fn vnop(_device: &mut crate::Device, _opcode: u32) {} 932 933pub fn execute_vec(device: &mut crate::Device, opcode: u32) { 934 device.rsp.cpu.instruction_type = crate::cpu::InstructionType::Vu; 935 device.rsp.cpu.vec_instrs[(opcode & 0x3F) as usize](device, opcode) 936} 937 938pub fn reserved(_device: &mut crate::Device, _opcode: u32) { 939 panic!("rsp vu reserved") 940}