qemu/target
Peter Maydell 5288145d71 target/arm: Fix SMLAD incorrect setting of Q bit
The SMLAD instruction is supposed to:
 * signed multiply Rn[15:0] * Rm[15:0]
 * signed multiply Rn[31:16] * Rm[31:16]
 * perform a signed addition of the products and Ra
 * set Rd to the low 32 bits of the theoretical
   infinite-precision result
 * set the Q flag if the sign-extension of Rd
   would differ from the infinite-precision result
   (ie on overflow)

Our current implementation doesn't quite do this, though: it performs
an addition of the products setting Q on overflow, and then it adds
Ra, again possibly setting Q.  This sometimes incorrectly sets Q when
the architecturally mandated only-check-for-overflow-once algorithm
does not. For instance:
 r1 = 0x80008000; r2 = 0x80008000; r3 = 0xffffffff
 smlad r0, r1, r2, r3
This is (-32768 * -32768) + (-32768 * -32768) - 1

The products are both 0x4000_0000, so when added together as 32-bit
signed numbers they overflow (and QEMU sets Q), but because the
addition of Ra == -1 brings the total back down to 0x7fff_ffff
there is no overflow for the complete operation and setting Q is
incorrect.

Fix this edge case by resorting to 64-bit arithmetic for the
case where we need to add three values together.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20201009144712.11187-1-peter.maydell@linaro.org
2020-10-20 16:12:00 +01:00
..
alpha cpu-timers, icount: new modules 2020-10-05 16:41:22 +02:00
arm target/arm: Fix SMLAD incorrect setting of Q bit 2020-10-20 16:12:00 +01:00
avr qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
cris qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
hppa qemu/atomic.h: rename atomic_ to qatomic_ 2020-09-23 16:07:44 +01:00
i386 * Drop ninjatool and just require ninja (Paolo) 2020-10-17 20:52:55 +01:00
lm32 qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
m68k qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
microblaze qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
mips target/mips: Increase number of TLB entries on the 34Kf core (16 -> 64) 2020-10-17 13:59:40 +02:00
moxie qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
nios2 qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
openrisc qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
ppc ppc: Fix return value in cpu_post_load() error path 2020-10-09 10:15:06 +11:00
riscv icount: rename functions to be consistent with the module name 2020-10-05 16:41:22 +02:00
rx qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
s390x disas: Enable capstone disassembly for s390x 2020-10-03 04:25:14 -05:00
sh4 qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
sparc target/sparc/int32_helper: Remove duplicated 'Tag Overflow' entry 2020-10-13 13:33:46 +02:00
tilegx qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
tricore qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
unicore32 qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros 2020-09-18 14:12:32 -04:00
xtensa qemu/atomic.h: rename atomic_ to qatomic_ 2020-09-23 16:07:44 +01:00
meson.build meson: target 2020-08-21 06:30:35 -04:00