diff options
author | Peter Maydell | 2021-06-28 15:58:20 +0200 |
---|---|---|
committer | Peter Maydell | 2021-07-02 12:48:36 +0200 |
commit | dfd66bc0f37dde37b8b2d7bad3a7075332e75fb4 (patch) | |
tree | e3c363f88c3b817a2574e750ee37a5e0dcd843a6 /target/arm/translate.c | |
parent | target/arm: Fix bugs in MVE VRMLALDAVH, VRMLSLDAVH (diff) | |
download | qemu-dfd66bc0f37dde37b8b2d7bad3a7075332e75fb4.tar.gz qemu-dfd66bc0f37dde37b8b2d7bad3a7075332e75fb4.tar.xz qemu-dfd66bc0f37dde37b8b2d7bad3a7075332e75fb4.zip |
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/arm/translate.c')
-rw-r--r-- | target/arm/translate.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c index a0c6cfa902..95ceb24ec3 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) { |