summaryrefslogtreecommitdiff
path: root/target-arm
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2011-02-03 19:43:24 +0000
committerAurelien Jarno <aurelien@aurel32.net>2011-02-04 21:30:15 +0100
commit5b43e045c6320f82faf187b0babc7009240ffdcf (patch)
tree85b73fd93fe22922e763e5526064a6e1c6e32a0f /target-arm
parent21166b4ea17510732e367beccb0b3eb92f7267c2 (diff)
downloadqemu-5b43e045c6320f82faf187b0babc7009240ffdcf.tar.gz
qemu-5b43e045c6320f82faf187b0babc7009240ffdcf.tar.bz2
qemu-5b43e045c6320f82faf187b0babc7009240ffdcf.zip
target-arm: Fix decoding of preload and memory hint space
Correct the decoding of the ARM preload and memory hint space, by adding decoding of PLI, PLDW and the v7MP unallocated hint space. This commit also corrects a slightly overexuberant decoding of PLD(register) which was not checking that bit 4 was one. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-arm')
-rw-r--r--target-arm/translate.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 514954300d..a8f1ffe6ff 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6100,9 +6100,31 @@ static void disas_arm_insn(CPUState * env, DisasContext *s)
goto illegal_op;
return;
}
- if ((insn & 0x0d70f000) == 0x0550f000)
- return; /* PLD */
- else if ((insn & 0x0ffffdff) == 0x01010000) {
+ if (((insn & 0x0f30f000) == 0x0510f000) ||
+ ((insn & 0x0f30f010) == 0x0710f000)) {
+ if ((insn & (1 << 22)) == 0) {
+ /* PLDW; v7MP */
+ if (!arm_feature(env, ARM_FEATURE_V7MP)) {
+ goto illegal_op;
+ }
+ }
+ /* Otherwise PLD; v5TE+ */
+ return;
+ }
+ if (((insn & 0x0f70f000) == 0x0450f000) ||
+ ((insn & 0x0f70f010) == 0x0650f000)) {
+ ARCH(7);
+ return; /* PLI; V7 */
+ }
+ if (((insn & 0x0f700000) == 0x04100000) ||
+ ((insn & 0x0f700010) == 0x06100000)) {
+ if (!arm_feature(env, ARM_FEATURE_V7MP)) {
+ goto illegal_op;
+ }
+ return; /* v7MP: Unallocated memory hint: must NOP */
+ }
+
+ if ((insn & 0x0ffffdff) == 0x01010000) {
ARCH(6);
/* setend */
if (insn & (1 << 9)) {