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