trunk/src/emu/cpu/arm7/arm7drc.c
| r20786 | r20787 | |
| 2383 | 2383 | else if ((insn & 0x0ff00090) == 0x01000080) // SMLAxy - v5 |
| 2384 | 2384 | { |
| 2385 | 2385 | UINT32 rm = insn&0xf; |
| 2386 | | UINT32 rn = (insn>>16)&0xf; |
| 2387 | | UINT32 rd = (insn>>12)&0xf; |
| 2388 | | UINT32 rr = (insn>>8)&0xf; |
| 2386 | UINT32 rn = (insn>>8)&0xf; |
| 2387 | UINT32 rd = (insn>>16)&0xf; |
| 2388 | UINT32 ra = (insn>>12)&0xf; |
| 2389 | 2389 | |
| 2390 | | INT32 src1 = GET_REGISTER(arm, insn&0xf); |
| 2391 | | INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf); |
| 2392 | | INT32 res1; |
| 2393 | | |
| 2394 | 2390 | UML_MOV(block, I0, DRC_REG(rm)); |
| 2395 | | UML_MOV(block, I1, DRC_REG(rr)); |
| 2391 | UML_MOV(block, I1, DRC_REG(rn)); |
| 2396 | 2392 | |
| 2397 | 2393 | // select top and bottom halves of src1/src2 and sign extend if necessary |
| 2398 | 2394 | if (insn & 0x20) |
| 2399 | 2395 | { |
| 2400 | 2396 | UML_SHR(block, I0, I0, 16); |
| 2401 | 2397 | } |
| 2402 | | else |
| 2403 | | { |
| 2404 | | UML_SEXT(block, I1, I1, SIZE_WORD); |
| 2405 | | src1 &= 0xffff; |
| 2406 | | if (src1 & 0x8000) |
| 2407 | | { |
| 2408 | | src1 |= 0xffff; |
| 2409 | | } |
| 2410 | | } |
| 2398 | UML_SEXT(block, I0, I0, SIZE_WORD); |
| 2411 | 2399 | |
| 2412 | 2400 | if (insn & 0x40) |
| 2413 | 2401 | { |
| 2414 | | src2 >>= 16; |
| 2402 | UML_SHR(block, I1, I1, 16); |
| 2415 | 2403 | } |
| 2416 | | else |
| 2417 | | { |
| 2418 | | src2 &= 0xffff; |
| 2419 | | if (src2 & 0x8000) |
| 2420 | | { |
| 2421 | | src2 |= 0xffff; |
| 2422 | | } |
| 2423 | | } |
| 2404 | UML_SEXT(block, I0, I0, SIZE_WORD); |
| 2424 | 2405 | |
| 2425 | 2406 | // do the signed multiply |
| 2426 | | res1 = src1 * src2; |
| 2407 | UML_MULS(block, I0, I1, I0, I1); |
| 2408 | UML_DSHL(block, I0, I0, 32); |
| 2409 | UML_DOR(block, I0, I0, I1); |
| 2410 | UML_MOV(block, I1, DRC_REG(ra)); |
| 2411 | UML_DADD(block, I0, I0, I1); |
| 2427 | 2412 | // and the accumulate. NOTE: only the accumulate can cause an overflow, which is why we do it this way. |
| 2428 | | saturate_qbit_overflow(arm, (INT64)res1 + (INT64)GET_REGISTER(arm, (insn>>12)&0xf)); |
| 2429 | | |
| 2430 | | SET_REGISTER(arm, (insn>>16)&0xf, res1 + GET_REGISTER(arm, (insn>>12)&0xf)); |
| 2431 | | R15 += 4; |
| 2413 | saturate_qbit_overflow(arm, block); |
| 2414 | UML_MOV(block, DRC_REG(rd), I0); |
| 2415 | UML_ADD(block, DRC_PC, DRC_PC, 4); |
| 2432 | 2416 | } |
| 2433 | 2417 | else if ((insn & 0x0ff00090) == 0x01400080) // SMLALxy - v5 |
| 2434 | 2418 | { |
| 2435 | | INT32 src1 = GET_REGISTER(arm, insn&0xf); |
| 2436 | | INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf); |
| 2437 | | INT64 dst; |
| 2419 | UINT32 rm = insn&0xf; |
| 2420 | UINT32 rn = (insn>>8)&0xf; |
| 2421 | UINT32 rdh = (insn>>16)&0xf; |
| 2422 | UINT32 rdl = (insn>>12)&0xf; |
| 2438 | 2423 | |
| 2424 | UML_MOV(block, I0, DRC_REG(rm)); |
| 2425 | UML_MOV(block, I1, DRC_REG(rn)); |
| 2426 | |
| 2439 | 2427 | // select top and bottom halves of src1/src2 and sign extend if necessary |
| 2440 | 2428 | if (insn & 0x20) |
| 2441 | 2429 | { |
| 2442 | | src1 >>= 16; |
| 2430 | UML_SHR(block, I0, I0, 16); |
| 2443 | 2431 | } |
| 2444 | | else |
| 2445 | | { |
| 2446 | | src1 &= 0xffff; |
| 2447 | | if (src1 & 0x8000) |
| 2448 | | { |
| 2449 | | src1 |= 0xffff; |
| 2450 | | } |
| 2451 | | } |
| 2432 | UML_SEXT(block, I0, I0, SIZE_WORD); |
| 2452 | 2433 | |
| 2453 | 2434 | if (insn & 0x40) |
| 2454 | 2435 | { |
| 2455 | | src2 >>= 16; |
| 2436 | UML_SHR(block, I1, I1, 16); |
| 2456 | 2437 | } |
| 2457 | | else |
| 2458 | | { |
| 2459 | | src2 &= 0xffff; |
| 2460 | | if (src2 & 0x8000) |
| 2461 | | { |
| 2462 | | src2 |= 0xffff; |
| 2463 | | } |
| 2464 | | } |
| 2438 | UML_SEXT(block, I0, I0, SIZE_WORD); |
| 2465 | 2439 | |
| 2440 | // do the signed multiply |
| 2441 | UML_MULS(block, I0, I1, I0, I1); |
| 2442 | |
| 2466 | 2443 | dst = (INT64)GET_REGISTER(arm, (insn>>12)&0xf); |
| 2467 | 2444 | dst |= (INT64)GET_REGISTER(arm, (insn>>16)&0xf)<<32; |
| 2468 | 2445 | |