Misc fixes, new compiler unit tests
Fixed disassembly logging, miscellaneous codegen bugs and added a
set of unit tests (most of which fail because array allocation isn't quite
there yet in the codegen).
Failing tests conditionally compiled out for now.
Change-Id: I39c148f9a7686fac21c844a7a7f5ec86d4e0e1c5
diff --git a/src/common_test.h b/src/common_test.h
index a405ce5..1f3f573 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -374,6 +374,447 @@
"AAABEAAABAAAANwCAAACIAAAGgAAAPoCAAADIAAABAAAAEAEAAAAIAAAAgAAAGgEAAAAEAAAAQAA"
"AIQEAAA=";
+//class IntMath {
+//
+// /*
+// * Try to cause some unary operations.
+// */
+// static int unopTest(int x) {
+// x = -x;
+// x ^= 0xffffffff;
+// return x;
+// }
+//
+// static int shiftTest1() {
+// final int[] mBytes = {
+// 0x11, 0x22, 0x33, 0x44, 0x88, 0x99, 0xaa, 0xbb
+// };
+// long l;
+// int i1, i2;
+//
+// i1 = mBytes[0] | mBytes[1] << 8 | mBytes[2] << 16 | mBytes[3] << 24;
+// i2 = mBytes[4] | mBytes[5] << 8 | mBytes[6] << 16 | mBytes[7] << 24;
+// l = i1 | ((long)i2 << 32);
+//
+// if (i1 != 0x44332211) { return 1; }
+// if (i2 != 0xbbaa9988) { return 2; }
+// if (l != 0xbbaa998844332211L) { return 3; }
+//
+// l = (long)mBytes[0]
+// | (long)mBytes[1] << 8
+// | (long)mBytes[2] << 16
+// | (long)mBytes[3] << 24
+// | (long)mBytes[4] << 32
+// | (long)mBytes[5] << 40
+// | (long)mBytes[6] << 48
+// | (long)mBytes[7] << 56;
+//
+// if (l != 0xbbaa998844332211L) { return 4; }
+// return 0;
+// }
+//
+// static int shiftTest2() {
+//
+// long a = 0x11;
+// long b = 0x22;
+// long c = 0x33;
+// long d = 0x44;
+// long e = 0x55;
+// long f = 0x66;
+// long g = 0x77;
+// long h = 0x88;
+//
+// long result = ((a << 56) | (b << 48) | (c << 40) | (d << 32) |
+// (e << 24) | (f << 16) | (g << 8) | h);
+//
+// if (result != 0x1122334455667788L) { return 1; }
+// return 0;
+// }
+//
+// static int unsignedShiftTest() {
+// byte b = -4;
+// short s = -4;
+// char c = 0xfffc;
+// int i = -4;
+//
+// b >>>= 4;
+// s >>>= 4;
+// c >>>= 4;
+// i >>>= 4;
+//
+// if ((int) b != -1) { return 1; }
+// if ((int) s != -1) { return 2; }
+// if ((int) c != 0x0fff) { return 3; }
+// if (i != 268435455) { return 4; }
+// return 0;
+// }
+//
+// static int convTest() {
+//
+// float f;
+// double d;
+// int i;
+// long l;
+//
+// /* int --> long */
+// i = 7654;
+// l = (long) i;
+// if (l != 7654L) { return 1; }
+//
+// i = -7654;
+// l = (long) i;
+// if (l != -7654L) { return 2; }
+//
+// /* long --> int (with truncation) */
+// l = 5678956789L;
+// i = (int) l;
+// if (i != 1383989493) { return 3; }
+//
+// l = -5678956789L;
+// i = (int) l;
+// if (i != -1383989493) { return 4; }
+// return 0;
+// }
+//
+// static int charSubTest() {
+//
+// char char1 = 0x00e9;
+// char char2 = 0xffff;
+// int i;
+//
+// /* chars are unsigned-expanded to ints before subtraction */
+// i = char1 - char2;
+// if (i != 0xffff00ea) { return 1; }
+// return 0;
+// }
+//
+// /*
+// * We pass in the arguments and return the results so the compiler
+// * doesn't do the math for us. (x=70000, y=-3)
+// */
+// static int intOperTest(int x, int y) {
+// int[] results = new int[10];
+//
+// /* this seems to generate "op-int" instructions */
+// results[0] = x + y;
+// results[1] = x - y;
+// results[2] = x * y;
+// results[3] = x * x;
+// results[4] = x / y;
+// results[5] = x % -y;
+// results[6] = x & y;
+// results[7] = x | y;
+// results[8] = x ^ y;
+//
+// /* this seems to generate "op-int/2addr" instructions */
+// results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
+//
+// /* check this edge case while we're here (div-int/2addr) */
+// int minInt = -2147483648;
+// int negOne = -results[5];
+// int plusOne = 1;
+// int result = (((minInt + plusOne) - plusOne) / negOne) / negOne;
+//
+// if (result != minInt) { return 1;};
+// if (results[0] != 69997) { return 2;};
+// if (results[1] != 70003) { return 3;};
+// if (results[2] != -210000) { return 4;};
+// if (results[3] != 605032704) { return 5;};
+// if (results[4] != -23333) { return 6;};
+// if (results[5] != 1) { return 7;};
+// if (results[6] != 70000) { return 8;};
+// if (results[7] != -3) { return 9;};
+// if (results[8] != -70003) { return 10;};
+// if (results[9] != 70000) { return 11;};
+//
+// return 0;
+// }
+//
+// /*
+// * More operations, this time with 16-bit constants. (x=77777)
+// */
+// static int lit16Test(int x) {
+//
+// int[] results = new int[8];
+//
+// /* try to generate op-int/lit16" instructions */
+// results[0] = x + 1000;
+// results[1] = 1000 - x;
+// results[2] = x * 1000;
+// results[3] = x / 1000;
+// results[4] = x % 1000;
+// results[5] = x & 1000;
+// results[6] = x | -1000;
+// results[7] = x ^ -1000;
+//
+// if (results[0] != 78777) { return 1; }
+// if (results[1] != -76777) { return 2; }
+// if (results[2] != 77777000) { return 3; }
+// if (results[3] != 77) { return 4; }
+// if (results[4] != 777) { return 5; }
+// if (results[5] != 960) { return 6; }
+// if (results[6] != -39) { return 7; }
+// if (results[7] != -76855) { return 8; }
+// return 0;
+// }
+//
+// /*
+// * More operations, this time with 8-bit constants. (x=-55555)
+// */
+// static int lit8Test(int x) {
+//
+// int[] results = new int[8];
+//
+// /* try to generate op-int/lit8" instructions */
+// results[0] = x + 10;
+// results[1] = 10 - x;
+// results[2] = x * 10;
+// results[3] = x / 10;
+// results[4] = x % 10;
+// results[5] = x & 10;
+// results[6] = x | -10;
+// results[7] = x ^ -10;
+// int minInt = -2147483648;
+// int result = minInt / -1;
+// if (result != minInt) {return 1; }
+// if (results[0] != -55545) {return 2; }
+// if (results[1] != 55565) {return 3; }
+// if (results[2] != -555550) {return 4; }
+// if (results[3] != -5555) {return 5; }
+// if (results[4] != -5) {return 6; }
+// if (results[5] != 8) {return 7; }
+// if (results[6] != -1) {return 8; }
+// if (results[7] != 55563) {return 9; }
+// return 0;
+// }
+//
+//
+// /*
+// * Shift some data. (value=0xff00aa01, dist=8)
+// */
+// static int intShiftTest(int value, int dist) {
+// int results[] = new int[4];
+// results[0] = value << dist;
+// results[1] = value >> dist;
+// results[2] = value >>> dist;
+// results[3] = (((value << dist) >> dist) >>> dist) << dist;
+// if (results[0] != 0x00aa0100) {return 1; }
+// if (results[1] != 0xffff00aa) {return 2; }
+// if (results[2] != 0x00ff00aa) {return 3; }
+// if (results[3] != 0xaa00) {return 4; }
+// return 0;
+// }
+//
+// /*
+// * We pass in the arguments and return the results so the compiler
+// * doesn't do the math for us. (x=70000000000, y=-3)
+// */
+// static int longOperTest(long x, long y) {
+// long[] results = new long[10];
+//
+// /* this seems to generate "op-long" instructions */
+// results[0] = x + y;
+// results[1] = x - y;
+// results[2] = x * y;
+// results[3] = x * x;
+// results[4] = x / y;
+// results[5] = x % -y;
+// results[6] = x & y;
+// results[7] = x | y;
+// results[8] = x ^ y;
+// /* this seems to generate "op-long/2addr" instructions */
+// results[9] = x + ((((((((x + y) - y) * y) / y) % y) & y) | y) ^ y);
+// /* check this edge case while we're here (div-long/2addr) */
+// long minLong = -9223372036854775808L;
+// long negOne = -results[5];
+// long plusOne = 1;
+// long result = (((minLong + plusOne) - plusOne) / negOne) / negOne;
+// if (result != minLong) { return 1; }
+// if (results[0] != 69999999997L) { return 2; }
+// if (results[1] != 70000000003L) { return 3; }
+// if (results[2] != -210000000000L) { return 4; }
+// if (results[3] != -6833923606740729856L) { return 5; } // overflow
+// if (results[4] != -23333333333L) { return 6; }
+// if (results[5] != 1) { return 7; }
+// if (results[6] != 70000000000L) { return 8; }
+// if (results[7] != -3) { return 9; }
+// if (results[8] != -70000000003L) { return 10; }
+// if (results[9] != 70000000000L) { return 11; }
+// if (results.length != 10) { return 12; }
+// return 0;
+// }
+//
+// /*
+// * Shift some data. (value=0xd5aa96deff00aa01, dist=8)
+// */
+// static long longShiftTest(long value, int dist) {
+// long results[] = new long[4];
+// results[0] = value << dist;
+// results[1] = value >> dist;
+// results[2] = value >>> dist;
+// results[3] = (((value << dist) >> dist) >>> dist) << dist;
+// if (results[0] != 0x96deff00aa010000L) { return 1; }
+// if (results[1] != 0xffffd5aa96deff00L) { return 2; }
+// if (results[2] != 0x0000d5aa96deff00L) { return 3; }
+// if (results[3] != 0xffff96deff000000L) { return 4; }
+// if (results.length != 4) { return 5; }
+//
+// return results[0]; // test return-long
+// }
+//
+//
+// public static void main(String[] args) {
+// int res = unopTest(38);
+// if (res == 37) {
+// System.out.printf("unopTest PASSED\n");
+// } else {
+// System.out.printf("unopTest FAILED: %d\n", res);
+// }
+// res = shiftTest1();
+// if (res == 0) {
+// System.out.printf("shiftTest1 PASSED\n");
+// } else {
+// System.out.printf("shiftTest1 FAILED: %d\n", res);
+// }
+// res = shiftTest2();
+// if (res == 0) {
+// System.out.printf("shiftTest2 PASSED\n");
+// } else {
+// System.out.printf("shiftTest2 FAILED: %d\n", res);
+// }
+// res = unsignedShiftTest();
+// if (res == 0) {
+// System.out.printf("unsignedShiftTest PASSED\n");
+// } else {
+// System.out.printf("unsignedShiftTest FAILED: %d\n", res);
+// }
+// res = convTest();
+// if (res == 0) {
+// System.out.printf("convTest PASSED\n");
+// } else {
+// System.out.printf("convTest FAILED: %d\n", res);
+// }
+// res = charSubTest();
+// if (res == 0) {
+// System.out.printf("charSubTest PASSED\n");
+// } else {
+// System.out.printf("charSubTest FAILED: %d\n", res);
+// }
+// res = intOperTest(70000, -3);
+// if (res == 0) {
+// System.out.printf("intOperTest PASSED\n");
+// } else {
+// System.out.printf("intOperTest FAILED: %d\n", res);
+// }
+// res = longOperTest(70000000000L, -3L);
+// if (res == 0) {
+// System.out.printf("longOperTest PASSED\n");
+// } else {
+// System.out.printf("longOperTest FAILED: %d\n", res);
+// }
+// long lres = longShiftTest(0xd5aa96deff00aa01L, 16);
+// if (lres == 0x96deff00aa010000L) {
+// System.out.printf("longShiftTest PASSED\n");
+// } else {
+// System.out.printf("longShiftTest FAILED: %d\n", res);
+// }
+// }
+//}
+static const char kIntMathDex[] =
+"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"
+"Fg6IABMQOACjAAAQExAwAKMCAhDBIBMCKACjAgQCwSATAiAAowIGAsEgEwIYAKMCCALBIBMCEACj"
+"AgoCwSATAggAowIMAsEgweAYAoh3ZlVEMyIRMQAAAjgABAASEA8AEgAo/gIAAQAAAAAAqxMAAAQA"
+"AAB7EN8AAP8PAAUAAAAAAAAAsxMAABcAAAAUAf///w8TBP8PEvONEI8RjkIyMAQAEhAPADIxBAAS"
+"ICj8MkIEABIwKPgSACj2AAABAAAAAAAAAAIAAAAAAAAAAgAAAAEAAQACAAAAAQAAAAIAAAAGAAsA"
+"AQAAAAwABjxpbml0PgABSQACSUkAA0lJSQADSUpKAAxJbnRNYXRoLmphdmEAAUoAA0pKSQACTEkA"
+"CUxJbnRNYXRoOwADTExMABVMamF2YS9pby9QcmludFN0cmVhbTsAE0xqYXZhL2xhbmcvSW50ZWdl"
+"cjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2YS9sYW5nL1N5"
+"c3RlbTsAC09iamVjdC5qYXZhAAFWAAJWTAACW0kAAltKABNbTGphdmEvbGFuZy9PYmplY3Q7ABNb"
+"TGphdmEvbGFuZy9TdHJpbmc7AAtjaGFyU3ViVGVzdAAXY2hhclN1YlRlc3QgRkFJTEVEOiAlZAoA"
+"E2NoYXJTdWJUZXN0IFBBU1NFRAoACGNvbnZUZXN0ABRjb252VGVzdCBGQUlMRUQ6ICVkCgAQY29u"
+"dlRlc3QgUEFTU0VECgALaW50T3BlclRlc3QAF2ludE9wZXJUZXN0IEZBSUxFRDogJWQKABNpbnRP"
+"cGVyVGVzdCBQQVNTRUQKAAxpbnRTaGlmdFRlc3QACWxpdDE2VGVzdAAIbGl0OFRlc3QADGxvbmdP"
+"cGVyVGVzdAAYbG9uZ09wZXJUZXN0IEZBSUxFRDogJWQKABRsb25nT3BlclRlc3QgUEFTU0VECgAN"
+"bG9uZ1NoaWZ0VGVzdAAZbG9uZ1NoaWZ0VGVzdCBGQUlMRUQ6ICVkCgAVbG9uZ1NoaWZ0VGVzdCBQ"
+"QVNTRUQKAARtYWluAANvdXQABnByaW50ZgAKc2hpZnRUZXN0MQAWc2hpZnRUZXN0MSBGQUlMRUQ6"
+"ICVkCgASc2hpZnRUZXN0MSBQQVNTRUQKAApzaGlmdFRlc3QyABZzaGlmdFRlc3QyIEZBSUxFRDog"
+"JWQKABJzaGlmdFRlc3QyIFBBU1NFRAoACHVub3BUZXN0ABR1bm9wVGVzdCBGQUlMRUQ6ICVkCgAQ"
+"dW5vcFRlc3QgUEFTU0VECgARdW5zaWduZWRTaGlmdFRlc3QAHXVuc2lnbmVkU2hpZnRUZXN0IEZB"
+"SUxFRDogJWQKABl1bnNpZ25lZFNoaWZ0VGVzdCBQQVNTRUQKAAd2YWx1ZU9mAAMABw4AAQAHDgBw"
+"AAcOAFQABw4tHgIOdwJ0HS0eiVoeeVoeeAB4AgAAB1lNS0tLS1paWlpr4y09WwIMLAJ1HZaWlpaW"
+"abSWw9MA3AECAAAHWS1LS0t4exqWlqUAogEBAAdZTUtLS0tLWlpbfwJ5HZaWh4eWlsMAvgEBAAdZ"
+"TUtLS0tLWlpdfwJ5HZaWh3iWlsMA7QECAAAHDk1aWlpaWmlaWmriLUsteAIMWQJ1HeHh4eHhtPDD"
+"/wERD5YAkwICAAAHWS1LS0t41wJ7HeHh4WoAowIBAAcsaUuZSy2ZSy2ZSy2ZSy2ZSy2Zhy2ZtC2Z"
+"tJaZAk4dAREUAREUAREUAREUAREUAREUAREUAREUAA0AB1l9AREPARQPagIOWQJzHXi1ATcXwwJo"
+"HQAqAAcOLS0tLS0tLS4BIxGlAAcBAAcOHi0AQAAHaB4eID8aS0wAAAABABCBgATEBQAADgAAgIAE"
+"2AUBCPAFAQiEBgEI+AYBCOgJAQj4CgEI9AwBCOwOAQjcEgEJpBQBCLQZAQiUHAEIpB0BCLwdAA0A"
+"AAAAAAAAAQAAAAAAAAABAAAAOQAAAHAAAAACAAAADQAAAFQBAAADAAAACQAAAIgBAAAEAAAAAQAA"
+"APQBAAAFAAAAEQAAAPwBAAAGAAAAAgAAAIQCAAABIAAADwAAAMQCAAABEAAABgAAAPwOAAACIAAA"
+"OQAAACoPAAADIAAADwAAAHASAAAAIAAAAgAAAL8TAAAAEAAAAQAAAAgUAAA=";
+
static inline DexFile* OpenDexFileBase64(const char* base64,
const std::string& location) {
CHECK(base64 != NULL);
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 17d6a34..4202a39 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -697,9 +697,14 @@
*/
bool oatCompileMethod(Method* method, art::InstructionSet insnSet)
{
- if (PrettyMethod(method, false) != "Fibonacci.fibonacci") {
+ if ((method->GetName()->ToModifiedUtf8().find("init>") !=
+ std::string::npos) ||
+ (method->GetName()->ToModifiedUtf8().find("foo") !=
+ std::string::npos)) {
LOG(INFO) << "not compiling " << PrettyMethod(method, false);
return false;
+ } else {
+ LOG(INFO) << "Compiling " << PrettyMethod(method, false);
}
CompilationUnit cUnit;
@@ -724,17 +729,16 @@
cUnit.insns = code_item->insns_;
cUnit.insnsSize = code_item->insns_size_;
#if 1
+ // TODO: Use command-line argument passing mechanism
cUnit.printMe = true;
cUnit.printMeVerbose = true;
-#endif
-#if 1
- cUnit.disableOpt = 0 |
- (1 << kLoadStoreElimination) |
- (1 << kLoadHoisting) |
- (1 << kTrackLiveTemps) |
- (1 << kSuppressLoads) |
- //(1 << kPromoteRegs) |:
- 0;
+ cUnit.disableOpt = 0 |
+ (1 << kLoadStoreElimination) |
+ (1 << kLoadHoisting) |
+ (1 << kTrackLiveTemps) |
+ (1 << kSuppressLoads) |
+ (1 << kPromoteRegs) |
+ 0;
#endif
/* Initialize the block list */
diff --git a/src/compiler/codegen/CodegenFactory.cc b/src/compiler/codegen/CodegenFactory.cc
index dd63621..5a75cee 100644
--- a/src/compiler/codegen/CodegenFactory.cc
+++ b/src/compiler/codegen/CodegenFactory.cc
@@ -183,6 +183,10 @@
{
LIR* defStart;
LIR* defEnd;
+ if(FPREG(rlSrc.lowReg)!=FPREG(rlSrc.highReg)) {
+ LOG(WARNING) << "rlSrc.lowreg:" << rlSrc.lowReg << ", rlSrc.highReg:"
+ << rlSrc.highReg;
+ }
assert(FPREG(rlSrc.lowReg)==FPREG(rlSrc.highReg));
assert(rlDest.wide);
assert(rlSrc.wide);
diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc
index 2f3af44..21ed8aa 100644
--- a/src/compiler/codegen/arm/ArchUtility.cc
+++ b/src/compiler/codegen/arm/ArchUtility.cc
@@ -308,8 +308,6 @@
ArmLIR* lir = (ArmLIR*) arg;
if (lir->flags.isNop)
return;
- char buf[256];
- char opName[256];
int offset = lir->generic.offset;
int dest = lir->operands[0];
const bool dumpNop = false;
@@ -361,16 +359,19 @@
default:
if (lir->flags.isNop && !dumpNop) {
break;
+ } else {
+ // TODO: rewrite using string
+ char opOperands[256];
+ char opName[256];
+ buildInsnString(EncodingMap[lir->opcode].name, lir, opName,
+ baseAddr, 256);
+ buildInsnString(EncodingMap[lir->opcode].fmt, lir, opOperands,
+ baseAddr, 256);
+ char tBuf[256];
+ snprintf(tBuf, 256, "%p (%04x): %-8s%s%s", baseAddr + offset, offset,
+ opName, opOperands, lir->flags.isNop ? "(nop)" : "");
+ LOG(INFO) << tBuf;
}
- buildInsnString(EncodingMap[lir->opcode].name, lir, opName,
- baseAddr, 256);
- buildInsnString(EncodingMap[lir->opcode].fmt, lir, buf, baseAddr,
- 256);
- char buf[100];
- snprintf(buf, 100, "%p (%04x): %-8s%s%s",
- baseAddr + offset, offset, opName, buf,
- lir->flags.isNop ? "(nop)" : "");
- LOG(INFO) << buf;
break;
}
@@ -450,7 +451,7 @@
std::string descriptor = method->GetDeclaringClass()->GetDescriptor()->
ToModifiedUtf8();
- char buf[100];
+ char buf[256];
LOG(INFO) << "*/";
sprintf(buf,"\n u1 %s%s_%s_code[] = {", descriptor.c_str(),
name.c_str(), signature.c_str());
@@ -458,8 +459,9 @@
if (buf[i] == ';') buf[i] = '_';
LOG(INFO) << buf;
strcpy(buf," ");
- for (int i = 0; i < cUnit->totalSize/2; i++) {
- sprintf(buf+strlen(buf),"0x%04x,", cUnit->codeBuffer[i]);
+ u1* pLiterals = (u1*)&cUnit->codeBuffer[0];
+ for (int i = 0; i < cUnit->totalSize; i++) {
+ sprintf(buf+strlen(buf),"0x%02x,", pLiterals[i]);
if (++linebreak == 8) {
linebreak = 0;
LOG(INFO) << buf;
diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc
index 0a0c9bc..400fff6 100644
--- a/src/compiler/codegen/arm/ArmRallocUtil.cc
+++ b/src/compiler/codegen/arm/ArmRallocUtil.cc
@@ -60,12 +60,16 @@
sReg = DECODE_REG(
oatConvertSSARegToDalvik(cUnit, ssaRep->defs[0]));
counts[sReg].doubleStart = true;
+ }
+ if (attrs & DF_DA_WIDE) {
cUnit->regLocation[ssaRep->defs[0]].wide = true;
}
if ((attrs & (DF_UA_WIDE|DF_FP_A)) == (DF_UA_WIDE|DF_FP_A)) {
sReg = DECODE_REG(
oatConvertSSARegToDalvik(cUnit, ssaRep->uses[first]));
counts[sReg].doubleStart = true;
+ }
+ if (attrs & DF_UA_WIDE) {
cUnit->regLocation[ssaRep->uses[first]].wide = true;
first += 2;
}
@@ -73,6 +77,8 @@
sReg = DECODE_REG(
oatConvertSSARegToDalvik(cUnit, ssaRep->uses[first]));
counts[sReg].doubleStart = true;
+ }
+ if (attrs & DF_UB_WIDE) {
cUnit->regLocation[ssaRep->uses[first]].wide = true;
first += 2;
}
@@ -80,6 +86,8 @@
sReg = DECODE_REG(
oatConvertSSARegToDalvik(cUnit, ssaRep->uses[first]));
counts[sReg].doubleStart = true;
+ }
+ if (attrs & DF_UC_WIDE) {
cUnit->regLocation[ssaRep->uses[first]].wide = true;
}
}
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index b8dcdb2..fd1b8a7 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -28,15 +28,16 @@
Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
GetResolvedClass(mir->dalvikInsn.vC);
if (classPtr == NULL) {
- LOG(FATAL) << "Unexpected null passPtr";
+ LOG(FATAL) << "Unexpected null classPtr";
} else {
loadValueDirectFixed(cUnit, rlSrc, r1); /* get Len */
loadConstant(cUnit, r0, (int)classPtr);
}
- // FIXME: need this to throw errNegativeArraySize
+ UNIMPLEMENTED(WARNING) << "Support for throwing errNegativeArraySize";
genRegImmCheck(cUnit, kArmCondMi, r1, 0, mir->offset, NULL);
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pArtAllocArrayByClass),
rLR);
+ UNIMPLEMENTED(WARNING) << "Need NoThrow wrapper";
newLIR1(cUnit, kThumbBlxR, rLR); // (arrayClass, length, allocFlags)
storeValue(cUnit, rlDest, retLoc);
}
@@ -63,7 +64,7 @@
Class* classPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
GetResolvedClass(typeIndex);
if (classPtr == NULL) {
- LOG(FATAL) << "Unexpected null passPtr";
+ LOG(FATAL) << "Unexpected null classPtr";
} else {
loadConstant(cUnit, r0, (int)classPtr);
loadConstant(cUnit, r1, elems);
@@ -897,7 +898,7 @@
rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
loadConstantValueWide(cUnit, rlResult.lowReg, rlResult.highReg,
0, mir->dalvikInsn.vB);
- storeValue(cUnit, rlDest, rlResult);
+ storeValueWide(cUnit, rlDest, rlResult);
break;
case OP_CONST_WIDE_HIGH16:
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 1a126e4..d8ecc84 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -1335,18 +1335,18 @@
switch( mir->dalvikInsn.opcode) {
case OP_SHL_LONG:
case OP_SHL_LONG_2ADDR:
+ UNIMPLEMENTED(FATAL) << "Need SHL_LONG helper";
//genDispatchToHandler(cUnit, TEMPLATE_SHL_LONG);
- assert(0); // unimp
break;
case OP_SHR_LONG:
case OP_SHR_LONG_2ADDR:
+ UNIMPLEMENTED(FATAL) << "Need SHR_LONG helper";
//genDispatchToHandler(cUnit, TEMPLATE_SHR_LONG);
- assert(0); // unimp
break;
case OP_USHR_LONG:
case OP_USHR_LONG_2ADDR:
+ UNIMPLEMENTED(FATAL) << "Need USHR_LONG helper";
//genDispatchToHandler(cUnit, TEMPLATE_USHR_LONG);
- assert(0); // unimp
break;
default:
return true;
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index c0d0c90..004a4a8 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -37,6 +37,287 @@
ASSERT_EQ(55, result);
}
+
+TEST_F(CompilerTest, UnopTest) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "unopTest", "(I)I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m, 38);
+ LOG(INFO) << "unopTest(38) == " << result;
+
+ ASSERT_EQ(37, result);
+}
+
+#if 0 // Does filled array - needs load-time class resolution
+TEST_F(CompilerTest, ShiftTest1) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "shiftTest1", "()I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m);
+
+ ASSERT_EQ(0, result);
+}
#endif
+#if 0 // Fails, needs 64-bit shift helper functions
+TEST_F(CompilerTest, ShiftTest2) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "shiftTest2", "()I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m);
+
+ ASSERT_EQ(0, result);
+}
+#endif
+
+TEST_F(CompilerTest, UnsignedShiftTest) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "unsignedShiftTest", "()I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m);
+
+ ASSERT_EQ(0, result);
+}
+
+#if 0 // Fail subtest #3, long to int conversion w/ truncation.
+TEST_F(CompilerTest, ConvTest) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "convTest", "()I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m);
+
+ ASSERT_EQ(0, result);
+}
+#endif
+
+TEST_F(CompilerTest, CharSubTest) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "charSubTest", "()I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m);
+
+ ASSERT_EQ(0, result);
+}
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, IntOperTest) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "intOperTest", "(II)I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m, 70000, -3);
+
+ ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, Lit16Test) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "lit16Test", "(I)I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m, 77777);
+
+ ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, Lit8Test) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "lit8Test", "(I)I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m, -55555);
+
+ ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, Lit8Test) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "lit8Test", "(I)I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m, -55555);
+
+ ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, IntShiftTest) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "intShiftTest", "(II)I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m, 0xff00aa01, 8);
+
+ ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, LongOperTest) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "longOperTest", "(LL)I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m, 70000000000L, 3);
+
+ ASSERT_EQ(0, result);
+}
+#endif
+
+#if 0 // Needs array allocation & r9 to be set up with Thread*
+TEST_F(CompilerTest, LongShiftTest) {
+ scoped_ptr<DexFile> dex_file(OpenDexFileBase64(kIntMathDex,
+ "kIntMathDex"));
+ PathClassLoader* class_loader = AllocPathClassLoader(dex_file.get());
+
+ Thread::Current()->SetClassLoaderOverride(class_loader);
+
+ JNIEnv* env = Thread::Current()->GetJniEnv();
+
+ jclass c = env->FindClass("IntMath");
+ ASSERT_TRUE(c != NULL);
+
+ jmethodID m = env->GetStaticMethodID(c, "longShiftTest", "(LL)I");
+ ASSERT_TRUE(m != NULL);
+
+ jint result = env->CallStaticIntMethod(c, m, 0xd5aa96deff00aa01, 8);
+
+ ASSERT_EQ(0, result);
+}
+#endif
+
+#endif // Arm
} // namespace art
diff --git a/src/thread.cc b/src/thread.cc
index 8d11541..409db2a 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -18,6 +18,51 @@
pthread_key_t Thread::pthread_key_self_;
+void Thread::InitFunctionPointers() {
+ pArtAllocArrayByClass = Array::Alloc;
+ pMemcpy = memcpy;
+#if 0
+//void* (Thread::*pMemcpy)(void*, const void*, size_t) /* = memcpy*/ ;
+float (Thread::*pI2f)(int);
+int (Thread::*pF2iz)(float);
+float (Thread::*pD2f)(double);
+double (Thread::*pF2d)(float);
+double (Thread::*pI2d)(int);
+int (Thread::*pD2iz)(double);
+float (Thread::*pL2f)(long);
+double (Thread::*pL2d)(long);
+long long (Thread::*pArtF2l)(float);
+long long (Thread::*pArtD2l)(double);
+float (Thread::*pFadd)(float, float);
+float (Thread::*pFsub)(float, float);
+float (Thread::*pFdiv)(float, float);
+float (Thread::*pFmul)(float, float);
+float (Thread::*pFmodf)(float, float);
+double (Thread::*pDadd)(double, double);
+double (Thread::*pDsub)(double, double);
+double (Thread::*pDdiv)(double, double);
+double (Thread::*pDmul)(double, double);
+double (Thread::*pFmod)(double, double);
+int (Thread::*pIdivmod)(int, int);
+int (Thread::*pIdiv)(int, int);
+long long (Thread::*pLdivmod)(long long, long long);
+bool (Thread::*pArtUnlockObject)(struct Thread*, struct Object*);
+bool (Thread::*pArtCanPutArrayElementNoThrow)(const struct ClassObject*,
+ const struct ClassObject*);
+int (Thread::*pArtInstanceofNonTrivialNoThrow)
+ (const struct ClassObject*, const struct ClassObject*);
+int (Thread::*pArtInstanceofNonTrivial) (const struct ClassObject*,
+ const struct ClassObject*);
+struct Method* (Thread::*pArtFindInterfaceMethodInCache)(ClassObject*, uint32_t,
+ const struct Method*, struct DvmDex*);
+bool (Thread::*pArtUnlockObjectNoThrow)(struct Thread*, struct Object*);
+void (Thread::*pArtLockObjectNoThrow)(struct Thread*, struct Object*);
+struct Object* (Thread::*pArtAllocObjectNoThrow)(struct ClassObject*, int);
+void (Thread::*pArtThrowException)(struct Thread*, struct Object*);
+bool (Thread::*pArtHandleFillArrayDataNoThrow)(struct ArrayObject*, const uint16_t*);
+#endif
+}
+
Mutex* Mutex::Create(const char* name) {
Mutex* mu = new Mutex(name);
int result = pthread_mutex_init(&mu->lock_impl_, NULL);
diff --git a/src/thread.h b/src/thread.h
index 7204577..bb97d4e 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -26,6 +26,8 @@
class Thread;
class ThreadList;
class Throwable;
+class Array;
+class Class;
class Mutex {
public:
@@ -166,7 +168,6 @@
static const size_t kDefaultStackSize = 64 * KB;
-// TODO - needs to be redone properly, just hacked into place for now
// Runtime support function pointers
void* (*pMemcpy)(void*, const void*, size_t);
float (*pI2f)(int);
@@ -194,22 +195,19 @@
long long (*pLdivmod)(long long, long long);
bool (*pArtUnlockObject)(struct Thread*, struct Object*);
bool (*pArtCanPutArrayElementNoThrow)(const struct ClassObject*,
- const struct ClassObject*);
- int (*pArtInstanceofNonTrivialNoThrow)
- (const struct ClassObject*, const struct ClassObject*);
- int (*pArtInstanceofNonTrivial) (const struct ClassObject*,
- const struct ClassObject*);
- struct ArrayObject* (*pArtAllocArrayByClass)(struct ClassObject*,
- size_t, int);
+ const struct ClassObject*);
+ int (*pArtInstanceofNonTrivialNoThrow) (const struct ClassObject*,
+ const struct ClassObject*);
+ int (*pArtInstanceofNonTrivial) (const struct ClassObject*, const struct ClassObject*);
+ Array* (*pArtAllocArrayByClass)(Class*, size_t);
struct Method* (*pArtFindInterfaceMethodInCache)(ClassObject*, uint32_t,
- const struct Method*, struct DvmDex*);
+ const struct Method*, struct DvmDex*);
bool (*pArtUnlockObjectNoThrow)(struct Thread*, struct Object*);
void (*pArtLockObjectNoThrow)(struct Thread*, struct Object*);
struct Object* (*pArtAllocObjectNoThrow)(struct ClassObject*, int);
void (*pArtThrowException)(struct Thread*, struct Object*);
bool (*pArtHandleFillArrayDataNoThrow)(struct ArrayObject*, const uint16_t*);
-
// Creates a new thread.
static Thread* Create(const Runtime* runtime);
@@ -388,6 +386,7 @@
exception_(NULL),
suspend_count_(0),
class_loader_override_(NULL) {
+ InitFunctionPointers();
}
~Thread() {
@@ -395,6 +394,7 @@
}
void InitCpu();
+ void InitFunctionPointers();
// Managed thread id.
uint32_t id_;