Previous 199869 Revisions Next

r20787 Thursday 7th February, 2013 at 03:01:34 UTC by Ryan Holtz
arm7ops.c: Fix SMLAL opcode. [MooglyGuy]

nw - looks like another dodgy one.
[src/emu/cpu/arm7]arm7drc.c arm7ops.c

trunk/src/emu/cpu/arm7/arm7drc.c
r20786r20787
23832383   else if ((insn & 0x0ff00090) == 0x01000080) // SMLAxy - v5
23842384   {
23852385      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;
23892389
2390      INT32 src1 = GET_REGISTER(arm, insn&0xf);
2391      INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf);
2392      INT32 res1;
2393
23942390      UML_MOV(block, I0, DRC_REG(rm));
2395      UML_MOV(block, I1, DRC_REG(rr));
2391      UML_MOV(block, I1, DRC_REG(rn));
23962392
23972393      // select top and bottom halves of src1/src2 and sign extend if necessary
23982394      if (insn & 0x20)
23992395      {
24002396         UML_SHR(block, I0, I0, 16);
24012397      }
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);
24112399
24122400      if (insn & 0x40)
24132401      {
2414         src2 >>= 16;
2402         UML_SHR(block, I1, I1, 16);
24152403      }
2416      else
2417      {
2418         src2 &= 0xffff;
2419         if (src2 & 0x8000)
2420         {
2421            src2 |= 0xffff;
2422         }
2423      }
2404      UML_SEXT(block, I0, I0, SIZE_WORD);
24242405
24252406      // 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);
24272412      // 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);
24322416   }
24332417   else if ((insn & 0x0ff00090) == 0x01400080) // SMLALxy - v5
24342418   {
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;
24382423
2424      UML_MOV(block, I0, DRC_REG(rm));
2425      UML_MOV(block, I1, DRC_REG(rn));
2426
24392427      // select top and bottom halves of src1/src2 and sign extend if necessary
24402428      if (insn & 0x20)
24412429      {
2442         src1 >>= 16;
2430         UML_SHR(block, I0, I0, 16);
24432431      }
2444      else
2445      {
2446         src1 &= 0xffff;
2447         if (src1 & 0x8000)
2448         {
2449            src1 |= 0xffff;
2450         }
2451      }
2432      UML_SEXT(block, I0, I0, SIZE_WORD);
24522433
24532434      if (insn & 0x40)
24542435      {
2455         src2 >>= 16;
2436         UML_SHR(block, I1, I1, 16);
24562437      }
2457      else
2458      {
2459         src2 &= 0xffff;
2460         if (src2 & 0x8000)
2461         {
2462            src2 |= 0xffff;
2463         }
2464      }
2438      UML_SEXT(block, I0, I0, SIZE_WORD);
24652439
2440      // do the signed multiply
2441      UML_MULS(block, I0, I1, I0, I1);
2442
24662443      dst = (INT64)GET_REGISTER(arm, (insn>>12)&0xf);
24672444      dst |= (INT64)GET_REGISTER(arm, (insn>>16)&0xf)<<32;
24682445
trunk/src/emu/cpu/arm7/arm7ops.c
r20786r20787
16521652      INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf);
16531653      INT64 dst;
16541654
1655      // select top and bottom halves of src1/src2 and sign extend if necessary
1656      if (insn & 0x20)
1657      {
1658         src1 >>= 16;
1659      }
1660      else
1661      {
1662         src1 &= 0xffff;
1663         if (src1 & 0x8000)
1664         {
1665            src1 |= 0xffff;
1666         }
1667      }
1668
1669      if (insn & 0x40)
1670      {
1671         src2 >>= 16;
1672      }
1673      else
1674      {
1675         src2 &= 0xffff;
1676         if (src2 & 0x8000)
1677         {
1678            src2 |= 0xffff;
1679         }
1680      }
1681
16821655      dst = (INT64)GET_REGISTER(arm, (insn>>12)&0xf);
16831656      dst |= (INT64)GET_REGISTER(arm, (insn>>16)&0xf)<<32;
16841657
r20786r20787
16861659      dst += (INT64)src1 * (INT64)src2;
16871660
16881661      // write back the result
1689      SET_REGISTER(cpustart, (insn>>12)&0xf, (UINT32)(dst&0xffffffff));
1690      SET_REGISTER(cpustart, (insn>>16)&0xf, (UINT32)(dst>>32));
1662      SET_REGISTER(cpustart, (insn>>12)&0xf, (UINT32)dst);
1663      SET_REGISTER(cpustart, (insn>>16)&0xf, (UINT32)(dst >> 32));
16911664   }
16921665   else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5
16931666   {

Previous 199869 Revisions Next


© 1997-2024 The MAME Team