summaryrefslogtreecommitdiffstats
path: root/vm/compiler/codegen
diff options
context:
space:
mode:
authorjeffhao <jeffhao@google.com>2010-02-10 10:51:02 -0800
committerjeffhao <jeffhao@google.com>2010-02-10 10:51:02 -0800
commit121ea790080b5a6bb713a07452c19f87d209de48 (patch)
treef40b049670aa589cdebfe69e1301171920480b1f /vm/compiler/codegen
parent91080d271405234756293eb16f4d5b6e1c71c9e7 (diff)
downloadandroid_dalvik-121ea790080b5a6bb713a07452c19f87d209de48.tar.gz
android_dalvik-121ea790080b5a6bb713a07452c19f87d209de48.tar.bz2
android_dalvik-121ea790080b5a6bb713a07452c19f87d209de48.zip
Added LDMIA/STMIA support to Self Verification mode.
Diffstat (limited to 'vm/compiler/codegen')
-rw-r--r--vm/compiler/codegen/arm/Assemble.c102
-rw-r--r--vm/compiler/codegen/arm/Thumb/Factory.c8
-rw-r--r--vm/compiler/codegen/arm/Thumb2/Factory.c8
3 files changed, 112 insertions, 6 deletions
diff --git a/vm/compiler/codegen/arm/Assemble.c b/vm/compiler/codegen/arm/Assemble.c
index 25f8ce0a4..6d901b922 100644
--- a/vm/compiler/codegen/arm/Assemble.c
+++ b/vm/compiler/codegen/arm/Assemble.c
@@ -1864,6 +1864,7 @@ enum {
kSVSignedHalfword,
kSVWord,
kSVDoubleword,
+ kSVVariable,
};
/* Load the value of a decoded register from the stack */
@@ -2075,6 +2076,8 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
kMemOpStrhRRI5 = 0x10, // strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0]
kMemOpLdrhRRI5 = 0x11, // ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0]
kMemOpLdrSpRel = 0x13, // ldr(4) [10011] rd[10..8] imm_8[7..0]
+ kMemOpStmia = 0x18, // stmia [11000] rn[10..8] reglist [7..0]
+ kMemOpLdmia = 0x19, // ldmia [11001] rn[10..8] reglist [7..0]
kMemOpStrRRR = 0x28, // str(2) [0101000] rm[8..6] rn[5..3] rd[2..0]
kMemOpStrhRRR = 0x29, // strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0]
kMemOpStrbRRR = 0x2A, // strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0]
@@ -2083,6 +2086,10 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
kMemOpLdrhRRR = 0x2D, // ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0]
kMemOpLdrbRRR = 0x2E, // ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0]
kMemOpLdrshRRR = 0x2F, // ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0]
+ kMemOp2Stmia = 0xE88, // stmia [111010001000[ rn[19..16] mask[15..0]
+ kMemOp2Ldmia = 0xE89, // ldmia [111010001001[ rn[19..16] mask[15..0]
+ kMemOp2Stmia2 = 0xE8A, // stmia [111010001010[ rn[19..16] mask[15..0]
+ kMemOp2Ldmia2 = 0xE8B, // ldmia [111010001011[ rn[19..16] mask[15..0]
kMemOp2Vstr = 0xED8, // Used for Vstrs and Vstrd
kMemOp2Vldr = 0xED9, // Used for Vldrs and Vldrd
kMemOp2Vstr2 = 0xEDC, // Used for Vstrs and Vstrd
@@ -2146,12 +2153,15 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
int rm = insn & 0xF;
int rn = (insn >> 16) & 0xF;
int rt = (insn >> 12) & 0xF;
+ bool wBack = true;
// Update the link register
selfVerificationMemRegStore(sp, old_lr+4, 13);
// Determine whether the mem op is a store or load
switch (opcode12) {
+ case kMemOp2Stmia:
+ case kMemOp2Stmia2:
case kMemOp2Vstr:
case kMemOp2Vstr2:
case kMemOp2StrbRRR:
@@ -2191,6 +2201,12 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
case kMemOp2Vldr2:
if (opcode4 == kMemOp2Double) size = kSVDoubleword;
break;
+ case kMemOp2Stmia:
+ case kMemOp2Ldmia:
+ case kMemOp2Stmia2:
+ case kMemOp2Ldmia2:
+ size = kSVVariable;
+ break;
}
// Load the value of the address
@@ -2235,6 +2251,13 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
case kMemOp2LdrshRRI12:
offset = imm12;
break;
+ case kMemOp2Stmia:
+ case kMemOp2Ldmia:
+ wBack = false;
+ case kMemOp2Stmia2:
+ case kMemOp2Ldmia2:
+ offset = 0;
+ break;
default:
LOGE("*** ERROR: UNRECOGNIZED THUMB2 MEM OP: %x", opcode12);
offset = 0;
@@ -2243,7 +2266,20 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
// Handle the decoded mem op accordingly
if (store) {
- if (size == kSVDoubleword) {
+ if (size == kSVVariable) {
+ LOGD("*** THUMB2 STMIA CURRENTLY UNUSED (AND UNTESTED)");
+ int i;
+ int regList = insn & 0xFFFF;
+ for (i = 0; i < 16; i++) {
+ if (regList & 0x1) {
+ data = selfVerificationMemRegLoad(sp, i);
+ selfVerificationStore(addr, data, kSVWord);
+ addr += 4;
+ }
+ regList = regList >> 1;
+ }
+ if (wBack) selfVerificationMemRegStore(sp, addr, rn);
+ } else if (size == kSVDoubleword) {
double_data = selfVerificationMemRegLoadDouble(sp, rt);
selfVerificationStoreDoubleword(addr+offset, double_data);
} else {
@@ -2251,7 +2287,20 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
selfVerificationStore(addr+offset, data, size);
}
} else {
- if (size == kSVDoubleword) {
+ if (size == kSVVariable) {
+ LOGD("*** THUMB2 LDMIA CURRENTLY UNUSED (AND UNTESTED)");
+ int i;
+ int regList = insn & 0xFFFF;
+ for (i = 0; i < 16; i++) {
+ if (regList & 0x1) {
+ data = selfVerificationLoad(addr, kSVWord);
+ selfVerificationMemRegStore(sp, data, i);
+ addr += 4;
+ }
+ regList = regList >> 1;
+ }
+ if (wBack) selfVerificationMemRegStore(sp, addr, rn);
+ } else if (size == kSVDoubleword) {
double_data = selfVerificationLoadDoubleword(addr+offset);
selfVerificationMemRegStoreDouble(sp, double_data, rt);
} else {
@@ -2286,6 +2335,7 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
case kMemOpStrRRI5:
case kMemOpStrbRRI5:
case kMemOpStrhRRI5:
+ case kMemOpStmia:
store = true;
}
@@ -2318,11 +2368,17 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
case kMemOpLdrhRRI5:
size = kSVHalfword;
break;
+ case kMemOpStmia:
+ case kMemOpLdmia:
+ size = kSVVariable;
+ break;
}
// Load the value of the address
if (opcode5 == kMemOpLdrPcRel)
addr = selfVerificationMemRegLoad(sp, 4);
+ else if (opcode5 == kMemOpStmia || opcode5 == kMemOpLdmia)
+ addr = selfVerificationMemRegLoad(sp, rd);
else
addr = selfVerificationMemRegLoad(sp, rn);
@@ -2348,6 +2404,10 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
case kMemOpLdrbRRI5:
offset = imm;
break;
+ case kMemOpStmia:
+ case kMemOpLdmia:
+ offset = 0;
+ break;
default:
LOGE("*** ERROR: UNRECOGNIZED THUMB MEM OP: %x", opcode5);
offset = 0;
@@ -2356,11 +2416,41 @@ void dvmSelfVerificationMemOpDecode(int lr, int* sp)
// Handle the decoded mem op accordingly
if (store) {
- data = selfVerificationMemRegLoad(sp, rt);
- selfVerificationStore(addr+offset, data, size);
+ if (size == kSVVariable) {
+ int i;
+ int regList = insn & 0xFF;
+ for (i = 0; i < 8; i++) {
+ if (regList & 0x1) {
+ data = selfVerificationMemRegLoad(sp, i);
+ selfVerificationStore(addr, data, kSVWord);
+ addr += 4;
+ }
+ regList = regList >> 1;
+ }
+ selfVerificationMemRegStore(sp, addr, rd);
+ } else {
+ data = selfVerificationMemRegLoad(sp, rt);
+ selfVerificationStore(addr+offset, data, size);
+ }
} else {
- data = selfVerificationLoad(addr+offset, size);
- selfVerificationMemRegStore(sp, data, rt);
+ if (size == kSVVariable) {
+ bool wBack = true;
+ int i;
+ int regList = insn & 0xFF;
+ for (i = 0; i < 8; i++) {
+ if (regList & 0x1) {
+ if (i == rd) wBack = false;
+ data = selfVerificationLoad(addr, kSVWord);
+ selfVerificationMemRegStore(sp, data, i);
+ addr += 4;
+ }
+ regList = regList >> 1;
+ }
+ if (wBack) selfVerificationMemRegStore(sp, addr, rd);
+ } else {
+ data = selfVerificationLoad(addr+offset, size);
+ selfVerificationMemRegStore(sp, data, rt);
+ }
}
}
}
diff --git a/vm/compiler/codegen/arm/Thumb/Factory.c b/vm/compiler/codegen/arm/Thumb/Factory.c
index de6bff6b5..5bf4048ff 100644
--- a/vm/compiler/codegen/arm/Thumb/Factory.c
+++ b/vm/compiler/codegen/arm/Thumb/Factory.c
@@ -508,6 +508,10 @@ static ArmLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask)
ArmLIR *res;
genBarrier(cUnit);
res = newLIR2(cUnit, kThumbLdmia, rBase, rMask);
+#if defined(WITH_SELF_VERIFICATION)
+ if (cUnit->heapMemOp)
+ res->branchInsertSV = true;
+#endif
genBarrier(cUnit);
return res;
}
@@ -517,6 +521,10 @@ static ArmLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask)
ArmLIR *res;
genBarrier(cUnit);
res = newLIR2(cUnit, kThumbStmia, rBase, rMask);
+#if defined(WITH_SELF_VERIFICATION)
+ if (cUnit->heapMemOp)
+ res->branchInsertSV = true;
+#endif
genBarrier(cUnit);
return res;
}
diff --git a/vm/compiler/codegen/arm/Thumb2/Factory.c b/vm/compiler/codegen/arm/Thumb2/Factory.c
index 9feb53fb1..0db2045d4 100644
--- a/vm/compiler/codegen/arm/Thumb2/Factory.c
+++ b/vm/compiler/codegen/arm/Thumb2/Factory.c
@@ -1038,6 +1038,10 @@ static ArmLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask)
} else {
res = newLIR2(cUnit, kThumb2Ldmia, rBase, rMask);
}
+#if defined(WITH_SELF_VERIFICATION)
+ if (cUnit->heapMemOp)
+ res->branchInsertSV = true;
+#endif
genBarrier(cUnit);
return res;
}
@@ -1051,6 +1055,10 @@ static ArmLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask)
} else {
res = newLIR2(cUnit, kThumb2Stmia, rBase, rMask);
}
+#if defined(WITH_SELF_VERIFICATION)
+ if (cUnit->heapMemOp)
+ res->branchInsertSV = true;
+#endif
genBarrier(cUnit);
return res;
}