summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen/arm
diff options
context:
space:
mode:
Diffstat (limited to 'vm/compiler/codegen/arm')
-rw-r--r--vm/compiler/codegen/arm/ArchUtility.c16
-rw-r--r--vm/compiler/codegen/arm/ArmLIR.h2
-rw-r--r--vm/compiler/codegen/arm/Assemble.c2
-rw-r--r--vm/compiler/codegen/arm/Thumb2/Factory.c26
4 files changed, 35 insertions, 11 deletions
diff --git a/vm/compiler/codegen/arm/ArchUtility.c b/vm/compiler/codegen/arm/ArchUtility.c
index 95b96c496..7a4d307b5 100644
--- a/vm/compiler/codegen/arm/ArchUtility.c
+++ b/vm/compiler/codegen/arm/ArchUtility.c
@@ -25,18 +25,24 @@ static char *shiftNames[4] = {
"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);
}
}
}
@@ -209,7 +215,7 @@ static void buildInsnString(char *fmt, ArmLIR *lir, char* buf,
strcpy(tbuf, "see above");
break;
case 'R':
- decodeRegList(operand, tbuf);
+ decodeRegList(lir->opcode, operand, tbuf);
break;
default:
strcpy(tbuf,"DecodeError");
diff --git a/vm/compiler/codegen/arm/ArmLIR.h b/vm/compiler/codegen/arm/ArmLIR.h
index 437c2ed96..0ee821d3f 100644
--- a/vm/compiler/codegen/arm/ArmLIR.h
+++ b/vm/compiler/codegen/arm/ArmLIR.h
@@ -515,7 +515,7 @@ typedef enum ArmOpcode {
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]
diff --git a/vm/compiler/codegen/arm/Assemble.c b/vm/compiler/codegen/arm/Assemble.c
index aa6128593..577f68320 100644
--- a/vm/compiler/codegen/arm/Assemble.c
+++ b/vm/compiler/codegen/arm/Assemble.c
@@ -641,7 +641,7 @@ ArmEncodingMap EncodingMap[kArmLast] = {
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
diff --git a/vm/compiler/codegen/arm/Thumb2/Factory.c b/vm/compiler/codegen/arm/Thumb2/Factory.c
index f50edfe32..fb30292e7 100644
--- a/vm/compiler/codegen/arm/Thumb2/Factory.c
+++ b/vm/compiler/codegen/arm/Thumb2/Factory.c
@@ -234,12 +234,30 @@ static ArmLIR *opImm(CompilationUnit *cUnit, OpKind op, int value)
{
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);
}