Lines Matching defs:rN
2369 IRExpr* mk_EA_reg_plusminus_imm12 ( UInt rN, UInt bU, UInt imm12,
2372 vassert(rN < 16);
2376 DIS(buf, "[r%u, #%c%u]", rN, opChar, imm12);
2379 getIRegA(rN),
2388 IRExpr* mk_EA_reg_plusminus_shifted_reg ( UInt rN, UInt bU, UInt rM,
2392 vassert(rN < 16);
2403 DIS(buf, "[r%u, %c r%u LSL #%u]", rN, opChar, rM, imm5);
2413 rN, opChar, rM, imm5 == 0 ? 32 : imm5);
2425 rN, opChar, rM, imm5 == 0 ? 32 : imm5);
2436 DIS(buf, "[r%u, %cr%u, RRX]", rN, opChar, rM);
2444 DIS(buf, "[r%u, %cr%u, ROR #%u]", rN, opChar, rM, imm5);
2452 getIRegA(rN), index);
2458 IRExpr* mk_EA_reg_plusminus_imm8 ( UInt rN, UInt bU, UInt imm8,
2461 vassert(rN < 16);
2465 DIS(buf, "[r%u, #%c%u]", rN, opChar, imm8);
2468 getIRegA(rN),
2475 IRExpr* mk_EA_reg_plusminus_reg ( UInt rN, UInt bU, UInt rM,
2478 vassert(rN < 16);
2483 DIS(buf, "[r%u, %c r%u]", rN, opChar, rM);
2485 getIRegA(rN), index);
8332 UInt rN = INSN(19,16);
8350 assign(initialRn, isT ? getIRegT(rN) : getIRegA(rN));
8394 DIP("}, [r%u]", rN);
8491 DIP("}, [r%u]", rN);
8505 putIRegT(rN, e, IRTemp_INVALID);
8507 putIRegA(rN, e, IRTemp_INVALID, Ijk_Boring);
8513 putIRegT(rN, e, IRTemp_INVALID);
8515 putIRegA(rN, e, IRTemp_INVALID, Ijk_Boring);
8779 putIRegT(rN, e, IRTemp_INVALID);
8781 putIRegA(rN, e, IRTemp_INVALID, Ijk_Boring);
8798 DIP("}, [r%u]", rN);
9000 /* ------------ smulwb<y><c> <Rd>,<Rn>,<Rm> ------------- */
9001 /* ------------ smulwt<y><c> <Rd>,<Rn>,<Rm> ------------- */
9061 /* ------------ pkhbt<c> Rd, Rn, Rm {,LSL #imm} ------------- */
9062 /* ------------ pkhtb<c> Rd, Rn, Rm {,ASR #imm} ------------- */
9122 /* ---------- usat<c> <Rd>,#<imm5>,<Rn>{,<shift>} ----------- */
9180 /* ----------- ssat<c> <Rd>,#<imm5>,<Rn>{,<shift>} ----------- */
9238 /* ----------- ssat16<c> <Rd>,#<imm>,<Rn> ----------- */
9302 /* -------------- usat16<c> <Rd>,#<imm4>,<Rn> --------------- */
9363 /* -------------- uadd16<c> <Rd>,<Rn>,<Rm> -------------- */
9412 /* -------------- sadd16<c> <Rd>,<Rn>,<Rm> -------------- */
9462 /* ---------------- usub16<c> <Rd>,<Rn>,<Rm> ---------------- */
9512 /* -------------- ssub16<c> <Rd>,<Rn>,<Rm> -------------- */
9562 /* ----------------- uadd8<c> <Rd>,<Rn>,<Rm> ---------------- */
9611 /* ------------------- sadd8<c> <Rd>,<Rn>,<Rm> ------------------ */
9661 /* ------------------- usub8<c> <Rd>,<Rn>,<Rm> ------------------ */
9711 /* ------------------- ssub8<c> <Rd>,<Rn>,<Rm> ------------------ */
9761 /* ------------------ qadd8<c> <Rd>,<Rn>,<Rm> ------------------- */
9806 /* ------------------ qsub8<c> <Rd>,<Rn>,<Rm> ------------------- */
9851 /* ------------------ uqadd8<c> <Rd>,<Rn>,<Rm> ------------------ */
9896 /* ------------------ uqsub8<c> <Rd>,<Rn>,<Rm> ------------------ */
9941 /* ----------------- uhadd8<c> <Rd>,<Rn>,<Rm> ------------------- */
9986 /* ----------------- uhadd16<c> <Rd>,<Rn>,<Rm> ------------------- */
10031 /* ----------------- shadd8<c> <Rd>,<Rn>,<Rm> ------------------- */
10076 /* ------------------ qadd16<c> <Rd>,<Rn>,<Rm> ------------------ */
10121 /* ------------------ qsub16<c> <Rd>,<Rn>,<Rm> ------------------ */
10166 /* ------------------- qsax<c> <Rd>,<Rn>,<Rm> ------------------- */
10237 /* ------------------- qasx<c> <Rd>,<Rn>,<Rm> ------------------- */
10305 /* ------------------- sasx<c> <Rd>,<Rn>,<Rm> ------------------- */
10379 /* --------------- smuad, smuadx<c><Rd>,<Rn>,<Rm> --------------- */
10380 /* --------------- smsad, smsadx<c><Rd>,<Rn>,<Rm> --------------- */
10458 /* --------------- smlad{X}<c> <Rd>,<Rn>,<Rm>,<Ra> -------------- */
10459 /* --------------- smlsd{X}<c> <Rd>,<Rn>,<Rm>,<Ra> -------------- */
10549 /* ----- smlabb, smlabt, smlatb, smlatt <Rd>,<Rn>,<Rm>,<Ra> ----- */
10619 /* ----- smlalbb, smlalbt, smlaltb, smlaltt <Rd>,<Rn>,<Rm>,<Ra> ----- */
10694 /* ----- smlawb, smlawt <Rd>,<Rn>,<Rm>,<Ra> ----- */
10765 /* ------------------- sel<c> <Rd>,<Rn>,<Rm> -------------------- */
10853 /* ----------------- uxtab16<c> Rd,Rn,Rm{,rot} ------------------ */
10916 /* --------------- usad8 Rd,Rn,Rm ---------------- */
10917 /* --------------- usada8 Rd,Rn,Rm,Ra ---------------- */
10919 UInt rD = 99, rN = 99, rM = 99, rA = 99;
10924 rN = INSNT0(3,0);
10928 if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM) && rA != 13)
10937 rN = INSNA(3,0);
10938 if (rD != 15 && rN != 15 && rM != 15 /* but rA can be 15 */)
10945 IRExpr* rNe = isT ? getIRegT(rN) : getIRegA(rN);
10959 nCC(conq), rD, rN, rM );
10962 nCC(conq), rD, rN, rM, rA );
10969 /* ------------------ qadd<c> <Rd>,<Rn>,<Rm> ------------------- */
11020 /* ------------------ qdadd<c> <Rd>,<Rm>,<Rn> ------------------- */
11079 /* ------------------ qsub<c> <Rd>,<Rn>,<Rm> ------------------- */
11130 /* ------------------ qdsub<c> <Rd>,<Rm>,<Rn> ------------------- */
11189 /* ------------------ uqsub16<c> <Rd>,<Rn>,<Rm> ------------------ */
11234 /* ----------------- shadd16<c> <Rd>,<Rn>,<Rm> ------------------- */
11279 /* ----------------- uhsub8<c> <Rd>,<Rn>,<Rm> ------------------- */
11324 /* ----------------- uhsub16<c> <Rd>,<Rn>,<Rm> ------------------- */
11369 /* ------------------ uqadd16<c> <Rd>,<Rn>,<Rm> ------------------ */
11414 /* ------------------- uqsax<c> <Rd>,<Rn>,<Rm> ------------------- */
11483 /* ------------------- uqasx<c> <Rd>,<Rn>,<Rm> ------------------- */
11551 /* ------------------- usax<c> <Rd>,<Rn>,<Rm> ------------------- */
11629 /* ------------------- uasx<c> <Rd>,<Rn>,<Rm> ------------------- */
11705 /* ------------------- ssax<c> <Rd>,<Rn>,<Rm> ------------------- */
11779 /* ----------------- shsub8<c> <Rd>,<Rn>,<Rm> ------------------- */
11824 /* ----------------- sxtab16<c> Rd,Rn,Rm{,rot} ------------------ */
11899 /* ----------------- shasx<c> <Rd>,<Rn>,<Rm> ------------------- */
11996 /* ----------------- uhasx<c> <Rd>,<Rn>,<Rm> ------------------- */
12093 /* ----------------- shsax<c> <Rd>,<Rn>,<Rm> ------------------- */
12190 /* ----------------- uhsax<c> <Rd>,<Rn>,<Rm> ------------------- */
12287 /* ----------------- shsub16<c> <Rd>,<Rn>,<Rm> ------------------- */
12332 /* ----------------- smmls{r}<c> <Rd>,<Rn>,<Rm>,<Ra> ------------------- */
12334 UInt rD = 99, rN = 99, rM = 99, rA = 99;
12346 rN = INSNT0(3,0);
12348 && !isBadRegT(rN) && !isBadRegT(rM) && !isBadRegT(rA))
12359 rN = INSNA(3,0);
12360 if (rD != 15 && rM != 15 && rN != 15)
12369 assign( irt_rN, isT ? getIRegT(rN) : getIRegA(rN) );
12383 round ? "r" : "", nCC(conq), rD, rN, rM, rA);
12389 /* -------------- smlald{x}<c> <RdLo>,<RdHi>,<Rn>,<Rm> ---------------- */
12391 UInt rN = 99, rDlo = 99, rDhi = 99, rM = 99;
12398 rN = INSNT0(3,0);
12403 if (!isBadRegT(rDlo) && !isBadRegT(rDhi) && !isBadRegT(rN)
12410 rN = INSNA(3,0);
12416 && rN != 15 && rM != 15 && rDlo != rDhi)
12433 assign( irt_rN, isT ? getIRegT(rN) : getIRegA(rN));
12472 m_swap ? 'x' : ' ', nCC(conq), rDlo, rDhi, rN, rM);
12478 /* -------------- smlsld{x}<c> <RdLo>,<RdHi>,<Rn>,<Rm> ---------------- */
12480 UInt rN = 99, rDlo = 99, rDhi = 99, rM = 99;
12487 rN = INSNT0(3,0);
12492 if (!isBadRegT(rDlo) && !isBadRegT(rDhi) && !isBadRegT(rN) &&
12499 rN = INSNA(3,0);
12505 rN != 15 && rM != 15 && rDlo != rDhi)
12521 assign( irt_rN, isT ? getIRegT(rN) : getIRegA(rN) );
12560 m_swap ? 'x' : ' ', nCC(conq), rDlo, rDhi, rN, rM);
12586 UInt rN, /* base reg */
12589 UInt bW, /* 1: writeback to Rn */
12596 /* Get hold of the old Rn value. We might need to write its value
12601 updates Rn in the guest state before any transfers take place.
12602 We have to do this as per comments below, in order that if Rn is
12606 assign(oldRnT, arm ? getIRegA(rN) : getIRegT(rN));
12621 // For xxMDA and xxMDB, update Rn first if necessary. We have
12627 // do the transfer first, and then update rN afterwards.
12636 putIRegA( rN, e, IRTemp_INVALID, Ijk_Boring );
12638 putIRegT( rN, e, IRTemp_INVALID );
12642 // in memory relative to the anchor. If the base reg (Rn) is part
12657 vassert(r != rN);
12670 if (bW == 0 && (regList & (1<<rN)) != 0) {
12675 vex_printf("\nREG_LIST_PRE: (rN=%d)\n", rN);
12683 if (xReg[i] == rN)
12726 if (rN == 13 && bL == 1 && bINC && !bBEFORE && bW == 1) {
12747 /* if we're storing Rn, make sure we use the correct
12750 r == rN ? mkexpr(oldRnT)
12756 // do the transfer first, and then update rN afterwards.
12760 putIRegA( rN, e, IRTemp_INVALID, Ijk_Boring );
12762 putIRegT( rN, e, IRTemp_INVALID );
12830 C4-100, C5-26 1 FSTMX cond 1100 1000 Rn Dd 1011 offset
12831 C4-100, C5-28 2 FSTMIAX cond 1100 1010 Rn Dd 1011 offset
12832 C4-100, C5-30 3 FSTMDBX cond 1101 0010 Rn Dd 1011 offset
12834 C4-42, C5-26 1 FLDMX cond 1100 1001 Rn Dd 1011 offset
12835 C4-42, C5-28 2 FLDMIAX cond 1100 1011 Rn Dd 1011 offset
12836 C4-42, C5-30 3 FLDMDBX cond 1101 0011 Rn Dd 1011 offset
12840 IA/DB: Rn is changed by (4 + 8 x # regs transferred)
12843 1 at-Rn (access at Rn)
12844 2 ia-Rn (access at Rn, then Rn += 4+8n)
12845 3 db-Rn (Rn -= 4+8n, then access at Rn)
12854 UInt rN = INSN(19,16);
12872 if (rN == 15 && (summary == 2 || summary == 3 || isT))
12895 /* get the old Rn value */
12897 assign(rnT, align4if(isT ? getIRegT(rN) : getIRegA(rN),
12898 rN == 15));
12900 /* make a new value for Rn, post-insn */
12913 /* update Rn if necessary -- in case 3, we're moving it down, so
12918 putIRegT(rN, mkexpr(rnTnew), IRTemp_INVALID);
12920 putIRegA(rN, mkexpr(rnTnew), IRTemp_INVALID, Ijk_Boring);
12933 /* update Rn if necessary -- in case 2, we're moving it up, so
12938 putIRegT(rN, mkexpr(rnTnew), IRTemp_INVALID);
12940 putIRegA(rN, mkexpr(rnTnew), IRTemp_INVALID, Ijk_Boring);
12946 nm, nCC(conq), rN, dD, dD + nRegs - 1);
12949 nm, nCC(conq), rN, dD, dD + nRegs - 1);
12952 nm, nCC(conq), rN, dD, dD + nRegs - 1);
12967 C4-96, C5-26 1 FSTMD cond 1100 1000 Rn Dd 1011 offset
12968 C4-96, C5-28 2 FSTMDIA cond 1100 1010 Rn Dd 1011 offset
12969 C4-96, C5-30 3 FSTMDDB cond 1101 0010 Rn Dd 1011 offset
12971 C4-38, C5-26 1 FLDMD cond 1100 1001 Rn Dd 1011 offset
12972 C4-38, C5-28 2 FLDMIAD cond 1100 1011 Rn Dd 1011 offset
12973 C4-38, C5-30 3 FLDMDBD cond 1101 0011 Rn Dd 1011 offset
12977 IA/DB: Rn is changed by (8 x # regs transferred)
12980 1 at-Rn (access at Rn)
12981 2 ia-Rn (access at Rn, then Rn += 8n)
12982 3 db-Rn (Rn -= 8n, then access at Rn)
12991 UInt rN = INSN(19,16);
13009 if (rN == 15 && (summary == 2 || summary == 3 || isT))
13032 /* get the old Rn value */
13034 assign(rnT, align4if(isT ? getIRegT(rN) : getIRegA(rN),
13035 rN == 15));
13037 /* make a new value for Rn, post-insn */
13050 /* update Rn if necessary -- in case 3, we're moving it down, so
13055 putIRegT(rN, mkexpr(rnTnew), IRTemp_INVALID);
13057 putIRegA(rN, mkexpr(rnTnew), IRTemp_INVALID, Ijk_Boring);
13070 /* update Rn if necessary -- in case 2, we're moving it up, so
13075 putIRegT(rN, mkexpr(rnTnew), IRTemp_INVALID);
13077 putIRegA(rN, mkexpr(rnTnew), IRTemp_INVALID, Ijk_Boring);
13083 nm, nCC(conq), rN, dD, dD + nRegs - 1);
13086 nm, nCC(conq), rN, dD, dD + nRegs - 1);
13089 nm, nCC(conq), rN, dD, dD + nRegs - 1);
13146 // VMOV dM, rD, rN
13150 UInt rN = INSN(19,16); /* hi32 */
13151 if (rD == 15 || rN == 15 || (isT && (rD == 13 || rN == 13))) {
13157 isT ? getIRegT(rN) : getIRegA(rN),
13160 DIP("vmov%s d%u, r%u, r%u\n", nCC(conq), dM, rD, rN);
13166 // VMOV rD, rN, dM
13170 UInt rN = INSN(19,16); /* hi32 */
13171 if (rD == 15 || rN == 15 || (isT && (rD == 13 || rN == 13))
13172 || rD == rN) {
13180 putIRegT(rN, hi32, condT);
13183 putIRegA(rN, hi32, condT, Ijk_Boring);
13186 DIP("vmov%s r%u, r%u, d%u\n", nCC(conq), rD, rN, dM);
13192 // VMOV sD, sD+1, rN, rM
13195 UInt rN = INSN(15,12);
13197 if (rM == 15 || rN == 15 || (isT && (rM == 13 || rN == 13))
13202 unop(Iop_ReinterpI32asF32, isT ? getIRegT(rN) : getIRegA(rN)),
13208 nCC(conq), sD, sD + 1, rN, rM);
13213 // VMOV rN, rM, sD, sD+1
13216 UInt rN = INSN(15,12);
13218 if (rM == 15 || rN == 15 || (isT && (rM == 13 || rN == 13))
13219 || sD == 31 || rN == rM) {
13225 putIRegT(rN, res0, condT);
13228 putIRegA(rN, res0, condT, Ijk_Boring);
13232 nCC(conq), rN, rM, sD, sD + 1);
13286 UInt rN = (INSN(7,7) << 4) | INSN(19,16);
13298 getDRegI64(rN),
13305 rT, rN, index);
13312 getDRegI64(rN),
13319 rT, rN, index);
13324 IRExpr* e = binop(Iop_GetElem32x2, getDRegI64(rN), mkU8(index));
13329 DIP("vmov%s.32 r%u, d%u[%u]\n", nCC(conq), rT, rN, index);
13427 UInt rN = INSN(19,16);
13441 align4if(isT ? getIRegT(rN) : getIRegA(rN),
13442 rN == 15),
13450 bL ? "ld" : "st", nCC(conq), dD, rN,
13736 C4-98, C5-26 1 FSTMD cond 1100 1x00 Rn Fd 1010 offset
13737 C4-98, C5-28 2 FSTMDIA cond 1100 1x10 Rn Fd 1010 offset
13738 C4-98, C5-30 3 FSTMDDB cond 1101 0x10 Rn Fd 1010 offset
13740 C4-40, C5-26 1 FLDMD cond 1100 1x01 Rn Fd 1010 offset
13741 C4-40, C5-26 2 FLDMIAD cond 1100 1x11 Rn Fd 1010 offset
13742 C4-40, C5-26 3 FLDMDBD cond 1101 0x11 Rn Fd 1010 offset
13746 IA/DB: Rn is changed by (4 x # regs transferred)
13749 1 at-Rn (access at Rn)
13750 Rn (access at Rn, then Rn += 4n)
13751 3 db-Rn (Rn -= 4n, then access at Rn)
13761 UInt rN = INSN(19,16);
13779 if (rN == 15 && (summary == 2 || summary == 3 || isT))
13802 /* get the old Rn value */
13804 assign(rnT, align4if(isT ? getIRegT(rN) : getIRegA(rN),
13805 rN == 15));
13807 /* make a new value for Rn, post-insn */
13820 /* update Rn if necessary -- in case 3, we're moving it down, so
13825 putIRegT(rN, mkexpr(rnTnew), IRTemp_INVALID);
13827 putIRegA(rN, mkexpr(rnTnew), IRTemp_INVALID, Ijk_Boring);
13840 /* update Rn if necessary -- in case 2, we're moving it up, so
13845 putIRegT(rN, mkexpr(rnTnew), IRTemp_INVALID);
13847 putIRegA(rN, mkexpr(rnTnew), IRTemp_INVALID, Ijk_Boring);
13853 nm, nCC(conq), rN, fD, fD + nRegs - 1);
13856 nm, nCC(conq), rN, fD, fD + nRegs - 1);
13859 nm, nCC(conq), rN, fD, fD + nRegs - 1);
13910 UInt rN = INSN(19,16);
13924 align4if(isT ? getIRegT(rN) : getIRegA(rN),
13925 rN == 15),
13933 bL ? "ld" : "st", nCC(conq), fD, rN,
14406 UInt rN = INSN(19,16);
14409 DIP("pld [r%u, #%c%u]\n", rN, bU ? '+' : '-', imm12);
14416 UInt rN = INSN(19,16);
14422 IRExpr* eaE = mk_EA_reg_plusminus_shifted_reg(rN, bU, rM,
14439 UInt rN = INSN(19,16);
14442 DIP("pli [r%u, #%c%u]\n", rN, bU ? '+' : '-', imm12);
14709 UInt rN = (insn >> 16) & 0xF; /* 19:16 */
14722 case BITS4(0,1,0,0): /* ADD: Rd = Rn + shifter_operand */
14724 case BITS4(0,0,1,0): /* SUB: Rd = Rn - shifter_operand */
14726 case BITS4(0,0,1,1): /* RSB: Rd = shifter_operand - Rn */
14728 case BITS4(0,0,0,0): /* AND: Rd = Rn & shifter_operand */
14730 case BITS4(1,1,0,0): /* OR: Rd = Rn | shifter_operand */
14732 case BITS4(0,0,0,1): /* EOR: Rd = Rn ^ shifter_operand */
14734 case BITS4(1,1,1,0): /* BIC: Rd = Rn & ~shifter_operand */
14748 assign(rNt, getIRegA(rN));
14758 // reverse-subtract: shifter_operand - Rn
14762 // andn: shifter_operand & ~Rn
14767 // normal: Rn op shifter_operand
14810 name, nCC(INSN_COND), bitS ? "s" : "", rD, rN, dis_buf );
14819 if (rN != 0)
14820 break; /* rN must be zero */
14856 case BITS4(1,0,1,0): /* CMP: (void) Rn - shifter_operand */
14857 case BITS4(1,0,1,1): { /* CMN: (void) Rn + shifter_operand */
14864 assign(rNt, getIRegA(rN));
14877 nCC(INSN_COND), rN, dis_buf );
14882 case BITS4(1,0,0,0): /* TST: (void) Rn & shifter_operand */
14883 case BITS4(1,0,0,1): { /* TEQ: (void) Rn ^ shifter_operand */
14890 assign(rNt, getIRegA(rN));
14908 nCC(INSN_COND), rN, dis_buf );
14913 case BITS4(0,1,0,1): /* ADC: Rd = Rn + shifter_operand + oldC */
14915 case BITS4(0,1,1,0): /* SBC: Rd = Rn - shifter_operand - (oldC ^ 1) */
14917 case BITS4(0,1,1,1): /* RSC: Rd = shifter_operand - Rn - (oldC ^ 1) */
14922 assign(rNt, getIRegA(rN));
14984 name, nCC(INSN_COND), bitS ? "s" : "", rD, rN, dis_buf );
14997 A5-20 1 | 16 cond 0101 UB0L Rn Rd imm12
14998 A5-22 1 | 32 cond 0111 UBOL Rn Rd imm5 sh2 0 Rm
14999 A5-24 2 | 16 cond 0101 UB1L Rn Rd imm12
15000 A5-26 2 | 32 cond 0111 UB1L Rn Rd imm5 sh2 0 Rm
15001 A5-28 3 | 16 cond 0100 UB0L Rn Rd imm12
15002 A5-32 3 | 32 cond 0110 UB0L Rn Rd imm5 sh2 0 Rm
15006 2 at-ea-then-upd (access at ea, then Rn = ea)
15007 3 at-Rn-then-upd (access at Rn, then Rn = ea)
15009 16 Rn +/- imm12
15010 32 Rn +/- Rm sh2 imm5
15041 { UInt rN = (insn >> 16) & 0xF; /* 19:16 */
15061 if (rN == 15) goto after_load_store_ubyte_or_word;
15062 if (bL == 1 && rN == rD) goto after_load_store_ubyte_or_word;
15066 if (rN == 15) goto after_load_store_ubyte_or_word;
15067 if (rN == rM) goto after_load_store_ubyte_or_word;
15068 if (bL == 1 && rN == rD) goto after_load_store_ubyte_or_word;
15079 eaE = mk_EA_reg_plusminus_imm12( rN, bU, imm12, dis_buf );
15082 eaE = mk_EA_reg_plusminus_shifted_reg( rN, bU, rM, sh2, imm5,
15090 /* get the old Rn value */
15092 assign(rnT, getIRegA(rN));
15116 /* Update Rn if necessary. */
15119 putIRegA( rN, mkexpr(eaT), condT, Ijk_Boring );
15144 if (rN == 13 && summary == (3 | 16) && bB == 0) {
15170 /* Update Rn if necessary. */
15175 vassert(rD != rN); /* since we just wrote rD */
15176 putIRegA( rN, mkexpr(eaT), condT, Ijk_Boring );
15186 case 2: DIP("%sr%s%s r%u, %s! (at-EA-then-Rn=EA)\n",
15190 case 3: DIP("%sr%s%s r%u, %s! (at-Rn-then-Rn=EA)\n",
15204 writeback, and the same register is specified for Rd and Rn,
15224 A5-36 1 | 16 cond 0001 U10L Rn Rd im4h 1SH1 im4l
15225 A5-38 1 | 32 cond 0001 U00L Rn Rd 0000 1SH1 Rm
15226 A5-40 2 | 16 cond 0001 U11L Rn Rd im4h 1SH1 im4l
15227 A5-42 2 | 32 cond 0001 U01L Rn Rd 0000 1SH1 Rm
15228 A5-44 3 | 16 cond 0000 U10L Rn Rd im4h 1SH1 im4l
15229 A5-46 3 | 32 cond 0000 U00L Rn Rd 0000 1SH1 Rm
15233 2 at-ea-then-upd (access at ea, then Rn = ea)
15234 3 at-Rn-then-upd (access at Rn, then Rn = ea)
15236 16 Rn +/- imm8
15237 32 Rn +/- Rm
15269 { UInt rN = (insn >> 16) & 0xF; /* 19:16 */
15286 /* Require 11:8 == 0 for Rn +/- Rm cases */
15300 if (rN == 15) goto after_load_store_sbyte_or_hword;
15301 if (bL == 1 && rN == rD) goto after_load_store_sbyte_or_hword;
15305 if (rN == 15) goto after_load_store_sbyte_or_hword;
15306 if (rN == rM) goto after_load_store_sbyte_or_hword;
15307 if (bL == 1 && rN == rD) goto after_load_store_sbyte_or_hword;
15330 eaE = mk_EA_reg_plusminus_imm8( rN, bU, imm8, dis_buf );
15333 eaE = mk_EA_reg_plusminus_reg( rN, bU, rM, dis_buf );
15340 /* get the old Rn value */
15342 assign(rnT, getIRegA(rN));
15392 /* Update Rn if necessary. */
15397 vassert(rD != rN); /* since we just wrote rD */
15398 putIRegA( rN, mkexpr(eaT), condT, Ijk_Boring );
15405 case 2: DIP("%s%s r%u, %s! (at-EA-then-Rn=EA)\n",
15408 case 3: DIP("%s%s r%u, %s! (at-Rn-then-Rn=EA)\n",
15421 writeback, and the same register is specified for Rd and Rn,
15439 // A5-50 LD/STMIA cond 1000 10WL Rn RegList
15440 // A5-51 LD/STMIB cond 1001 10WL Rn RegList
15441 // A5-53 LD/STMDA cond 1000 00WL Rn RegList
15442 // A5-53 LD/STMDB cond 1001 00WL Rn RegList
15449 UInt bW = (insn >> 21) & 1; /* Rn wback=1, no wback=0 */
15450 UInt rN = (insn >> 16) & 0xF;
15458 if (rN == 15) goto after_load_store_multiple;
15461 // if requested to writeback Rn, and this is a load instruction,
15462 // then Rn can't appear in RegList, since we'd have two competing
15463 // new values for Rn. We do however accept this case for store
15465 if (bW == 1 && bL == 1 && ((1 << rN) & regList) > 0)
15477 mk_ldm_stm( True/*arm*/, rN, bINC, bBEFORE, bW, bL, regList );
15482 rN, bW ? "!" : "", regList);
15690 UInt rN = INSN(3,0);
15691 if (rD == 15 || rM == 15 || rN == 15) {
15697 assign(argL, getIRegA(rN));
15701 DIP("sdiv r%u, r%u, r%u\n", rD, rN, rM);
15712 UInt rN = INSN(3,0);
15713 if (rD == 15 || rM == 15 || rN == 15) {
15719 assign(argL, getIRegA(rN));
15723 DIP("udiv r%u, r%u, r%u\n", rD, rN, rM);
15734 UInt rN = INSN(15,12);
15742 if (rD == 15 || rM == 15 || rS == 15 || rN == 15) {
15753 assign( argP, getIRegA(rN));
15775 nCC(INSN_COND), rD, rM, rS, rN);
15888 UInt rN = INSN(3,0);
15889 if (rDlo == 15 || rDhi == 15 || rN == 15 || rM == 15 || rDhi == rDlo) {
15899 assign( argN, getIRegA(rN) );
15915 nCC(INSN_COND), rDlo, rDhi, rN, rM);
15947 UInt rN = INSN(3,0);
15950 if (rN != 15 && (write_nzcvq || write_ge)) {
15952 assign(rNt, getIRegA(rN));
15955 write_nzcvq ? "f" : "", write_ge ? "g" : "", rN);
15997 UInt rN = INSN(19,16);
16006 if (rD == 15 || rN == 15 || rM == 15 || rN == rM || rN == rD) {
16015 assign(tRn, getIRegA(rN));
16039 isB ? "b" : "", nCC(INSN_COND), rD, rM, rN);
16054 UInt rN = INSN(19,16);
16067 if (rT == 15 || rN == 15)
16071 if ((rT & 1) == 1 || rT == 14 || rN == 15)
16084 stmt( IRStmt_LLSC(Iend_LE, res, getIRegA(rN),
16093 nm, nCC(INSN_COND), rT+0, rT+1, rN);
16098 DIP("ldrex%s%s r%u, [r%u]\n", nm, nCC(INSN_COND), rT, rN);
16108 UInt rN = INSN(19,16);
16122 if (rD == 15 || rN == 15 || rT == 15
16123 || rD == rN || rD == rT)
16127 if (rD == 15 || (rT & 1) == 1 || rT == 14 || rN == 15
16128 || rD == rN || rD == rT || rD == rT+1)
16149 stmt( IRStmt_LLSC(Iend_LE, resSC1, getIRegA(rN), mkexpr(data)) );
16161 nm, nCC(INSN_COND), rD, rT, rT+1, rN);
16164 nm, nCC(INSN_COND), rD, rT, rN);
16270 UInt rN = INSN(3,0);
16284 assign(src, rN == 15 ? mkU32(0) : getIRegA(rN));
16298 if (rN == 15) {
16303 nCC(INSN_COND), rD, rN, lsb, msb-lsb+1);
16314 UInt rN = INSN(3,0);
16319 if (rD == 15 || rN == 15 || msb >= 32) {
16329 assign(src, getIRegA(rN));
16341 nCC(INSN_COND), rD, rN, lsb, wm1 + 1);
16351 A5-36 1 | 16 cond 0001 U100 Rn Rd im4h 11S1 im4l
16352 A5-38 1 | 32 cond 0001 U000 Rn Rd 0000 11S1 Rm
16353 A5-40 2 | 16 cond 0001 U110 Rn Rd im4h 11S1 im4l
16354 A5-42 2 | 32 cond 0001 U010 Rn Rd 0000 11S1 Rm
16355 A5-44 3 | 16 cond 0000 U100 Rn Rd im4h 11S1 im4l
16356 A5-46 3 | 32 cond 0000 U000 Rn Rd 0000 11S1 Rm
16360 2 at-ea-then-upd (access at ea, then Rn = ea)
16361 3 at-Rn-then-upd (access at Rn, then Rn = ea)
16363 16 Rn +/- imm8
16364 32 Rn +/- Rm
16396 { UInt rN = (insn >> 16) & 0xF; /* 19:16 */
16407 /* Require 11:8 == 0 for Rn +/- Rm cases */
16421 if (rN == 15) goto after_load_store_doubleword;
16422 if (bS == 0 && (rN == rD || rN == rD+1))
16427 if (rN == 15) goto after_load_store_doubleword;
16428 if (rN == rM) goto after_load_store_doubleword;
16429 if (bS == 0 && (rN == rD || rN == rD+1))
16452 eaE = mk_EA_reg_plusminus_imm8( rN, bU, imm8, dis_buf );
16455 eaE = mk_EA_reg_plusminus_reg( rN, bU, rM, dis_buf );
16462 /* get the old Rn value */
16464 assign(rnT, getIRegA(rN));
16486 && rN == 13 && rN != rD && rN != rD+1
16488 putIRegA( rN, mkexpr(eaT), condT, Ijk_Boring );
16521 /* Update Rn if necessary. */
16525 vassert(rN != 15); /* from checks above */
16527 vassert(rD+0 != rN); /* since we just wrote rD+0 */
16528 vassert(rD+1 != rN); /* since we just wrote rD+1 */
16531 putIRegA( rN, mkexpr(eaT), condT, Ijk_Boring );
16538 case 2: DIP("%s%s r%u, %s! (at-EA-then-Rn=EA)\n",
16541 case 3: DIP("%s%s r%u, %s! (at-Rn-then-Rn=EA)\n",
16556 UInt rN = INSN(19,16);
16561 if (rN == 15/*it's {S,U}XTB*/ || rD == 15 || rM == 15) {
16568 assign(srcL, getIRegA(rN));
16576 isU ? 'u' : 's', nCC(INSN_COND), rD, rN, rM, rot);
16586 UInt rN = INSN(19,16);
16591 if (rN == 15/*it's {S,U}XTH*/ || rD == 15 || rM == 15) {
16598 assign(srcL, getIRegA(rN));
16607 isU ? 'u' : 's', nCC(INSN_COND), rD, rN, rM, rot);
16682 UInt rN = INSN(3,0);
16683 if (rD != 15 && rM != 15 && rN != 15) {
16687 binop(Iop_MullS32, getIRegA(rN), getIRegA(rM)),
16691 nCC(INSN_COND), bitR ? "r" : "", rD, rN, rM);
16704 UInt rN = INSN(3,0);
16705 if (rD != 15 && rM != 15 && rN != 15) {
16711 binop(Iop_MullS32, getIRegA(rN), getIRegA(rM))),
16715 nCC(INSN_COND), bitR ? "r" : "", rD, rN, rM, rA);
16728 ldrt<c> Rt, [Rn] {, #+/-imm12}
16732 UInt rN = INSN(19,16);
16736 if (rT == 15 || rN == 15 || rN == rT) valid = False;
16740 ILGop_Ident32, getIRegA(rN), getIRegA(rT), condT );
16743 getIRegA(rN), mkU32(imm12));
16744 putIRegA(rN, erN, condT, Ijk_Boring);
16746 nCC(INSN_COND), rT, rN, bU ? '+' : '-', imm12);
16753 ldrt<c> Rt, [Rn], +/-Rm{, shift}
16758 UInt rN = INSN(19,16);
16764 if (rT == 15 || rN == 15 || rN == rT || rM == 15
16765 /* || (ArchVersion() < 6 && rM == rN) */)
16770 ILGop_Ident32, getIRegA(rN), getIRegA(rT), condT );
16773 IRExpr* erN = mk_EA_reg_plusminus_shifted_reg(rN, bU, rM,
16775 putIRegA(rN, erN, condT, Ijk_Boring);
16783 ldrbt<c> Rt, [Rn], #+/-imm12
16787 UInt rN = INSN(19,16);
16791 if (rT == 15 || rN == 15 || rN == rT) valid = False;
16795 ILGop_8Uto32, getIRegA(rN), getIRegA(rT), condT );
16798 getIRegA(rN), mkU32(imm12));
16799 putIRegA(rN, erN, condT, Ijk_Boring);
16801 nCC(INSN_COND), rT, rN, bU ? '+' : '-', imm12);
16808 ldrbt<c> Rt, [Rn], +/-Rm{, shift}
16813 UInt rN = INSN(19,16);
16819 if (rT == 15 || rN == 15 || rN == rT || rM == 15
16820 /* || (ArchVersion() < 6 && rM == rN) */)
16825 ILGop_8Uto32, getIRegA(rN), getIRegA(rT), condT );
16828 IRExpr* erN = mk_EA_reg_plusminus_shifted_reg(rN, bU, rM,
16830 putIRegA(rN, erN, condT, Ijk_Boring);
16838 ldrht<c> Rt, [Rn] {, #+/-imm8}
16843 UInt rN = INSN(19,16);
16849 if (rT == 15 || rN == 15 || rN == rT)
16854 ILGop_16Uto32, getIRegA(rN), getIRegA(rT), condT );
16857 getIRegA(rN), mkU32(imm8));
16858 putIRegA(rN, erN, condT, Ijk_Boring);
16860 nCC(INSN_COND), rT, rN, bU ? '+' : '-', imm8);
16867 ldrht<c> Rt, [Rn], +/-Rm
16872 UInt rN = INSN(19,16);
16876 if (rT == 15 || rN == 15 || rN == rT || rM == 15)
16881 ILGop_16Uto32, getIRegA(rN), getIRegA(rT), condT );
16884 getIRegA(rN), getIRegA(rM));
16885 putIRegA(rN, erN, condT, Ijk_Boring);
16887 nCC(INSN_COND), rT, rN, bU ? '+' : '-', rM);
16894 ldrsht<c> Rt, [Rn] {, #+/-imm8}
16899 UInt rN = INSN(19,16);
16905 if (rN == 15 || rT == 15 || rN == rT)
16910 ILGop_16Sto32, getIRegA(rN), getIRegA(rT), condT );
16913 getIRegA(rN), mkU32(imm8));
16914 putIRegA(rN, erN, condT, Ijk_Boring);
16916 nCC(INSN_COND), rT, rN, bU ? '+' : '-', imm8);
16923 ldrsht<c> Rt, [Rn], +/-Rm
16928 UInt rN = INSN(19,16);
16932 if (rN == 15 || rT == 15 || rN == rT || rM == 15)
16937 ILGop_16Sto32, getIRegA(rN), getIRegA(rT), condT );
16940 getIRegA(rN), getIRegA(rM));
16941 putIRegA(rN, erN, condT, Ijk_Boring);
16943 nCC(INSN_COND), rT, rN, bU ? '+' : '-', rM);
16950 ldrsbt<c> Rt, [Rn] {, #+/-imm8}
16955 UInt rN = INSN(19,16);
16961 if (rT == 15 || rN == 15 || rN == rT)
16966 ILGop_8Sto32, getIRegA(rN), getIRegA(rT), condT );
16969 getIRegA(rN), mkU32(imm8));
16970 putIRegA(rN, erN, condT, Ijk_Boring);
16972 nCC(INSN_COND), rT, rN, bU ? '+' : '-', imm8);
16979 ldrsbt<c> Rt, [Rn], +/-Rm
16984 UInt rN = INSN(19,16);
16988 if (rT == 15 || rN == 15 || rN == rT || rM == 15)
16993 ILGop_8Sto32, getIRegA(rN), getIRegA(rT), condT );
16996 getIRegA(rN), getIRegA(rM));
16997 putIRegA(rN, erN, condT, Ijk_Boring);
16999 nCC(INSN_COND), rT, rN, bU ? '+' : '-', rM);
17006 strbt<c> Rt, [Rn], #+/-imm12
17010 UInt rN = INSN(19,16);
17014 if (rT == 15 || rN == 15 || rN == rT) valid = False;
17016 IRExpr* address = getIRegA(rN);
17020 getIRegA(rN), mkU32(imm12));
17021 putIRegA(rN, newRn, condT, Ijk_Boring);
17023 nCC(INSN_COND), rT, rN, bU ? '+' : '-', imm12);
17030 strbt<c> Rt, [Rn], +/-Rm{, shift}
17035 UInt rN = INSN(19,16);
17041 if (rT == 15 || rN == 15 || rN == rT || rM == 15) valid = False;
17043 IRExpr* address = getIRegA(rN);
17047 IRExpr* erN = mk_EA_reg_plusminus_shifted_reg(rN, bU, rM,
17049 putIRegA(rN, erN, condT, Ijk_Boring);
17057 strht<c> Rt, [Rn], #+/-imm8
17062 UInt rN = INSN(19,16);
17068 if (rT == 15 || rN == 15 || rN == rT) valid = False;
17070 IRExpr* address = getIRegA(rN);
17074 getIRegA(rN), mkU32(imm8));
17075 putIRegA(rN, newRn, condT, Ijk_Boring);
17077 nCC(INSN_COND), rT, rN, bU ? '+' : '-', imm8);
17084 strht<c> Rt, [Rn], +/-Rm
17089 UInt rN = INSN(19,16);
17093 if (rT == 15 || rN == 15 || rN == rT || rM == 15) valid = False;
17095 IRExpr* address = getIRegA(rN);
17099 rN), getIRegA(rM));
17100 putIRegA(rN, newRn, condT, Ijk_Boring);
17102 nCC(INSN_COND), rT, rN, bU ? '+' : '-', rM);
17109 strt<c> Rt, [Rn], #+/-imm12
17113 UInt rN = INSN(19,16);
17117 if (rN == 15 || rN == rT) valid = False;
17119 IRExpr* address = getIRegA(rN);
17122 getIRegA(rN), mkU32(imm12));
17123 putIRegA(rN, newRn, condT, Ijk_Boring);
17125 nCC(INSN_COND), rT, rN, bU ? '+' : '-', imm12);
17132 strt<c> Rt, [Rn], +/-Rm{, shift}
17137 UInt rN = INSN(19,16);
17143 if (rN == 15 || rN == rT || rM == 15) valid = False;
17145 if ArchVersion() < 6 && rM == rN then UNPREDICTABLE */
17147 storeGuardedLE( getIRegA(rN), getIRegA(rT), condT);
17149 IRExpr* erN = mk_EA_reg_plusminus_shifted_reg(rN, bU, rM,
17151 putIRegA(rN, erN, condT, Ijk_Boring);
17828 /* ---------------- CMP Rn, Rm ---------------- */
17830 UInt rN = INSN0(2,0);
17834 assign( argL, getIRegT(rN) );
17839 DIP("%s r%u, r%u\n", isCMN ? "cmn" : "cmp", rN, rM);
17844 /* ---------------- TST Rn, Rm ---------------- */
17845 UInt rN = INSN0(2,0);
17852 assign( res, binop(Iop_And32, getIRegT(rN), getIRegT(rM)) );
17855 DIP("tst r%u, r%u\n", rN, rM);
18113 /* ---------------- REVSH Rd, Rn ---------------- */
18291 UInt rN = (h1 << 3) | INSN0(2,0);
18295 assign( argL, getIRegT(rN) );
18299 DIP("cmphi r%u, r%u\n", rN, rM);
18367 UInt rN = INSN0(2,0);
18374 getIRegT(rN), mkU32(0)) );
18385 DIP("cb%s r%u, 0x%x\n", bOP ? "nz" : "z", rN, dst - 1);
18545 /* ---------------- ADDS Rd, Rn, #uimm3 ---------------- */
18546 /* ---------------- SUBS Rd, Rn, #uimm3 ---------------- */
18548 UInt rN = INSN0(5,3);
18553 assign( argL, getIRegT(rN) );
18560 DIP("%s r%u, r%u, #%u\n", isSub ? "subs" : "adds", rD, rN, uimm3);
18566 /* ---------------- ADDS Rd, Rn, Rm ---------------- */
18567 /* ---------------- SUBS Rd, Rn, Rm ---------------- */
18569 UInt rN = INSN0(5,3);
18574 assign( argL, getIRegT(rN) );
18581 DIP("%s r%u, r%u, r%u\n", isSub ? "subs" : "adds", rD, rN, rM);
18587 /* ------------- LDR Rd, [Rn, Rm] ------------- */
18588 /* ------------- STR Rd, [Rn, Rm] ------------- */
18589 /* LDR/STR Rd, [Rn + Rm] */
18591 UInt rN = INSN0(5,3);
18595 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), getIRegT(rM));
18606 DIP("%s r%u, [r%u, r%u]\n", isLD ? "ldr" : "str", rD, rN, rM);
18612 /* ------------- LDRH Rd, [Rn, Rm] ------------- */
18613 /* ------------- STRH Rd, [Rn, Rm] ------------- */
18614 /* LDRH/STRH Rd, [Rn + Rm] */
18616 UInt rN = INSN0(5,3);
18620 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), getIRegT(rM));
18631 DIP("%sh r%u, [r%u, r%u]\n", isLD ? "ldr" : "str", rD, rN, rM);
18636 /* ------------- LDRSH Rd, [Rn, Rm] ------------- */
18637 /* LDRSH Rd, [Rn + Rm] */
18639 UInt rN = INSN0(5,3);
18642 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), getIRegT(rM));
18649 DIP("ldrsh r%u, [r%u, r%u]\n", rD, rN, rM);
18654 /* ------------- LDRSB Rd, [Rn, Rm] ------------- */
18655 /* LDRSB Rd, [Rn + Rm] */
18657 UInt rN = INSN0(5,3);
18660 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), getIRegT(rM));
18667 DIP("ldrsb r%u, [r%u, r%u]\n", rD, rN, rM);
18673 /* ------------- LDRB Rd, [Rn, Rm] ------------- */
18674 /* ------------- STRB Rd, [Rn, Rm] ------------- */
18675 /* LDRB/STRB Rd, [Rn + Rm] */
18677 UInt rN = INSN0(5,3);
18681 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), getIRegT(rM));
18692 DIP("%sb r%u, [r%u, r%u]\n", isLD ? "ldr" : "str", rD, rN, rM);
18708 /* ---------------- ADDS Rn, #uimm8 ---------------- */
18709 /* ---------------- SUBS Rn, #uimm8 ---------------- */
18711 UInt rN = INSN0(10,8);
18715 assign( argL, getIRegT(rN) );
18717 putIRegT( rN, binop(isSub ? Iop_Sub32 : Iop_Add32,
18721 DIP("%s r%u, #%u\n", isSub ? "subs" : "adds", rN, uimm8);
18750 /* ---------------- CMP Rn, #uimm8 ---------------- */
18751 UInt rN = INSN0(10,8);
18755 assign( argL, getIRegT(rN) );
18759 DIP("cmp r%u, #%u\n", rN, uimm8);
18764 /* -------------- (T1) MOVS Rn, #uimm8 -------------- */
18802 /* ------------- LDR Rd, [Rn, #imm5 * 4] ------------- */
18803 /* ------------- STR Rd, [Rn, #imm5 * 4] ------------- */
18804 /* LDR/STR Rd, [Rn + imm5 * 4] */
18806 UInt rN = INSN0(5,3);
18810 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), mkU32(imm5 * 4));
18821 DIP("%s r%u, [r%u, #%u]\n", isLD ? "ldr" : "str", rD, rN, imm5 * 4);
18827 /* ------------- LDRH Rd, [Rn, #imm5 * 2] ------------- */
18828 /* ------------- STRH Rd, [Rn, #imm5 * 2] ------------- */
18829 /* LDRH/STRH Rd, [Rn + imm5 * 2] */
18831 UInt rN = INSN0(5,3);
18835 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), mkU32(imm5 * 2));
18846 DIP("%sh r%u, [r%u, #%u]\n", isLD ? "ldr" : "str", rD, rN, imm5 * 2);
18852 /* ------------- LDRB Rd, [Rn, #imm5] ------------- */
18853 /* ------------- STRB Rd, [Rn, #imm5] ------------- */
18854 /* LDRB/STRB Rd, [Rn + imm5] */
18856 UInt rN = INSN0(5,3);
18860 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), mkU32(imm5));
18871 DIP("%sb r%u, [r%u, #%u]\n", isLD ? "ldr" : "str", rD, rN, imm5);
18900 /* ------------- LDMIA Rn!, {reglist} ------------- */
18902 UInt rN = INSN0(10,8);
18913 assign(oldRn, getIRegT(rN));
18926 /* Only do the writeback for rN if it isn't in the list of
18928 if (0 == (list & (1 << rN))) {
18929 putIRegT(rN,
18939 DIP("ldmia r%u!, {0x%04x}\n", rN, list);
18946 /* ------------- STMIA Rn!, {reglist} ------------- */
18948 UInt rN = INSN0(10,8);
18950 /* Empty lists aren't allowed. Also, if rN is in the list then
18953 if (valid && 0 != (list & (1 << rN))) {
18954 for (i = 0; i < rN; i++) {
18967 assign(oldRn, getIRegT(rN));
18977 putIRegT(rN,
18985 DIP("stmia r%u!, {0x%04x}\n", rN, list);
19207 UInt bW = INSN0(5,5); /* writeback Rn ? */
19209 UInt rN = INSN0(3,0);
19231 if (rN == 15) valid = False;
19234 if (bW == 1 && (regList & (1<<rN))) valid = False;
19238 if (rN == 15) valid = False;
19240 if (bW == 1 && (regList & (1<<rN))) valid = False;
19256 mk_ldm_stm(False/*!arm*/, rN, bINC, bBEFORE, bW, bL, regList);
19268 rN, bW ? "!" : "", regList);
19274 /* -------------- (T3) ADD{S}.W Rd, Rn, #constT -------------- */
19279 UInt rN = INSN0(3,0);
19281 Bool valid = !isBadRegT(rN) && !isBadRegT(rD);
19283 if (!valid && rD <= 14 && rN == 13)
19290 assign(argL, getIRegT(rN));
19297 bS == 1 ? "s" : "", rD, rN, imm32);
19302 /* ---------------- (T4) ADDW Rd, Rn, #uimm12 -------------- */
19306 UInt rN = INSN0(3,0);
19308 Bool valid = !isBadRegT(rN) && !isBadRegT(rD);
19310 rN == 13)
19317 assign(argL, getIRegT(rN));
19321 DIP("addw r%u, r%u, #%u\n", rD, rN, imm12);
19326 /* ---------------- (T2) CMP.W Rn, #constT ---------------- */
19327 /* ---------------- (T2) CMN.W Rn, #constT ---------------- */
19333 UInt rN = INSN0(3,0);
19334 if (rN != 15) {
19339 assign(argL, getIRegT(rN));
19343 DIP("%s.w r%u, #%u\n", isCMN ? "cmn" : "cmp", rN, imm32);
19348 /* -------------- (T1) TST.W Rn, #constT -------------- */
19349 /* -------------- (T1) TEQ.W Rn, #constT -------------- */
19355 UInt rN = INSN0(3,0);
19356 if (!isBadRegT(rN)) { // yes, really, it's inconsistent with CMP.W
19365 assign(argL, getIRegT(rN));
19374 DIP("%s.w r%u, #%u\n", isTST ? "tst" : "teq", rN, imm32);
19379 /* -------------- (T3) SUB{S}.W Rd, Rn, #constT -------------- */
19380 /* -------------- (T3) RSB{S}.W Rd, Rn, #constT -------------- */
19387 UInt rN = INSN0(3,0);
19389 Bool valid = !isBadRegT(rN) && !isBadRegT(rD);
19392 if (!valid && !isRSB && rN == 13 && rD != 15)
19399 assign(argL, getIRegT(rN));
19412 isRSB ? "rsb" : "sub", bS == 1 ? "s" : "", rD, rN, imm32);
19417 /* -------------- (T4) SUBW Rd, Rn, #uimm12 ------------------- */
19421 UInt rN = INSN0(3,0);
19423 Bool valid = !isBadRegT(rN) && !isBadRegT(rD);
19425 if (!valid && rD == 13 && rN == 13)
19432 assign(argL, getIRegT(rN));
19436 DIP("subw r%u, r%u, #%u\n", rD, rN, imm12);
19441 /* -------------- (T1) ADC{S}.W Rd, Rn, #constT -------------- */
19442 /* -------------- (T1) SBC{S}.W Rd, Rn, #constT -------------- */
19447 /* ADC: Rd = Rn + constT + oldC */
19448 /* SBC: Rd = Rn - constT - (oldC ^ 1) */
19450 UInt rN = INSN0(3,0);
19452 if (!isBadRegT(rN) && !isBadRegT(rD)) {
19458 assign(argL, getIRegT(rN));
19489 nm, bS == 1 ? "s" : "", rD, rN, imm32);
19494 /* -------------- (T1) ORR{S}.W Rd, Rn, #constT -------------- */
19495 /* -------------- (T1) AND{S}.W Rd, Rn, #constT -------------- */
19496 /* -------------- (T1) BIC{S}.W Rd, Rn, #constT -------------- */
19497 /* -------------- (T1) EOR{S}.W Rd, Rn, #constT -------------- */
19506 UInt rN = INSN0(3,0);
19508 if (!isBadRegT(rN) && !isBadRegT(rD)) {
19527 assign(argL, getIRegT(rN));
19542 nm, bS == 1 ? "s" : "", rD, rN, imm32);
19547 /* ---------- (T3) ADD{S}.W Rd, Rn, Rm, {shift} ---------- */
19548 /* ---------- (T3) SUB{S}.W Rd, Rn, Rm, {shift} ---------- */
19549 /* ---------- (T3) RSB{S}.W Rd, Rn, Rm, {shift} ---------- */
19555 UInt rN = INSN0(3,0);
19562 Bool valid = !isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM);
19566 && rD != 15 && rN == 13 && imm5 <= 3 && how == 0) {
19572 && rD != 15 && rN == 13 && imm5 == 0 && how == 0) {
19588 assign(argL, getIRegT(rN));
19621 nm, bS ? "s" : "", rD, rN, dis_buf);
19626 /* ---------- (T3) ADC{S}.W Rd, Rn, Rm, {shift} ---------- */
19627 /* ---------- (T2) SBC{S}.W Rd, Rn, Rm, {shift} ---------- */
19632 /* ADC: Rd = Rn + shifter_operand + oldC */
19633 /* SBC: Rd = Rn - shifter_operand - (oldC ^ 1) */
19634 UInt rN = INSN0(3,0);
19637 if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM)) {
19643 assign(argL, getIRegT(rN));
19686 nm, bS ? "s" : "", rD, rN, dis_buf);
19691 /* ---------- (T3) AND{S}.W Rd, Rn, Rm, {shift} ---------- */
19692 /* ---------- (T3) ORR{S}.W Rd, Rn, Rm, {shift} ---------- */
19693 /* ---------- (T3) EOR{S}.W Rd, Rn, Rm, {shift} ---------- */
19694 /* ---------- (T3) BIC{S}.W Rd, Rn, Rm, {shift} ---------- */
19695 /* ---------- (T1) ORN{S}.W Rd, Rn, Rm, {shift} ---------- */
19703 UInt rN = INSN0(3,0);
19706 if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM)) {
19725 assign(rNt, getIRegT(rN));
19755 nm, bS ? "s" : "", rD, rN, dis_buf);
19760 /* -------------- (T?) LSL{S}.W Rd, Rn, Rm -------------- */
19761 /* -------------- (T?) LSR{S}.W Rd, Rn, Rm -------------- */
19762 /* -------------- (T?) ASR{S}.W Rd, Rn, Rm -------------- */
19763 /* -------------- (T?) ROR{S}.W Rd, Rn, Rm -------------- */
19768 UInt rN = INSN0(3,0);
19772 Bool valid = !isBadRegT(rN) && !isBadRegT(rM) && !isBadRegT(rD);
19781 assign(rNt, getIRegT(rN));
19785 rNt, how, rMt, rN, rM
19795 nm, bS ? "s" : "", rD, rN, rM);
19800 /* ------------ (T?) MOV{S}.W Rd, Rn, {shift} ------------ */
19801 /* ------------ (T?) MVN{S}.W Rd, Rn, {shift} ------------ */
19805 UInt rN = INSN1(3,0);
19807 int badRegs = bS ? (isBadRegT(rD) || isBadRegT(rN))
19808 : (rD == 15 || rN == 15 || (rD == 15 && rN == 15));
19816 assign(rNt, getIRegT(rN));
19821 dis_buf, &oldRn, bS ? &oldC : NULL, rNt, how, imm5, rN
19840 /* -------------- (T?) TST.W Rn, Rm, {shift} -------------- */
19841 /* -------------- (T?) TEQ.W Rn, Rm, {shift} -------------- */
19847 UInt rN = INSN0(3,0);
19849 if (!isBadRegT(rN) && !isBadRegT(rM)) {
19856 assign(argL, getIRegT(rN));
19876 DIP("%s.w r%u, %s\n", isTST ? "tst" : "teq", rN, dis_buf);
19881 /* -------------- (T3) CMP.W Rn, Rm, {shift} -------------- */
19882 /* -------------- (T2) CMN.W Rn, Rm, {shift} -------------- */
19888 UInt rN = INSN0(3,0);
19890 if (!isBadRegT(rN) && !isBadRegT(rM)) {
19896 assign(argL, getIRegT(rN));
19909 DIP("%s.w r%u, %s\n", isCMN ? "cmn" : "cmp", rN, dis_buf);
19981 op Rt, [Rn, #-imm8] or
19982 op Rt, [Rn], #+/-imm8 or
19983 op Rt, [Rn, #+/-imm8]!
20016 UInt rN = INSN0(3,0);
20029 if (rN == 15)
20031 if (bW == 1 && rN == rT)
20058 assign(preAddr, getIRegT(rN));
20082 /* Update Rn if necessary. */
20084 vassert(rN != rT); // assured by validity check above
20085 putIRegT(rN, mkexpr(postAddr), condT);
20137 /* Update Rn if necessary. */
20139 vassert(rN != rT); // assured by validity check above
20140 putIRegT(rN, mkexpr(postAddr), condT);
20145 vassert(rN != 15); // assured by validity check above
20156 nm, rT, rN, bU ? '+' : '-', imm8);
20160 nm, rT, rN, bU ? '+' : '-', imm8);
20165 nm, rT, rN, bU ? '+' : '-', imm8);
20174 op Rt, [Rn, Rm, LSL #imm8]
20208 UInt rN = INSN0(3,0);
20217 if (rN == 15 || isBadRegT(rT) || isBadRegT(rM))
20221 if (rN == 15 || isBadRegT(rM))
20247 getIRegT(rN),
20308 vassert(rN != 15); // assured by validity check above
20318 nm, rT, rN, rM, imm2);
20326 op Rt, [Rn, #+-imm12]
20357 UInt rN = INSN0(3,0);
20362 if (rN != 15 && bU == 0) {
20369 if (rN == 15 || rT == 15)
20375 case, rN == 15 is allowable. In this case however, the
20376 value obtained for rN is (apparently)
20399 if (rN == 15) {
20403 assign(rNt, getIRegT(rN));
20469 DIP("%s.w r%u, [r%u, +#%u]\n", nm, rT, rN, imm12);
20477 ldrd/strd Rt, Rt2, [Rn, #+/-imm8] or
20478 ldrd/strd Rt, Rt2, [Rn], #+/-imm8 or
20479 ldrd/strd Rt, Rt2, [Rn, #+/-imm8]!
20486 UInt rN = INSN0(3,0);
20493 if (bW == 1 && (rN == rT || rN == rT2)) valid = False;
20498 if (rN == 15 && (bL == 0/*store*/
20503 assign(preAddr, 15 == rN
20505 : getIRegT(rN));
20521 && rN == 13 && rN != rT && rN != rT2
20523 putIRegT(rN, mkexpr(postAddr), condT);
20556 putIRegT(rN, mkexpr(postAddr), condT);
20563 nm, rT, rT2, rN, bU ? '+' : '-', imm8 << 2);
20567 nm, rT, rT2, rN, bU ? '+' : '-', imm8 << 2);
20572 nm, rT, rT2, rN, bU ? '+' : '-', imm8 << 2);
20661 UInt rN = INSN0(3,0);
20664 if (bH/*ATC*/ || (rN != 13 && !isBadRegT(rM))) {
20673 getIRegT(rN),
20696 bH ? 'h' : 'b', rN, rM, bH ? ", LSL #1" : "");
20709 UInt rN = INSN0(3,0);
20714 if (!isBadRegT(rD) && !isBadRegT(rN) && msb <= 31) {
20723 assign(src, getIRegT(rN));
20734 isU ? "ubfx" : "sbfx", rD, rN, lsb, wm1 + 1);
20820 /* -------------- MUL.W Rd, Rn, Rm -------------- */
20823 UInt rN = INSN0(3,0);
20826 if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM)) {
20828 assign(res, binop(Iop_Mul32, getIRegT(rN), getIRegT(rM)));
20830 DIP("mul.w r%u, r%u, r%u\n", rD, rN, rM);
20835 /* -------------- SDIV.W Rd, Rn, Rm -------------- */
20838 UInt rN = INSN0(3,0);
20841 if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM)) {
20845 assign(argL, getIRegT(rN));
20849 DIP("sdiv.w r%u, r%u, r%u\n", rD, rN, rM);
20854 /* -------------- UDIV.W Rd, Rn, Rm -------------- */
20857 UInt rN = INSN0(3,0);
20860 if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM)) {
20864 assign(argL, getIRegT(rN));
20868 DIP("udiv.w r%u, r%u, r%u\n", rD, rN, rM);
20877 UInt rN = INSN0(3,0);
20882 && !isBadRegT(rN) && !isBadRegT(rM) && rDlo != rDhi) {
20885 getIRegT(rN), getIRegT(rM)));
20889 isU ? 'u' : 's', rDlo, rDhi, rN, rM);
20898 UInt rN = INSN0(3,0);
20902 if (!isBadRegT(rD) && !isBadRegT(rN)
20909 binop(Iop_Mul32, getIRegT(rN), getIRegT(rM))));
20912 isMLA ? "mla" : "mls", rD, rN, rM, rA);
20939 UInt rN = INSN0(3,0);
20943 if (!isBadRegT(rDlo) && !isBadRegT(rDhi) && !isBadRegT(rN)
20954 assign( argR, getIRegT(rN));
20964 isS ? 's' : 'u', rDlo, rDhi, rN, rM);
20971 UInt rN = INSN0(3,0);
20975 if (!isBadRegT(rDlo) && !isBadRegT(rDhi) && !isBadRegT(rN)
20984 assign( argN, getIRegT(rN) );
20998 DIP("umaal r%u, r%u, r%u, r%u\n", rDlo, rDhi, rN, rM);
21011 UInt rN = INSN0(3,0);
21012 if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM)) {
21016 binop(Iop_MullS32, getIRegT(rN), getIRegT(rM)),
21020 bitR ? "r" : "", rD, rN, rM);
21033 UInt rN = INSN0(3,0);
21034 if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM) && (rA != 13)) {
21040 binop(Iop_MullS32, getIRegT(rN), getIRegT(rM))),
21044 bitR ? "r" : "", rD, rN, rM, rA);
21070 UInt rN = INSN0(3,0);
21073 if (isBadRegT(rD) || rN == 13 || msb < lsb) {
21084 assign(src, rN == 15 ? mkU32(0) : getIRegT(rN));
21098 if (rN == 15) {
21103 rD, rN, lsb, msb-lsb+1);
21116 UInt rN = INSN0(3,0);
21120 if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM)) {
21125 assign(srcL, getIRegT(rN));
21133 isU ? 'u' : 's', rD, rN, rM, rot);
21145 UInt rN = INSN0(3,0);
21149 if (!isBadRegT(rD) && !isBadRegT(rN) && !isBadRegT(rM)) {
21154 assign(srcL, getIRegT(rN));
21162 isU ? 'u' : 's', rD, rN, rM, rot);
21263 UInt rN = INSN0(3,0);
21266 if (!isBadRegT(rN) && (write_nzcvq || write_ge)) {
21268 assign(rNt, getIRegT(rN));
21271 write_nzcvq ? "f" : "", write_ge ? "g" : "", rN);
21290 UInt rN = INSN0(3,0);
21293 if (!isBadRegT(rT) && rN != 15) {
21301 binop(Iop_Add32, getIRegT(rN), mkU32(imm8 * 4)),
21304 DIP("ldrex r%u, [r%u, #+%u]\n", rT, rN, imm8 * 4);
21312 UInt rN = INSN0(3,0);
21315 if (!isBadRegT(rT) && rN != 15) {
21321 stmt( IRStmt_LLSC(Iend_LE, res, getIRegT(rN),
21325 DIP("ldrex%c r%u, [r%u]\n", isH ? 'h' : 'b', rT, rN);
21332 UInt rN = INSN0(3,0);
21335 if (!isBadRegT(rT) && !isBadRegT(rT2) && rT != rT2 && rN != 15) {
21342 stmt( IRStmt_LLSC(Iend_LE, res, getIRegT(rN),
21347 DIP("ldrexd r%u, r%u, [r%u]\n", rT, rT2, rN);
21354 UInt rN = INSN0(3,0);
21358 if (!isBadRegT(rD) && !isBadRegT(rT) && rN != 15
21359 && rD != rN && rD != rT) {
21368 binop(Iop_Add32, getIRegT(rN), mkU32(imm8 * 4)),
21376 DIP("strex r%u, r%u, [r%u, #+%u]\n", rD, rT, rN, imm8 * 4);
21384 UInt rN = INSN0(3,0);
21388 if (!isBadRegT(rD) && !isBadRegT(rT) && rN != 15
21389 && rD != rN && rD != rT) {
21396 stmt( IRStmt_LLSC(Iend_LE, resSC1, getIRegT(rN),
21405 DIP("strex%c r%u, r%u, [r%u]\n", isH ? 'h' : 'b', rD, rT, rN);
21412 UInt rN = INSN0(3,0);
21417 && rN != 15 && rD != rN && rD != rT && rD != rT) {
21428 stmt( IRStmt_LLSC(Iend_LE, resSC1, getIRegT(rN), mkexpr(data)));
21435 DIP("strexd r%u, r%u, r%u, [r%u]\n", rD, rT, rT2, rN);
21483 UInt rN = INSN0(3,0);
21486 DIP("pld%s [r%u, #%u]\n", bW ? "w" : "", rN, imm12);
21493 UInt rN = INSN0(3,0);
21496 DIP("pld%s [r%u, #-%u]\n", bW ? "w" : "", rN, imm8);
21503 UInt rN = INSN0(3,0);
21508 DIP("pld%s [r%u, r%u, lsl %d]\n", bW ? "w" : "", rN, rM, imm2);
21551 ldrt Rt, [Rn, #imm8]
21556 UInt rN = INSN0(3,0);
21559 if (rN == 15 || isBadRegT(rT)) valid = False;
21562 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), mkU32(imm8));
21567 DIP("ldrt r%u, [r%u, #%u]\n", rT, rN, imm8);
21574 strt Rt, [Rn, #imm8]
21579 UInt rN = INSN0(3,0);
21582 if (rN == 15 || isBadRegT(rT)) valid = False;
21585 IRExpr* address = binop(Iop_Add32, getIRegT(rN), mkU32(imm8));
21588 DIP("strt r%u, [r%u, #%u]\n", rT, rN, imm8);
21595 strbt Rt, [Rn, #imm8]
21600 UInt rN = INSN0(3,0);
21603 if (rN == 15 || isBadRegT(rT)) valid = False;
21606 IRExpr* address = binop(Iop_Add32, getIRegT(rN), mkU32(imm8));
21610 DIP("strbt r%u, [r%u, #%u]\n", rT, rN, imm8);
21617 ldrht Rt, [Rn, #imm8]
21621 UInt rN = INSN0(3,0);
21623 if (rN == 15) {
21634 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), mkU32(imm8));
21639 DIP("ldrht r%u, [r%u, #%u]\n", rT, rN, imm8);
21646 ldrsht Rt, [Rn, #imm8]
21650 UInt rN = INSN0(3,0);
21652 if (rN == 15) {
21663 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), mkU32(imm8));
21668 DIP("ldrsht r%u, [r%u, #%u]\n", rT, rN, imm8);
21675 strht Rt, [Rn, #imm8]
21680 UInt rN = INSN0(3,0);
21683 if (rN == 15 || isBadRegT(rT)) valid = False;
21686 IRExpr* address = binop(Iop_Add32, getIRegT(rN), mkU32(imm8));
21690 DIP("strht r%u, [r%u, #%u]\n", rT, rN, imm8);
21697 ldrbt Rt, [Rn, #imm8]
21701 UInt rN = INSN0(3,0);
21705 if (rN == 15 /* insn is LDRB (literal) */) valid = False;
21709 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), mkU32(imm8));
21714 DIP("ldrbt r%u, [r%u, #%u]\n", rT, rN, imm8);
21721 ldrsbt Rt, [Rn, #imm8]
21725 UInt rN = INSN0(3,0);
21729 if (rN == 15 /* insn is LDRSB (literal) */) valid = False;
21733 IRExpr* ea = binop(Iop_Add32, getIRegT(rN), mkU32(imm8));
21738 DIP("ldrsbt r%u, [r%u, #%u]\n", rT, rN, imm8);
21745 pli [Rn, #imm12]
21749 UInt rN = INSN0(3,0);
21751 if (rN != 15) {
21752 DIP("pli [r%u, #%u]\n", rN, imm12);
21759 pli [Rn, #-imm8]
21763 UInt rN = INSN0(3,0);
21765 if (rN != 15) {
21766 DIP("pli [r%u, #-%u]\n", rN, imm8);