Method prologue and epilogues, add missing x86 functionality.
Enables compiling and running a number of JNI internal managed code
methods on the host.
Change-Id: I56fceb813d0cb24637bc784ba57f2d1d16911d48
diff --git a/src/compiler/codegen/x86/ArchUtility.cc b/src/compiler/codegen/x86/ArchUtility.cc
index 23cee14..9830e13 100644
--- a/src/compiler/codegen/x86/ArchUtility.cc
+++ b/src/compiler/codegen/x86/ArchUtility.cc
@@ -23,110 +23,80 @@
namespace art {
/* For dumping instructions */
-#define X86_REG_COUNT 16
-static const char *x86RegName[X86_REG_COUNT] = {
+static const char* x86RegName[] = {
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
};
+static const char* x86CondName[] = {
+ "O",
+ "NO",
+ "B/NAE/C",
+ "NB/AE/NC",
+ "Z/EQ",
+ "NZ/NE",
+ "BE/NA",
+ "NBE/A",
+ "S",
+ "NS",
+ "P/PE",
+ "NP/PO",
+ "L/NGE",
+ "NL/GE",
+ "LE/NG",
+ "NLE/G"
+};
+
/*
* Interpret a format string and build a string no longer than size
* See format key in Assemble.c.
*/
-std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr)
-{
- std::string buf;
- int i;
- const char *fmtEnd = &fmt[strlen(fmt)];
- char tbuf[256];
- char nc;
- while (fmt < fmtEnd) {
- int operand;
- if (*fmt == '!') {
- fmt++;
- DCHECK_LT(fmt, fmtEnd);
- nc = *fmt++;
- if (nc=='!') {
- strcpy(tbuf, "!");
+std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr) {
+ std::string buf;
+ size_t i = 0;
+ size_t fmt_len = strlen(fmt);
+ while(i < fmt_len) {
+ if (fmt[i] != '!') {
+ buf += fmt[i];
+ i++;
+ } else {
+ i++;
+ DCHECK_LT(i, fmt_len);
+ char operand_number_ch = fmt[i];
+ i++;
+ if (operand_number_ch == '!') {
+ buf += "!";
+ } else {
+ int operand_number = operand_number_ch - '0';
+ DCHECK_LT(operand_number, 6); // Expect upto 6 LIR operands.
+ DCHECK_LT(i, fmt_len);
+ int operand = lir->operands[operand_number];
+ switch(fmt[i]) {
+ case 'd':
+ buf += StringPrintf("%d", operand);
+ break;
+ case 'r':
+ if (FPREG(operand) || DOUBLEREG(operand)) {
+ int fp_reg = operand & FP_REG_MASK;
+ buf += StringPrintf("xmm%d", fp_reg);
} else {
- DCHECK_LT(fmt, fmtEnd);
- DCHECK_LT((unsigned)(nc-'0'), 4u);
- operand = lir->operands[nc-'0'];
- switch(*fmt++) {
- case 'b':
- strcpy(tbuf,"0000");
- for (i=3; i>= 0; i--) {
- tbuf[i] += operand & 1;
- operand >>= 1;
- }
- break;
- case 's':
- sprintf(tbuf,"$f%d",operand & FP_REG_MASK);
- break;
- case 'S':
- DCHECK_EQ(((operand & FP_REG_MASK) & 1), 0);
- sprintf(tbuf,"$f%d",operand & FP_REG_MASK);
- break;
- case 'h':
- sprintf(tbuf,"%04x", operand);
- break;
- case 'M':
- case 'd':
- sprintf(tbuf,"%d", operand);
- break;
- case 'D':
- sprintf(tbuf,"%d", operand+1);
- break;
- case 'E':
- sprintf(tbuf,"%d", operand*4);
- break;
- case 'F':
- sprintf(tbuf,"%d", operand*2);
- break;
- case 't':
- sprintf(tbuf,"0x%08x (L%p)",
- (int) baseAddr + lir->offset + 4 +
- (operand << 2),
- lir->target);
- break;
- case 'T':
- sprintf(tbuf,"0x%08x",
- (int) (operand << 2));
- break;
- case 'u': {
- int offset_1 = lir->operands[0];
- int offset_2 = NEXT_LIR(lir)->operands[0];
- intptr_t target =
- ((((intptr_t) baseAddr + lir->offset + 4) &
- ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) &
- 0xfffffffc;
- sprintf(tbuf, "%p", (void *) target);
- break;
- }
-
- /* Nothing to print for BLX_2 */
- case 'v':
- strcpy(tbuf, "see above");
- break;
- case 'r':
- DCHECK(operand >= 0 && operand < X86_REG_COUNT);
- strcpy(tbuf, x86RegName[operand]);
- break;
- case 'N':
- // Placeholder for delay slot handling
- strcpy(tbuf, "; nop");
- break;
- default:
- strcpy(tbuf,"DecodeError");
- break;
- }
- buf += tbuf;
+ DCHECK_LT(static_cast<size_t>(operand), sizeof(x86RegName));
+ buf += x86RegName[operand];
}
- } else {
- buf += *fmt++;
+ break;
+ case 'c':
+ DCHECK_LT(static_cast<size_t>(operand), sizeof(x86CondName));
+ buf += x86CondName[operand];
+ break;
+ default:
+ buf += StringPrintf("DecodeError '%c'", fmt[i]);
+ break;
}
+ i++;
+ }
}
- return buf;
+ }
+ return buf;
}
void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix)