qemu/target-ppc
Talha Imran a575d9ab2e target-ppc/fpu_helper: Fix efscmp* instructions handling
With specification at hand from the reference manual from Freescale
http://cache.nxp.com/files/32bit/doc/ref_manual/SPEPEM.pdf , I have found a fix
to efscmp* instructions handling in QEMU.

efscmp* instructions in QEMU set crD (Condition Register nibble) values as
(0b0100 << 2) = 0b10000 (consider the HELPER_SINGLE_SPE_CMP macro which left
shifts the value returned by efscmp* handler by 2 bits). A value of 0b10000 is
not correct according the to the reference manual.

The reference manual expects efscmp* instructions to return a value of 0bx1xx.
Please find attached a patch which disables left shifting in
HELPER_SINGLE_SPE_CMP macro. This macro is used by efscmp* and efstst*
instructions only. efstst* instruction handlers, in turn, call efscmp* handlers
too.

*Explanation:*
Traditionally, each crD (condition register nibble) consist of 4 bits, which is
set by comparisons as follows:
crD = W X Y Z
where
W = Less than
X = Greater than
Y = Equal to

However, efscmp* instructions being a special case return a binary result.
(efscmpeq will set the crD = 0bx1xx iff when op1 == op2 and 0bx0xx otherwise;
i.e. there is no notion of different crD values based on Less than, Greater
than and Equal to).

This effectively means that crD will store a "Greater than" comparison result
iff efscmp* instruction comparison is TRUE. Compiler exploits this feature by
checking for "Branch if Less than or Equal to" (ble instruction) OR "Branch if
Greater than" (bgt instruction) for Branch if FALSE OR Branch if TRUE
respectively after an efscmp* instruction. This can be seen in a assembly code
snippet below:

27          if (__real__ x != 3.0f || __imag__ x != 4.0f)
10000498:   lwz r10,8(r31)
1000049c:   lis r9,16448
100004a0:   efscmpeq cr7,r10,r9
100004a4:   ble- cr7,0x100004b8 <bar+60>  //jump to abort() call
100004a8:   lwz r10,12(r31)
100004ac:   lis r9,16512
100004b0:   efscmpeq cr7,r10,r9
100004b4:   bgt- cr7,0x100004bc <bar+64>  //skip abort() call
28            abort ();
100004b8:   bl 0x10000808 <abort>

Signed-off-by: Talha Imran <talha_imran@mentor.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2016-06-07 10:17:44 +10:00
..
arch_dump.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00
cpu-models.c target-ppc: Add PVR for POWER8NVL processor 2016-03-16 09:55:05 +11:00
cpu-models.h target-ppc: Add PVR for POWER8NVL processor 2016-03-16 09:55:05 +11:00
cpu-qom.h target-ppc: make cpu-qom.h not target specific 2016-05-19 16:41:33 +02:00
cpu.h ppc: Do some batching of TCG tlb flushes 2016-05-30 13:20:04 +10:00
dfp_helper.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00
excp_helper.c ppc: Do some batching of TCG tlb flushes 2016-05-30 13:20:04 +10:00
fpu_helper.c target-ppc/fpu_helper: Fix efscmp* instructions handling 2016-06-07 10:17:44 +10:00
gdbstub.c qemu-common: push cpu.h inclusion out of qemu-common.h 2016-05-19 16:42:29 +02:00
helper_regs.h ppc: Do some batching of TCG tlb flushes 2016-05-30 13:20:04 +10:00
helper.h ppc: Do some batching of TCG tlb flushes 2016-05-30 13:20:04 +10:00
int_helper.c cpu: move exec-all.h inclusion out of cpu.h 2016-05-19 16:42:29 +02:00
kvm_ppc.h spapr_iommu: Finish renaming vfio_accel to need_vfio 2016-05-27 09:40:23 +10:00
kvm-stub.c qemu-common: push cpu.h inclusion out of qemu-common.h 2016-05-19 16:42:29 +02:00
kvm.c qemu-common: push cpu.h inclusion out of qemu-common.h 2016-05-19 16:42:29 +02:00
machine.c ppc: Use split I/D mmu modes to avoid flushes on interrupts 2016-05-30 13:20:04 +10:00
Makefile.objs kvm_ppc: remove kvmppc_timer_hack 2015-09-20 22:48:38 +02:00
mem_helper.c cpu: move exec-all.h inclusion out of cpu.h 2016-05-19 16:42:29 +02:00
mfrom_table_gen.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00
mfrom_table.c find -type f | xargs sed -i 's/[\t ]$//g' # on most files 2007-09-16 21:08:06 +00:00
misc_helper.c cpu: move exec-all.h inclusion out of cpu.h 2016-05-19 16:42:29 +02:00
mmu_helper.c ppc: Do some batching of TCG tlb flushes 2016-05-30 13:20:04 +10:00
mmu-hash32.c cpu: move exec-all.h inclusion out of cpu.h 2016-05-19 16:42:29 +02:00
mmu-hash32.h target-ppc: do not use target_ulong in cpu-qom.h 2016-05-19 13:08:05 +02:00
mmu-hash64.c ppc: Do some batching of TCG tlb flushes 2016-05-30 13:20:04 +10:00
mmu-hash64.h target-ppc: do not use target_ulong in cpu-qom.h 2016-05-19 13:08:05 +02:00
monitor.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00
STATUS target-ppc: remove powerpc 970gx 2014-03-05 03:06:23 +01:00
timebase_helper.c cpu: move exec-all.h inclusion out of cpu.h 2016-05-19 16:42:29 +02:00
translate_init.c ppc: Add PPC_64H instruction flag to POWER7 and POWER8 2016-05-30 13:20:04 +10:00
translate.c target-*: dfilter support for in_asm 2016-06-05 09:26:24 -07:00
user_only_helper.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00