qemu/target/ppc
Fabiano Rosas 936fda4d77 target/ppc: Fix bcdsub. emulation when result overflows
The commit d03b174a83 (target/ppc: simplify bcdadd/sub functions)
meant to simplify some of the code but it inadvertently altered the
way the CR6 field is set after the operation has overflowed.

The CR6 bits are set based on the *unbounded* result of the operation,
so we need to look at the result before returning from bcd_add_mag,
otherwise we will look at 0 when it overflows.

Consider the following subtraction:

v0 = 0x9999999999999999999999999999999c (maximum positive BCD value)
v1 = 0x0000000000000000000000000000001d (negative one BCD value)
bcdsub. v0,v0,v1,0

The Power ISA 2.07B says:
If the unbounded result is greater than zero, do the following.
  If PS=0, the sign code of the result is set to 0b1100.
  If PS=1, the sign code of the result is set to 0b1111.
  If the operation overflows, CR field 6 is set to 0b0101. Otherwise,
  CR field 6 is set to 0b0100.

POWER9 hardware:
vr0 = 0x0000000000000000000000000000000c (positive zero BCD value)
cr6 = 0b0101 (0x5) (positive, overflow)

QEMU:
vr0 = 0x0000000000000000000000000000000c (positive zero BCD value)
cr6 = 0b0011 (0x3) (zero, overflow) <--- wrong

This patch reverts the part of d03b174a83 that introduced the
problem and adds a test-case to avoid further regressions:

before:
$ make run-tcg-tests-ppc64le-linux-user
(...)
  TEST    bcdsub on ppc64le
bcdsub: qemu/tests/tcg/ppc64le/bcdsub.c:58: test_bcdsub_gt:
Assertion `(cr >> 4) == ((1 << 2) | (1 << 0))' failed.

Fixes: d03b174a83 (target/ppc: simplify bcdadd/sub functions)
Reported-by: Paul Clarke <pc@us.ibm.com>
Signed-off-by: Fabiano Rosas <farosas@linux.ibm.com>
Message-Id: <20210222194035.2723056-1-farosas@linux.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2021-03-10 09:07:09 +11:00
..
translate ppc/translate: Rewrite gen_lxvdsx to use gvec primitives 2020-12-14 15:54:09 +11:00
arch_dump.c target/ppc: Add helper_mfvscr 2019-02-18 11:00:44 +11:00
compat.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
cpu-models.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
cpu-models.h powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
cpu-param.h tcg: Split out target/arch/cpu-param.h 2019-06-10 07:03:34 -07:00
cpu-qom.h target/ppc: Introduce an mmu_is_64bit() helper 2020-12-14 15:54:12 +11:00
cpu.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
cpu.h target/ppc: Add E500 L2CSR0 write helper 2021-02-10 14:50:11 +11:00
dfp_helper.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
excp_helper.c target/ppc: Introduce an mmu_is_64bit() helper 2020-12-14 15:54:12 +11:00
fpu_helper.c ppc/translate: Raise exceptions after setting the cc 2020-12-14 15:53:59 +11:00
gdbstub.c target/ppc: Drop use of gdb_get_float64() and ldfq_p() 2021-02-15 09:38:44 +00:00
helper_regs.h powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
helper.h target/ppc: add vmulh{su}d instructions 2020-08-12 13:16:27 +10:00
int_helper.c target/ppc: Fix bcdsub. emulation when result overflows 2021-03-10 09:07:09 +11:00
internal.h powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
kvm_ppc.h spapr: Add PEF based confidential guest support 2021-02-08 16:57:38 +11:00
kvm-stub.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
kvm.c sev/i386: Don't allow a system reset under an SEV-ES guest 2021-02-16 17:15:39 +01:00
machine.c migration: Replace migration's JSON writer by the general one 2020-12-19 10:39:16 +01:00
mem_helper.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
meson.build meson: target 2020-08-21 06:30:35 -04:00
mfrom_table_gen.c target/ppc: Style fixes for mfrom_table.inc.c & mfrom_table_gen.c 2019-04-26 10:42:38 +10:00
mfrom_table.c.inc meson: rename included C source files to .c.inc 2020-08-21 06:18:30 -04:00
misc_helper.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
mmu_helper.c target/ppc: Introduce an mmu_is_64bit() helper 2020-12-14 15:54:12 +11:00
mmu-book3s-v3.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
mmu-book3s-v3.h powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
mmu-hash32.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
mmu-hash32.h target/ppc: Manage external HPT via virtual hypervisor 2017-03-01 11:23:39 +11:00
mmu-hash64.c target/ppc: Introduce an mmu_is_64bit() helper 2020-12-14 15:54:12 +11:00
mmu-hash64.h ppc/hash64: Rework R and C bit updates 2019-04-26 11:37:57 +10:00
mmu-radix64.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
mmu-radix64.h target/ppc: Pass const pointer to ppc_radix64_get_prot_amr() 2020-05-27 15:29:36 +10:00
monitor.c hmp: Pass monitor to mon_get_cpu_env() 2020-11-13 12:45:51 +00:00
timebase_helper.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00
trace-events trace-events: Delete unused trace points 2020-09-09 17:17:02 +01:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
translate_init.c.inc target/ppc: Drop use of gdb_get_float64() and ldfq_p() 2021-02-15 09:38:44 +00:00
translate.c target/ppc: Introduce an mmu_is_64bit() helper 2020-12-14 15:54:12 +11:00
user_only_helper.c powerpc tcg: Fix Lesser GPL version number 2020-11-15 16:38:50 +01:00