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