aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@google.com>2009-10-06 11:18:29 -0700
committerDavid 'Digit' Turner <digit@google.com>2009-10-06 11:18:29 -0700
commitbcc6ae14820ddb24e2403d84b420ce61f371ae94 (patch)
tree0a66fe380b727cf9fce01569c07a4a08f81c40b9
parentddf49e53df97a349f42c733059165dc73c9907dc (diff)
downloadexternal_qemu-bcc6ae14820ddb24e2403d84b420ce61f371ae94.zip
external_qemu-bcc6ae14820ddb24e2403d84b420ce61f371ae94.tar.gz
external_qemu-bcc6ae14820ddb24e2403d84b420ce61f371ae94.tar.bz2
Finally fix ARMv7 NEON emulation.
The real problem was the size of the static intermediate TCG opcode buffer. Due to its SIMD nature, a single Neon instruction can generate a very large number of corresponding TCG opcodes. Using lots of Neon instructions in a big looop like the one we have in our ARMv7-optimized memcpy did generate enough opcodes to overwrite the static gen_opc_buf buffer, resulting in overwrites into the following global buffer (gen_opparam_buf) corresponding to opcode parameters. The end result was generation of really broken host machine code, and completely unreliable emulation, including potential assertion failure in the liveness analysis pass. This patch does the following: - bumps the buffer size from 512 to 2048 - adds sanity checks that will abort the emulator if another similar overwrite is detected before machine code is generated. - remove the previous hack where we disabled the liveness analysis pass for ARMv7 Note that fixing the code generator to not use a static buffer is not trivial at this point, and that we much prefer to stay true to the upstream sources at the moment. Keep in mind that a previous patch also fixed a bug in the ARM->TCG translator (typo required changing a 0 into a 1) which affected Neon instructions too. I can't believe I just lost 2 weeks of my life on that bug :-(
-rw-r--r--android/main.c10
-rw-r--r--exec-all.h2
-rw-r--r--tcg/tcg.c21
-rw-r--r--tcg/tcg.h4
4 files changed, 13 insertions, 24 deletions
diff --git a/android/main.c b/android/main.c
index 686dac8..682cfce 100644
--- a/android/main.c
+++ b/android/main.c
@@ -67,8 +67,6 @@
#include "android/globals.h"
#include "tcpdump.h"
-#include "tcg.h"
-
/* in vl.c */
extern void qemu_help(int code);
@@ -2358,14 +2356,6 @@ int main(int argc, char **argv)
args[n++] = "-cpu";
args[n++] = "cortex-a8";
}
- /* we also disable liveness analysis in the code generator, because it seems
- * that ARMv7 -> x86 code generation triggers a fatal assertion when it is
- * activated. The drawback is that the generated code is slower, but at the
- * moment, ARMv7 emulation is only used to run the dex preopt pass within the
- * Android build system. This hack should be removed when we fix the code
- * generator.
- */
- tcg_disable_liveness_analysis = 1;
}
args[n++] = "-initrd";
diff --git a/exec-all.h b/exec-all.h
index 6d7ea60..0a240ee 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -38,7 +38,7 @@ typedef struct TranslationBlock TranslationBlock;
#define MAX_OP_PER_INSTR 64
/* A Call op needs up to 6 + 2N parameters (N = number of arguments). */
#define MAX_OPC_PARAM 10
-#define OPC_BUF_SIZE 512
+#define OPC_BUF_SIZE 2048
#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
/* Maximum size a TCG op can expand to. This is complicated because a
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 735b779..5d18842 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -57,8 +57,6 @@
#include "tcg-op.h"
#include "elf.h"
-int tcg_disable_liveness_analysis;
-
static void patch_reloc(uint8_t *code_ptr, int type,
tcg_target_long value, tcg_target_long addend);
@@ -1079,13 +1077,11 @@ static void tcg_liveness_analysis(TCGContext *s)
uint8_t *dead_temps;
unsigned int dead_iargs;
- if (tcg_disable_liveness_analysis) {
- int nb_ops;
- nb_ops = gen_opc_ptr - gen_opc_buf + 1;
-
- s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
- memset(s->op_dead_iargs, 0, nb_ops * sizeof(uint16_t));
- return;
+ /* sanity check */
+ if (gen_opc_ptr - gen_opc_buf > OPC_BUF_SIZE) {
+ fprintf(stderr, "PANIC: too many opcodes generated (%d > %d)\n",
+ gen_opc_ptr - gen_opc_buf, OPC_BUF_SIZE);
+ tcg_abort();
}
gen_opc_ptr++; /* skip end */
@@ -2021,6 +2017,13 @@ int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
}
#endif
+ /* sanity check */
+ if (gen_opc_ptr - gen_opc_buf > OPC_BUF_SIZE) {
+ fprintf(stderr, "PANIC: too many opcodes generated (%d > %d)\n",
+ gen_opc_ptr - gen_opc_buf, OPC_BUF_SIZE);
+ tcg_abort();
+ }
+
tcg_gen_code_common(s, gen_code_buf, -1);
/* flush instruction cache */
diff --git a/tcg/tcg.h b/tcg/tcg.h
index e00f35c..ad0bd14 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -471,7 +471,3 @@ extern uint8_t code_gen_prologue[];
#else
#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)
#endif
-
-/* set to 1 to disable LIVENESS ANALYSIS - temporary work-around for
- * specific fatal assertion error in ARMv7 -> x86 code translation. */
-extern int tcg_disable_liveness_analysis;