1 /* 2 * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 #include "qemu/osdep.h" 18 #include "cpu.h" 19 #include "qemu/host-utils.h" 20 #include "exec/helper-proto.h" 21 #include "exec/exec-all.h" 22 #include "exec/cpu_ldst.h" 23 #include <zlib.h> /* for crc32 */ 24 25 26 /* Exception helpers */ 27 28 static void QEMU_NORETURN 29 raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin, 30 uintptr_t pc, uint32_t fcd_pc) 31 { 32 CPUState *cs = env_cpu(env); 33 /* in case we come from a helper-call we need to restore the PC */ 34 cpu_restore_state(cs, pc, true); 35 36 /* Tin is loaded into d[15] */ 37 env->gpr_d[15] = tin; 38 39 if (class == TRAPC_CTX_MNG && tin == TIN3_FCU) { 40 /* upper context cannot be saved, if the context list is empty */ 41 } else { 42 helper_svucx(env); 43 } 44 45 /* The return address in a[11] is updated */ 46 if (class == TRAPC_CTX_MNG && tin == TIN3_FCD) { 47 env->SYSCON |= MASK_SYSCON_FCD_SF; 48 /* when we run out of CSAs after saving a context a FCD trap is taken 49 and the return address is the start of the trap handler which used 50 the last CSA */ 51 env->gpr_a[11] = fcd_pc; 52 } else if (class == TRAPC_SYSCALL) { 53 env->gpr_a[11] = env->PC + 4; 54 } else { 55 env->gpr_a[11] = env->PC; 56 } 57 /* The stack pointer in A[10] is set to the Interrupt Stack Pointer (ISP) 58 when the processor was not previously using the interrupt stack 59 (in case of PSW.IS = 0). The stack pointer bit is set for using the 60 interrupt stack: PSW.IS = 1. */ 61 if ((env->PSW & MASK_PSW_IS) == 0) { 62 env->gpr_a[10] = env->ISP; 63 } 64 env->PSW |= MASK_PSW_IS; 65 /* The I/O mode is set to Supervisor mode, which means all permissions 66 are enabled: PSW.IO = 10 B .*/ 67 env->PSW |= (2 << 10); 68 69 /*The current Protection Register Set is set to 0: PSW.PRS = 00 B .*/ 70 env->PSW &= ~MASK_PSW_PRS; 71 72 /* The Call Depth Counter (CDC) is cleared, and the call depth limit is 73 set for 64: PSW.CDC = 0000000 B .*/ 74 env->PSW &= ~MASK_PSW_CDC; 75 76 /* Call Depth Counter is enabled, PSW.CDE = 1. */ 77 env->PSW |= MASK_PSW_CDE; 78 79 /* Write permission to global registers A[0], A[1], A[8], A[9] is 80 disabled: PSW.GW = 0. */ 81 env->PSW &= ~MASK_PSW_GW; 82 83 /*The interrupt system is globally disabled: ICR.IE = 0. The ‘old’ 84 ICR.IE and ICR.CCPN are saved */ 85 86 /* PCXI.PIE = ICR.IE */ 87 env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE_1_3) + 88 ((env->ICR & MASK_ICR_IE_1_3) << 15)); 89 /* PCXI.PCPN = ICR.CCPN */ 90 env->PCXI = (env->PCXI & 0xffffff) + 91 ((env->ICR & MASK_ICR_CCPN) << 24); 92 /* Update PC using the trap vector table */ 93 env->PC = env->BTV | (class << 5); 94 95 cpu_loop_exit(cs); 96 } 97 98 void helper_raise_exception_sync(CPUTriCoreState *env, uint32_t class, 99 uint32_t tin) 100 { 101 raise_exception_sync_internal(env, class, tin, 0, 0); 102 } 103 104 static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class, 105 uint32_t tin, uintptr_t pc) 106 { 107 raise_exception_sync_internal(env, class, tin, pc, 0); 108 } 109 110 void helper_qemu_excp(CPUTriCoreState *env, uint32_t excp) 111 { 112 CPUState *cs = env_cpu(env); 113 cs->exception_index = excp; 114 cpu_loop_exit(cs); 115 } 116 117 /* Addressing mode helper */ 118 119 static uint16_t reverse16(uint16_t val) 120 { 121 uint8_t high = (uint8_t)(val >> 8); 122 uint8_t low = (uint8_t)(val & 0xff); 123 124 uint16_t rh, rl; 125 126 rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023); 127 rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023); 128 129 return (rh << 8) | rl; 130 } 131 132 uint32_t helper_br_update(uint32_t reg) 133 { 134 uint32_t index = reg & 0xffff; 135 uint32_t incr = reg >> 16; 136 uint32_t new_index = reverse16(reverse16(index) + reverse16(incr)); 137 return reg - index + new_index; 138 } 139 140 uint32_t helper_circ_update(uint32_t reg, uint32_t off) 141 { 142 uint32_t index = reg & 0xffff; 143 uint32_t length = reg >> 16; 144 int32_t new_index = index + off; 145 if (new_index < 0) { 146 new_index += length; 147 } else { 148 new_index %= length; 149 } 150 return reg - index + new_index; 151 } 152 153 static uint32_t ssov32(CPUTriCoreState *env, int64_t arg) 154 { 155 uint32_t ret; 156 int64_t max_pos = INT32_MAX; 157 int64_t max_neg = INT32_MIN; 158 if (arg > max_pos) { 159 env->PSW_USB_V = (1 << 31); 160 env->PSW_USB_SV = (1 << 31); 161 ret = (target_ulong)max_pos; 162 } else { 163 if (arg < max_neg) { 164 env->PSW_USB_V = (1 << 31); 165 env->PSW_USB_SV = (1 << 31); 166 ret = (target_ulong)max_neg; 167 } else { 168 env->PSW_USB_V = 0; 169 ret = (target_ulong)arg; 170 } 171 } 172 env->PSW_USB_AV = arg ^ arg * 2u; 173 env->PSW_USB_SAV |= env->PSW_USB_AV; 174 return ret; 175 } 176 177 static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg) 178 { 179 uint32_t ret; 180 uint64_t max_pos = UINT32_MAX; 181 if (arg > max_pos) { 182 env->PSW_USB_V = (1 << 31); 183 env->PSW_USB_SV = (1 << 31); 184 ret = (target_ulong)max_pos; 185 } else { 186 env->PSW_USB_V = 0; 187 ret = (target_ulong)arg; 188 } 189 env->PSW_USB_AV = arg ^ arg * 2u; 190 env->PSW_USB_SAV |= env->PSW_USB_AV; 191 return ret; 192 } 193 194 static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg) 195 { 196 uint32_t ret; 197 198 if (arg < 0) { 199 env->PSW_USB_V = (1 << 31); 200 env->PSW_USB_SV = (1 << 31); 201 ret = 0; 202 } else { 203 env->PSW_USB_V = 0; 204 ret = (target_ulong)arg; 205 } 206 env->PSW_USB_AV = arg ^ arg * 2u; 207 env->PSW_USB_SAV |= env->PSW_USB_AV; 208 return ret; 209 } 210 211 static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1) 212 { 213 int32_t max_pos = INT16_MAX; 214 int32_t max_neg = INT16_MIN; 215 int32_t av0, av1; 216 217 env->PSW_USB_V = 0; 218 av0 = hw0 ^ hw0 * 2u; 219 if (hw0 > max_pos) { 220 env->PSW_USB_V = (1 << 31); 221 hw0 = max_pos; 222 } else if (hw0 < max_neg) { 223 env->PSW_USB_V = (1 << 31); 224 hw0 = max_neg; 225 } 226 227 av1 = hw1 ^ hw1 * 2u; 228 if (hw1 > max_pos) { 229 env->PSW_USB_V = (1 << 31); 230 hw1 = max_pos; 231 } else if (hw1 < max_neg) { 232 env->PSW_USB_V = (1 << 31); 233 hw1 = max_neg; 234 } 235 236 env->PSW_USB_SV |= env->PSW_USB_V; 237 env->PSW_USB_AV = (av0 | av1) << 16; 238 env->PSW_USB_SAV |= env->PSW_USB_AV; 239 return (hw0 & 0xffff) | (hw1 << 16); 240 } 241 242 static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1) 243 { 244 int32_t max_pos = UINT16_MAX; 245 int32_t av0, av1; 246 247 env->PSW_USB_V = 0; 248 av0 = hw0 ^ hw0 * 2u; 249 if (hw0 > max_pos) { 250 env->PSW_USB_V = (1 << 31); 251 hw0 = max_pos; 252 } else if (hw0 < 0) { 253 env->PSW_USB_V = (1 << 31); 254 hw0 = 0; 255 } 256 257 av1 = hw1 ^ hw1 * 2u; 258 if (hw1 > max_pos) { 259 env->PSW_USB_V = (1 << 31); 260 hw1 = max_pos; 261 } else if (hw1 < 0) { 262 env->PSW_USB_V = (1 << 31); 263 hw1 = 0; 264 } 265 266 env->PSW_USB_SV |= env->PSW_USB_V; 267 env->PSW_USB_AV = (av0 | av1) << 16; 268 env->PSW_USB_SAV |= env->PSW_USB_AV; 269 return (hw0 & 0xffff) | (hw1 << 16); 270 } 271 272 target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1, 273 target_ulong r2) 274 { 275 int64_t t1 = sextract64(r1, 0, 32); 276 int64_t t2 = sextract64(r2, 0, 32); 277 int64_t result = t1 + t2; 278 return ssov32(env, result); 279 } 280 281 uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 282 { 283 uint64_t result; 284 int64_t ovf; 285 286 result = r1 + r2; 287 ovf = (result ^ r1) & ~(r1 ^ r2); 288 env->PSW_USB_AV = (result ^ result * 2u) >> 32; 289 env->PSW_USB_SAV |= env->PSW_USB_AV; 290 if (ovf < 0) { 291 env->PSW_USB_V = (1 << 31); 292 env->PSW_USB_SV = (1 << 31); 293 /* ext_ret > MAX_INT */ 294 if ((int64_t)r1 >= 0) { 295 result = INT64_MAX; 296 /* ext_ret < MIN_INT */ 297 } else { 298 result = INT64_MIN; 299 } 300 } else { 301 env->PSW_USB_V = 0; 302 } 303 return result; 304 } 305 306 target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1, 307 target_ulong r2) 308 { 309 int32_t ret_hw0, ret_hw1; 310 311 ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16); 312 ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16); 313 return ssov16(env, ret_hw0, ret_hw1); 314 } 315 316 uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 317 uint32_t r2_h) 318 { 319 int64_t mul_res0 = sextract64(r1, 0, 32); 320 int64_t mul_res1 = sextract64(r1, 32, 32); 321 int64_t r2_low = sextract64(r2_l, 0, 32); 322 int64_t r2_high = sextract64(r2_h, 0, 32); 323 int64_t result0, result1; 324 uint32_t ovf0, ovf1; 325 uint32_t avf0, avf1; 326 327 ovf0 = ovf1 = 0; 328 329 result0 = r2_low + mul_res0 + 0x8000; 330 result1 = r2_high + mul_res1 + 0x8000; 331 332 avf0 = result0 * 2u; 333 avf0 = result0 ^ avf0; 334 avf1 = result1 * 2u; 335 avf1 = result1 ^ avf1; 336 337 if (result0 > INT32_MAX) { 338 ovf0 = (1 << 31); 339 result0 = INT32_MAX; 340 } else if (result0 < INT32_MIN) { 341 ovf0 = (1 << 31); 342 result0 = INT32_MIN; 343 } 344 345 if (result1 > INT32_MAX) { 346 ovf1 = (1 << 31); 347 result1 = INT32_MAX; 348 } else if (result1 < INT32_MIN) { 349 ovf1 = (1 << 31); 350 result1 = INT32_MIN; 351 } 352 353 env->PSW_USB_V = ovf0 | ovf1; 354 env->PSW_USB_SV |= env->PSW_USB_V; 355 356 env->PSW_USB_AV = avf0 | avf1; 357 env->PSW_USB_SAV |= env->PSW_USB_AV; 358 359 return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 360 } 361 362 uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 363 uint32_t r2_h) 364 { 365 int64_t mul_res0 = sextract64(r1, 0, 32); 366 int64_t mul_res1 = sextract64(r1, 32, 32); 367 int64_t r2_low = sextract64(r2_l, 0, 32); 368 int64_t r2_high = sextract64(r2_h, 0, 32); 369 int64_t result0, result1; 370 uint32_t ovf0, ovf1; 371 uint32_t avf0, avf1; 372 373 ovf0 = ovf1 = 0; 374 375 result0 = r2_low - mul_res0 + 0x8000; 376 result1 = r2_high + mul_res1 + 0x8000; 377 378 avf0 = result0 * 2u; 379 avf0 = result0 ^ avf0; 380 avf1 = result1 * 2u; 381 avf1 = result1 ^ avf1; 382 383 if (result0 > INT32_MAX) { 384 ovf0 = (1 << 31); 385 result0 = INT32_MAX; 386 } else if (result0 < INT32_MIN) { 387 ovf0 = (1 << 31); 388 result0 = INT32_MIN; 389 } 390 391 if (result1 > INT32_MAX) { 392 ovf1 = (1 << 31); 393 result1 = INT32_MAX; 394 } else if (result1 < INT32_MIN) { 395 ovf1 = (1 << 31); 396 result1 = INT32_MIN; 397 } 398 399 env->PSW_USB_V = ovf0 | ovf1; 400 env->PSW_USB_SV |= env->PSW_USB_V; 401 402 env->PSW_USB_AV = avf0 | avf1; 403 env->PSW_USB_SAV |= env->PSW_USB_AV; 404 405 return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 406 } 407 408 409 target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1, 410 target_ulong r2) 411 { 412 int64_t t1 = extract64(r1, 0, 32); 413 int64_t t2 = extract64(r2, 0, 32); 414 int64_t result = t1 + t2; 415 return suov32_pos(env, result); 416 } 417 418 target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1, 419 target_ulong r2) 420 { 421 int32_t ret_hw0, ret_hw1; 422 423 ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16); 424 ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16); 425 return suov16(env, ret_hw0, ret_hw1); 426 } 427 428 target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1, 429 target_ulong r2) 430 { 431 int64_t t1 = sextract64(r1, 0, 32); 432 int64_t t2 = sextract64(r2, 0, 32); 433 int64_t result = t1 - t2; 434 return ssov32(env, result); 435 } 436 437 uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 438 { 439 uint64_t result; 440 int64_t ovf; 441 442 result = r1 - r2; 443 ovf = (result ^ r1) & (r1 ^ r2); 444 env->PSW_USB_AV = (result ^ result * 2u) >> 32; 445 env->PSW_USB_SAV |= env->PSW_USB_AV; 446 if (ovf < 0) { 447 env->PSW_USB_V = (1 << 31); 448 env->PSW_USB_SV = (1 << 31); 449 /* ext_ret > MAX_INT */ 450 if ((int64_t)r1 >= 0) { 451 result = INT64_MAX; 452 /* ext_ret < MIN_INT */ 453 } else { 454 result = INT64_MIN; 455 } 456 } else { 457 env->PSW_USB_V = 0; 458 } 459 return result; 460 } 461 462 target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1, 463 target_ulong r2) 464 { 465 int32_t ret_hw0, ret_hw1; 466 467 ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16); 468 ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16); 469 return ssov16(env, ret_hw0, ret_hw1); 470 } 471 472 uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 473 uint32_t r2_h) 474 { 475 int64_t mul_res0 = sextract64(r1, 0, 32); 476 int64_t mul_res1 = sextract64(r1, 32, 32); 477 int64_t r2_low = sextract64(r2_l, 0, 32); 478 int64_t r2_high = sextract64(r2_h, 0, 32); 479 int64_t result0, result1; 480 uint32_t ovf0, ovf1; 481 uint32_t avf0, avf1; 482 483 ovf0 = ovf1 = 0; 484 485 result0 = r2_low - mul_res0 + 0x8000; 486 result1 = r2_high - mul_res1 + 0x8000; 487 488 avf0 = result0 * 2u; 489 avf0 = result0 ^ avf0; 490 avf1 = result1 * 2u; 491 avf1 = result1 ^ avf1; 492 493 if (result0 > INT32_MAX) { 494 ovf0 = (1 << 31); 495 result0 = INT32_MAX; 496 } else if (result0 < INT32_MIN) { 497 ovf0 = (1 << 31); 498 result0 = INT32_MIN; 499 } 500 501 if (result1 > INT32_MAX) { 502 ovf1 = (1 << 31); 503 result1 = INT32_MAX; 504 } else if (result1 < INT32_MIN) { 505 ovf1 = (1 << 31); 506 result1 = INT32_MIN; 507 } 508 509 env->PSW_USB_V = ovf0 | ovf1; 510 env->PSW_USB_SV |= env->PSW_USB_V; 511 512 env->PSW_USB_AV = avf0 | avf1; 513 env->PSW_USB_SAV |= env->PSW_USB_AV; 514 515 return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 516 } 517 518 uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 519 uint32_t r2_h) 520 { 521 int64_t mul_res0 = sextract64(r1, 0, 32); 522 int64_t mul_res1 = sextract64(r1, 32, 32); 523 int64_t r2_low = sextract64(r2_l, 0, 32); 524 int64_t r2_high = sextract64(r2_h, 0, 32); 525 int64_t result0, result1; 526 uint32_t ovf0, ovf1; 527 uint32_t avf0, avf1; 528 529 ovf0 = ovf1 = 0; 530 531 result0 = r2_low + mul_res0 + 0x8000; 532 result1 = r2_high - mul_res1 + 0x8000; 533 534 avf0 = result0 * 2u; 535 avf0 = result0 ^ avf0; 536 avf1 = result1 * 2u; 537 avf1 = result1 ^ avf1; 538 539 if (result0 > INT32_MAX) { 540 ovf0 = (1 << 31); 541 result0 = INT32_MAX; 542 } else if (result0 < INT32_MIN) { 543 ovf0 = (1 << 31); 544 result0 = INT32_MIN; 545 } 546 547 if (result1 > INT32_MAX) { 548 ovf1 = (1 << 31); 549 result1 = INT32_MAX; 550 } else if (result1 < INT32_MIN) { 551 ovf1 = (1 << 31); 552 result1 = INT32_MIN; 553 } 554 555 env->PSW_USB_V = ovf0 | ovf1; 556 env->PSW_USB_SV |= env->PSW_USB_V; 557 558 env->PSW_USB_AV = avf0 | avf1; 559 env->PSW_USB_SAV |= env->PSW_USB_AV; 560 561 return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 562 } 563 564 target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1, 565 target_ulong r2) 566 { 567 int64_t t1 = extract64(r1, 0, 32); 568 int64_t t2 = extract64(r2, 0, 32); 569 int64_t result = t1 - t2; 570 return suov32_neg(env, result); 571 } 572 573 target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1, 574 target_ulong r2) 575 { 576 int32_t ret_hw0, ret_hw1; 577 578 ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16); 579 ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16); 580 return suov16(env, ret_hw0, ret_hw1); 581 } 582 583 target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1, 584 target_ulong r2) 585 { 586 int64_t t1 = sextract64(r1, 0, 32); 587 int64_t t2 = sextract64(r2, 0, 32); 588 int64_t result = t1 * t2; 589 return ssov32(env, result); 590 } 591 592 target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1, 593 target_ulong r2) 594 { 595 int64_t t1 = extract64(r1, 0, 32); 596 int64_t t2 = extract64(r2, 0, 32); 597 int64_t result = t1 * t2; 598 599 return suov32_pos(env, result); 600 } 601 602 target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1, 603 target_ulong r2) 604 { 605 int64_t t1 = sextract64(r1, 0, 32); 606 int32_t t2 = sextract64(r2, 0, 6); 607 int64_t result; 608 if (t2 == 0) { 609 result = t1; 610 } else if (t2 > 0) { 611 result = t1 << t2; 612 } else { 613 result = t1 >> -t2; 614 } 615 return ssov32(env, result); 616 } 617 618 uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1) 619 { 620 target_ulong result; 621 result = ((int32_t)r1 >= 0) ? r1 : (0 - r1); 622 return ssov32(env, result); 623 } 624 625 uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1) 626 { 627 int32_t ret_h0, ret_h1; 628 629 ret_h0 = sextract32(r1, 0, 16); 630 ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0); 631 632 ret_h1 = sextract32(r1, 16, 16); 633 ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1); 634 635 return ssov16(env, ret_h0, ret_h1); 636 } 637 638 target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1, 639 target_ulong r2) 640 { 641 int64_t t1 = sextract64(r1, 0, 32); 642 int64_t t2 = sextract64(r2, 0, 32); 643 int64_t result; 644 645 if (t1 > t2) { 646 result = t1 - t2; 647 } else { 648 result = t2 - t1; 649 } 650 return ssov32(env, result); 651 } 652 653 uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1, 654 target_ulong r2) 655 { 656 int32_t t1, t2; 657 int32_t ret_h0, ret_h1; 658 659 t1 = sextract32(r1, 0, 16); 660 t2 = sextract32(r2, 0, 16); 661 if (t1 > t2) { 662 ret_h0 = t1 - t2; 663 } else { 664 ret_h0 = t2 - t1; 665 } 666 667 t1 = sextract32(r1, 16, 16); 668 t2 = sextract32(r2, 16, 16); 669 if (t1 > t2) { 670 ret_h1 = t1 - t2; 671 } else { 672 ret_h1 = t2 - t1; 673 } 674 675 return ssov16(env, ret_h0, ret_h1); 676 } 677 678 target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1, 679 target_ulong r2, target_ulong r3) 680 { 681 int64_t t1 = sextract64(r1, 0, 32); 682 int64_t t2 = sextract64(r2, 0, 32); 683 int64_t t3 = sextract64(r3, 0, 32); 684 int64_t result; 685 686 result = t2 + (t1 * t3); 687 return ssov32(env, result); 688 } 689 690 target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1, 691 target_ulong r2, target_ulong r3) 692 { 693 uint64_t t1 = extract64(r1, 0, 32); 694 uint64_t t2 = extract64(r2, 0, 32); 695 uint64_t t3 = extract64(r3, 0, 32); 696 int64_t result; 697 698 result = t2 + (t1 * t3); 699 return suov32_pos(env, result); 700 } 701 702 uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1, 703 uint64_t r2, target_ulong r3) 704 { 705 uint64_t ret, ovf; 706 int64_t t1 = sextract64(r1, 0, 32); 707 int64_t t3 = sextract64(r3, 0, 32); 708 int64_t mul; 709 710 mul = t1 * t3; 711 ret = mul + r2; 712 ovf = (ret ^ mul) & ~(mul ^ r2); 713 714 t1 = ret >> 32; 715 env->PSW_USB_AV = t1 ^ t1 * 2u; 716 env->PSW_USB_SAV |= env->PSW_USB_AV; 717 718 if ((int64_t)ovf < 0) { 719 env->PSW_USB_V = (1 << 31); 720 env->PSW_USB_SV = (1 << 31); 721 /* ext_ret > MAX_INT */ 722 if (mul >= 0) { 723 ret = INT64_MAX; 724 /* ext_ret < MIN_INT */ 725 } else { 726 ret = INT64_MIN; 727 } 728 } else { 729 env->PSW_USB_V = 0; 730 } 731 732 return ret; 733 } 734 735 uint32_t 736 helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 737 { 738 int64_t result; 739 740 result = (r1 + r2); 741 742 env->PSW_USB_AV = (result ^ result * 2u); 743 env->PSW_USB_SAV |= env->PSW_USB_AV; 744 745 /* we do the saturation by hand, since we produce an overflow on the host 746 if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 747 case, we flip the saturated value. */ 748 if (r2 == 0x8000000000000000LL) { 749 if (result > 0x7fffffffLL) { 750 env->PSW_USB_V = (1 << 31); 751 env->PSW_USB_SV = (1 << 31); 752 result = INT32_MIN; 753 } else if (result < -0x80000000LL) { 754 env->PSW_USB_V = (1 << 31); 755 env->PSW_USB_SV = (1 << 31); 756 result = INT32_MAX; 757 } else { 758 env->PSW_USB_V = 0; 759 } 760 } else { 761 if (result > 0x7fffffffLL) { 762 env->PSW_USB_V = (1 << 31); 763 env->PSW_USB_SV = (1 << 31); 764 result = INT32_MAX; 765 } else if (result < -0x80000000LL) { 766 env->PSW_USB_V = (1 << 31); 767 env->PSW_USB_SV = (1 << 31); 768 result = INT32_MIN; 769 } else { 770 env->PSW_USB_V = 0; 771 } 772 } 773 return (uint32_t)result; 774 } 775 776 uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, 777 uint32_t r3, uint32_t n) 778 { 779 int64_t t1 = (int64_t)r1; 780 int64_t t2 = sextract64(r2, 0, 32); 781 int64_t t3 = sextract64(r3, 0, 32); 782 int64_t result, mul; 783 int64_t ovf; 784 785 mul = (t2 * t3) << n; 786 result = mul + t1; 787 788 env->PSW_USB_AV = (result ^ result * 2u) >> 32; 789 env->PSW_USB_SAV |= env->PSW_USB_AV; 790 791 ovf = (result ^ mul) & ~(mul ^ t1); 792 /* we do the saturation by hand, since we produce an overflow on the host 793 if the mul was (0x80000000 * 0x80000000) << 1). If this is the 794 case, we flip the saturated value. */ 795 if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) { 796 if (ovf >= 0) { 797 env->PSW_USB_V = (1 << 31); 798 env->PSW_USB_SV = (1 << 31); 799 /* ext_ret > MAX_INT */ 800 if (mul < 0) { 801 result = INT64_MAX; 802 /* ext_ret < MIN_INT */ 803 } else { 804 result = INT64_MIN; 805 } 806 } else { 807 env->PSW_USB_V = 0; 808 } 809 } else { 810 if (ovf < 0) { 811 env->PSW_USB_V = (1 << 31); 812 env->PSW_USB_SV = (1 << 31); 813 /* ext_ret > MAX_INT */ 814 if (mul >= 0) { 815 result = INT64_MAX; 816 /* ext_ret < MIN_INT */ 817 } else { 818 result = INT64_MIN; 819 } 820 } else { 821 env->PSW_USB_V = 0; 822 } 823 } 824 return (uint64_t)result; 825 } 826 827 uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 828 uint32_t r3, uint32_t n) 829 { 830 int64_t t1 = sextract64(r1, 0, 32); 831 int64_t t2 = sextract64(r2, 0, 32); 832 int64_t t3 = sextract64(r3, 0, 32); 833 int64_t mul, ret; 834 835 if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 836 mul = 0x7fffffff; 837 } else { 838 mul = (t2 * t3) << n; 839 } 840 841 ret = t1 + mul + 0x8000; 842 843 env->PSW_USB_AV = ret ^ ret * 2u; 844 env->PSW_USB_SAV |= env->PSW_USB_AV; 845 846 if (ret > 0x7fffffffll) { 847 env->PSW_USB_V = (1 << 31); 848 env->PSW_USB_SV |= env->PSW_USB_V; 849 ret = INT32_MAX; 850 } else if (ret < -0x80000000ll) { 851 env->PSW_USB_V = (1 << 31); 852 env->PSW_USB_SV |= env->PSW_USB_V; 853 ret = INT32_MIN; 854 } else { 855 env->PSW_USB_V = 0; 856 } 857 return ret & 0xffff0000ll; 858 } 859 860 uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1, 861 uint64_t r2, target_ulong r3) 862 { 863 uint64_t ret, mul; 864 uint64_t t1 = extract64(r1, 0, 32); 865 uint64_t t3 = extract64(r3, 0, 32); 866 867 mul = t1 * t3; 868 ret = mul + r2; 869 870 t1 = ret >> 32; 871 env->PSW_USB_AV = t1 ^ t1 * 2u; 872 env->PSW_USB_SAV |= env->PSW_USB_AV; 873 874 if (ret < r2) { 875 env->PSW_USB_V = (1 << 31); 876 env->PSW_USB_SV = (1 << 31); 877 /* saturate */ 878 ret = UINT64_MAX; 879 } else { 880 env->PSW_USB_V = 0; 881 } 882 return ret; 883 } 884 885 target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1, 886 target_ulong r2, target_ulong r3) 887 { 888 int64_t t1 = sextract64(r1, 0, 32); 889 int64_t t2 = sextract64(r2, 0, 32); 890 int64_t t3 = sextract64(r3, 0, 32); 891 int64_t result; 892 893 result = t2 - (t1 * t3); 894 return ssov32(env, result); 895 } 896 897 target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1, 898 target_ulong r2, target_ulong r3) 899 { 900 uint64_t t1 = extract64(r1, 0, 32); 901 uint64_t t2 = extract64(r2, 0, 32); 902 uint64_t t3 = extract64(r3, 0, 32); 903 uint64_t result; 904 uint64_t mul; 905 906 mul = (t1 * t3); 907 result = t2 - mul; 908 909 env->PSW_USB_AV = result ^ result * 2u; 910 env->PSW_USB_SAV |= env->PSW_USB_AV; 911 /* we calculate ovf by hand here, because the multiplication can overflow on 912 the host, which would give false results if we compare to less than 913 zero */ 914 if (mul > t2) { 915 env->PSW_USB_V = (1 << 31); 916 env->PSW_USB_SV = (1 << 31); 917 result = 0; 918 } else { 919 env->PSW_USB_V = 0; 920 } 921 return result; 922 } 923 924 uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1, 925 uint64_t r2, target_ulong r3) 926 { 927 uint64_t ret, ovf; 928 int64_t t1 = sextract64(r1, 0, 32); 929 int64_t t3 = sextract64(r3, 0, 32); 930 int64_t mul; 931 932 mul = t1 * t3; 933 ret = r2 - mul; 934 ovf = (ret ^ r2) & (mul ^ r2); 935 936 t1 = ret >> 32; 937 env->PSW_USB_AV = t1 ^ t1 * 2u; 938 env->PSW_USB_SAV |= env->PSW_USB_AV; 939 940 if ((int64_t)ovf < 0) { 941 env->PSW_USB_V = (1 << 31); 942 env->PSW_USB_SV = (1 << 31); 943 /* ext_ret > MAX_INT */ 944 if (mul < 0) { 945 ret = INT64_MAX; 946 /* ext_ret < MIN_INT */ 947 } else { 948 ret = INT64_MIN; 949 } 950 } else { 951 env->PSW_USB_V = 0; 952 } 953 return ret; 954 } 955 956 uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1, 957 uint64_t r2, target_ulong r3) 958 { 959 uint64_t ret, mul; 960 uint64_t t1 = extract64(r1, 0, 32); 961 uint64_t t3 = extract64(r3, 0, 32); 962 963 mul = t1 * t3; 964 ret = r2 - mul; 965 966 t1 = ret >> 32; 967 env->PSW_USB_AV = t1 ^ t1 * 2u; 968 env->PSW_USB_SAV |= env->PSW_USB_AV; 969 970 if (ret > r2) { 971 env->PSW_USB_V = (1 << 31); 972 env->PSW_USB_SV = (1 << 31); 973 /* saturate */ 974 ret = 0; 975 } else { 976 env->PSW_USB_V = 0; 977 } 978 return ret; 979 } 980 981 uint32_t 982 helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 983 { 984 int64_t result; 985 int64_t t1 = (int64_t)r1; 986 int64_t t2 = (int64_t)r2; 987 988 result = t1 - t2; 989 990 env->PSW_USB_AV = (result ^ result * 2u); 991 env->PSW_USB_SAV |= env->PSW_USB_AV; 992 993 /* we do the saturation by hand, since we produce an overflow on the host 994 if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 995 case, we flip the saturated value. */ 996 if (r2 == 0x8000000000000000LL) { 997 if (result > 0x7fffffffLL) { 998 env->PSW_USB_V = (1 << 31); 999 env->PSW_USB_SV = (1 << 31); 1000 result = INT32_MIN; 1001 } else if (result < -0x80000000LL) { 1002 env->PSW_USB_V = (1 << 31); 1003 env->PSW_USB_SV = (1 << 31); 1004 result = INT32_MAX; 1005 } else { 1006 env->PSW_USB_V = 0; 1007 } 1008 } else { 1009 if (result > 0x7fffffffLL) { 1010 env->PSW_USB_V = (1 << 31); 1011 env->PSW_USB_SV = (1 << 31); 1012 result = INT32_MAX; 1013 } else if (result < -0x80000000LL) { 1014 env->PSW_USB_V = (1 << 31); 1015 env->PSW_USB_SV = (1 << 31); 1016 result = INT32_MIN; 1017 } else { 1018 env->PSW_USB_V = 0; 1019 } 1020 } 1021 return (uint32_t)result; 1022 } 1023 1024 uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, 1025 uint32_t r3, uint32_t n) 1026 { 1027 int64_t t1 = (int64_t)r1; 1028 int64_t t2 = sextract64(r2, 0, 32); 1029 int64_t t3 = sextract64(r3, 0, 32); 1030 int64_t result, mul; 1031 int64_t ovf; 1032 1033 mul = (t2 * t3) << n; 1034 result = t1 - mul; 1035 1036 env->PSW_USB_AV = (result ^ result * 2u) >> 32; 1037 env->PSW_USB_SAV |= env->PSW_USB_AV; 1038 1039 ovf = (result ^ t1) & (t1 ^ mul); 1040 /* we do the saturation by hand, since we produce an overflow on the host 1041 if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 1042 case, we flip the saturated value. */ 1043 if (mul == 0x8000000000000000LL) { 1044 if (ovf >= 0) { 1045 env->PSW_USB_V = (1 << 31); 1046 env->PSW_USB_SV = (1 << 31); 1047 /* ext_ret > MAX_INT */ 1048 if (mul >= 0) { 1049 result = INT64_MAX; 1050 /* ext_ret < MIN_INT */ 1051 } else { 1052 result = INT64_MIN; 1053 } 1054 } else { 1055 env->PSW_USB_V = 0; 1056 } 1057 } else { 1058 if (ovf < 0) { 1059 env->PSW_USB_V = (1 << 31); 1060 env->PSW_USB_SV = (1 << 31); 1061 /* ext_ret > MAX_INT */ 1062 if (mul < 0) { 1063 result = INT64_MAX; 1064 /* ext_ret < MIN_INT */ 1065 } else { 1066 result = INT64_MIN; 1067 } 1068 } else { 1069 env->PSW_USB_V = 0; 1070 } 1071 } 1072 1073 return (uint64_t)result; 1074 } 1075 1076 uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 1077 uint32_t r3, uint32_t n) 1078 { 1079 int64_t t1 = sextract64(r1, 0, 32); 1080 int64_t t2 = sextract64(r2, 0, 32); 1081 int64_t t3 = sextract64(r3, 0, 32); 1082 int64_t mul, ret; 1083 1084 if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 1085 mul = 0x7fffffff; 1086 } else { 1087 mul = (t2 * t3) << n; 1088 } 1089 1090 ret = t1 - mul + 0x8000; 1091 1092 env->PSW_USB_AV = ret ^ ret * 2u; 1093 env->PSW_USB_SAV |= env->PSW_USB_AV; 1094 1095 if (ret > 0x7fffffffll) { 1096 env->PSW_USB_V = (1 << 31); 1097 env->PSW_USB_SV |= env->PSW_USB_V; 1098 ret = INT32_MAX; 1099 } else if (ret < -0x80000000ll) { 1100 env->PSW_USB_V = (1 << 31); 1101 env->PSW_USB_SV |= env->PSW_USB_V; 1102 ret = INT32_MIN; 1103 } else { 1104 env->PSW_USB_V = 0; 1105 } 1106 return ret & 0xffff0000ll; 1107 } 1108 1109 uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg) 1110 { 1111 int32_t b, i; 1112 int32_t ovf = 0; 1113 int32_t avf = 0; 1114 int32_t ret = 0; 1115 1116 for (i = 0; i < 4; i++) { 1117 b = sextract32(arg, i * 8, 8); 1118 b = (b >= 0) ? b : (0 - b); 1119 ovf |= (b > 0x7F) || (b < -0x80); 1120 avf |= b ^ b * 2u; 1121 ret |= (b & 0xff) << (i * 8); 1122 } 1123 1124 env->PSW_USB_V = ovf << 31; 1125 env->PSW_USB_SV |= env->PSW_USB_V; 1126 env->PSW_USB_AV = avf << 24; 1127 env->PSW_USB_SAV |= env->PSW_USB_AV; 1128 1129 return ret; 1130 } 1131 1132 uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg) 1133 { 1134 int32_t h, i; 1135 int32_t ovf = 0; 1136 int32_t avf = 0; 1137 int32_t ret = 0; 1138 1139 for (i = 0; i < 2; i++) { 1140 h = sextract32(arg, i * 16, 16); 1141 h = (h >= 0) ? h : (0 - h); 1142 ovf |= (h > 0x7FFF) || (h < -0x8000); 1143 avf |= h ^ h * 2u; 1144 ret |= (h & 0xffff) << (i * 16); 1145 } 1146 1147 env->PSW_USB_V = ovf << 31; 1148 env->PSW_USB_SV |= env->PSW_USB_V; 1149 env->PSW_USB_AV = avf << 16; 1150 env->PSW_USB_SAV |= env->PSW_USB_AV; 1151 1152 return ret; 1153 } 1154 1155 uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1156 { 1157 int32_t b, i; 1158 int32_t extr_r2; 1159 int32_t ovf = 0; 1160 int32_t avf = 0; 1161 int32_t ret = 0; 1162 1163 for (i = 0; i < 4; i++) { 1164 extr_r2 = sextract32(r2, i * 8, 8); 1165 b = sextract32(r1, i * 8, 8); 1166 b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b); 1167 ovf |= (b > 0x7F) || (b < -0x80); 1168 avf |= b ^ b * 2u; 1169 ret |= (b & 0xff) << (i * 8); 1170 } 1171 1172 env->PSW_USB_V = ovf << 31; 1173 env->PSW_USB_SV |= env->PSW_USB_V; 1174 env->PSW_USB_AV = avf << 24; 1175 env->PSW_USB_SAV |= env->PSW_USB_AV; 1176 return ret; 1177 } 1178 1179 uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1180 { 1181 int32_t h, i; 1182 int32_t extr_r2; 1183 int32_t ovf = 0; 1184 int32_t avf = 0; 1185 int32_t ret = 0; 1186 1187 for (i = 0; i < 2; i++) { 1188 extr_r2 = sextract32(r2, i * 16, 16); 1189 h = sextract32(r1, i * 16, 16); 1190 h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h); 1191 ovf |= (h > 0x7FFF) || (h < -0x8000); 1192 avf |= h ^ h * 2u; 1193 ret |= (h & 0xffff) << (i * 16); 1194 } 1195 1196 env->PSW_USB_V = ovf << 31; 1197 env->PSW_USB_SV |= env->PSW_USB_V; 1198 env->PSW_USB_AV = avf << 16; 1199 env->PSW_USB_SAV |= env->PSW_USB_AV; 1200 1201 return ret; 1202 } 1203 1204 uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1205 uint32_t r2_h) 1206 { 1207 int64_t mul_res0 = sextract64(r1, 0, 32); 1208 int64_t mul_res1 = sextract64(r1, 32, 32); 1209 int64_t r2_low = sextract64(r2_l, 0, 32); 1210 int64_t r2_high = sextract64(r2_h, 0, 32); 1211 int64_t result0, result1; 1212 uint32_t ovf0, ovf1; 1213 uint32_t avf0, avf1; 1214 1215 ovf0 = ovf1 = 0; 1216 1217 result0 = r2_low + mul_res0 + 0x8000; 1218 result1 = r2_high + mul_res1 + 0x8000; 1219 1220 if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1221 ovf0 = (1 << 31); 1222 } 1223 1224 if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1225 ovf1 = (1 << 31); 1226 } 1227 1228 env->PSW_USB_V = ovf0 | ovf1; 1229 env->PSW_USB_SV |= env->PSW_USB_V; 1230 1231 avf0 = result0 * 2u; 1232 avf0 = result0 ^ avf0; 1233 avf1 = result1 * 2u; 1234 avf1 = result1 ^ avf1; 1235 1236 env->PSW_USB_AV = avf0 | avf1; 1237 env->PSW_USB_SAV |= env->PSW_USB_AV; 1238 1239 return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1240 } 1241 1242 uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1243 uint32_t r2_h) 1244 { 1245 int64_t mul_res0 = sextract64(r1, 0, 32); 1246 int64_t mul_res1 = sextract64(r1, 32, 32); 1247 int64_t r2_low = sextract64(r2_l, 0, 32); 1248 int64_t r2_high = sextract64(r2_h, 0, 32); 1249 int64_t result0, result1; 1250 uint32_t ovf0, ovf1; 1251 uint32_t avf0, avf1; 1252 1253 ovf0 = ovf1 = 0; 1254 1255 result0 = r2_low - mul_res0 + 0x8000; 1256 result1 = r2_high + mul_res1 + 0x8000; 1257 1258 if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1259 ovf0 = (1 << 31); 1260 } 1261 1262 if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1263 ovf1 = (1 << 31); 1264 } 1265 1266 env->PSW_USB_V = ovf0 | ovf1; 1267 env->PSW_USB_SV |= env->PSW_USB_V; 1268 1269 avf0 = result0 * 2u; 1270 avf0 = result0 ^ avf0; 1271 avf1 = result1 * 2u; 1272 avf1 = result1 ^ avf1; 1273 1274 env->PSW_USB_AV = avf0 | avf1; 1275 env->PSW_USB_SAV |= env->PSW_USB_AV; 1276 1277 return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1278 } 1279 1280 uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 1281 uint32_t r3, uint32_t n) 1282 { 1283 int64_t t1 = sextract64(r1, 0, 32); 1284 int64_t t2 = sextract64(r2, 0, 32); 1285 int64_t t3 = sextract64(r3, 0, 32); 1286 int64_t mul, ret; 1287 1288 if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 1289 mul = 0x7fffffff; 1290 } else { 1291 mul = (t2 * t3) << n; 1292 } 1293 1294 ret = t1 + mul + 0x8000; 1295 1296 if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) { 1297 env->PSW_USB_V = (1 << 31); 1298 env->PSW_USB_SV |= env->PSW_USB_V; 1299 } else { 1300 env->PSW_USB_V = 0; 1301 } 1302 env->PSW_USB_AV = ret ^ ret * 2u; 1303 env->PSW_USB_SAV |= env->PSW_USB_AV; 1304 1305 return ret & 0xffff0000ll; 1306 } 1307 1308 uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1309 { 1310 int32_t b, i; 1311 int32_t extr_r1, extr_r2; 1312 int32_t ovf = 0; 1313 int32_t avf = 0; 1314 uint32_t ret = 0; 1315 1316 for (i = 0; i < 4; i++) { 1317 extr_r1 = sextract32(r1, i * 8, 8); 1318 extr_r2 = sextract32(r2, i * 8, 8); 1319 1320 b = extr_r1 + extr_r2; 1321 ovf |= ((b > 0x7f) || (b < -0x80)); 1322 avf |= b ^ b * 2u; 1323 ret |= ((b & 0xff) << (i*8)); 1324 } 1325 1326 env->PSW_USB_V = (ovf << 31); 1327 env->PSW_USB_SV |= env->PSW_USB_V; 1328 env->PSW_USB_AV = avf << 24; 1329 env->PSW_USB_SAV |= env->PSW_USB_AV; 1330 1331 return ret; 1332 } 1333 1334 uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1335 { 1336 int32_t h, i; 1337 int32_t extr_r1, extr_r2; 1338 int32_t ovf = 0; 1339 int32_t avf = 0; 1340 int32_t ret = 0; 1341 1342 for (i = 0; i < 2; i++) { 1343 extr_r1 = sextract32(r1, i * 16, 16); 1344 extr_r2 = sextract32(r2, i * 16, 16); 1345 h = extr_r1 + extr_r2; 1346 ovf |= ((h > 0x7fff) || (h < -0x8000)); 1347 avf |= h ^ h * 2u; 1348 ret |= (h & 0xffff) << (i * 16); 1349 } 1350 1351 env->PSW_USB_V = (ovf << 31); 1352 env->PSW_USB_SV |= env->PSW_USB_V; 1353 env->PSW_USB_AV = (avf << 16); 1354 env->PSW_USB_SAV |= env->PSW_USB_AV; 1355 1356 return ret; 1357 } 1358 1359 uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1360 uint32_t r2_h) 1361 { 1362 int64_t mul_res0 = sextract64(r1, 0, 32); 1363 int64_t mul_res1 = sextract64(r1, 32, 32); 1364 int64_t r2_low = sextract64(r2_l, 0, 32); 1365 int64_t r2_high = sextract64(r2_h, 0, 32); 1366 int64_t result0, result1; 1367 uint32_t ovf0, ovf1; 1368 uint32_t avf0, avf1; 1369 1370 ovf0 = ovf1 = 0; 1371 1372 result0 = r2_low - mul_res0 + 0x8000; 1373 result1 = r2_high - mul_res1 + 0x8000; 1374 1375 if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1376 ovf0 = (1 << 31); 1377 } 1378 1379 if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1380 ovf1 = (1 << 31); 1381 } 1382 1383 env->PSW_USB_V = ovf0 | ovf1; 1384 env->PSW_USB_SV |= env->PSW_USB_V; 1385 1386 avf0 = result0 * 2u; 1387 avf0 = result0 ^ avf0; 1388 avf1 = result1 * 2u; 1389 avf1 = result1 ^ avf1; 1390 1391 env->PSW_USB_AV = avf0 | avf1; 1392 env->PSW_USB_SAV |= env->PSW_USB_AV; 1393 1394 return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1395 } 1396 1397 uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1398 uint32_t r2_h) 1399 { 1400 int64_t mul_res0 = sextract64(r1, 0, 32); 1401 int64_t mul_res1 = sextract64(r1, 32, 32); 1402 int64_t r2_low = sextract64(r2_l, 0, 32); 1403 int64_t r2_high = sextract64(r2_h, 0, 32); 1404 int64_t result0, result1; 1405 uint32_t ovf0, ovf1; 1406 uint32_t avf0, avf1; 1407 1408 ovf0 = ovf1 = 0; 1409 1410 result0 = r2_low + mul_res0 + 0x8000; 1411 result1 = r2_high - mul_res1 + 0x8000; 1412 1413 if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1414 ovf0 = (1 << 31); 1415 } 1416 1417 if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1418 ovf1 = (1 << 31); 1419 } 1420 1421 env->PSW_USB_V = ovf0 | ovf1; 1422 env->PSW_USB_SV |= env->PSW_USB_V; 1423 1424 avf0 = result0 * 2u; 1425 avf0 = result0 ^ avf0; 1426 avf1 = result1 * 2u; 1427 avf1 = result1 ^ avf1; 1428 1429 env->PSW_USB_AV = avf0 | avf1; 1430 env->PSW_USB_SAV |= env->PSW_USB_AV; 1431 1432 return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1433 } 1434 1435 uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 1436 uint32_t r3, uint32_t n) 1437 { 1438 int64_t t1 = sextract64(r1, 0, 32); 1439 int64_t t2 = sextract64(r2, 0, 32); 1440 int64_t t3 = sextract64(r3, 0, 32); 1441 int64_t mul, ret; 1442 1443 if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 1444 mul = 0x7fffffff; 1445 } else { 1446 mul = (t2 * t3) << n; 1447 } 1448 1449 ret = t1 - mul + 0x8000; 1450 1451 if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) { 1452 env->PSW_USB_V = (1 << 31); 1453 env->PSW_USB_SV |= env->PSW_USB_V; 1454 } else { 1455 env->PSW_USB_V = 0; 1456 } 1457 env->PSW_USB_AV = ret ^ ret * 2u; 1458 env->PSW_USB_SAV |= env->PSW_USB_AV; 1459 1460 return ret & 0xffff0000ll; 1461 } 1462 1463 uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1464 { 1465 int32_t b, i; 1466 int32_t extr_r1, extr_r2; 1467 int32_t ovf = 0; 1468 int32_t avf = 0; 1469 uint32_t ret = 0; 1470 1471 for (i = 0; i < 4; i++) { 1472 extr_r1 = sextract32(r1, i * 8, 8); 1473 extr_r2 = sextract32(r2, i * 8, 8); 1474 1475 b = extr_r1 - extr_r2; 1476 ovf |= ((b > 0x7f) || (b < -0x80)); 1477 avf |= b ^ b * 2u; 1478 ret |= ((b & 0xff) << (i*8)); 1479 } 1480 1481 env->PSW_USB_V = (ovf << 31); 1482 env->PSW_USB_SV |= env->PSW_USB_V; 1483 env->PSW_USB_AV = avf << 24; 1484 env->PSW_USB_SAV |= env->PSW_USB_AV; 1485 1486 return ret; 1487 } 1488 1489 uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1490 { 1491 int32_t h, i; 1492 int32_t extr_r1, extr_r2; 1493 int32_t ovf = 0; 1494 int32_t avf = 0; 1495 int32_t ret = 0; 1496 1497 for (i = 0; i < 2; i++) { 1498 extr_r1 = sextract32(r1, i * 16, 16); 1499 extr_r2 = sextract32(r2, i * 16, 16); 1500 h = extr_r1 - extr_r2; 1501 ovf |= ((h > 0x7fff) || (h < -0x8000)); 1502 avf |= h ^ h * 2u; 1503 ret |= (h & 0xffff) << (i * 16); 1504 } 1505 1506 env->PSW_USB_V = (ovf << 31); 1507 env->PSW_USB_SV |= env->PSW_USB_V; 1508 env->PSW_USB_AV = avf << 16; 1509 env->PSW_USB_SAV |= env->PSW_USB_AV; 1510 1511 return ret; 1512 } 1513 1514 uint32_t helper_eq_b(target_ulong r1, target_ulong r2) 1515 { 1516 int32_t ret; 1517 int32_t i, msk; 1518 1519 ret = 0; 1520 msk = 0xff; 1521 for (i = 0; i < 4; i++) { 1522 if ((r1 & msk) == (r2 & msk)) { 1523 ret |= msk; 1524 } 1525 msk = msk << 8; 1526 } 1527 1528 return ret; 1529 } 1530 1531 uint32_t helper_eq_h(target_ulong r1, target_ulong r2) 1532 { 1533 int32_t ret = 0; 1534 1535 if ((r1 & 0xffff) == (r2 & 0xffff)) { 1536 ret = 0xffff; 1537 } 1538 1539 if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) { 1540 ret |= 0xffff0000; 1541 } 1542 1543 return ret; 1544 } 1545 1546 uint32_t helper_eqany_b(target_ulong r1, target_ulong r2) 1547 { 1548 int32_t i; 1549 uint32_t ret = 0; 1550 1551 for (i = 0; i < 4; i++) { 1552 ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8)); 1553 } 1554 1555 return ret; 1556 } 1557 1558 uint32_t helper_eqany_h(target_ulong r1, target_ulong r2) 1559 { 1560 uint32_t ret; 1561 1562 ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16)); 1563 ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16)); 1564 1565 return ret; 1566 } 1567 1568 uint32_t helper_lt_b(target_ulong r1, target_ulong r2) 1569 { 1570 int32_t i; 1571 uint32_t ret = 0; 1572 1573 for (i = 0; i < 4; i++) { 1574 if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) { 1575 ret |= (0xff << (i * 8)); 1576 } 1577 } 1578 1579 return ret; 1580 } 1581 1582 uint32_t helper_lt_bu(target_ulong r1, target_ulong r2) 1583 { 1584 int32_t i; 1585 uint32_t ret = 0; 1586 1587 for (i = 0; i < 4; i++) { 1588 if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) { 1589 ret |= (0xff << (i * 8)); 1590 } 1591 } 1592 1593 return ret; 1594 } 1595 1596 uint32_t helper_lt_h(target_ulong r1, target_ulong r2) 1597 { 1598 uint32_t ret = 0; 1599 1600 if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) { 1601 ret |= 0xffff; 1602 } 1603 1604 if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) { 1605 ret |= 0xffff0000; 1606 } 1607 1608 return ret; 1609 } 1610 1611 uint32_t helper_lt_hu(target_ulong r1, target_ulong r2) 1612 { 1613 uint32_t ret = 0; 1614 1615 if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) { 1616 ret |= 0xffff; 1617 } 1618 1619 if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) { 1620 ret |= 0xffff0000; 1621 } 1622 1623 return ret; 1624 } 1625 1626 #define EXTREMA_H_B(name, op) \ 1627 uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \ 1628 { \ 1629 int32_t i, extr_r1, extr_r2; \ 1630 uint32_t ret = 0; \ 1631 \ 1632 for (i = 0; i < 4; i++) { \ 1633 extr_r1 = sextract32(r1, i * 8, 8); \ 1634 extr_r2 = sextract32(r2, i * 8, 8); \ 1635 extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1636 ret |= (extr_r1 & 0xff) << (i * 8); \ 1637 } \ 1638 return ret; \ 1639 } \ 1640 \ 1641 uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\ 1642 { \ 1643 int32_t i; \ 1644 uint32_t extr_r1, extr_r2; \ 1645 uint32_t ret = 0; \ 1646 \ 1647 for (i = 0; i < 4; i++) { \ 1648 extr_r1 = extract32(r1, i * 8, 8); \ 1649 extr_r2 = extract32(r2, i * 8, 8); \ 1650 extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1651 ret |= (extr_r1 & 0xff) << (i * 8); \ 1652 } \ 1653 return ret; \ 1654 } \ 1655 \ 1656 uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \ 1657 { \ 1658 int32_t extr_r1, extr_r2; \ 1659 uint32_t ret = 0; \ 1660 \ 1661 extr_r1 = sextract32(r1, 0, 16); \ 1662 extr_r2 = sextract32(r2, 0, 16); \ 1663 ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1664 ret = ret & 0xffff; \ 1665 \ 1666 extr_r1 = sextract32(r1, 16, 16); \ 1667 extr_r2 = sextract32(r2, 16, 16); \ 1668 extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1669 ret |= extr_r1 << 16; \ 1670 \ 1671 return ret; \ 1672 } \ 1673 \ 1674 uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\ 1675 { \ 1676 uint32_t extr_r1, extr_r2; \ 1677 uint32_t ret = 0; \ 1678 \ 1679 extr_r1 = extract32(r1, 0, 16); \ 1680 extr_r2 = extract32(r2, 0, 16); \ 1681 ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1682 ret = ret & 0xffff; \ 1683 \ 1684 extr_r1 = extract32(r1, 16, 16); \ 1685 extr_r2 = extract32(r2, 16, 16); \ 1686 extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1687 ret |= extr_r1 << (16); \ 1688 \ 1689 return ret; \ 1690 } \ 1691 \ 1692 uint64_t helper_ix##name(uint64_t r1, uint32_t r2) \ 1693 { \ 1694 int64_t r2l, r2h, r1hl; \ 1695 uint64_t ret = 0; \ 1696 \ 1697 ret = ((r1 + 2) & 0xffff); \ 1698 r2l = sextract64(r2, 0, 16); \ 1699 r2h = sextract64(r2, 16, 16); \ 1700 r1hl = sextract64(r1, 32, 16); \ 1701 \ 1702 if ((r2l op ## = r2h) && (r2l op r1hl)) { \ 1703 ret |= (r2l & 0xffff) << 32; \ 1704 ret |= extract64(r1, 0, 16) << 16; \ 1705 } else if ((r2h op r2l) && (r2h op r1hl)) { \ 1706 ret |= extract64(r2, 16, 16) << 32; \ 1707 ret |= extract64(r1 + 1, 0, 16) << 16; \ 1708 } else { \ 1709 ret |= r1 & 0xffffffff0000ull; \ 1710 } \ 1711 return ret; \ 1712 } \ 1713 \ 1714 uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2) \ 1715 { \ 1716 int64_t r2l, r2h, r1hl; \ 1717 uint64_t ret = 0; \ 1718 \ 1719 ret = ((r1 + 2) & 0xffff); \ 1720 r2l = extract64(r2, 0, 16); \ 1721 r2h = extract64(r2, 16, 16); \ 1722 r1hl = extract64(r1, 32, 16); \ 1723 \ 1724 if ((r2l op ## = r2h) && (r2l op r1hl)) { \ 1725 ret |= (r2l & 0xffff) << 32; \ 1726 ret |= extract64(r1, 0, 16) << 16; \ 1727 } else if ((r2h op r2l) && (r2h op r1hl)) { \ 1728 ret |= extract64(r2, 16, 16) << 32; \ 1729 ret |= extract64(r1 + 1, 0, 16) << 16; \ 1730 } else { \ 1731 ret |= r1 & 0xffffffff0000ull; \ 1732 } \ 1733 return ret; \ 1734 } 1735 1736 EXTREMA_H_B(max, >) 1737 EXTREMA_H_B(min, <) 1738 1739 #undef EXTREMA_H_B 1740 1741 uint32_t helper_clo_h(target_ulong r1) 1742 { 1743 uint32_t ret_hw0 = extract32(r1, 0, 16); 1744 uint32_t ret_hw1 = extract32(r1, 16, 16); 1745 1746 ret_hw0 = clo32(ret_hw0 << 16); 1747 ret_hw1 = clo32(ret_hw1 << 16); 1748 1749 if (ret_hw0 > 16) { 1750 ret_hw0 = 16; 1751 } 1752 if (ret_hw1 > 16) { 1753 ret_hw1 = 16; 1754 } 1755 1756 return ret_hw0 | (ret_hw1 << 16); 1757 } 1758 1759 uint32_t helper_clz_h(target_ulong r1) 1760 { 1761 uint32_t ret_hw0 = extract32(r1, 0, 16); 1762 uint32_t ret_hw1 = extract32(r1, 16, 16); 1763 1764 ret_hw0 = clz32(ret_hw0 << 16); 1765 ret_hw1 = clz32(ret_hw1 << 16); 1766 1767 if (ret_hw0 > 16) { 1768 ret_hw0 = 16; 1769 } 1770 if (ret_hw1 > 16) { 1771 ret_hw1 = 16; 1772 } 1773 1774 return ret_hw0 | (ret_hw1 << 16); 1775 } 1776 1777 uint32_t helper_cls_h(target_ulong r1) 1778 { 1779 uint32_t ret_hw0 = extract32(r1, 0, 16); 1780 uint32_t ret_hw1 = extract32(r1, 16, 16); 1781 1782 ret_hw0 = clrsb32(ret_hw0 << 16); 1783 ret_hw1 = clrsb32(ret_hw1 << 16); 1784 1785 if (ret_hw0 > 15) { 1786 ret_hw0 = 15; 1787 } 1788 if (ret_hw1 > 15) { 1789 ret_hw1 = 15; 1790 } 1791 1792 return ret_hw0 | (ret_hw1 << 16); 1793 } 1794 1795 uint32_t helper_sh(target_ulong r1, target_ulong r2) 1796 { 1797 int32_t shift_count = sextract32(r2, 0, 6); 1798 1799 if (shift_count == -32) { 1800 return 0; 1801 } else if (shift_count < 0) { 1802 return r1 >> -shift_count; 1803 } else { 1804 return r1 << shift_count; 1805 } 1806 } 1807 1808 uint32_t helper_sh_h(target_ulong r1, target_ulong r2) 1809 { 1810 int32_t ret_hw0, ret_hw1; 1811 int32_t shift_count; 1812 1813 shift_count = sextract32(r2, 0, 5); 1814 1815 if (shift_count == -16) { 1816 return 0; 1817 } else if (shift_count < 0) { 1818 ret_hw0 = extract32(r1, 0, 16) >> -shift_count; 1819 ret_hw1 = extract32(r1, 16, 16) >> -shift_count; 1820 return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 1821 } else { 1822 ret_hw0 = extract32(r1, 0, 16) << shift_count; 1823 ret_hw1 = extract32(r1, 16, 16) << shift_count; 1824 return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 1825 } 1826 } 1827 1828 uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1829 { 1830 int32_t shift_count; 1831 int64_t result, t1; 1832 uint32_t ret; 1833 1834 shift_count = sextract32(r2, 0, 6); 1835 t1 = sextract32(r1, 0, 32); 1836 1837 if (shift_count == 0) { 1838 env->PSW_USB_C = env->PSW_USB_V = 0; 1839 ret = r1; 1840 } else if (shift_count == -32) { 1841 env->PSW_USB_C = r1; 1842 env->PSW_USB_V = 0; 1843 ret = t1 >> 31; 1844 } else if (shift_count > 0) { 1845 result = t1 << shift_count; 1846 /* calc carry */ 1847 env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0); 1848 /* calc v */ 1849 env->PSW_USB_V = (((result > 0x7fffffffLL) || 1850 (result < -0x80000000LL)) << 31); 1851 /* calc sv */ 1852 env->PSW_USB_SV |= env->PSW_USB_V; 1853 ret = (uint32_t)result; 1854 } else { 1855 env->PSW_USB_V = 0; 1856 env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1)); 1857 ret = t1 >> -shift_count; 1858 } 1859 1860 env->PSW_USB_AV = ret ^ ret * 2u; 1861 env->PSW_USB_SAV |= env->PSW_USB_AV; 1862 1863 return ret; 1864 } 1865 1866 uint32_t helper_sha_h(target_ulong r1, target_ulong r2) 1867 { 1868 int32_t shift_count; 1869 int32_t ret_hw0, ret_hw1; 1870 1871 shift_count = sextract32(r2, 0, 5); 1872 1873 if (shift_count == 0) { 1874 return r1; 1875 } else if (shift_count < 0) { 1876 ret_hw0 = sextract32(r1, 0, 16) >> -shift_count; 1877 ret_hw1 = sextract32(r1, 16, 16) >> -shift_count; 1878 return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 1879 } else { 1880 ret_hw0 = sextract32(r1, 0, 16) << shift_count; 1881 ret_hw1 = sextract32(r1, 16, 16) << shift_count; 1882 return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 1883 } 1884 } 1885 1886 uint32_t helper_bmerge(target_ulong r1, target_ulong r2) 1887 { 1888 uint32_t i, ret; 1889 1890 ret = 0; 1891 for (i = 0; i < 16; i++) { 1892 ret |= (r1 & 1) << (2 * i + 1); 1893 ret |= (r2 & 1) << (2 * i); 1894 r1 = r1 >> 1; 1895 r2 = r2 >> 1; 1896 } 1897 return ret; 1898 } 1899 1900 uint64_t helper_bsplit(uint32_t r1) 1901 { 1902 int32_t i; 1903 uint64_t ret; 1904 1905 ret = 0; 1906 for (i = 0; i < 32; i = i + 2) { 1907 /* even */ 1908 ret |= (r1 & 1) << (i/2); 1909 r1 = r1 >> 1; 1910 /* odd */ 1911 ret |= (uint64_t)(r1 & 1) << (i/2 + 32); 1912 r1 = r1 >> 1; 1913 } 1914 return ret; 1915 } 1916 1917 uint32_t helper_parity(target_ulong r1) 1918 { 1919 uint32_t ret; 1920 uint32_t nOnes, i; 1921 1922 ret = 0; 1923 nOnes = 0; 1924 for (i = 0; i < 8; i++) { 1925 ret ^= (r1 & 1); 1926 r1 = r1 >> 1; 1927 } 1928 /* second byte */ 1929 nOnes = 0; 1930 for (i = 0; i < 8; i++) { 1931 nOnes ^= (r1 & 1); 1932 r1 = r1 >> 1; 1933 } 1934 ret |= nOnes << 8; 1935 /* third byte */ 1936 nOnes = 0; 1937 for (i = 0; i < 8; i++) { 1938 nOnes ^= (r1 & 1); 1939 r1 = r1 >> 1; 1940 } 1941 ret |= nOnes << 16; 1942 /* fourth byte */ 1943 nOnes = 0; 1944 for (i = 0; i < 8; i++) { 1945 nOnes ^= (r1 & 1); 1946 r1 = r1 >> 1; 1947 } 1948 ret |= nOnes << 24; 1949 1950 return ret; 1951 } 1952 1953 uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high, 1954 target_ulong r2) 1955 { 1956 uint32_t ret; 1957 int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac; 1958 int32_t int_exp = r1_high; 1959 int32_t int_mant = r1_low; 1960 uint32_t flag_rnd = (int_mant & (1 << 7)) && ( 1961 (int_mant & (1 << 8)) || 1962 (int_mant & 0x7f) || 1963 (carry != 0)); 1964 if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) { 1965 fp_exp = 255; 1966 fp_frac = extract32(int_mant, 8, 23); 1967 } else if ((int_mant & (1<<31)) && (int_exp >= 127)) { 1968 fp_exp = 255; 1969 fp_frac = 0; 1970 } else if ((int_mant & (1<<31)) && (int_exp <= -128)) { 1971 fp_exp = 0; 1972 fp_frac = 0; 1973 } else if (int_mant == 0) { 1974 fp_exp = 0; 1975 fp_frac = 0; 1976 } else { 1977 if (((int_mant & (1 << 31)) == 0)) { 1978 temp_exp = 0; 1979 } else { 1980 temp_exp = int_exp + 128; 1981 } 1982 fp_exp_frac = (((temp_exp & 0xff) << 23) | 1983 extract32(int_mant, 8, 23)) 1984 + flag_rnd; 1985 fp_exp = extract32(fp_exp_frac, 23, 8); 1986 fp_frac = extract32(fp_exp_frac, 0, 23); 1987 } 1988 ret = r2 & (1 << 31); 1989 ret = ret + (fp_exp << 23); 1990 ret = ret + (fp_frac & 0x7fffff); 1991 1992 return ret; 1993 } 1994 1995 uint64_t helper_unpack(target_ulong arg1) 1996 { 1997 int32_t fp_exp = extract32(arg1, 23, 8); 1998 int32_t fp_frac = extract32(arg1, 0, 23); 1999 uint64_t ret; 2000 int32_t int_exp, int_mant; 2001 2002 if (fp_exp == 255) { 2003 int_exp = 255; 2004 int_mant = (fp_frac << 7); 2005 } else if ((fp_exp == 0) && (fp_frac == 0)) { 2006 int_exp = -127; 2007 int_mant = 0; 2008 } else if ((fp_exp == 0) && (fp_frac != 0)) { 2009 int_exp = -126; 2010 int_mant = (fp_frac << 7); 2011 } else { 2012 int_exp = fp_exp - 127; 2013 int_mant = (fp_frac << 7); 2014 int_mant |= (1 << 30); 2015 } 2016 ret = int_exp; 2017 ret = ret << 32; 2018 ret |= int_mant; 2019 2020 return ret; 2021 } 2022 2023 uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2024 { 2025 uint64_t ret; 2026 int32_t abs_sig_dividend, abs_divisor; 2027 2028 ret = sextract32(r1, 0, 32); 2029 ret = ret << 24; 2030 if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 2031 ret |= 0xffffff; 2032 } 2033 2034 abs_sig_dividend = abs((int32_t)r1) >> 8; 2035 abs_divisor = abs((int32_t)r2); 2036 /* calc overflow 2037 ofv if (a/b >= 255) <=> (a/255 >= b) */ 2038 env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31; 2039 env->PSW_USB_V = env->PSW_USB_V << 31; 2040 env->PSW_USB_SV |= env->PSW_USB_V; 2041 env->PSW_USB_AV = 0; 2042 2043 return ret; 2044 } 2045 2046 uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2047 { 2048 uint64_t ret = sextract32(r1, 0, 32); 2049 2050 ret = ret << 24; 2051 if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 2052 ret |= 0xffffff; 2053 } 2054 /* calc overflow */ 2055 env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80))); 2056 env->PSW_USB_V = env->PSW_USB_V << 31; 2057 env->PSW_USB_SV |= env->PSW_USB_V; 2058 env->PSW_USB_AV = 0; 2059 2060 return ret; 2061 } 2062 2063 uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2064 { 2065 uint64_t ret; 2066 int32_t abs_sig_dividend, abs_divisor; 2067 2068 ret = sextract32(r1, 0, 32); 2069 ret = ret << 16; 2070 if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 2071 ret |= 0xffff; 2072 } 2073 2074 abs_sig_dividend = abs((int32_t)r1) >> 16; 2075 abs_divisor = abs((int32_t)r2); 2076 /* calc overflow 2077 ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */ 2078 env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31; 2079 env->PSW_USB_V = env->PSW_USB_V << 31; 2080 env->PSW_USB_SV |= env->PSW_USB_V; 2081 env->PSW_USB_AV = 0; 2082 2083 return ret; 2084 } 2085 2086 uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2087 { 2088 uint64_t ret = sextract32(r1, 0, 32); 2089 2090 ret = ret << 16; 2091 if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 2092 ret |= 0xffff; 2093 } 2094 /* calc overflow */ 2095 env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000))); 2096 env->PSW_USB_V = env->PSW_USB_V << 31; 2097 env->PSW_USB_SV |= env->PSW_USB_V; 2098 env->PSW_USB_AV = 0; 2099 2100 return ret; 2101 } 2102 2103 uint64_t helper_dvadj(uint64_t r1, uint32_t r2) 2104 { 2105 int32_t x_sign = (r1 >> 63); 2106 int32_t q_sign = x_sign ^ (r2 >> 31); 2107 int32_t eq_pos = x_sign & ((r1 >> 32) == r2); 2108 int32_t eq_neg = x_sign & ((r1 >> 32) == -r2); 2109 uint32_t quotient; 2110 uint64_t remainder; 2111 2112 if ((q_sign & ~eq_neg) | eq_pos) { 2113 quotient = (r1 + 1) & 0xffffffff; 2114 } else { 2115 quotient = r1 & 0xffffffff; 2116 } 2117 2118 if (eq_pos | eq_neg) { 2119 remainder = 0; 2120 } else { 2121 remainder = (r1 & 0xffffffff00000000ull); 2122 } 2123 return remainder | quotient; 2124 } 2125 2126 uint64_t helper_dvstep(uint64_t r1, uint32_t r2) 2127 { 2128 int32_t dividend_sign = extract64(r1, 63, 1); 2129 int32_t divisor_sign = extract32(r2, 31, 1); 2130 int32_t quotient_sign = (dividend_sign != divisor_sign); 2131 int32_t addend, dividend_quotient, remainder; 2132 int32_t i, temp; 2133 2134 if (quotient_sign) { 2135 addend = r2; 2136 } else { 2137 addend = -r2; 2138 } 2139 dividend_quotient = (int32_t)r1; 2140 remainder = (int32_t)(r1 >> 32); 2141 2142 for (i = 0; i < 8; i++) { 2143 remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1); 2144 dividend_quotient <<= 1; 2145 temp = remainder + addend; 2146 if ((temp < 0) == dividend_sign) { 2147 remainder = temp; 2148 } 2149 if (((temp < 0) == dividend_sign)) { 2150 dividend_quotient = dividend_quotient | !quotient_sign; 2151 } else { 2152 dividend_quotient = dividend_quotient | quotient_sign; 2153 } 2154 } 2155 return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient; 2156 } 2157 2158 uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2) 2159 { 2160 int32_t dividend_quotient = extract64(r1, 0, 32); 2161 int64_t remainder = extract64(r1, 32, 32); 2162 int32_t i; 2163 int64_t temp; 2164 for (i = 0; i < 8; i++) { 2165 remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1); 2166 dividend_quotient <<= 1; 2167 temp = (remainder & 0xffffffff) - r2; 2168 if (temp >= 0) { 2169 remainder = temp; 2170 } 2171 dividend_quotient = dividend_quotient | !(temp < 0); 2172 } 2173 return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient; 2174 } 2175 2176 uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2177 { 2178 int32_t quotient, remainder; 2179 int32_t dividend = (int32_t)r1; 2180 int32_t divisor = (int32_t)r2; 2181 2182 if (divisor == 0) { 2183 if (dividend >= 0) { 2184 quotient = 0x7fffffff; 2185 remainder = 0; 2186 } else { 2187 quotient = 0x80000000; 2188 remainder = 0; 2189 } 2190 env->PSW_USB_V = (1 << 31); 2191 } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) { 2192 quotient = 0x7fffffff; 2193 remainder = 0; 2194 env->PSW_USB_V = (1 << 31); 2195 } else { 2196 remainder = dividend % divisor; 2197 quotient = (dividend - remainder)/divisor; 2198 env->PSW_USB_V = 0; 2199 } 2200 env->PSW_USB_SV |= env->PSW_USB_V; 2201 env->PSW_USB_AV = 0; 2202 return ((uint64_t)remainder << 32) | (uint32_t)quotient; 2203 } 2204 2205 uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2206 { 2207 uint32_t quotient, remainder; 2208 uint32_t dividend = r1; 2209 uint32_t divisor = r2; 2210 2211 if (divisor == 0) { 2212 quotient = 0xffffffff; 2213 remainder = 0; 2214 env->PSW_USB_V = (1 << 31); 2215 } else { 2216 remainder = dividend % divisor; 2217 quotient = (dividend - remainder)/divisor; 2218 env->PSW_USB_V = 0; 2219 } 2220 env->PSW_USB_SV |= env->PSW_USB_V; 2221 env->PSW_USB_AV = 0; 2222 return ((uint64_t)remainder << 32) | quotient; 2223 } 2224 2225 uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01, 2226 uint32_t arg10, uint32_t arg11, uint32_t n) 2227 { 2228 uint32_t result0, result1; 2229 2230 int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 2231 ((arg10 & 0xffff) == 0x8000) && (n == 1); 2232 int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 2233 ((arg11 & 0xffff) == 0x8000) && (n == 1); 2234 if (sc1) { 2235 result1 = 0x7fffffff; 2236 } else { 2237 result1 = (((uint32_t)(arg00 * arg10)) << n); 2238 } 2239 if (sc0) { 2240 result0 = 0x7fffffff; 2241 } else { 2242 result0 = (((uint32_t)(arg01 * arg11)) << n); 2243 } 2244 return (((uint64_t)result1 << 32)) | result0; 2245 } 2246 2247 uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01, 2248 uint32_t arg10, uint32_t arg11, uint32_t n) 2249 { 2250 uint64_t ret; 2251 int64_t result0, result1; 2252 2253 int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 2254 ((arg10 & 0xffff) == 0x8000) && (n == 1); 2255 int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 2256 ((arg11 & 0xffff) == 0x8000) && (n == 1); 2257 2258 if (sc1) { 2259 result1 = 0x7fffffff; 2260 } else { 2261 result1 = (((int32_t)arg00 * (int32_t)arg10) << n); 2262 } 2263 if (sc0) { 2264 result0 = 0x7fffffff; 2265 } else { 2266 result0 = (((int32_t)arg01 * (int32_t)arg11) << n); 2267 } 2268 ret = (result1 + result0); 2269 ret = ret << 16; 2270 return ret; 2271 } 2272 uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01, 2273 uint32_t arg10, uint32_t arg11, uint32_t n) 2274 { 2275 uint32_t result0, result1; 2276 2277 int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 2278 ((arg10 & 0xffff) == 0x8000) && (n == 1); 2279 int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 2280 ((arg11 & 0xffff) == 0x8000) && (n == 1); 2281 2282 if (sc1) { 2283 result1 = 0x7fffffff; 2284 } else { 2285 result1 = ((arg00 * arg10) << n) + 0x8000; 2286 } 2287 if (sc0) { 2288 result0 = 0x7fffffff; 2289 } else { 2290 result0 = ((arg01 * arg11) << n) + 0x8000; 2291 } 2292 return (result1 & 0xffff0000) | (result0 >> 16); 2293 } 2294 2295 uint32_t helper_crc32(uint32_t arg0, uint32_t arg1) 2296 { 2297 uint8_t buf[4]; 2298 stl_be_p(buf, arg0); 2299 2300 return crc32(arg1, buf, 4); 2301 } 2302 2303 /* context save area (CSA) related helpers */ 2304 2305 static int cdc_increment(target_ulong *psw) 2306 { 2307 if ((*psw & MASK_PSW_CDC) == 0x7f) { 2308 return 0; 2309 } 2310 2311 (*psw)++; 2312 /* check for overflow */ 2313 int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 2314 int mask = (1u << (7 - lo)) - 1; 2315 int count = *psw & mask; 2316 if (count == 0) { 2317 (*psw)--; 2318 return 1; 2319 } 2320 return 0; 2321 } 2322 2323 static int cdc_decrement(target_ulong *psw) 2324 { 2325 if ((*psw & MASK_PSW_CDC) == 0x7f) { 2326 return 0; 2327 } 2328 /* check for underflow */ 2329 int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 2330 int mask = (1u << (7 - lo)) - 1; 2331 int count = *psw & mask; 2332 if (count == 0) { 2333 return 1; 2334 } 2335 (*psw)--; 2336 return 0; 2337 } 2338 2339 static bool cdc_zero(target_ulong *psw) 2340 { 2341 int cdc = *psw & MASK_PSW_CDC; 2342 /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC == 2343 7'b1111111, otherwise returns FALSE. */ 2344 if (cdc == 0x7f) { 2345 return true; 2346 } 2347 /* find CDC.COUNT */ 2348 int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 2349 int mask = (1u << (7 - lo)) - 1; 2350 int count = *psw & mask; 2351 return count == 0; 2352 } 2353 2354 static void save_context_upper(CPUTriCoreState *env, int ea) 2355 { 2356 cpu_stl_data(env, ea, env->PCXI); 2357 cpu_stl_data(env, ea+4, psw_read(env)); 2358 cpu_stl_data(env, ea+8, env->gpr_a[10]); 2359 cpu_stl_data(env, ea+12, env->gpr_a[11]); 2360 cpu_stl_data(env, ea+16, env->gpr_d[8]); 2361 cpu_stl_data(env, ea+20, env->gpr_d[9]); 2362 cpu_stl_data(env, ea+24, env->gpr_d[10]); 2363 cpu_stl_data(env, ea+28, env->gpr_d[11]); 2364 cpu_stl_data(env, ea+32, env->gpr_a[12]); 2365 cpu_stl_data(env, ea+36, env->gpr_a[13]); 2366 cpu_stl_data(env, ea+40, env->gpr_a[14]); 2367 cpu_stl_data(env, ea+44, env->gpr_a[15]); 2368 cpu_stl_data(env, ea+48, env->gpr_d[12]); 2369 cpu_stl_data(env, ea+52, env->gpr_d[13]); 2370 cpu_stl_data(env, ea+56, env->gpr_d[14]); 2371 cpu_stl_data(env, ea+60, env->gpr_d[15]); 2372 } 2373 2374 static void save_context_lower(CPUTriCoreState *env, int ea) 2375 { 2376 cpu_stl_data(env, ea, env->PCXI); 2377 cpu_stl_data(env, ea+4, env->gpr_a[11]); 2378 cpu_stl_data(env, ea+8, env->gpr_a[2]); 2379 cpu_stl_data(env, ea+12, env->gpr_a[3]); 2380 cpu_stl_data(env, ea+16, env->gpr_d[0]); 2381 cpu_stl_data(env, ea+20, env->gpr_d[1]); 2382 cpu_stl_data(env, ea+24, env->gpr_d[2]); 2383 cpu_stl_data(env, ea+28, env->gpr_d[3]); 2384 cpu_stl_data(env, ea+32, env->gpr_a[4]); 2385 cpu_stl_data(env, ea+36, env->gpr_a[5]); 2386 cpu_stl_data(env, ea+40, env->gpr_a[6]); 2387 cpu_stl_data(env, ea+44, env->gpr_a[7]); 2388 cpu_stl_data(env, ea+48, env->gpr_d[4]); 2389 cpu_stl_data(env, ea+52, env->gpr_d[5]); 2390 cpu_stl_data(env, ea+56, env->gpr_d[6]); 2391 cpu_stl_data(env, ea+60, env->gpr_d[7]); 2392 } 2393 2394 static void restore_context_upper(CPUTriCoreState *env, int ea, 2395 target_ulong *new_PCXI, target_ulong *new_PSW) 2396 { 2397 *new_PCXI = cpu_ldl_data(env, ea); 2398 *new_PSW = cpu_ldl_data(env, ea+4); 2399 env->gpr_a[10] = cpu_ldl_data(env, ea+8); 2400 env->gpr_a[11] = cpu_ldl_data(env, ea+12); 2401 env->gpr_d[8] = cpu_ldl_data(env, ea+16); 2402 env->gpr_d[9] = cpu_ldl_data(env, ea+20); 2403 env->gpr_d[10] = cpu_ldl_data(env, ea+24); 2404 env->gpr_d[11] = cpu_ldl_data(env, ea+28); 2405 env->gpr_a[12] = cpu_ldl_data(env, ea+32); 2406 env->gpr_a[13] = cpu_ldl_data(env, ea+36); 2407 env->gpr_a[14] = cpu_ldl_data(env, ea+40); 2408 env->gpr_a[15] = cpu_ldl_data(env, ea+44); 2409 env->gpr_d[12] = cpu_ldl_data(env, ea+48); 2410 env->gpr_d[13] = cpu_ldl_data(env, ea+52); 2411 env->gpr_d[14] = cpu_ldl_data(env, ea+56); 2412 env->gpr_d[15] = cpu_ldl_data(env, ea+60); 2413 } 2414 2415 static void restore_context_lower(CPUTriCoreState *env, int ea, 2416 target_ulong *ra, target_ulong *pcxi) 2417 { 2418 *pcxi = cpu_ldl_data(env, ea); 2419 *ra = cpu_ldl_data(env, ea+4); 2420 env->gpr_a[2] = cpu_ldl_data(env, ea+8); 2421 env->gpr_a[3] = cpu_ldl_data(env, ea+12); 2422 env->gpr_d[0] = cpu_ldl_data(env, ea+16); 2423 env->gpr_d[1] = cpu_ldl_data(env, ea+20); 2424 env->gpr_d[2] = cpu_ldl_data(env, ea+24); 2425 env->gpr_d[3] = cpu_ldl_data(env, ea+28); 2426 env->gpr_a[4] = cpu_ldl_data(env, ea+32); 2427 env->gpr_a[5] = cpu_ldl_data(env, ea+36); 2428 env->gpr_a[6] = cpu_ldl_data(env, ea+40); 2429 env->gpr_a[7] = cpu_ldl_data(env, ea+44); 2430 env->gpr_d[4] = cpu_ldl_data(env, ea+48); 2431 env->gpr_d[5] = cpu_ldl_data(env, ea+52); 2432 env->gpr_d[6] = cpu_ldl_data(env, ea+56); 2433 env->gpr_d[7] = cpu_ldl_data(env, ea+60); 2434 } 2435 2436 void helper_call(CPUTriCoreState *env, uint32_t next_pc) 2437 { 2438 target_ulong tmp_FCX; 2439 target_ulong ea; 2440 target_ulong new_FCX; 2441 target_ulong psw; 2442 2443 psw = psw_read(env); 2444 /* if (FCX == 0) trap(FCU); */ 2445 if (env->FCX == 0) { 2446 /* FCU trap */ 2447 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); 2448 } 2449 /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */ 2450 if (psw & MASK_PSW_CDE) { 2451 if (cdc_increment(&psw)) { 2452 /* CDO trap */ 2453 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC()); 2454 } 2455 } 2456 /* PSW.CDE = 1;*/ 2457 psw |= MASK_PSW_CDE; 2458 /* tmp_FCX = FCX; */ 2459 tmp_FCX = env->FCX; 2460 /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 2461 ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 2462 ((env->FCX & MASK_FCX_FCXO) << 6); 2463 /* new_FCX = M(EA, word); */ 2464 new_FCX = cpu_ldl_data(env, ea); 2465 /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 2466 A[12], A[13], A[14], A[15], D[12], D[13], D[14], 2467 D[15]}; */ 2468 save_context_upper(env, ea); 2469 2470 /* PCXI.PCPN = ICR.CCPN; */ 2471 env->PCXI = (env->PCXI & 0xffffff) + 2472 ((env->ICR & MASK_ICR_CCPN) << 24); 2473 /* PCXI.PIE = ICR.IE; */ 2474 env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE_1_3) + 2475 ((env->ICR & MASK_ICR_IE_1_3) << 15)); 2476 /* PCXI.UL = 1; */ 2477 env->PCXI |= MASK_PCXI_UL; 2478 2479 /* PCXI[19: 0] = FCX[19: 0]; */ 2480 env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 2481 /* FCX[19: 0] = new_FCX[19: 0]; */ 2482 env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 2483 /* A[11] = next_pc[31: 0]; */ 2484 env->gpr_a[11] = next_pc; 2485 2486 /* if (tmp_FCX == LCX) trap(FCD);*/ 2487 if (tmp_FCX == env->LCX) { 2488 /* FCD trap */ 2489 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); 2490 } 2491 psw_write(env, psw); 2492 } 2493 2494 void helper_ret(CPUTriCoreState *env) 2495 { 2496 target_ulong ea; 2497 target_ulong new_PCXI; 2498 target_ulong new_PSW, psw; 2499 2500 psw = psw_read(env); 2501 /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/ 2502 if (psw & MASK_PSW_CDE) { 2503 if (cdc_decrement(&psw)) { 2504 /* CDU trap */ 2505 psw_write(env, psw); 2506 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDU, GETPC()); 2507 } 2508 } 2509 /* if (PCXI[19: 0] == 0) then trap(CSU); */ 2510 if ((env->PCXI & 0xfffff) == 0) { 2511 /* CSU trap */ 2512 psw_write(env, psw); 2513 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC()); 2514 } 2515 /* if (PCXI.UL == 0) then trap(CTYP); */ 2516 if ((env->PCXI & MASK_PCXI_UL) == 0) { 2517 /* CTYP trap */ 2518 cdc_increment(&psw); /* restore to the start of helper */ 2519 psw_write(env, psw); 2520 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC()); 2521 } 2522 /* PC = {A11 [31: 1], 1’b0}; */ 2523 env->PC = env->gpr_a[11] & 0xfffffffe; 2524 2525 /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 2526 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 2527 ((env->PCXI & MASK_PCXI_PCXO) << 6); 2528 /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2529 A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 2530 restore_context_upper(env, ea, &new_PCXI, &new_PSW); 2531 /* M(EA, word) = FCX; */ 2532 cpu_stl_data(env, ea, env->FCX); 2533 /* FCX[19: 0] = PCXI[19: 0]; */ 2534 env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 2535 /* PCXI = new_PCXI; */ 2536 env->PCXI = new_PCXI; 2537 2538 if (tricore_feature(env, TRICORE_FEATURE_13)) { 2539 /* PSW = new_PSW */ 2540 psw_write(env, new_PSW); 2541 } else { 2542 /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */ 2543 psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000))); 2544 } 2545 } 2546 2547 void helper_bisr(CPUTriCoreState *env, uint32_t const9) 2548 { 2549 target_ulong tmp_FCX; 2550 target_ulong ea; 2551 target_ulong new_FCX; 2552 2553 if (env->FCX == 0) { 2554 /* FCU trap */ 2555 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); 2556 } 2557 2558 tmp_FCX = env->FCX; 2559 ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6); 2560 2561 /* new_FCX = M(EA, word); */ 2562 new_FCX = cpu_ldl_data(env, ea); 2563 /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4] 2564 , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */ 2565 save_context_lower(env, ea); 2566 2567 2568 /* PCXI.PCPN = ICR.CCPN */ 2569 env->PCXI = (env->PCXI & 0xffffff) + 2570 ((env->ICR & MASK_ICR_CCPN) << 24); 2571 /* PCXI.PIE = ICR.IE */ 2572 env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE_1_3) + 2573 ((env->ICR & MASK_ICR_IE_1_3) << 15)); 2574 /* PCXI.UL = 0 */ 2575 env->PCXI &= ~(MASK_PCXI_UL); 2576 /* PCXI[19: 0] = FCX[19: 0] */ 2577 env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 2578 /* FXC[19: 0] = new_FCX[19: 0] */ 2579 env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 2580 /* ICR.IE = 1 */ 2581 env->ICR |= MASK_ICR_IE_1_3; 2582 2583 env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/ 2584 2585 if (tmp_FCX == env->LCX) { 2586 /* FCD trap */ 2587 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); 2588 } 2589 } 2590 2591 void helper_rfe(CPUTriCoreState *env) 2592 { 2593 target_ulong ea; 2594 target_ulong new_PCXI; 2595 target_ulong new_PSW; 2596 /* if (PCXI[19: 0] == 0) then trap(CSU); */ 2597 if ((env->PCXI & 0xfffff) == 0) { 2598 /* raise csu trap */ 2599 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC()); 2600 } 2601 /* if (PCXI.UL == 0) then trap(CTYP); */ 2602 if ((env->PCXI & MASK_PCXI_UL) == 0) { 2603 /* raise CTYP trap */ 2604 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC()); 2605 } 2606 /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */ 2607 if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) { 2608 /* raise NEST trap */ 2609 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_NEST, GETPC()); 2610 } 2611 env->PC = env->gpr_a[11] & ~0x1; 2612 /* ICR.IE = PCXI.PIE; */ 2613 env->ICR = (env->ICR & ~MASK_ICR_IE_1_3) 2614 + ((env->PCXI & MASK_PCXI_PIE_1_3) >> 15); 2615 /* ICR.CCPN = PCXI.PCPN; */ 2616 env->ICR = (env->ICR & ~MASK_ICR_CCPN) + 2617 ((env->PCXI & MASK_PCXI_PCPN) >> 24); 2618 /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/ 2619 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 2620 ((env->PCXI & MASK_PCXI_PCXO) << 6); 2621 /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2622 A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 2623 restore_context_upper(env, ea, &new_PCXI, &new_PSW); 2624 /* M(EA, word) = FCX;*/ 2625 cpu_stl_data(env, ea, env->FCX); 2626 /* FCX[19: 0] = PCXI[19: 0]; */ 2627 env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 2628 /* PCXI = new_PCXI; */ 2629 env->PCXI = new_PCXI; 2630 /* write psw */ 2631 psw_write(env, new_PSW); 2632 } 2633 2634 void helper_rfm(CPUTriCoreState *env) 2635 { 2636 env->PC = (env->gpr_a[11] & ~0x1); 2637 /* ICR.IE = PCXI.PIE; */ 2638 env->ICR = (env->ICR & ~MASK_ICR_IE_1_3) 2639 | ((env->PCXI & MASK_PCXI_PIE_1_3) >> 15); 2640 /* ICR.CCPN = PCXI.PCPN; */ 2641 env->ICR = (env->ICR & ~MASK_ICR_CCPN) | 2642 ((env->PCXI & MASK_PCXI_PCPN) >> 24); 2643 /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */ 2644 env->PCXI = cpu_ldl_data(env, env->DCX); 2645 psw_write(env, cpu_ldl_data(env, env->DCX+4)); 2646 env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8); 2647 env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12); 2648 2649 if (tricore_feature(env, TRICORE_FEATURE_131)) { 2650 env->DBGTCR = 0; 2651 } 2652 } 2653 2654 void helper_ldlcx(CPUTriCoreState *env, uint32_t ea) 2655 { 2656 uint32_t dummy; 2657 /* insn doesn't load PCXI and RA */ 2658 restore_context_lower(env, ea, &dummy, &dummy); 2659 } 2660 2661 void helper_lducx(CPUTriCoreState *env, uint32_t ea) 2662 { 2663 uint32_t dummy; 2664 /* insn doesn't load PCXI and PSW */ 2665 restore_context_upper(env, ea, &dummy, &dummy); 2666 } 2667 2668 void helper_stlcx(CPUTriCoreState *env, uint32_t ea) 2669 { 2670 save_context_lower(env, ea); 2671 } 2672 2673 void helper_stucx(CPUTriCoreState *env, uint32_t ea) 2674 { 2675 save_context_upper(env, ea); 2676 } 2677 2678 void helper_svlcx(CPUTriCoreState *env) 2679 { 2680 target_ulong tmp_FCX; 2681 target_ulong ea; 2682 target_ulong new_FCX; 2683 2684 if (env->FCX == 0) { 2685 /* FCU trap */ 2686 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); 2687 } 2688 /* tmp_FCX = FCX; */ 2689 tmp_FCX = env->FCX; 2690 /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 2691 ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 2692 ((env->FCX & MASK_FCX_FCXO) << 6); 2693 /* new_FCX = M(EA, word); */ 2694 new_FCX = cpu_ldl_data(env, ea); 2695 /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 2696 A[12], A[13], A[14], A[15], D[12], D[13], D[14], 2697 D[15]}; */ 2698 save_context_lower(env, ea); 2699 2700 /* PCXI.PCPN = ICR.CCPN; */ 2701 env->PCXI = (env->PCXI & 0xffffff) + 2702 ((env->ICR & MASK_ICR_CCPN) << 24); 2703 /* PCXI.PIE = ICR.IE; */ 2704 env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE_1_3) + 2705 ((env->ICR & MASK_ICR_IE_1_3) << 15)); 2706 /* PCXI.UL = 0; */ 2707 env->PCXI &= ~MASK_PCXI_UL; 2708 2709 /* PCXI[19: 0] = FCX[19: 0]; */ 2710 env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 2711 /* FCX[19: 0] = new_FCX[19: 0]; */ 2712 env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 2713 2714 /* if (tmp_FCX == LCX) trap(FCD);*/ 2715 if (tmp_FCX == env->LCX) { 2716 /* FCD trap */ 2717 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); 2718 } 2719 } 2720 2721 void helper_svucx(CPUTriCoreState *env) 2722 { 2723 target_ulong tmp_FCX; 2724 target_ulong ea; 2725 target_ulong new_FCX; 2726 2727 if (env->FCX == 0) { 2728 /* FCU trap */ 2729 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); 2730 } 2731 /* tmp_FCX = FCX; */ 2732 tmp_FCX = env->FCX; 2733 /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 2734 ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 2735 ((env->FCX & MASK_FCX_FCXO) << 6); 2736 /* new_FCX = M(EA, word); */ 2737 new_FCX = cpu_ldl_data(env, ea); 2738 /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 2739 A[12], A[13], A[14], A[15], D[12], D[13], D[14], 2740 D[15]}; */ 2741 save_context_upper(env, ea); 2742 2743 /* PCXI.PCPN = ICR.CCPN; */ 2744 env->PCXI = (env->PCXI & 0xffffff) + 2745 ((env->ICR & MASK_ICR_CCPN) << 24); 2746 /* PCXI.PIE = ICR.IE; */ 2747 env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE_1_3) + 2748 ((env->ICR & MASK_ICR_IE_1_3) << 15)); 2749 /* PCXI.UL = 1; */ 2750 env->PCXI |= MASK_PCXI_UL; 2751 2752 /* PCXI[19: 0] = FCX[19: 0]; */ 2753 env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 2754 /* FCX[19: 0] = new_FCX[19: 0]; */ 2755 env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 2756 2757 /* if (tmp_FCX == LCX) trap(FCD);*/ 2758 if (tmp_FCX == env->LCX) { 2759 /* FCD trap */ 2760 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); 2761 } 2762 } 2763 2764 void helper_rslcx(CPUTriCoreState *env) 2765 { 2766 target_ulong ea; 2767 target_ulong new_PCXI; 2768 /* if (PCXI[19: 0] == 0) then trap(CSU); */ 2769 if ((env->PCXI & 0xfffff) == 0) { 2770 /* CSU trap */ 2771 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC()); 2772 } 2773 /* if (PCXI.UL == 1) then trap(CTYP); */ 2774 if ((env->PCXI & MASK_PCXI_UL) != 0) { 2775 /* CTYP trap */ 2776 raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC()); 2777 } 2778 /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 2779 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 2780 ((env->PCXI & MASK_PCXI_PCXO) << 6); 2781 /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2782 A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 2783 restore_context_lower(env, ea, &env->gpr_a[11], &new_PCXI); 2784 /* M(EA, word) = FCX; */ 2785 cpu_stl_data(env, ea, env->FCX); 2786 /* M(EA, word) = FCX; */ 2787 cpu_stl_data(env, ea, env->FCX); 2788 /* FCX[19: 0] = PCXI[19: 0]; */ 2789 env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 2790 /* PCXI = new_PCXI; */ 2791 env->PCXI = new_PCXI; 2792 } 2793 2794 void helper_psw_write(CPUTriCoreState *env, uint32_t arg) 2795 { 2796 psw_write(env, arg); 2797 } 2798 2799 uint32_t helper_psw_read(CPUTriCoreState *env) 2800 { 2801 return psw_read(env); 2802 } 2803