1) Thumb 'push' can handle lr and 'pop' can handle pc, so make use of them.
2) Thumb2 push was incorrectly encoded as stmia, which should be stmdb
instead.
None of the above affect the code that we currently ship.
Change-Id: I89ab46b032a3d562355c2cc3bc05fe308ba40957
"ror"};
/* Decode and print a ARM register name */
-static char * decodeRegList(int vector, char *buf)
+static char * decodeRegList(ArmOpcode opcode, int vector, char *buf)
{
int i;
bool printed = false;
buf[0] = 0;
- for (i = 0; i < 8; i++, vector >>= 1) {
+ for (i = 0; i < 16; i++, vector >>= 1) {
if (vector & 0x1) {
+ int regId = i;
+ if (opcode == kThumbPush && i == 8) {
+ regId = rlr;
+ } else if (opcode == kThumbPop && i == 8) {
+ regId = rpc;
+ }
if (printed) {
- sprintf(buf + strlen(buf), ", r%d", i);
+ sprintf(buf + strlen(buf), ", r%d", regId);
} else {
printed = true;
- sprintf(buf, "r%d", i);
+ sprintf(buf, "r%d", regId);
}
}
}
strcpy(tbuf, "see above");
break;
case 'R':
- decodeRegList(operand, tbuf);
+ decodeRegList(lir->opcode, operand, tbuf);
break;
default:
strcpy(tbuf,"DecodeError");
kThumb2StrbRRI12, /* strb rt,[rn,#imm12] [111110001000]
rt[15..12] rn[19..16] imm12[11..0] */
kThumb2Pop, /* pop [1110100010111101] list[15-0]*/
- kThumb2Push, /* push [1110100010101101] list[15-0]*/
+ kThumb2Push, /* push [1110100100101101] list[15-0]*/
kThumb2CmpRI8, /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0]
imm3 [1111] imm8[7..0] */
kThumb2AdcRRR, /* adc [111010110101] rn[19..16] [0000] rd[11..8]
kFmtUnused, -1, -1,
IS_UNARY_OP | REG_DEF_SP | REG_USE_SP | REG_DEF_LIST0
| IS_LOAD, "pop", "<!0R>", 2),
- ENCODING_MAP(kThumb2Push, 0xe8ad0000,
+ ENCODING_MAP(kThumb2Push, 0xe92d0000,
kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
kFmtUnused, -1, -1,
IS_UNARY_OP | REG_DEF_SP | REG_USE_SP | REG_USE_LIST0
{
ArmOpcode opcode = kThumbBkpt;
switch (op) {
- case kOpPush:
- opcode = ((value & 0xff00) != 0) ? kThumb2Push : kThumbPush;
+ case kOpPush: {
+ if ((value & 0xff00) == 0) {
+ opcode = kThumbPush;
+ } else if ((value & 0xff00) == (1 << rlr)) {
+ /* Thumb push can handle lr, which is encoded by bit 8 */
+ opcode = kThumbPush;
+ value = (value & 0xff) | (1<<8);
+ } else {
+ opcode = kThumb2Push;
+ }
break;
- case kOpPop:
- opcode = ((value & 0xff00) != 0) ? kThumb2Pop : kThumbPop;
+ }
+ case kOpPop: {
+ if ((value & 0xff00) == 0) {
+ opcode = kThumbPop;
+ } else if ((value & 0xff00) == (1 << rpc)) {
+ /* Thumb pop can handle pc, which is encoded by bit 8 */
+ opcode = kThumbPop;
+ value = (value & 0xff) | (1<<8);
+ } else {
+ opcode = kThumb2Pop;
+ }
break;
+ }
default:
assert(0);
}