qemu/target-ppc
James Clarke d1277156b5 target-ppc: mcrfs should always update FEX/VX and only clear exception bits
Here is the description of the mcrfs instruction from the PowerPC Architecture
Book, Version 2.02, Book I: PowerPC User Instruction Set Architecture
(http://www.ibm.com/developerworks/systems/library/es-archguide-v2.html), found
on page 120:

    The contents of FPSCR field BFA are copied to Condition Register field BF.
    All exception bits copied are set to 0 in the FPSCR. If the FX bit is
    copied, it is set to 0 in the FPSCR.

    Special Registers Altered:
        CR field BF
        FX OX                        (if BFA=0)
        UX ZX XX VXSNAN              (if BFA=1)
        VXISI VXIDI VXZDZ VXIMZ      (if BFA=2)
        VXVC                         (if BFA=3)
        VXSOFT VXSQRT VXCVI          (if BFA=5)

However, currently every bit in FPSCR field BFA is set to 0, including ones not
on that list.

This can be seen in the following simple C program:

    #include <fenv.h>
    #include <stdio.h>

    int main(int argc, char **argv) {
        int ret;
        ret = fegetround();
        printf("Current rounding: %d\n", ret);
        ret = fesetround(FE_UPWARD);
        printf("Setting to FE_UPWARD (%d): %d\n", FE_UPWARD, ret);
        ret = fegetround();
        printf("Current rounding: %d\n", ret);
        ret = fegetround();
        printf("Current rounding: %d\n", ret);
        return 0;
    }

which gave the output (before this commit):

    Current rounding: 0
    Setting to FE_UPWARD (2): 0
    Current rounding: 2
    Current rounding: 0

instead of (after this commit):

    Current rounding: 0
    Setting to FE_UPWARD (2): 0
    Current rounding: 2
    Current rounding: 2

The relevant disassembly is in fegetround(), which, on my system, is:

    __GI___fegetround:
    <+0>:   mcrfs  cr7, cr7
    <+4>:   mfcr   r3
    <+8>:   clrldi r3, r3, 62
    <+12>:  blr

What happens is that, the first time fegetround() is called, FPSCR field 7 is
retrieved. However, because of the bug in mcrfs, the entirety of field 7 is set
to 0, which includes the rounding mode.

There are other issues this will fix, such as condition flags not persisting
when they should if read, and if you were to read a specific field with some
exception bits set, but no others were set in the entire register, then the
bits would be cleared correctly, but FEX/VX would not be updated to 0 as they
should be.

Signed-off-by: James Clarke <jrtc27@jrtc27.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
2016-02-01 13:27:01 +11:00
..
arch_dump.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00
cpu-models.c target-ppc: Use sensible POWER8/POWER8E versions 2016-01-30 23:36:16 +11:00
cpu-models.h target-ppc: Use sensible POWER8/POWER8E versions 2016-01-30 23:36:16 +11:00
cpu-qom.h dump: qemunotes aren't commonly needed 2016-01-15 14:40:24 +00:00
cpu.h target-ppc: mcrfs should always update FEX/VX and only clear exception bits 2016-02-01 13:27:01 +11:00
dfp_helper.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00
excp_helper.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00
fpu_helper.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00
gdbstub.c target-ppc: rename and export maybe_bswap_register() 2016-01-30 23:37:37 +11:00
helper_regs.h PPC: Only enter MSR_POW when no interrupts pending 2014-04-08 11:20:05 +02:00
helper.h target-ppc: Split 44x tlbiva from ppc_tlb_invalidate_one() 2016-01-30 23:49:26 +11:00
int_helper.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00
kvm_ppc.h target-ppc: Remove unused kvmppc_read_segment_page_sizes() stub 2016-01-30 23:37:38 +11:00
kvm-stub.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00
kvm.c target-ppc: Rework ppc_store_slb 2016-01-30 23:37:38 +11:00
machine.c target-ppc: Rework SLB page size lookup 2016-01-30 23:37:38 +11:00
Makefile.objs kvm_ppc: remove kvmppc_timer_hack 2015-09-20 22:48:38 +02:00
mem_helper.c ppc: Clean up includes 2016-01-29 15:07:22 +00: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 ppc: Clean up includes 2016-01-29 15:07:22 +00:00
mmu_helper.c target-ppc: Split 44x tlbiva from ppc_tlb_invalidate_one() 2016-01-30 23:49:26 +11:00
mmu-hash32.c target-ppc: Convert mmu-hash{32,64}.[ch] from CPUPPCState to PowerPCCPU 2016-01-30 23:37:38 +11:00
mmu-hash32.h target-ppc: Convert mmu-hash{32,64}.[ch] from CPUPPCState to PowerPCCPU 2016-01-30 23:37:38 +11:00
mmu-hash64.c target-ppc: Helper to determine page size information from hpte alone 2016-01-30 23:49:27 +11:00
mmu-hash64.h target-ppc: Allow more page sizes for POWER7 & POWER8 in TCG 2016-01-30 23:49:27 +11: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 ppc: Clean up includes 2016-01-29 15:07:22 +00:00
translate_init.c target-ppc: Allow more page sizes for POWER7 & POWER8 in TCG 2016-01-30 23:49:27 +11:00
translate.c target-ppc: mcrfs should always update FEX/VX and only clear exception bits 2016-02-01 13:27:01 +11:00
user_only_helper.c ppc: Clean up includes 2016-01-29 15:07:22 +00:00