aboutsummaryrefslogtreecommitdiff
path: root/target/arm/translate-vfp.inc.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-06-13 17:39:06 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-06-17 15:14:19 +0100
commitd6a092d479333b5f20a647a912a31b0102d37335 (patch)
tree7f8f03679a881548137229c3b36ca96205ba0799 /target/arm/translate-vfp.inc.c
parent0edfcc9ec06fbbcc154cce64748752a5c565a32c (diff)
downloadqemu-d6a092d479333b5f20a647a912a31b0102d37335.zip
qemu-d6a092d479333b5f20a647a912a31b0102d37335.tar.gz
qemu-d6a092d479333b5f20a647a912a31b0102d37335.tar.bz2
target/arm: Move vfp_expand_imm() to translate.[ch]
We want to use vfp_expand_imm() in the AArch32 VFP decode; move it from the a64-only header/source file to the AArch32 one (which is always compiled even for AArch64). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-id: 20190613163917.28589-2-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/translate-vfp.inc.c')
-rw-r--r--target/arm/translate-vfp.inc.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
index 709fc65..a66084f 100644
--- a/target/arm/translate-vfp.inc.c
+++ b/target/arm/translate-vfp.inc.c
@@ -31,6 +31,39 @@
#include "decode-vfp-uncond.inc.c"
/*
+ * The imm8 encodes the sign bit, enough bits to represent an exponent in
+ * the range 01....1xx to 10....0xx, and the most significant 4 bits of
+ * the mantissa; see VFPExpandImm() in the v8 ARM ARM.
+ */
+uint64_t vfp_expand_imm(int size, uint8_t imm8)
+{
+ uint64_t imm;
+
+ switch (size) {
+ case MO_64:
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
+ (extract32(imm8, 6, 1) ? 0x3fc0 : 0x4000) |
+ extract32(imm8, 0, 6);
+ imm <<= 48;
+ break;
+ case MO_32:
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
+ (extract32(imm8, 6, 1) ? 0x3e00 : 0x4000) |
+ (extract32(imm8, 0, 6) << 3);
+ imm <<= 16;
+ break;
+ case MO_16:
+ imm = (extract32(imm8, 7, 1) ? 0x8000 : 0) |
+ (extract32(imm8, 6, 1) ? 0x3000 : 0x4000) |
+ (extract32(imm8, 0, 6) << 6);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ return imm;
+}
+
+/*
* Return the offset of a 16-bit half of the specified VFP single-precision
* register. If top is true, returns the top 16 bits; otherwise the bottom
* 16 bits.