aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-06-28 14:58:20 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-07-02 11:48:36 +0100
commitdfd66bc0f37dde37b8b2d7bad3a7075332e75fb4 (patch)
treee3c363f88c3b817a2574e750ee37a5e0dcd843a6 /target
parent303db86fc73c68d8774203d4796b9995cc122886 (diff)
downloadqemu-dfd66bc0f37dde37b8b2d7bad3a7075332e75fb4.zip
qemu-dfd66bc0f37dde37b8b2d7bad3a7075332e75fb4.tar.gz
qemu-dfd66bc0f37dde37b8b2d7bad3a7075332e75fb4.tar.bz2
target/arm: Make asimd_imm_const() public
The function asimd_imm_const() in translate-neon.c is an implementation of the pseudocode AdvSIMDExpandImm(), which we will also want for MVE. Move the implementation to translate.c, with a prototype in translate.h. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210628135835.6690-4-peter.maydell@linaro.org
Diffstat (limited to 'target')
-rw-r--r--target/arm/translate-neon.c63
-rw-r--r--target/arm/translate.c57
-rw-r--r--target/arm/translate.h16
3 files changed, 73 insertions, 63 deletions
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
index 633fef3..f915f70 100644
--- a/target/arm/translate-neon.c
+++ b/target/arm/translate-neon.c
@@ -1781,69 +1781,6 @@ DO_FP_2SH(VCVT_UH, gen_helper_gvec_vcvt_uh)
DO_FP_2SH(VCVT_HS, gen_helper_gvec_vcvt_hs)
DO_FP_2SH(VCVT_HU, gen_helper_gvec_vcvt_hu)
-static uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
-{
- /*
- * Expand the encoded constant.
- * Note that cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
- * We choose to not special-case this and will behave as if a
- * valid constant encoding of 0 had been given.
- * cmode = 15 op = 1 must UNDEF; we assume decode has handled that.
- */
- switch (cmode) {
- case 0: case 1:
- /* no-op */
- break;
- case 2: case 3:
- imm <<= 8;
- break;
- case 4: case 5:
- imm <<= 16;
- break;
- case 6: case 7:
- imm <<= 24;
- break;
- case 8: case 9:
- imm |= imm << 16;
- break;
- case 10: case 11:
- imm = (imm << 8) | (imm << 24);
- break;
- case 12:
- imm = (imm << 8) | 0xff;
- break;
- case 13:
- imm = (imm << 16) | 0xffff;
- break;
- case 14:
- if (op) {
- /*
- * This is the only case where the top and bottom 32 bits
- * of the encoded constant differ.
- */
- uint64_t imm64 = 0;
- int n;
-
- for (n = 0; n < 8; n++) {
- if (imm & (1 << n)) {
- imm64 |= (0xffULL << (n * 8));
- }
- }
- return imm64;
- }
- imm |= (imm << 8) | (imm << 16) | (imm << 24);
- break;
- case 15:
- imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
- | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
- break;
- }
- if (op) {
- imm = ~imm;
- }
- return dup_const(MO_32, imm);
-}
-
static bool do_1reg_imm(DisasContext *s, arg_1reg_imm *a,
GVecGen2iFn *fn)
{
diff --git a/target/arm/translate.c b/target/arm/translate.c
index a0c6cfa..95ceb24 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -90,6 +90,63 @@ void arm_translate_init(void)
a64_translate_init();
}
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
+{
+ /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
+ switch (cmode) {
+ case 0: case 1:
+ /* no-op */
+ break;
+ case 2: case 3:
+ imm <<= 8;
+ break;
+ case 4: case 5:
+ imm <<= 16;
+ break;
+ case 6: case 7:
+ imm <<= 24;
+ break;
+ case 8: case 9:
+ imm |= imm << 16;
+ break;
+ case 10: case 11:
+ imm = (imm << 8) | (imm << 24);
+ break;
+ case 12:
+ imm = (imm << 8) | 0xff;
+ break;
+ case 13:
+ imm = (imm << 16) | 0xffff;
+ break;
+ case 14:
+ if (op) {
+ /*
+ * This is the only case where the top and bottom 32 bits
+ * of the encoded constant differ.
+ */
+ uint64_t imm64 = 0;
+ int n;
+
+ for (n = 0; n < 8; n++) {
+ if (imm & (1 << n)) {
+ imm64 |= (0xffULL << (n * 8));
+ }
+ }
+ return imm64;
+ }
+ imm |= (imm << 8) | (imm << 16) | (imm << 24);
+ break;
+ case 15:
+ imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
+ | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
+ break;
+ }
+ if (op) {
+ imm = ~imm;
+ }
+ return dup_const(MO_32, imm);
+}
+
/* Generate a label used for skipping this instruction */
void arm_gen_condlabel(DisasContext *s)
{
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 99c917c..6c8d5f6 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -532,4 +532,20 @@ static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
return opc | s->be_data;
}
+/**
+ * asimd_imm_const: Expand an encoded SIMD constant value
+ *
+ * Expand a SIMD constant value. This is essentially the pseudocode
+ * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
+ * VMVN and VBIC (when cmode < 14 && op == 1).
+ *
+ * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
+ * callers must catch this.
+ *
+ * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
+ * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
+ * we produce an immediate constant value of 0 in these cases.
+ */
+uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
+
#endif /* TARGET_ARM_TRANSLATE_H */