* [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support
@ 2013-09-27 0:47 Alexander Graf
2013-09-27 0:47 ` [Qemu-devel] [PATCH 01/60] arm: Use symbolic device names for vfp cmp Alexander Graf
` (61 more replies)
0 siblings, 62 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:47 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
Howdy,
This is the first batch of patches to implement AArch64 instruction
emulation in QEMU. It implements enough to execute simple AArch64
programs in linux-user mode.
We still have quite a big number of patches outstanding that will
come after this initial set, both in linux-user code as well as in
the AArch64 instruction emulator. But this series is already quite
big, so let's get this one through first.
If you need a rootfs to try this out on, I recommend using our openSUSE
12.3 tarball:
http://download.opensuse.org/repositories/devel:/ARM:/AArch64:/12.3/images/
Alex
Alexander Graf (60):
arm: Use symbolic device names for vfp cmp
arm: Give the fpscr rounding modes names
arm: Split VFP cmp from FPSCR setting
arm: Add AArch64 disassembler stub
softfloat: Add stubs for int16 conversion
AArch64: Add set_pc cpu method
ARM: Add 64bit VFP handling
AArch64: Add support to print VFP registers in CPU dump
AArch64: Add b and bl handling
AArch64: Add handling for br instructions
AArch64: Add STP instruction emulation
AArch64: Add ldarx style instruction emulation
AArch64: Add stubs for a64 specific helpers
AArch64: Add orr instruction emulation
AArch64: Add add instruction family emulation
AArch64: Add emulation for SIMD ld/st multiple
AArch64: Add dup GPR->Vec instruction emulation
AArch64: Add umov instruction emulation
AArch64: Add ins GPR->Vec instruction emulation
AArch64: Add SIMD ORR family instruction emulation
AArch64: Convert SIMD load/store to common function
AArch64: Add AdvSIMD scalar three same group handling
AArch64: Add AdvSIMD modified immediate group handling
AArch64: Add SIMD ushll instruction emulation
AArch64: Add SIMD shl instruction emulation
AArch64: Add ADR instruction emulation
AArch64: Add addi instruction emulation
AArch64: Add movi instruction emulation
AArch64: Add orri instruction emulation
AArch64: Add extr instruction emulation
AArch64: Add bfm family instruction emulation
AArch64: Add svc instruction emulation
AArch64: Add bc instruction emulation
AArch64: Add b.cond instruction emulation
AArch64: Add mrs instruction emulation
AArch64: Add msr instruction emulation
AArch64: Add hint instruction emulation
AArch64: Add stub barrier instruction emulation
AArch64: Add stub sys instruction emulation
AArch64: Add tbz instruction emulation
AArch64: Add ldr/str instruction family emulation
AArch64: Add literal ld instruction emulation
AArch64: Add cinc instruction emulation
AArch64: Add division instruction family emulation
AArch64: Add shift instruction family emulation
AArch64: Add rev instruction family emulation
AArch64: Add clz instruction emulation
AArch64: Add 0x1a encoding of add instructions
AArch64: Add "Data-processing (3 source)" instruction family
emulation
AArch64: Add "Floating-point<->fixed-point conversions" category
emulation
AArch64: Add fmov (scalar, immediate) instruction emulation
AArch64: Add "Floating-point<->integer conversions" instruction
family emulation
AArch64: Add "Floating-point compare" instruction family emulation
AArch64: Add "Floating-point data-processing (1 source)" (32 bit)
instruction family emulation
AArch64: Add "Floating-point data-processing (1 source)" (64 bit)
instruction family emulation
AArch64: Add "Floating-point data-processing (2 source)" (32 bit)
instruction family emulation
AArch64: Add "Floating-point data-processing (2 source)" (64 bit)
instruction family emulation
AArch64: Add "ADD (vector)" instruction emulation
AArch64: Add "Floating-point data-processing (3 source)" (32 bit)
instruction family emulation
AArch64: Add "Floating-point data-processing (3 source)" (64 bit)
instruction family emulation
disas.c | 6 +-
disas/Makefile.objs | 1 +
disas/aarch64.c | 31 +
fpu/softfloat.c | 21 +
include/disas/bfd.h | 1 +
include/fpu/softfloat.h | 4 +
target-arm/Makefile.objs | 2 +-
target-arm/cpu.h | 5 +
target-arm/cpu64.c | 8 +
target-arm/helper-a64.c | 309 +++++
target-arm/helper-a64.h | 35 +
target-arm/helper.c | 108 +-
target-arm/helper.h | 24 +-
target-arm/translate-a64.c | 2915 +++++++++++++++++++++++++++++++++++++++++++-
target-arm/translate.c | 13 +-
target-arm/translate.h | 5 +
16 files changed, 3424 insertions(+), 64 deletions(-)
create mode 100644 disas/aarch64.c
create mode 100644 target-arm/helper-a64.c
create mode 100644 target-arm/helper-a64.h
--
1.7.12.4
^ permalink raw reply [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 01/60] arm: Use symbolic device names for vfp cmp
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
@ 2013-09-27 0:47 ` Alexander Graf
2013-09-27 0:47 ` [Qemu-devel] [PATCH 02/60] arm: Give the fpscr rounding modes names Alexander Graf
` (60 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:47 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
The VFP cmp and cmpe helpers are quite cryptic to understand. This is
mostly thanks to the fact that they hardcode values rather than use
their symbolic counterparts.
Make them use names instead.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper.c | 50 ++++++++++++++++++++++++++------------------------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index e51ef20..3ec56d6 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3603,30 +3603,32 @@ float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env)
}
/* XXX: check quiet/signaling case */
-#define DO_VFP_cmp(p, type) \
-void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
-{ \
- uint32_t flags; \
- switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
- case 0: flags = 0x6; break; \
- case -1: flags = 0x8; break; \
- case 1: flags = 0x2; break; \
- default: case 2: flags = 0x3; break; \
- } \
- env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
- | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
-} \
-void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
-{ \
- uint32_t flags; \
- switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
- case 0: flags = 0x6; break; \
- case -1: flags = 0x8; break; \
- case 1: flags = 0x2; break; \
- default: case 2: flags = 0x3; break; \
- } \
- env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
- | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
+#define DO_VFP_cmp(p, type) \
+void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
+{ \
+ uint32_t flags; \
+ switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
+ case float_relation_equal: flags = PSTATE_Z | PSTATE_C; break; \
+ case float_relation_less: flags = PSTATE_N; break; \
+ case float_relation_greater: flags = PSTATE_C; break; \
+ default: \
+ case float_relation_unordered: flags = PSTATE_V | PSTATE_C; break; \
+ } \
+ env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
+ | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
+} \
+void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
+{ \
+ uint32_t flags; \
+ switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
+ case float_relation_equal: flags = PSTATE_Z | PSTATE_C; break; \
+ case float_relation_less: flags = PSTATE_N; break; \
+ case float_relation_greater: flags = PSTATE_C; break; \
+ default: \
+ case float_relation_unordered: flags = PSTATE_V | PSTATE_C; break; \
+ } \
+ env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
+ | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
}
DO_VFP_cmp(s, float32)
DO_VFP_cmp(d, float64)
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 02/60] arm: Give the fpscr rounding modes names
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
2013-09-27 0:47 ` [Qemu-devel] [PATCH 01/60] arm: Use symbolic device names for vfp cmp Alexander Graf
@ 2013-09-27 0:47 ` Alexander Graf
2013-09-27 0:47 ` [Qemu-devel] [PATCH 03/60] arm: Split VFP cmp from FPSCR setting Alexander Graf
` (59 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:47 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
When setting rounding modes we currently just hardcode the numeric values
for rounding modes in a big switch statement.
With AArch64 support coming, we will need to refer to these rounding modes
at different places throughout the code though, so let's better give them
names so we don't get confused by accident.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/cpu.h | 5 +++++
target-arm/helper.c | 8 ++++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index ce835ef..e69bb74 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -315,6 +315,11 @@ static inline bool is_a64(CPUARMState *env)
#define PSTATE_V_SHIFT 0
#define PSTATE_V (1 << PSTATE_V_SHIFT)
+#define ROUND_MODE_TIEEVEN 0
+#define ROUND_MODE_UP 1
+#define ROUND_MODE_DOWN 2
+#define ROUND_MODE_ZERO 3
+
/* you can call this signal handler from your SIGBUS and SIGSEGV
signal handlers to inform the virtual CPU of exceptions. non zero
is returned if the signal was handled by the virtual CPU. */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 3ec56d6..24e8ae4 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3521,16 +3521,16 @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
if (changed & (3 << 22)) {
i = (val >> 22) & 3;
switch (i) {
- case 0:
+ case ROUND_MODE_TIEEVEN:
i = float_round_nearest_even;
break;
- case 1:
+ case ROUND_MODE_UP:
i = float_round_up;
break;
- case 2:
+ case ROUND_MODE_DOWN:
i = float_round_down;
break;
- case 3:
+ case ROUND_MODE_ZERO:
i = float_round_to_zero;
break;
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 03/60] arm: Split VFP cmp from FPSCR setting
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
2013-09-27 0:47 ` [Qemu-devel] [PATCH 01/60] arm: Use symbolic device names for vfp cmp Alexander Graf
2013-09-27 0:47 ` [Qemu-devel] [PATCH 02/60] arm: Give the fpscr rounding modes names Alexander Graf
@ 2013-09-27 0:47 ` Alexander Graf
2013-09-27 14:05 ` Richard Henderson
2013-09-27 0:47 ` [Qemu-devel] [PATCH 04/60] arm: Add AArch64 disassembler stub Alexander Graf
` (58 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:47 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
The VFP cmp operations do a comparison and then store the result
in FPSCR.
For AArch64, we need to compare but store the result in normal PSTATE
instead. So split the comparison from FPSCR modifications.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper.c | 14 ++++++++++++--
target-arm/helper.h | 12 ++++++++----
target-arm/translate.c | 8 ++++----
3 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 24e8ae4..2b031a8 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3604,7 +3604,7 @@ float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env)
/* XXX: check quiet/signaling case */
#define DO_VFP_cmp(p, type) \
-void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
+uint32_t VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
{ \
uint32_t flags; \
switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
@@ -3614,10 +3614,15 @@ void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
default: \
case float_relation_unordered: flags = PSTATE_V | PSTATE_C; break; \
} \
+ return flags; \
+} \
+void VFP_HELPER(fpscr_cmp, p)(type a, type b, CPUARMState *env) \
+{ \
+ uint32_t flags = VFP_HELPER(cmp, p)(a, b, env); \
env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
| (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
} \
-void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
+uint32_t VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
{ \
uint32_t flags; \
switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
@@ -3627,6 +3632,11 @@ void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
default: \
case float_relation_unordered: flags = PSTATE_V | PSTATE_C; break; \
} \
+ return flags; \
+} \
+void VFP_HELPER(fpscr_cmpe, p)(type a, type b, CPUARMState *env) \
+{ \
+ uint32_t flags = VFP_HELPER(cmpe, p)(a, b, env); \
env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
| (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
}
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 63ae13a..e66362a 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -85,10 +85,14 @@ DEF_HELPER_1(vfp_abss, f32, f32)
DEF_HELPER_1(vfp_absd, f64, f64)
DEF_HELPER_2(vfp_sqrts, f32, f32, env)
DEF_HELPER_2(vfp_sqrtd, f64, f64, env)
-DEF_HELPER_3(vfp_cmps, void, f32, f32, env)
-DEF_HELPER_3(vfp_cmpd, void, f64, f64, env)
-DEF_HELPER_3(vfp_cmpes, void, f32, f32, env)
-DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
+DEF_HELPER_3(vfp_fpscr_cmps, void, f32, f32, env)
+DEF_HELPER_3(vfp_fpscr_cmpd, void, f64, f64, env)
+DEF_HELPER_3(vfp_fpscr_cmpes, void, f32, f32, env)
+DEF_HELPER_3(vfp_fpscr_cmped, void, f64, f64, env)
+DEF_HELPER_3(vfp_cmps, i32, f32, f32, env)
+DEF_HELPER_3(vfp_cmpd, i32, f64, f64, env)
+DEF_HELPER_3(vfp_cmpes, i32, f32, f32, env)
+DEF_HELPER_3(vfp_cmped, i32, f64, f64, env)
DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index b0a25ca..ef284da 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -1059,17 +1059,17 @@ static inline void gen_vfp_sqrt(int dp)
static inline void gen_vfp_cmp(int dp)
{
if (dp)
- gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
+ gen_helper_vfp_fpscr_cmpd(cpu_F0d, cpu_F1d, cpu_env);
else
- gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
+ gen_helper_vfp_fpscr_cmps(cpu_F0s, cpu_F1s, cpu_env);
}
static inline void gen_vfp_cmpe(int dp)
{
if (dp)
- gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
+ gen_helper_vfp_fpscr_cmped(cpu_F0d, cpu_F1d, cpu_env);
else
- gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
+ gen_helper_vfp_fpscr_cmpes(cpu_F0s, cpu_F1s, cpu_env);
}
static inline void gen_vfp_F1_ld0(int dp)
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 04/60] arm: Add AArch64 disassembler stub
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (2 preceding siblings ...)
2013-09-27 0:47 ` [Qemu-devel] [PATCH 03/60] arm: Split VFP cmp from FPSCR setting Alexander Graf
@ 2013-09-27 0:47 ` Alexander Graf
2013-09-27 14:07 ` Richard Henderson
2013-09-27 0:47 ` [Qemu-devel] [PATCH 05/60] softfloat: Add stubs for int16 conversion Alexander Graf
` (57 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:47 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
While we don't have a working disassembler for AArch64 yet, we still
don't want AArch64 code be disassembled through the old AArch32
disassembler.
So add a small disassembler stub that declares every instruction as
unsupported. This should be a good enough base to plug in a real one
later.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
disas.c | 6 +++++-
disas/Makefile.objs | 1 +
disas/aarch64.c | 31 +++++++++++++++++++++++++++++++
include/disas/bfd.h | 1 +
4 files changed, 38 insertions(+), 1 deletion(-)
create mode 100644 disas/aarch64.c
diff --git a/disas.c b/disas.c
index 0203ef2..5b6956e 100644
--- a/disas.c
+++ b/disas.c
@@ -150,7 +150,7 @@ bfd_vma bfd_getb16 (const bfd_byte *addr)
return (bfd_vma) v;
}
-#ifdef TARGET_ARM
+#if defined(TARGET_ARM) && !defined(TARGET_AARCH64)
static int
print_insn_thumb1(bfd_vma pc, disassemble_info *info)
{
@@ -224,6 +224,8 @@ void target_disas(FILE *out, CPUArchState *env, target_ulong code,
s.info.mach = bfd_mach_i386_i386;
}
print_insn = print_insn_i386;
+#elif defined(TARGET_AARCH64)
+ print_insn = print_insn_aarch64;
#elif defined(TARGET_ARM)
if (flags & 1) {
print_insn = print_insn_thumb1;
@@ -464,6 +466,8 @@ void monitor_disas(Monitor *mon, CPUArchState *env,
s.info.mach = bfd_mach_i386_i386;
}
print_insn = print_insn_i386;
+#elif defined(TARGET_AARCH64)
+ print_insn = print_insn_aarch64;
#elif defined(TARGET_ARM)
print_insn = print_insn_arm;
#elif defined(TARGET_ALPHA)
diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index 3b1e77a..55e9da4 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -13,6 +13,7 @@ common-obj-$(CONFIG_S390_DIS) += s390.o
common-obj-$(CONFIG_SH4_DIS) += sh4.o
common-obj-$(CONFIG_SPARC_DIS) += sparc.o
common-obj-$(CONFIG_LM32_DIS) += lm32.o
+common-obj-$(CONFIG_ARM_DIS) += aarch64.o
# TODO: As long as the TCG interpreter and its generated code depend
# on the QEMU target, we cannot compile the disassembler here.
diff --git a/disas/aarch64.c b/disas/aarch64.c
new file mode 100644
index 0000000..13c667d
--- /dev/null
+++ b/disas/aarch64.c
@@ -0,0 +1,31 @@
+#include "disas/bfd.h"
+
+#define INSNLEN 4
+
+/* Stub disassembler for aarch64. */
+
+int print_insn_aarch64(bfd_vma pc, struct disassemble_info *info)
+{
+ bfd_byte buffer[INSNLEN];
+ int status;
+ unsigned int size = 4;
+ uint32_t data;
+
+ /* Aarch64 instructions are always little-endian */
+ info->endian = BFD_ENDIAN_LITTLE;
+ info->bytes_per_chunk = size = INSNLEN;
+ info->display_endian = info->endian;
+
+ status = (*info->read_memory_func)(pc, buffer, size, info);
+ if (status != 0) {
+ (*info->memory_error_func)(status, pc, info);
+ return -1;
+ }
+
+ data = ldl_p(buffer);
+
+ (*info->fprintf_func)(info->stream, "\t[0x%08x] (%02x)\t.unknown",
+ data, (data >> 24) & 0x1f);
+
+ return size;
+}
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index 803b6ef..6947e4c 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -409,6 +409,7 @@ int print_insn_crisv10 (bfd_vma, disassemble_info*);
int print_insn_microblaze (bfd_vma, disassemble_info*);
int print_insn_ia64 (bfd_vma, disassemble_info*);
int print_insn_lm32 (bfd_vma, disassemble_info*);
+int print_insn_aarch64 (bfd_vma, disassemble_info*);
#if 0
/* Fetch the disassembler for a given BFD, if that support is available. */
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 05/60] softfloat: Add stubs for int16 conversion
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (3 preceding siblings ...)
2013-09-27 0:47 ` [Qemu-devel] [PATCH 04/60] arm: Add AArch64 disassembler stub Alexander Graf
@ 2013-09-27 0:47 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 06/60] AArch64: Add set_pc cpu method Alexander Graf
` (56 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:47 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On AArch64 we have a few instructions that can convert between floats
and 16 bit integers. Add stubs in the softfloat code to handle these,
but don't add code to actually do so. Instead, any call to them will
assert(0) for now.
This stub implementation should be replaced by something that actually
does something useful by someone who understands softfloat later.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
fpu/softfloat.c | 21 +++++++++++++++++++++
include/fpu/softfloat.h | 4 ++++
2 files changed, 25 insertions(+)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 7ba51b6..3e6f219 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -41,6 +41,7 @@ these four paragraphs for those parts of this code that are retained.
#include "config.h"
#include "fpu/softfloat.h"
+#include "assert.h"
/*----------------------------------------------------------------------------
| Primitive arithmetic functions, including multi-word arithmetic, and
@@ -1378,6 +1379,11 @@ int32 float32_to_int32( float32 a STATUS_PARAM )
}
+int_fast16_t float32_to_int16( float32 a STATUS_PARAM )
+{
+ assert(0);
+}
+
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point value
| `a' to the 32-bit two's complement integer format. The conversion is
@@ -2762,6 +2768,11 @@ int32 float64_to_int32( float64 a STATUS_PARAM )
}
+int_fast16_t float64_to_int16( float64 a STATUS_PARAM )
+{
+ assert(0);
+}
+
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point value
| `a' to the 32-bit two's complement integer format. The conversion is
@@ -6446,6 +6457,11 @@ uint32 float32_to_uint32( float32 a STATUS_PARAM )
return res;
}
+uint_fast16_t float32_to_uint16( float32 a STATUS_PARAM )
+{
+ assert(0);
+}
+
uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
{
int64_t v;
@@ -6500,6 +6516,11 @@ uint32 float64_to_uint32( float64 a STATUS_PARAM )
return res;
}
+uint_fast16_t float64_to_uint16( float64 a STATUS_PARAM )
+{
+ assert(0);
+}
+
uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
{
int64_t v;
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index f3927e2..b3c85f4 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -268,6 +268,8 @@ extern const float16 float16_default_nan;
int_fast16_t float32_to_int16_round_to_zero(float32 STATUS_PARAM);
uint_fast16_t float32_to_uint16_round_to_zero(float32 STATUS_PARAM);
int32 float32_to_int32( float32 STATUS_PARAM );
+int_fast16_t float32_to_int16( float32 STATUS_PARAM );
+uint_fast16_t float32_to_uint16( float32 STATUS_PARAM );
int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM );
uint32 float32_to_uint32( float32 STATUS_PARAM );
uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM );
@@ -373,6 +375,8 @@ int_fast16_t float64_to_int16_round_to_zero(float64 STATUS_PARAM);
uint_fast16_t float64_to_uint16_round_to_zero(float64 STATUS_PARAM);
int32 float64_to_int32( float64 STATUS_PARAM );
int32 float64_to_int32_round_to_zero( float64 STATUS_PARAM );
+int_fast16_t float64_to_int16( float64 STATUS_PARAM );
+uint_fast16_t float64_to_uint16( float64 STATUS_PARAM );
uint32 float64_to_uint32( float64 STATUS_PARAM );
uint32 float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
int64 float64_to_int64( float64 STATUS_PARAM );
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 06/60] AArch64: Add set_pc cpu method
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (4 preceding siblings ...)
2013-09-27 0:47 ` [Qemu-devel] [PATCH 05/60] softfloat: Add stubs for int16 conversion Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 07/60] ARM: Add 64bit VFP handling Alexander Graf
` (55 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
When executing translation blocks we need to be able to recover
our program counter. Add a method to set it for AArch64 CPUs.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/cpu64.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c
index 3e99c21..a53748a 100644
--- a/target-arm/cpu64.c
+++ b/target-arm/cpu64.c
@@ -68,11 +68,19 @@ static void aarch64_cpu_finalizefn(Object *obj)
{
}
+static void aarch64_cpu_set_pc(CPUState *cs, vaddr value)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+
+ cpu->env.pc = value;
+}
+
static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
cc->dump_state = aarch64_cpu_dump_state;
+ cc->set_pc = aarch64_cpu_set_pc;
cc->gdb_read_register = aarch64_cpu_gdb_read_register;
cc->gdb_write_register = aarch64_cpu_gdb_write_register;
cc->gdb_num_core_regs = 34;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 07/60] ARM: Add 64bit VFP handling
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (5 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 06/60] AArch64: Add set_pc cpu method Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 08/60] AArch64: Add support to print VFP registers in CPU Alexander Graf
` (54 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
With AArch64 VFP can now handle 64bit wide VFP float-int conversions.
Add handlers for them.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper.c | 40 +++++++++++++++++++++++++---------------
target-arm/helper.h | 8 ++++++++
2 files changed, 33 insertions(+), 15 deletions(-)
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2b031a8..7bf32b8 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3698,36 +3698,46 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
}
/* VFP3 fixed point conversion. */
-#define VFP_CONV_FIX(name, p, fsz, itype, sign) \
-float##fsz HELPER(vfp_##name##to##p)(uint##fsz##_t x, uint32_t shift, \
+#define VFP_CONV_FIX(name, p, fsz, isz, itype, sign) \
+float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
void *fpstp) \
{ \
float_status *fpst = fpstp; \
float##fsz tmp; \
- tmp = sign##int32_to_##float##fsz((itype##_t)x, fpst); \
+ tmp = sign##int##isz##_to_##float##fsz((itype##_t)x, fpst); \
return float##fsz##_scalbn(tmp, -(int)shift, fpst); \
} \
-uint##fsz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \
+uint##isz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \
void *fpstp) \
{ \
float_status *fpst = fpstp; \
float##fsz tmp; \
+ uint##isz##_t r; \
if (float##fsz##_is_any_nan(x)) { \
float_raise(float_flag_invalid, fpst); \
return 0; \
} \
tmp = float##fsz##_scalbn(x, shift, fpst); \
- return float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \
-}
-
-VFP_CONV_FIX(sh, d, 64, int16, )
-VFP_CONV_FIX(sl, d, 64, int32, )
-VFP_CONV_FIX(uh, d, 64, uint16, u)
-VFP_CONV_FIX(ul, d, 64, uint32, u)
-VFP_CONV_FIX(sh, s, 32, int16, )
-VFP_CONV_FIX(sl, s, 32, int32, )
-VFP_CONV_FIX(uh, s, 32, uint16, u)
-VFP_CONV_FIX(ul, s, 32, uint32, u)
+ if (((float_status*)fpstp)->float_rounding_mode == float_round_to_zero) { \
+ r = float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \
+ } else { \
+ r = float##fsz##_to_##itype(tmp, fpst); \
+ } \
+ return r; \
+}
+
+VFP_CONV_FIX(sh, d, 64, 64, int16, )
+VFP_CONV_FIX(sl, d, 64, 64, int32, )
+VFP_CONV_FIX(sq, d, 64, 64, int64, )
+VFP_CONV_FIX(uh, d, 64, 64, uint16, u)
+VFP_CONV_FIX(ul, d, 64, 64, uint32, u)
+VFP_CONV_FIX(uq, d, 64, 64, uint64, u)
+VFP_CONV_FIX(sh, s, 32, 32, int16, )
+VFP_CONV_FIX(sl, s, 32, 32, int32, )
+VFP_CONV_FIX(sq, s, 32, 64, int64, )
+VFP_CONV_FIX(uh, s, 32, 32, uint16, u)
+VFP_CONV_FIX(ul, s, 32, 32, uint32, u)
+VFP_CONV_FIX(uq, s, 32, 64, int64, u)
#undef VFP_CONV_FIX
/* Half precision conversions. */
diff --git a/target-arm/helper.h b/target-arm/helper.h
index e66362a..2caa219 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -113,20 +113,28 @@ DEF_HELPER_2(vfp_tosizd, i32, f64, ptr)
DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
+DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
DEF_HELPER_3(vfp_touhs, i32, f32, i32, ptr)
DEF_HELPER_3(vfp_touls, i32, f32, i32, ptr)
+DEF_HELPER_3(vfp_touqs, i64, f32, i32, ptr)
DEF_HELPER_3(vfp_toshd, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_tosld, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_tosqd, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_touhd, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_tould, i64, f64, i32, ptr)
+DEF_HELPER_3(vfp_touqd, i64, f64, i32, ptr)
DEF_HELPER_3(vfp_shtos, f32, i32, i32, ptr)
DEF_HELPER_3(vfp_sltos, f32, i32, i32, ptr)
+DEF_HELPER_3(vfp_sqtos, f32, i64, i32, ptr)
DEF_HELPER_3(vfp_uhtos, f32, i32, i32, ptr)
DEF_HELPER_3(vfp_ultos, f32, i32, i32, ptr)
+DEF_HELPER_3(vfp_uqtos, f32, i64, i32, ptr)
DEF_HELPER_3(vfp_shtod, f64, i64, i32, ptr)
DEF_HELPER_3(vfp_sltod, f64, i64, i32, ptr)
+DEF_HELPER_3(vfp_sqtod, f64, i64, i32, ptr)
DEF_HELPER_3(vfp_uhtod, f64, i64, i32, ptr)
DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
+DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env)
DEF_HELPER_2(vfp_fcvt_f32_to_f16, i32, f32, env)
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 08/60] AArch64: Add support to print VFP registers in CPU
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (6 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 07/60] ARM: Add 64bit VFP handling Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 09/60] AArch64: Add b and bl handling Alexander Graf
` (53 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
When dumping the current CPU state, we can also get a request
to dump the FPU state along with the CPU's integer state.
Add support to dump the VFP state when that flag is set, so that
we can properly debug code that modifies floating point registers.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index f120088..73ccade 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -85,6 +85,21 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
env->pstate & PSTATE_C ? 'c' : '.',
env->pstate & PSTATE_V ? 'v' : '.');
cpu_fprintf(f, "\n");
+
+ if (flags & CPU_DUMP_FPU) {
+ int numvfpregs = 32;
+ for (i = 0; i < numvfpregs; i++) {
+ uint64_t v = float64_val(env->vfp.regs[i * 2]);
+ uint64_t v1 = float64_val(env->vfp.regs[(i * 2) + 1]);
+ if (!v && !v1) {
+ /* skip empty registers - makes traces easier to read */
+ continue;
+ }
+ cpu_fprintf(f, "d%02d.0=%016" PRIx64 " " "d%02d.0=%016" PRIx64 "\n",
+ i, v, i, v1);
+ }
+ cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
+ }
}
void gen_a64_set_pc_im(uint64_t val)
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 09/60] AArch64: Add b and bl handling
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (7 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 08/60] AArch64: Add support to print VFP registers in CPU Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 9:11 ` Claudio Fontana
2013-09-27 14:40 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 10/60] AArch64: Add handling for br instructions Alexander Graf
` (52 subsequent siblings)
61 siblings, 2 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This adds handling for the b and bl instructions.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 73ccade..267fd4d 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -133,6 +133,58 @@ static void real_unallocated_encoding(DisasContext *s)
real_unallocated_encoding(s); \
} while (0)
+static int get_bits(uint32_t inst, int start, int len)
+{
+ return (inst >> start) & ((1 << len) - 1);
+}
+
+static int get_sbits(uint32_t inst, int start, int len)
+{
+ int r = get_bits(inst, start, len);
+ if (r & (1 << (len - 1))) {
+ /* Extend the MSB 1 to the higher bits */
+ r |= -1 & ~((1ULL << len) - 1);
+ }
+ return r;
+}
+
+static TCGv_i64 cpu_reg(int reg)
+{
+ if (reg == 31) {
+ /* XXX leaks temps */
+ return tcg_const_i64(0);
+ } else {
+ return cpu_X[reg];
+ }
+}
+
+static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
+{
+ TranslationBlock *tb;
+
+ tb = s->tb;
+ if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+ tcg_gen_goto_tb(n);
+ gen_a64_set_pc_im(dest);
+ tcg_gen_exit_tb((tcg_target_long)tb + n);
+ } else {
+ gen_a64_set_pc_im(dest);
+ tcg_gen_exit_tb(0);
+ }
+}
+
+static void handle_b(DisasContext *s, uint32_t insn)
+{
+ uint64_t addr = s->pc - 4 + (get_sbits(insn, 0, 26) << 2);
+
+ if (get_bits(insn, 31, 1)) {
+ /* BL */
+ tcg_gen_movi_i64(cpu_reg(30), s->pc);
+ }
+ gen_goto_tb(s, 0, addr);
+ s->is_jmp = DISAS_TB_JUMP;
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -141,12 +193,21 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
s->insn = insn;
s->pc += 4;
+ /* One-off branch instruction layout */
+ switch (insn >> 26) {
+ case 0x25:
+ case 0x5:
+ handle_b(s, insn);
+ goto insn_done;
+ }
+
switch ((insn >> 24) & 0x1f) {
default:
unallocated_encoding(s);
break;
}
+insn_done:
if (unlikely(s->singlestep_enabled) && (s->is_jmp == DISAS_TB_JUMP)) {
/* go through the main loop for single step */
s->is_jmp = DISAS_JUMP;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 10/60] AArch64: Add handling for br instructions
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (8 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 09/60] AArch64: Add b and bl handling Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 14:51 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 11/60] AArch64: Add STP instruction emulation Alexander Graf
` (51 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds support for branch instructions that act on registers
rather than immediates (jmp, call, ret).
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 267fd4d..f4694b4 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -185,6 +185,29 @@ static void handle_b(DisasContext *s, uint32_t insn)
s->is_jmp = DISAS_TB_JUMP;
}
+static void handle_br(DisasContext *s, uint32_t insn)
+{
+ int branch_type = get_bits(insn, 21, 2);
+ int source = get_bits(insn, 5, 5);
+
+ switch (branch_type) {
+ case 0: /* JMP */
+ break;
+ case 1: /* CALL */
+ tcg_gen_movi_i64(cpu_reg(30), s->pc);
+ break;
+ case 2: /* RET */
+ source = 30;
+ break;
+ case 3:
+ unallocated_encoding(s);
+ return;
+ }
+
+ tcg_gen_mov_i64(cpu_pc, cpu_reg(source));
+ s->is_jmp = DISAS_JUMP;
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -199,6 +222,12 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x5:
handle_b(s, insn);
goto insn_done;
+ case 0x35:
+ if ((insn & 0xff9ffc1f) == 0xd61f0000) {
+ handle_br(s, insn);
+ goto insn_done;
+ }
+ break;
}
switch ((insn >> 24) & 0x1f) {
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 11/60] AArch64: Add STP instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (9 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 10/60] AArch64: Add handling for br instructions Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 17:38 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 12/60] AArch64: Add ldarx style " Alexander Graf
` (50 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds support for the STP instruction. It spans pretty much
all store possibilities, so the patch also adds handling for load/store
of integer as well as vector registers.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 263 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 263 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index f4694b4..5db48c7 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -102,6 +102,12 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
}
}
+static int get_mem_index(DisasContext *s)
+{
+ /* XXX only user mode for now */
+ return 1;
+}
+
void gen_a64_set_pc_im(uint64_t val)
{
tcg_gen_movi_i64(cpu_pc, val);
@@ -148,6 +154,11 @@ static int get_sbits(uint32_t inst, int start, int len)
return r;
}
+static int get_reg(uint32_t inst)
+{
+ return get_bits(inst, 0, 5);
+}
+
static TCGv_i64 cpu_reg(int reg)
{
if (reg == 31) {
@@ -158,6 +169,20 @@ static TCGv_i64 cpu_reg(int reg)
}
}
+static TCGv_i64 cpu_reg_sp(int reg)
+{
+ return cpu_X[reg];
+}
+
+static void clear_fpreg(int dest)
+{
+ int freg_offs = offsetof(CPUARMState, vfp.regs[dest * 2]);
+ TCGv_i64 tcg_zero = tcg_const_i64(0);
+
+ tcg_gen_st_i64(tcg_zero, cpu_env, freg_offs);
+ tcg_gen_st_i64(tcg_zero, cpu_env, freg_offs + sizeof(float64));
+}
+
static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
{
TranslationBlock *tb;
@@ -208,6 +233,221 @@ static void handle_br(DisasContext *s, uint32_t insn)
s->is_jmp = DISAS_JUMP;
}
+static void ldst_do_vec_int(DisasContext *s, int freg_offs, TCGv_i64 tcg_addr,
+ int size, bool is_store)
+{
+ TCGv_i64 tcg_tmp = tcg_temp_new_i64();
+
+ if (is_store) {
+ switch (size) {
+ case 0:
+ tcg_gen_ld8u_i64(tcg_tmp, cpu_env, freg_offs);
+ tcg_gen_qemu_st8(tcg_tmp, tcg_addr, get_mem_index(s));
+ break;
+ case 1:
+ tcg_gen_ld16u_i64(tcg_tmp, cpu_env, freg_offs);
+ tcg_gen_qemu_st16(tcg_tmp, tcg_addr, get_mem_index(s));
+ break;
+ case 2:
+ tcg_gen_ld32u_i64(tcg_tmp, cpu_env, freg_offs);
+ tcg_gen_qemu_st32(tcg_tmp, tcg_addr, get_mem_index(s));
+ break;
+ case 4:
+ tcg_gen_ld_i64(tcg_tmp, cpu_env, freg_offs);
+ tcg_gen_qemu_st64(tcg_tmp, tcg_addr, get_mem_index(s));
+ freg_offs += sizeof(uint64_t);
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, sizeof(uint64_t));
+ /* fall through */
+ case 3:
+ tcg_gen_ld_i64(tcg_tmp, cpu_env, freg_offs);
+ tcg_gen_qemu_st64(tcg_tmp, tcg_addr, get_mem_index(s));
+ break;
+ }
+ } else {
+ switch (size) {
+ case 0:
+ tcg_gen_qemu_ld8u(tcg_tmp, tcg_addr, get_mem_index(s));
+ tcg_gen_st8_i64(tcg_tmp, cpu_env, freg_offs);
+ break;
+ case 1:
+ tcg_gen_qemu_ld16u(tcg_tmp, tcg_addr, get_mem_index(s));
+ tcg_gen_st16_i64(tcg_tmp, cpu_env, freg_offs);
+ break;
+ case 2:
+ tcg_gen_qemu_ld32u(tcg_tmp, tcg_addr, get_mem_index(s));
+ tcg_gen_st32_i64(tcg_tmp, cpu_env, freg_offs);
+ break;
+ case 4:
+ tcg_gen_qemu_ld64(tcg_tmp, tcg_addr, get_mem_index(s));
+ tcg_gen_st_i64(tcg_tmp, cpu_env, freg_offs);
+ freg_offs += sizeof(uint64_t);
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, sizeof(uint64_t));
+ /* fall through */
+ case 3:
+ tcg_gen_qemu_ld64(tcg_tmp, tcg_addr, get_mem_index(s));
+ tcg_gen_st_i64(tcg_tmp, cpu_env, freg_offs);
+ break;
+ }
+ }
+
+ tcg_temp_free_i64(tcg_tmp);
+}
+
+static void ldst_do_vec(DisasContext *s, int dest, TCGv_i64 tcg_addr_real,
+ int size, bool is_store)
+{
+ TCGv_i64 tcg_addr = tcg_temp_new_i64();
+ int freg_offs = offsetof(CPUARMState, vfp.regs[dest * 2]);
+
+ /* we don't want to modify the caller's tcg_addr */
+ tcg_gen_mov_i64(tcg_addr, tcg_addr_real);
+
+ if (!is_store) {
+ /* normal ldst clears non-loaded bits */
+ clear_fpreg(dest);
+ }
+
+ ldst_do_vec_int(s, freg_offs, tcg_addr, size, is_store);
+
+ tcg_temp_free(tcg_addr);
+}
+
+static void ldst_do_gpr(DisasContext *s, int dest, TCGv_i64 tcg_addr, int size,
+ bool is_store, bool is_signed)
+{
+ if (is_store) {
+ switch (size) {
+ case 0:
+ tcg_gen_qemu_st8(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ case 1:
+ tcg_gen_qemu_st16(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ case 2:
+ tcg_gen_qemu_st32(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ case 3:
+ tcg_gen_qemu_st64(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ }
+ } else {
+ if (is_signed) {
+ /* XXX check what impact regsize has */
+ switch (size) {
+ case 0:
+ tcg_gen_qemu_ld8s(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ case 1:
+ tcg_gen_qemu_ld16s(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ case 2:
+ tcg_gen_qemu_ld32s(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ case 3:
+ tcg_gen_qemu_ld64(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ }
+ } else {
+ switch (size) {
+ case 0:
+ tcg_gen_qemu_ld8u(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ case 1:
+ tcg_gen_qemu_ld16u(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ case 2:
+ tcg_gen_qemu_ld32u(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ case 3:
+ tcg_gen_qemu_ld64(cpu_reg(dest), tcg_addr, get_mem_index(s));
+ break;
+ }
+ }
+ }
+}
+
+static void ldst_do(DisasContext *s, int dest, TCGv_i64 tcg_addr, int size,
+ bool is_store, bool is_signed, bool is_vector)
+{
+ if (is_vector) {
+ ldst_do_vec(s, dest, tcg_addr, size, is_store);
+ } else {
+ ldst_do_gpr(s, dest, tcg_addr, size, is_store, is_signed);
+ }
+}
+
+static void handle_stp(DisasContext *s, uint32_t insn)
+{
+ int rt = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int rt2 = get_bits(insn, 10, 5);
+ int offset = get_sbits(insn, 15, 7);
+ int is_store = !get_bits(insn, 22, 1);
+ int type = get_bits(insn, 23, 2);
+ int is_vector = get_bits(insn, 26, 1);
+ int is_signed = get_bits(insn, 30, 1);
+ int is_32bit = !get_bits(insn, 31, 1);
+ TCGv_i64 tcg_addr;
+ bool postindex;
+ bool wback;
+ int size = is_32bit ? 2 : 3;
+
+ if (is_vector) {
+ size = 2 + get_bits(insn, 30, 2);
+ }
+
+ switch (type) {
+ default:
+ case 0:
+ postindex = false;
+ wback = false;
+ break;
+ case 1: /* STP (post-index) */
+ postindex = true;
+ wback = true;
+ break;
+ case 2: /* STP (signed offset */
+ postindex = false;
+ wback = false;
+ break;
+ case 3: /* STP (pre-index) */
+ postindex = false;
+ wback = true;
+ break;
+ }
+
+ if (is_signed && !is_32bit) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ offset <<= size;
+
+ tcg_addr = tcg_temp_new_i64();
+ if (rn == 31) {
+ /* XXX check SP alignment */
+ }
+ tcg_gen_mov_i64(tcg_addr, cpu_reg_sp(rn));
+
+ if (!postindex) {
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
+ }
+
+ ldst_do(s, rt, tcg_addr, size, is_store, is_signed, is_vector);
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
+ ldst_do(s, rt2, tcg_addr, size, is_store, is_signed, is_vector);
+ tcg_gen_subi_i64(tcg_addr, tcg_addr, 1 << size);
+
+ if (wback) {
+ if (postindex) {
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
+ }
+ tcg_gen_mov_i64(cpu_reg_sp(rn), tcg_addr);
+ }
+
+ tcg_temp_free_i64(tcg_addr);
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -230,7 +470,30 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
break;
}
+ /* Typical major opcode encoding */
switch ((insn >> 24) & 0x1f) {
+ case 0x08:
+ case 0x09:
+ if (get_bits(insn, 29, 1)) {
+ handle_stp(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
+ case 0x0c:
+ if (get_bits(insn, 29, 1)) {
+ handle_stp(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
+ case 0x0d:
+ if (get_bits(insn, 29, 1)) {
+ handle_stp(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 12/60] AArch64: Add ldarx style instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (10 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 11/60] AArch64: Add STP instruction emulation Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 13/60] AArch64: Add stubs for a64 specific helpers Alexander Graf
` (49 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for load and store instructions with register
offset.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 38 +++++++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 5db48c7..039e73a 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -448,6 +448,42 @@ static void handle_stp(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_addr);
}
+static void handle_ldarx(DisasContext *s, uint32_t insn)
+{
+ int rt = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int rt2 = get_bits(insn, 10, 5);
+ int is_atomic = !get_bits(insn, 15, 1);
+ int rs = get_bits(insn, 16, 5);
+ int is_pair = get_bits(insn, 21, 1);
+ int is_store = !get_bits(insn, 22, 1);
+ int is_excl = !get_bits(insn, 23, 1);
+ int size = get_bits(insn, 30, 2);
+ TCGv_i64 tcg_addr;
+
+ tcg_addr = tcg_temp_new_i64();
+ if (rn == 31) {
+ /* XXX check SP alignment */
+ }
+ tcg_gen_mov_i64(tcg_addr, cpu_reg_sp(rn));
+
+ if (is_atomic) {
+ /* XXX add locking */
+ }
+ if (is_store && is_excl) {
+ /* XXX find out what status it wants */
+ tcg_gen_movi_i64(cpu_reg(rs), 0);
+ }
+
+ ldst_do_gpr(s, rt, tcg_addr, size, is_store, false);
+ if (is_pair) {
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
+ ldst_do_gpr(s, rt2, tcg_addr, size, is_store, false);
+ }
+
+ tcg_temp_free_i64(tcg_addr);
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -477,7 +513,7 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
if (get_bits(insn, 29, 1)) {
handle_stp(s, insn);
} else {
- unallocated_encoding(s);
+ handle_ldarx(s, insn);
}
break;
case 0x0c:
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 13/60] AArch64: Add stubs for a64 specific helpers
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (11 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 12/60] AArch64: Add ldarx style " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation Alexander Graf
` (48 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
We will need helpers that only make sense with AArch64. Add
helper-a64.{c,h} files as stubs that we can fill with these
helpers in the following patches.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/Makefile.objs | 2 +-
target-arm/helper-a64.c | 26 ++++++++++++++++++++++++++
target-arm/helper-a64.h | 19 +++++++++++++++++++
target-arm/helper.h | 4 ++++
4 files changed, 50 insertions(+), 1 deletion(-)
create mode 100644 target-arm/helper-a64.c
create mode 100644 target-arm/helper-a64.h
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index 6453f5c..0979eeb 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -5,4 +5,4 @@ obj-$(CONFIG_NO_KVM) += kvm-stub.o
obj-y += translate.o op_helper.o helper.o cpu.o
obj-y += neon_helper.o iwmmxt_helper.o
obj-y += gdbstub.o
-obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o gdbstub64.o
+obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
new file mode 100644
index 0000000..8105fb5
--- /dev/null
+++ b/target-arm/helper-a64.c
@@ -0,0 +1,26 @@
+/*
+ * AArch64 specific helpers
+ *
+ * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cpu.h"
+#include "exec/gdbstub.h"
+#include "helper.h"
+#include "qemu/host-utils.h"
+#include "sysemu/sysemu.h"
+#include "qemu/bitops.h"
+
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
new file mode 100644
index 0000000..30ecf78
--- /dev/null
+++ b/target-arm/helper-a64.h
@@ -0,0 +1,19 @@
+/*
+ * AArch64 specific helper definitions
+ *
+ * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 2caa219..bbdd267 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -470,4 +470,8 @@ DEF_HELPER_3(neon_qzip8, void, env, i32, i32)
DEF_HELPER_3(neon_qzip16, void, env, i32, i32)
DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
+#ifdef TARGET_AARCH64
+#include "helper-a64.h"
+#endif
+
#include "exec/def-helper.h"
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (12 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 13/60] AArch64: Add stubs for a64 specific helpers Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 18:25 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 15/60] AArch64: Add add instruction family emulation Alexander Graf
` (47 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for the orr instruction.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 28 +++++++++++
target-arm/helper-a64.h | 1 +
target-arm/translate-a64.c | 120 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 149 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 8105fb5..da72b7f 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -24,3 +24,31 @@
#include "sysemu/sysemu.h"
#include "qemu/bitops.h"
+uint32_t HELPER(pstate_add)(uint32_t pstate, uint64_t a1, uint64_t a2,
+ uint64_t ar)
+{
+ int64_t s1 = a1;
+ int64_t s2 = a2;
+ int64_t sr = ar;
+
+ pstate &= ~(PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V);
+
+ if (sr < 0) {
+ pstate |= PSTATE_N;
+ }
+
+ if (!ar) {
+ pstate |= PSTATE_Z;
+ }
+
+ if (ar && (ar < a1)) {
+ pstate |= PSTATE_C;
+ }
+
+ if ((s1 > 0 && s2 > 0 && sr < 0) ||
+ (s1 < 0 && s2 < 0 && sr > 0)) {
+ pstate |= PSTATE_V;
+ }
+
+ return pstate;
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 30ecf78..1492b15 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -17,3 +17,4 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+DEF_HELPER_FLAGS_4(pstate_add, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 039e73a..2a80715 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -484,6 +484,123 @@ static void handle_ldarx(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_addr);
}
+static TCGv_i64 get_shift(int reg, int shift_type, TCGv_i64 tcg_shift,
+ int is_32bit)
+{
+ TCGv_i64 r;
+
+ r = tcg_temp_new_i64();
+
+ /* XXX carry_out */
+ switch (shift_type) {
+ case 0: /* LSL */
+ tcg_gen_shl_i64(r, cpu_reg(reg), tcg_shift);
+ break;
+ case 1: /* LSR */
+ tcg_gen_shr_i64(r, cpu_reg(reg), tcg_shift);
+ break;
+ case 2: /* ASR */
+ if (is_32bit) {
+ TCGv_i64 tcg_tmp = tcg_temp_new_i64();
+ tcg_gen_ext32s_i64(tcg_tmp, cpu_reg(reg));
+ tcg_gen_sar_i64(r, tcg_tmp, tcg_shift);
+ tcg_temp_free_i64(tcg_tmp);
+ } else {
+ tcg_gen_sar_i64(r, cpu_reg(reg), tcg_shift);
+ }
+ break;
+ case 3:
+ tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
+ break;
+ }
+
+ return r;
+}
+
+static TCGv_i64 get_shifti(int reg, int shift_type, int shift, int is_32bit)
+{
+ TCGv_i64 tcg_shift;
+ TCGv_i64 r;
+
+ if (!shift) {
+ r = tcg_temp_new_i64();
+ tcg_gen_mov_i64(r, cpu_reg(reg));
+ return r;
+ }
+
+ tcg_shift = tcg_const_i64(shift);
+ r = get_shift(reg, shift_type, tcg_shift, is_32bit);
+ tcg_temp_free_i64(tcg_shift);
+
+ return r;
+}
+
+static void handle_orr(DisasContext *s, uint32_t insn)
+{
+ int is_32bit = !get_bits(insn, 31, 1);
+ int dest = get_reg(insn);
+ int source = get_bits(insn, 5, 5);
+ int rm = get_bits(insn, 16, 5);
+ int shift_amount = get_sbits(insn, 10, 6);
+ int is_n = get_bits(insn, 21, 1);
+ int shift_type = get_bits(insn, 22, 2);
+ int opc = get_bits(insn, 29, 2);
+ bool setflags = (opc == 0x3);
+ TCGv_i64 tcg_op2;
+ TCGv_i64 tcg_dest;
+
+ if (is_32bit && (shift_amount < 0)) {
+ /* reserved value */
+ unallocated_encoding(s);
+ }
+
+ /* MOV is dest = xzr & (source & ~0) */
+ if (!shift_amount && source == 0x1f) {
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(cpu_reg_sp(dest), cpu_reg(rm));
+ } else {
+ tcg_gen_mov_i64(cpu_reg_sp(dest), cpu_reg(rm));
+ }
+ if (is_n) {
+ tcg_gen_not_i64(cpu_reg_sp(dest), cpu_reg_sp(dest));
+ }
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(cpu_reg_sp(dest), cpu_reg_sp(dest));
+ }
+ return;
+ }
+
+ tcg_op2 = get_shifti(rm, shift_type, shift_amount & (is_32bit ? 31 : 63),
+ is_32bit);
+ if (is_n) {
+ tcg_gen_not_i64(tcg_op2, tcg_op2);
+ }
+
+ tcg_dest = cpu_reg(dest);
+ switch (opc) {
+ case 0x0:
+ case 0x3:
+ tcg_gen_and_i64(tcg_dest, cpu_reg(source), tcg_op2);
+ break;
+ case 0x1:
+ tcg_gen_or_i64(tcg_dest, cpu_reg(source), tcg_op2);
+ break;
+ case 0x2:
+ tcg_gen_xor_i64(tcg_dest, cpu_reg(source), tcg_op2);
+ break;
+ }
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(tcg_dest, tcg_dest);
+ }
+
+ if (setflags) {
+ gen_helper_pstate_add(pstate, pstate, tcg_dest, cpu_reg(31), tcg_dest);
+ }
+
+ tcg_temp_free_i64(tcg_op2);
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -516,6 +633,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_ldarx(s, insn);
}
break;
+ case 0x0a:
+ handle_orr(s, insn);
+ break;
case 0x0c:
if (get_bits(insn, 29, 1)) {
handle_stp(s, insn);
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 15/60] AArch64: Add add instruction family emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (13 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 18:51 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 16/60] AArch64: Add emulation for SIMD ld/st multiple Alexander Graf
` (46 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds support for add and friends.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 85 +++++++++++++++++++++++++
target-arm/helper-a64.h | 3 +
target-arm/translate-a64.c | 150 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 238 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index da72b7f..2400b6e 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -52,3 +52,88 @@ uint32_t HELPER(pstate_add)(uint32_t pstate, uint64_t a1, uint64_t a2,
return pstate;
}
+
+uint32_t HELPER(pstate_add32)(uint32_t pstate, uint64_t x1, uint64_t x2,
+ uint64_t xr)
+{
+ uint32_t a1 = x1;
+ uint32_t a2 = x2;
+ uint32_t ar = xr;
+
+ int32_t s1 = a1;
+ int32_t s2 = a2;
+ int32_t sr = ar;
+
+ pstate &= ~(PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V);
+
+ if (sr < 0) {
+ pstate |= PSTATE_N;
+ }
+
+ if (!ar) {
+ pstate |= PSTATE_Z;
+ }
+
+ if (ar && (ar < a1)) {
+ pstate |= PSTATE_C;
+ }
+
+ if ((s1 > 0 && s2 > 0 && sr < 0) ||
+ (s1 < 0 && s2 < 0 && sr > 0)) {
+ pstate |= PSTATE_V;
+ }
+
+ return pstate;
+}
+
+uint32_t HELPER(pstate_sub)(uint32_t pstate, uint64_t a1, uint64_t a2,
+ uint64_t ar)
+{
+ int64_t sr = ar;
+ int64_t s1 = a1;
+ int64_t s2 = a2;
+
+ pstate = helper_pstate_add(pstate, a1, a2, ar);
+
+ pstate &= ~(PSTATE_C | PSTATE_V);
+
+ if (a2 <= a1) {
+ pstate |= PSTATE_C;
+ }
+
+ /* XXX check if this is the only special case */
+ if ((!a1 && a2 == 0x8000000000000000ULL) ||
+ (s1 > 0 && s2 < 0 && sr < 0) ||
+ (s1 < 0 && s2 > 0 && sr > 0)) {
+ pstate |= PSTATE_V;
+ }
+
+ return pstate;
+}
+
+uint32_t HELPER(pstate_sub32)(uint32_t pstate, uint64_t x1, uint64_t x2,
+ uint64_t xr)
+{
+ uint32_t a1 = x1;
+ uint32_t a2 = x2;
+ uint32_t ar = xr;
+ int32_t sr = ar;
+ int32_t s1 = a1;
+ int32_t s2 = a2;
+
+ pstate = helper_pstate_add32(pstate, a1, a2, ar);
+
+ pstate &= ~(PSTATE_C | PSTATE_V);
+
+ if (a2 <= a1) {
+ pstate |= PSTATE_C;
+ }
+
+ if ((!a1 && a2 == 0x80000000ULL) ||
+ (s1 > 0 && s2 < 0 && sr < 0) ||
+ (s1 < 0 && s2 > 0 && sr > 0)) {
+ pstate |= PSTATE_V;
+ }
+
+ return pstate;
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 1492b15..4deab64 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -18,3 +18,6 @@
*/
DEF_HELPER_FLAGS_4(pstate_add, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
+DEF_HELPER_FLAGS_4(pstate_add32, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
+DEF_HELPER_FLAGS_4(pstate_sub, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
+DEF_HELPER_FLAGS_4(pstate_sub32, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 2a80715..a0df55c 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -601,6 +601,153 @@ static void handle_orr(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_op2);
}
+static void setflags_add(bool sub_op, bool is_32bit, TCGv_i64 src,
+ TCGv_i64 op2, TCGv_i64 res)
+{
+ if (sub_op) {
+ if (is_32bit) {
+ gen_helper_pstate_sub32(pstate, pstate, src, op2, res);
+ } else {
+ gen_helper_pstate_sub(pstate, pstate, src, op2, res);
+ }
+ } else {
+ if (is_32bit) {
+ gen_helper_pstate_add32(pstate, pstate, src, op2, res);
+ } else {
+ gen_helper_pstate_add(pstate, pstate, src, op2, res);
+ }
+ }
+}
+
+static void reg_extend(TCGv_i64 tcg_offset, int option, int shift, int reg)
+{
+ int extsize = get_bits(option, 0, 2);
+ bool is_signed = get_bits(option, 2, 1);
+
+ if (is_signed) {
+ switch (extsize) {
+ case 0:
+ tcg_gen_ext8s_i64(tcg_offset, cpu_reg(reg));
+ break;
+ case 1:
+ tcg_gen_ext16s_i64(tcg_offset, cpu_reg(reg));
+ break;
+ case 2:
+ tcg_gen_ext32s_i64(tcg_offset, cpu_reg(reg));
+ break;
+ case 3:
+ tcg_gen_mov_i64(tcg_offset, cpu_reg(reg));
+ break;
+ }
+ } else {
+ switch (extsize) {
+ case 0:
+ tcg_gen_ext8u_i64(tcg_offset, cpu_reg(reg));
+ break;
+ case 1:
+ tcg_gen_ext16u_i64(tcg_offset, cpu_reg(reg));
+ break;
+ case 2:
+ tcg_gen_ext32u_i64(tcg_offset, cpu_reg(reg));
+ break;
+ case 3:
+ tcg_gen_mov_i64(tcg_offset, cpu_reg(reg));
+ break;
+ }
+ }
+
+ if (shift) {
+ tcg_gen_shli_i64(tcg_offset, tcg_offset, shift);
+ }
+}
+
+static void handle_add(DisasContext *s, uint32_t insn)
+{
+ int dest = get_reg(insn);
+ int source = get_bits(insn, 5, 5);
+ int shift_amount = get_sbits(insn, 10, 6);
+ int rm = get_bits(insn, 16, 5);
+ bool extend = get_bits(insn, 21, 1);
+ int shift_type = get_bits(insn, 22, 2);
+ bool is_carry = (get_bits(insn, 24, 5) == 0x1a);
+ bool setflags = get_bits(insn, 29, 1);
+ bool sub_op = get_bits(insn, 30, 1);
+ bool is_32bit = !get_bits(insn, 31, 1);
+ TCGv_i64 tcg_op2;
+ TCGv_i64 tcg_src = tcg_temp_new_i64();
+ TCGv_i64 tcg_dst;
+ TCGv_i64 tcg_result = tcg_temp_new_i64();
+
+ if (extend && shift_type) {
+ unallocated_encoding(s);
+ }
+
+ tcg_gen_mov_i64(tcg_src, cpu_reg(source));
+ tcg_dst = cpu_reg(dest);
+ if (extend) {
+ if ((shift_amount & 0x7) > 4) {
+ /* reserved value */
+ unallocated_encoding(s);
+ }
+ if (!setflags) {
+ tcg_gen_mov_i64(tcg_src, cpu_reg_sp(source));
+ tcg_dst = cpu_reg_sp(dest);
+ }
+ } else {
+ if (shift_type == 3) {
+ /* reserved value */
+ unallocated_encoding(s);
+ }
+ if (is_32bit && (shift_amount < 0)) {
+ /* reserved value */
+ unallocated_encoding(s);
+ }
+ }
+
+ if (extend) {
+ tcg_op2 = tcg_temp_new_i64();
+ reg_extend(tcg_op2, shift_amount >> 3, shift_amount & 0x7, rm);
+ } else {
+ tcg_op2 = get_shifti(rm, shift_type, shift_amount, is_32bit);
+ }
+
+ if (is_32bit) {
+ tcg_gen_ext32s_i64(tcg_src, tcg_src);
+ tcg_gen_ext32s_i64(tcg_op2, tcg_op2);
+ }
+
+ if (sub_op) {
+ tcg_gen_sub_i64(tcg_result, tcg_src, tcg_op2);
+ } else {
+ tcg_gen_add_i64(tcg_result, tcg_src, tcg_op2);
+ }
+
+ if (is_carry) {
+ TCGv_i64 tcg_carry = tcg_temp_new_i64();
+ tcg_gen_shri_i64(tcg_carry, pstate, PSTATE_C_SHIFT);
+ tcg_gen_andi_i64(tcg_carry, tcg_carry, 1);
+ tcg_gen_add_i64(tcg_result, tcg_result, tcg_carry);
+ if (sub_op) {
+ tcg_gen_subi_i64(tcg_result, tcg_result, 1);
+ }
+ tcg_temp_free_i64(tcg_carry);
+ }
+
+ if (setflags) {
+ setflags_add(sub_op, is_32bit, tcg_src, tcg_op2, tcg_result);
+ }
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(tcg_dst, tcg_result);
+ } else {
+ tcg_gen_mov_i64(tcg_dst, tcg_result);
+ }
+
+ tcg_temp_free_i64(tcg_src);
+ tcg_temp_free_i64(tcg_op2);
+ tcg_temp_free_i64(tcg_result);
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -636,6 +783,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x0a:
handle_orr(s, insn);
break;
+ case 0x0b:
+ handle_add(s, insn);
+ break;
case 0x0c:
if (get_bits(insn, 29, 1)) {
handle_stp(s, insn);
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 16/60] AArch64: Add emulation for SIMD ld/st multiple
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (14 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 15/60] AArch64: Add add instruction family emulation Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 17/60] AArch64: Add dup GPR->Vec instruction emulation Alexander Graf
` (45 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds support for the SIMD load/store multiple (post-indexed)
category of instructions.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index a0df55c..a864a90 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -748,6 +748,91 @@ static void handle_add(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_result);
}
+/* SIMD load/store multiple (post-indexed) */
+static void handle_simdldstm(DisasContext *s, uint32_t insn, bool is_wback)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int rm = get_bits(insn, 16, 5);
+ int size = get_bits(insn, 10, 2);
+ int opcode = get_bits(insn, 12, 4);
+ bool is_store = !get_bits(insn, 22, 1);
+ bool is_q = get_bits(insn, 30, 1);
+ TCGv_i64 tcg_tmp = tcg_temp_new_i64();
+ TCGv_i64 tcg_addr = tcg_temp_new_i64();
+ int r, e, xs, tt, rpt, selem;
+ int ebytes = 1 << size;
+ int elements = (is_q ? 128 : 64) / (8 << size);
+
+ tcg_gen_mov_i64(tcg_addr, cpu_reg_sp(rn));
+
+ switch (opcode) {
+ case 0x0:
+ rpt = 1;
+ selem = 4;
+ break;
+ case 0x2:
+ rpt = 4;
+ selem = 1;
+ break;
+ case 0x4:
+ rpt = 1;
+ selem = 3;
+ break;
+ case 0x6:
+ rpt = 3;
+ selem = 1;
+ break;
+ case 0x7:
+ rpt = 1;
+ selem = 1;
+ break;
+ case 0x8:
+ rpt = 1;
+ selem = 2;
+ break;
+ case 0xa:
+ rpt = 2;
+ selem = 1;
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (size == 3 && !is_q && selem != 1) {
+ /* reserved */
+ unallocated_encoding(s);
+ }
+
+ /* XXX check SP alignment on Rn */
+
+ for (r = 0; r < rpt; r++) {
+ for (e = 0; e < elements; e++) {
+ tt = (rd + r) % 32;
+ for (xs = 0; xs < selem; xs++) {
+ int freg_offs = offsetof(CPUARMState, vfp.regs[tt * 2]) +
+ (e * ebytes);
+
+ ldst_do_vec_int(s, freg_offs, tcg_addr, size, is_store);
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, ebytes);
+ tt = (tt + 1) % 32;
+ }
+ }
+ }
+
+ if (is_wback) {
+ if (rm == 31) {
+ tcg_gen_mov_i64(cpu_reg_sp(rn), tcg_addr);
+ } else {
+ tcg_gen_add_i64(cpu_reg_sp(rn), cpu_reg(rn), cpu_reg(rm));
+ }
+ }
+
+ tcg_temp_free_i64(tcg_tmp);
+ tcg_temp_free_i64(tcg_addr);
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -789,6 +874,12 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x0c:
if (get_bits(insn, 29, 1)) {
handle_stp(s, insn);
+ } else if (!get_bits(insn, 31, 1) && get_bits(insn, 23, 1) &&
+ !get_bits(insn, 21, 1)) {
+ handle_simdldstm(s, insn, true);
+ } else if (!get_bits(insn, 31, 1) && !get_bits(insn, 29, 1) &&
+ !get_bits(insn, 23, 1) && !get_bits(insn, 16, 6)) {
+ handle_simdldstm(s, insn, false);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 17/60] AArch64: Add dup GPR->Vec instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (15 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 16/60] AArch64: Add emulation for SIMD ld/st multiple Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 18:55 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 18/60] AArch64: Add umov " Alexander Graf
` (44 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the DUP instruction flavor that copies
GPR contents into vector register parts.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index a864a90..ba19e10 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -833,6 +833,53 @@ static void handle_simdldstm(DisasContext *s, uint32_t insn, bool is_wback)
tcg_temp_free_i64(tcg_addr);
}
+static void handle_dupg(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int imm5 = get_bits(insn, 16, 6);
+ int q = get_bits(insn, 30, 1);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ int size;
+ int i;
+
+ for (size = 0; !(imm5 & (1 << size)); size++) {
+ if (size > 3) {
+ unallocated_encoding(s);
+ return;
+ }
+ }
+
+ if ((size == 3) && !q) {
+ /* XXX reserved value */
+ unallocated_encoding(s);
+ }
+
+ clear_fpreg(rd);
+ switch (size) {
+ case 0:
+ for (i = 0; i < (q ? 16 : 8); i++) {
+ tcg_gen_st8_i64(cpu_reg(rn), cpu_env, freg_offs_d + i);
+ }
+ break;
+ case 1:
+ for (i = 0; i < (q ? 16 : 8); i+=2) {
+ tcg_gen_st16_i64(cpu_reg(rn), cpu_env, freg_offs_d + i);
+ }
+ break;
+ case 2:
+ for (i = 0; i < (q ? 16 : 8); i+=4) {
+ tcg_gen_st32_i64(cpu_reg(rn), cpu_env, freg_offs_d + i);
+ }
+ break;
+ case 3:
+ for (i = 0; i < (q ? 16 : 8); i+=8) {
+ tcg_gen_st_i64(cpu_reg(rn), cpu_env, freg_offs_d + i);
+ }
+ break;
+ }
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -891,6 +938,14 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
unallocated_encoding(s);
}
break;
+ case 0x0e:
+ if (!get_bits(insn, 31, 1) && !get_bits(insn, 29, 1) &&
+ (get_bits(insn, 10, 6) == 0x3)) {
+ handle_dupg(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 18/60] AArch64: Add umov instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (16 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 17/60] AArch64: Add dup GPR->Vec instruction emulation Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 18:56 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 19/60] AArch64: Add ins GPR->Vec " Alexander Graf
` (43 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the umov instruction that copies vector
register contents into GPRs.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index ba19e10..e29d5a8 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -880,6 +880,48 @@ static void handle_dupg(DisasContext *s, uint32_t insn)
}
}
+static void handle_umov(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int imm5 = get_bits(insn, 16, 6);
+ int q = get_bits(insn, 30, 1);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int size;
+ int idx;
+
+ for (size = 0; !(imm5 & (1 << size)); size++) {
+ if (size > 3) {
+ unallocated_encoding(s);
+ return;
+ }
+ }
+
+ if ((size == 3) && !q) {
+ /* XXX reserved value */
+ unallocated_encoding(s);
+ }
+
+ switch (size) {
+ case 0:
+ idx = get_bits(imm5, 1, 4) << 0;
+ tcg_gen_ld8u_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
+ break;
+ case 1:
+ idx = get_bits(imm5, 2, 3) << 1;
+ tcg_gen_ld16u_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
+ break;
+ case 2:
+ idx = get_bits(imm5, 3, 2) << 2;
+ tcg_gen_ld32u_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
+ break;
+ case 3:
+ idx = get_bits(imm5, 4, 1) << 3;
+ tcg_gen_ld_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
+ break;
+ }
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -942,6 +984,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
if (!get_bits(insn, 31, 1) && !get_bits(insn, 29, 1) &&
(get_bits(insn, 10, 6) == 0x3)) {
handle_dupg(s, insn);
+ } else if (!get_bits(insn, 31, 1) && !get_bits(insn, 29, 1) &&
+ (get_bits(insn, 10, 6) == 0xf)) {
+ handle_umov(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 19/60] AArch64: Add ins GPR->Vec instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (17 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 18/60] AArch64: Add umov " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 20/60] AArch64: Add SIMD ORR family " Alexander Graf
` (42 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the INS instruction flavor that copies
GPR contents into vector register parts.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index e29d5a8..546ca13 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -922,6 +922,42 @@ static void handle_umov(DisasContext *s, uint32_t insn)
}
}
+static void handle_insg(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int imm5 = get_bits(insn, 16, 6);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ int size;
+ int idx;
+
+ for (size = 0; !(imm5 & (1 << size)); size++) {
+ if (size > 3) {
+ unallocated_encoding(s);
+ return;
+ }
+ }
+
+ switch (size) {
+ case 0:
+ idx = get_bits(imm5, 1, 4) << 0;
+ tcg_gen_st8_i64(cpu_reg(rn), cpu_env, freg_offs_d + idx);
+ break;
+ case 1:
+ idx = get_bits(imm5, 2, 3) << 1;
+ tcg_gen_st16_i64(cpu_reg(rn), cpu_env, freg_offs_d + idx);
+ break;
+ case 2:
+ idx = get_bits(imm5, 3, 2) << 2;
+ tcg_gen_st32_i64(cpu_reg(rn), cpu_env, freg_offs_d + idx);
+ break;
+ case 3:
+ idx = get_bits(imm5, 4, 1) << 3;
+ tcg_gen_st_i64(cpu_reg(rn), cpu_env, freg_offs_d + idx);
+ break;
+ }
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -987,6 +1023,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
} else if (!get_bits(insn, 31, 1) && !get_bits(insn, 29, 1) &&
(get_bits(insn, 10, 6) == 0xf)) {
handle_umov(s, insn);
+ } else if ((get_bits(insn, 29, 3) == 2) && !get_bits(insn, 21, 3) &&
+ (get_bits(insn, 10, 6) == 0x7)) {
+ handle_insg(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 20/60] AArch64: Add SIMD ORR family instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (18 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 19/60] AArch64: Add ins GPR->Vec " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 19:21 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 21/60] AArch64: Convert SIMD load/store to common function Alexander Graf
` (41 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for SIMD ORR instructions (and, or, xor).
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 546ca13..f054488 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -958,6 +958,68 @@ static void handle_insg(DisasContext *s, uint32_t insn)
}
}
+/* SIMD ORR */
+static void handle_simdorr(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int rm = get_bits(insn, 16, 5);
+ int size = get_bits(insn, 22, 2);
+ int opcode = get_bits(insn, 11, 5);
+ bool is_q = get_bits(insn, 30, 1);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int freg_offs_m = offsetof(CPUARMState, vfp.regs[rm * 2]);
+ TCGv_i64 tcg_op1_1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op1_2 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op2_1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op2_2 = tcg_temp_new_i64();
+ TCGv_i64 tcg_res_1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_res_2 = tcg_temp_new_i64();
+
+ tcg_gen_ld_i64(tcg_op1_1, cpu_env, freg_offs_n);
+ tcg_gen_ld_i64(tcg_op2_1, cpu_env, freg_offs_m);
+ if (is_q) {
+ tcg_gen_ld_i64(tcg_op1_2, cpu_env, freg_offs_n + sizeof(float64));
+ tcg_gen_ld_i64(tcg_op2_2, cpu_env, freg_offs_m + sizeof(float64));
+ } else {
+ tcg_gen_movi_i64(tcg_op1_2, 0);
+ tcg_gen_movi_i64(tcg_op2_2, 0);
+ }
+
+ switch (opcode) {
+ case 0x3: /* ORR */
+ if (size & 1) {
+ tcg_gen_not_i64(tcg_op2_1, tcg_op2_1);
+ tcg_gen_not_i64(tcg_op2_2, tcg_op2_2);
+ }
+ if (size & 2) {
+ tcg_gen_or_i64(tcg_res_1, tcg_op1_1, tcg_op2_1);
+ tcg_gen_or_i64(tcg_res_2, tcg_op1_2, tcg_op2_2);
+ } else {
+ tcg_gen_and_i64(tcg_res_1, tcg_op1_1, tcg_op2_1);
+ tcg_gen_and_i64(tcg_res_2, tcg_op1_2, tcg_op2_2);
+ }
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ tcg_gen_st_i64(tcg_res_1, cpu_env, freg_offs_d);
+ if (!is_q) {
+ tcg_gen_movi_i64(tcg_res_2, 0);
+ }
+ tcg_gen_st_i64(tcg_res_2, cpu_env, freg_offs_d + sizeof(float64));
+
+ tcg_temp_free_i64(tcg_op1_1);
+ tcg_temp_free_i64(tcg_op1_2);
+ tcg_temp_free_i64(tcg_op2_1);
+ tcg_temp_free_i64(tcg_op2_2);
+ tcg_temp_free_i64(tcg_res_1);
+ tcg_temp_free_i64(tcg_res_2);
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -1026,6 +1088,10 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
} else if ((get_bits(insn, 29, 3) == 2) && !get_bits(insn, 21, 3) &&
(get_bits(insn, 10, 6) == 0x7)) {
handle_insg(s, insn);
+ } else if (!get_bits(insn, 31, 1) && !get_bits(insn, 29, 1) &&
+ get_bits(insn, 21, 1) && get_bits(insn, 10, 1) &&
+ (get_bits(insn, 11, 5) == 0x3)) {
+ handle_simdorr(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 21/60] AArch64: Convert SIMD load/store to common function
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (19 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 20/60] AArch64: Add SIMD ORR family " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 22/60] AArch64: Add AdvSIMD scalar three same group handling Alexander Graf
` (40 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
We currently dulplicate load/store logic for simd operations throughout
the place. Fortunately they follow a pretty clear pattern, so let's
create common code to handle them.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 99 ++++++++++++++++++++--------------------------
1 file changed, 42 insertions(+), 57 deletions(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index f054488..ad20892 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -833,6 +833,42 @@ static void handle_simdldstm(DisasContext *s, uint32_t insn, bool is_wback)
tcg_temp_free_i64(tcg_addr);
}
+static void simd_ld(TCGv_i64 tcg_reg, int freg_offs, int size)
+{
+ switch (size) {
+ case 0:
+ tcg_gen_ld8u_i64(tcg_reg, cpu_env, freg_offs);
+ break;
+ case 1:
+ tcg_gen_ld16u_i64(tcg_reg, cpu_env, freg_offs);
+ break;
+ case 2:
+ tcg_gen_ld32u_i64(tcg_reg, cpu_env, freg_offs);
+ break;
+ case 3:
+ tcg_gen_ld_i64(tcg_reg, cpu_env, freg_offs);
+ break;
+ }
+}
+
+static void simd_st(TCGv_i64 tcg_reg, int freg_offs, int size)
+{
+ switch (size) {
+ case 0:
+ tcg_gen_st8_i64(tcg_reg, cpu_env, freg_offs);
+ break;
+ case 1:
+ tcg_gen_st16_i64(tcg_reg, cpu_env, freg_offs);
+ break;
+ case 2:
+ tcg_gen_st32_i64(tcg_reg, cpu_env, freg_offs);
+ break;
+ case 3:
+ tcg_gen_st_i64(tcg_reg, cpu_env, freg_offs);
+ break;
+ }
+}
+
static void handle_dupg(DisasContext *s, uint32_t insn)
{
int rd = get_bits(insn, 0, 5);
@@ -856,27 +892,8 @@ static void handle_dupg(DisasContext *s, uint32_t insn)
}
clear_fpreg(rd);
- switch (size) {
- case 0:
- for (i = 0; i < (q ? 16 : 8); i++) {
- tcg_gen_st8_i64(cpu_reg(rn), cpu_env, freg_offs_d + i);
- }
- break;
- case 1:
- for (i = 0; i < (q ? 16 : 8); i+=2) {
- tcg_gen_st16_i64(cpu_reg(rn), cpu_env, freg_offs_d + i);
- }
- break;
- case 2:
- for (i = 0; i < (q ? 16 : 8); i+=4) {
- tcg_gen_st32_i64(cpu_reg(rn), cpu_env, freg_offs_d + i);
- }
- break;
- case 3:
- for (i = 0; i < (q ? 16 : 8); i+=8) {
- tcg_gen_st_i64(cpu_reg(rn), cpu_env, freg_offs_d + i);
- }
- break;
+ for (i = 0; i < (q ? 16 : 8); i += (1 << size)) {
+ simd_st(cpu_reg(rn), freg_offs_d + i, size);
}
}
@@ -902,24 +919,8 @@ static void handle_umov(DisasContext *s, uint32_t insn)
unallocated_encoding(s);
}
- switch (size) {
- case 0:
- idx = get_bits(imm5, 1, 4) << 0;
- tcg_gen_ld8u_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
- break;
- case 1:
- idx = get_bits(imm5, 2, 3) << 1;
- tcg_gen_ld16u_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
- break;
- case 2:
- idx = get_bits(imm5, 3, 2) << 2;
- tcg_gen_ld32u_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
- break;
- case 3:
- idx = get_bits(imm5, 4, 1) << 3;
- tcg_gen_ld_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
- break;
- }
+ idx = get_bits(imm5, 1 + size, 4 - size) << size;
+ simd_ld(cpu_reg(rd), freg_offs_n + idx, size);
}
static void handle_insg(DisasContext *s, uint32_t insn)
@@ -938,24 +939,8 @@ static void handle_insg(DisasContext *s, uint32_t insn)
}
}
- switch (size) {
- case 0:
- idx = get_bits(imm5, 1, 4) << 0;
- tcg_gen_st8_i64(cpu_reg(rn), cpu_env, freg_offs_d + idx);
- break;
- case 1:
- idx = get_bits(imm5, 2, 3) << 1;
- tcg_gen_st16_i64(cpu_reg(rn), cpu_env, freg_offs_d + idx);
- break;
- case 2:
- idx = get_bits(imm5, 3, 2) << 2;
- tcg_gen_st32_i64(cpu_reg(rn), cpu_env, freg_offs_d + idx);
- break;
- case 3:
- idx = get_bits(imm5, 4, 1) << 3;
- tcg_gen_st_i64(cpu_reg(rn), cpu_env, freg_offs_d + idx);
- break;
- }
+ idx = get_bits(imm5, 1 + size, 4 - size) << size;
+ simd_st(cpu_reg(rn), freg_offs_d + idx, size);
}
/* SIMD ORR */
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 22/60] AArch64: Add AdvSIMD scalar three same group handling
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (20 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 21/60] AArch64: Convert SIMD load/store to common function Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 19:24 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 23/60] AArch64: Add AdvSIMD modified immediate " Alexander Graf
` (39 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds decoding for the AdvSIMD scalar three same group with U == 0.
While at it, it also adds support for the ADD / SUB operations in this group.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index ad20892..9d6edf4 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1005,6 +1005,56 @@ static void handle_simdorr(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_res_2);
}
+/* AdvSIMD scalar three same (U=0) */
+static void handle_simd3su0(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int opcode = get_bits(insn, 11, 5);
+ int rm = get_bits(insn, 16, 5);
+ int size = get_bits(insn, 22, 2);
+ bool is_sub = get_bits(insn, 29, 1);
+ bool is_q = get_bits(insn, 30, 1);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int freg_offs_m = offsetof(CPUARMState, vfp.regs[rm * 2]);
+ TCGv_i64 tcg_op1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op2 = tcg_temp_new_i64();
+ TCGv_i64 tcg_res = tcg_temp_new_i64();
+ int ebytes = (1 << size);
+ int i;
+
+ for (i = 0; i < 16; i += ebytes) {
+ simd_ld(tcg_op1, freg_offs_n + i, size);
+ simd_ld(tcg_op2, freg_offs_m + i, size);
+
+ switch (opcode) {
+ case 0x10: /* ADD / SUB */
+ if (is_sub) {
+ tcg_gen_sub_i64(tcg_res, tcg_op1, tcg_op2);
+ } else {
+ tcg_gen_add_i64(tcg_res, tcg_op1, tcg_op2);
+ }
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ simd_st(tcg_res, freg_offs_d + i, size);
+ }
+
+ if (!is_q) {
+ TCGv_i64 tcg_zero = tcg_const_i64(0);
+ simd_st(tcg_zero, freg_offs_d + sizeof(float64), 3);
+ tcg_temp_free_i64(tcg_zero);
+ }
+
+ tcg_temp_free_i64(tcg_op1);
+ tcg_temp_free_i64(tcg_op2);
+ tcg_temp_free_i64(tcg_res);
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -1077,6 +1127,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
get_bits(insn, 21, 1) && get_bits(insn, 10, 1) &&
(get_bits(insn, 11, 5) == 0x3)) {
handle_simdorr(s, insn);
+ } else if (!get_bits(insn, 31, 1) && get_bits(insn, 21, 1) &&
+ get_bits(insn, 10, 1)) {
+ handle_simd3su0(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 23/60] AArch64: Add AdvSIMD modified immediate group handling
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (21 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 22/60] AArch64: Add AdvSIMD scalar three same group handling Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-11-19 20:23 ` Janne Grunau
2013-09-27 0:48 ` [Qemu-devel] [PATCH 24/60] AArch64: Add SIMD ushll instruction emulation Alexander Graf
` (38 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds support for the AdvSIMD modified immediate group with
all its suboperations (movi, orr, fmov, mvni, bic).
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 129 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 9d6edf4..50561cf 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1055,6 +1055,127 @@ static void handle_simd3su0(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_res);
}
+/* AdvSIMD modified immediate */
+static void handle_simdmodi(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int cmode = get_bits(insn, 12, 4);
+ uint64_t abcdefgh = get_bits(insn, 5, 5) | (get_bits(insn, 16, 3) << 5);
+ bool is_neg = get_bits(insn, 29, 1);
+ bool is_q = get_bits(insn, 30, 1);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ uint64_t imm = 0;
+ int shift, i;
+ TCGv_i64 tcg_op1_1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op1_2 = tcg_temp_new_i64();
+ TCGv_i64 tcg_res_1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_res_2 = tcg_temp_new_i64();
+ TCGv_i64 tcg_imm;
+
+ switch ((cmode >> 1) & 0x7) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ shift = ((cmode >> 1) & 0x7) * 8;
+ imm = (abcdefgh << shift) | (abcdefgh << (32 + shift));
+ break;
+ case 4:
+ case 5:
+ shift = ((cmode >> 1) & 0x1) * 8;
+ imm = (abcdefgh << shift) |
+ (abcdefgh << (16 + shift)) |
+ (abcdefgh << (32 + shift)) |
+ (abcdefgh << (48 + shift));
+ break;
+ case 6:
+ if (cmode & 1) {
+ imm = (abcdefgh << 8) |
+ (abcdefgh << 48) |
+ 0x000000ff000000ffULL;
+ } else {
+ imm = (abcdefgh << 16) |
+ (abcdefgh << 56) |
+ 0x0000ffff0000ffffULL;
+ }
+ break;
+ case 7:
+ if (!(cmode & 1) && !is_neg) {
+ imm = abcdefgh |
+ (abcdefgh << 8) |
+ (abcdefgh << 16) |
+ (abcdefgh << 24) |
+ (abcdefgh << 32) |
+ (abcdefgh << 40) |
+ (abcdefgh << 48) |
+ (abcdefgh << 56);
+ } else if (!(cmode & 1) && is_neg) {
+ imm = 0;
+ for (i = 0; i < 8; i++) {
+ if ((abcdefgh) & (1 << (7 - i))) {
+ imm |= 0xffULL << (i * 8);
+ }
+ }
+ } else if (cmode & 1) {
+ shift = is_neg ? 48 : 19;
+ imm = (abcdefgh & 0x1f) << 19;
+ if (abcdefgh & 0x80) {
+ imm |= 0x80000000;
+ }
+ if (!(abcdefgh & 0x40)) {
+ imm |= 0x40000000;
+ }
+ if (abcdefgh & 0x20) {
+ imm |= is_neg ? 0x3fc00000 : 0x3e000000;
+ }
+ imm |= (imm << 32);
+ }
+ shift = ((cmode >> 1) & 0x1) * 8;
+ break;
+ }
+
+ if (is_neg) {
+ imm = ~imm;
+ }
+ tcg_imm = tcg_const_i64(imm);
+
+ tcg_gen_ld_i64(tcg_op1_1, cpu_env, freg_offs_d);
+ if (is_q) {
+ tcg_gen_ld_i64(tcg_op1_2, cpu_env, freg_offs_d + sizeof(float64));
+ } else {
+ tcg_gen_movi_i64(tcg_op1_2, 0);
+ }
+
+ if ((cmode == 0xf) && is_neg && !is_q) {
+ unallocated_encoding(s);
+ return;
+ } else if ((cmode & 1) && is_neg) {
+ /* AND (BIC) */
+ tcg_gen_and_i64(tcg_res_1, tcg_op1_1, tcg_imm);
+ tcg_gen_and_i64(tcg_res_2, tcg_op1_2, tcg_imm);
+ } else if ((cmode & 1) && !is_neg) {
+ /* ORR */
+ tcg_gen_or_i64(tcg_res_1, tcg_op1_1, tcg_imm);
+ tcg_gen_or_i64(tcg_res_2, tcg_op1_2, tcg_imm);
+ } else {
+ /* MOVI */
+ tcg_gen_mov_i64(tcg_res_1, tcg_imm);
+ tcg_gen_mov_i64(tcg_res_2, tcg_imm);
+ }
+
+ tcg_gen_st_i64(tcg_res_1, cpu_env, freg_offs_d);
+ if (!is_q) {
+ tcg_gen_movi_i64(tcg_res_2, 0);
+ }
+ tcg_gen_st_i64(tcg_res_2, cpu_env, freg_offs_d + sizeof(float64));
+
+ tcg_temp_free_i64(tcg_op1_1);
+ tcg_temp_free_i64(tcg_op1_2);
+ tcg_temp_free_i64(tcg_res_1);
+ tcg_temp_free_i64(tcg_res_2);
+ tcg_temp_free_i64(tcg_imm);
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -1134,6 +1255,14 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
unallocated_encoding(s);
}
break;
+ case 0x0f:
+ if (!get_bits(insn, 31, 1) && !get_bits(insn, 19, 5) &&
+ (get_bits(insn, 10, 2) == 1)) {
+ handle_simdmodi(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 24/60] AArch64: Add SIMD ushll instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (22 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 23/60] AArch64: Add AdvSIMD modified immediate " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 19:29 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 25/60] AArch64: Add SIMD shl " Alexander Graf
` (37 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for the ushll instruction.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 50561cf..6a3b34e 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1176,6 +1176,55 @@ static void handle_simdmodi(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_imm);
}
+/* SIMD shift ushll */
+static void handle_ushll(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int immh = get_bits(insn, 19, 4);
+ bool is_q = get_bits(insn, 30, 1);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ TCGv_i64 tcg_tmp = tcg_temp_new_i64();
+ int i;
+ int ebytes;
+ int size;
+ int shift = get_bits(insn, 16, 7);
+
+ if (is_q) {
+ freg_offs_n += sizeof(float64);
+ }
+
+ for (size = 0; !(immh & (1 << size)); size++) {
+ if (size > 3) {
+ unallocated_encoding(s);
+ return;
+ }
+ }
+
+ ebytes = 1 << size;
+ shift -= (8 << size);
+
+ if (!immh) {
+ /* XXX see asimdimm */
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (immh & 0x8) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ for (i = 0; i < (8 / ebytes); i++) {
+ simd_ld(tcg_tmp, freg_offs_n + (i * ebytes), size);
+ tcg_gen_shli_i64(tcg_tmp, tcg_tmp, shift);
+ simd_st(tcg_tmp, freg_offs_d + (i * ebytes * 2), size + 1);
+ }
+
+ tcg_temp_free_i64(tcg_tmp);
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -1259,6 +1308,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
if (!get_bits(insn, 31, 1) && !get_bits(insn, 19, 5) &&
(get_bits(insn, 10, 2) == 1)) {
handle_simdmodi(s, insn);
+ } else if (!get_bits(insn, 31, 1) && !get_bits(insn, 23, 1) &&
+ (get_bits(insn, 10, 6) == 0x29)) {
+ handle_ushll(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 25/60] AArch64: Add SIMD shl instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (23 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 24/60] AArch64: Add SIMD ushll instruction emulation Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 26/60] AArch64: Add ADR " Alexander Graf
` (36 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for the SIMD shl instruction. It belongs
to the same instruction group as ushll and can probably be handled in a shared
function with that one eventually.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 6a3b34e..bc91324 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1225,6 +1225,53 @@ static void handle_ushll(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_tmp);
}
+/* SIMD shift shl */
+static void handle_simdshl(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int immh = get_bits(insn, 19, 4);
+ bool is_q = get_bits(insn, 30, 1);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ TCGv_i64 tcg_tmp = tcg_temp_new_i64();
+ int i;
+ int ebytes;
+ int size;
+ int shift = get_bits(insn, 16, 7);
+
+ size = clz32(immh) - (31 - 4);
+
+ if (size > 3) {
+ /* XXX implement 128bit operations */
+ unallocated_encoding(s);
+ return;
+ }
+
+ ebytes = 1 << size;
+ shift -= (8 << size);
+
+ if (!immh) {
+ /* XXX see asimdimm */
+ unallocated_encoding(s);
+ return;
+ }
+
+ for (i = 0; i < (16 / ebytes); i++) {
+ simd_ld(tcg_tmp, freg_offs_n + (i * ebytes), size);
+ tcg_gen_shli_i64(tcg_tmp, tcg_tmp, shift);
+ simd_st(tcg_tmp, freg_offs_d + (i * ebytes), size);
+ }
+
+ if (!is_q) {
+ TCGv_i64 tcg_zero = tcg_const_i64(0);
+ simd_st(tcg_zero, freg_offs_d + sizeof(float64), 3);
+ tcg_temp_free_i64(tcg_zero);
+ }
+
+ tcg_temp_free_i64(tcg_tmp);
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -1311,6 +1358,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
} else if (!get_bits(insn, 31, 1) && !get_bits(insn, 23, 1) &&
(get_bits(insn, 10, 6) == 0x29)) {
handle_ushll(s, insn);
+ } else if (!get_bits(insn, 31, 1) && !get_bits(insn, 23, 1) &&
+ (get_bits(insn, 10, 6) == 0x15)) {
+ handle_simdshl(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 26/60] AArch64: Add ADR instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (24 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 25/60] AArch64: Add SIMD shl " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-11-19 17:17 ` Claudio Fontana
2013-09-27 0:48 ` [Qemu-devel] [PATCH 27/60] AArch64: Add addi " Alexander Graf
` (35 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for the adr instruction.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index bc91324..00eda0f 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -943,6 +943,27 @@ static void handle_insg(DisasContext *s, uint32_t insn)
simd_st(cpu_reg(rn), freg_offs_d + idx, size);
}
+/* PC relative address calculation */
+static void handle_adr(DisasContext *s, uint32_t insn)
+{
+ int reg = get_reg(insn);
+ int is_page = get_bits(insn, 31, 1);
+ uint64_t imm;
+ uint64_t base;
+
+ imm = get_sbits(insn, 5, 19) << 2;
+ imm |= get_bits(insn, 29, 2);
+
+ base = s->pc - 4;
+ if (is_page) {
+ /* ADRP (page based) */
+ base &= ~0xFFFULL;
+ imm <<= 12;
+ }
+
+ tcg_gen_movi_i64(cpu_reg(reg), base + imm);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -1365,6 +1386,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
unallocated_encoding(s);
}
break;
+ case 0x10:
+ handle_adr(s, insn);
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 27/60] AArch64: Add addi instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (25 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 26/60] AArch64: Add ADR " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 28/60] AArch64: Add movi " Alexander Graf
` (34 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for the add immediate instruction.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 00eda0f..c5d0def 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -964,6 +964,53 @@ static void handle_adr(DisasContext *s, uint32_t insn)
tcg_gen_movi_i64(cpu_reg(reg), base + imm);
}
+static void handle_addi(DisasContext *s, uint32_t insn)
+{
+ TCGv_i64 tcg_result = tcg_temp_new_i64();
+ TCGv_i64 tcg_imm;
+ int dest = get_reg(insn);
+ int source = get_bits(insn, 5, 5);
+ uint64_t imm = get_bits(insn, 10, 12);
+ int shift = get_bits(insn, 22, 2);
+ bool setflags = get_bits(insn, 29, 1);
+ bool sub_op = get_bits(insn, 30, 1);
+ bool is_32bit = !get_bits(insn, 31, 1);
+
+ switch (shift) {
+ case 0x0:
+ break;
+ case 0x1:
+ imm <<= 12;
+ break;
+ default:
+ unallocated_encoding(s);
+ }
+
+ tcg_imm = tcg_const_i64(imm);
+
+ if (sub_op) {
+ tcg_gen_subi_i64(tcg_result, cpu_reg_sp(source), imm);
+ } else {
+ tcg_gen_addi_i64(tcg_result, cpu_reg_sp(source), imm);
+ }
+
+ if (setflags) {
+ setflags_add(sub_op, is_32bit, cpu_reg_sp(source), tcg_imm, tcg_result);
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(cpu_reg(dest), tcg_result);
+ } else {
+ tcg_gen_mov_i64(cpu_reg(dest), tcg_result);
+ }
+ } else {
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(cpu_reg_sp(dest), tcg_result);
+ } else {
+ tcg_gen_mov_i64(cpu_reg_sp(dest), tcg_result);
+ }
+ }
+
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -1389,6 +1436,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x10:
handle_adr(s, insn);
break;
+ case 0x11:
+ handle_addi(s, insn);
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 28/60] AArch64: Add movi instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (26 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 27/60] AArch64: Add addi " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 19:38 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 29/60] AArch64: Add orri " Alexander Graf
` (33 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the movi instruction.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index c5d0def..e4f0306 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1011,6 +1011,44 @@ static void handle_addi(DisasContext *s, uint32_t insn)
}
+static void handle_movi(DisasContext *s, uint32_t insn)
+{
+ int reg = get_reg(insn);
+ uint64_t imm = get_bits(insn, 5, 16);
+ int is_32bit = !get_bits(insn, 31, 1);
+ int is_k = get_bits(insn, 29, 1);
+ int is_n = !get_bits(insn, 30, 1);
+ int pos = get_bits(insn, 21, 2) << 4;
+ TCGv_i64 tcg_imm;
+
+ if (get_bits(insn, 23, 1) != 1) {
+ /* reserved */
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (is_k && is_n) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (is_k) {
+ tcg_imm = tcg_const_i64(imm);
+ tcg_gen_deposit_i64(cpu_reg(reg), cpu_reg(reg), tcg_imm, pos, 16);
+ tcg_temp_free_i64(tcg_imm);
+ } else {
+ tcg_gen_movi_i64(cpu_reg(reg), imm << pos);
+ }
+
+ if (is_n) {
+ tcg_gen_not_i64(cpu_reg(reg), cpu_reg(reg));
+ }
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(cpu_reg(reg), cpu_reg(reg));
+ }
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -1439,6 +1477,13 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x11:
handle_addi(s, insn);
break;
+ case 0x12:
+ if (get_bits(insn, 23, 1)) {
+ handle_movi(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 29/60] AArch64: Add orri instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (27 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 28/60] AArch64: Add movi " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 19:42 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 30/60] AArch64: Add extr " Alexander Graf
` (32 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for the orr immediate instruction
family with all its implementations (and, or, xor).
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 96 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 1 deletion(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index e4f0306..63eca24 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1049,6 +1049,100 @@ static void handle_movi(DisasContext *s, uint32_t insn)
}
}
+static uint64_t replicate(uint64_t mask, int esize)
+{
+ int i;
+ uint64_t out_mask = 0;
+ for (i = 0; (i * esize) < 64; i++) {
+ out_mask = out_mask | (mask << (i * esize));
+ }
+ return out_mask;
+}
+
+static uint64_t bitmask(int len)
+{
+ if (len == 64) {
+ return -1;
+ }
+ return (1ULL << len) - 1;
+}
+
+static uint64_t decode_wmask(int immn, int imms, int immr)
+{
+ uint64_t mask;
+ int len = 31 - clz32((immn << 6) | (~imms & 0x3f));
+ int esize = 1 << len;
+ int levels = (esize - 1) & 0x3f;
+ int s = imms & levels;
+ int r = immr & levels;
+
+ mask = bitmask(s + 1);
+ mask = ((mask >> r) | (mask << (esize - r)));
+ mask &= bitmask(esize);
+ mask = replicate(mask, esize);
+
+ return mask;
+}
+
+static void handle_orri(DisasContext *s, uint32_t insn)
+{
+ int is_32bit = !get_bits(insn, 31, 1);
+ int is_n = get_bits(insn, 22, 1);
+ int opc = get_bits(insn, 29, 2);
+ int dest = get_reg(insn);
+ int source = get_bits(insn, 5, 5);
+ int imms = get_bits(insn, 10, 6);
+ int immr = get_bits(insn, 16, 6);
+ TCGv_i64 tcg_dst;
+ TCGv_i64 tcg_op2;
+ bool setflags = false;
+ uint64_t wmask;
+
+ if (is_32bit && is_n) {
+ /* reserved */
+ unallocated_encoding(s);
+ }
+
+ if (opc == 0x3) {
+ setflags = true;
+ }
+
+ if (setflags) {
+ tcg_dst = cpu_reg(dest);
+ } else {
+ tcg_dst = cpu_reg_sp(dest);
+ }
+
+ wmask = decode_wmask(is_n, imms, immr);
+ if (is_32bit) {
+ wmask = (uint32_t)wmask;
+ }
+ tcg_op2 = tcg_const_i64(wmask);
+
+ switch (opc) {
+ case 0x3:
+ case 0x0:
+ tcg_gen_and_i64(tcg_dst, cpu_reg(source), tcg_op2);
+ break;
+ case 0x1:
+ tcg_gen_or_i64(tcg_dst, cpu_reg(source), tcg_op2);
+ break;
+ case 0x2:
+ tcg_gen_xor_i64(tcg_dst, cpu_reg(source), tcg_op2);
+ break;
+ }
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(tcg_dst, tcg_dst);
+ }
+
+ if (setflags) {
+ gen_helper_pstate_add(pstate, pstate, tcg_dst, cpu_reg(31), tcg_dst);
+ }
+
+ tcg_temp_free_i64(tcg_op2);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -1481,7 +1575,7 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
if (get_bits(insn, 23, 1)) {
handle_movi(s, insn);
} else {
- unallocated_encoding(s);
+ handle_orri(s, insn);
}
break;
default:
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 30/60] AArch64: Add extr instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (28 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 29/60] AArch64: Add orri " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 19:45 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 31/60] AArch64: Add bfm family " Alexander Graf
` (31 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for the extr instruction.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 63eca24..a314af0 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1143,6 +1143,33 @@ static void handle_orri(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_op2);
}
+static void handle_extr(DisasContext *s, uint32_t insn)
+{
+ int rd = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int imms = get_bits(insn, 10, 6);
+ int rm = get_bits(insn, 16, 5);
+ bool is_32bit = !get_bits(insn, 31, 1);
+ int bitsize = is_32bit ? 32 : 64;
+ TCGv_i64 tcg_res = tcg_temp_new_i64();
+ TCGv_i64 tcg_tmp = tcg_temp_new_i64();
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(tcg_tmp, cpu_reg(rm));
+ } else {
+ tcg_gen_mov_i64(tcg_tmp, cpu_reg(rm));
+ }
+ tcg_gen_shri_i64(tcg_res, cpu_reg(rm), imms);
+ tcg_gen_shli_i64(tcg_tmp, cpu_reg(rn), bitsize - imms);
+ tcg_gen_or_i64(cpu_reg(rd), tcg_tmp, tcg_res);
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(cpu_reg(rd), cpu_reg(rd));
+ }
+
+ tcg_temp_free_i64(tcg_tmp);
+ tcg_temp_free_i64(tcg_res);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -1578,6 +1605,14 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_orri(s, insn);
}
break;
+ case 0x13:
+ if (get_bits(insn, 23, 1) && !get_bits(insn, 21, 1) &&
+ !get_bits(insn, 29, 2)) {
+ handle_extr(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 31/60] AArch64: Add bfm family instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (29 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 30/60] AArch64: Add extr " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 20:01 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 32/60] AArch64: Add svc " Alexander Graf
` (30 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for BFM and friends (SBFM, UBFM).
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 9 +++++
target-arm/helper-a64.h | 1 +
target-arm/translate-a64.c | 86 +++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 95 insertions(+), 1 deletion(-)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 2400b6e..bc575a2 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -137,3 +137,12 @@ uint32_t HELPER(pstate_sub32)(uint32_t pstate, uint64_t x1, uint64_t x2,
return pstate;
}
+
+uint64_t HELPER(sign_extend)(uint64_t x, uint64_t is_signed, uint64_t mask)
+{
+ if (x & is_signed) {
+ x |= mask;
+ }
+
+ return x;
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 4deab64..7c5cdc6 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -21,3 +21,4 @@ DEF_HELPER_FLAGS_4(pstate_add, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
DEF_HELPER_FLAGS_4(pstate_add32, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
DEF_HELPER_FLAGS_4(pstate_sub, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
DEF_HELPER_FLAGS_4(pstate_sub32, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
+DEF_HELPER_FLAGS_3(sign_extend, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index a314af0..583a68f 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1170,6 +1170,90 @@ static void handle_extr(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_res);
}
+static void handle_bfm(DisasContext *s, uint32_t insn)
+{
+ bool is_32bit = !get_bits(insn, 31, 1);
+ int opc = get_bits(insn, 29, 2);
+ int dest = get_reg(insn);
+ int source = get_bits(insn, 5, 5);
+ int is_n = get_bits(insn, 22, 1);
+ int imms = get_bits(insn, 10, 6);
+ int immr = get_bits(insn, 16, 6);
+ TCGv_i64 tcg_newmask;
+ uint64_t mask, tmask, topmask;
+ uint64_t signbit = 1;
+ int bitsize = is_32bit ? 32 : 64;
+
+ if (!is_32bit && !is_n) {
+ /* reserved */
+ unallocated_encoding(s);
+ }
+
+ if (is_32bit && (is_n || (immr & (1 << 5)) || imms & (1 << 5))) {
+ /* reserved */
+ unallocated_encoding(s);
+ }
+
+ tcg_newmask = tcg_temp_new_i64();
+
+ if (imms == 0x3f) {
+ tmask = mask = ~0ULL;
+ } else {
+ tmask = mask = ((1ULL << (imms + 1)) - 1);
+ }
+
+ tcg_gen_andi_i64(tcg_newmask, cpu_reg(source), mask);
+ if (imms < immr) {
+ tcg_gen_shli_i64(tcg_newmask, tcg_newmask, bitsize - immr);
+ tmask <<= bitsize - immr;
+ signbit <<= bitsize + imms - immr;
+ if (signbit == 0x8000000000000000ULL) {
+ /* Can't pad anymore - highest bit is already set */
+ topmask = 0;
+ } else {
+ topmask = ~((1ULL << (bitsize + imms - immr + 1)) - 1);
+ }
+ } else {
+ tcg_gen_shri_i64(tcg_newmask, tcg_newmask, immr);
+ tmask >>= immr;
+ signbit <<= imms - immr;
+ topmask = ~tmask;
+ }
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(tcg_newmask, tcg_newmask);
+ }
+
+ switch (opc) {
+ case 0: { /* SBFM */
+ TCGv_i64 tcg_mask = tcg_const_i64(topmask);
+ TCGv_i64 tcg_signbit = tcg_const_i64(signbit);
+ gen_helper_sign_extend(cpu_reg(dest), tcg_newmask, tcg_signbit,
+ tcg_mask);
+ tcg_temp_free_i64(tcg_mask);
+ tcg_temp_free_i64(tcg_signbit);
+ break;
+ }
+ case 1: /* BFM */
+ /* replace the field inside dest */
+ tcg_gen_andi_i64(cpu_reg(dest), cpu_reg(dest), ~tmask);
+ tcg_gen_or_i64(cpu_reg(dest), cpu_reg(dest), tcg_newmask);
+ break;
+ case 2: /* UBFM */
+ tcg_gen_mov_i64(cpu_reg(dest), tcg_newmask);
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(cpu_reg(dest), cpu_reg(dest));
+ }
+
+ tcg_temp_free_i64(tcg_newmask);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -1610,7 +1694,7 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
!get_bits(insn, 29, 2)) {
handle_extr(s, insn);
} else {
- unallocated_encoding(s);
+ handle_bfm(s, insn);
}
break;
default:
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 32/60] AArch64: Add svc instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (30 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 31/60] AArch64: Add bfm family " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 33/60] AArch64: Add bc " Alexander Graf
` (29 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the syscall (svc) instruction.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 13 +++++++++++++
target-arm/translate.c | 5 -----
target-arm/translate.h | 5 +++++
3 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 583a68f..fdcf876 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1583,6 +1583,12 @@ static void handle_simdshl(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_tmp);
}
+static void handle_svc(DisasContext *s, uint32_t insn)
+{
+ gen_a64_set_pc_im(s->pc);
+ s->is_jmp = DISAS_SWI;
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -1697,6 +1703,13 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_bfm(s, insn);
}
break;
+ case 0x14:
+ if (get_bits(insn, 29, 3) == 0x6 && !get_bits(insn, 2, 3)) {
+ handle_svc(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index ef284da..8d75f33 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -55,11 +55,6 @@ static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
#define IS_USER(s) (s->user)
#endif
-/* These instructions trap after executing, so defer them until after the
- conditional execution state has been updated. */
-#define DISAS_WFI 4
-#define DISAS_SWI 5
-
TCGv_ptr cpu_env;
/* We reuse the same 64-bit temporaries for efficiency. */
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
diff --git a/target-arm/translate.h b/target-arm/translate.h
index 67c7760..bc21741 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -1,6 +1,11 @@
#ifndef TARGET_ARM_TRANSLATE_H
#define TARGET_ARM_TRANSLATE_H
+/* These instructions trap after executing, so defer them until after the
+ conditional execution state has been updated. */
+#define DISAS_WFI 4
+#define DISAS_SWI 5
+
/* internal defines */
typedef struct DisasContext {
target_ulong pc;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 33/60] AArch64: Add bc instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (31 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 32/60] AArch64: Add svc " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 34/60] AArch64: Add b.cond " Alexander Graf
` (28 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for compare and branch instructions (cbz, cbnz)
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index fdcf876..229b467 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -233,6 +233,41 @@ static void handle_br(DisasContext *s, uint32_t insn)
s->is_jmp = DISAS_JUMP;
}
+static void handle_cb(DisasContext *s, uint32_t insn)
+{
+ uint64_t addr = s->pc - 4 + (get_sbits(insn, 5, 19) << 2);
+ bool is_zero = !get_bits(insn, 24, 1);
+ bool is_32bit = !get_bits(insn, 31, 1);
+ int dest = get_reg(insn);
+ int no_match;
+ TCGv_i64 tcg_cmp, tcg_zero;
+
+ tcg_cmp = tcg_temp_new_i64();
+ tcg_zero = tcg_const_i64(0);
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(tcg_cmp, cpu_reg(dest));
+ } else {
+ tcg_gen_mov_i64(tcg_cmp, cpu_reg(dest));
+ }
+
+ no_match = gen_new_label();
+ if (is_zero) {
+ tcg_gen_brcond_i64(TCG_COND_NE, tcg_cmp, tcg_zero, no_match);
+ } else {
+ tcg_gen_brcond_i64(TCG_COND_EQ, tcg_cmp, tcg_zero, no_match);
+ }
+ gen_goto_tb(s, 0, addr);
+
+ gen_set_label(no_match);
+ gen_goto_tb(s, 1, s->pc);
+
+ s->is_jmp = DISAS_TB_JUMP;
+
+ tcg_temp_free_i64(tcg_cmp);
+ tcg_temp_free_i64(tcg_zero);
+}
+
static void ldst_do_vec_int(DisasContext *s, int freg_offs, TCGv_i64 tcg_addr,
int size, bool is_store)
{
@@ -1706,6 +1741,15 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x14:
if (get_bits(insn, 29, 3) == 0x6 && !get_bits(insn, 2, 3)) {
handle_svc(s, insn);
+ } else if (get_bits(insn, 29, 2) == 0x1) {
+ handle_cb(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
+ case 0x15:
+ if (get_bits(insn, 29, 2) == 0x1) {
+ handle_cb(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 34/60] AArch64: Add b.cond instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (32 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 33/60] AArch64: Add bc " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 35/60] AArch64: Add mrs " Alexander Graf
` (27 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the conditional branch (b.cond) instruction.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 41 +++++++++++++++++++++++++++++++++++++++++
target-arm/helper-a64.h | 1 +
target-arm/translate-a64.c | 28 ++++++++++++++++++++++++++++
3 files changed, 70 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index bc575a2..9aaf181 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -146,3 +146,44 @@ uint64_t HELPER(sign_extend)(uint64_t x, uint64_t is_signed, uint64_t mask)
return x;
}
+
+uint32_t HELPER(cond)(uint32_t pstate, uint32_t cond)
+{
+ uint32_t r;
+
+ switch (cond >> 1) {
+ case 0:
+ r = pstate & PSTATE_Z;
+ break;
+ case 1:
+ r = pstate & PSTATE_C;
+ break;
+ case 2:
+ r = pstate & PSTATE_N;
+ break;
+ case 3:
+ r = pstate & PSTATE_V;
+ break;
+ case 4:
+ r = (pstate & PSTATE_C) && !(pstate & PSTATE_Z);
+ break;
+ case 5:
+ r = (((pstate & PSTATE_N) ? 1 : 0) == ((pstate & PSTATE_V) ? 1 : 0));
+ break;
+ case 6:
+ r = (((pstate & PSTATE_N) ? 1 : 0) == ((pstate & PSTATE_V) ? 1 : 0))
+ && !(pstate & PSTATE_Z);
+ break;
+ case 7:
+ default:
+ /* ALWAYS */
+ r = 1;
+ break;
+ }
+
+ if ((cond & 1) && (cond != 0xf)) {
+ r = !r;
+ }
+
+ return !!r;
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 7c5cdc6..99f4be7 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -22,3 +22,4 @@ DEF_HELPER_FLAGS_4(pstate_add32, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
DEF_HELPER_FLAGS_4(pstate_sub, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
DEF_HELPER_FLAGS_4(pstate_sub32, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
DEF_HELPER_FLAGS_3(sign_extend, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
+DEF_HELPER_FLAGS_2(cond, TCG_CALL_NO_RWG_SE, i32, i32, i32)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 229b467..d5cc199 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -268,6 +268,32 @@ static void handle_cb(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_zero);
}
+static void handle_condb(DisasContext *s, uint32_t insn)
+{
+ uint64_t addr = s->pc - 4 + (get_sbits(insn, 5, 19) << 2);
+ int cond = get_bits(insn, 0, 4);
+ int no_match;
+ TCGv_i32 tcg_zero = tcg_const_i32(0);
+ TCGv_i32 tcg_cond = tcg_const_i32(cond);
+ TCGv_i32 tcg_condmatch = tcg_temp_new_i32();
+
+ no_match = gen_new_label();
+
+ gen_helper_cond(tcg_condmatch, pstate, tcg_cond);
+ tcg_gen_brcond_i32(TCG_COND_EQ, tcg_condmatch, tcg_zero, no_match);
+
+ gen_goto_tb(s, 0, addr);
+
+ gen_set_label(no_match);
+ gen_goto_tb(s, 1, s->pc);
+
+ tcg_temp_free_i32(tcg_zero);
+ tcg_temp_free_i32(tcg_cond);
+ tcg_temp_free_i32(tcg_condmatch);
+
+ s->is_jmp = DISAS_TB_JUMP;
+}
+
static void ldst_do_vec_int(DisasContext *s, int freg_offs, TCGv_i64 tcg_addr,
int size, bool is_store)
{
@@ -1743,6 +1769,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_svc(s, insn);
} else if (get_bits(insn, 29, 2) == 0x1) {
handle_cb(s, insn);
+ } else if (get_bits(insn, 29, 3) == 0x2) {
+ handle_condb(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 35/60] AArch64: Add mrs instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (33 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 34/60] AArch64: Add b.cond " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 36/60] AArch64: Add msr " Alexander Graf
` (26 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the mrs instruction. It is very incomplete
though and will need major rework to become as dynamic and good as the
cp15 handling.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index d5cc199..4879073 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1650,6 +1650,37 @@ static void handle_svc(DisasContext *s, uint32_t insn)
s->is_jmp = DISAS_SWI;
}
+static void handle_mrs(DisasContext *s, uint32_t insn)
+{
+ int dest = get_reg(insn);
+ int op2 = get_bits(insn, 5, 3);
+ int crm = get_bits(insn, 8, 4);
+ int crn = get_bits(insn, 12, 4);
+ int op1 = get_bits(insn, 16, 3);
+ int op0 = get_bits(insn, 19, 2);
+
+ /* XXX handle properly */
+ if (op0 == 3 && op1 == 3 && op2 == 2 && !crm && crn == 13) {
+ tcg_gen_ld_i64(cpu_reg(dest), cpu_env,
+ offsetof(CPUARMState, sr.tpidr_el0));
+ } else if (op0 == 3 && op1 == 3 && (op2 == 0 || op2 == 1) &&
+ crm == 4 && crn == 4) {
+ /* XXX this is probably wrong! */
+ tcg_gen_ld32u_i64(cpu_reg(dest), cpu_env,
+ offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPSCR]));
+ } else if (op0 == 3 && op1 == 3 && op2 == 1 && crm == 0 && crn == 0) {
+ /*
+ * CTR_EL0 [3:0] contains log2 of icache line size in words.
+ * CTR_EL0 [19:16] contains log2 of dcache line size in words.
+ */
+ tcg_gen_movi_i64(cpu_reg(dest), 0x30003);
+ } else {
+ qemu_log_mask(LOG_UNIMP, "MRS: %d %d %d %d %d\n", op0, op1, op2, crm,
+ crn);
+ unallocated_encoding(s);
+ }
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -1778,6 +1809,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x15:
if (get_bits(insn, 29, 2) == 0x1) {
handle_cb(s, insn);
+ } else if (get_bits(insn, 20, 12) == 0xd53) {
+ handle_mrs(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 36/60] AArch64: Add msr instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (34 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 35/60] AArch64: Add mrs " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 37/60] AArch64: Add hint " Alexander Graf
` (25 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the msr instruction. It suffers from the same
shortcomings as mrs emulation and should be combined with it.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 4879073..a2d5942 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1681,6 +1681,31 @@ static void handle_mrs(DisasContext *s, uint32_t insn)
}
}
+static void handle_msr(DisasContext *s, uint32_t insn)
+{
+ int dest = get_reg(insn);
+ int op2 = get_bits(insn, 5, 3);
+ int crm = get_bits(insn, 8, 4);
+ int crn = get_bits(insn, 12, 4);
+ int op1 = get_bits(insn, 16, 3);
+ int op0 = get_bits(insn, 19, 2);
+
+ /* XXX handle properly */
+ if (op0 == 3 && op1 == 3 && op2 == 2 && !crm && crn == 13) {
+ tcg_gen_st_i64(cpu_reg(dest), cpu_env,
+ offsetof(CPUARMState, sr.tpidr_el0));
+ } else if (op0 == 3 && op1 == 3 && (op2 == 0 || op2 == 1) &&
+ crm == 4 && crn == 4) {
+ /* XXX this is probably wrong! */
+ tcg_gen_st32_i64(cpu_reg(dest), cpu_env,
+ offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPSCR]));
+ } else {
+ qemu_log_mask(LOG_UNIMP, "MSR: %d %d %d %d %d\n", op0, op1, op2, crm,
+ crn);
+ unallocated_encoding(s);
+ }
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -1811,6 +1836,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_cb(s, insn);
} else if (get_bits(insn, 20, 12) == 0xd53) {
handle_mrs(s, insn);
+ } else if (get_bits(insn, 20, 12) == 0xd51) {
+ handle_msr(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 37/60] AArch64: Add hint instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (35 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 36/60] AArch64: Add msr " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 38/60] AArch64: Add stub barrier " Alexander Graf
` (24 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds handling for HINT instructions as noops.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index a2d5942..cbfc449 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1838,6 +1838,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_mrs(s, insn);
} else if (get_bits(insn, 20, 12) == 0xd51) {
handle_msr(s, insn);
+ } else if ((insn & 0xfffff01f) == 0xd503201f) {
+ /* HINT instructions, do nothing */
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 38/60] AArch64: Add stub barrier instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (36 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 37/60] AArch64: Add hint " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 39/60] AArch64: Add stub sys " Alexander Graf
` (23 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds handling for barrier instructions as noops.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index cbfc449..cfad24f 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1840,6 +1840,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_msr(s, insn);
} else if ((insn & 0xfffff01f) == 0xd503201f) {
/* HINT instructions, do nothing */
+ } else if ((insn & 0xfffff09f) == 0xd503309f) {
+ /* barrier instructions, do nothing */
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 39/60] AArch64: Add stub sys instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (37 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 38/60] AArch64: Add stub barrier " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 40/60] AArch64: Add tbz " Alexander Graf
` (22 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds handling for the sys instruction as noop.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index cfad24f..2c2adb8 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1706,6 +1706,14 @@ static void handle_msr(DisasContext *s, uint32_t insn)
}
}
+static void handle_sys(DisasContext *s, uint32_t insn)
+{
+ /*
+ * XXX Simply ignore sys for now. We only need to start worrying about it
+ * when we start implementing system emulation.
+ */
+}
+
void disas_a64_insn(CPUARMState *env, DisasContext *s)
{
uint32_t insn;
@@ -1842,6 +1850,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
/* HINT instructions, do nothing */
} else if ((insn & 0xfffff09f) == 0xd503309f) {
/* barrier instructions, do nothing */
+ } else if (get_bits(insn, 19, 13) == 0x1aa1) {
+ handle_sys(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 40/60] AArch64: Add tbz instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (38 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 39/60] AArch64: Add stub sys " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 20:50 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 41/60] AArch64: Add ldr/str instruction family emulation Alexander Graf
` (21 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the tbz/tbnz instructions.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 2c2adb8..7232cf4 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -294,6 +294,38 @@ static void handle_condb(DisasContext *s, uint32_t insn)
s->is_jmp = DISAS_TB_JUMP;
}
+static void handle_tbz(DisasContext *s, uint32_t insn)
+{
+ uint64_t addr = s->pc - 4 + (get_sbits(insn, 5, 14) << 2);
+ bool is_one = get_bits(insn, 24, 1);
+ int shift = get_bits(insn, 19, 5) | (get_bits(insn, 31, 1) << 5);
+ int source = get_reg(insn);
+ int no_match;
+ uint64_t mask = 1ULL << shift;
+ TCGv_i64 tcg_cmp, tcg_mask;
+
+ tcg_cmp = tcg_temp_new_i64();
+ tcg_mask = tcg_const_i64(mask);
+ tcg_gen_and_i64(tcg_cmp, cpu_reg(source), tcg_mask);
+
+ no_match = gen_new_label();
+ if (is_one) {
+ tcg_gen_brcond_i64(TCG_COND_NE, tcg_cmp, tcg_mask, no_match);
+ } else {
+ tcg_gen_brcond_i64(TCG_COND_EQ, tcg_cmp, tcg_mask, no_match);
+ }
+ gen_goto_tb(s, 0, addr);
+ tcg_gen_exit_tb(0);
+
+ gen_set_label(no_match);
+ gen_goto_tb(s, 1, s->pc);
+
+ tcg_temp_free_i64(tcg_cmp);
+ tcg_temp_free_i64(tcg_mask);
+
+ s->is_jmp = DISAS_TB_JUMP;
+}
+
static void ldst_do_vec_int(DisasContext *s, int freg_offs, TCGv_i64 tcg_addr,
int size, bool is_store)
{
@@ -1856,6 +1888,14 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
unallocated_encoding(s);
}
break;
+ case 0x16:
+ case 0x17:
+ if (get_bits(insn, 29, 2) == 0x1) {
+ handle_tbz(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 41/60] AArch64: Add ldr/str instruction family emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (39 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 40/60] AArch64: Add tbz " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 42/60] AArch64: Add literal ld instruction emulation Alexander Graf
` (20 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for various versions of ldr and str
instructions.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 124 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 124 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 7232cf4..2a7b042 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1347,6 +1347,120 @@ static void handle_bfm(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_newmask);
}
+static void ldst_calc_index(DisasContext *s, TCGv_i64 tcg_addr,
+ bool is_reg_offset, int offset, int size)
+{
+ bool is_shift = get_bits(offset, 0, 1);
+ int option = get_bits(offset, 1, 3);
+ int rn = get_bits(offset, 4, 5);
+ int shift = size;
+ TCGv_i64 tcg_offset;
+
+ if (!is_reg_offset) {
+ tcg_offset = tcg_const_i64(offset);
+ goto add_offset;
+ }
+
+ /* offset in register */
+ if (!(option & 2)) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (!is_shift) {
+ shift = 0;
+ }
+
+ tcg_offset = tcg_temp_new_i64();
+ reg_extend(tcg_offset, option, shift, rn);
+
+add_offset:
+ tcg_gen_add_i64(tcg_addr, tcg_addr, tcg_offset);
+ tcg_temp_free_i64(tcg_offset);
+}
+
+static void handle_ldst(DisasContext *s, uint32_t insn)
+{
+ int dest = get_reg(insn);
+ int source = get_bits(insn, 5, 5);
+ bool wback = get_bits(insn, 10, 1);
+ int type = get_bits(insn, 10, 2);
+ bool is_reg_offset = get_bits(insn, 21, 1);
+ bool is_store = !get_bits(insn, 22, 1);
+ bool opc1 = get_bits(insn, 23, 1);
+ bool is_imm12 = get_bits(insn, 24, 1);
+ bool is_vector = get_bits(insn, 26, 1);
+ int size = get_bits(insn, 30, 2);
+ bool is_signed = false;
+ bool postindex = false;
+ TCGv_i64 tcg_addr;
+ int offset;
+
+ if (is_imm12) {
+ /* wback, postindex and reg_offset bits are inside imm12 */
+ postindex = false;
+ wback = false;
+ is_reg_offset = false;
+ } else {
+ /* These only apply to the IMM9 variant */
+ if (is_reg_offset && type != 2) {
+ unallocated_encoding(s);
+ return;
+ }
+ /* LDR (post-index) */
+ postindex = (type == 1);
+ }
+
+ if (is_vector) {
+ size = (opc1 ? 0x4 : 0) | size;
+ if (size > 4) {
+ unallocated_encoding(s);
+ return;
+ }
+ } else if (opc1) {
+ if (size == 3) {
+ /* prefetch */
+ if (!is_store) {
+ unallocated_encoding(s);
+ }
+ return;
+ }
+ if (size == 2 && !is_store) {
+ unallocated_encoding(s);
+ }
+ is_store = false;
+ is_signed = true;
+ }
+
+ if (is_imm12) {
+ /* UIMM12 version */
+ offset = get_bits(insn, 10, 12) << size;
+ } else {
+ /* SIMM9 version */
+ offset = get_sbits(insn, 12, 9);
+ }
+
+ tcg_addr = tcg_temp_new_i64();
+
+ tcg_gen_mov_i64(tcg_addr, cpu_reg_sp(source));
+
+ if (!postindex) {
+ ldst_calc_index(s, tcg_addr, is_reg_offset, offset, size);
+ }
+
+ ldst_do(s, dest, tcg_addr, size, is_store, is_signed, is_vector);
+
+ if (postindex) {
+ ldst_calc_index(s, tcg_addr, is_reg_offset, offset, size);
+ }
+
+ if (wback) {
+ tcg_gen_mov_i64(cpu_reg_sp(source), tcg_addr);
+ }
+
+ tcg_temp_free_i64(tcg_addr);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -1896,6 +2010,16 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
unallocated_encoding(s);
}
break;
+ case 0x18:
+ case 0x19:
+ case 0x1c:
+ case 0x1d:
+ if (get_bits(insn, 29, 1)) {
+ handle_ldst(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 42/60] AArch64: Add literal ld instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (40 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 41/60] AArch64: Add ldr/str instruction family emulation Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 43/60] AArch64: Add cinc " Alexander Graf
` (19 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for PC-relative ld instructions.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 38 +++++++++++++++++++++++++++++++++++++-
1 file changed, 37 insertions(+), 1 deletion(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 2a7b042..2f2d8bd 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1461,6 +1461,42 @@ static void handle_ldst(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_addr);
}
+static void handle_ld_literal(DisasContext *s, uint32_t insn)
+{
+ int dest = get_reg(insn);
+ int64_t imm = get_sbits(insn, 5, 19) << 2;
+ bool is_vector = get_bits(insn, 26, 1);
+ int opc = get_bits(insn, 30, 2);
+ TCGv_i64 tcg_addr;
+ bool is_signed;
+ int size;
+
+ tcg_addr = tcg_const_i64((s->pc - 4) + imm);
+
+ switch (opc) {
+ case 0:
+ is_signed = false;
+ size = 2;
+ break;
+ case 1:
+ is_signed = false;
+ size = 3;
+ break;
+ case 2:
+ is_signed = true;
+ size = 2;
+ break;
+ case 3:
+ /* prefetch */
+ goto out;
+ }
+
+ ldst_do(s, dest, tcg_addr, size, false, is_signed, is_vector);
+
+out:
+ tcg_temp_free_i64(tcg_addr);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2017,7 +2053,7 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
if (get_bits(insn, 29, 1)) {
handle_ldst(s, insn);
} else {
- unallocated_encoding(s);
+ handle_ld_literal(s, insn);
}
break;
default:
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 43/60] AArch64: Add cinc instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (41 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 42/60] AArch64: Add literal ld instruction emulation Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 20:52 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 44/60] AArch64: Add division instruction family emulation Alexander Graf
` (18 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the conditional increment (cinc) instruction.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 34 ++++++++++++++++++++++++++++++++++
target-arm/helper-a64.h | 1 +
target-arm/translate-a64.c | 17 +++++++++++++++++
3 files changed, 52 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 9aaf181..3f055b6 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -187,3 +187,37 @@ uint32_t HELPER(cond)(uint32_t pstate, uint32_t cond)
return !!r;
}
+
+static int get_bits(uint32_t inst, int start, int len)
+{
+ return (inst >> start) & ((1 << len) - 1);
+}
+
+uint64_t HELPER(cinc)(uint32_t pstate, uint32_t insn, uint64_t n, uint64_t m)
+{
+ bool else_inc = get_bits(insn, 10, 1);
+ int cond = get_bits(insn, 12, 4);
+ bool else_inv = get_bits(insn, 30, 1);
+ bool is_32bit = !get_bits(insn, 31, 1);
+ uint64_t r;
+
+ if (helper_cond(pstate, cond)) {
+ r = n;
+ goto out;
+ }
+
+ r = m;
+ if (else_inv) {
+ r = ~r;
+ }
+ if (else_inc) {
+ r++;
+ }
+
+out:
+ if (is_32bit) {
+ r = (uint32_t)r;
+ }
+
+ return r;
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 99f4be7..8874518 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -23,3 +23,4 @@ DEF_HELPER_FLAGS_4(pstate_sub, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
DEF_HELPER_FLAGS_4(pstate_sub32, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
DEF_HELPER_FLAGS_3(sign_extend, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
DEF_HELPER_FLAGS_2(cond, TCG_CALL_NO_RWG_SE, i32, i32, i32)
+DEF_HELPER_FLAGS_4(cinc, TCG_CALL_NO_RWG_SE, i64, i32, i32, i64, i64)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 2f2d8bd..cd2dfe6 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1497,6 +1497,16 @@ out:
tcg_temp_free_i64(tcg_addr);
}
+static void handle_cinc(DisasContext *s, uint32_t insn)
+{
+ int rd = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int rm = get_bits(insn, 16, 5);
+ TCGv_i32 tcg_insn = tcg_const_i32(insn);
+
+ gen_helper_cinc(cpu_reg(rd), pstate, tcg_insn, cpu_reg(rn), cpu_reg(rm));
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2056,6 +2066,13 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_ld_literal(s, insn);
}
break;
+ case 0x1a:
+ if ((insn & 0x3fe00800) == 0x1a800000) {
+ handle_cinc(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 44/60] AArch64: Add division instruction family emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (42 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 43/60] AArch64: Add cinc " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 20:54 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 45/60] AArch64: Add shift " Alexander Graf
` (17 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for the udiv and sdiv instructions.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 16 ++++++++++++++++
target-arm/helper-a64.h | 2 ++
target-arm/translate-a64.c | 43 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 3f055b6..a56ce75 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -221,3 +221,19 @@ out:
return r;
}
+
+uint64_t HELPER(udiv64)(uint64_t num, uint64_t den)
+{
+ if (den == 0)
+ return 0;
+ return num / den;
+}
+
+int64_t HELPER(sdiv64)(int64_t num, int64_t den)
+{
+ if (den == 0)
+ return 0;
+ if (num == LLONG_MIN && den == -1)
+ return LLONG_MIN;
+ return num / den;
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 8874518..ad1a94a 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -24,3 +24,5 @@ DEF_HELPER_FLAGS_4(pstate_sub32, TCG_CALL_NO_RWG_SE, i32, i32, i64, i64, i64)
DEF_HELPER_FLAGS_3(sign_extend, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
DEF_HELPER_FLAGS_2(cond, TCG_CALL_NO_RWG_SE, i32, i32, i32)
DEF_HELPER_FLAGS_4(cinc, TCG_CALL_NO_RWG_SE, i64, i32, i32, i64, i64)
+DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index cd2dfe6..6954ff7 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1507,6 +1507,47 @@ static void handle_cinc(DisasContext *s, uint32_t insn)
gen_helper_cinc(cpu_reg(rd), pstate, tcg_insn, cpu_reg(rn), cpu_reg(rm));
}
+static void handle_div(DisasContext *s, uint32_t insn)
+{
+ int rd = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int rm = get_bits(insn, 16, 5);
+ bool is_signed = get_bits(insn, 10, 1);
+ bool is_32bit = !get_bits(insn, 31, 1);
+ TCGv_i64 n = tcg_temp_new_i64();
+ TCGv_i64 m = tcg_temp_new_i64();
+
+ if (is_32bit) {
+ if (is_signed) {
+ tcg_gen_ext32s_i64(n, cpu_reg(rn));
+ tcg_gen_ext32s_i64(m, cpu_reg(rm));
+ } else {
+ tcg_gen_ext32u_i64(n, cpu_reg(rn));
+ tcg_gen_ext32u_i64(m, cpu_reg(rm));
+ }
+ } else {
+ tcg_gen_mov_i64(n, cpu_reg(rn));
+ tcg_gen_mov_i64(m, cpu_reg(rm));
+ }
+
+ if (is_signed) {
+ gen_helper_sdiv64(cpu_reg(rd), n, m);
+ } else {
+ gen_helper_udiv64(cpu_reg(rd), n, m);
+ }
+
+ if (is_32bit) {
+ if (is_signed) {
+ tcg_gen_ext32s_i64(cpu_reg(rd), cpu_reg(rd));
+ } else {
+ tcg_gen_ext32u_i64(cpu_reg(rd), cpu_reg(rd));
+ }
+ }
+
+ tcg_temp_free_i64(n);
+ tcg_temp_free_i64(m);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2069,6 +2110,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x1a:
if ((insn & 0x3fe00800) == 0x1a800000) {
handle_cinc(s, insn);
+ } else if ((insn & 0x7fe0f800) == 0x1ac00800) {
+ handle_div(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 45/60] AArch64: Add shift instruction family emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (43 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 44/60] AArch64: Add division instruction family emulation Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 46/60] AArch64: Add rev " Alexander Graf
` (16 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for variable (register based) shift
instructions such as ASRV, LSLV, LSRV, RORV.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 6954ff7..6e0f4bd 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1548,6 +1548,24 @@ static void handle_div(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(m);
}
+static void handle_shift_reg(DisasContext *s, uint32_t insn)
+{
+ int rd = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int shift_type = get_bits(insn, 10, 2);
+ int rm = get_bits(insn, 16, 5);
+ bool is_32bit = !get_bits(insn, 31, 1);
+ TCGv_i64 tcg_shift;
+ TCGv_i64 tcg_shifted;
+
+ tcg_shift = tcg_temp_new_i64();
+ tcg_gen_andi_i64(tcg_shift, cpu_reg(rm), is_32bit ? 31 : 63);
+ tcg_shifted = get_shift(rn, shift_type, tcg_shift, is_32bit);
+ tcg_gen_mov_i64(cpu_reg(rd), tcg_shifted);
+ tcg_temp_free_i64(tcg_shift);
+ tcg_temp_free_i64(tcg_shifted);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2112,6 +2130,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_cinc(s, insn);
} else if ((insn & 0x7fe0f800) == 0x1ac00800) {
handle_div(s, insn);
+ } else if ((insn & 0x7fe0f000) == 0x1ac02000) {
+ handle_shift_reg(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 46/60] AArch64: Add rev instruction family emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (44 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 45/60] AArch64: Add shift " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 21:07 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 47/60] AArch64: Add clz instruction emulation Alexander Graf
` (15 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emlulation support for rev and rbit instructions.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 19 +++++++++++++++++++
target-arm/helper-a64.h | 1 +
target-arm/translate-a64.c | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 58 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index a56ce75..e20b89f 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -237,3 +237,22 @@ int64_t HELPER(sdiv64)(int64_t num, int64_t den)
return LLONG_MIN;
return num / den;
}
+
+uint64_t HELPER(rbit64)(uint64_t x)
+{
+ x = ((x & 0xff00000000000000ULL) >> 56)
+ | ((x & 0x00ff000000000000ULL) >> 40)
+ | ((x & 0x0000ff0000000000ULL) >> 24)
+ | ((x & 0x000000ff00000000ULL) >> 8)
+ | ((x & 0x00000000ff000000ULL) << 8)
+ | ((x & 0x0000000000ff0000ULL) << 24)
+ | ((x & 0x000000000000ff00ULL) << 40)
+ | ((x & 0x00000000000000ffULL) << 56);
+ x = ((x & 0xf0f0f0f0f0f0f0f0ULL) >> 4)
+ | ((x & 0x0f0f0f0f0f0f0f0fULL) << 4);
+ x = ((x & 0x8888888888888888ULL) >> 3)
+ | ((x & 0x4444444444444444ULL) >> 1)
+ | ((x & 0x2222222222222222ULL) << 1)
+ | ((x & 0x1111111111111111ULL) << 3);
+ return x;
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index ad1a94a..5e5cda0 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -26,3 +26,4 @@ DEF_HELPER_FLAGS_2(cond, TCG_CALL_NO_RWG_SE, i32, i32, i32)
DEF_HELPER_FLAGS_4(cinc, TCG_CALL_NO_RWG_SE, i64, i32, i32, i64, i64)
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
+DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 6e0f4bd..208d06b 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1566,6 +1566,42 @@ static void handle_shift_reg(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_shifted);
}
+static void handle_rev(DisasContext *s, uint32_t insn)
+{
+ int rd = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int opc = get_bits(insn, 10, 2);
+ bool is_32bit = !get_bits(insn, 31, 1);
+ TCGv_i32 tcg_tmp;
+
+ switch (opc) {
+ case 0x0: /* RBIT */
+ if (is_32bit) {
+ tcg_tmp = tcg_temp_new_i32();
+ tcg_gen_trunc_i64_i32(tcg_tmp, cpu_reg(rn));
+ gen_helper_rbit(tcg_tmp, tcg_tmp);
+ tcg_gen_extu_i32_i64(cpu_reg(rd), tcg_tmp);
+ tcg_temp_free_i32(tcg_tmp);
+ } else {
+ gen_helper_rbit64(cpu_reg(rd), cpu_reg(rn));
+ }
+ break;
+ case 0x1: /* REV16 */
+ tcg_gen_bswap16_i64(cpu_reg(rd), cpu_reg(rn));
+ break;
+ case 0x2: /* REV32 */
+ tcg_gen_bswap32_i64(cpu_reg(rd), cpu_reg(rn));
+ break;
+ case 0x3: /* REV64 */
+ tcg_gen_bswap64_i64(cpu_reg(rd), cpu_reg(rn));
+ break;
+ }
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(cpu_reg(rd), cpu_reg(rd));
+ }
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2132,6 +2168,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_div(s, insn);
} else if ((insn & 0x7fe0f000) == 0x1ac02000) {
handle_shift_reg(s, insn);
+ } else if ((insn & 0x7ffff000) == 0x5ac00000) {
+ handle_rev(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 47/60] AArch64: Add clz instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (45 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 46/60] AArch64: Add rev " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 48/60] AArch64: Add 0x1a encoding of add instructions Alexander Graf
` (14 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emlulation support for the clz instruction.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 5 +++++
target-arm/helper-a64.h | 1 +
target-arm/translate-a64.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 37 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index e20b89f..a8a8499 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -256,3 +256,8 @@ uint64_t HELPER(rbit64)(uint64_t x)
| ((x & 0x1111111111111111ULL) << 3);
return x;
}
+
+uint64_t HELPER(clz64)(uint64_t x)
+{
+ return clz64(x);
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 5e5cda0..607ba8a 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -27,3 +27,4 @@ DEF_HELPER_FLAGS_4(cinc, TCG_CALL_NO_RWG_SE, i64, i32, i32, i64, i64)
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
+DEF_HELPER_FLAGS_1(clz64, TCG_CALL_NO_RWG_SE, i64, i64)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 208d06b..db55389 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1602,6 +1602,35 @@ static void handle_rev(DisasContext *s, uint32_t insn)
}
}
+static void handle_clz(DisasContext *s, uint32_t insn)
+{
+ int rd = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int opc = get_bits(insn, 10, 2);
+ bool is_32bit = !get_bits(insn, 31, 1);
+ TCGv_i64 tcg_val = tcg_temp_new_i64();
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(tcg_val, cpu_reg(rn));
+ } else {
+ tcg_gen_mov_i64(tcg_val, cpu_reg(rn));
+ }
+
+ switch (opc) {
+ case 0x0: /* CLZ */
+ gen_helper_clz64(cpu_reg(rd), tcg_val);
+ if (is_32bit) {
+ tcg_gen_subi_i64(cpu_reg(rd), cpu_reg(rd), 32);
+ }
+ break;
+ case 0x1: /* CLS */
+ unallocated_encoding(s);
+ break;
+ }
+
+ tcg_temp_free_i64(tcg_val);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2170,6 +2199,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_shift_reg(s, insn);
} else if ((insn & 0x7ffff000) == 0x5ac00000) {
handle_rev(s, insn);
+ } else if ((insn & 0x7ffff800) == 0x5ac01000) {
+ handle_clz(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 48/60] AArch64: Add 0x1a encoding of add instructions
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (46 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 47/60] AArch64: Add clz instruction emulation Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 49/60] AArch64: Add "Data-processing (3 source)" instruction Alexander Graf
` (13 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
The "Add/subtract (with carry)" instructions can also be handled by our
generic add instruction decoder, so get them handled by that one too.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index db55389..32cfab3 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2201,6 +2201,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
handle_rev(s, insn);
} else if ((insn & 0x7ffff800) == 0x5ac01000) {
handle_clz(s, insn);
+ } else if (!get_bits(insn, 21, 3) && !get_bits(insn, 10, 6)) {
+ handle_add(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 49/60] AArch64: Add "Data-processing (3 source)" instruction
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (47 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 48/60] AArch64: Add 0x1a encoding of add instructions Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 50/60] AArch64: Add "Floating-point<->fixed-point Alexander Graf
` (12 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for most of the "Data-processing (3 source)" family
of instructions, namely MADD, MSUB, SMADDL, SMSUBL, SMULH, UMADDL, UMSUBL,
UMULH.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 14 ++++++++
target-arm/helper-a64.h | 2 ++
target-arm/translate-a64.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 106 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index a8a8499..a46b00e 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -261,3 +261,17 @@ uint64_t HELPER(clz64)(uint64_t x)
{
return clz64(x);
}
+
+uint64_t HELPER(umulh)(uint64_t n, uint64_t m)
+{
+ uint64_t rl, rh;
+ mulu64(&rl, &rh, n, m);
+ return rh;
+}
+
+uint64_t HELPER(smulh)(uint64_t n, uint64_t m)
+{
+ uint64_t rl, rh;
+ muls64(&rl, &rh, n, m);
+ return rh;
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 607ba8a..41dedd7 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -28,3 +28,5 @@ DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(clz64, TCG_CALL_NO_RWG_SE, i64, i64)
+DEF_HELPER_FLAGS_2(umulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_FLAGS_2(smulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 32cfab3..5985c01 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1631,6 +1631,93 @@ static void handle_clz(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_val);
}
+static void handle_mulh(DisasContext *s, uint32_t insn)
+{
+ int rd = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int rm = get_bits(insn, 16, 5);
+ bool is_signed = !get_bits(insn, 23, 1);
+
+ if (is_signed) {
+ gen_helper_smulh(cpu_reg(rd), cpu_reg(rn), cpu_reg(rm));
+ } else {
+ gen_helper_umulh(cpu_reg(rd), cpu_reg(rn), cpu_reg(rm));
+ }
+}
+
+/* Data-processing (3 source) */
+static void handle_dp3s(DisasContext *s, uint32_t insn)
+{
+ int rd = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int ra = get_bits(insn, 10, 5);
+ int rm = get_bits(insn, 16, 5);
+ int op_id = (get_bits(insn, 29, 3) << 4) |
+ (get_bits(insn, 21, 3) << 1) |
+ get_bits(insn, 15, 1);
+ bool is_32bit = !(op_id & 0x40);
+ bool is_sub = op_id & 0x1;
+ bool is_signed = (op_id >= 0x42) && (op_id <= 0x44);
+ bool is_high = op_id & 0x4;
+ TCGv_i64 tcg_op1;
+ TCGv_i64 tcg_op2;
+ TCGv_i64 tcg_tmp;
+
+ switch (op_id) {
+ case 0x0: /* MADD (32bit) */
+ case 0x1: /* MSUB (32bit) */
+ case 0x40: /* MADD (64bit) */
+ case 0x41: /* MSUB (64bit) */
+ case 0x42: /* SMADDL */
+ case 0x43: /* SMSUBL */
+ case 0x44: /* SMULH */
+ case 0x4a: /* UMADDL */
+ case 0x4b: /* UMSUBL */
+ case 0x4c: /* UMULH */
+ break;
+ default:
+ unallocated_encoding(s);
+ }
+
+ if (is_high) {
+ handle_mulh(s, insn);
+ return;
+ }
+
+ tcg_op1 = tcg_temp_new_i64();
+ tcg_op2 = tcg_temp_new_i64();
+ tcg_tmp = tcg_temp_new_i64();
+
+ if (op_id < 0x42) {
+ tcg_gen_mov_i64(tcg_op1, cpu_reg(rn));
+ tcg_gen_mov_i64(tcg_op2, cpu_reg(rm));
+ } else {
+ if (is_signed) {
+ tcg_gen_ext32s_i64(tcg_op1, cpu_reg(rn));
+ tcg_gen_ext32s_i64(tcg_op2, cpu_reg(rm));
+ } else {
+ tcg_gen_ext32u_i64(tcg_op1, cpu_reg(rn));
+ tcg_gen_ext32u_i64(tcg_op2, cpu_reg(rm));
+ }
+ }
+
+ tcg_gen_mul_i64(tcg_tmp, tcg_op1, tcg_op2);
+
+ if (is_sub) {
+ tcg_gen_sub_i64(cpu_reg(rd), cpu_reg(ra), tcg_tmp);
+ } else {
+ tcg_gen_add_i64(cpu_reg(rd), cpu_reg(ra), tcg_tmp);
+ }
+
+ if (is_32bit) {
+ tcg_gen_ext32u_i64(cpu_reg(rd), cpu_reg(rd));
+ }
+
+ tcg_temp_free_i64(tcg_op1);
+ tcg_temp_free_i64(tcg_op2);
+ tcg_temp_free_i64(tcg_tmp);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2207,6 +2294,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
unallocated_encoding(s);
}
break;
+ case 0x1b:
+ handle_dp3s(s, insn);
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 50/60] AArch64: Add "Floating-point<->fixed-point
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (48 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 49/60] AArch64: Add "Data-processing (3 source)" instruction Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-11-19 20:41 ` Janne Grunau
2013-09-27 0:48 ` [Qemu-devel] [PATCH 51/60] AArch64: Add fmov (scalar, immediate) instruction Alexander Graf
` (11 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the instruction group labeled
"Floating-point <-> fixed-point conversions" in the ARM ARM.
Namely this includes the instructions SCVTF, UCVTF, FCVTZS, FCVTZU
(scalar, fixed-point).
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 22 ++++++
target-arm/helper-a64.h | 1 +
target-arm/translate-a64.c | 173 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 196 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index a46b00e..0b7aee1 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -275,3 +275,25 @@ uint64_t HELPER(smulh)(uint64_t n, uint64_t m)
muls64(&rl, &rh, n, m);
return rh;
}
+
+void HELPER(set_rmode)(uint32_t rmode, void *fp_status)
+{
+ switch (rmode) {
+ case ROUND_MODE_TIEEVEN:
+ default:
+ rmode = float_round_nearest_even;
+ break;
+ case ROUND_MODE_UP:
+ rmode = float_round_up;
+ break;
+ case ROUND_MODE_DOWN:
+ rmode = float_round_down;
+ break;
+ case ROUND_MODE_ZERO:
+ rmode = float_round_to_zero;
+ break;
+ /* XXX add fpcr rounding (exact and not exact) */
+ }
+
+ set_float_rounding_mode(rmode, fp_status);
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 41dedd7..f42edf8 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -30,3 +30,4 @@ DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(clz64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_2(umulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(smulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
+DEF_HELPER_2(set_rmode, void, i32, ptr)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 5985c01..654e011 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -183,6 +183,17 @@ static void clear_fpreg(int dest)
tcg_gen_st_i64(tcg_zero, cpu_env, freg_offs + sizeof(float64));
}
+static TCGv_ptr get_fpstatus_ptr(void)
+{
+ TCGv_ptr statusptr = tcg_temp_new_ptr();
+ int offset;
+
+ offset = offsetof(CPUARMState, vfp.standard_fp_status);
+ tcg_gen_addi_ptr(statusptr, cpu_env, offset);
+
+ return statusptr;
+}
+
static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
{
TranslationBlock *tb;
@@ -1718,6 +1729,161 @@ static void handle_dp3s(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_tmp);
}
+static void handle_fpfpcvt(DisasContext *s, uint32_t insn, bool direction,
+ int rmode)
+{
+ int rd = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int scale = get_bits(insn, 10, 6);
+ int opcode = get_bits(insn, 16, 3);
+ int type = get_bits(insn, 22, 2);
+ bool is_32bit = !get_bits(insn, 31, 1);
+ bool is_double = get_bits(type, 0, 1);
+ bool is_signed = !get_bits(opcode, 0, 1);
+ int freg_offs;
+ int fp_reg;
+ TCGv_i64 tcg_int;
+ TCGv_i64 tcg_single;
+ TCGv_i64 tcg_double;
+ TCGv_i64 tcg_fpstatus = get_fpstatus_ptr();
+ TCGv_i32 tcg_shift = tcg_const_i32(scale);
+ TCGv_i32 tcg_rmode = tcg_const_i32(rmode);
+ TCGv_i64 tcg_tmp;
+
+ if (direction) {
+ fp_reg = rn;
+ tcg_int = cpu_reg(rd);
+ } else {
+ fp_reg = rd;
+ tcg_int = cpu_reg(rn);
+ }
+ freg_offs = offsetof(CPUARMState, vfp.regs[fp_reg * 2]);
+
+ if (!direction) {
+ clear_fpreg(fp_reg);
+ }
+
+ if (is_32bit && !direction) {
+ tcg_tmp = tcg_temp_new_i64();
+ if (is_signed) {
+ tcg_gen_ext32s_i64(tcg_tmp, tcg_int);
+ } else {
+ tcg_gen_ext32u_i64(tcg_tmp, tcg_int);
+ }
+ tcg_int = tcg_tmp;
+ }
+
+ gen_helper_set_rmode(tcg_rmode, tcg_fpstatus);
+
+ switch ((direction ? 0x10 : 0)|
+ (is_double ? 0x1 : 0) |
+ (is_signed ? 0x2 : 0)) {
+ case 0x0: /* unsigned scalar->single */
+ tcg_single = tcg_temp_new_i32();
+ tcg_tmp = tcg_temp_new_i64();
+ gen_helper_vfp_uqtos(tcg_single, tcg_int, tcg_shift, tcg_fpstatus);
+ tcg_gen_extu_i32_i64(tcg_tmp, tcg_single);
+ tcg_gen_st32_i64(tcg_tmp, cpu_env, freg_offs);
+ tcg_temp_free_i32(tcg_single);
+ tcg_temp_free_i64(tcg_tmp);
+ break;
+ case 0x1: /* unsigned scalar->double */
+ tcg_double = tcg_temp_new_i64();
+ gen_helper_vfp_uqtod(tcg_double, tcg_int, tcg_shift, tcg_fpstatus);
+ tcg_gen_st_i64(tcg_double, cpu_env, freg_offs);
+ tcg_temp_free_i64(tcg_double);
+ break;
+ case 0x2: /* signed scalar->single */
+ tcg_single = tcg_temp_new_i32();
+ tcg_tmp = tcg_temp_new_i64();
+ gen_helper_vfp_sqtos(tcg_single, tcg_int, tcg_shift, tcg_fpstatus);
+ tcg_gen_extu_i32_i64(tcg_tmp, tcg_single);
+ tcg_gen_st32_i64(tcg_tmp, cpu_env, freg_offs);
+ tcg_temp_free_i32(tcg_single);
+ tcg_temp_free_i64(tcg_tmp);
+ break;
+ case 0x3: /* signed scalar->double */
+ tcg_double = tcg_temp_new_i64();
+ gen_helper_vfp_sqtod(tcg_double, tcg_int, tcg_shift, tcg_fpstatus);
+ tcg_gen_st_i64(tcg_double, cpu_env, freg_offs);
+ tcg_temp_free_i64(tcg_double);
+ break;
+ case 0x10: /* unsigned single->scalar */
+ tcg_single = tcg_temp_new_i32();
+ tcg_tmp = tcg_temp_new_i64();
+ tcg_gen_ld32u_i64(tcg_tmp, cpu_env, freg_offs);
+ tcg_gen_trunc_i64_i32(tcg_single, tcg_tmp);
+ gen_helper_vfp_touqs(tcg_int, tcg_single, tcg_shift, tcg_fpstatus);
+ tcg_temp_free_i32(tcg_single);
+ tcg_temp_free_i64(tcg_tmp);
+ break;
+ case 0x11: /* unsigned single->double */
+ tcg_double = tcg_temp_new_i64();
+ tcg_gen_ld_i64(tcg_double, cpu_env, freg_offs);
+ gen_helper_vfp_touqd(tcg_int, tcg_double, tcg_shift, tcg_fpstatus);
+ tcg_temp_free_i64(tcg_double);
+ break;
+ case 0x12: /* signed single->scalar */
+ tcg_single = tcg_temp_new_i32();
+ tcg_tmp = tcg_temp_new_i64();
+ tcg_gen_ld32u_i64(tcg_tmp, cpu_env, freg_offs);
+ tcg_gen_trunc_i64_i32(tcg_single, tcg_tmp);
+ gen_helper_vfp_tosqs(tcg_int, tcg_single, tcg_shift, tcg_fpstatus);
+ tcg_temp_free_i32(tcg_single);
+ tcg_temp_free_i64(tcg_tmp);
+ break;
+ case 0x13: /* signed single->double */
+ tcg_double = tcg_temp_new_i64();
+ tcg_gen_ld_i64(tcg_double, cpu_env, freg_offs);
+ gen_helper_vfp_tosqd(tcg_int, tcg_double, tcg_shift, tcg_fpstatus);
+ tcg_temp_free_i64(tcg_double);
+ break;
+ default:
+ unallocated_encoding(s);
+ }
+
+ /* XXX use fpcr */
+ tcg_gen_movi_i32(tcg_rmode, -1);
+ gen_helper_set_rmode(tcg_rmode, tcg_fpstatus);
+
+ if (is_32bit && direction) {
+ tcg_gen_ext32u_i64(tcg_int, tcg_int);
+ }
+
+ tcg_temp_free_i64(tcg_fpstatus);
+ tcg_temp_free_i32(tcg_shift);
+ tcg_temp_free_i32(tcg_rmode);
+}
+
+/* fixed <-> floating conversion */
+static void handle_fpfpconv(DisasContext *s, uint32_t insn)
+{
+ int opcode = get_bits(insn, 16, 3);
+ int rmode = get_bits(insn, 20, 2);
+ int type = get_bits(insn, 22, 2);
+ bool is_s = get_bits(insn, 29, 1);
+ bool direction;
+
+ if (is_s || (type > 1) || (opcode > 1)) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ switch (rmode) {
+ case 0x1: /* [S|U]CVTF (scalar->float) */
+ direction = 0;
+ break;
+ case 0x3: /* FCVTZ[S|U] (float->scalar) */
+ direction = 1;
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ handle_fpfpcvt(s, insn, direction, ROUND_MODE_ZERO);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2297,6 +2463,13 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x1b:
handle_dp3s(s, insn);
break;
+ case 0x1e:
+ if (!get_bits(insn, 21, 1) && !get_bits(insn, 30, 1)) {
+ handle_fpfpconv(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 51/60] AArch64: Add fmov (scalar, immediate) instruction
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (49 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 50/60] AArch64: Add "Floating-point<->fixed-point Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 52/60] AArch64: Add "Floating-point<->integer conversions" Alexander Graf
` (10 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the fmov instruction working on scalars
with an immediate payload.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 654e011..33163fd 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1884,6 +1884,39 @@ static void handle_fpfpconv(DisasContext *s, uint32_t insn)
handle_fpfpcvt(s, insn, direction, ROUND_MODE_ZERO);
}
+/* fmov (immediate) */
+static void handle_fmovi(DisasContext *s, uint32_t insn)
+{
+ int rd = get_reg(insn);
+ int imm8 = get_bits(insn, 13, 8);
+ int is_double = get_bits(insn, 22, 2);
+ uint64_t imm;
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ TCGv_i64 tcg_res;
+
+ if (is_double > 1) {
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (is_double) {
+ imm = (get_bits(imm8, 7, 1) ? 0x8000 : 0) |
+ (get_bits(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
+ get_bits(imm8, 0, 6);
+ imm <<= 48;
+ } else {
+ imm = (get_bits(imm8, 7, 1) ? 0x8000 : 0) |
+ (get_bits(imm8, 6, 1) ? 0x3e00 : 0x4000) |
+ (get_bits(imm8, 0, 6) << 3);
+ imm <<= 16;
+ }
+
+ tcg_res = tcg_const_i64(imm);
+ clear_fpreg(rd);
+ tcg_gen_st_i64(tcg_res, cpu_env, freg_offs_d);
+ tcg_temp_free_i64(tcg_res);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2466,6 +2499,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x1e:
if (!get_bits(insn, 21, 1) && !get_bits(insn, 30, 1)) {
handle_fpfpconv(s, insn);
+ } else if (!get_bits(insn, 29, 3) && get_bits(insn, 21, 1) &&
+ (get_bits(insn, 5, 8) == 0x80)) {
+ handle_fmovi(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 52/60] AArch64: Add "Floating-point<->integer conversions"
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (50 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 51/60] AArch64: Add fmov (scalar, immediate) instruction Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 53/60] AArch64: Add "Floating-point compare" instruction Alexander Graf
` (9 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation support for the "Floating-point<->integer conversions"
family of instructions.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 33163fd..cc35c4e 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1917,6 +1917,64 @@ static void handle_fmovi(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_res);
}
+/* floating <-> integer conversion */
+static void handle_fpintconv(DisasContext *s, uint32_t insn)
+{
+ int rd = get_reg(insn);
+ int rn = get_bits(insn, 5, 5);
+ int opcode = get_bits(insn, 16, 3);
+ int rmode = get_bits(insn, 19, 2);
+ int type = get_bits(insn, 22, 2);
+ bool is_s = get_bits(insn, 29, 1);
+ bool is_32bit = !get_bits(insn, 31, 1);
+
+ if (!is_s && (rmode < 2) && (opcode > 5)) {
+ /* FMOV */
+ bool itof = opcode & 1;
+ int dest = itof ? rd : rn;
+ int freg_offs = offsetof(CPUARMState, vfp.regs[dest * 2]);
+
+ if (rmode & 1) {
+ freg_offs += sizeof(float64);
+ }
+
+ if (itof && (!(rmode & 1))) {
+ clear_fpreg(dest);
+ }
+
+ switch (type |
+ ((rmode & 1) ? 0x4 : 0) |
+ (itof ? 0x8 : 0)) {
+ case 0x0:
+ tcg_gen_ld32u_i64(cpu_reg(rd), cpu_env, freg_offs);
+ break;
+ case 0x1:
+ case 0x2 | 0x4:
+ tcg_gen_ld_i64(cpu_reg(rd), cpu_env, freg_offs);
+ break;
+ case 0x8 | 0x0:
+ tcg_gen_st32_i64(cpu_reg(rn), cpu_env, freg_offs);
+ break;
+ case 0x8 | 0x1:
+ case 0x8 | 0x2 | 0x4:
+ tcg_gen_st_i64(cpu_reg(rn), cpu_env, freg_offs);
+ break;
+ default:
+ unallocated_encoding(s);
+ }
+
+ if (is_32bit && !itof) {
+ tcg_gen_ext32u_i64(cpu_reg(rd), cpu_reg(rd));
+ }
+ } else if (!is_s && ((opcode & 0x6) < 5)) {
+ /* [S|U]CVTF and FCVT[N|P|M|Z][S|U] */
+ handle_fpfpcvt(s, insn, !(opcode & 0x6), rmode);
+ } else {
+ /* XXX */
+ unallocated_encoding(s);
+ }
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2502,6 +2560,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
} else if (!get_bits(insn, 29, 3) && get_bits(insn, 21, 1) &&
(get_bits(insn, 5, 8) == 0x80)) {
handle_fmovi(s, insn);
+ } else if (get_bits(insn, 21, 1) && !get_bits(insn, 30, 1) &&
+ !get_bits(insn, 10, 6)) {
+ handle_fpintconv(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 53/60] AArch64: Add "Floating-point compare" instruction
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (51 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 52/60] AArch64: Add "Floating-point<->integer conversions" Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 54/60] AArch64: Add "Floating-point data-processing (1 Alexander Graf
` (8 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds support for instructions that belong to the "Floating-point
compare" group of instructions.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index cc35c4e..948e5c4 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1975,6 +1975,69 @@ static void handle_fpintconv(DisasContext *s, uint32_t insn)
}
}
+/* Floating-point compare */
+static void handle_fcmp(DisasContext *s, uint32_t insn)
+{
+ int opc = get_bits(insn, 3, 2);
+ int rn = get_bits(insn, 5, 5);
+ int rm = get_bits(insn, 16, 5);
+ bool is_32bit = !get_bits(insn, 22, 1);
+ bool is_cmp_with_zero = get_bits(opc, 0, 1);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int freg_offs_m = offsetof(CPUARMState, vfp.regs[rm * 2]);
+ TCGv_i32 tcg_op1_32 = tcg_temp_new_i32();
+ TCGv_i32 tcg_op1_64 = tcg_temp_new_i64();
+ TCGv_i32 tcg_op2_32;
+ TCGv_i32 tcg_op2_64;
+
+ if (get_bits(insn, 23, 1)) {
+ unallocated_encoding(s);
+ }
+
+ tcg_gen_ld_i64(tcg_op1_64, cpu_env, freg_offs_n);
+
+ if (is_32bit) {
+ tcg_gen_trunc_i64_i32(tcg_op1_32, tcg_op1_64);
+ }
+
+ if (is_cmp_with_zero) {
+ tcg_op2_32 = tcg_const_i32(0);
+ tcg_op2_64 = tcg_const_i64(0);
+ } else {
+ tcg_op2_32 = tcg_temp_new_i32();
+ tcg_op2_64 = tcg_temp_new_i64();
+
+ tcg_gen_ld_i64(tcg_op2_64, cpu_env, freg_offs_m);
+ if (is_32bit) {
+ tcg_gen_trunc_i64_i32(tcg_op2_32, tcg_op2_64);
+ }
+ }
+
+ switch (opc | (is_32bit ? 0x0 : 0x4)) {
+ case 0x0: /* FCMP single, 32bit */
+ case 0x1: /* FCMPZ single, 32bit */
+ gen_helper_vfp_cmps(pstate, tcg_op1_32, tcg_op2_32, cpu_env);
+ break;
+ case 0x2: /* FCMPE single, 32bit */
+ case 0x3: /* FCMPEZ single, 32bit */
+ gen_helper_vfp_cmpes(pstate, tcg_op1_32, tcg_op2_32, cpu_env);
+ break;
+ case 0x4: /* FCMP double, 64bit */
+ case 0x5: /* FCMPZ double, 64bit */
+ gen_helper_vfp_cmpd(pstate, tcg_op1_64, tcg_op2_64, cpu_env);
+ break;
+ case 0x6: /* FCMPE double, 64bit */
+ case 0x7: /* FCMPEZ double, 64bit */
+ gen_helper_vfp_cmped(pstate, tcg_op1_64, tcg_op2_64, cpu_env);
+ break;
+ }
+
+ tcg_temp_free_i64(tcg_op1_64);
+ tcg_temp_free_i64(tcg_op2_64);
+ tcg_temp_free_i32(tcg_op1_32);
+ tcg_temp_free_i32(tcg_op2_32);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2563,6 +2626,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
} else if (get_bits(insn, 21, 1) && !get_bits(insn, 30, 1) &&
!get_bits(insn, 10, 6)) {
handle_fpintconv(s, insn);
+ } else if (!get_bits(insn, 29, 3) && get_bits(insn, 21, 1) &&
+ (get_bits(insn, 10, 6) == 0x8) && !get_bits(insn, 0, 3)) {
+ handle_fcmp(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 54/60] AArch64: Add "Floating-point data-processing (1
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (52 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 53/60] AArch64: Add "Floating-point compare" instruction Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 55/60] " Alexander Graf
` (7 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the "Floating-point data-processing (1 source)"
group of instructions in their 32 bit flavors.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 5 +++
target-arm/helper-a64.h | 1 +
target-arm/translate-a64.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 85 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 0b7aee1..b430823 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -297,3 +297,8 @@ void HELPER(set_rmode)(uint32_t rmode, void *fp_status)
set_float_rounding_mode(rmode, fp_status);
}
+
+float32 HELPER(rints)(float32 x, void *fp_status)
+{
+ return float32_round_to_int(x, fp_status);
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index f42edf8..4dbc56a 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -31,3 +31,4 @@ DEF_HELPER_FLAGS_1(clz64, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_2(umulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(smulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_2(set_rmode, void, i32, ptr)
+DEF_HELPER_FLAGS_2(rints, TCG_CALL_NO_RWG_SE, f32, f32, ptr)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 948e5c4..52ecef4 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2038,6 +2038,82 @@ static void handle_fcmp(DisasContext *s, uint32_t insn)
tcg_temp_free_i32(tcg_op2_32);
}
+/* Floating-point data-processing (1 source) - 32 bit */
+static void handle_fpdp1s32(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int opcode = get_bits(insn, 15, 6);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ TCGv_i64 tcg_tmp = tcg_temp_new_i64();
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
+ TCGv_ptr fpst = get_fpstatus_ptr();
+ bool skip_write = false;
+
+ tcg_gen_ld_i64(tcg_tmp, cpu_env, freg_offs_n);
+ tcg_gen_trunc_i64_i32(tcg_op, tcg_tmp);
+
+ switch (opcode) {
+ case 0x0: /* FMOV */
+ tcg_gen_mov_i32(tcg_res, tcg_op);
+ break;
+ case 0x1: /* FABS */
+ gen_helper_vfp_abss(tcg_res, tcg_op);
+ break;
+ case 0x2: /* FNEG */
+ gen_helper_vfp_negs(tcg_res, tcg_op);
+ break;
+ case 0x3: /* FSQRT */
+ gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
+ break;
+ case 0x5: /* FCVT (single to double) */
+ skip_write = true;
+ gen_helper_vfp_fcvtds(tcg_tmp, tcg_op, cpu_env);
+ clear_fpreg(rd);
+ tcg_gen_st_i64(tcg_tmp, cpu_env, freg_offs_d);
+ break;
+ case 0x7: /* FCVT (single to half) */
+ /* XXX */
+ unallocated_encoding(s);
+ return;
+ case 0x8: /* FRINTN XXX add rounding mode */
+ case 0x9: /* FRINTP */
+ case 0xa: /* FRINTM */
+ case 0xb: /* FRINTZ */
+ case 0xc: /* FRINTA */
+ case 0xe: /* FRINTX */
+ case 0xf: /* FRINTI */
+ {
+ TCGv_i32 tcg_rmode = tcg_const_i32(opcode & 7);
+
+ gen_helper_set_rmode(tcg_rmode, fpst);
+ gen_helper_rints(tcg_res, tcg_op, fpst);
+
+ /* XXX use fpcr */
+ tcg_gen_movi_i32(tcg_rmode, -1);
+ gen_helper_set_rmode(tcg_rmode, fpst);
+ tcg_temp_free_i32(tcg_rmode);
+ break;
+ }
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ if (!skip_write) {
+ clear_fpreg(rd);
+ tcg_gen_ext32u_i64(tcg_tmp, tcg_res);
+ tcg_gen_st32_i64(tcg_tmp, cpu_env, freg_offs_d);
+ }
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i32(tcg_op);
+ tcg_temp_free_i32(tcg_res);
+ tcg_temp_free_i64(tcg_tmp);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2629,6 +2705,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
} else if (!get_bits(insn, 29, 3) && get_bits(insn, 21, 1) &&
(get_bits(insn, 10, 6) == 0x8) && !get_bits(insn, 0, 3)) {
handle_fcmp(s, insn);
+ } else if (!get_bits(insn, 29, 3) && !get_bits(insn, 22, 2) &&
+ get_bits(insn, 21, 1) && (get_bits(insn, 10, 5) == 0x10)) {
+ handle_fpdp1s32(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 55/60] AArch64: Add "Floating-point data-processing (1
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (53 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 54/60] AArch64: Add "Floating-point data-processing (1 Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 56/60] AArch64: Add "Floating-point data-processing (2 Alexander Graf
` (6 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the "Floating-point data-processing (1 source)"
group of instructions in their 64 bit flavors.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/helper-a64.c | 5 ++++
target-arm/helper-a64.h | 1 +
target-arm/translate-a64.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 75 insertions(+)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index b430823..562d147 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -302,3 +302,8 @@ float32 HELPER(rints)(float32 x, void *fp_status)
{
return float32_round_to_int(x, fp_status);
}
+
+float64 HELPER(rintd)(float64 x, void *fp_status)
+{
+ return float64_round_to_int(x, fp_status);
+}
diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
index 4dbc56a..b22cae8 100644
--- a/target-arm/helper-a64.h
+++ b/target-arm/helper-a64.h
@@ -32,3 +32,4 @@ DEF_HELPER_FLAGS_2(umulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_FLAGS_2(smulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
DEF_HELPER_2(set_rmode, void, i32, ptr)
DEF_HELPER_FLAGS_2(rints, TCG_CALL_NO_RWG_SE, f32, f32, ptr)
+DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG_SE, f64, f64, ptr)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 52ecef4..1f3f4f5 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2114,6 +2114,72 @@ static void handle_fpdp1s32(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_tmp);
}
+/* Floating-point data-processing (1 source) - 64 bit */
+static void handle_fpdp1s64(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int opcode = get_bits(insn, 15, 6);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ TCGv_i64 tcg_op = tcg_temp_new_i64();
+ TCGv_i64 tcg_res = tcg_temp_new_i64();
+ TCGv_ptr fpst = get_fpstatus_ptr();
+
+ tcg_gen_ld_i64(tcg_op, cpu_env, freg_offs_n);
+
+ switch (opcode) {
+ case 0x0: /* FMOV */
+ tcg_gen_mov_i64(tcg_res, tcg_op);
+ break;
+ case 0x1: /* FABS */
+ gen_helper_vfp_absd(tcg_res, tcg_op);
+ break;
+ case 0x2: /* FNEG */
+ gen_helper_vfp_negd(tcg_res, tcg_op);
+ break;
+ case 0x3: /* FSQRT */
+ gen_helper_vfp_sqrtd(tcg_res, tcg_op, cpu_env);
+ break;
+ case 0x4: /* FCVT (double to single) */
+ gen_helper_vfp_fcvtsd(tcg_res, tcg_op, cpu_env);
+ break;
+ case 0x7: /* FCVT (double to half) */
+ /* XXX */
+ unallocated_encoding(s);
+ return;
+ case 0x8: /* FRINTN XXX add rounding mode */
+ case 0x9: /* FRINTP */
+ case 0xa: /* FRINTM */
+ case 0xb: /* FRINTZ */
+ case 0xc: /* FRINTA */
+ case 0xe: /* FRINTX */
+ case 0xf: /* FRINTI */
+ {
+ TCGv_i32 tcg_rmode = tcg_const_i32(opcode & 7);
+
+ gen_helper_set_rmode(tcg_rmode, fpst);
+ gen_helper_rintd(tcg_res, tcg_op, fpst);
+
+ /* XXX use fpcr */
+ tcg_gen_movi_i32(tcg_rmode, -1);
+ gen_helper_set_rmode(tcg_rmode, fpst);
+ tcg_temp_free_i32(tcg_rmode);
+ break;
+ }
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ clear_fpreg(rd);
+ tcg_gen_st_i64(tcg_res, cpu_env, freg_offs_d);
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i64(tcg_op);
+ tcg_temp_free_i64(tcg_res);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2708,6 +2774,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
} else if (!get_bits(insn, 29, 3) && !get_bits(insn, 22, 2) &&
get_bits(insn, 21, 1) && (get_bits(insn, 10, 5) == 0x10)) {
handle_fpdp1s32(s, insn);
+ } else if (!get_bits(insn, 29, 3) && (get_bits(insn, 22, 2) == 0x1) &&
+ get_bits(insn, 21, 1) && (get_bits(insn, 10, 5) == 0x10)) {
+ handle_fpdp1s64(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 56/60] AArch64: Add "Floating-point data-processing (2
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (54 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 55/60] " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 57/60] " Alexander Graf
` (5 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the "Floating-point data-processing (2 source)"
group of instructions in their 32 bit flavors.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 1f3f4f5..5b2232b 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2180,6 +2180,60 @@ static void handle_fpdp1s64(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_res);
}
+/* Floating-point data-processing (2 source) - 32 bit */
+static void handle_fpdp2s32(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int opcode = get_bits(insn, 12, 4);
+ int rm = get_bits(insn, 16, 5);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int freg_offs_m = offsetof(CPUARMState, vfp.regs[rm * 2]);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ TCGv_i64 tcg_tmp = tcg_temp_new_i64();
+ TCGv_i32 tcg_op1 = tcg_temp_new_i32();
+ TCGv_i32 tcg_op2 = tcg_temp_new_i32();
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
+ TCGv_ptr fpst = get_fpstatus_ptr();
+
+ tcg_gen_ld_i64(tcg_tmp, cpu_env, freg_offs_n);
+ tcg_gen_trunc_i64_i32(tcg_op1, tcg_tmp);
+ tcg_gen_ld_i64(tcg_tmp, cpu_env, freg_offs_m);
+ tcg_gen_trunc_i64_i32(tcg_op2, tcg_tmp);
+
+ switch (opcode) {
+ case 0x0: /* FMUL */
+ gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x8: /* FNMUL */
+ gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
+ gen_helper_vfp_negs(tcg_res, tcg_res);
+ break;
+ case 0x1: /* FDIV */
+ gen_helper_vfp_divs(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x2: /* FADD */
+ gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x3: /* FSUB */
+ gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ clear_fpreg(rd);
+ tcg_gen_ext32u_i64(tcg_tmp, tcg_res);
+ tcg_gen_st32_i64(tcg_tmp, cpu_env, freg_offs_d);
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i32(tcg_op1);
+ tcg_temp_free_i32(tcg_op2);
+ tcg_temp_free_i32(tcg_res);
+ tcg_temp_free_i64(tcg_tmp);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2777,6 +2831,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
} else if (!get_bits(insn, 29, 3) && (get_bits(insn, 22, 2) == 0x1) &&
get_bits(insn, 21, 1) && (get_bits(insn, 10, 5) == 0x10)) {
handle_fpdp1s64(s, insn);
+ } else if (!get_bits(insn, 29, 3) && !get_bits(insn, 22, 2) &&
+ get_bits(insn, 21, 1) && (get_bits(insn, 10, 2) == 0x2)) {
+ handle_fpdp2s32(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 57/60] AArch64: Add "Floating-point data-processing (2
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (55 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 56/60] AArch64: Add "Floating-point data-processing (2 Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 58/60] AArch64: Add "ADD (vector)" instruction emulation Alexander Graf
` (4 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the "Floating-point data-processing (2 source)"
group of instructions in their 64 bit flavors.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 5b2232b..a7b5be1 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2234,6 +2234,55 @@ static void handle_fpdp2s32(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_tmp);
}
+/* Floating-point data-processing (2 source) - 64 bit */
+static void handle_fpdp2s64(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int rm = get_bits(insn, 16, 5);
+ int opcode = get_bits(insn, 12, 4);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int freg_offs_m = offsetof(CPUARMState, vfp.regs[rm * 2]);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ TCGv_i64 tcg_op1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op2 = tcg_temp_new_i64();
+ TCGv_i64 tcg_res = tcg_temp_new_i64();
+ TCGv_ptr fpst = get_fpstatus_ptr();
+
+ tcg_gen_ld_i64(tcg_op1, cpu_env, freg_offs_n);
+ tcg_gen_ld_i64(tcg_op2, cpu_env, freg_offs_m);
+
+ switch (opcode) {
+ case 0x0: /* FMUL */
+ gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x8: /* FNMUL */
+ gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
+ gen_helper_vfp_negd(tcg_res, tcg_res);
+ break;
+ case 0x1: /* FDIV */
+ gen_helper_vfp_divd(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x2: /* FADD */
+ gen_helper_vfp_addd(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ case 0x3: /* FSUB */
+ gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst);
+ break;
+ default:
+ unallocated_encoding(s);
+ return;
+ }
+
+ clear_fpreg(rd);
+ tcg_gen_st_i64(tcg_res, cpu_env, freg_offs_d);
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i64(tcg_op1);
+ tcg_temp_free_i64(tcg_op2);
+ tcg_temp_free_i64(tcg_res);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2834,6 +2883,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
} else if (!get_bits(insn, 29, 3) && !get_bits(insn, 22, 2) &&
get_bits(insn, 21, 1) && (get_bits(insn, 10, 2) == 0x2)) {
handle_fpdp2s32(s, insn);
+ } else if (!get_bits(insn, 29, 3) && (get_bits(insn, 22, 2) == 0x1) &&
+ get_bits(insn, 21, 1) && (get_bits(insn, 10, 2) == 0x2)) {
+ handle_fpdp2s64(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 58/60] AArch64: Add "ADD (vector)" instruction emulation
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (56 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 57/60] " Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 59/60] AArch64: Add "Floating-point data-processing (3 Alexander Graf
` (3 subsequent siblings)
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds support for the "ADD (vector)" instruction which is part
of the "AdvSIMD scalar three same" group.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index a7b5be1..e21bbcb 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2612,6 +2612,38 @@ static void handle_simdshl(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_tmp);
}
+/* AdvSIMD scalar three same, ADD (vector) */
+static void handle_v3add(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int rm = get_bits(insn, 16, 5);
+ int size = get_bits(insn, 22, 2);
+ bool is_sub = get_bits(insn, 29, 1);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int freg_offs_m = offsetof(CPUARMState, vfp.regs[rm * 2]);
+ TCGv_i64 tcg_op1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op2 = tcg_temp_new_i64();
+ TCGv_i64 tcg_res = tcg_temp_new_i64();
+
+ simd_ld(tcg_op1, freg_offs_n, size);
+ simd_ld(tcg_op2, freg_offs_m, size);
+
+ if (is_sub) {
+ tcg_gen_sub_i64(tcg_res, tcg_op1, tcg_op2);
+ } else {
+ tcg_gen_add_i64(tcg_res, tcg_op1, tcg_op2);
+ }
+
+ clear_fpreg(rd);
+ simd_st(tcg_res, freg_offs_d, size);
+
+ tcg_temp_free_i64(tcg_op1);
+ tcg_temp_free_i64(tcg_op2);
+ tcg_temp_free_i64(tcg_res);
+}
+
static void handle_svc(DisasContext *s, uint32_t insn)
{
gen_a64_set_pc_im(s->pc);
@@ -2886,6 +2918,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
} else if (!get_bits(insn, 29, 3) && (get_bits(insn, 22, 2) == 0x1) &&
get_bits(insn, 21, 1) && (get_bits(insn, 10, 2) == 0x2)) {
handle_fpdp2s64(s, insn);
+ } else if ((get_bits(insn, 30, 2) == 0x1) && get_bits(insn, 21, 1) &&
+ (get_bits(insn, 10, 6) == 0x21)) {
+ handle_v3add(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 59/60] AArch64: Add "Floating-point data-processing (3
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (57 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 58/60] AArch64: Add "ADD (vector)" instruction emulation Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 21:34 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 60/60] " Alexander Graf
` (2 subsequent siblings)
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the "Floating-point data-processing (3 source)"
group of instructions in their 32 bit flavors.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index e21bbcb..b5a0359 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2283,6 +2283,57 @@ static void handle_fpdp2s64(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_res);
}
+/* Floating-point data-processing (3 source) - 32 bit */
+static void handle_fpdp3s32(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int ra = get_bits(insn, 10, 5);
+ bool is_sub = get_bits(insn, 15, 1);
+ int rm = get_bits(insn, 16, 5);
+ bool is_neg = get_bits(insn, 21, 1);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int freg_offs_a = offsetof(CPUARMState, vfp.regs[ra * 2]);
+ int freg_offs_m = offsetof(CPUARMState, vfp.regs[rm * 2]);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ TCGv_i64 tcg_tmp = tcg_temp_new_i64();
+ TCGv_i32 tcg_op1 = tcg_temp_new_i32();
+ TCGv_i32 tcg_op2 = tcg_temp_new_i32();
+ TCGv_i32 tcg_op3 = tcg_temp_new_i32();
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
+ TCGv_ptr fpst = get_fpstatus_ptr();
+
+ tcg_gen_ld_i64(tcg_tmp, cpu_env, freg_offs_n);
+ tcg_gen_trunc_i64_i32(tcg_op1, tcg_tmp);
+ tcg_gen_ld_i64(tcg_tmp, cpu_env, freg_offs_m);
+ tcg_gen_trunc_i64_i32(tcg_op2, tcg_tmp);
+ tcg_gen_ld_i64(tcg_tmp, cpu_env, freg_offs_a);
+ tcg_gen_trunc_i64_i32(tcg_op3, tcg_tmp);
+
+ if (is_neg) {
+ gen_helper_vfp_negs(tcg_op1, tcg_op1);
+ gen_helper_vfp_negs(tcg_op3, tcg_op3);
+ }
+
+ gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
+ if (is_sub) {
+ gen_helper_vfp_subs(tcg_res, tcg_op3, tcg_res, fpst);
+ } else {
+ gen_helper_vfp_adds(tcg_res, tcg_op3, tcg_res, fpst);
+ }
+
+ clear_fpreg(rd);
+ tcg_gen_ext32u_i64(tcg_tmp, tcg_res);
+ tcg_gen_st32_i64(tcg_tmp, cpu_env, freg_offs_d);
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i32(tcg_op1);
+ tcg_temp_free_i32(tcg_op2);
+ tcg_temp_free_i32(tcg_op3);
+ tcg_temp_free_i32(tcg_res);
+ tcg_temp_free_i64(tcg_tmp);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2925,6 +2976,13 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
unallocated_encoding(s);
}
break;
+ case 0x1f:
+ if (!get_bits(insn, 29, 3) && !get_bits(insn, 22, 2)) {
+ handle_fpdp3s32(s, insn);
+ } else {
+ unallocated_encoding(s);
+ }
+ break;
default:
unallocated_encoding(s);
break;
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* [Qemu-devel] [PATCH 60/60] AArch64: Add "Floating-point data-processing (3
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (58 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 59/60] AArch64: Add "Floating-point data-processing (3 Alexander Graf
@ 2013-09-27 0:48 ` Alexander Graf
2013-09-27 1:02 ` [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
2013-10-16 19:54 ` Edgar E. Iglesias
61 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 0:48 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
This patch adds emulation for the "Floating-point data-processing (3 source)"
group of instructions in their 64 bit flavors.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
target-arm/translate-a64.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index b5a0359..8e7430b 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -2334,6 +2334,50 @@ static void handle_fpdp3s32(DisasContext *s, uint32_t insn)
tcg_temp_free_i64(tcg_tmp);
}
+static void handle_fpdp3s64(DisasContext *s, uint32_t insn)
+{
+ int rd = get_bits(insn, 0, 5);
+ int rn = get_bits(insn, 5, 5);
+ int ra = get_bits(insn, 10, 5);
+ int rm = get_bits(insn, 16, 5);
+ bool is_neg = get_bits(insn, 21, 1);
+ bool is_sub = get_bits(insn, 15, 1);
+ int freg_offs_n = offsetof(CPUARMState, vfp.regs[rn * 2]);
+ int freg_offs_a = offsetof(CPUARMState, vfp.regs[ra * 2]);
+ int freg_offs_m = offsetof(CPUARMState, vfp.regs[rm * 2]);
+ int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
+ TCGv_i64 tcg_op1 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op2 = tcg_temp_new_i64();
+ TCGv_i64 tcg_op3 = tcg_temp_new_i64();
+ TCGv_i64 tcg_res = tcg_temp_new_i64();
+ TCGv_ptr fpst = get_fpstatus_ptr();
+
+ tcg_gen_ld_i64(tcg_op1, cpu_env, freg_offs_n);
+ tcg_gen_ld_i64(tcg_op2, cpu_env, freg_offs_m);
+ tcg_gen_ld_i64(tcg_op3, cpu_env, freg_offs_a);
+
+ if (is_neg) {
+ gen_helper_vfp_negd(tcg_op1, tcg_op1);
+ gen_helper_vfp_negd(tcg_op3, tcg_op3);
+ }
+
+ gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
+ if (is_sub) {
+ gen_helper_vfp_subd(tcg_res, tcg_op3, tcg_res, fpst);
+ } else {
+ gen_helper_vfp_addd(tcg_res, tcg_op3, tcg_res, fpst);
+ }
+
+ clear_fpreg(rd);
+ tcg_gen_st_i64(tcg_res, cpu_env, freg_offs_d);
+
+ tcg_temp_free_ptr(fpst);
+ tcg_temp_free_i64(tcg_op1);
+ tcg_temp_free_i64(tcg_op2);
+ tcg_temp_free_i64(tcg_op3);
+ tcg_temp_free_i64(tcg_res);
+}
+
/* SIMD ORR */
static void handle_simdorr(DisasContext *s, uint32_t insn)
{
@@ -2979,6 +3023,8 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
case 0x1f:
if (!get_bits(insn, 29, 3) && !get_bits(insn, 22, 2)) {
handle_fpdp3s32(s, insn);
+ } else if (!get_bits(insn, 29, 3) && (get_bits(insn, 22, 2) == 0x1)) {
+ handle_fpdp3s64(s, insn);
} else {
unallocated_encoding(s);
}
--
1.7.12.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (59 preceding siblings ...)
2013-09-27 0:48 ` [Qemu-devel] [PATCH 60/60] " Alexander Graf
@ 2013-09-27 1:02 ` Alexander Graf
2013-09-27 2:30 ` Peter Maydell
2013-10-16 19:54 ` Edgar E. Iglesias
61 siblings, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 1:02 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Michael Matz, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On 27.09.2013, at 02:47, Alexander Graf wrote:
> Howdy,
>
> This is the first batch of patches to implement AArch64 instruction
> emulation in QEMU. It implements enough to execute simple AArch64
> programs in linux-user mode.
Ah, one important thing I forgot to mention is that this patch set is based on Peter Maydell's aarch64 branch.
Also, if you'd just like to give this a go without messing with patch applying, here's a git branch that contains all 60 patches on top of Peter's aarch64 branch:
git://github.com/agraf/qemu.git aarch64-tcg-batch1-v1
Alex
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support
2013-09-27 1:02 ` [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
@ 2013-09-27 2:30 ` Peter Maydell
2013-09-27 10:39 ` Alexander Graf
0 siblings, 1 reply; 115+ messages in thread
From: Peter Maydell @ 2013-09-27 2:30 UTC (permalink / raw)
To: Alexander Graf
Cc: Michael Matz, QEMU Developers, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On 27 September 2013 10:02, Alexander Graf <agraf@suse.de> wrote:
> On 27.09.2013, at 02:47, Alexander Graf wrote:
>> This is the first batch of patches to implement AArch64 instruction
>> emulation in QEMU. It implements enough to execute simple AArch64
>> programs in linux-user mode.
>
> Ah, one important thing I forgot to mention is that this patch set is based
> on Peter Maydell's aarch64 branch
What's not in mainline that you need? I committed the preparation-patchset
so your tcg patches wouldn't need to depend on not-in-mainline stuff...
-- PMM
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 09/60] AArch64: Add b and bl handling
2013-09-27 0:48 ` [Qemu-devel] [PATCH 09/60] AArch64: Add b and bl handling Alexander Graf
@ 2013-09-27 9:11 ` Claudio Fontana
2013-09-27 14:40 ` Richard Henderson
1 sibling, 0 replies; 115+ messages in thread
From: Claudio Fontana @ 2013-09-27 9:11 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
Hi Alex,
On 09/27/13 02:48, Alexander Graf wrote:
> This adds handling for the b and bl instructions.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
> target-arm/translate-a64.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 61 insertions(+)
>
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index 73ccade..267fd4d 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -133,6 +133,58 @@ static void real_unallocated_encoding(DisasContext *s)
> real_unallocated_encoding(s); \
> } while (0)
>
> +static int get_bits(uint32_t inst, int start, int len)
> +{
> + return (inst >> start) & ((1 << len) - 1);
> +}
> +
do you think it makes sense to reuse extract32 from bitops here?
> +static int get_sbits(uint32_t inst, int start, int len)
> +{
> + int r = get_bits(inst, start, len);
> + if (r & (1 << (len - 1))) {
> + /* Extend the MSB 1 to the higher bits */
> + r |= -1 & ~((1ULL << len) - 1);
> + }
> + return r;
> +}
> +
sextract32?
> +static TCGv_i64 cpu_reg(int reg)
> +{
> + if (reg == 31) {
> + /* XXX leaks temps */
> + return tcg_const_i64(0);
...
> + } else {
> + return cpu_X[reg];
> + }
> +}
> +
> +static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
> +{
> + TranslationBlock *tb;
> +
> + tb = s->tb;
> + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
> + tcg_gen_goto_tb(n);
> + gen_a64_set_pc_im(dest);
> + tcg_gen_exit_tb((tcg_target_long)tb + n);
> + } else {
> + gen_a64_set_pc_im(dest);
> + tcg_gen_exit_tb(0);
> + }
> +}
> +
> +static void handle_b(DisasContext *s, uint32_t insn)
> +{
> + uint64_t addr = s->pc - 4 + (get_sbits(insn, 0, 26) << 2);
> +
> + if (get_bits(insn, 31, 1)) {
> + /* BL */
> + tcg_gen_movi_i64(cpu_reg(30), s->pc);
> + }
> + gen_goto_tb(s, 0, addr);
> + s->is_jmp = DISAS_TB_JUMP;
> +}
> +
> void disas_a64_insn(CPUARMState *env, DisasContext *s)
> {
> uint32_t insn;
> @@ -141,12 +193,21 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
> s->insn = insn;
> s->pc += 4;
>
> + /* One-off branch instruction layout */
> + switch (insn >> 26) {
> + case 0x25:
> + case 0x5:
> + handle_b(s, insn);
> + goto insn_done;
> + }
> +
> switch ((insn >> 24) & 0x1f) {
> default:
> unallocated_encoding(s);
> break;
> }
>
> +insn_done:
> if (unlikely(s->singlestep_enabled) && (s->is_jmp == DISAS_TB_JUMP)) {
> /* go through the main loop for single step */
> s->is_jmp = DISAS_JUMP;
>
Ciao,
Claudio
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support
2013-09-27 2:30 ` Peter Maydell
@ 2013-09-27 10:39 ` Alexander Graf
0 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-09-27 10:39 UTC (permalink / raw)
To: Peter Maydell
Cc: Michael Matz, QEMU Developers, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On 27.09.2013, at 04:30, Peter Maydell wrote:
> On 27 September 2013 10:02, Alexander Graf <agraf@suse.de> wrote:
>> On 27.09.2013, at 02:47, Alexander Graf wrote:
>>> This is the first batch of patches to implement AArch64 instruction
>>> emulation in QEMU. It implements enough to execute simple AArch64
>>> programs in linux-user mode.
>>
>> Ah, one important thing I forgot to mention is that this patch set is based
>> on Peter Maydell's aarch64 branch
>
> What's not in mainline that you need? I committed the preparation-patchset
> so your tcg patches wouldn't need to depend on not-in-mainline stuff...
You're right. I had a stale tree registered as "origin" and didn't realize it :). I've rebased the patches on top of upstream/master now (which was conflict free) keeping the "linux-user .mak" patch from you in. I also fixed a few TCGv i32/64/ptr hickups that were still left in the tree.
Considering the minimal amount of changes this incurred, I will refrain from reposting a giant 60-patches patch set and instead just pushed it to a new branch on github:
git://github.com/agraf/qemu.git aarch64-tcg-batch1-v2
In a nutshell the changes from v1 -> v2 are:
New: 0001-default-configs-Add-config-for-aarch64-linux-user.patch
0016-AArch64-Add-add-instruction-family-emulation.patch:v1 -> v2:
0016-AArch64-Add-add-instruction-family-emulation.patch-
0016-AArch64-Add-add-instruction-family-emulation.patch- - Fix TCG i32/i64 misusage for pstate
--
0051-AArch64-Add-Floating-point-fixed-point-conversions-c.patch:v1 -> v2:
0051-AArch64-Add-Floating-point-fixed-point-conversions-c.patch-
0051-AArch64-Add-Floating-point-fixed-point-conversions-c.patch- - use TCGv_ptr for fpstatus
0051-AArch64-Add-Floating-point-fixed-point-conversions-c.patch- - use TCGv_i32 for single temporary
--
0054-AArch64-Add-Floating-point-compare-instruction-famil.patch:v1 -> v2:
0054-AArch64-Add-Floating-point-compare-instruction-famil.patch-
0054-AArch64-Add-Floating-point-compare-instruction-famil.patch- - Use TCGv_i64 for 64bit variables
--
0055-AArch64-Add-Floating-point-data-processing-1-source-.patch:v1 -> v2:
0055-AArch64-Add-Floating-point-data-processing-1-source-.patch-
0055-AArch64-Add-Floating-point-data-processing-1-source-.patch- - Fix i32/i64 misusage on extu
--
0056-AArch64-Add-Floating-point-data-processing-1-source-.patch:v1 -> v2:
0056-AArch64-Add-Floating-point-data-processing-1-source-.patch-
0056-AArch64-Add-Floating-point-data-processing-1-source-.patch- - Fix TCGv i32/i64 misusage
--
0057-AArch64-Add-Floating-point-data-processing-2-source-.patch:v1 -> v2:
0057-AArch64-Add-Floating-point-data-processing-2-source-.patch-
0057-AArch64-Add-Floating-point-data-processing-2-source-.patch- - Fix i32/i64 misusage on extu
--
0060-AArch64-Add-Floating-point-data-processing-3-source-.patch:v1 -> v2:
0060-AArch64-Add-Floating-point-data-processing-3-source-.patch-
0060-AArch64-Add-Floating-point-data-processing-3-source-.patch- - Fix i32/i64 misusage on extu
Alex
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 03/60] arm: Split VFP cmp from FPSCR setting
2013-09-27 0:47 ` [Qemu-devel] [PATCH 03/60] arm: Split VFP cmp from FPSCR setting Alexander Graf
@ 2013-09-27 14:05 ` Richard Henderson
2013-09-27 22:38 ` Richard Henderson
0 siblings, 1 reply; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 14:05 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:47 PM, Alexander Graf wrote:
> -DEF_HELPER_3(vfp_cmps, void, f32, f32, env)
> -DEF_HELPER_3(vfp_cmpd, void, f64, f64, env)
> -DEF_HELPER_3(vfp_cmpes, void, f32, f32, env)
> -DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
> +DEF_HELPER_3(vfp_fpscr_cmps, void, f32, f32, env)
> +DEF_HELPER_3(vfp_fpscr_cmpd, void, f64, f64, env)
> +DEF_HELPER_3(vfp_fpscr_cmpes, void, f32, f32, env)
> +DEF_HELPER_3(vfp_fpscr_cmped, void, f64, f64, env)
> +DEF_HELPER_3(vfp_cmps, i32, f32, f32, env)
> +DEF_HELPER_3(vfp_cmpd, i32, f64, f64, env)
> +DEF_HELPER_3(vfp_cmpes, i32, f32, f32, env)
> +DEF_HELPER_3(vfp_cmped, i32, f64, f64, env)
While you're changing these, please change them to use DEF_HELPER_FLAGS_*.
For the fpscr helpers, TCG_CALL_NO_RWG (since they have the side effect of
setting the fpscr); for the new helpers, TCG_CALL_NO_RWG_SE since there are
no side effects at all.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 04/60] arm: Add AArch64 disassembler stub
2013-09-27 0:47 ` [Qemu-devel] [PATCH 04/60] arm: Add AArch64 disassembler stub Alexander Graf
@ 2013-09-27 14:07 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 14:07 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:47 PM, Alexander Graf wrote:
> While we don't have a working disassembler for AArch64 yet, we still
> don't want AArch64 code be disassembled through the old AArch32
> disassembler.
>
> So add a small disassembler stub that declares every instruction as
> unsupported. This should be a good enough base to plug in a real one
> later.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
Relic from before print_insn_objdump?
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 09/60] AArch64: Add b and bl handling
2013-09-27 0:48 ` [Qemu-devel] [PATCH 09/60] AArch64: Add b and bl handling Alexander Graf
2013-09-27 9:11 ` Claudio Fontana
@ 2013-09-27 14:40 ` Richard Henderson
1 sibling, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 14:40 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> +static int get_bits(uint32_t inst, int start, int len)
> +{
> + return (inst >> start) & ((1 << len) - 1);
> +}
> +
> +static int get_sbits(uint32_t inst, int start, int len)
> +{
> + int r = get_bits(inst, start, len);
> + if (r & (1 << (len - 1))) {
> + /* Extend the MSB 1 to the higher bits */
> + r |= -1 & ~((1ULL << len) - 1);
> + }
> + return r;
> +}
extract32 and sextract32 please.
> +static TCGv_i64 cpu_reg(int reg)
> +{
> + if (reg == 31) {
> + /* XXX leaks temps */
> + return tcg_const_i64(0);
> + } else {
> + return cpu_X[reg];
> + }
> +}
See how we treat temporaries in the sparc translator.
We record them in the DisasContext to be freed at the
end of the insn.
> + tb = s->tb;
> + if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
Not the only conditions you need to check. In
particular, no single-stepping or tb->flags & CF_LAST_IO.
C.f. target-alpha's use_goto_tb function.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 10/60] AArch64: Add handling for br instructions
2013-09-27 0:48 ` [Qemu-devel] [PATCH 10/60] AArch64: Add handling for br instructions Alexander Graf
@ 2013-09-27 14:51 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 14:51 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> +static void handle_br(DisasContext *s, uint32_t insn)
> +{
> + int branch_type = get_bits(insn, 21, 2);
> + int source = get_bits(insn, 5, 5);
> +
> + switch (branch_type) {
> + case 0: /* JMP */
> + break;
> + case 1: /* CALL */
> + tcg_gen_movi_i64(cpu_reg(30), s->pc);
> + break;
> + case 2: /* RET */
> + source = 30;
> + break;
This is incorrect. One can RET from any register; the only difference between
JMP and RET is a branch prediction hint irrelevant to QEMU.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 11/60] AArch64: Add STP instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 11/60] AArch64: Add STP instruction emulation Alexander Graf
@ 2013-09-27 17:38 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 17:38 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> +static int get_reg(uint32_t inst)
> +{
> + return get_bits(inst, 0, 5);
> +}
Surely get_rt or some such related to the actual field name, not something
so generic as "reg" which applies equally to any of several fields.
> +static void ldst_do_vec(DisasContext *s, int dest, TCGv_i64 tcg_addr_real,
> + int size, bool is_store)
> +{
> + TCGv_i64 tcg_addr = tcg_temp_new_i64();
> + int freg_offs = offsetof(CPUARMState, vfp.regs[dest * 2]);
> +
> + /* we don't want to modify the caller's tcg_addr */
> + tcg_gen_mov_i64(tcg_addr, tcg_addr_real);
Surely merge with ldst_do_vec_int, for the single case of 16 byte size?
> +
> + if (!is_store) {
> + /* normal ldst clears non-loaded bits */
> + clear_fpreg(dest);
> + }
Surely merge with ldst_do_vec_int, to avoid redundant stores into the
vfp register set?
> +static void handle_stp(DisasContext *s, uint32_t insn)
> +{
This handles both ldp and stp though, right?
> + ldst_do(s, rt, tcg_addr, size, is_store, is_signed, is_vector);
> + tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);
> + ldst_do(s, rt2, tcg_addr, size, is_store, is_signed, is_vector);
> + tcg_gen_subi_i64(tcg_addr, tcg_addr, 1 << size);
Why subtract instead of using another temporary?
> + /* Typical major opcode encoding */
> switch ((insn >> 24) & 0x1f) {
> + case 0x08:
> + case 0x09:
> + if (get_bits(insn, 29, 1)) {
> + handle_stp(s, insn);
> + } else {
> + unallocated_encoding(s);
> + }
> + break;
> + case 0x0c:
> + if (get_bits(insn, 29, 1)) {
> + handle_stp(s, insn);
> + } else {
> + unallocated_encoding(s);
> + }
> + break;
> + case 0x0d:
> + if (get_bits(insn, 29, 1)) {
> + handle_stp(s, insn);
> + } else {
> + unallocated_encoding(s);
> + }
> + break;
This leads me to believe that this isn't the best arrangement of the decoder.
I would expect the structure to look more like the arrangement in chapter C3,
especially the major encoding groups in table C3-1.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation Alexander Graf
@ 2013-09-27 18:25 ` Richard Henderson
2013-10-31 0:29 ` Alexander Graf
2013-11-18 10:15 ` Claudio Fontana
0 siblings, 2 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 18:25 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> This patch adds emulation support for the orr instruction.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
> target-arm/helper-a64.c | 28 +++++++++++
> target-arm/helper-a64.h | 1 +
> target-arm/translate-a64.c | 120 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 149 insertions(+)
>
> diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
> index 8105fb5..da72b7f 100644
> --- a/target-arm/helper-a64.c
> +++ b/target-arm/helper-a64.c
> @@ -24,3 +24,31 @@
> #include "sysemu/sysemu.h"
> #include "qemu/bitops.h"
>
> +uint32_t HELPER(pstate_add)(uint32_t pstate, uint64_t a1, uint64_t a2,
> + uint64_t ar)
> +{
> + int64_t s1 = a1;
> + int64_t s2 = a2;
> + int64_t sr = ar;
> +
> + pstate &= ~(PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V);
> +
> + if (sr < 0) {
> + pstate |= PSTATE_N;
> + }
> +
> + if (!ar) {
> + pstate |= PSTATE_Z;
> + }
> +
> + if (ar && (ar < a1)) {
> + pstate |= PSTATE_C;
> + }
> +
> + if ((s1 > 0 && s2 > 0 && sr < 0) ||
> + (s1 < 0 && s2 < 0 && sr > 0)) {
> + pstate |= PSTATE_V;
> + }
> +
> + return pstate;
> +}
Why are you not using the same split apart bits as A32?
> + /* XXX carry_out */
> + switch (shift_type) {
What carry out? I see no such in the ShiftReg description.
> + case 3:
> + tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
> + break;
Incorrect rotate for 32bit?
> +static void handle_orr(DisasContext *s, uint32_t insn)
> +{
> + int is_32bit = !get_bits(insn, 31, 1);
> + int dest = get_reg(insn);
> + int source = get_bits(insn, 5, 5);
> + int rm = get_bits(insn, 16, 5);
> + int shift_amount = get_sbits(insn, 10, 6);
> + int is_n = get_bits(insn, 21, 1);
> + int shift_type = get_bits(insn, 22, 2);
> + int opc = get_bits(insn, 29, 2);
> + bool setflags = (opc == 0x3);
> + TCGv_i64 tcg_op2;
> + TCGv_i64 tcg_dest;
> +
> + if (is_32bit && (shift_amount < 0)) {
> + /* reserved value */
> + unallocated_encoding(s);
> + }
Why are you extracting shift_amount signed?
> +
> + /* MOV is dest = xzr & (source & ~0) */
Comment is wrong.
> + if (!shift_amount && source == 0x1f) {
> + if (is_32bit) {
> + tcg_gen_ext32u_i64(cpu_reg_sp(dest), cpu_reg(rm));
> + } else {
> + tcg_gen_mov_i64(cpu_reg_sp(dest), cpu_reg(rm));
> + }
> + if (is_n) {
> + tcg_gen_not_i64(cpu_reg_sp(dest), cpu_reg_sp(dest));
> + }
> + if (is_32bit) {
> + tcg_gen_ext32u_i64(cpu_reg_sp(dest), cpu_reg_sp(dest));
> + }
These are incorrect -- no sp in the logical ops, but xzr instead.
And surely we can emit fewer opcodes for the simple cases here.
Since these are the canonical aliases for mov/mvn, it'll pay off.
TCGv src = cpu_reg(rm);
TCGv dst = cpu_reg(rd);
if (is_n) {
tcg_gen_not_i64(dst, src);
src = dst;
}
if (is_32bit) {
tcg_gen_ext32u_i64(dst, src);
} else {
tcg_gen_mov_i64(dst, src);
}
Note that tcg_gen_mov_i64 does the src == dst check, so a simple
64-bit mvn will only emit the not.
> + tcg_dest = cpu_reg(dest);
> + switch (opc) {
> + case 0x0:
> + case 0x3:
> + tcg_gen_and_i64(tcg_dest, cpu_reg(source), tcg_op2);
> + break;
> + case 0x1:
> + tcg_gen_or_i64(tcg_dest, cpu_reg(source), tcg_op2);
> + break;
> + case 0x2:
> + tcg_gen_xor_i64(tcg_dest, cpu_reg(source), tcg_op2);
> + break;
> + }
> +
> + if (is_32bit) {
> + tcg_gen_ext32u_i64(tcg_dest, tcg_dest);
> + }
> +
> + if (setflags) {
> + gen_helper_pstate_add(pstate, pstate, tcg_dest, cpu_reg(31), tcg_dest);
> + }
Incorrect flags generated. They're different between add/sub and logical.
In particular, C and V are always zero.
> + handle_orr(s, insn);
And please use a more proper name than ORR for something that handles all
of the logical insns.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 15/60] AArch64: Add add instruction family emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 15/60] AArch64: Add add instruction family emulation Alexander Graf
@ 2013-09-27 18:51 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 18:51 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> + tcg_gen_mov_i64(tcg_src, cpu_reg(source));
> + tcg_dst = cpu_reg(dest);
> + if (extend) {
> + if ((shift_amount & 0x7) > 4) {
> + /* reserved value */
> + unallocated_encoding(s);
> + }
> + if (!setflags) {
> + tcg_gen_mov_i64(tcg_src, cpu_reg_sp(source));
> + tcg_dst = cpu_reg_sp(dest);
> + }
> + } else {
> + if (shift_type == 3) {
> + /* reserved value */
> + unallocated_encoding(s);
> + }
> + if (is_32bit && (shift_amount < 0)) {
> + /* reserved value */
> + unallocated_encoding(s);
> + }
> + }
You'd do better to load up the source and destination TCGv values in that IF
sequence, and emit one tcg_gen_mov_i64 afterward.
At the moment you're emitting two for the extend && !setflags case.
> + if (extend) {
> + tcg_op2 = tcg_temp_new_i64();
> + reg_extend(tcg_op2, shift_amount >> 3, shift_amount & 0x7, rm);
> + } else {
> + tcg_op2 = get_shifti(rm, shift_type, shift_amount, is_32bit);
> + }
Why does get_shifti return a temp, but reg_extend requires one to be passed in?
> + if (is_32bit) {
> + tcg_gen_ext32s_i64(tcg_src, tcg_src);
> + tcg_gen_ext32s_i64(tcg_op2, tcg_op2);
> + }
Why? You'll zero-extend the result, and the flags setting will truncate the
inputs itself.
> + if (sub_op) {
> + tcg_gen_sub_i64(tcg_result, tcg_src, tcg_op2);
> + } else {
> + tcg_gen_add_i64(tcg_result, tcg_src, tcg_op2);
> + }
> +
> + if (is_carry) {
> + TCGv_i64 tcg_carry = tcg_temp_new_i64();
> + tcg_gen_shri_i64(tcg_carry, pstate, PSTATE_C_SHIFT);
> + tcg_gen_andi_i64(tcg_carry, tcg_carry, 1);
> + tcg_gen_add_i64(tcg_result, tcg_result, tcg_carry);
> + if (sub_op) {
> + tcg_gen_subi_i64(tcg_result, tcg_result, 1);
> + }
> + tcg_temp_free_i64(tcg_carry);
> + }
For sub_op && is_carry, it's probably better to do exactly what the manual
says, rd = rn + ~rm + C, as opposed to rd = rn - rm + c - 1 as you do here.
This will be especially true if you eventually split up the flags as is done on
the A32 side. One can compute rd plus the new carry via add2.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 17/60] AArch64: Add dup GPR->Vec instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 17/60] AArch64: Add dup GPR->Vec instruction emulation Alexander Graf
@ 2013-09-27 18:55 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 18:55 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> + case 0x0e:
> + if (!get_bits(insn, 31, 1) && !get_bits(insn, 29, 1) &&
> + (get_bits(insn, 10, 6) == 0x3)) {
> + handle_dupg(s, insn);
Is this really better than (insn & y) == x ?
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 18/60] AArch64: Add umov instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 18/60] AArch64: Add umov " Alexander Graf
@ 2013-09-27 18:56 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 18:56 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> + switch (size) {
> + case 0:
> + idx = get_bits(imm5, 1, 4) << 0;
> + tcg_gen_ld8u_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
> + break;
> + case 1:
> + idx = get_bits(imm5, 2, 3) << 1;
> + tcg_gen_ld16u_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
> + break;
> + case 2:
> + idx = get_bits(imm5, 3, 2) << 2;
> + tcg_gen_ld32u_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
> + break;
> + case 3:
> + idx = get_bits(imm5, 4, 1) << 3;
> + tcg_gen_ld_i64(cpu_reg(rd), cpu_env, freg_offs_n + idx);
> + break;
> + }
I see no offset adjustment for big-endian host here.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 20/60] AArch64: Add SIMD ORR family instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 20/60] AArch64: Add SIMD ORR family " Alexander Graf
@ 2013-09-27 19:21 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 19:21 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> +/* SIMD ORR */
> +static void handle_simdorr(DisasContext *s, uint32_t insn)
A better name please. E.g. handle_simd_three_same, which is the name
given to the insn group by C3.6.16.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 22/60] AArch64: Add AdvSIMD scalar three same group handling
2013-09-27 0:48 ` [Qemu-devel] [PATCH 22/60] AArch64: Add AdvSIMD scalar three same group handling Alexander Graf
@ 2013-09-27 19:24 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 19:24 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> This patch adds decoding for the AdvSIMD scalar three same group with U == 0.
> While at it, it also adds support for the ADD / SUB operations in this group.
According to c3.6.16, your simdorr function is from the same group.
What gives?
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 24/60] AArch64: Add SIMD ushll instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 24/60] AArch64: Add SIMD ushll instruction emulation Alexander Graf
@ 2013-09-27 19:29 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 19:29 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> + for (i = 0; i < (8 / ebytes); i++) {
> + simd_ld(tcg_tmp, freg_offs_n + (i * ebytes), size);
> + tcg_gen_shli_i64(tcg_tmp, tcg_tmp, shift);
> + simd_st(tcg_tmp, freg_offs_d + (i * ebytes * 2), size + 1);
> + }
Are we really going to open-code all of the simd insns?
If so, then it makes me wonder if we ought to handle them as tcg registers
instead of continually loading and storing into the backing storage.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 28/60] AArch64: Add movi instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 28/60] AArch64: Add movi " Alexander Graf
@ 2013-09-27 19:38 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 19:38 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> + if (is_k) {
> + tcg_imm = tcg_const_i64(imm);
> + tcg_gen_deposit_i64(cpu_reg(reg), cpu_reg(reg), tcg_imm, pos, 16);
> + tcg_temp_free_i64(tcg_imm);
> + } else {
> + tcg_gen_movi_i64(cpu_reg(reg), imm << pos);
> + }
> +
> + if (is_n) {
> + tcg_gen_not_i64(cpu_reg(reg), cpu_reg(reg));
> + }
> +
> + if (is_32bit) {
> + tcg_gen_ext32u_i64(cpu_reg(reg), cpu_reg(reg));
> + }
You've a constant input. This should be done in one tcg op:
if (is_k) {
...
} else {
imm <<= pos;
if (is_n) {
imm = ~imm;
}
if (is_32bit) {
imm &= 0xffffffffu;
}
tcg_gen_movi_i64(cpu_reg(reg), imm);
}
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 29/60] AArch64: Add orri instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 29/60] AArch64: Add orri " Alexander Graf
@ 2013-09-27 19:42 ` Richard Henderson
2013-11-26 11:56 ` Claudio Fontana
0 siblings, 1 reply; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 19:42 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> + if (setflags) {
> + tcg_dst = cpu_reg(dest);
> + } else {
> + tcg_dst = cpu_reg_sp(dest);
> + }
Never sp for logicals.
> + handle_orri(s, insn);
And yet again, a better function name.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 30/60] AArch64: Add extr instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 30/60] AArch64: Add extr " Alexander Graf
@ 2013-09-27 19:45 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 19:45 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> + if (is_32bit) {
> + tcg_gen_ext32u_i64(tcg_tmp, cpu_reg(rm));
> + } else {
> + tcg_gen_mov_i64(tcg_tmp, cpu_reg(rm));
> + }
> + tcg_gen_shri_i64(tcg_res, cpu_reg(rm), imms);
> + tcg_gen_shli_i64(tcg_tmp, cpu_reg(rn), bitsize - imms);
> + tcg_gen_or_i64(cpu_reg(rd), tcg_tmp, tcg_res);
The first ext/mov is incorrectly unused. This will
produce incorrect results for is_32bit.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 31/60] AArch64: Add bfm family instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 31/60] AArch64: Add bfm family " Alexander Graf
@ 2013-09-27 20:01 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 20:01 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> +
> +uint64_t HELPER(sign_extend)(uint64_t x, uint64_t is_signed, uint64_t mask)
> +{
> + if (x & is_signed) {
> + x |= mask;
> + }
> +
> + return x;
> +}
Why in the world do you have such a simple helper?
> + tcg_gen_andi_i64(tcg_newmask, cpu_reg(source), mask);
> + if (imms < immr) {
> + tcg_gen_shli_i64(tcg_newmask, tcg_newmask, bitsize - immr);
> + tmask <<= bitsize - immr;
> + signbit <<= bitsize + imms - immr;
> + if (signbit == 0x8000000000000000ULL) {
> + /* Can't pad anymore - highest bit is already set */
> + topmask = 0;
> + } else {
> + topmask = ~((1ULL << (bitsize + imms - immr + 1)) - 1);
> + }
> + } else {
> + tcg_gen_shri_i64(tcg_newmask, tcg_newmask, immr);
> + tmask >>= immr;
> + signbit <<= imms - immr;
> + topmask = ~tmask;
> + }
> +
> + if (is_32bit) {
> + tcg_gen_ext32u_i64(tcg_newmask, tcg_newmask);
> + }
> +
> + switch (opc) {
> + case 0: { /* SBFM */
> + TCGv_i64 tcg_mask = tcg_const_i64(topmask);
> + TCGv_i64 tcg_signbit = tcg_const_i64(signbit);
> + gen_helper_sign_extend(cpu_reg(dest), tcg_newmask, tcg_signbit,
> + tcg_mask);
Ah. Perhaps it'll be helpful to know this can be done as
dest = (newmask ^ signbit) - signbit;
So you don't have to compute tcg_mask either.
Although given that ASR, LSL, LSR, are all canonical aliases, we'd probably
do well to detect those special cases.
> + case 1: /* BFM */
> + /* replace the field inside dest */
> + tcg_gen_andi_i64(cpu_reg(dest), cpu_reg(dest), ~tmask);
> + tcg_gen_or_i64(cpu_reg(dest), cpu_reg(dest), tcg_newmask);
> + break;
Ideally we'd emit deposit here for appropriate imms+immr.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 40/60] AArch64: Add tbz instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 40/60] AArch64: Add tbz " Alexander Graf
@ 2013-09-27 20:50 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 20:50 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> + tcg_cmp = tcg_temp_new_i64();
> + tcg_mask = tcg_const_i64(mask);
> + tcg_gen_and_i64(tcg_cmp, cpu_reg(source), tcg_mask);
> +
> + no_match = gen_new_label();
> + if (is_one) {
> + tcg_gen_brcond_i64(TCG_COND_NE, tcg_cmp, tcg_mask, no_match);
> + } else {
> + tcg_gen_brcond_i64(TCG_COND_EQ, tcg_cmp, tcg_mask, no_match);
> + }
You'd do better to brcond vs zero after the and.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 43/60] AArch64: Add cinc instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 43/60] AArch64: Add cinc " Alexander Graf
@ 2013-09-27 20:52 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 20:52 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> +uint64_t HELPER(cinc)(uint32_t pstate, uint32_t insn, uint64_t n, uint64_t m)
> +{
> + bool else_inc = get_bits(insn, 10, 1);
> + int cond = get_bits(insn, 12, 4);
> + bool else_inv = get_bits(insn, 30, 1);
> + bool is_32bit = !get_bits(insn, 31, 1);
> + uint64_t r;
> +
> + if (helper_cond(pstate, cond)) {
> + r = n;
> + goto out;
> + }
> +
> + r = m;
> + if (else_inv) {
> + r = ~r;
> + }
> + if (else_inc) {
> + r++;
> + }
> +
> +out:
> + if (is_32bit) {
> + r = (uint32_t)r;
> + }
> +
> + return r;
> +}
Better to properly decode this during translate. And it's easy to do
everything you need via setcond and movcond.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 44/60] AArch64: Add division instruction family emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 44/60] AArch64: Add division instruction family emulation Alexander Graf
@ 2013-09-27 20:54 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 20:54 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> + if (is_32bit) {
> + if (is_signed) {
> + tcg_gen_ext32s_i64(cpu_reg(rd), cpu_reg(rd));
> + } else {
> + tcg_gen_ext32u_i64(cpu_reg(rd), cpu_reg(rd));
> + }
> + }
Incorrect. Result is always zero-extended.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 46/60] AArch64: Add rev instruction family emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 46/60] AArch64: Add rev " Alexander Graf
@ 2013-09-27 21:07 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 21:07 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> This patch adds emlulation support for rev and rbit instructions.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
> target-arm/helper-a64.c | 19 +++++++++++++++++++
> target-arm/helper-a64.h | 1 +
> target-arm/translate-a64.c | 38 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 58 insertions(+)
>
> diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
> index a56ce75..e20b89f 100644
> --- a/target-arm/helper-a64.c
> +++ b/target-arm/helper-a64.c
> @@ -237,3 +237,22 @@ int64_t HELPER(sdiv64)(int64_t num, int64_t den)
> return LLONG_MIN;
> return num / den;
> }
> +
> +uint64_t HELPER(rbit64)(uint64_t x)
> +{
> + x = ((x & 0xff00000000000000ULL) >> 56)
> + | ((x & 0x00ff000000000000ULL) >> 40)
> + | ((x & 0x0000ff0000000000ULL) >> 24)
> + | ((x & 0x000000ff00000000ULL) >> 8)
> + | ((x & 0x00000000ff000000ULL) << 8)
> + | ((x & 0x0000000000ff0000ULL) << 24)
> + | ((x & 0x000000000000ff00ULL) << 40)
> + | ((x & 0x00000000000000ffULL) << 56);
This first step is of course bswap64, no?
> + case 0x0: /* RBIT */
> + if (is_32bit) {
> + tcg_tmp = tcg_temp_new_i32();
> + tcg_gen_trunc_i64_i32(tcg_tmp, cpu_reg(rn));
> + gen_helper_rbit(tcg_tmp, tcg_tmp);
> + tcg_gen_extu_i32_i64(cpu_reg(rd), tcg_tmp);
> + tcg_temp_free_i32(tcg_tmp);
> + } else {
> + gen_helper_rbit64(cpu_reg(rd), cpu_reg(rn));
> + }
I suppose that works. Alternately, compute as
rd = rbit64(rn << 32);
> + case 0x1: /* REV16 */
> + tcg_gen_bswap16_i64(cpu_reg(rd), cpu_reg(rn));
> + break;
> + case 0x2: /* REV32 */
> + tcg_gen_bswap32_i64(cpu_reg(rd), cpu_reg(rn));
> + break;
Aren't these two wrong? Doesn't revN swap pairs of N bits
all the way up the register? See gen_rev16 for A32.
Certainly one could use bswap32_i64 for REV32 if is_32bit.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 59/60] AArch64: Add "Floating-point data-processing (3
2013-09-27 0:48 ` [Qemu-devel] [PATCH 59/60] AArch64: Add "Floating-point data-processing (3 Alexander Graf
@ 2013-09-27 21:34 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 21:34 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/26/2013 05:48 PM, Alexander Graf wrote:
> + if (is_neg) {
> + gen_helper_vfp_negs(tcg_op1, tcg_op1);
> + gen_helper_vfp_negs(tcg_op3, tcg_op3);
> + }
> +
> + gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
> + if (is_sub) {
> + gen_helper_vfp_subs(tcg_res, tcg_op3, tcg_res, fpst);
> + } else {
> + gen_helper_vfp_adds(tcg_res, tcg_op3, tcg_res, fpst);
> + }
> +
Unlike original vfp, aarch64 requires infinite precision intermediate.
Which means that you need to use float_muladd. Note that
opa_neg = float_muladd_negate_c
op1_neg = float_muladd_negate_product
Or those together into the 4th argument to float_muladd.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 03/60] arm: Split VFP cmp from FPSCR setting
2013-09-27 14:05 ` Richard Henderson
@ 2013-09-27 22:38 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-09-27 22:38 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 09/27/2013 07:05 AM, Richard Henderson wrote:
> On 09/26/2013 05:47 PM, Alexander Graf wrote:
>> -DEF_HELPER_3(vfp_cmps, void, f32, f32, env)
>> -DEF_HELPER_3(vfp_cmpd, void, f64, f64, env)
>> -DEF_HELPER_3(vfp_cmpes, void, f32, f32, env)
>> -DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
>> +DEF_HELPER_3(vfp_fpscr_cmps, void, f32, f32, env)
>> +DEF_HELPER_3(vfp_fpscr_cmpd, void, f64, f64, env)
>> +DEF_HELPER_3(vfp_fpscr_cmpes, void, f32, f32, env)
>> +DEF_HELPER_3(vfp_fpscr_cmped, void, f64, f64, env)
>> +DEF_HELPER_3(vfp_cmps, i32, f32, f32, env)
>> +DEF_HELPER_3(vfp_cmpd, i32, f64, f64, env)
>> +DEF_HELPER_3(vfp_cmpes, i32, f32, f32, env)
>> +DEF_HELPER_3(vfp_cmped, i32, f64, f64, env)
>
> While you're changing these, please change them to use DEF_HELPER_FLAGS_*.
> For the fpscr helpers, TCG_CALL_NO_RWG (since they have the side effect of
> setting the fpscr); for the new helpers, TCG_CALL_NO_RWG_SE since there are
> no side effects at all.
Actually I forgot the side effect of setting exception bits because
of the comparison. So TCG_CALL_NO_RWG for both.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
` (60 preceding siblings ...)
2013-09-27 1:02 ` [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
@ 2013-10-16 19:54 ` Edgar E. Iglesias
2013-10-17 12:23 ` Alexander Graf
61 siblings, 1 reply; 115+ messages in thread
From: Edgar E. Iglesias @ 2013-10-16 19:54 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On Fri, Sep 27, 2013 at 02:47:54AM +0200, Alexander Graf wrote:
> Howdy,
>
> This is the first batch of patches to implement AArch64 instruction
> emulation in QEMU. It implements enough to execute simple AArch64
> programs in linux-user mode.
>
> We still have quite a big number of patches outstanding that will
> come after this initial set, both in linux-user code as well as in
> the AArch64 instruction emulator. But this series is already quite
> big, so let's get this one through first.
Impressive work Alex!
It would be fun to try this out, do you have a public repo with these
patches?
How much progress have you made on system emulation?
Best regards,
Edgar
>
> If you need a rootfs to try this out on, I recommend using our openSUSE
> 12.3 tarball:
>
> http://download.opensuse.org/repositories/devel:/ARM:/AArch64:/12.3/images/
>
>
> Alex
>
> Alexander Graf (60):
> arm: Use symbolic device names for vfp cmp
> arm: Give the fpscr rounding modes names
> arm: Split VFP cmp from FPSCR setting
> arm: Add AArch64 disassembler stub
> softfloat: Add stubs for int16 conversion
> AArch64: Add set_pc cpu method
> ARM: Add 64bit VFP handling
> AArch64: Add support to print VFP registers in CPU dump
> AArch64: Add b and bl handling
> AArch64: Add handling for br instructions
> AArch64: Add STP instruction emulation
> AArch64: Add ldarx style instruction emulation
> AArch64: Add stubs for a64 specific helpers
> AArch64: Add orr instruction emulation
> AArch64: Add add instruction family emulation
> AArch64: Add emulation for SIMD ld/st multiple
> AArch64: Add dup GPR->Vec instruction emulation
> AArch64: Add umov instruction emulation
> AArch64: Add ins GPR->Vec instruction emulation
> AArch64: Add SIMD ORR family instruction emulation
> AArch64: Convert SIMD load/store to common function
> AArch64: Add AdvSIMD scalar three same group handling
> AArch64: Add AdvSIMD modified immediate group handling
> AArch64: Add SIMD ushll instruction emulation
> AArch64: Add SIMD shl instruction emulation
> AArch64: Add ADR instruction emulation
> AArch64: Add addi instruction emulation
> AArch64: Add movi instruction emulation
> AArch64: Add orri instruction emulation
> AArch64: Add extr instruction emulation
> AArch64: Add bfm family instruction emulation
> AArch64: Add svc instruction emulation
> AArch64: Add bc instruction emulation
> AArch64: Add b.cond instruction emulation
> AArch64: Add mrs instruction emulation
> AArch64: Add msr instruction emulation
> AArch64: Add hint instruction emulation
> AArch64: Add stub barrier instruction emulation
> AArch64: Add stub sys instruction emulation
> AArch64: Add tbz instruction emulation
> AArch64: Add ldr/str instruction family emulation
> AArch64: Add literal ld instruction emulation
> AArch64: Add cinc instruction emulation
> AArch64: Add division instruction family emulation
> AArch64: Add shift instruction family emulation
> AArch64: Add rev instruction family emulation
> AArch64: Add clz instruction emulation
> AArch64: Add 0x1a encoding of add instructions
> AArch64: Add "Data-processing (3 source)" instruction family
> emulation
> AArch64: Add "Floating-point<->fixed-point conversions" category
> emulation
> AArch64: Add fmov (scalar, immediate) instruction emulation
> AArch64: Add "Floating-point<->integer conversions" instruction
> family emulation
> AArch64: Add "Floating-point compare" instruction family emulation
> AArch64: Add "Floating-point data-processing (1 source)" (32 bit)
> instruction family emulation
> AArch64: Add "Floating-point data-processing (1 source)" (64 bit)
> instruction family emulation
> AArch64: Add "Floating-point data-processing (2 source)" (32 bit)
> instruction family emulation
> AArch64: Add "Floating-point data-processing (2 source)" (64 bit)
> instruction family emulation
> AArch64: Add "ADD (vector)" instruction emulation
> AArch64: Add "Floating-point data-processing (3 source)" (32 bit)
> instruction family emulation
> AArch64: Add "Floating-point data-processing (3 source)" (64 bit)
> instruction family emulation
>
> disas.c | 6 +-
> disas/Makefile.objs | 1 +
> disas/aarch64.c | 31 +
> fpu/softfloat.c | 21 +
> include/disas/bfd.h | 1 +
> include/fpu/softfloat.h | 4 +
> target-arm/Makefile.objs | 2 +-
> target-arm/cpu.h | 5 +
> target-arm/cpu64.c | 8 +
> target-arm/helper-a64.c | 309 +++++
> target-arm/helper-a64.h | 35 +
> target-arm/helper.c | 108 +-
> target-arm/helper.h | 24 +-
> target-arm/translate-a64.c | 2915 +++++++++++++++++++++++++++++++++++++++++++-
> target-arm/translate.c | 13 +-
> target-arm/translate.h | 5 +
> 16 files changed, 3424 insertions(+), 64 deletions(-)
> create mode 100644 disas/aarch64.c
> create mode 100644 target-arm/helper-a64.c
> create mode 100644 target-arm/helper-a64.h
>
> --
> 1.7.12.4
>
>
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support
2013-10-16 19:54 ` Edgar E. Iglesias
@ 2013-10-17 12:23 ` Alexander Graf
0 siblings, 0 replies; 115+ messages in thread
From: Alexander Graf @ 2013-10-17 12:23 UTC (permalink / raw)
To: Edgar E. Iglesias
Cc: Peter Maydell, Michael Matz, QEMU Developers, C Fontana,
Dirk Mueller, Laurent Desnogues, Christoffer Dall,
Richard Henderson
On 16.10.2013, at 21:54, Edgar E. Iglesias <edgar.iglesias@gmail.com> wrote:
> On Fri, Sep 27, 2013 at 02:47:54AM +0200, Alexander Graf wrote:
>> Howdy,
>>
>> This is the first batch of patches to implement AArch64 instruction
>> emulation in QEMU. It implements enough to execute simple AArch64
>> programs in linux-user mode.
>>
>> We still have quite a big number of patches outstanding that will
>> come after this initial set, both in linux-user code as well as in
>> the AArch64 instruction emulator. But this series is already quite
>> big, so let's get this one through first.
>
>
> Impressive work Alex!
>
> It would be fun to try this out, do you have a public repo with these
> patches?
I even have a repo with a not as clean, but fully working backend:
https://github.com/openSUSE/qemu/commits/aarch64-work
> How much progress have you made on system emulation?
None :). So far the target was user emulation. When I get a bit of spare time on my hands again I'll take a stab at system emulation too, but so far I haven't gotten around to it. In fact, doing v2 is definitely higher on my todo list than system emulation ;).
Alex
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-09-27 18:25 ` Richard Henderson
@ 2013-10-31 0:29 ` Alexander Graf
2013-10-31 1:44 ` Peter Maydell
2013-11-18 10:15 ` Claudio Fontana
1 sibling, 1 reply; 115+ messages in thread
From: Alexander Graf @ 2013-10-31 0:29 UTC (permalink / raw)
To: Richard Henderson
Cc: Peter Maydell, Michael Matz, QEMU Developers, C Fontana,
Dirk Mueller, Laurent Desnogues, Christoffer Dall
On 27.09.2013, at 11:25, Richard Henderson <rth@twiddle.net> wrote:
> On 09/26/2013 05:48 PM, Alexander Graf wrote:
>> This patch adds emulation support for the orr instruction.
>>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>> ---
>> target-arm/helper-a64.c | 28 +++++++++++
>> target-arm/helper-a64.h | 1 +
>> target-arm/translate-a64.c | 120 +++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 149 insertions(+)
>>
>> diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
>> index 8105fb5..da72b7f 100644
>> --- a/target-arm/helper-a64.c
>> +++ b/target-arm/helper-a64.c
>> @@ -24,3 +24,31 @@
>> #include "sysemu/sysemu.h"
>> #include "qemu/bitops.h"
>>
>> +uint32_t HELPER(pstate_add)(uint32_t pstate, uint64_t a1, uint64_t a2,
>> + uint64_t ar)
>> +{
>> + int64_t s1 = a1;
>> + int64_t s2 = a2;
>> + int64_t sr = ar;
>> +
>> + pstate &= ~(PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V);
>> +
>> + if (sr < 0) {
>> + pstate |= PSTATE_N;
>> + }
>> +
>> + if (!ar) {
>> + pstate |= PSTATE_Z;
>> + }
>> +
>> + if (ar && (ar < a1)) {
>> + pstate |= PSTATE_C;
>> + }
>> +
>> + if ((s1 > 0 && s2 > 0 && sr < 0) ||
>> + (s1 < 0 && s2 < 0 && sr > 0)) {
>> + pstate |= PSTATE_V;
>> + }
>> +
>> + return pstate;
>> +}
>
> Why are you not using the same split apart bits as A32?
There is an architecturally defined register that specifies what pstate looks like and IIRC that includes system level state as well, similar to EFLAGS. So I figured it's more straight forward to use a single variable for it.
I don't think it really makes much of a difference either way though. If we see that doing it in a split way makes more sense we can always just switch to that later.
Alex
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-10-31 0:29 ` Alexander Graf
@ 2013-10-31 1:44 ` Peter Maydell
0 siblings, 0 replies; 115+ messages in thread
From: Peter Maydell @ 2013-10-31 1:44 UTC (permalink / raw)
To: Alexander Graf
Cc: Michael Matz, QEMU Developers, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On 31 October 2013 00:29, Alexander Graf <agraf@suse.de> wrote:
>
> On 27.09.2013, at 11:25, Richard Henderson <rth@twiddle.net> wrote:
>> Why are you not using the same split apart bits as A32?
>
> There is an architecturally defined register that specifies
> what pstate looks like and IIRC that includes system level
> state as well, similar to EFLAGS.
No, the architecture goes out of its way to point out that pstate
is not a register. There are a collection of different state bits
which are generally accessible via different MSR/MRS
instructions or in some cases not accessible at all. This
is a difference from A32.
In any case as Richard says we already split NZCV from
the rest of CPSR in A32 -- the few places that want a
complete 32 bit CPSR call a helper function that assembles
it from the various separate parts.
> I don't think it really makes much of a difference either way
> though. If we see that doing it in a split way makes more
> sense we can always just switch to that later.
I think the split is less critical for A64 because of the
severely reduced conditionality which means we're less
likely to be making frequent NZCV checks. However it's
probably still worth having because it's pretty nearly free.
-- PMM
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-09-27 18:25 ` Richard Henderson
2013-10-31 0:29 ` Alexander Graf
@ 2013-11-18 10:15 ` Claudio Fontana
2013-11-18 10:37 ` Laurent Desnogues
2013-11-18 13:12 ` Michael Matz
1 sibling, 2 replies; 115+ messages in thread
From: Claudio Fontana @ 2013-11-18 10:15 UTC (permalink / raw)
To: Richard Henderson
Cc: Peter Maydell, Michael Matz, Alexander Graf, qemu-devel,
Dirk Mueller, Laurent Desnogues, Christoffer Dall
Hello,
On 09/27/2013 08:25 PM, Richard Henderson wrote:
> On 09/26/2013 05:48 PM, Alexander Graf wrote:
>> This patch adds emulation support for the orr instruction.
>>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>> ---
>> target-arm/helper-a64.c | 28 +++++++++++
>> target-arm/helper-a64.h | 1 +
>> target-arm/translate-a64.c | 120 +++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 149 insertions(+)
>>
>> diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
>> index 8105fb5..da72b7f 100644
>> --- a/target-arm/helper-a64.c
>> +++ b/target-arm/helper-a64.c
>> @@ -24,3 +24,31 @@
>> #include "sysemu/sysemu.h"
>> #include "qemu/bitops.h"
>>
>> +uint32_t HELPER(pstate_add)(uint32_t pstate, uint64_t a1, uint64_t a2,
>> + uint64_t ar)
>> +{
>> + int64_t s1 = a1;
>> + int64_t s2 = a2;
>> + int64_t sr = ar;
>> +
>> + pstate &= ~(PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V);
>> +
>> + if (sr < 0) {
>> + pstate |= PSTATE_N;
>> + }
>> +
>> + if (!ar) {
>> + pstate |= PSTATE_Z;
>> + }
>> +
>> + if (ar && (ar < a1)) {
>> + pstate |= PSTATE_C;
>> + }
>> +
>> + if ((s1 > 0 && s2 > 0 && sr < 0) ||
>> + (s1 < 0 && s2 < 0 && sr > 0)) {
>> + pstate |= PSTATE_V;
>> + }
>> +
>> + return pstate;
>> +}
>
> Why are you not using the same split apart bits as A32?
>
>> + /* XXX carry_out */
>> + switch (shift_type) {
>
> What carry out? I see no such in the ShiftReg description.
>
>> + case 3:
>> + tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
>> + break;
>
> Incorrect rotate for 32bit?
>
>> +static void handle_orr(DisasContext *s, uint32_t insn)
>> +{
>> + int is_32bit = !get_bits(insn, 31, 1);
>> + int dest = get_reg(insn);
>> + int source = get_bits(insn, 5, 5);
>> + int rm = get_bits(insn, 16, 5);
>> + int shift_amount = get_sbits(insn, 10, 6);
>> + int is_n = get_bits(insn, 21, 1);
>> + int shift_type = get_bits(insn, 22, 2);
>> + int opc = get_bits(insn, 29, 2);
>> + bool setflags = (opc == 0x3);
>> + TCGv_i64 tcg_op2;
>> + TCGv_i64 tcg_dest;
>> +
>> + if (is_32bit && (shift_amount < 0)) {
>> + /* reserved value */
>> + unallocated_encoding(s);
>> + }
>
> Why are you extracting shift_amount signed?
>
>> +
>> + /* MOV is dest = xzr & (source & ~0) */
>
> Comment is wrong.
>
>> + if (!shift_amount && source == 0x1f) {
Besides the comment, is this correct?
I am trying to rework this patch, but this part seems incorrect to me.
We land here for the AND as well, and if source(rn) is xzr,
then I would expect the result to be zero for AND regardless of anything else,
and not a MOV.
Can we really do this optimization in general here for AND, OR, EOR?
Thanks for any clarification,
Claudio
>> + if (is_32bit) {
>> + tcg_gen_ext32u_i64(cpu_reg_sp(dest), cpu_reg(rm));
>> + } else {
>> + tcg_gen_mov_i64(cpu_reg_sp(dest), cpu_reg(rm));
>> + }
>> + if (is_n) {
>> + tcg_gen_not_i64(cpu_reg_sp(dest), cpu_reg_sp(dest));
>> + }
>> + if (is_32bit) {
>> + tcg_gen_ext32u_i64(cpu_reg_sp(dest), cpu_reg_sp(dest));
>> + }
>
> These are incorrect -- no sp in the logical ops, but xzr instead.
>
> And surely we can emit fewer opcodes for the simple cases here.
> Since these are the canonical aliases for mov/mvn, it'll pay off.
>
> TCGv src = cpu_reg(rm);
> TCGv dst = cpu_reg(rd);
>
> if (is_n) {
> tcg_gen_not_i64(dst, src);
> src = dst;
> }
> if (is_32bit) {
> tcg_gen_ext32u_i64(dst, src);
> } else {
> tcg_gen_mov_i64(dst, src);
> }
>
> Note that tcg_gen_mov_i64 does the src == dst check, so a simple
> 64-bit mvn will only emit the not.
>
>
>> + tcg_dest = cpu_reg(dest);
>> + switch (opc) {
>> + case 0x0:
>> + case 0x3:
>> + tcg_gen_and_i64(tcg_dest, cpu_reg(source), tcg_op2);
>> + break;
>> + case 0x1:
>> + tcg_gen_or_i64(tcg_dest, cpu_reg(source), tcg_op2);
>> + break;
>> + case 0x2:
>> + tcg_gen_xor_i64(tcg_dest, cpu_reg(source), tcg_op2);
>> + break;
>> + }
>> +
>> + if (is_32bit) {
>> + tcg_gen_ext32u_i64(tcg_dest, tcg_dest);
>> + }
>> +
>> + if (setflags) {
>> + gen_helper_pstate_add(pstate, pstate, tcg_dest, cpu_reg(31), tcg_dest);
>> + }
>
> Incorrect flags generated. They're different between add/sub and logical.
> In particular, C and V are always zero.
>
>> + handle_orr(s, insn);
>
> And please use a more proper name than ORR for something that handles all
> of the logical insns.
>
>
> r~
>
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-11-18 10:15 ` Claudio Fontana
@ 2013-11-18 10:37 ` Laurent Desnogues
2013-11-18 13:12 ` Michael Matz
1 sibling, 0 replies; 115+ messages in thread
From: Laurent Desnogues @ 2013-11-18 10:37 UTC (permalink / raw)
To: Claudio Fontana
Cc: Peter Maydell, Michael Matz, qemu-devel@nongnu.org,
Alexander Graf, Dirk Mueller, Christoffer Dall, Richard Henderson
On Mon, Nov 18, 2013 at 11:15 AM, Claudio Fontana
<claudio.fontana@linaro.org> wrote:
> Hello,
>
> On 09/27/2013 08:25 PM, Richard Henderson wrote:
>> On 09/26/2013 05:48 PM, Alexander Graf wrote:
>>> This patch adds emulation support for the orr instruction.
>>>
>>> Signed-off-by: Alexander Graf <agraf@suse.de>
>>> ---
>>> target-arm/helper-a64.c | 28 +++++++++++
>>> target-arm/helper-a64.h | 1 +
>>> target-arm/translate-a64.c | 120 +++++++++++++++++++++++++++++++++++++++++++++
>>> 3 files changed, 149 insertions(+)
>>>
>>> diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
>>> index 8105fb5..da72b7f 100644
>>> --- a/target-arm/helper-a64.c
>>> +++ b/target-arm/helper-a64.c
>>> @@ -24,3 +24,31 @@
>>> #include "sysemu/sysemu.h"
>>> #include "qemu/bitops.h"
>>>
>>> +uint32_t HELPER(pstate_add)(uint32_t pstate, uint64_t a1, uint64_t a2,
>>> + uint64_t ar)
>>> +{
>>> + int64_t s1 = a1;
>>> + int64_t s2 = a2;
>>> + int64_t sr = ar;
>>> +
>>> + pstate &= ~(PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V);
>>> +
>>> + if (sr < 0) {
>>> + pstate |= PSTATE_N;
>>> + }
>>> +
>>> + if (!ar) {
>>> + pstate |= PSTATE_Z;
>>> + }
>>> +
>>> + if (ar && (ar < a1)) {
>>> + pstate |= PSTATE_C;
>>> + }
>>> +
>>> + if ((s1 > 0 && s2 > 0 && sr < 0) ||
>>> + (s1 < 0 && s2 < 0 && sr > 0)) {
>>> + pstate |= PSTATE_V;
>>> + }
>>> +
>>> + return pstate;
>>> +}
>>
>> Why are you not using the same split apart bits as A32?
>>
>>> + /* XXX carry_out */
>>> + switch (shift_type) {
>>
>> What carry out? I see no such in the ShiftReg description.
>>
>>> + case 3:
>>> + tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
>>> + break;
>>
>> Incorrect rotate for 32bit?
>>
>>> +static void handle_orr(DisasContext *s, uint32_t insn)
>>> +{
>>> + int is_32bit = !get_bits(insn, 31, 1);
>>> + int dest = get_reg(insn);
>>> + int source = get_bits(insn, 5, 5);
>>> + int rm = get_bits(insn, 16, 5);
>>> + int shift_amount = get_sbits(insn, 10, 6);
>>> + int is_n = get_bits(insn, 21, 1);
>>> + int shift_type = get_bits(insn, 22, 2);
>>> + int opc = get_bits(insn, 29, 2);
>>> + bool setflags = (opc == 0x3);
>>> + TCGv_i64 tcg_op2;
>>> + TCGv_i64 tcg_dest;
>>> +
>>> + if (is_32bit && (shift_amount < 0)) {
>>> + /* reserved value */
>>> + unallocated_encoding(s);
>>> + }
>>
>> Why are you extracting shift_amount signed?
>>
>>> +
>>> + /* MOV is dest = xzr & (source & ~0) */
>>
>> Comment is wrong.
>>
>>> + if (!shift_amount && source == 0x1f) {
>
> Besides the comment, is this correct?
> I am trying to rework this patch, but this part seems incorrect to me.
>
> We land here for the AND as well, and if source(rn) is xzr,
> then I would expect the result to be zero for AND regardless of anything else,
> and not a MOV.
>
> Can we really do this optimization in general here for AND, OR, EOR?
That part is definitely wrong: there's a missing check that opc = 1
(ORR/ORN for MOV/MVN). The comment also is very wrong :-)
Also note that SP can't be accessed by the shifted reg logical ops as
Richard wrote.
Laurent
> Thanks for any clarification,
>
> Claudio
>
>>> + if (is_32bit) {
>>> + tcg_gen_ext32u_i64(cpu_reg_sp(dest), cpu_reg(rm));
>>> + } else {
>>> + tcg_gen_mov_i64(cpu_reg_sp(dest), cpu_reg(rm));
>>> + }
>>> + if (is_n) {
>>> + tcg_gen_not_i64(cpu_reg_sp(dest), cpu_reg_sp(dest));
>>> + }
>>> + if (is_32bit) {
>>> + tcg_gen_ext32u_i64(cpu_reg_sp(dest), cpu_reg_sp(dest));
>>> + }
>>
>> These are incorrect -- no sp in the logical ops, but xzr instead.
>>
>> And surely we can emit fewer opcodes for the simple cases here.
>> Since these are the canonical aliases for mov/mvn, it'll pay off.
>>
>> TCGv src = cpu_reg(rm);
>> TCGv dst = cpu_reg(rd);
>>
>> if (is_n) {
>> tcg_gen_not_i64(dst, src);
>> src = dst;
>> }
>> if (is_32bit) {
>> tcg_gen_ext32u_i64(dst, src);
>> } else {
>> tcg_gen_mov_i64(dst, src);
>> }
>>
>> Note that tcg_gen_mov_i64 does the src == dst check, so a simple
>> 64-bit mvn will only emit the not.
>>
>>
>>> + tcg_dest = cpu_reg(dest);
>>> + switch (opc) {
>>> + case 0x0:
>>> + case 0x3:
>>> + tcg_gen_and_i64(tcg_dest, cpu_reg(source), tcg_op2);
>>> + break;
>>> + case 0x1:
>>> + tcg_gen_or_i64(tcg_dest, cpu_reg(source), tcg_op2);
>>> + break;
>>> + case 0x2:
>>> + tcg_gen_xor_i64(tcg_dest, cpu_reg(source), tcg_op2);
>>> + break;
>>> + }
>>> +
>>> + if (is_32bit) {
>>> + tcg_gen_ext32u_i64(tcg_dest, tcg_dest);
>>> + }
>>> +
>>> + if (setflags) {
>>> + gen_helper_pstate_add(pstate, pstate, tcg_dest, cpu_reg(31), tcg_dest);
>>> + }
>>
>> Incorrect flags generated. They're different between add/sub and logical.
>> In particular, C and V are always zero.
>>
>>> + handle_orr(s, insn);
>>
>> And please use a more proper name than ORR for something that handles all
>> of the logical insns.
>>
>>
>> r~
>>
>
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-11-18 10:15 ` Claudio Fontana
2013-11-18 10:37 ` Laurent Desnogues
@ 2013-11-18 13:12 ` Michael Matz
2013-11-18 13:15 ` Peter Maydell
2013-11-18 13:43 ` Claudio Fontana
1 sibling, 2 replies; 115+ messages in thread
From: Michael Matz @ 2013-11-18 13:12 UTC (permalink / raw)
To: Claudio Fontana
Cc: Peter Maydell, qemu-devel, Alexander Graf, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1599 bytes --]
Hi,
On Mon, 18 Nov 2013, Claudio Fontana wrote:
> >> + case 3:
> >> + tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
> >> + break;
> >
> > Incorrect rotate for 32bit?
32bit rotates and shifts were fixed in a patch later than the 60er series
Alex posted. See attached. (Generally there are many fixes to emulated
instructions in that branch)
> >> + if (!shift_amount && source == 0x1f) {
>
> Besides the comment, is this correct?
No, it needs to check for opc == 1.
> >> + tcg_dest = cpu_reg(dest);
> >> + switch (opc) {
> >> + case 0x0:
> >> + case 0x3:
> >> + tcg_gen_and_i64(tcg_dest, cpu_reg(source), tcg_op2);
> >> + break;
> >> + case 0x1:
> >> + tcg_gen_or_i64(tcg_dest, cpu_reg(source), tcg_op2);
> >> + break;
> >> + case 0x2:
> >> + tcg_gen_xor_i64(tcg_dest, cpu_reg(source), tcg_op2);
> >> + break;
> >> + }
> >> +
> >> + if (is_32bit) {
> >> + tcg_gen_ext32u_i64(tcg_dest, tcg_dest);
> >> + }
> >> +
> >> + if (setflags) {
> >> + gen_helper_pstate_add(pstate, pstate, tcg_dest, cpu_reg(31), tcg_dest);
> >> + }
> >
> > Incorrect flags generated. They're different between add/sub and logical.
> > In particular, C and V are always zero.
That's done correctly with the fixed pstate helpers coming with a later
patch (see attached as well). reg31 is zero, so that's flags as if for
"dest == dest + 0", and PSTATE_C and PSTATE_V will be zero. That is, the
logical flags are the same as the arithmetic flags for result plus zero
with no carry_in.
Ciao,
Michael.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: TEXT/x-patch; name=0001-Fix-32bit-rotates.patch, Size: 2736 bytes --]
From df54486da31d6329696effa61096eda5ab85395a Mon Sep 17 00:00:00 2001
From: Michael Matz <matz@suse.de>
Date: Sun, 24 Mar 2013 02:52:42 +0100
Subject: [PATCH] Fix 32bit rotates.
The 32bit shifts generally weren't careful with the upper parts,
either bits could leak in (for right shift) or leak or (for left shift).
And rotate was completely off, rotating around bit 63, not 31.
This fixes the CAST5 hash algorithm.
---
target-arm/translate-a64.c | 30 +++++++++++++++++++++++++++---
1 file changed, 27 insertions(+), 3 deletions(-)
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 96dc281..e3941a1 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -596,25 +596,49 @@ static TCGv_i64 get_shift(int reg, int shift_type, TCGv_i64 tcg_shift,
r = tcg_temp_new_i64();
/* XXX carry_out */
+ /* Careful with the width. We work on 64bit, but must make sure
+ that we zero-extend the result on out, and ignore any upper bits,
+ that might still be set in that register. */
switch (shift_type) {
case 0: /* LSL */
+ /* left shift is easy, simply zero-extend on out */
tcg_gen_shl_i64(r, cpu_reg(reg), tcg_shift);
+ if (is_32bit)
+ tcg_gen_ext32u_i64 (r, r);
break;
case 1: /* LSR */
- tcg_gen_shr_i64(r, cpu_reg(reg), tcg_shift);
+ /* For logical right shift we zero extend first, to zero
+ the upper bits. We don't need to extend on out. */
+ if (is_32bit) {
+ tcg_gen_ext32u_i64 (r, cpu_reg(reg));
+ tcg_gen_shr_i64 (r, r, tcg_shift);
+ } else
+ tcg_gen_shr_i64(r, cpu_reg(reg), tcg_shift);
break;
case 2: /* ASR */
+ /* For arithmetic right shift we sign extend first, then shift,
+ and then need to clear the upper bits again. */
if (is_32bit) {
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
tcg_gen_ext32s_i64(tcg_tmp, cpu_reg(reg));
tcg_gen_sar_i64(r, tcg_tmp, tcg_shift);
+ tcg_gen_ext32u_i64 (r, r);
tcg_temp_free_i64(tcg_tmp);
} else {
tcg_gen_sar_i64(r, cpu_reg(reg), tcg_shift);
}
break;
- case 3:
- tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
+ case 3: /* ROR */
+ /* For rotation extending doesn't help, we really have to use
+ a 32bit rotate. */
+ if (is_32bit) {
+ TCGv_i32 tmp = tcg_temp_new_i32();
+ tcg_gen_trunc_i64_i32(tmp, cpu_reg(reg));
+ tcg_gen_rotr_i32(tmp, tmp, tcg_shift);
+ tcg_gen_extu_i32_i64(r, tmp);
+ tcg_temp_free_i32(tmp);
+ } else
+ tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
break;
}
--
1.8.1.4
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: Type: TEXT/x-patch; name=0002-Fix-the-pstate-flags-helpers.patch, Size: 3578 bytes --]
From 33137f8a660750d7d8598c7e467f4ccc8dc5ef85 Mon Sep 17 00:00:00 2001
From: Michael Matz <matz@suse.de>
Date: Sat, 23 Mar 2013 04:53:44 +0100
Subject: [PATCH] Fix the pstate flags helpers
ADCS and SBCS/SUBS sometimes gave the wrong results
for the C and V flags. This fixes it.
---
target-arm/helper-a64.c | 52 ++++++++++++-------------------------------------
1 file changed, 12 insertions(+), 40 deletions(-)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 4375bf0..4fcb09b 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -7,8 +7,6 @@
uint32_t HELPER(pstate_add)(uint32_t pstate, uint64_t a1, uint64_t a2, uint64_t ar)
{
- int64_t s1 = a1;
- int64_t s2 = a2;
int64_t sr = ar;
pstate &= ~(PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V);
@@ -21,11 +19,15 @@ uint32_t HELPER(pstate_add)(uint32_t pstate, uint64_t a1, uint64_t a2, uint64_t
pstate |= PSTATE_Z;
}
- if (ar && (ar < a1)) {
+ if (ar < a1) {
pstate |= PSTATE_C;
+ } else if (ar != (a1 + a2) && ar == a1) {
+ /* If result isn't what we expect it must be because we added
+ in some carry. If so we also produce a carry when ar == a1. */
+ pstate |= PSTATE_C;
}
- if ((s1 > 0 && s2 > 0 && sr < 0) || (s1 < 0 && s2 < 0 && sr > 0)) {
+ if ((int64_t)((a1 ^ a2 ^ -1) & (a1 ^ ar)) < 0) {
pstate |= PSTATE_V;
}
@@ -38,8 +40,6 @@ uint32_t HELPER(pstate_add32)(uint32_t pstate, uint64_t x1, uint64_t x2, uint64_
uint32_t a2 = x2;
uint32_t ar = xr;
- int32_t s1 = a1;
- int32_t s2 = a2;
int32_t sr = ar;
pstate &= ~(PSTATE_N | PSTATE_Z | PSTATE_C | PSTATE_V);
@@ -52,11 +52,13 @@ uint32_t HELPER(pstate_add32)(uint32_t pstate, uint64_t x1, uint64_t x2, uint64_
pstate |= PSTATE_Z;
}
- if (ar && (ar < a1)) {
+ if (ar < a1) {
pstate |= PSTATE_C;
+ } else if (ar != (a1 + a2) && ar == a1) {
+ pstate |= PSTATE_C;
}
- if ((s1 > 0 && s2 > 0 && sr < 0) || (s1 < 0 && s2 < 0 && sr > 0)) {
+ if ((int32_t)((a1 ^ a2 ^ -1) & (a1 ^ ar)) < 0) {
pstate |= PSTATE_V;
}
@@ -65,23 +67,7 @@ uint32_t HELPER(pstate_add32)(uint32_t pstate, uint64_t x1, uint64_t x2, uint64_
uint32_t HELPER(pstate_sub)(uint32_t pstate, uint64_t a1, uint64_t a2, uint64_t ar)
{
- int64_t sr = ar;
- int64_t s1 = a1;
- int64_t s2 = a2;
-
- pstate = helper_pstate_add(pstate, a1, a2, ar);
-
- pstate &= ~(PSTATE_C | PSTATE_V);
-
- if (a2 <= a1) {
- pstate |= PSTATE_C;
- }
-
- /* XXX check if this is the only special case */
- if ((!a1 && a2 == 0x8000000000000000ULL) || (s1 > 0 && s2 < 0 && sr < 0) || (s1 < 0 && s2 > 0 && sr > 0)) {
- pstate |= PSTATE_V;
- }
-
+ pstate = helper_pstate_add(pstate, a1, ~a2, ar);
return pstate;
}
@@ -90,22 +76,8 @@ uint32_t HELPER(pstate_sub32)(uint32_t pstate, uint64_t x1, uint64_t x2, uint64_
uint32_t a1 = x1;
uint32_t a2 = x2;
uint32_t ar = xr;
- int32_t sr = ar;
- int32_t s1 = a1;
- int32_t s2 = a2;
-
- pstate = helper_pstate_add32(pstate, a1, a2, ar);
-
- pstate &= ~(PSTATE_C | PSTATE_V);
-
- if (a2 <= a1) {
- pstate |= PSTATE_C;
- }
-
- if ((!a1 && a2 == 0x80000000ULL) || (s1 > 0 && s2 < 0 && sr < 0) || (s1 < 0 && s2 > 0 && sr > 0)) {
- pstate |= PSTATE_V;
- }
+ pstate = helper_pstate_add32(pstate, a1, ~a2, ar);
return pstate;
}
--
1.8.1.4
^ permalink raw reply related [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-11-18 13:12 ` Michael Matz
@ 2013-11-18 13:15 ` Peter Maydell
2013-11-18 13:24 ` Claudio Fontana
2013-11-18 13:46 ` Michael Matz
2013-11-18 13:43 ` Claudio Fontana
1 sibling, 2 replies; 115+ messages in thread
From: Peter Maydell @ 2013-11-18 13:15 UTC (permalink / raw)
To: Michael Matz
Cc: QEMU Developers, Alexander Graf, Claudio Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On 18 November 2013 13:12, Michael Matz <matz@suse.de> wrote:
> Hi,
>
> On Mon, 18 Nov 2013, Claudio Fontana wrote:
>
>> >> + case 3:
>> >> + tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
>> >> + break;
>> >
>> > Incorrect rotate for 32bit?
>
> 32bit rotates and shifts were fixed in a patch later than the 60er series
> Alex posted. See attached. (Generally there are many fixes to emulated
> instructions in that branch)
I think we're going to need to look through and fold in those
fixes, otherwise we'll end up reduplicating that work in the
course of code review :-(
-- PMM
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-11-18 13:15 ` Peter Maydell
@ 2013-11-18 13:24 ` Claudio Fontana
2013-11-18 13:46 ` Michael Matz
1 sibling, 0 replies; 115+ messages in thread
From: Claudio Fontana @ 2013-11-18 13:24 UTC (permalink / raw)
To: Peter Maydell
Cc: Michael Matz, QEMU Developers, Alexander Graf, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On 11/18/2013 02:15 PM, Peter Maydell wrote:
> On 18 November 2013 13:12, Michael Matz <matz@suse.de> wrote:
>> Hi,
>>
>> On Mon, 18 Nov 2013, Claudio Fontana wrote:
>>
>>>>> + case 3:
>>>>> + tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
>>>>> + break;
>>>>
>>>> Incorrect rotate for 32bit?
>>
>> 32bit rotates and shifts were fixed in a patch later than the 60er series
>> Alex posted. See attached. (Generally there are many fixes to emulated
>> instructions in that branch)
>
> I think we're going to need to look through and fold in those
> fixes, otherwise we'll end up reduplicating that work in the
> course of code review :-(
>
> -- PMM
>
Thanks all.
Regarding the access to registers in 32 bit mode, and the consequent write to registers in 32 bit mode,
I am investigating how to do it a little bit more general, in the sense that generally when we access registers in 32bit mode
we will (often) need to ignore the upper bits of the source register, and write zero to the destination register.
Not always but often. This could be done once for all to reduce the chances of mistakes.
C.
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-11-18 13:12 ` Michael Matz
2013-11-18 13:15 ` Peter Maydell
@ 2013-11-18 13:43 ` Claudio Fontana
2013-11-18 13:44 ` Peter Maydell
2013-11-18 13:55 ` Michael Matz
1 sibling, 2 replies; 115+ messages in thread
From: Claudio Fontana @ 2013-11-18 13:43 UTC (permalink / raw)
To: Michael Matz
Cc: Peter Maydell, qemu-devel, Alexander Graf, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
Btw, in the first patch:
On 11/18/2013 02:12 PM, Michael Matz wrote:
>
> From df54486da31d6329696effa61096eda5ab85395a Mon Sep 17 00:00:00 2001
> From: Michael Matz <matz@suse.de>
> Date: Sun, 24 Mar 2013 02:52:42 +0100
> Subject: [PATCH] Fix 32bit rotates.
>
> The 32bit shifts generally weren't careful with the upper parts,
> either bits could leak in (for right shift) or leak or (for left shift).
> And rotate was completely off, rotating around bit 63, not 31.
> This fixes the CAST5 hash algorithm.
> ---
> target-arm/translate-a64.c | 30 +++++++++++++++++++++++++++---
> 1 file changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index 96dc281..e3941a1 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -596,25 +596,49 @@ static TCGv_i64 get_shift(int reg, int shift_type, TCGv_i64 tcg_shift,
> r = tcg_temp_new_i64();
>
> /* XXX carry_out */
> + /* Careful with the width. We work on 64bit, but must make sure
> + that we zero-extend the result on out, and ignore any upper bits,
> + that might still be set in that register. */
> switch (shift_type) {
> case 0: /* LSL */
> + /* left shift is easy, simply zero-extend on out */
> tcg_gen_shl_i64(r, cpu_reg(reg), tcg_shift);
> + if (is_32bit)
> + tcg_gen_ext32u_i64 (r, r);
> break;
> case 1: /* LSR */
> - tcg_gen_shr_i64(r, cpu_reg(reg), tcg_shift);
> + /* For logical right shift we zero extend first, to zero
> + the upper bits. We don't need to extend on out. */
> + if (is_32bit) {
> + tcg_gen_ext32u_i64 (r, cpu_reg(reg));
> + tcg_gen_shr_i64 (r, r, tcg_shift);
> + } else
> + tcg_gen_shr_i64(r, cpu_reg(reg), tcg_shift);
> break;
> case 2: /* ASR */
> + /* For arithmetic right shift we sign extend first, then shift,
> + and then need to clear the upper bits again. */
> if (is_32bit) {
> TCGv_i64 tcg_tmp = tcg_temp_new_i64();
> tcg_gen_ext32s_i64(tcg_tmp, cpu_reg(reg));
> tcg_gen_sar_i64(r, tcg_tmp, tcg_shift);
> + tcg_gen_ext32u_i64 (r, r);
> tcg_temp_free_i64(tcg_tmp);
> } else {
> tcg_gen_sar_i64(r, cpu_reg(reg), tcg_shift);
> }
> break;
> - case 3:
> - tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
> + case 3: /* ROR */
> + /* For rotation extending doesn't help, we really have to use
> + a 32bit rotate. */
> + if (is_32bit) {
> + TCGv_i32 tmp = tcg_temp_new_i32();
> + tcg_gen_trunc_i64_i32(tmp, cpu_reg(reg));
> + tcg_gen_rotr_i32(tmp, tmp, tcg_shift);
Isn't this problematic?
We are using gen_rotr_i32, but passing tcg_shift, which is a TCGv_i64.
I remember I had compilation failures in the past when I tried something similar,
so my understanding is that this can work with a certain compiler under certain compiler options,
but is not guaranteed to work in all cases.
I think we need to either explicitly convert the tcg_shift to a TCGv_i32, or we need to use an open coded version of the rotr_i64 that inserts at (32 - n) instead of (64 - n)
What do you think?
C.
> + tcg_gen_extu_i32_i64(r, tmp);
> + tcg_temp_free_i32(tmp);
> + } else
> + tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
> break;
> }
>
> -- 1.8.1.4
>
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-11-18 13:43 ` Claudio Fontana
@ 2013-11-18 13:44 ` Peter Maydell
2013-11-18 13:55 ` Michael Matz
1 sibling, 0 replies; 115+ messages in thread
From: Peter Maydell @ 2013-11-18 13:44 UTC (permalink / raw)
To: Claudio Fontana
Cc: Michael Matz, QEMU Developers, Alexander Graf, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On 18 November 2013 13:43, Claudio Fontana <claudio.fontana@linaro.org> wrote:
> We are using gen_rotr_i32, but passing tcg_shift, which is a TCGv_i64.
> I remember I had compilation failures in the past when I tried something similar,
> so my understanding is that this can work with a certain compiler under certain compiler options,
> but is not guaranteed to work in all cases.
It's a debug option -- if you build with --enable-debug
then TCGv_i32/TCGv_i64 mismatches should always cause
compile failures.
-- PMM
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-11-18 13:15 ` Peter Maydell
2013-11-18 13:24 ` Claudio Fontana
@ 2013-11-18 13:46 ` Michael Matz
2013-11-18 13:49 ` Peter Maydell
1 sibling, 1 reply; 115+ messages in thread
From: Michael Matz @ 2013-11-18 13:46 UTC (permalink / raw)
To: Peter Maydell
Cc: QEMU Developers, Alexander Graf, Claudio Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
Hi,
On Mon, 18 Nov 2013, Peter Maydell wrote:
> >> >> + case 3:
> >> >> + tcg_gen_rotr_i64(r, cpu_reg(reg), tcg_shift);
> >> >> + break;
> >> >
> >> > Incorrect rotate for 32bit?
> >
> > 32bit rotates and shifts were fixed in a patch later than the 60er series
> > Alex posted. See attached. (Generally there are many fixes to emulated
> > instructions in that branch)
>
> I think we're going to need to look through and fold in those fixes,
> otherwise we'll end up reduplicating that work in the course of code
> review :-(
Most probably. Authorship will be lost :-/ I was planning to submit all
of these once the 60er set of Alex would be applied. If you're reworking
that set more of less completely then it indeed makes more sense to fold
in those things and so it'd probably be better to have them applied (i.e.
basically have our full branch applied when dissecting things).
The commits that fix things in the a64 decoder proper (not the linux-user
implementation) would be:
e14c1a5 softfloat: correctly handle overflow in float[32|64] to uint64 conversion
cbc98b1 aarch64: Fix FCVTZU for single float
a91f762 aarch64: Fix UZP/ZIP/TRN
644c748 aarch64: Fix 32bit TST
2a717e8 Fix FCVTAS and FCVTAU
0dd22d0 Fix decoding of floating<->fixed conversions
d52c999 Fix implementation of USHLL/SSHLL
cfbb9e1 Fix using uninitialized value
ecfdfcd Fix typo in FSUB detection
87fd8ca Increase MAX_OP_PER_INSTR
38452d8 Fix USHLL, and implement other SIMD shifts
4146d40 Fix INS element
a62437c Fix fcmp(e) with NaNs
ec2b8f3 softfloat: Fix float64_to_uint64
b003867 Fix EXTR for 32bit
df54486 Fix 32bit rotates.
33137f8 Fix the pstate flags helpers
75cb838 Don't set flush to zero by default
564e811 Fix 128bit ldr (literal)
0ff91a0 Fix long immediate constants
(That's all on top Alex' posted patchset but not git rebased onto it, top
of Alex roughly corresponds to commit 40d66b61)
Ciao,
Michael.
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-11-18 13:46 ` Michael Matz
@ 2013-11-18 13:49 ` Peter Maydell
0 siblings, 0 replies; 115+ messages in thread
From: Peter Maydell @ 2013-11-18 13:49 UTC (permalink / raw)
To: Michael Matz
Cc: QEMU Developers, Alexander Graf, Claudio Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On 18 November 2013 13:46, Michael Matz <matz@suse.de> wrote:
> On Mon, 18 Nov 2013, Peter Maydell wrote:
>> I think we're going to need to look through and fold in those fixes,
>> otherwise we'll end up reduplicating that work in the course of code
>> review :-(
>
> Most probably. Authorship will be lost :-/ I was planning to submit all
> of these once the 60er set of Alex would be applied. If you're reworking
> that set more of less completely then it indeed makes more sense to fold
> in those things and so it'd probably be better to have them applied (i.e.
> basically have our full branch applied when dissecting things).
>
> The commits that fix things in the a64 decoder proper (not the linux-user
> implementation) would be:
>
> e14c1a5 softfloat: correctly handle overflow in float[32|64] to uint64 conversion
> cbc98b1 aarch64: Fix FCVTZU for single float
> a91f762 aarch64: Fix UZP/ZIP/TRN
> 644c748 aarch64: Fix 32bit TST
> 2a717e8 Fix FCVTAS and FCVTAU
> 0dd22d0 Fix decoding of floating<->fixed conversions
> d52c999 Fix implementation of USHLL/SSHLL
> cfbb9e1 Fix using uninitialized value
> ecfdfcd Fix typo in FSUB detection
> 87fd8ca Increase MAX_OP_PER_INSTR
> 38452d8 Fix USHLL, and implement other SIMD shifts
> 4146d40 Fix INS element
> a62437c Fix fcmp(e) with NaNs
> ec2b8f3 softfloat: Fix float64_to_uint64
> b003867 Fix EXTR for 32bit
> df54486 Fix 32bit rotates.
> 33137f8 Fix the pstate flags helpers
> 75cb838 Don't set flush to zero by default
> 564e811 Fix 128bit ldr (literal)
> 0ff91a0 Fix long immediate constants
This looks like a small enough list to be tractable to fold
in. My suggestion for authorship would be that we have the
'From' line indicate whoever wrote the bulk of the code and
add sign-off lines from both of you.
(Some of those, like the softfloat fixes, are probably
standalone patches anyway.)
thanks
-- PMM
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-11-18 13:43 ` Claudio Fontana
2013-11-18 13:44 ` Peter Maydell
@ 2013-11-18 13:55 ` Michael Matz
2013-11-18 19:51 ` Richard Henderson
1 sibling, 1 reply; 115+ messages in thread
From: Michael Matz @ 2013-11-18 13:55 UTC (permalink / raw)
To: Claudio Fontana
Cc: Peter Maydell, qemu-devel, Alexander Graf, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
Hi,
On Mon, 18 Nov 2013, Claudio Fontana wrote:
> > + tcg_gen_trunc_i64_i32(tmp, cpu_reg(reg));
> > + tcg_gen_rotr_i32(tmp, tmp, tcg_shift);
>
> Isn't this problematic?
> We are using gen_rotr_i32, but passing tcg_shift, which is a TCGv_i64.
With CONFIG_DEBUG_TCG it'll break, yes. Though in principle there's no
canonical relation between the two argument types for shifts and rotates
(unlike addition for example) TCG indeed wants to ensure that
typeof(arg2)==typeof(arg1).
> I remember I had compilation failures in the past when I tried something
> similar, so my understanding is that this can work with a certain
> compiler under certain compiler options, but is not guaranteed to work
> in all cases.
>
> I think we need to either explicitly convert the tcg_shift to a
> TCGv_i32, or we need to use an open coded version of the rotr_i64 that
> inserts at (32 - n) instead of (64 - n)
>
> What do you think?
I think converting tcg_shift might eventually lead to better generated
code (if tcg is optmizing enough, now or in the future, haven't checked).
Ciao,
Michael.
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation
2013-11-18 13:55 ` Michael Matz
@ 2013-11-18 19:51 ` Richard Henderson
0 siblings, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-11-18 19:51 UTC (permalink / raw)
To: Michael Matz, Claudio Fontana
Cc: Peter Maydell, Alexander Graf, qemu-devel, Dirk Mueller,
Laurent Desnogues, Christoffer Dall
On 11/18/2013 11:55 PM, Michael Matz wrote:
>> > I think we need to either explicitly convert the tcg_shift to a
>> > TCGv_i32, or we need to use an open coded version of the rotr_i64 that
>> > inserts at (32 - n) instead of (64 - n)
>> >
>> > What do you think?
> I think converting tcg_shift might eventually lead to better generated
> code (if tcg is optmizing enough, now or in the future, haven't checked).
Agreed.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 26/60] AArch64: Add ADR instruction emulation
2013-09-27 0:48 ` [Qemu-devel] [PATCH 26/60] AArch64: Add ADR " Alexander Graf
@ 2013-11-19 17:17 ` Claudio Fontana
2013-11-19 17:52 ` Claudio Fontana
2013-11-20 14:40 ` Michael Matz
0 siblings, 2 replies; 115+ messages in thread
From: Claudio Fontana @ 2013-11-19 17:17 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
Hello all,
On 09/27/2013 02:48 AM, Alexander Graf wrote:
> This patch adds emulation support for the adr instruction.
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
> target-arm/translate-a64.c | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index bc91324..00eda0f 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -943,6 +943,27 @@ static void handle_insg(DisasContext *s, uint32_t insn)
> simd_st(cpu_reg(rn), freg_offs_d + idx, size);
> }
>
> +/* PC relative address calculation */
> +static void handle_adr(DisasContext *s, uint32_t insn)
> +{
> + int reg = get_reg(insn);
> + int is_page = get_bits(insn, 31, 1);
> + uint64_t imm;
> + uint64_t base;
> +
> + imm = get_sbits(insn, 5, 19) << 2;
> + imm |= get_bits(insn, 29, 2);
> +
> + base = s->pc - 4;
> + if (is_page) {
> + /* ADRP (page based) */
> + base &= ~0xFFFULL;
> + imm <<= 12;
> + }
> +
> + tcg_gen_movi_i64(cpu_reg(reg), base + imm);
> +}
> +
does this work with negative values?
The spec says to SignExtend:
if page then
imm = SignExtend(immhi:immlo:Zeros(12), 64);
else
imm = SignExtend(immhi:immlo, 64);
/*...*/
maybe Michael you know if this is an issue in practice?
If I want to get a negative PC relative offset, how does this work?
Claudio
> /* SIMD ORR */
> static void handle_simdorr(DisasContext *s, uint32_t insn)
> {
> @@ -1365,6 +1386,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
> unallocated_encoding(s);
> }
> break;
> + case 0x10:
> + handle_adr(s, insn);
> + break;
> default:
> unallocated_encoding(s);
> break;
>
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 26/60] AArch64: Add ADR instruction emulation
2013-11-19 17:17 ` Claudio Fontana
@ 2013-11-19 17:52 ` Claudio Fontana
2013-11-19 18:03 ` Peter Maydell
2013-11-20 14:40 ` Michael Matz
1 sibling, 1 reply; 115+ messages in thread
From: Claudio Fontana @ 2013-11-19 17:52 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, Dirk Mueller,
Laurent Desnogues, Alex Bennée, Christoffer Dall,
Richard Henderson
On 11/19/2013 06:17 PM, Claudio Fontana wrote:
> Hello all,
>
> On 09/27/2013 02:48 AM, Alexander Graf wrote:
>> This patch adds emulation support for the adr instruction.
>>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>> ---
>> target-arm/translate-a64.c | 24 ++++++++++++++++++++++++
>> 1 file changed, 24 insertions(+)
>>
>> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
>> index bc91324..00eda0f 100644
>> --- a/target-arm/translate-a64.c
>> +++ b/target-arm/translate-a64.c
>> @@ -943,6 +943,27 @@ static void handle_insg(DisasContext *s, uint32_t insn)
>> simd_st(cpu_reg(rn), freg_offs_d + idx, size);
>> }
>>
>> +/* PC relative address calculation */
>> +static void handle_adr(DisasContext *s, uint32_t insn)
>> +{
>> + int reg = get_reg(insn);
>> + int is_page = get_bits(insn, 31, 1);
>> + uint64_t imm;
>> + uint64_t base;
>> +
>> + imm = get_sbits(insn, 5, 19) << 2;
>> + imm |= get_bits(insn, 29, 2);
>> +
>> + base = s->pc - 4;
>> + if (is_page) {
>> + /* ADRP (page based) */
>> + base &= ~0xFFFULL;
>> + imm <<= 12;
>> + }
>> +
>> + tcg_gen_movi_i64(cpu_reg(reg), base + imm);
>> +}
>> +
>
> does this work with negative values?
> The spec says to SignExtend:
>
> if page then
> imm = SignExtend(immhi:immlo:Zeros(12), 64);
> else
> imm = SignExtend(immhi:immlo, 64);
>
> /*...*/
>
> maybe Michael you know if this is an issue in practice?
> If I want to get a negative PC relative offset, how does this work?
>
> Claudio
This is a totally untested idea of what I would think/roughly implement:
static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
{
/*
* 31 30 29 28 27 26 25 24 23 5 4 0
* op immlo 1 0 0 0 0 immhi Rd
*/
unsigned int page, imm, rd, len; /* op -> page, immhi:immlo -> imm */
uint64_t base;
sint64_t offset; /* SignExtend(imm) -> offset */
page = insn & (1 << 31) ? 1 : 0;
imm = extract32(insn, 29, 2) + extract32(insn, 5, 19) << 2;
rd = extract32(insn, 0, 5);
base = s->pc - 4;
len = 19 + 2; /* immhi:immlo */
offset = imm;
if (page) {
/* ADRP (page based) */
base &= ~0xfff;
len += 12; /* immhi:immlo:Zeros(12) */
offset <<= 12; /* apply Zeros */
}
offset = (offset << (64 - len)) >> (64 - len); /* sign extend */
tcg_gen_movi_i64(cpu_reg(reg), base + offset);
}
But maybe I am completely off and the original code is perfectly fine..?
C.
>
>
>> /* SIMD ORR */
>> static void handle_simdorr(DisasContext *s, uint32_t insn)
>> {
>> @@ -1365,6 +1386,9 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
>> unallocated_encoding(s);
>> }
>> break;
>> + case 0x10:
>> + handle_adr(s, insn);
>> + break;
>> default:
>> unallocated_encoding(s);
>> break;
>>
>
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 26/60] AArch64: Add ADR instruction emulation
2013-11-19 17:52 ` Claudio Fontana
@ 2013-11-19 18:03 ` Peter Maydell
2013-11-19 18:09 ` Peter Maydell
0 siblings, 1 reply; 115+ messages in thread
From: Peter Maydell @ 2013-11-19 18:03 UTC (permalink / raw)
To: Claudio Fontana
Cc: Michael Matz, Alexander Graf, QEMU Developers, Dirk Mueller,
Laurent Desnogues, Alex Bennée, Christoffer Dall,
Richard Henderson
On 19 November 2013 17:52, Claudio Fontana <claudio.fontana@linaro.org> wrote:
> static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
> {
> /*
> * 31 30 29 28 27 26 25 24 23 5 4 0
> * op immlo 1 0 0 0 0 immhi Rd
> */
> unsigned int page, imm, rd, len; /* op -> page, immhi:immlo -> imm */
> uint64_t base;
> sint64_t offset; /* SignExtend(imm) -> offset */
>
> page = insn & (1 << 31) ? 1 : 0;
> imm = extract32(insn, 29, 2) + extract32(insn, 5, 19) << 2;
> rd = extract32(insn, 0, 5);
Claiming you want sign extension and not using sextract32()
is a bit odd.
>
> base = s->pc - 4;
> len = 19 + 2; /* immhi:immlo */
> offset = imm;
>
> if (page) {
> /* ADRP (page based) */
> base &= ~0xfff;
> len += 12; /* immhi:immlo:Zeros(12) */
> offset <<= 12; /* apply Zeros */
> }
>
> offset = (offset << (64 - len)) >> (64 - len); /* sign extend */
Don't manually sign extend, please.
> tcg_gen_movi_i64(cpu_reg(reg), base + offset);
> }
thanks
-- PMM
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 26/60] AArch64: Add ADR instruction emulation
2013-11-19 18:03 ` Peter Maydell
@ 2013-11-19 18:09 ` Peter Maydell
0 siblings, 0 replies; 115+ messages in thread
From: Peter Maydell @ 2013-11-19 18:09 UTC (permalink / raw)
To: Claudio Fontana
Cc: Michael Matz, Alexander Graf, QEMU Developers, Dirk Mueller,
Laurent Desnogues, Alex Bennée, Christoffer Dall,
Richard Henderson
On 19 November 2013 18:03, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 19 November 2013 17:52, Claudio Fontana <claudio.fontana@linaro.org> wrote:
>> static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
>> {
>> /*
>> * 31 30 29 28 27 26 25 24 23 5 4 0
>> * op immlo 1 0 0 0 0 immhi Rd
>> */
>> unsigned int page, imm, rd, len; /* op -> page, immhi:immlo -> imm */
>> uint64_t base;
>> sint64_t offset; /* SignExtend(imm) -> offset */
>>
>> page = insn & (1 << 31) ? 1 : 0;
>> imm = extract32(insn, 29, 2) + extract32(insn, 5, 19) << 2;
>> rd = extract32(insn, 0, 5);
>
> Claiming you want sign extension and not using sextract32()
> is a bit odd.
...to be a bit more specific, you can get the immediate
into a signed 64 bit variable like this:
int64_t imm = (sextract32(insn, 5, 19) << 2)
| extract32(insn, 29, 2);
if (page) {
imm <<= 12;
}
which is exactly what Alex's original patch does, except
it's not using the standard sextract/extract functions
(probably because they weren't in master at the point he
wrote it).
thanks
-- PMM
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 23/60] AArch64: Add AdvSIMD modified immediate group handling
2013-09-27 0:48 ` [Qemu-devel] [PATCH 23/60] AArch64: Add AdvSIMD modified immediate " Alexander Graf
@ 2013-11-19 20:23 ` Janne Grunau
0 siblings, 0 replies; 115+ messages in thread
From: Janne Grunau @ 2013-11-19 20:23 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On 2013-09-27 02:48:17 +0200, Alexander Graf wrote:
> This patch adds support for the AdvSIMD modified immediate group with
> all its suboperations (movi, orr, fmov, mvni, bic).
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
> target-arm/translate-a64.c | 129 +++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 129 insertions(+)
>
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index 9d6edf4..50561cf 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -1055,6 +1055,127 @@ static void handle_simd3su0(DisasContext *s, uint32_t insn)
> tcg_temp_free_i64(tcg_res);
> }
>
> +/* AdvSIMD modified immediate */
> +static void handle_simdmodi(DisasContext *s, uint32_t insn)
> +{
> + int rd = get_bits(insn, 0, 5);
> + int cmode = get_bits(insn, 12, 4);
> + uint64_t abcdefgh = get_bits(insn, 5, 5) | (get_bits(insn, 16, 3) << 5);
> + bool is_neg = get_bits(insn, 29, 1);
> + bool is_q = get_bits(insn, 30, 1);
> + int freg_offs_d = offsetof(CPUARMState, vfp.regs[rd * 2]);
> + uint64_t imm = 0;
> + int shift, i;
> + TCGv_i64 tcg_op1_1 = tcg_temp_new_i64();
> + TCGv_i64 tcg_op1_2 = tcg_temp_new_i64();
> + TCGv_i64 tcg_res_1 = tcg_temp_new_i64();
> + TCGv_i64 tcg_res_2 = tcg_temp_new_i64();
> + TCGv_i64 tcg_imm;
> +
> + switch ((cmode >> 1) & 0x7) {
> + case 0:
> + case 1:
> + case 2:
> + case 3:
> + shift = ((cmode >> 1) & 0x7) * 8;
> + imm = (abcdefgh << shift) | (abcdefgh << (32 + shift));
> + break;
> + case 4:
> + case 5:
> + shift = ((cmode >> 1) & 0x1) * 8;
> + imm = (abcdefgh << shift) |
> + (abcdefgh << (16 + shift)) |
> + (abcdefgh << (32 + shift)) |
> + (abcdefgh << (48 + shift));
> + break;
> + case 6:
> + if (cmode & 1) {
> + imm = (abcdefgh << 8) |
> + (abcdefgh << 48) |
> + 0x000000ff000000ffULL;
> + } else {
> + imm = (abcdefgh << 16) |
> + (abcdefgh << 56) |
> + 0x0000ffff0000ffffULL;
> + }
> + break;
> + case 7:
> + if (!(cmode & 1) && !is_neg) {
> + imm = abcdefgh |
> + (abcdefgh << 8) |
> + (abcdefgh << 16) |
> + (abcdefgh << 24) |
> + (abcdefgh << 32) |
> + (abcdefgh << 40) |
> + (abcdefgh << 48) |
> + (abcdefgh << 56);
> + } else if (!(cmode & 1) && is_neg) {
> + imm = 0;
> + for (i = 0; i < 8; i++) {
> + if ((abcdefgh) & (1 << (7 - i))) {
> + imm |= 0xffULL << (i * 8);
byte order inverted, Feel free to squash
http://git.jannau.net/qemu.git/commit/?h=aarch64-tcg-batch1-v3-fixes&id=07075bee423954a3b0f7ee6682c7a1ca555055ce
> + }
> + }
> + } else if (cmode & 1) {
> + shift = is_neg ? 48 : 19;
> + imm = (abcdefgh & 0x1f) << 19;
> + if (abcdefgh & 0x80) {
> + imm |= 0x80000000;
> + }
> + if (!(abcdefgh & 0x40)) {
> + imm |= 0x40000000;
> + }
> + if (abcdefgh & 0x20) {
> + imm |= is_neg ? 0x3fc00000 : 0x3e000000;
> + }
> + imm |= (imm << 32);
> + }
> + shift = ((cmode >> 1) & 0x1) * 8;
> + break;
> + }
> +
> + if (is_neg) {
> + imm = ~imm;
> + }
this is not true for 64 bit immediates, see
http://git.jannau.net/qemu.git/commit/?h=aarch64-tcg-batch1-v3-fixes&id=c7598a9c2afdc66ddc11cfad328f3e9722bca129
Janne
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 50/60] AArch64: Add "Floating-point<->fixed-point
2013-09-27 0:48 ` [Qemu-devel] [PATCH 50/60] AArch64: Add "Floating-point<->fixed-point Alexander Graf
@ 2013-11-19 20:41 ` Janne Grunau
2013-11-20 14:47 ` Michael Matz
0 siblings, 1 reply; 115+ messages in thread
From: Janne Grunau @ 2013-11-19 20:41 UTC (permalink / raw)
To: Alexander Graf
Cc: Peter Maydell, Michael Matz, qemu-devel, C Fontana, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
On 2013-09-27 02:48:44 +0200, Alexander Graf wrote:
> This patch adds emulation for the instruction group labeled
> "Floating-point <-> fixed-point conversions" in the ARM ARM.
>
> Namely this includes the instructions SCVTF, UCVTF, FCVTZS, FCVTZU
> (scalar, fixed-point).
>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---
> target-arm/helper-a64.c | 22 ++++++
> target-arm/helper-a64.h | 1 +
> target-arm/translate-a64.c | 173 +++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 196 insertions(+)
>
> diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
> index a46b00e..0b7aee1 100644
> --- a/target-arm/helper-a64.c
> +++ b/target-arm/helper-a64.c
> @@ -275,3 +275,25 @@ uint64_t HELPER(smulh)(uint64_t n, uint64_t m)
> muls64(&rl, &rh, n, m);
> return rh;
> }
> +
> +void HELPER(set_rmode)(uint32_t rmode, void *fp_status)
> +{
> + switch (rmode) {
> + case ROUND_MODE_TIEEVEN:
> + default:
> + rmode = float_round_nearest_even;
> + break;
> + case ROUND_MODE_UP:
> + rmode = float_round_up;
> + break;
> + case ROUND_MODE_DOWN:
> + rmode = float_round_down;
> + break;
> + case ROUND_MODE_ZERO:
> + rmode = float_round_to_zero;
> + break;
> + /* XXX add fpcr rounding (exact and not exact) */
> + }
> +
> + set_float_rounding_mode(rmode, fp_status);
> +}
> diff --git a/target-arm/helper-a64.h b/target-arm/helper-a64.h
> index 41dedd7..f42edf8 100644
> --- a/target-arm/helper-a64.h
> +++ b/target-arm/helper-a64.h
> @@ -30,3 +30,4 @@ DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
> DEF_HELPER_FLAGS_1(clz64, TCG_CALL_NO_RWG_SE, i64, i64)
> DEF_HELPER_FLAGS_2(umulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
> DEF_HELPER_FLAGS_2(smulh, TCG_CALL_NO_RWG_SE, i64, i64, i64)
> +DEF_HELPER_2(set_rmode, void, i32, ptr)
> diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
> index 5985c01..654e011 100644
> --- a/target-arm/translate-a64.c
> +++ b/target-arm/translate-a64.c
> @@ -183,6 +183,17 @@ static void clear_fpreg(int dest)
> tcg_gen_st_i64(tcg_zero, cpu_env, freg_offs + sizeof(float64));
> }
>
> +static TCGv_ptr get_fpstatus_ptr(void)
> +{
> + TCGv_ptr statusptr = tcg_temp_new_ptr();
> + int offset;
> +
> + offset = offsetof(CPUARMState, vfp.standard_fp_status);
> + tcg_gen_addi_ptr(statusptr, cpu_env, offset);
> +
> + return statusptr;
> +}
> +
> static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
> {
> TranslationBlock *tb;
> @@ -1718,6 +1729,161 @@ static void handle_dp3s(DisasContext *s, uint32_t insn)
> tcg_temp_free_i64(tcg_tmp);
> }
>
> +static void handle_fpfpcvt(DisasContext *s, uint32_t insn, bool direction,
> + int rmode)
> +{
> + int rd = get_reg(insn);
> + int rn = get_bits(insn, 5, 5);
> + int scale = get_bits(insn, 10, 6);
> + int opcode = get_bits(insn, 16, 3);
> + int type = get_bits(insn, 22, 2);
> + bool is_32bit = !get_bits(insn, 31, 1);
> + bool is_double = get_bits(type, 0, 1);
> + bool is_signed = !get_bits(opcode, 0, 1);
> + int freg_offs;
> + int fp_reg;
> + TCGv_i64 tcg_int;
> + TCGv_i64 tcg_single;
> + TCGv_i64 tcg_double;
> + TCGv_i64 tcg_fpstatus = get_fpstatus_ptr();
> + TCGv_i32 tcg_shift = tcg_const_i32(scale);
shift/fractional bits are encoded encoded as 64 - scale for fixed point
to float conversion
feel free to grab
http://git.jannau.net/qemu.git/commit/?h=aarch64-tcg-batch1-v3-fixes&id=16ff73c6801c0c0b677216457dacb64a7d310ad1
> + TCGv_i32 tcg_rmode = tcg_const_i32(rmode);
> + TCGv_i64 tcg_tmp;
> +
> + if (direction) {
> + fp_reg = rn;
> + tcg_int = cpu_reg(rd);
> + } else {
> + fp_reg = rd;
> + tcg_int = cpu_reg(rn);
> + }
> + freg_offs = offsetof(CPUARMState, vfp.regs[fp_reg * 2]);
> +
> + if (!direction) {
> + clear_fpreg(fp_reg);
> + }
> +
> + if (is_32bit && !direction) {
> + tcg_tmp = tcg_temp_new_i64();
> + if (is_signed) {
> + tcg_gen_ext32s_i64(tcg_tmp, tcg_int);
> + } else {
> + tcg_gen_ext32u_i64(tcg_tmp, tcg_int);
> + }
> + tcg_int = tcg_tmp;
> + }
> +
> + gen_helper_set_rmode(tcg_rmode, tcg_fpstatus);
> +
> + switch ((direction ? 0x10 : 0)|
> + (is_double ? 0x1 : 0) |
> + (is_signed ? 0x2 : 0)) {
> + case 0x0: /* unsigned scalar->single */
> + tcg_single = tcg_temp_new_i32();
> + tcg_tmp = tcg_temp_new_i64();
> + gen_helper_vfp_uqtos(tcg_single, tcg_int, tcg_shift, tcg_fpstatus);
> + tcg_gen_extu_i32_i64(tcg_tmp, tcg_single);
> + tcg_gen_st32_i64(tcg_tmp, cpu_env, freg_offs);
> + tcg_temp_free_i32(tcg_single);
> + tcg_temp_free_i64(tcg_tmp);
> + break;
> + case 0x1: /* unsigned scalar->double */
> + tcg_double = tcg_temp_new_i64();
> + gen_helper_vfp_uqtod(tcg_double, tcg_int, tcg_shift, tcg_fpstatus);
> + tcg_gen_st_i64(tcg_double, cpu_env, freg_offs);
> + tcg_temp_free_i64(tcg_double);
> + break;
> + case 0x2: /* signed scalar->single */
> + tcg_single = tcg_temp_new_i32();
> + tcg_tmp = tcg_temp_new_i64();
> + gen_helper_vfp_sqtos(tcg_single, tcg_int, tcg_shift, tcg_fpstatus);
> + tcg_gen_extu_i32_i64(tcg_tmp, tcg_single);
> + tcg_gen_st32_i64(tcg_tmp, cpu_env, freg_offs);
> + tcg_temp_free_i32(tcg_single);
> + tcg_temp_free_i64(tcg_tmp);
> + break;
> + case 0x3: /* signed scalar->double */
> + tcg_double = tcg_temp_new_i64();
> + gen_helper_vfp_sqtod(tcg_double, tcg_int, tcg_shift, tcg_fpstatus);
> + tcg_gen_st_i64(tcg_double, cpu_env, freg_offs);
> + tcg_temp_free_i64(tcg_double);
> + break;
> + case 0x10: /* unsigned single->scalar */
> + tcg_single = tcg_temp_new_i32();
> + tcg_tmp = tcg_temp_new_i64();
> + tcg_gen_ld32u_i64(tcg_tmp, cpu_env, freg_offs);
> + tcg_gen_trunc_i64_i32(tcg_single, tcg_tmp);
> + gen_helper_vfp_touqs(tcg_int, tcg_single, tcg_shift, tcg_fpstatus);
> + tcg_temp_free_i32(tcg_single);
> + tcg_temp_free_i64(tcg_tmp);
> + break;
> + case 0x11: /* unsigned single->double */
> + tcg_double = tcg_temp_new_i64();
> + tcg_gen_ld_i64(tcg_double, cpu_env, freg_offs);
> + gen_helper_vfp_touqd(tcg_int, tcg_double, tcg_shift, tcg_fpstatus);
> + tcg_temp_free_i64(tcg_double);
> + break;
> + case 0x12: /* signed single->scalar */
> + tcg_single = tcg_temp_new_i32();
> + tcg_tmp = tcg_temp_new_i64();
> + tcg_gen_ld32u_i64(tcg_tmp, cpu_env, freg_offs);
> + tcg_gen_trunc_i64_i32(tcg_single, tcg_tmp);
> + gen_helper_vfp_tosqs(tcg_int, tcg_single, tcg_shift, tcg_fpstatus);
> + tcg_temp_free_i32(tcg_single);
> + tcg_temp_free_i64(tcg_tmp);
> + break;
> + case 0x13: /* signed single->double */
> + tcg_double = tcg_temp_new_i64();
> + tcg_gen_ld_i64(tcg_double, cpu_env, freg_offs);
> + gen_helper_vfp_tosqd(tcg_int, tcg_double, tcg_shift, tcg_fpstatus);
> + tcg_temp_free_i64(tcg_double);
> + break;
> + default:
> + unallocated_encoding(s);
> + }
> +
> + /* XXX use fpcr */
> + tcg_gen_movi_i32(tcg_rmode, -1);
> + gen_helper_set_rmode(tcg_rmode, tcg_fpstatus);
> +
> + if (is_32bit && direction) {
> + tcg_gen_ext32u_i64(tcg_int, tcg_int);
> + }
> +
> + tcg_temp_free_i64(tcg_fpstatus);
> + tcg_temp_free_i32(tcg_shift);
> + tcg_temp_free_i32(tcg_rmode);
> +}
> +
> +/* fixed <-> floating conversion */
> +static void handle_fpfpconv(DisasContext *s, uint32_t insn)
> +{
> + int opcode = get_bits(insn, 16, 3);
> + int rmode = get_bits(insn, 20, 2);
rmode is at 19
> + int type = get_bits(insn, 22, 2);
> + bool is_s = get_bits(insn, 29, 1);
> + bool direction;
> +
> + if (is_s || (type > 1) || (opcode > 1)) {
> + unallocated_encoding(s);
> + return;
> + }
> +
> + switch (rmode) {
> + case 0x1: /* [S|U]CVTF (scalar->float) */
and it's case 0x0: for [S|U]CVTF
see
http://git.jannau.net/qemu.git/commit/?h=aarch64-tcg-batch1-v3-fixes&id=69cd918ae935e98dc5245f5d594a0e4162f65d59
> + direction = 0;
> + break;
> + case 0x3: /* FCVTZ[S|U] (float->scalar) */
The comments don't make much sense it's scalar (opposed to vector) float
to fixed point conversion
Janne
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 26/60] AArch64: Add ADR instruction emulation
2013-11-19 17:17 ` Claudio Fontana
2013-11-19 17:52 ` Claudio Fontana
@ 2013-11-20 14:40 ` Michael Matz
1 sibling, 0 replies; 115+ messages in thread
From: Michael Matz @ 2013-11-20 14:40 UTC (permalink / raw)
To: Claudio Fontana
Cc: Peter Maydell, Alexander Graf, qemu-devel, Dirk Mueller,
Laurent Desnogues, Christoffer Dall, Richard Henderson
Hi,
On Tue, 19 Nov 2013, Claudio Fontana wrote:
> > + uint64_t imm;
> > + uint64_t base;
> > +
> > + imm = get_sbits(insn, 5, 19) << 2;
> > + imm |= get_bits(insn, 29, 2);
>
> does this work with negative values?
Yes. get_sbits returns a sign extended (32bit) int, the shift doesn't
change that, the conversion to uint64_t first sign extends to 64bit and
then converts to unsigned (conceptually). From then on it's an unsigned
value (with high bits set when input was negative), but two complement
arithmetic makes that irrelevant.
Ciao,
Michael.
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 50/60] AArch64: Add "Floating-point<->fixed-point
2013-11-19 20:41 ` Janne Grunau
@ 2013-11-20 14:47 ` Michael Matz
2013-11-21 12:34 ` Janne Grunau
0 siblings, 1 reply; 115+ messages in thread
From: Michael Matz @ 2013-11-20 14:47 UTC (permalink / raw)
To: Janne Grunau
Cc: Peter Maydell, Alexander Graf, qemu-devel, C Fontana,
Dirk Mueller, Laurent Desnogues, Christoffer Dall,
Richard Henderson
Hi,
On Tue, 19 Nov 2013, Janne Grunau wrote:
> > +static void handle_fpfpconv(DisasContext *s, uint32_t insn)
> > +{
> > + int opcode = get_bits(insn, 16, 3);
> > + int rmode = get_bits(insn, 20, 2);
>
> rmode is at 19
>
> > + case 0x1: /* [S|U]CVTF (scalar->float) */
>
> and it's case 0x0: for [S|U]CVTF
Both were fixed after Alex' series with 0dd22d0c:
https://github.com/susematz/qemu/commit/0dd22d0c5cd1dcdccd5df953f1981d461d3054e5
Ciao,
Michael.
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 50/60] AArch64: Add "Floating-point<->fixed-point
2013-11-20 14:47 ` Michael Matz
@ 2013-11-21 12:34 ` Janne Grunau
2013-11-21 12:40 ` Peter Maydell
0 siblings, 1 reply; 115+ messages in thread
From: Janne Grunau @ 2013-11-21 12:34 UTC (permalink / raw)
To: Michael Matz
Cc: Peter Maydell, Alexander Graf, qemu-devel, C Fontana,
Dirk Mueller, Laurent Desnogues, Christoffer Dall,
Richard Henderson
On 2013-11-20 15:47:18 +0100, Michael Matz wrote:
> Hi,
>
> On Tue, 19 Nov 2013, Janne Grunau wrote:
>
> > > +static void handle_fpfpconv(DisasContext *s, uint32_t insn)
> > > +{
> > > + int opcode = get_bits(insn, 16, 3);
> > > + int rmode = get_bits(insn, 20, 2);
> >
> > rmode is at 19
> >
> > > + case 0x1: /* [S|U]CVTF (scalar->float) */
> >
> > and it's case 0x0: for [S|U]CVTF
>
> Both were fixed after Alex' series with 0dd22d0c:
> https://github.com/susematz/qemu/commit/0dd22d0c5cd1dcdccd5df953f1981d461d3054e5
wouldn't make sense to squash that fix into this patch? I'm not used to
the qemu development model but committing patches with already fixed
issues looks strange to me. Unless it's planned to fold the entire patch
series into one large commit.
Janne
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 50/60] AArch64: Add "Floating-point<->fixed-point
2013-11-21 12:34 ` Janne Grunau
@ 2013-11-21 12:40 ` Peter Maydell
0 siblings, 0 replies; 115+ messages in thread
From: Peter Maydell @ 2013-11-21 12:40 UTC (permalink / raw)
To: Janne Grunau
Cc: Michael Matz, Alexander Graf, QEMU Developers, C Fontana,
Dirk Mueller, Laurent Desnogues, Christoffer Dall,
Richard Henderson
On 21 November 2013 12:34, Janne Grunau <j@jannau.net> wrote:
> wouldn't make sense to squash that fix into this patch? I'm not used to
> the qemu development model but committing patches with already fixed
> issues looks strange to me. Unless it's planned to fold the entire patch
> series into one large commit.
Yes, we intend as part of the cleanup of this patch
series to fold in any later fixes where that makes
sense.
-- PMM
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 29/60] AArch64: Add orri instruction emulation
2013-09-27 19:42 ` Richard Henderson
@ 2013-11-26 11:56 ` Claudio Fontana
2013-11-26 12:05 ` Laurent Desnogues
2013-11-27 21:56 ` Richard Henderson
0 siblings, 2 replies; 115+ messages in thread
From: Claudio Fontana @ 2013-11-26 11:56 UTC (permalink / raw)
To: Richard Henderson
Cc: Peter Maydell, Michael Matz, Alexander Graf, qemu-devel,
Dirk Mueller, Laurent Desnogues, Christoffer Dall
On 09/27/2013 09:42 PM, Richard Henderson wrote:
> On 09/26/2013 05:48 PM, Alexander Graf wrote:
>> + if (setflags) {
>> + tcg_dst = cpu_reg(dest);
>> + } else {
>> + tcg_dst = cpu_reg_sp(dest);
>> + }
>
> Never sp for logicals.
This should be ok in my view, the manual explicitly shows in the pseudocode:
if d == 31 && !setflags then
SP[] = result;
else
X[d] = result;
Claudio
>
>> + handle_orri(s, insn);
>
> And yet again, a better function name.
>
>
> r~
>
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 29/60] AArch64: Add orri instruction emulation
2013-11-26 11:56 ` Claudio Fontana
@ 2013-11-26 12:05 ` Laurent Desnogues
2013-11-27 21:56 ` Richard Henderson
1 sibling, 0 replies; 115+ messages in thread
From: Laurent Desnogues @ 2013-11-26 12:05 UTC (permalink / raw)
To: Claudio Fontana
Cc: Peter Maydell, Michael Matz, qemu-devel@nongnu.org,
Alexander Graf, Dirk Mueller, Christoffer Dall, Richard Henderson
On Tue, Nov 26, 2013 at 12:56 PM, Claudio Fontana
<claudio.fontana@linaro.org> wrote:
> On 09/27/2013 09:42 PM, Richard Henderson wrote:
>> On 09/26/2013 05:48 PM, Alexander Graf wrote:
>>> + if (setflags) {
>>> + tcg_dst = cpu_reg(dest);
>>> + } else {
>>> + tcg_dst = cpu_reg_sp(dest);
>>> + }
>>
>> Never sp for logicals.
>
> This should be ok in my view, the manual explicitly shows in the pseudocode:
>
> if d == 31 && !setflags then
> SP[] = result;
> else
> X[d] = result;
Agreed: for immediate logical instructions, destination can be SP
except for ANDS. ANDS with destination as r31 is aliased to TST.
Laurent
> Claudio
>
>>
>>> + handle_orri(s, insn);
>>
>> And yet again, a better function name.
>>
>>
>> r~
>>
>
^ permalink raw reply [flat|nested] 115+ messages in thread
* Re: [Qemu-devel] [PATCH 29/60] AArch64: Add orri instruction emulation
2013-11-26 11:56 ` Claudio Fontana
2013-11-26 12:05 ` Laurent Desnogues
@ 2013-11-27 21:56 ` Richard Henderson
1 sibling, 0 replies; 115+ messages in thread
From: Richard Henderson @ 2013-11-27 21:56 UTC (permalink / raw)
To: Claudio Fontana
Cc: Peter Maydell, Michael Matz, Alexander Graf, qemu-devel,
Dirk Mueller, Laurent Desnogues, Christoffer Dall
On 11/27/2013 12:56 AM, Claudio Fontana wrote:
> On 09/27/2013 09:42 PM, Richard Henderson wrote:
>> On 09/26/2013 05:48 PM, Alexander Graf wrote:
>>> + if (setflags) {
>>> + tcg_dst = cpu_reg(dest);
>>> + } else {
>>> + tcg_dst = cpu_reg_sp(dest);
>>> + }
>>
>> Never sp for logicals.
>
> This should be ok in my view, the manual explicitly shows in the pseudocode:
>
> if d == 31 && !setflags then
> SP[] = result;
> else
> X[d] = result;
Sure enough. I mis-read that Logical (register) and Logical (immediate) are
different in their ability to use XSP as an output.
r~
^ permalink raw reply [flat|nested] 115+ messages in thread
end of thread, other threads:[~2013-11-27 21:56 UTC | newest]
Thread overview: 115+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-27 0:47 [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
2013-09-27 0:47 ` [Qemu-devel] [PATCH 01/60] arm: Use symbolic device names for vfp cmp Alexander Graf
2013-09-27 0:47 ` [Qemu-devel] [PATCH 02/60] arm: Give the fpscr rounding modes names Alexander Graf
2013-09-27 0:47 ` [Qemu-devel] [PATCH 03/60] arm: Split VFP cmp from FPSCR setting Alexander Graf
2013-09-27 14:05 ` Richard Henderson
2013-09-27 22:38 ` Richard Henderson
2013-09-27 0:47 ` [Qemu-devel] [PATCH 04/60] arm: Add AArch64 disassembler stub Alexander Graf
2013-09-27 14:07 ` Richard Henderson
2013-09-27 0:47 ` [Qemu-devel] [PATCH 05/60] softfloat: Add stubs for int16 conversion Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 06/60] AArch64: Add set_pc cpu method Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 07/60] ARM: Add 64bit VFP handling Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 08/60] AArch64: Add support to print VFP registers in CPU Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 09/60] AArch64: Add b and bl handling Alexander Graf
2013-09-27 9:11 ` Claudio Fontana
2013-09-27 14:40 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 10/60] AArch64: Add handling for br instructions Alexander Graf
2013-09-27 14:51 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 11/60] AArch64: Add STP instruction emulation Alexander Graf
2013-09-27 17:38 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 12/60] AArch64: Add ldarx style " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 13/60] AArch64: Add stubs for a64 specific helpers Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 14/60] AArch64: Add orr instruction emulation Alexander Graf
2013-09-27 18:25 ` Richard Henderson
2013-10-31 0:29 ` Alexander Graf
2013-10-31 1:44 ` Peter Maydell
2013-11-18 10:15 ` Claudio Fontana
2013-11-18 10:37 ` Laurent Desnogues
2013-11-18 13:12 ` Michael Matz
2013-11-18 13:15 ` Peter Maydell
2013-11-18 13:24 ` Claudio Fontana
2013-11-18 13:46 ` Michael Matz
2013-11-18 13:49 ` Peter Maydell
2013-11-18 13:43 ` Claudio Fontana
2013-11-18 13:44 ` Peter Maydell
2013-11-18 13:55 ` Michael Matz
2013-11-18 19:51 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 15/60] AArch64: Add add instruction family emulation Alexander Graf
2013-09-27 18:51 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 16/60] AArch64: Add emulation for SIMD ld/st multiple Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 17/60] AArch64: Add dup GPR->Vec instruction emulation Alexander Graf
2013-09-27 18:55 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 18/60] AArch64: Add umov " Alexander Graf
2013-09-27 18:56 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 19/60] AArch64: Add ins GPR->Vec " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 20/60] AArch64: Add SIMD ORR family " Alexander Graf
2013-09-27 19:21 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 21/60] AArch64: Convert SIMD load/store to common function Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 22/60] AArch64: Add AdvSIMD scalar three same group handling Alexander Graf
2013-09-27 19:24 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 23/60] AArch64: Add AdvSIMD modified immediate " Alexander Graf
2013-11-19 20:23 ` Janne Grunau
2013-09-27 0:48 ` [Qemu-devel] [PATCH 24/60] AArch64: Add SIMD ushll instruction emulation Alexander Graf
2013-09-27 19:29 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 25/60] AArch64: Add SIMD shl " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 26/60] AArch64: Add ADR " Alexander Graf
2013-11-19 17:17 ` Claudio Fontana
2013-11-19 17:52 ` Claudio Fontana
2013-11-19 18:03 ` Peter Maydell
2013-11-19 18:09 ` Peter Maydell
2013-11-20 14:40 ` Michael Matz
2013-09-27 0:48 ` [Qemu-devel] [PATCH 27/60] AArch64: Add addi " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 28/60] AArch64: Add movi " Alexander Graf
2013-09-27 19:38 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 29/60] AArch64: Add orri " Alexander Graf
2013-09-27 19:42 ` Richard Henderson
2013-11-26 11:56 ` Claudio Fontana
2013-11-26 12:05 ` Laurent Desnogues
2013-11-27 21:56 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 30/60] AArch64: Add extr " Alexander Graf
2013-09-27 19:45 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 31/60] AArch64: Add bfm family " Alexander Graf
2013-09-27 20:01 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 32/60] AArch64: Add svc " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 33/60] AArch64: Add bc " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 34/60] AArch64: Add b.cond " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 35/60] AArch64: Add mrs " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 36/60] AArch64: Add msr " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 37/60] AArch64: Add hint " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 38/60] AArch64: Add stub barrier " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 39/60] AArch64: Add stub sys " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 40/60] AArch64: Add tbz " Alexander Graf
2013-09-27 20:50 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 41/60] AArch64: Add ldr/str instruction family emulation Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 42/60] AArch64: Add literal ld instruction emulation Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 43/60] AArch64: Add cinc " Alexander Graf
2013-09-27 20:52 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 44/60] AArch64: Add division instruction family emulation Alexander Graf
2013-09-27 20:54 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 45/60] AArch64: Add shift " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 46/60] AArch64: Add rev " Alexander Graf
2013-09-27 21:07 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 47/60] AArch64: Add clz instruction emulation Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 48/60] AArch64: Add 0x1a encoding of add instructions Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 49/60] AArch64: Add "Data-processing (3 source)" instruction Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 50/60] AArch64: Add "Floating-point<->fixed-point Alexander Graf
2013-11-19 20:41 ` Janne Grunau
2013-11-20 14:47 ` Michael Matz
2013-11-21 12:34 ` Janne Grunau
2013-11-21 12:40 ` Peter Maydell
2013-09-27 0:48 ` [Qemu-devel] [PATCH 51/60] AArch64: Add fmov (scalar, immediate) instruction Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 52/60] AArch64: Add "Floating-point<->integer conversions" Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 53/60] AArch64: Add "Floating-point compare" instruction Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 54/60] AArch64: Add "Floating-point data-processing (1 Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 55/60] " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 56/60] AArch64: Add "Floating-point data-processing (2 Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 57/60] " Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 58/60] AArch64: Add "ADD (vector)" instruction emulation Alexander Graf
2013-09-27 0:48 ` [Qemu-devel] [PATCH 59/60] AArch64: Add "Floating-point data-processing (3 Alexander Graf
2013-09-27 21:34 ` Richard Henderson
2013-09-27 0:48 ` [Qemu-devel] [PATCH 60/60] " Alexander Graf
2013-09-27 1:02 ` [Qemu-devel] [PATCH 00/60] AArch64 TCG emulation support Alexander Graf
2013-09-27 2:30 ` Peter Maydell
2013-09-27 10:39 ` Alexander Graf
2013-10-16 19:54 ` Edgar E. Iglesias
2013-10-17 12:23 ` Alexander Graf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).