All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05
@ 2014-03-06 23:32 Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 001/130] target-ppc: fix compile error when PPC_DUMP_CPU is enabled Alexander Graf
                   ` (130 more replies)
  0 siblings, 131 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Peter Maydell, qemu-ppc, aurelien, aliguori

Hi Blue / Aurelien / Anthony / Peter,

This is my current patch queue for ppc.  Please pull.

This pull request includes:

  - VSX emulation support
  - book3s pr/hv selection
  - some bug fixes
  - qdev stable numbering
  - eTSEC emulation


Alex


The following changes since commit f55ea6297cc0224fe4934b90ff5343b620b14669:

  block/gluster: Add missing argument to qemu_gluster_init() call (2014-03-04 20:20:57 +0000)

are available in the git repository at:

  git://github.com/agraf/qemu.git tags/signed-ppc-for-upstream

for you to fetch changes up to 0f20ba62c35e6a779ba4ea00616192ef2abb6896:

  target-ppc: spapr: e500: fix to use cpu_dt_id (2014-03-05 03:07:04 +0100)

----------------------------------------------------------------
Patch queue for ppc - 2014-03-05

This pull request includes:

  - VSX emulation support
  - book3s pr/hv selection
  - some bug fixes
  - qdev stable numbering
  - eTSEC emulation

----------------------------------------------------------------
Alexander Graf (3):
      KVM: Split QEMUMachine typedef into separate header
      qdev: Keep global allocation counter per bus
      PPC: sPAPR: Only use getpagesize() when we run with kvm

Alexey Kardashevskiy (19):
      target-ppc: fix compile error when PPC_DUMP_CPU is enabled
      target-ppc: fix LPCR SPR number
      target-ppc: remove powerpc 970gx
      target-ppc: fix SPR_CTRL/SPR_UCTRL register numbers
      target-ppc: remove embedded MMU SPRs from 970, P5+/7/7+/8
      target-ppc: remove unsupported SPRs from 970 and P5+
      target-ppc: fix Authority Mask Register init value
      PPC: KVM: fix "set one register"
      spapr-pci: enable adding PHB via -device
      target-ppc: disable unsupported modes for SPR_CTRL/SPR_UCTRL
      PPC: KVM: store SLB slot number
      PPC: KVM: suppress warnings about not supported SPRs
      spapr: support only ELF kernel images
      moxie: fix load_elf() usage
      elf-loader: add more return codes
      spapr: print more detailed error message on failed load_elf()
      spapr-vlan: flush queue whenever can_receive can go from false to true
      target-ppc: add PowerPCCPU::cpu_dt_id
      target-ppc: spapr: e500: fix to use cpu_dt_id

Aneesh Kumar K.V (6):
      kvm: Add a new machine option kvm-type
      target-ppc: Update external_htab even when HTAB is managed by kernel
      target-ppc: Fix htab_mask calculation
      target-ppc: Fix page table lookup with kvm enabled
      target-ppc: Change the hpte store API
      target-ppc: Update ppc_hash64_store_hpte to support updating in-kernel htab

Anton Blanchard (1):
      target-ppc: dump DAR and DSISR

Cédric Le Goater (2):
      mmu-hash64: fix Virtual Page Class Key Protection
      target-ppc: add extended opcodes for dcbt/dcbtst

Edgar E. Iglesias (1):
      virtex_ml507: Add support for loading initrd images

Fabien Chouteau (1):
      Add Enhanced Three-Speed Ethernet Controller (eTSEC)

Greg Kurz (1):
      PPC: KVM: add support for LPCR

Laurent Dufour (1):
      target-ppc: Introduce hypervisor call H_GET_TCE

Nathan Whitehorn (1):
      spapr_vscsi: Fix REPORT_LUNS handling

Peter Maydell (1):
      target-ppc/translate.c: Use ULL suffix for 64 bit constants

Tom Musta (93):
      target-ppc: Add set_fprf Argument to fload_invalid_op_excp()
      target-ppc: General Support for VSX Helpers
      target-ppc: Add VSX ISA2.06 xadd/xsub Instructions
      target-ppc: Add VSX ISA2.06 xmul Instructions
      target-ppc: Add VSX ISA2.06 xdiv Instructions
      target-ppc: Add VSX ISA2.06 xre Instructions
      target-ppc: Add VSX ISA2.06 xsqrt Instructions
      target-ppc: Add VSX ISA2.06 xrsqrte Instructions
      target-ppc: Add VSX ISA2.06 xtdiv Instructions
      target-ppc: Add VSX ISA2.06 xtsqrt Instructions
      target-ppc: Add VSX ISA2.06 Multiply Add Instructions
      target-ppc: Add VSX xscmp*dp Instructions
      target-ppc: Add VSX xmax/xmin Instructions
      target-ppc: Add VSX Vector Compare Instructions
      target-ppc: Add VSX Floating Point to Floating Point Conversion Instructions
      target-ppc: Add VSX ISA2.06 Integer Conversion Instructions
      target-ppc: Add VSX Rounding Instructions
      target-ppc: VSX Stage 4: Add VSX 2.07 Flag
      target-ppc: VSX Stage 4: Refactor lxsdx
      target-ppc: VSX Stage 4: Add lxsiwax, lxsiwzx and lxsspx
      target-ppc: VSX Stage 4: Refactor stxsdx
      target-ppc: VSX Stage 4: Add stxsiwx and stxsspx
      target-ppc: VSX Stage 4: Add xsaddsp and xssubsp
      target-ppc: VSX Stage 4: Add xsmulsp
      target-ppc: VSX Stage 4: Add xsdivsp
      target-ppc: VSX Stage 4: Add xsresp
      target-ppc: VSX Stage 4: Add xssqrtsp
      target-ppc: VSX Stage 4: add xsrsqrtesp
      target-ppc: VSX Stage 4: Add Scalar SP Fused Multiply-Adds
      target-ppc: VSX Stage 4: Add xscvsxdsp and xscvuxdsp
      target-ppc: VSX Stage 4: Add xxleqv, xxlnand and xxlorc
      target-ppc: Move To/From VSR Instructions
      target-ppc: Floating Merge Word Instructions
      target-ppc: Scalar Round to Single Precision
      target-ppc: Scalar Non-Signalling Conversions
      target-ppc: Add ISA2.06 bpermd Instruction
      target-ppc: Add Flag for ISA2.06 Divide Extended Instructions
      target-ppc: Add ISA2.06 divdeu[o] Instructions
      target-ppc: Add ISA2.06 divde[o] Instructions
      target-ppc: Add ISA 2.06 divweu[o] Instructions
      target-ppc: Add ISA 2.06 divwe[o] Instructions
      target-ppc: Add Flag for ISA2.06 Atomic Instructions
      target-ppc: Add ISA2.06 lbarx, lharx Instructions
      target-ppc: Add ISA 2.06 stbcx. and sthcx. Instructions
      target-ppc: Add Flag for ISA V2.06 Floating Point Conversion
      target-ppc: Add ISA2.06 Float to Integer Instructions
      target-ppc: Add ISA 2.06 fcfid[u][s] Instructions
      target-ppc: Fix and enable fri[mnpz]
      target-ppc: Add Flag for Power ISA V2.06 Floating Point Test Instructions
      target-ppc: Add ISA 2.06 ftdiv Instruction
      target-ppc: Add ISA 2.06 ftsqrt
      target-ppc: Enable frsqrtes on Power7 and Power8
      target-ppc: Add ISA2.06 lfiwzx Instruction
      target-ppc: Fix xxpermdi When T==A or T==B
      target-ppc: Add Flag for bctar
      target-ppc: Add Target Address SPR (TAR) to Power8
      target-ppc: Add bctar Instruction
      target-ppc: Add Flag for ISA 2.07 Load/Store Quadword Instructions
      target-ppc: Add is_user_mode Utility Routine
      target-ppc: Load Quadword
      target-ppc: Store Quadword
      target-ppc: Add Load Quadword and Reserve
      target-ppc: Add Store Quadword Conditional
      target-ppc: Altivec 2.07: Add Instruction Flag
      target-ppc: Altivec 2.07: Update AVR Structure
      target-ppc: Altivec 2.07: Add GEN_VXFORM3
      target-ppc: Altivec 2.07: Add Support for Dual Altivec Instructions
      target-ppc: Altivec 2.07: Add Opcode Macro for VX Form Instructions
      target-ppc: Altivec 2.07: Add Support for R-Form Dual Instructions
      target-ppc: Altivec 2.07: Vector Logical Instructions
      target-ppc: Altivec 2.07: Add/Subtract Unsigned Doubleword Modulo
      target-ppc: Altivec 2.07: Change VMUL_DO to Support 64-bit Integers
      target-ppc: Altivec 2.07: Multiply Even/Odd Word Instructions
      target-ppc: Altivec 2.07: vmuluw Instruction
      target-ppc: Altivec 2.07: Add Vector Count Leading Zeroes
      target-ppc: Altivec 2.07: Vector Population Count Instructions
      target-ppc: Altivec 2.07: Vector Min/Max Doubleword Instructions
      target-ppc: Altivec 2.07: Pack Doubleword Instructions
      target-ppc: Altivec 2.07: Unpack Signed Word Instructions
      target-ppc: Altivec 2.07: Vector Merge Instructions
      target-ppc: Altivec 2.07: Change Bit Masks to Support 64-bit Rotates and Shifts
      target-ppc: Altivec 2.07: Vector Doubleword Rotate and Shift Instructions
      target-ppc: Altivec 2.07: Quadword Addition and Subtracation
      target-ppc: Altivec 2.07: vbpermq Instruction
      target-ppc: Altivec 2.07: Doubleword Compares
      target-ppc: Altivec 2.07: Vector Gather Bits by Bytes
      target-ppc: Altivec 2.07: Vector Polynomial Multiply Sum
      target-ppc: Altivec 2.07: Binary Coded Decimal Instructions
      target-ppc: Altivec 2.07: AES Instructions
      target-ppc: Altivec 2.07: Vector SHA Sigma Instructions
      target-ppc: Altivec 2.07: Vector Permute and Exclusive OR
      target-ppc: Fix Compiler Warnings Due to 64-Bit Constants Declared as UL
      target-ppc: Use Additional Temporary in stqcx Case

 default-configs/ppc-softmmu.mak |    1 +
 hw/core/loader.c                |   30 +-
 hw/core/qdev.c                  |   20 +-
 hw/i386/pc_piix.c               |    8 +-
 hw/intc/openpic_kvm.c           |    2 +-
 hw/intc/xics.c                  |   15 +-
 hw/intc/xics_kvm.c              |   10 +-
 hw/moxie/moxiesim.c             |    2 +-
 hw/net/Makefile.objs            |    3 +
 hw/net/fsl_etsec/etsec.c        |  465 +++++++++++++
 hw/net/fsl_etsec/etsec.h        |  174 +++++
 hw/net/fsl_etsec/miim.c         |  146 ++++
 hw/net/fsl_etsec/registers.c    |  295 ++++++++
 hw/net/fsl_etsec/registers.h    |  320 +++++++++
 hw/net/fsl_etsec/rings.c        |  650 ++++++++++++++++++
 hw/net/spapr_llan.c             |    2 +
 hw/ppc/e500.c                   |    7 +-
 hw/ppc/ppc.c                    |   22 +
 hw/ppc/spapr.c                  |   56 +-
 hw/ppc/spapr_hcall.c            |   87 ++-
 hw/ppc/spapr_iommu.c            |   37 +
 hw/ppc/spapr_pci.c              |   15 +-
 hw/ppc/spapr_rtas.c             |   14 +-
 hw/ppc/virtex_ml507.c           |   34 +-
 hw/s390x/ipl.c                  |    4 +-
 hw/scsi/spapr_vscsi.c           |   60 ++
 include/hw/boards.h             |    6 +-
 include/hw/elf_ops.h            |   19 +-
 include/hw/loader.h             |    6 +
 include/hw/qdev-core.h          |    2 +
 include/hw/xen/xen.h            |    3 +-
 include/qemu/host-utils.h       |   28 +
 include/sysemu/kvm.h            |    3 +-
 include/sysemu/qemumachine.h    |   16 +
 include/sysemu/qtest.h          |    3 +-
 kvm-all.c                       |   17 +-
 kvm-stub.c                      |    3 +-
 linux-user/main.c               |   18 +-
 qtest.c                         |    2 +-
 target-ppc/STATUS               |    9 -
 target-ppc/cpu-models.c         |    2 -
 target-ppc/cpu-models.h         |    1 -
 target-ppc/cpu-qom.h            |    2 +
 target-ppc/cpu.h                |   55 +-
 target-ppc/fpu_helper.c         | 1294 +++++++++++++++++++++++++++++++----
 target-ppc/helper.h             |  207 ++++++
 target-ppc/int_helper.c         | 1411 +++++++++++++++++++++++++++++++++++++--
 target-ppc/kvm.c                |  117 +++-
 target-ppc/kvm_ppc.h            |   35 +-
 target-ppc/machine.c            |   11 +-
 target-ppc/misc_helper.c        |    4 +-
 target-ppc/mmu-hash64.c         |  117 +++-
 target-ppc/mmu-hash64.h         |   47 +-
 target-ppc/mmu_helper.c         |    3 +-
 target-ppc/translate.c          | 1268 +++++++++++++++++++++++++++++++----
 target-ppc/translate_init.c     |  274 ++------
 trace-events                    |    3 +
 util/host-utils.c               |   75 +++
 vl.c                            |   14 +-
 xen-all.c                       |    2 +-
 xen-stub.c                      |    2 +-
 61 files changed, 6818 insertions(+), 740 deletions(-)
 create mode 100644 hw/net/fsl_etsec/etsec.c
 create mode 100644 hw/net/fsl_etsec/etsec.h
 create mode 100644 hw/net/fsl_etsec/miim.c
 create mode 100644 hw/net/fsl_etsec/registers.c
 create mode 100644 hw/net/fsl_etsec/registers.h
 create mode 100644 hw/net/fsl_etsec/rings.c
 create mode 100644 include/sysemu/qemumachine.h

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 001/130] target-ppc: fix compile error when PPC_DUMP_CPU is enabled
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 002/130] target-ppc: fix LPCR SPR number Alexander Graf
                   ` (129 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

Since last use of PPC_DUMP_CPU by whoever he/she was, env->tlb became
a union and POWERPC CPU class got QOM'ed so defining PPC_DUMP_CPU
breaks compile.

This fixes compiler errors.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate_init.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 445c360..7bbda13 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8149,9 +8149,10 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
         }
         printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
                "    MMU model        : %s\n",
-               pcc->name, pcc->pvr, pcc->msr_mask, mmu_model);
+               object_class_get_name(OBJECT_CLASS(pcc)),
+               pcc->pvr, pcc->msr_mask, mmu_model);
 #if !defined(CONFIG_USER_ONLY)
-        if (env->tlb != NULL) {
+        if (env->tlb.tlb6) {
             printf("                       %d %s TLB in %d ways\n",
                    env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
                    env->nb_ways);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 002/130] target-ppc: fix LPCR SPR number
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 001/130] target-ppc: fix compile error when PPC_DUMP_CPU is enabled Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 003/130] target-ppc: remove powerpc 970gx Alexander Graf
                   ` (128 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

PowerISA defines LPCR SPR number as 318=0x13E but QEMU uses the value of
316.

This fixes the definition of LPCR SPR.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            | 2 +-
 target-ppc/translate_init.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index bb84767..4369e7c 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1322,12 +1322,12 @@ static inline int cpu_mmu_index (CPUPPCState *env)
 #define SPR_BOOKE_IAC3        (0x13A)
 #define SPR_HSRR1             (0x13B)
 #define SPR_BOOKE_IAC4        (0x13B)
-#define SPR_LPCR              (0x13C)
 #define SPR_BOOKE_DAC1        (0x13C)
 #define SPR_LPIDR             (0x13D)
 #define SPR_DABR2             (0x13D)
 #define SPR_BOOKE_DAC2        (0x13D)
 #define SPR_BOOKE_DVC1        (0x13E)
+#define SPR_LPCR              (0x13E)
 #define SPR_BOOKE_DVC2        (0x13F)
 #define SPR_BOOKE_TSR         (0x150)
 #define SPR_BOOKE_TCR         (0x154)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 7bbda13..ed70087 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -2578,8 +2578,8 @@ static void gen_spr_8xx (CPUPPCState *env)
  * HRMOR   => SPR 313 (Power 2.04 hypv)
  * HSRR0   => SPR 314 (Power 2.04 hypv)
  * HSRR1   => SPR 315 (Power 2.04 hypv)
- * LPCR    => SPR 316 (970)
  * LPIDR   => SPR 317 (970)
+ * LPCR    => SPR 318 (970)
  * EPR     => SPR 702 (Power 2.04 emb)
  * perf    => 768-783 (Power 2.04)
  * perf    => 784-799 (Power 2.04)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 003/130] target-ppc: remove powerpc 970gx
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 001/130] target-ppc: fix compile error when PPC_DUMP_CPU is enabled Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 002/130] target-ppc: fix LPCR SPR number Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 004/130] target-ppc: fix SPR_CTRL/SPR_UCTRL register numbers Alexander Graf
                   ` (127 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

The 970GX definition was added in 2007 and it made sense then but this
version has never been released to the markets and it does not exist in
the real world so there is no point in emulating it.

This removes 970GX.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/STATUS           |   9 ----
 target-ppc/cpu-models.c     |   2 -
 target-ppc/cpu-models.h     |   1 -
 target-ppc/translate_init.c | 100 --------------------------------------------
 4 files changed, 112 deletions(-)

diff --git a/target-ppc/STATUS b/target-ppc/STATUS
index c8e9018..a4d48a7 100644
--- a/target-ppc/STATUS
+++ b/target-ppc/STATUS
@@ -377,15 +377,6 @@ MMU   OK
 EXCP  KO partially implemented
 Remarks: Should be able to boot but there is no hw platform currently emulated.
 
-PowerPC 970GX:
-INSN  KO Altivec missing and more
-SPR   KO
-MSR   ?
-IRQ   OK
-MMU   OK
-EXCP  KO partially implemented
-Remarks: Should be able to boot but there is no hw platform currently emulated.
-
 PowerPC Cell:
 INSN  KO Altivec missing and more
 SPR   KO
diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index 7c9466f..f6c9b3a 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1156,8 +1156,6 @@
                 "PowerPC 970FX v3.0 (G5)")
     POWERPC_DEF("970fx_v3.1",    CPU_POWERPC_970FX_v31,              970FX,
                 "PowerPC 970FX v3.1 (G5)")
-    POWERPC_DEF("970gx",         CPU_POWERPC_970GX,                  970GX,
-                "PowerPC 970GX (G5)")
     POWERPC_DEF("970mp_v1.0",    CPU_POWERPC_970MP_v10,              970MP,
                 "PowerPC 970MP v1.0")
     POWERPC_DEF("970mp_v1.1",    CPU_POWERPC_970MP_v11,              970MP,
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index 49ba4a4..644a126 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -570,7 +570,6 @@ enum {
     CPU_POWERPC_970FX_v21          = 0x003C0201,
     CPU_POWERPC_970FX_v30          = 0x003C0300,
     CPU_POWERPC_970FX_v31          = 0x003C0301,
-    CPU_POWERPC_970GX              = 0x00450000,
     CPU_POWERPC_970MP_v10          = 0x00440100,
     CPU_POWERPC_970MP_v11          = 0x00440101,
 #define CPU_POWERPC_CELL             CPU_POWERPC_CELL_v32
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index ed70087..df8b4b1 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -6830,106 +6830,6 @@ POWERPC_FAMILY(970FX)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
-static int check_pow_970GX (CPUPPCState *env)
-{
-    if (env->spr[SPR_HID0] & 0x00600000)
-        return 1;
-
-    return 0;
-}
-
-static void init_proc_970GX (CPUPPCState *env)
-{
-    gen_spr_ne_601(env);
-    gen_spr_7xx(env);
-    /* Time base */
-    gen_tbl(env);
-    /* Hardware implementation registers */
-    /* XXX : not implemented */
-    spr_register(env, SPR_HID0, "HID0",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_clear,
-                 0x60000000);
-    /* XXX : not implemented */
-    spr_register(env, SPR_HID1, "HID1",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    /* XXX : not implemented */
-    spr_register(env, SPR_750FX_HID2, "HID2",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    /* XXX : not implemented */
-    spr_register(env, SPR_970_HID5, "HID5",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 POWERPC970_HID5_INIT);
-    /* XXX : not implemented */
-    spr_register(env, SPR_L2CR, "L2CR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, spr_access_nop,
-                 0x00000000);
-    /* Memory management */
-    /* XXX: not correct */
-    gen_low_BATs(env);
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCFG, "MMUCFG",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, SPR_NOACCESS,
-                 0x00000000); /* TOFIX */
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCSR0, "MMUCSR0",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000); /* TOFIX */
-    spr_register(env, SPR_HIOR, "SPR_HIOR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_hior, &spr_write_hior,
-                 0x00000000);
-#if !defined(CONFIG_USER_ONLY)
-    env->slb_nr = 32;
-#endif
-    init_excp_970(env);
-    env->dcache_line_size = 128;
-    env->icache_line_size = 128;
-    /* Allocate hardware IRQ controller */
-    ppc970_irq_init(env);
-    /* Can't find information on what this should be on reset.  This
-     * value is the one used by 74xx processors. */
-    vscr_init(env, 0x00010000);
-}
-
-POWERPC_FAMILY(970GX)(ObjectClass *oc, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(oc);
-    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
-    dc->desc = "PowerPC 970 GX";
-    pcc->init_proc = init_proc_970GX;
-    pcc->check_pow = check_pow_970GX;
-    pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
-                       PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
-                       PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
-                       PPC_FLOAT_STFIWX |
-                       PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
-                       PPC_MEM_SYNC | PPC_MEM_EIEIO |
-                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_64B | PPC_ALTIVEC |
-                       PPC_SEGMENT_64B | PPC_SLBI;
-    pcc->msr_mask = 0x800000000204FF36ULL;
-    pcc->mmu_model = POWERPC_MMU_64B;
-#if defined(CONFIG_SOFTMMU)
-    pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
-#endif
-    pcc->excp_model = POWERPC_EXCP_970;
-    pcc->bus_model = PPC_FLAGS_INPUT_970;
-    pcc->bfd_mach = bfd_mach_ppc64;
-    pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
-                 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
-                 POWERPC_FLAG_BUS_CLK;
-}
-
 static int check_pow_970MP (CPUPPCState *env)
 {
     if (env->spr[SPR_HID0] & 0x01C00000)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 004/130] target-ppc: fix SPR_CTRL/SPR_UCTRL register numbers
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (2 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 003/130] target-ppc: remove powerpc 970gx Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 005/130] target-ppc: remove embedded MMU SPRs from 970, P5+/7/7+/8 Alexander Graf
                   ` (126 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

Assuming that "U" in SPR_UCTRL is for "user", there is inconsistency with
970 user manuals/P5-bookIV/PowerISA204 which define the number as:

                       priviledged
#   spr5-9 spr0-4 name mtspr mfspr len cat
136 00100  01000  CTRL   -    no    32  S
152 00100  11000  CTRL  yes    -    32  S

This swaps the numbers. No effect from this change is expected though.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 4369e7c..51bcd4a 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1250,7 +1250,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
 #define SPR_MPC_EIE           (0x050)
 #define SPR_MPC_EID           (0x051)
 #define SPR_MPC_NRI           (0x052)
-#define SPR_CTRL              (0x088)
+#define SPR_UCTRL             (0x088)
 #define SPR_MPC_CMPA          (0x090)
 #define SPR_MPC_CMPB          (0x091)
 #define SPR_MPC_CMPC          (0x092)
@@ -1259,7 +1259,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
 #define SPR_MPC_DER           (0x095)
 #define SPR_MPC_COUNTA        (0x096)
 #define SPR_MPC_COUNTB        (0x097)
-#define SPR_UCTRL             (0x098)
+#define SPR_CTRL              (0x098)
 #define SPR_MPC_CMPE          (0x098)
 #define SPR_MPC_CMPF          (0x099)
 #define SPR_MPC_CMPG          (0x09A)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 005/130] target-ppc: remove embedded MMU SPRs from 970, P5+/7/7+/8
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (3 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 004/130] target-ppc: fix SPR_CTRL/SPR_UCTRL register numbers Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 006/130] target-ppc: remove unsupported SPRs from 970 and P5+ Alexander Graf
                   ` (125 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

PowerISA 2.04+ puts MMUCFG and MMUCSR0 SPRs to "E" (embedded) category so
remove it from POWER7/8 class as it is "S" (server) category.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate_init.c | 46 ---------------------------------------------
 1 file changed, 46 deletions(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index df8b4b1..d645b1b 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -6661,16 +6661,6 @@ static void init_proc_970 (CPUPPCState *env)
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCFG, "MMUCFG",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, SPR_NOACCESS,
-                 0x00000000); /* TOFIX */
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCSR0, "MMUCSR0",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000); /* TOFIX */
     spr_register(env, SPR_HIOR, "SPR_HIOR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_hior, &spr_write_hior,
@@ -6761,16 +6751,6 @@ static void init_proc_970FX (CPUPPCState *env)
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCFG, "MMUCFG",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, SPR_NOACCESS,
-                 0x00000000); /* TOFIX */
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCSR0, "MMUCSR0",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000); /* TOFIX */
     spr_register(env, SPR_HIOR, "SPR_HIOR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_hior, &spr_write_hior,
@@ -6873,16 +6853,6 @@ static void init_proc_970MP (CPUPPCState *env)
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCFG, "MMUCFG",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, SPR_NOACCESS,
-                 0x00000000); /* TOFIX */
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCSR0, "MMUCSR0",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000); /* TOFIX */
     spr_register(env, SPR_HIOR, "SPR_HIOR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_hior, &spr_write_hior,
@@ -6965,16 +6935,6 @@ static void init_proc_power5plus(CPUPPCState *env)
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCFG, "MMUCFG",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, SPR_NOACCESS,
-                 0x00000000); /* TOFIX */
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCSR0, "MMUCSR0",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000); /* TOFIX */
     spr_register(env, SPR_HIOR, "SPR_HIOR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_hior, &spr_write_hior,
@@ -7077,12 +7037,6 @@ static void init_proc_POWER7 (CPUPPCState *env)
                      &spr_read_generic, &spr_write_generic,
                      KVM_REG_PPC_PMC6, 0x00000000);
 #endif /* !CONFIG_USER_ONLY */
-    /* Memory management */
-    /* XXX : not implemented */
-    spr_register(env, SPR_MMUCFG, "MMUCFG",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, SPR_NOACCESS,
-                 0x00000000); /* TOFIX */
     gen_spr_amr(env);
     /* XXX : not implemented */
     spr_register(env, SPR_CTRL, "SPR_CTRLT",
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 006/130] target-ppc: remove unsupported SPRs from 970 and P5+
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (4 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 005/130] target-ppc: remove embedded MMU SPRs from 970, P5+/7/7+/8 Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 007/130] KVM: Split QEMUMachine typedef into separate header Alexander Graf
                   ` (124 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

SPR_750FX_HID2 and L2CR are not defined in 970* user manuals nor POWER5
bookIV nor PowerISA 2.04, the numbers assigned to them are not defined
either so remove them.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate_init.c | 39 ---------------------------------------
 1 file changed, 39 deletions(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index d645b1b..f5a8490 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -6644,20 +6644,10 @@ static void init_proc_970 (CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
-    spr_register(env, SPR_750FX_HID2, "HID2",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    /* XXX : not implemented */
     spr_register(env, SPR_970_HID5, "HID5",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  POWERPC970_HID5_INIT);
-    /* XXX : not implemented */
-    spr_register(env, SPR_L2CR, "L2CR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, spr_access_nop,
-                 0x00000000);
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
@@ -6734,20 +6724,10 @@ static void init_proc_970FX (CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
-    spr_register(env, SPR_750FX_HID2, "HID2",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    /* XXX : not implemented */
     spr_register(env, SPR_970_HID5, "HID5",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  POWERPC970_HID5_INIT);
-    /* XXX : not implemented */
-    spr_register(env, SPR_L2CR, "L2CR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, spr_access_nop,
-                 0x00000000);
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
@@ -6836,20 +6816,11 @@ static void init_proc_970MP (CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
-    spr_register(env, SPR_750FX_HID2, "HID2",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    /* XXX : not implemented */
     spr_register(env, SPR_970_HID5, "HID5",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  POWERPC970_HID5_INIT);
     /* XXX : not implemented */
-    spr_register(env, SPR_L2CR, "L2CR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, spr_access_nop,
-                 0x00000000);
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
@@ -6918,20 +6889,10 @@ static void init_proc_power5plus(CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
-    spr_register(env, SPR_750FX_HID2, "HID2",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    /* XXX : not implemented */
     spr_register(env, SPR_970_HID5, "HID5",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  POWERPC970_HID5_INIT);
-    /* XXX : not implemented */
-    spr_register(env, SPR_L2CR, "L2CR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, spr_access_nop,
-                 0x00000000);
     /* Memory management */
     /* XXX: not correct */
     gen_low_BATs(env);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 007/130] KVM: Split QEMUMachine typedef into separate header
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (5 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 006/130] target-ppc: remove unsupported SPRs from 970 and P5+ Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-07  7:31   ` Paolo Bonzini
  2014-03-06 23:32 ` [Qemu-devel] [PULL 008/130] kvm: Add a new machine option kvm-type Alexander Graf
                   ` (123 subsequent siblings)
  130 siblings, 1 reply; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Peter Maydell, qemu-ppc, aurelien, aliguori

Older gcc versions (such as the one in SLES11) get confused when you declare
a typedef on the same struct twice.

To work around that limitation, let's extract the QEMUMachine typedef into a
separate header file that is guarded by preprocessor duplicate include checks.

This fixes the following type of compile errors for me:

  In file included from vl.c:125:
  include/hw/xen/xen.h:39: error: redefinition of typedef "QEMUMachine"
  include/sysemu/kvm.h:155: error: previous declaration of "QEMUMachine" was here

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 include/hw/boards.h          |  3 +--
 include/hw/xen/xen.h         |  1 +
 include/sysemu/kvm.h         |  1 +
 include/sysemu/qemumachine.h | 16 ++++++++++++++++
 include/sysemu/qtest.h       |  1 +
 kvm-stub.c                   |  1 +
 6 files changed, 21 insertions(+), 2 deletions(-)
 create mode 100644 include/sysemu/qemumachine.h

diff --git a/include/hw/boards.h b/include/hw/boards.h
index 2151460..ed6d9f8 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -4,10 +4,9 @@
 #define HW_BOARDS_H
 
 #include "sysemu/blockdev.h"
+#include "sysemu/qemumachine.h"
 #include "hw/qdev.h"
 
-typedef struct QEMUMachine QEMUMachine;
-
 typedef struct QEMUMachineInitArgs {
     const QEMUMachine *machine;
     ram_addr_t ram_size;
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index e1f88bf..81e5bb1 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -10,6 +10,7 @@
 
 #include "hw/irq.h"
 #include "qemu-common.h"
+#include "sysemu/qemumachine.h"
 
 /* xen-machine.c */
 enum xen_mode {
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index a02d67c..c982570 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -18,6 +18,7 @@
 #include "config-host.h"
 #include "qemu/queue.h"
 #include "qom/cpu.h"
+#include "sysemu/qemumachine.h"
 
 #ifdef CONFIG_KVM
 #include <linux/kvm.h>
diff --git a/include/sysemu/qemumachine.h b/include/sysemu/qemumachine.h
new file mode 100644
index 0000000..4cefd56
--- /dev/null
+++ b/include/sysemu/qemumachine.h
@@ -0,0 +1,16 @@
+/*
+ * QEMU Machine typedef
+ *
+ * Copyright Alexander Graf <agraf@suse.de>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMUMACHINE_H
+#define QEMUMACHINE_H
+
+typedef struct QEMUMachine QEMUMachine;
+
+#endif /* !QEMUMACHINE_H */
diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
index 28f4875..d6434cd 100644
--- a/include/sysemu/qtest.h
+++ b/include/sysemu/qtest.h
@@ -16,6 +16,7 @@
 
 #include "qemu-common.h"
 #include "qapi/error.h"
+#include "sysemu/qemumachine.h"
 
 extern bool qtest_allowed;
 
diff --git a/kvm-stub.c b/kvm-stub.c
index e979f76..b1c4429 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -14,6 +14,7 @@
 #include "hw/hw.h"
 #include "cpu.h"
 #include "sysemu/kvm.h"
+#include "sysemu/qemumachine.h"
 
 #ifndef CONFIG_USER_ONLY
 #include "hw/pci/msi.h"
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 008/130] kvm: Add a new machine option kvm-type
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (6 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 007/130] KVM: Split QEMUMachine typedef into separate header Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 009/130] target-ppc: dump DAR and DSISR Alexander Graf
                   ` (122 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, qemu-ppc, Aneesh Kumar K.V, aliguori,
	aurelien

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

Targets like ppc64 support different types of KVM, one which use
hypervisor mode and the other which doesn't. Add a new machine
option kvm-type that helps in selecting the respective ones
We also add a new QEMUMachine callback get_vm_type that helps
in mapping the string representation of kvm type specified.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
[agraf: spelling fixes, use error_report(), use qemumachine.h]
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c         | 20 ++++++++++++++++++++
 include/hw/boards.h    |  3 +++
 include/hw/xen/xen.h   |  2 +-
 include/sysemu/kvm.h   |  2 +-
 include/sysemu/qtest.h |  2 +-
 kvm-all.c              | 17 ++++++++++++++---
 kvm-stub.c             |  2 +-
 qtest.c                |  2 +-
 vl.c                   | 14 +++++++++-----
 xen-all.c              |  2 +-
 xen-stub.c             |  2 +-
 11 files changed, 53 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 93d02c1..5b21562 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -49,6 +49,7 @@
 #include "exec/address-spaces.h"
 #include "hw/usb.h"
 #include "qemu/config-file.h"
+#include "qemu/error-report.h"
 
 #include <libfdt.h>
 
@@ -1366,6 +1367,24 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
     assert(spapr->fdt_skel != NULL);
 }
 
+static int spapr_kvm_type(const char *vm_type)
+{
+    if (!vm_type) {
+        return 0;
+    }
+
+    if (!strcmp(vm_type, "HV")) {
+        return 1;
+    }
+
+    if (!strcmp(vm_type, "PR")) {
+        return 2;
+    }
+
+    error_report("Unknown kvm-type specified '%s'", vm_type);
+    exit(1);
+}
+
 static QEMUMachine spapr_machine = {
     .name = "pseries",
     .desc = "pSeries Logical Partition (PAPR compliant)",
@@ -1376,6 +1395,7 @@ static QEMUMachine spapr_machine = {
     .max_cpus = MAX_CPUS,
     .no_parallel = 1,
     .default_boot_order = NULL,
+    .kvm_type = spapr_kvm_type,
 };
 
 static void spapr_machine_init(void)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index ed6d9f8..c2096e6 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -23,6 +23,8 @@ typedef void QEMUMachineResetFunc(void);
 
 typedef void QEMUMachineHotAddCPUFunc(const int64_t id, Error **errp);
 
+typedef int QEMUMachineGetKvmtypeFunc(const char *arg);
+
 struct QEMUMachine {
     const char *name;
     const char *alias;
@@ -30,6 +32,7 @@ struct QEMUMachine {
     QEMUMachineInitFunc *init;
     QEMUMachineResetFunc *reset;
     QEMUMachineHotAddCPUFunc *hot_add_cpu;
+    QEMUMachineGetKvmtypeFunc *kvm_type;
     BlockInterfaceType block_default_type;
     int max_cpus;
     unsigned int no_serial:1,
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index 81e5bb1..e181821 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -37,7 +37,7 @@ void xen_cmos_set_s3_resume(void *opaque, int irq, int level);
 
 qemu_irq *xen_interrupt_controller_init(void);
 
-int xen_init(void);
+int xen_init(QEMUMachine *machine);
 int xen_hvm_init(MemoryRegion **ram_memory);
 void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);
 
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index c982570..ed01998 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -153,7 +153,7 @@ extern KVMState *kvm_state;
 
 /* external API */
 
-int kvm_init(void);
+int kvm_init(QEMUMachine *machine);
 
 int kvm_has_sync_mmu(void);
 int kvm_has_vcpu_events(void);
diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
index d6434cd..e62281d 100644
--- a/include/sysemu/qtest.h
+++ b/include/sysemu/qtest.h
@@ -27,7 +27,7 @@ static inline bool qtest_enabled(void)
 
 bool qtest_driver(void);
 
-int qtest_init_accel(void);
+int qtest_init_accel(QEMUMachine *machine);
 void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);
 
 static inline int qtest_available(void)
diff --git a/kvm-all.c b/kvm-all.c
index fd8157a..87fe482 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -36,6 +36,8 @@
 #include "qemu/event_notifier.h"
 #include "trace.h"
 
+#include "hw/boards.h"
+
 /* This check must be after config-host.h is included */
 #ifdef CONFIG_EVENTFD
 #include <sys/eventfd.h>
@@ -1339,7 +1341,7 @@ static int kvm_max_vcpus(KVMState *s)
     return (ret) ? ret : kvm_recommended_vcpus(s);
 }
 
-int kvm_init(void)
+int kvm_init(QEMUMachine *machine)
 {
     static const char upgrade_note[] =
         "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
@@ -1356,7 +1358,8 @@ int kvm_init(void)
     KVMState *s;
     const KVMCapabilityInfo *missing_cap;
     int ret;
-    int i;
+    int i, type = 0;
+    const char *kvm_type;
 
     s = g_malloc0(sizeof(KVMState));
 
@@ -1430,8 +1433,16 @@ int kvm_init(void)
         nc++;
     }
 
+    kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type");
+    if (machine->kvm_type) {
+        type = machine->kvm_type(kvm_type);
+    } else if (kvm_type) {
+        fprintf(stderr, "Invalid argument kvm-type=%s\n", kvm_type);
+        goto err;
+    }
+
     do {
-        ret = kvm_ioctl(s, KVM_CREATE_VM, 0);
+        ret = kvm_ioctl(s, KVM_CREATE_VM, type);
     } while (ret == -EINTR);
 
     if (ret < 0) {
diff --git a/kvm-stub.c b/kvm-stub.c
index b1c4429..4ef084e 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -35,7 +35,7 @@ int kvm_init_vcpu(CPUState *cpu)
     return -ENOSYS;
 }
 
-int kvm_init(void)
+int kvm_init(QEMUMachine *machine)
 {
     return -ENOSYS;
 }
diff --git a/qtest.c b/qtest.c
index ae941d6..0ac9f42 100644
--- a/qtest.c
+++ b/qtest.c
@@ -500,7 +500,7 @@ static void qtest_event(void *opaque, int event)
     }
 }
 
-int qtest_init_accel(void)
+int qtest_init_accel(QEMUMachine *machine)
 {
     configure_icount("0");
 
diff --git a/vl.c b/vl.c
index 685a7a9..41581c1 100644
--- a/vl.c
+++ b/vl.c
@@ -374,6 +374,10 @@ static QemuOptsList qemu_machine_opts = {
             .name = "firmware",
             .type = QEMU_OPT_STRING,
             .help = "firmware image",
+        },{
+            .name = "kvm-type",
+            .type = QEMU_OPT_STRING,
+            .help = "Specifies the KVM virtualization mode (HV, PR)",
         },
         { /* End of list */ }
     },
@@ -2578,7 +2582,7 @@ static QEMUMachine *machine_parse(const char *name)
     exit(!name || !is_help_option(name));
 }
 
-static int tcg_init(void)
+static int tcg_init(QEMUMachine *machine)
 {
     tcg_exec_init(tcg_tb_size * 1024 * 1024);
     return 0;
@@ -2588,7 +2592,7 @@ static struct {
     const char *opt_name;
     const char *name;
     int (*available)(void);
-    int (*init)(void);
+    int (*init)(QEMUMachine *);
     bool *allowed;
 } accel_list[] = {
     { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
@@ -2597,7 +2601,7 @@ static struct {
     { "qtest", "QTest", qtest_available, qtest_init_accel, &qtest_allowed },
 };
 
-static int configure_accelerator(void)
+static int configure_accelerator(QEMUMachine *machine)
 {
     const char *p;
     char buf[10];
@@ -2624,7 +2628,7 @@ static int configure_accelerator(void)
                     continue;
                 }
                 *(accel_list[i].allowed) = true;
-                ret = accel_list[i].init();
+                ret = accel_list[i].init(machine);
                 if (ret < 0) {
                     init_failed = true;
                     fprintf(stderr, "failed to initialize %s: %s\n",
@@ -4053,7 +4057,7 @@ int main(int argc, char **argv, char **envp)
         exit(0);
     }
 
-    configure_accelerator();
+    configure_accelerator(machine);
 
     if (qtest_chrdev) {
         Error *local_err = NULL;
diff --git a/xen-all.c b/xen-all.c
index 4a594bd..ba34739 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -1001,7 +1001,7 @@ static void xen_exit_notifier(Notifier *n, void *data)
     xs_daemon_close(state->xenstore);
 }
 
-int xen_init(void)
+int xen_init(QEMUMachine *machine)
 {
     xen_xc = xen_xc_interface_open(0, 0, 0);
     if (xen_xc == XC_HANDLER_INITIAL_VALUE) {
diff --git a/xen-stub.c b/xen-stub.c
index ad189a6..59927cb 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -47,7 +47,7 @@ qemu_irq *xen_interrupt_controller_init(void)
     return NULL;
 }
 
-int xen_init(void)
+int xen_init(QEMUMachine *machine)
 {
     return -ENOSYS;
 }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 009/130] target-ppc: dump DAR and DSISR
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (7 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 008/130] kvm: Add a new machine option kvm-type Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 010/130] target-ppc: fix Authority Mask Register init value Alexander Graf
                   ` (121 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, qemu-ppc, Anton Blanchard, aliguori, aurelien

From: Anton Blanchard <anton@samba.org>

The DAR and DSISR can be very useful when debugging issues, so add
them to ppc_cpu_dump_state. We had another bug in this area: all
of the v2.06 MMU types were missing.

Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c5c1108..31f32df 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -10260,8 +10260,13 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
     case POWERPC_MMU_SOFT_74xx:
 #if defined(TARGET_PPC64)
     case POWERPC_MMU_64B:
+    case POWERPC_MMU_2_06:
+    case POWERPC_MMU_2_06a:
+    case POWERPC_MMU_2_06d:
 #endif
-        cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "\n", env->spr[SPR_SDR1]);
+        cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "   DAR " TARGET_FMT_lx
+                       "  DSISR " TARGET_FMT_lx "\n", env->spr[SPR_SDR1],
+                    env->spr[SPR_DAR], env->spr[SPR_DSISR]);
         break;
     case POWERPC_MMU_BOOKE206:
         cpu_fprintf(f, " MAS0 " TARGET_FMT_lx "  MAS1 " TARGET_FMT_lx
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 010/130] target-ppc: fix Authority Mask Register init value
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (8 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 009/130] target-ppc: dump DAR and DSISR Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 011/130] mmu-hash64: fix Virtual Page Class Key Protection Alexander Graf
                   ` (120 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

The existing default value (-1) of the AMR register forbids data access
to all 32 classes. Since the guest linux does not change this register,
we end up with the guest hanging right after switching from the real to
protected mode.

This sets the default AMR value to zero what enables data access for all
classes.

The only reason for not hitting this bug before is that
kvm_arch_put_registers() did not put any SPR to KVM due to missing
assignment of @one_reg_id in _spr_register() (which is going to be fixed
by a separate patch).

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate_init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index f5a8490..a8987d4 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -1064,7 +1064,7 @@ static void gen_spr_amr (CPUPPCState *env)
     spr_register_kvm(env, SPR_AMR, "AMR",
                      SPR_NOACCESS, SPR_NOACCESS,
                      &spr_read_generic, &spr_write_generic,
-                     KVM_REG_PPC_AMR, 0xffffffffffffffffULL);
+                     KVM_REG_PPC_AMR, 0);
     spr_register_kvm(env, SPR_UAMOR, "UAMOR",
                      SPR_NOACCESS, SPR_NOACCESS,
                      &spr_read_generic, &spr_write_generic,
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 011/130] mmu-hash64: fix Virtual Page Class Key Protection
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (9 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 010/130] target-ppc: fix Authority Mask Register init value Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 012/130] PPC: KVM: fix "set one register" Alexander Graf
                   ` (119 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, Cédric Le Goater, qemu-ppc,
	aliguori, aurelien

From: Cédric Le Goater <clg@fr.ibm.com>

commit f80872e21c07edd06eb343eeeefc8af404b518a6 (mmu-hash64: Implement
Virtual Page Class Key Protection) added a new page protection
mechanism based on page keys and the AMR register to control access.

The AMR register allows or prohibits reads and/or writes on a page
depending on the control bits associated to the key. A store or a load
is only permitted if the associate bit is 0 (Power ISA), and not 1 as
the code is currently doing. This patch modifies ppc_hash64_amr_prot()
to correct the protection check.

This issue was unvailed by commit ccfb53ed6360cac0d5f6f7915ca9ae7eed866412
(target-ppc: fix Authority Mask Register init value) which changed the
initialisation value of the AMR register to 0.

Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/mmu-hash64.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 67fc1b5..c1c33b0 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -278,12 +278,12 @@ static int ppc_hash64_pte_prot(CPUPPCState *env,
 static int ppc_hash64_amr_prot(CPUPPCState *env, ppc_hash_pte64_t pte)
 {
     int key, amrbits;
-    int prot = PAGE_EXEC;
+    int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 
 
     /* Only recent MMUs implement Virtual Page Class Key Protection */
     if (!(env->mmu_model & POWERPC_MMU_AMR)) {
-        return PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+        return prot;
     }
 
     key = HPTE64_R_KEY(pte.pte1);
@@ -292,11 +292,19 @@ static int ppc_hash64_amr_prot(CPUPPCState *env, ppc_hash_pte64_t pte)
     /* fprintf(stderr, "AMR protection: key=%d AMR=0x%" PRIx64 "\n", key, */
     /*         env->spr[SPR_AMR]); */
 
+    /*
+     * A store is permitted if the AMR bit is 0. Remove write
+     * protection if it is set.
+     */
     if (amrbits & 0x2) {
-        prot |= PAGE_WRITE;
+        prot &= ~PAGE_WRITE;
     }
+    /*
+     * A load is permitted if the AMR bit is 0. Remove read
+     * protection if it is set.
+     */
     if (amrbits & 0x1) {
-        prot |= PAGE_READ;
+        prot &= ~PAGE_READ;
     }
 
     return prot;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 012/130] PPC: KVM: fix "set one register"
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (10 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 011/130] mmu-hash64: fix Virtual Page Class Key Protection Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 013/130] PPC: KVM: add support for LPCR Alexander Graf
                   ` (118 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

Due to missing @one_reg_id assignment in _spr_register(),
the kvm_get_one_reg/kvm_set_one_reg API has never really been working.

This reenables the API by assigning the @one_reg_id field in the SPR
descriptor.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate_init.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index a8987d4..80f225a 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -628,6 +628,9 @@ static inline void _spr_register(CPUPPCState *env, int num,
     spr->oea_read = oea_read;
     spr->oea_write = oea_write;
 #endif
+#if defined(CONFIG_KVM)
+    spr->one_reg_id = one_reg_id,
+#endif
     env->spr[num] = initial_value;
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 013/130] PPC: KVM: add support for LPCR
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (11 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 012/130] PPC: KVM: fix "set one register" Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 014/130] spapr-pci: enable adding PHB via -device Alexander Graf
                   ` (117 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, qemu-ppc, aliguori, aurelien, Greg Kurz

From: Greg Kurz <gkurz@linux.vnet.ibm.com>

The LPCR special purpose register was introduced with the PowerPC 970MP family.

This patch initializes LPCR for the following families:
- 970 MP
- POWER5+
- POWER7
- POWER8

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate_init.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 80f225a..d751fc3 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -2582,7 +2582,6 @@ static void gen_spr_8xx (CPUPPCState *env)
  * HSRR0   => SPR 314 (Power 2.04 hypv)
  * HSRR1   => SPR 315 (Power 2.04 hypv)
  * LPIDR   => SPR 317 (970)
- * LPCR    => SPR 318 (970)
  * EPR     => SPR 702 (Power 2.04 emb)
  * perf    => 768-783 (Power 2.04)
  * perf    => 784-799 (Power 2.04)
@@ -6831,6 +6830,11 @@ static void init_proc_970MP (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_hior, &spr_write_hior,
                  0x00000000);
+    /* Logical partitionning */
+    spr_register_kvm(env, SPR_LPCR, "LPCR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_LPCR, 0x00000000);
 #if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
@@ -6915,6 +6919,11 @@ static void init_proc_power5plus(CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
+    /* Logical partitionning */
+    spr_register_kvm(env, SPR_LPCR, "LPCR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_LPCR, 0x00000000);
 #if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 64;
 #endif
@@ -7019,6 +7028,11 @@ static void init_proc_POWER7 (CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
+    /* Logical partitionning */
+    spr_register_kvm(env, SPR_LPCR, "LPCR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     KVM_REG_PPC_LPCR, 0x00000000);
 #if !defined(CONFIG_USER_ONLY)
     env->slb_nr = 32;
 #endif
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 014/130] spapr-pci: enable adding PHB via -device
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (12 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 013/130] PPC: KVM: add support for LPCR Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 015/130] spapr_vscsi: Fix REPORT_LUNS handling Alexander Graf
                   ` (116 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

Recent changes introduced cannot_instantiate_with_device_add_yet
and removed capability of adding yet another PCI host bridge via
command line for SPAPR platform (POWERPC64 server).

This brings the capability back and puts SPAPR PHB into "bridge"
category.

This is not much use for emulated PHB but it is absolutely required
for VFIO as we put an IOMMU group onto a separate PHB on SPAPR.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 4c7c3ae..3956328 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -728,6 +728,8 @@ static void spapr_phb_class_init(ObjectClass *klass, void *data)
     dc->props = spapr_phb_properties;
     dc->reset = spapr_phb_reset;
     dc->vmsd = &vmstate_spapr_pci;
+    set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
+    dc->cannot_instantiate_with_device_add_yet = false;
 }
 
 static const TypeInfo spapr_phb_info = {
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 015/130] spapr_vscsi: Fix REPORT_LUNS handling
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (13 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 014/130] spapr-pci: enable adding PHB via -device Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 016/130] target-ppc: disable unsupported modes for SPR_CTRL/SPR_UCTRL Alexander Graf
                   ` (115 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, qemu-ppc, Nathan Whitehorn, aliguori,
	aurelien

From: Nathan Whitehorn <nwhitehorn@freebsd.org>

Intercept REPORT_LUNS commands addressed either to SRP LUN 0 or the well-known
LUN for REPORT_LUNS commands. This is required to implement the SAM and SPC
specifications.

Since SRP implements only a single SCSI target port per connection, the SRP
target is required to report all available LUNs in response to a REPORT_LUNS
command addressed either to LUN 0 or the well-known LUN. Instead, QEMU was
forwarding such requests to the first QEMU SCSI target, with the result that
initiators that relied on this feature would only see LUNs on the first QEMU
SCSI target.

Behavior for REPORT_LUNS commands addressed to any other LUN is not specified
by the standard and so is left unchanged. This preserves behavior under Linux
and SLOF, which enumerate possible LUNs by hand and so address no commands
either to LUN 0 or the well-known REPORT_LUNS LUN.

Signed-off-by: Nathan Whitehorn <nwhitehorn@freebsd.org>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
[agraf: define constant as ULL for 32bit hosts]
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/scsi/spapr_vscsi.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index e8bca39..b3835c8 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -62,6 +62,8 @@
 
 #define SRP_RSP_SENSE_DATA_LEN  18
 
+#define SRP_REPORT_LUNS_WLUN    0xc10100000000000ULL
+
 typedef union vscsi_crq {
     struct viosrp_crq s;
     uint8_t raw[16];
@@ -719,12 +721,70 @@ static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req)
     }
 }
 
+static void vscsi_report_luns(VSCSIState *s, vscsi_req *req)
+{
+    BusChild *kid;
+    int i, len, n, rc;
+    uint8_t *resp_data;
+    bool found_lun0;
+
+    n = 0;
+    found_lun0 = false;
+    QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+        SCSIDevice *dev = SCSI_DEVICE(kid->child);
+
+        n += 8;
+        if (dev->channel == 0 && dev->id == 0 && dev->lun == 0) {
+            found_lun0 = true;
+        }
+    }
+    if (!found_lun0) {
+        n += 8;
+    }
+    len = n+8;
+
+    resp_data = g_malloc0(len);
+    memset(resp_data, 0, len);
+    stl_be_p(resp_data, n);
+    i = found_lun0 ? 8 : 16;
+    QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+        DeviceState *qdev = kid->child;
+        SCSIDevice *dev = SCSI_DEVICE(qdev);
+
+        if (dev->id == 0 && dev->channel == 0) {
+            resp_data[i] = 0;         /* Use simple LUN for 0 (SAM5 4.7.7.1) */
+        } else {
+            resp_data[i] = (2 << 6);  /* Otherwise LUN addressing (4.7.7.4)  */
+        }
+        resp_data[i] |= dev->id;
+        resp_data[i+1] = (dev->channel << 5);
+        resp_data[i+1] |= dev->lun;
+        i += 8;
+    }
+
+    vscsi_preprocess_desc(req);
+    rc = vscsi_srp_transfer_data(s, req, 0, resp_data, len);
+    g_free(resp_data);
+    if (rc < 0) {
+        vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
+        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
+    } else {
+        vscsi_send_rsp(s, req, 0, len - rc, 0);
+    }
+}
+
 static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
 {
     union srp_iu *srp = &req->iu.srp;
     SCSIDevice *sdev;
     int n, lun;
 
+    if ((srp->cmd.lun == 0 || be64_to_cpu(srp->cmd.lun) == SRP_REPORT_LUNS_WLUN)
+      && srp->cmd.cdb[0] == REPORT_LUNS) {
+        vscsi_report_luns(s, req);
+        return 0;
+    }
+
     sdev = vscsi_device_find(&s->bus, be64_to_cpu(srp->cmd.lun), &lun);
     if (!sdev) {
         DPRINTF("VSCSI: Command for lun %08" PRIx64 " with no drive\n",
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 016/130] target-ppc: disable unsupported modes for SPR_CTRL/SPR_UCTRL
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (14 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 015/130] spapr_vscsi: Fix REPORT_LUNS handling Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 017/130] target-ppc: Add set_fprf Argument to fload_invalid_op_excp() Alexander Graf
                   ` (114 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

The Figure 17 "SPR encodings" of the PowerISA 2.07 describes CTRL SPR as:

                       priviledged
#   spr5-9 spr0-4 name mtspr mfspr len cat
136 00100  01000  CTRL   -    no    32  S
152 00100  11000  CTRL  yes    -    32  S

According to this chart, the hypervisor's CTRL (#152) does not support
reading, the user-space's CTRL (UCTRL, #136) does not support writing.

This replaces unsupported operations with the default SPR_NOACCESS hook.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate_init.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index d751fc3..02f5867 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -6739,11 +6739,11 @@ static void init_proc_970FX (CPUPPCState *env)
                  0x00000000);
     spr_register(env, SPR_CTRL, "SPR_CTRL",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 SPR_NOACCESS, &spr_write_generic,
                  0x00000000);
     spr_register(env, SPR_UCTRL, "SPR_UCTRL",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, SPR_NOACCESS,
                  0x00000000);
     spr_register(env, SPR_VRSAVE, "SPR_VRSAVE",
                  &spr_read_generic, &spr_write_generic,
@@ -6909,11 +6909,11 @@ static void init_proc_power5plus(CPUPPCState *env)
                  0x00000000);
     spr_register(env, SPR_CTRL, "SPR_CTRL",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 SPR_NOACCESS, &spr_write_generic,
                  0x00000000);
     spr_register(env, SPR_UCTRL, "SPR_UCTRL",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, SPR_NOACCESS,
                  0x00000000);
     spr_register(env, SPR_VRSAVE, "SPR_VRSAVE",
                  &spr_read_generic, &spr_write_generic,
@@ -7014,11 +7014,11 @@ static void init_proc_POWER7 (CPUPPCState *env)
     /* XXX : not implemented */
     spr_register(env, SPR_CTRL, "SPR_CTRLT",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 SPR_NOACCESS, &spr_write_generic,
                  0x80800000);
     spr_register(env, SPR_UCTRL, "SPR_CTRLF",
                  SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, SPR_NOACCESS,
                  0x80800000);
     spr_register(env, SPR_VRSAVE, "SPR_VRSAVE",
                  &spr_read_generic, &spr_write_generic,
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 017/130] target-ppc: Add set_fprf Argument to fload_invalid_op_excp()
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (15 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 016/130] target-ppc: disable unsupported modes for SPR_CTRL/SPR_UCTRL Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 018/130] target-ppc: General Support for VSX Helpers Alexander Graf
                   ` (113 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

The fload_invalid_op_excp() function sets assorted invalid
operation status bits.  However, it also implicitly modifies
the FPRF field of the PowerPC FPSCR.  Many VSX instructions
set invalid operation bits but do not alter FPRF.  Thus the
function is more generally useful if the setting of the FPRF
field is made conditional via a parameter.

All invocations of this routine in existing instructions are
modified to pass 1 and thus retain their current behavior.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 103 ++++++++++++++++++++++++++----------------------
 1 file changed, 55 insertions(+), 48 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 4f60218..f0b0a49 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -106,7 +106,8 @@ uint32_t helper_compute_fprf(CPUPPCState *env, uint64_t arg, uint32_t set_fprf)
 }
 
 /* Floating-point invalid operations exception */
-static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op)
+static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op,
+                                             int set_fpcc)
 {
     uint64_t ret = 0;
     int ve;
@@ -138,8 +139,10 @@ static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op)
     case POWERPC_EXCP_FP_VXVC:
         /* Ordered comparison of NaN */
         env->fpscr |= 1 << FPSCR_VXVC;
-        env->fpscr &= ~(0xF << FPSCR_FPCC);
-        env->fpscr |= 0x11 << FPSCR_FPCC;
+        if (set_fpcc) {
+            env->fpscr &= ~(0xF << FPSCR_FPCC);
+            env->fpscr |= 0x11 << FPSCR_FPCC;
+        }
         /* We must update the target FPR before raising the exception */
         if (ve != 0) {
             env->exception_index = POWERPC_EXCP_PROGRAM;
@@ -158,8 +161,10 @@ static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op)
         if (ve == 0) {
             /* Set the result to quiet NaN */
             ret = 0x7FF8000000000000ULL;
-            env->fpscr &= ~(0xF << FPSCR_FPCC);
-            env->fpscr |= 0x11 << FPSCR_FPCC;
+            if (set_fpcc) {
+                env->fpscr &= ~(0xF << FPSCR_FPCC);
+                env->fpscr |= 0x11 << FPSCR_FPCC;
+            }
         }
         break;
     case POWERPC_EXCP_FP_VXCVI:
@@ -169,8 +174,10 @@ static inline uint64_t fload_invalid_op_excp(CPUPPCState *env, int op)
         if (ve == 0) {
             /* Set the result to quiet NaN */
             ret = 0x7FF8000000000000ULL;
-            env->fpscr &= ~(0xF << FPSCR_FPCC);
-            env->fpscr |= 0x11 << FPSCR_FPCC;
+            if (set_fpcc) {
+                env->fpscr &= ~(0xF << FPSCR_FPCC);
+                env->fpscr |= 0x11 << FPSCR_FPCC;
+            }
         }
         break;
     }
@@ -505,12 +512,12 @@ uint64_t helper_fadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
     if (unlikely(float64_is_infinity(farg1.d) && float64_is_infinity(farg2.d) &&
                  float64_is_neg(farg1.d) != float64_is_neg(farg2.d))) {
         /* Magnitude subtraction of infinities */
-        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI);
+        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
     } else {
         if (unlikely(float64_is_signaling_nan(farg1.d) ||
                      float64_is_signaling_nan(farg2.d))) {
             /* sNaN addition */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
         farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status);
     }
@@ -529,12 +536,12 @@ uint64_t helper_fsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
     if (unlikely(float64_is_infinity(farg1.d) && float64_is_infinity(farg2.d) &&
                  float64_is_neg(farg1.d) == float64_is_neg(farg2.d))) {
         /* Magnitude subtraction of infinities */
-        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI);
+        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
     } else {
         if (unlikely(float64_is_signaling_nan(farg1.d) ||
                      float64_is_signaling_nan(farg2.d))) {
             /* sNaN subtraction */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
         farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status);
     }
@@ -553,12 +560,12 @@ uint64_t helper_fmul(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
     if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||
                  (float64_is_zero(farg1.d) && float64_is_infinity(farg2.d)))) {
         /* Multiplication of zero by infinity */
-        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ);
+        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
     } else {
         if (unlikely(float64_is_signaling_nan(farg1.d) ||
                      float64_is_signaling_nan(farg2.d))) {
             /* sNaN multiplication */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
         farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
     }
@@ -577,15 +584,15 @@ uint64_t helper_fdiv(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
     if (unlikely(float64_is_infinity(farg1.d) &&
                  float64_is_infinity(farg2.d))) {
         /* Division of infinity by infinity */
-        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI);
+        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1);
     } else if (unlikely(float64_is_zero(farg1.d) && float64_is_zero(farg2.d))) {
         /* Division of zero by zero */
-        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ);
+        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1);
     } else {
         if (unlikely(float64_is_signaling_nan(farg1.d) ||
                      float64_is_signaling_nan(farg2.d))) {
             /* sNaN division */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
         farg1.d = float64_div(farg1.d, farg2.d, &env->fp_status);
     }
@@ -603,11 +610,11 @@ uint64_t helper_fctiw(CPUPPCState *env, uint64_t arg)
     if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN conversion */
         farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                        POWERPC_EXCP_FP_VXCVI);
+                                        POWERPC_EXCP_FP_VXCVI, 1);
     } else if (unlikely(float64_is_quiet_nan(farg.d) ||
                         float64_is_infinity(farg.d))) {
         /* qNan / infinity conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI);
+        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);
     } else {
         farg.ll = float64_to_int32(farg.d, &env->fp_status);
         /* XXX: higher bits are not supposed to be significant.
@@ -628,11 +635,11 @@ uint64_t helper_fctiwz(CPUPPCState *env, uint64_t arg)
     if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN conversion */
         farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                        POWERPC_EXCP_FP_VXCVI);
+                                        POWERPC_EXCP_FP_VXCVI, 1);
     } else if (unlikely(float64_is_quiet_nan(farg.d) ||
                         float64_is_infinity(farg.d))) {
         /* qNan / infinity conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI);
+        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);
     } else {
         farg.ll = float64_to_int32_round_to_zero(farg.d, &env->fp_status);
         /* XXX: higher bits are not supposed to be significant.
@@ -663,11 +670,11 @@ uint64_t helper_fctid(CPUPPCState *env, uint64_t arg)
     if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN conversion */
         farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                        POWERPC_EXCP_FP_VXCVI);
+                                        POWERPC_EXCP_FP_VXCVI, 1);
     } else if (unlikely(float64_is_quiet_nan(farg.d) ||
                         float64_is_infinity(farg.d))) {
         /* qNan / infinity conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI);
+        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);
     } else {
         farg.ll = float64_to_int64(farg.d, &env->fp_status);
     }
@@ -684,11 +691,11 @@ uint64_t helper_fctidz(CPUPPCState *env, uint64_t arg)
     if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN conversion */
         farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                        POWERPC_EXCP_FP_VXCVI);
+                                        POWERPC_EXCP_FP_VXCVI, 1);
     } else if (unlikely(float64_is_quiet_nan(farg.d) ||
                         float64_is_infinity(farg.d))) {
         /* qNan / infinity conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI);
+        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);
     } else {
         farg.ll = float64_to_int64_round_to_zero(farg.d, &env->fp_status);
     }
@@ -707,11 +714,11 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg,
     if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN round */
         farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                        POWERPC_EXCP_FP_VXCVI);
+                                        POWERPC_EXCP_FP_VXCVI, 1);
     } else if (unlikely(float64_is_quiet_nan(farg.d) ||
                         float64_is_infinity(farg.d))) {
         /* qNan / infinity round */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI);
+        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);
     } else {
         set_float_rounding_mode(rounding_mode, &env->fp_status);
         farg.ll = float64_round_to_int(farg.d, &env->fp_status);
@@ -754,13 +761,13 @@ uint64_t helper_fmadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
     if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||
                  (float64_is_zero(farg1.d) && float64_is_infinity(farg2.d)))) {
         /* Multiplication of zero by infinity */
-        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ);
+        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
     } else {
         if (unlikely(float64_is_signaling_nan(farg1.d) ||
                      float64_is_signaling_nan(farg2.d) ||
                      float64_is_signaling_nan(farg3.d))) {
             /* sNaN operation */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
         /* This is the way the PowerPC specification defines it */
         float128 ft0_128, ft1_128;
@@ -772,7 +779,7 @@ uint64_t helper_fmadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
                      float64_is_infinity(farg3.d) &&
                      float128_is_neg(ft0_128) != float64_is_neg(farg3.d))) {
             /* Magnitude subtraction of infinities */
-            farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI);
+            farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
         } else {
             ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
             ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
@@ -797,13 +804,13 @@ uint64_t helper_fmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
                  (float64_is_zero(farg1.d) &&
                   float64_is_infinity(farg2.d)))) {
         /* Multiplication of zero by infinity */
-        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ);
+        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
     } else {
         if (unlikely(float64_is_signaling_nan(farg1.d) ||
                      float64_is_signaling_nan(farg2.d) ||
                      float64_is_signaling_nan(farg3.d))) {
             /* sNaN operation */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
         /* This is the way the PowerPC specification defines it */
         float128 ft0_128, ft1_128;
@@ -815,7 +822,7 @@ uint64_t helper_fmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
                      float64_is_infinity(farg3.d) &&
                      float128_is_neg(ft0_128) == float64_is_neg(farg3.d))) {
             /* Magnitude subtraction of infinities */
-            farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI);
+            farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
         } else {
             ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
             ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
@@ -838,13 +845,13 @@ uint64_t helper_fnmadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
     if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||
                  (float64_is_zero(farg1.d) && float64_is_infinity(farg2.d)))) {
         /* Multiplication of zero by infinity */
-        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ);
+        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
     } else {
         if (unlikely(float64_is_signaling_nan(farg1.d) ||
                      float64_is_signaling_nan(farg2.d) ||
                      float64_is_signaling_nan(farg3.d))) {
             /* sNaN operation */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
         /* This is the way the PowerPC specification defines it */
         float128 ft0_128, ft1_128;
@@ -856,7 +863,7 @@ uint64_t helper_fnmadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
                      float64_is_infinity(farg3.d) &&
                      float128_is_neg(ft0_128) != float64_is_neg(farg3.d))) {
             /* Magnitude subtraction of infinities */
-            farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI);
+            farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
         } else {
             ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
             ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
@@ -883,13 +890,13 @@ uint64_t helper_fnmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
                  (float64_is_zero(farg1.d) &&
                   float64_is_infinity(farg2.d)))) {
         /* Multiplication of zero by infinity */
-        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ);
+        farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
     } else {
         if (unlikely(float64_is_signaling_nan(farg1.d) ||
                      float64_is_signaling_nan(farg2.d) ||
                      float64_is_signaling_nan(farg3.d))) {
             /* sNaN operation */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
         /* This is the way the PowerPC specification defines it */
         float128 ft0_128, ft1_128;
@@ -901,7 +908,7 @@ uint64_t helper_fnmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
                      float64_is_infinity(farg3.d) &&
                      float128_is_neg(ft0_128) == float64_is_neg(farg3.d))) {
             /* Magnitude subtraction of infinities */
-            farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI);
+            farg1.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
         } else {
             ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
             ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
@@ -924,7 +931,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
 
     if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN square root */
-        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
     }
     f32 = float64_to_float32(farg.d, &env->fp_status);
     farg.d = float32_to_float64(f32, &env->fp_status);
@@ -941,11 +948,11 @@ uint64_t helper_fsqrt(CPUPPCState *env, uint64_t arg)
 
     if (unlikely(float64_is_neg(farg.d) && !float64_is_zero(farg.d))) {
         /* Square root of a negative nonzero number */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT);
+        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1);
     } else {
         if (unlikely(float64_is_signaling_nan(farg.d))) {
             /* sNaN square root */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
         farg.d = float64_sqrt(farg.d, &env->fp_status);
     }
@@ -961,7 +968,7 @@ uint64_t helper_fre(CPUPPCState *env, uint64_t arg)
 
     if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN reciprocal */
-        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
     }
     farg.d = float64_div(float64_one, farg.d, &env->fp_status);
     return farg.d;
@@ -977,7 +984,7 @@ uint64_t helper_fres(CPUPPCState *env, uint64_t arg)
 
     if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN reciprocal */
-        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
     }
     farg.d = float64_div(float64_one, farg.d, &env->fp_status);
     f32 = float64_to_float32(farg.d, &env->fp_status);
@@ -996,11 +1003,11 @@ uint64_t helper_frsqrte(CPUPPCState *env, uint64_t arg)
 
     if (unlikely(float64_is_neg(farg.d) && !float64_is_zero(farg.d))) {
         /* Reciprocal square root of a negative nonzero number */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT);
+        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1);
     } else {
         if (unlikely(float64_is_signaling_nan(farg.d))) {
             /* sNaN reciprocal square root */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
         }
         farg.d = float64_sqrt(farg.d, &env->fp_status);
         farg.d = float64_div(float64_one, farg.d, &env->fp_status);
@@ -1053,7 +1060,7 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
                  && (float64_is_signaling_nan(farg1.d) ||
                      float64_is_signaling_nan(farg2.d)))) {
         /* sNaN comparison */
-        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);
+        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
     }
 }
 
@@ -1085,10 +1092,10 @@ void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
             float64_is_signaling_nan(farg2.d)) {
             /* sNaN comparison */
             fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                  POWERPC_EXCP_FP_VXVC);
+                                  POWERPC_EXCP_FP_VXVC, 1);
         } else {
             /* qNaN comparison */
-            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC);
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 1);
         }
     }
 }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 018/130] target-ppc: General Support for VSX Helpers
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (16 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 017/130] target-ppc: Add set_fprf Argument to fload_invalid_op_excp() Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 019/130] target-ppc: Add VSX ISA2.06 xadd/xsub Instructions Alexander Graf
                   ` (112 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds general support that will be used by the VSX helper
routines:

  - a union describing the various VSR subfields.
  - access routines to get and set VSRs
  - VSX decoders
  - a general routine to generate a handler that invokes a VSX
    helper.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 41 +++++++++++++++++++++++++++++++++++++++++
 target-ppc/translate.c  | 14 ++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index f0b0a49..cea94ac 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1717,3 +1717,44 @@ uint32_t helper_efdcmpeq(CPUPPCState *env, uint64_t op1, uint64_t op2)
     /* XXX: TODO: test special values (NaN, infinites, ...) */
     return helper_efdtsteq(env, op1, op2);
 }
+
+#define DECODE_SPLIT(opcode, shift1, nb1, shift2, nb2) \
+    (((((opcode) >> (shift1)) & ((1 << (nb1)) - 1)) << nb2) |    \
+     (((opcode) >> (shift2)) & ((1 << (nb2)) - 1)))
+
+#define xT(opcode) DECODE_SPLIT(opcode, 0, 1, 21, 5)
+#define xA(opcode) DECODE_SPLIT(opcode, 2, 1, 16, 5)
+#define xB(opcode) DECODE_SPLIT(opcode, 1, 1, 11, 5)
+#define xC(opcode) DECODE_SPLIT(opcode, 3, 1,  6, 5)
+#define BF(opcode) (((opcode) >> (31-8)) & 7)
+
+typedef union _ppc_vsr_t {
+    uint64_t u64[2];
+    uint32_t u32[4];
+    float32 f32[4];
+    float64 f64[2];
+} ppc_vsr_t;
+
+static void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
+{
+    if (n < 32) {
+        vsr->f64[0] = env->fpr[n];
+        vsr->u64[1] = env->vsr[n];
+    } else {
+        vsr->u64[0] = env->avr[n-32].u64[0];
+        vsr->u64[1] = env->avr[n-32].u64[1];
+    }
+}
+
+static void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
+{
+    if (n < 32) {
+        env->fpr[n] = vsr->f64[0];
+        env->vsr[n] = vsr->u64[1];
+    } else {
+        env->avr[n-32].u64[0] = vsr->u64[0];
+        env->avr[n-32].u64[1] = vsr->u64[1];
+    }
+}
+
+#define float64_to_float64(x, env) x
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 31f32df..8c17005 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7289,6 +7289,20 @@ VSX_VECTOR_MOVE(xvnabssp, OP_NABS, SGN_MASK_SP)
 VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP)
 VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP)
 
+#define GEN_VSX_HELPER_2(name, op1, op2, inval, type)                         \
+static void gen_##name(DisasContext * ctx)                                    \
+{                                                                             \
+    TCGv_i32 opc;                                                             \
+    if (unlikely(!ctx->vsx_enabled)) {                                        \
+        gen_exception(ctx, POWERPC_EXCP_VSXU);                                \
+        return;                                                               \
+    }                                                                         \
+    /* NIP cannot be restored if the memory exception comes from an helper */ \
+    gen_update_nip(ctx, ctx->nip - 4);                                        \
+    opc = tcg_const_i32(ctx->opcode);                                         \
+    gen_helper_##name(cpu_env, opc);                                          \
+    tcg_temp_free_i32(opc);                                                   \
+}
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 019/130] target-ppc: Add VSX ISA2.06 xadd/xsub Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (17 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 018/130] target-ppc: General Support for VSX Helpers Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 020/130] target-ppc: Add VSX ISA2.06 xmul Instructions Alexander Graf
                   ` (111 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the floating point addition and subtraction
instructions defined by V2.06 of the PowerPC ISA: xssubdp,
xvsubdp and xvsubsp.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  9 +++++++++
 target-ppc/translate.c  | 18 ++++++++++++++++++
 3 files changed, 77 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index cea94ac..74c1ce1 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1758,3 +1758,53 @@ static void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
 }
 
 #define float64_to_float64(x, env) x
+
+
+/* VSX_ADD_SUB - VSX floating point add/subract
+ *   name  - instruction mnemonic
+ *   op    - operation (add or sub)
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   sfprf - set FPRF
+ */
+#define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf)                          \
+void helper_##name(CPUPPCState *env, uint32_t opcode)                        \
+{                                                                            \
+    ppc_vsr_t xt, xa, xb;                                                    \
+    int i;                                                                   \
+                                                                             \
+    getVSR(xA(opcode), &xa, env);                                            \
+    getVSR(xB(opcode), &xb, env);                                            \
+    getVSR(xT(opcode), &xt, env);                                            \
+    helper_reset_fpstatus(env);                                              \
+                                                                             \
+    for (i = 0; i < nels; i++) {                                             \
+        float_status tstat = env->fp_status;                                 \
+        set_float_exception_flags(0, &tstat);                                \
+        xt.fld[i] = tp##_##op(xa.fld[i], xb.fld[i], &tstat);                 \
+        env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
+                                                                             \
+        if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
+            if (tp##_is_infinity(xa.fld[i]) && tp##_is_infinity(xb.fld[i])) {\
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf);    \
+            } else if (tp##_is_signaling_nan(xa.fld[i]) ||                   \
+                       tp##_is_signaling_nan(xb.fld[i])) {                   \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);   \
+            }                                                                \
+        }                                                                    \
+                                                                             \
+        if (sfprf) {                                                         \
+            helper_compute_fprf(env, xt.fld[i], sfprf);                      \
+        }                                                                    \
+    }                                                                        \
+    putVSR(xT(opcode), &xt, env);                                            \
+    helper_float_check_status(env);                                          \
+}
+
+VSX_ADD_SUB(xsadddp, add, 1, float64, f64, 1)
+VSX_ADD_SUB(xvadddp, add, 2, float64, f64, 0)
+VSX_ADD_SUB(xvaddsp, add, 4, float32, f32, 0)
+VSX_ADD_SUB(xssubdp, sub, 1, float64, f64, 1)
+VSX_ADD_SUB(xvsubdp, sub, 2, float64, f64, 0)
+VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 6d282bb..966200d 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -251,6 +251,15 @@ DEF_HELPER_4(vcfsx, void, env, avr, avr, i32)
 DEF_HELPER_4(vctuxs, void, env, avr, avr, i32)
 DEF_HELPER_4(vctsxs, void, env, avr, avr, i32)
 
+DEF_HELPER_2(xsadddp, void, env, i32)
+DEF_HELPER_2(xssubdp, void, env, i32)
+
+DEF_HELPER_2(xvadddp, void, env, i32)
+DEF_HELPER_2(xvsubdp, void, env, i32)
+
+DEF_HELPER_2(xvaddsp, void, env, i32)
+DEF_HELPER_2(xvsubsp, void, env, i32)
+
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
 DEF_HELPER_2(efscfuf, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 8c17005..9b4e8b1 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7304,6 +7304,15 @@ static void gen_##name(DisasContext * ctx)                                    \
     tcg_temp_free_i32(opc);                                                   \
 }
 
+GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
+
+GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
+
+GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
+
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
     {                                                                \
@@ -9985,6 +9994,15 @@ GEN_XX2FORM(xvnabssp, 0x12, 0x1A, PPC2_VSX),
 GEN_XX2FORM(xvnegsp, 0x12, 0x1B, PPC2_VSX),
 GEN_XX3FORM(xvcpsgnsp, 0x00, 0x1A, PPC2_VSX),
 
+GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX),
+GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX),
+
+GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
+GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
+
+GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
+GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
+
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
 GEN_XX3FORM(name, opc2, opc3, fl2)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 020/130] target-ppc: Add VSX ISA2.06 xmul Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (18 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 019/130] target-ppc: Add VSX ISA2.06 xadd/xsub Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 021/130] target-ppc: Add VSX ISA2.06 xdiv Instructions Alexander Graf
                   ` (110 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX floating point multiply instructions defined
by V2.06 of the PowerPC ISA: xsmuldp, xvmuldp, xvmulsp.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  3 +++
 target-ppc/translate.c  |  6 ++++++
 3 files changed, 56 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 74c1ce1..51ca589 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1808,3 +1808,50 @@ VSX_ADD_SUB(xvaddsp, add, 4, float32, f32, 0)
 VSX_ADD_SUB(xssubdp, sub, 1, float64, f64, 1)
 VSX_ADD_SUB(xvsubdp, sub, 2, float64, f64, 0)
 VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0)
+
+/* VSX_MUL - VSX floating point multiply
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   sfprf - set FPRF
+ */
+#define VSX_MUL(op, nels, tp, fld, sfprf)                                    \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
+{                                                                            \
+    ppc_vsr_t xt, xa, xb;                                                    \
+    int i;                                                                   \
+                                                                             \
+    getVSR(xA(opcode), &xa, env);                                            \
+    getVSR(xB(opcode), &xb, env);                                            \
+    getVSR(xT(opcode), &xt, env);                                            \
+    helper_reset_fpstatus(env);                                              \
+                                                                             \
+    for (i = 0; i < nels; i++) {                                             \
+        float_status tstat = env->fp_status;                                 \
+        set_float_exception_flags(0, &tstat);                                \
+        xt.fld[i] = tp##_mul(xa.fld[i], xb.fld[i], &tstat);                  \
+        env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
+                                                                             \
+        if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
+            if ((tp##_is_infinity(xa.fld[i]) && tp##_is_zero(xb.fld[i])) ||  \
+                (tp##_is_infinity(xb.fld[i]) && tp##_is_zero(xa.fld[i]))) {  \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, sfprf);    \
+            } else if (tp##_is_signaling_nan(xa.fld[i]) ||                   \
+                       tp##_is_signaling_nan(xb.fld[i])) {                   \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);   \
+            }                                                                \
+        }                                                                    \
+                                                                             \
+        if (sfprf) {                                                         \
+            helper_compute_fprf(env, xt.fld[i], sfprf);                      \
+        }                                                                    \
+    }                                                                        \
+                                                                             \
+    putVSR(xT(opcode), &xt, env);                                            \
+    helper_float_check_status(env);                                          \
+}
+
+VSX_MUL(xsmuldp, 1, float64, f64, 1)
+VSX_MUL(xvmuldp, 2, float64, f64, 0)
+VSX_MUL(xvmulsp, 4, float32, f32, 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 966200d..ecb900f 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -253,12 +253,15 @@ DEF_HELPER_4(vctsxs, void, env, avr, avr, i32)
 
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
+DEF_HELPER_2(xsmuldp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
+DEF_HELPER_2(xvmuldp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
+DEF_HELPER_2(xvmulsp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 9b4e8b1..bf15f91 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7306,12 +7306,15 @@ static void gen_##name(DisasContext * ctx)                                    \
 
 GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -9996,12 +9999,15 @@ GEN_XX3FORM(xvcpsgnsp, 0x00, 0x1A, PPC2_VSX),
 
 GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX),
 GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX),
+GEN_XX3FORM(xsmuldp, 0x00, 0x06, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
+GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
+GEN_XX3FORM(xvmulsp, 0x00, 0x0A, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 021/130] target-ppc: Add VSX ISA2.06 xdiv Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (19 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 020/130] target-ppc: Add VSX ISA2.06 xmul Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 022/130] target-ppc: Add VSX ISA2.06 xre Instructions Alexander Graf
                   ` (109 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX floating point divide instructions defined
by V2.06 of the PowerPC ISA: xsdivdp, xvdivdp, xvdivsp.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  3 +++
 target-ppc/translate.c  |  6 ++++++
 3 files changed, 58 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 51ca589..c84f432 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1855,3 +1855,52 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
 VSX_MUL(xsmuldp, 1, float64, f64, 1)
 VSX_MUL(xvmuldp, 2, float64, f64, 0)
 VSX_MUL(xvmulsp, 4, float32, f32, 0)
+
+/* VSX_DIV - VSX floating point divide
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   sfprf - set FPRF
+ */
+#define VSX_DIV(op, nels, tp, fld, sfprf)                                     \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
+{                                                                             \
+    ppc_vsr_t xt, xa, xb;                                                     \
+    int i;                                                                    \
+                                                                              \
+    getVSR(xA(opcode), &xa, env);                                             \
+    getVSR(xB(opcode), &xb, env);                                             \
+    getVSR(xT(opcode), &xt, env);                                             \
+    helper_reset_fpstatus(env);                                               \
+                                                                              \
+    for (i = 0; i < nels; i++) {                                              \
+        float_status tstat = env->fp_status;                                  \
+        set_float_exception_flags(0, &tstat);                                 \
+        xt.fld[i] = tp##_div(xa.fld[i], xb.fld[i], &tstat);                   \
+        env->fp_status.float_exception_flags |= tstat.float_exception_flags;  \
+                                                                              \
+        if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {     \
+            if (tp##_is_infinity(xa.fld[i]) && tp##_is_infinity(xb.fld[i])) { \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, sfprf);     \
+            } else if (tp##_is_zero(xa.fld[i]) &&                             \
+                tp##_is_zero(xb.fld[i])) {                                    \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf);     \
+            } else if (tp##_is_signaling_nan(xa.fld[i]) ||                    \
+                tp##_is_signaling_nan(xb.fld[i])) {                           \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);    \
+            }                                                                 \
+        }                                                                     \
+                                                                              \
+        if (sfprf) {                                                          \
+            helper_compute_fprf(env, xt.fld[i], sfprf);                       \
+        }                                                                     \
+    }                                                                         \
+                                                                              \
+    putVSR(xT(opcode), &xt, env);                                             \
+    helper_float_check_status(env);                                           \
+}
+
+VSX_DIV(xsdivdp, 1, float64, f64, 1)
+VSX_DIV(xvdivdp, 2, float64, f64, 0)
+VSX_DIV(xvdivsp, 4, float32, f32, 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index ecb900f..6ede7ea 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -254,14 +254,17 @@ DEF_HELPER_4(vctsxs, void, env, avr, avr, i32)
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
 DEF_HELPER_2(xsmuldp, void, env, i32)
+DEF_HELPER_2(xsdivdp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
 DEF_HELPER_2(xvmuldp, void, env, i32)
+DEF_HELPER_2(xvdivdp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
 DEF_HELPER_2(xvmulsp, void, env, i32)
+DEF_HELPER_2(xvdivsp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index bf15f91..076574e 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7307,14 +7307,17 @@ static void gen_##name(DisasContext * ctx)                                    \
 GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10000,14 +10003,17 @@ GEN_XX3FORM(xvcpsgnsp, 0x00, 0x1A, PPC2_VSX),
 GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX),
 GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX),
 GEN_XX3FORM(xsmuldp, 0x00, 0x06, PPC2_VSX),
+GEN_XX3FORM(xsdivdp, 0x00, 0x07, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
 GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX),
+GEN_XX3FORM(xvdivdp, 0x00, 0x0F, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
 GEN_XX3FORM(xvmulsp, 0x00, 0x0A, PPC2_VSX),
+GEN_XX3FORM(xvdivsp, 0x00, 0x0B, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 022/130] target-ppc: Add VSX ISA2.06 xre Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (20 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 021/130] target-ppc: Add VSX ISA2.06 xdiv Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 023/130] target-ppc: Add VSX ISA2.06 xsqrt Instructions Alexander Graf
                   ` (108 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX floating point reciprocal estimate instructions
defined by V2.06 of the PowerPC ISA: xsredp, xvredp, xvresp.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 35 +++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  3 +++
 target-ppc/translate.c  |  6 ++++++
 3 files changed, 44 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index c84f432..5908e41 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1904,3 +1904,38 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
 VSX_DIV(xsdivdp, 1, float64, f64, 1)
 VSX_DIV(xvdivdp, 2, float64, f64, 0)
 VSX_DIV(xvdivsp, 4, float32, f32, 0)
+
+/* VSX_RE  - VSX floating point reciprocal estimate
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   sfprf - set FPRF
+ */
+#define VSX_RE(op, nels, tp, fld, sfprf)                                      \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
+{                                                                             \
+    ppc_vsr_t xt, xb;                                                         \
+    int i;                                                                    \
+                                                                              \
+    getVSR(xB(opcode), &xb, env);                                             \
+    getVSR(xT(opcode), &xt, env);                                             \
+    helper_reset_fpstatus(env);                                               \
+                                                                              \
+    for (i = 0; i < nels; i++) {                                              \
+        if (unlikely(tp##_is_signaling_nan(xb.fld[i]))) {                     \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);    \
+        }                                                                     \
+        xt.fld[i] = tp##_div(tp##_one, xb.fld[i], &env->fp_status);           \
+        if (sfprf) {                                                          \
+            helper_compute_fprf(env, xt.fld[0], sfprf);                       \
+        }                                                                     \
+    }                                                                         \
+                                                                              \
+    putVSR(xT(opcode), &xt, env);                                             \
+    helper_float_check_status(env);                                           \
+}
+
+VSX_RE(xsredp, 1, float64, f64, 1)
+VSX_RE(xvredp, 2, float64, f64, 0)
+VSX_RE(xvresp, 4, float32, f32, 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 6ede7ea..fe5b61c 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -255,16 +255,19 @@ DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
 DEF_HELPER_2(xsmuldp, void, env, i32)
 DEF_HELPER_2(xsdivdp, void, env, i32)
+DEF_HELPER_2(xsredp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
 DEF_HELPER_2(xvmuldp, void, env, i32)
 DEF_HELPER_2(xvdivdp, void, env, i32)
+DEF_HELPER_2(xvredp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
 DEF_HELPER_2(xvmulsp, void, env, i32)
 DEF_HELPER_2(xvdivsp, void, env, i32)
+DEF_HELPER_2(xvresp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 076574e..897ffd9 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7308,16 +7308,19 @@ GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10004,16 +10007,19 @@ GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX),
 GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX),
 GEN_XX3FORM(xsmuldp, 0x00, 0x06, PPC2_VSX),
 GEN_XX3FORM(xsdivdp, 0x00, 0x07, PPC2_VSX),
+GEN_XX2FORM(xsredp,  0x14, 0x05, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
 GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX),
 GEN_XX3FORM(xvdivdp, 0x00, 0x0F, PPC2_VSX),
+GEN_XX2FORM(xvredp,  0x14, 0x0D, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
 GEN_XX3FORM(xvmulsp, 0x00, 0x0A, PPC2_VSX),
 GEN_XX3FORM(xvdivsp, 0x00, 0x0B, PPC2_VSX),
+GEN_XX2FORM(xvresp, 0x14, 0x09, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 023/130] target-ppc: Add VSX ISA2.06 xsqrt Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (21 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 022/130] target-ppc: Add VSX ISA2.06 xre Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 024/130] target-ppc: Add VSX ISA2.06 xrsqrte Instructions Alexander Graf
                   ` (107 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX floating point square root instructions
defined by V2.06 of the PowerPC ISA: xssqrtdp, xvsqrtdp, xvsqrtsp.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  3 +++
 target-ppc/translate.c  |  6 ++++++
 3 files changed, 53 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 5908e41..060e6a0 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1939,3 +1939,47 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
 VSX_RE(xsredp, 1, float64, f64, 1)
 VSX_RE(xvredp, 2, float64, f64, 0)
 VSX_RE(xvresp, 4, float32, f32, 0)
+
+/* VSX_SQRT - VSX floating point square root
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   sfprf - set FPRF
+ */
+#define VSX_SQRT(op, nels, tp, fld, sfprf)                                   \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
+{                                                                            \
+    ppc_vsr_t xt, xb;                                                        \
+    int i;                                                                   \
+                                                                             \
+    getVSR(xB(opcode), &xb, env);                                            \
+    getVSR(xT(opcode), &xt, env);                                            \
+    helper_reset_fpstatus(env);                                              \
+                                                                             \
+    for (i = 0; i < nels; i++) {                                             \
+        float_status tstat = env->fp_status;                                 \
+        set_float_exception_flags(0, &tstat);                                \
+        xt.fld[i] = tp##_sqrt(xb.fld[i], &tstat);                            \
+        env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
+                                                                             \
+        if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
+            if (tp##_is_neg(xb.fld[i]) && !tp##_is_zero(xb.fld[i])) {        \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf);   \
+            } else if (tp##_is_signaling_nan(xb.fld[i])) {                   \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);   \
+            }                                                                \
+        }                                                                    \
+                                                                             \
+        if (sfprf) {                                                         \
+            helper_compute_fprf(env, xt.fld[i], sfprf);                      \
+        }                                                                    \
+    }                                                                        \
+                                                                             \
+    putVSR(xT(opcode), &xt, env);                                            \
+    helper_float_check_status(env);                                          \
+}
+
+VSX_SQRT(xssqrtdp, 1, float64, f64, 1)
+VSX_SQRT(xvsqrtdp, 2, float64, f64, 0)
+VSX_SQRT(xvsqrtsp, 4, float32, f32, 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index fe5b61c..a6e7e62 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -256,18 +256,21 @@ DEF_HELPER_2(xssubdp, void, env, i32)
 DEF_HELPER_2(xsmuldp, void, env, i32)
 DEF_HELPER_2(xsdivdp, void, env, i32)
 DEF_HELPER_2(xsredp, void, env, i32)
+DEF_HELPER_2(xssqrtdp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
 DEF_HELPER_2(xvmuldp, void, env, i32)
 DEF_HELPER_2(xvdivdp, void, env, i32)
 DEF_HELPER_2(xvredp, void, env, i32)
+DEF_HELPER_2(xvsqrtdp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
 DEF_HELPER_2(xvmulsp, void, env, i32)
 DEF_HELPER_2(xvdivsp, void, env, i32)
 DEF_HELPER_2(xvresp, void, env, i32)
+DEF_HELPER_2(xvsqrtsp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 897ffd9..0e4b49f 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7309,18 +7309,21 @@ GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10008,18 +10011,21 @@ GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX),
 GEN_XX3FORM(xsmuldp, 0x00, 0x06, PPC2_VSX),
 GEN_XX3FORM(xsdivdp, 0x00, 0x07, PPC2_VSX),
 GEN_XX2FORM(xsredp,  0x14, 0x05, PPC2_VSX),
+GEN_XX2FORM(xssqrtdp,  0x16, 0x04, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
 GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX),
 GEN_XX3FORM(xvdivdp, 0x00, 0x0F, PPC2_VSX),
 GEN_XX2FORM(xvredp,  0x14, 0x0D, PPC2_VSX),
+GEN_XX2FORM(xvsqrtdp,  0x16, 0x0C, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
 GEN_XX3FORM(xvmulsp, 0x00, 0x0A, PPC2_VSX),
 GEN_XX3FORM(xvdivsp, 0x00, 0x0B, PPC2_VSX),
 GEN_XX2FORM(xvresp, 0x14, 0x09, PPC2_VSX),
+GEN_XX2FORM(xvsqrtsp, 0x16, 0x08, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 024/130] target-ppc: Add VSX ISA2.06 xrsqrte Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (22 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 023/130] target-ppc: Add VSX ISA2.06 xsqrt Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 025/130] target-ppc: Add VSX ISA2.06 xtdiv Instructions Alexander Graf
                   ` (106 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX floating point reciprocal square root
estimate instructions defined by V2.06 of the PowerPC ISA: xsrsqrtedp,
xvrsqrtedp, xvrsqrtesp.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  3 +++
 target-ppc/translate.c  |  6 ++++++
 3 files changed, 54 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 060e6a0..31669f1 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1983,3 +1983,48 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
 VSX_SQRT(xssqrtdp, 1, float64, f64, 1)
 VSX_SQRT(xvsqrtdp, 2, float64, f64, 0)
 VSX_SQRT(xvsqrtsp, 4, float32, f32, 0)
+
+/* VSX_RSQRTE - VSX floating point reciprocal square root estimate
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   sfprf - set FPRF
+ */
+#define VSX_RSQRTE(op, nels, tp, fld, sfprf)                                 \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
+{                                                                            \
+    ppc_vsr_t xt, xb;                                                        \
+    int i;                                                                   \
+                                                                             \
+    getVSR(xB(opcode), &xb, env);                                            \
+    getVSR(xT(opcode), &xt, env);                                            \
+    helper_reset_fpstatus(env);                                              \
+                                                                             \
+    for (i = 0; i < nels; i++) {                                             \
+        float_status tstat = env->fp_status;                                 \
+        set_float_exception_flags(0, &tstat);                                \
+        xt.fld[i] = tp##_sqrt(xb.fld[i], &tstat);                            \
+        xt.fld[i] = tp##_div(tp##_one, xt.fld[i], &tstat);                   \
+        env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
+                                                                             \
+        if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
+            if (tp##_is_neg(xb.fld[i]) && !tp##_is_zero(xb.fld[i])) {        \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf);   \
+            } else if (tp##_is_signaling_nan(xb.fld[i])) {                   \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);   \
+            }                                                                \
+        }                                                                    \
+                                                                             \
+        if (sfprf) {                                                         \
+            helper_compute_fprf(env, xt.fld[i], sfprf);                      \
+        }                                                                    \
+    }                                                                        \
+                                                                             \
+    putVSR(xT(opcode), &xt, env);                                            \
+    helper_float_check_status(env);                                          \
+}
+
+VSX_RSQRTE(xsrsqrtedp, 1, float64, f64, 1)
+VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0)
+VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index a6e7e62..4d5e31b 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -257,6 +257,7 @@ DEF_HELPER_2(xsmuldp, void, env, i32)
 DEF_HELPER_2(xsdivdp, void, env, i32)
 DEF_HELPER_2(xsredp, void, env, i32)
 DEF_HELPER_2(xssqrtdp, void, env, i32)
+DEF_HELPER_2(xsrsqrtedp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
@@ -264,6 +265,7 @@ DEF_HELPER_2(xvmuldp, void, env, i32)
 DEF_HELPER_2(xvdivdp, void, env, i32)
 DEF_HELPER_2(xvredp, void, env, i32)
 DEF_HELPER_2(xvsqrtdp, void, env, i32)
+DEF_HELPER_2(xvrsqrtedp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
@@ -271,6 +273,7 @@ DEF_HELPER_2(xvmulsp, void, env, i32)
 DEF_HELPER_2(xvdivsp, void, env, i32)
 DEF_HELPER_2(xvresp, void, env, i32)
 DEF_HELPER_2(xvsqrtsp, void, env, i32)
+DEF_HELPER_2(xvrsqrtesp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 0e4b49f..bd6c9a0 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7310,6 +7310,7 @@ GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -7317,6 +7318,7 @@ GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
@@ -7324,6 +7326,7 @@ GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10012,6 +10015,7 @@ GEN_XX3FORM(xsmuldp, 0x00, 0x06, PPC2_VSX),
 GEN_XX3FORM(xsdivdp, 0x00, 0x07, PPC2_VSX),
 GEN_XX2FORM(xsredp,  0x14, 0x05, PPC2_VSX),
 GEN_XX2FORM(xssqrtdp,  0x16, 0x04, PPC2_VSX),
+GEN_XX2FORM(xsrsqrtedp,  0x14, 0x04, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
@@ -10019,6 +10023,7 @@ GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX),
 GEN_XX3FORM(xvdivdp, 0x00, 0x0F, PPC2_VSX),
 GEN_XX2FORM(xvredp,  0x14, 0x0D, PPC2_VSX),
 GEN_XX2FORM(xvsqrtdp,  0x16, 0x0C, PPC2_VSX),
+GEN_XX2FORM(xvrsqrtedp,  0x14, 0x0C, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
@@ -10026,6 +10031,7 @@ GEN_XX3FORM(xvmulsp, 0x00, 0x0A, PPC2_VSX),
 GEN_XX3FORM(xvdivsp, 0x00, 0x0B, PPC2_VSX),
 GEN_XX2FORM(xvresp, 0x14, 0x09, PPC2_VSX),
 GEN_XX2FORM(xvsqrtsp, 0x16, 0x08, PPC2_VSX),
+GEN_XX2FORM(xvrsqrtesp, 0x14, 0x08, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 025/130] target-ppc: Add VSX ISA2.06 xtdiv Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (23 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 024/130] target-ppc: Add VSX ISA2.06 xrsqrte Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 026/130] target-ppc: Add VSX ISA2.06 xtsqrt Instructions Alexander Graf
                   ` (105 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX floating point test for software divide
instructions defined by V2.06 of the PowerPC ISA: xstdivdp, xvtdivdp,
and xvtdivsp.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  3 +++
 target-ppc/translate.c  |  6 +++++
 3 files changed, 76 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 31669f1..ee03942 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2028,3 +2028,70 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
 VSX_RSQRTE(xsrsqrtedp, 1, float64, f64, 1)
 VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0)
 VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0)
+
+static inline int ppc_float32_get_unbiased_exp(float32 f)
+{
+    return ((f >> 23) & 0xFF) - 127;
+}
+
+static inline int ppc_float64_get_unbiased_exp(float64 f)
+{
+    return ((f >> 52) & 0x7FF) - 1023;
+}
+
+/* VSX_TDIV - VSX floating point test for divide
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   emin  - minimum unbiased exponent
+ *   emax  - maximum unbiased exponent
+ *   nbits - number of fraction bits
+ */
+#define VSX_TDIV(op, nels, tp, fld, emin, emax, nbits)                  \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                     \
+{                                                                       \
+    ppc_vsr_t xa, xb;                                                   \
+    int i;                                                              \
+    int fe_flag = 0;                                                    \
+    int fg_flag = 0;                                                    \
+                                                                        \
+    getVSR(xA(opcode), &xa, env);                                       \
+    getVSR(xB(opcode), &xb, env);                                       \
+                                                                        \
+    for (i = 0; i < nels; i++) {                                        \
+        if (unlikely(tp##_is_infinity(xa.fld[i]) ||                     \
+                     tp##_is_infinity(xb.fld[i]) ||                     \
+                     tp##_is_zero(xb.fld[i]))) {                        \
+            fe_flag = 1;                                                \
+            fg_flag = 1;                                                \
+        } else {                                                        \
+            int e_a = ppc_##tp##_get_unbiased_exp(xa.fld[i]);           \
+            int e_b = ppc_##tp##_get_unbiased_exp(xb.fld[i]);           \
+                                                                        \
+            if (unlikely(tp##_is_any_nan(xa.fld[i]) ||                  \
+                         tp##_is_any_nan(xb.fld[i]))) {                 \
+                fe_flag = 1;                                            \
+            } else if ((e_b <= emin) || (e_b >= (emax-2))) {            \
+                fe_flag = 1;                                            \
+            } else if (!tp##_is_zero(xa.fld[i]) &&                      \
+                       (((e_a - e_b) >= emax) ||                        \
+                        ((e_a - e_b) <= (emin+1)) ||                    \
+                         (e_a <= (emin+nbits)))) {                      \
+                fe_flag = 1;                                            \
+            }                                                           \
+                                                                        \
+            if (unlikely(tp##_is_zero_or_denormal(xb.fld[i]))) {        \
+                /* XB is not zero because of the above check and */     \
+                /* so must be denormalized.                      */     \
+                fg_flag = 1;                                            \
+            }                                                           \
+        }                                                               \
+    }                                                                   \
+                                                                        \
+    env->crf[BF(opcode)] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); \
+}
+
+VSX_TDIV(xstdivdp, 1, float64, f64, -1022, 1023, 52)
+VSX_TDIV(xvtdivdp, 2, float64, f64, -1022, 1023, 52)
+VSX_TDIV(xvtdivsp, 4, float32, f32, -126, 127, 23)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 4d5e31b..80cffc9 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -258,6 +258,7 @@ DEF_HELPER_2(xsdivdp, void, env, i32)
 DEF_HELPER_2(xsredp, void, env, i32)
 DEF_HELPER_2(xssqrtdp, void, env, i32)
 DEF_HELPER_2(xsrsqrtedp, void, env, i32)
+DEF_HELPER_2(xstdivdp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
@@ -266,6 +267,7 @@ DEF_HELPER_2(xvdivdp, void, env, i32)
 DEF_HELPER_2(xvredp, void, env, i32)
 DEF_HELPER_2(xvsqrtdp, void, env, i32)
 DEF_HELPER_2(xvrsqrtedp, void, env, i32)
+DEF_HELPER_2(xvtdivdp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
@@ -274,6 +276,7 @@ DEF_HELPER_2(xvdivsp, void, env, i32)
 DEF_HELPER_2(xvresp, void, env, i32)
 DEF_HELPER_2(xvsqrtsp, void, env, i32)
 DEF_HELPER_2(xvrsqrtesp, void, env, i32)
+DEF_HELPER_2(xvtdivsp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index bd6c9a0..ded5f19 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7311,6 +7311,7 @@ GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xstdivdp, 0x14, 0x07, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -7319,6 +7320,7 @@ GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvtdivdp, 0x14, 0x0F, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
@@ -7327,6 +7329,7 @@ GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvtdivsp, 0x14, 0x0B, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10016,6 +10019,7 @@ GEN_XX3FORM(xsdivdp, 0x00, 0x07, PPC2_VSX),
 GEN_XX2FORM(xsredp,  0x14, 0x05, PPC2_VSX),
 GEN_XX2FORM(xssqrtdp,  0x16, 0x04, PPC2_VSX),
 GEN_XX2FORM(xsrsqrtedp,  0x14, 0x04, PPC2_VSX),
+GEN_XX3FORM(xstdivdp,  0x14, 0x07, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
@@ -10024,6 +10028,7 @@ GEN_XX3FORM(xvdivdp, 0x00, 0x0F, PPC2_VSX),
 GEN_XX2FORM(xvredp,  0x14, 0x0D, PPC2_VSX),
 GEN_XX2FORM(xvsqrtdp,  0x16, 0x0C, PPC2_VSX),
 GEN_XX2FORM(xvrsqrtedp,  0x14, 0x0C, PPC2_VSX),
+GEN_XX3FORM(xvtdivdp, 0x14, 0x0F, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
@@ -10032,6 +10037,7 @@ GEN_XX3FORM(xvdivsp, 0x00, 0x0B, PPC2_VSX),
 GEN_XX2FORM(xvresp, 0x14, 0x09, PPC2_VSX),
 GEN_XX2FORM(xvsqrtsp, 0x16, 0x08, PPC2_VSX),
 GEN_XX2FORM(xvrsqrtesp, 0x14, 0x08, PPC2_VSX),
+GEN_XX3FORM(xvtdivsp, 0x14, 0x0B, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 026/130] target-ppc: Add VSX ISA2.06 xtsqrt Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (24 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 025/130] target-ppc: Add VSX ISA2.06 xtdiv Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 027/130] target-ppc: Add VSX ISA2.06 Multiply Add Instructions Alexander Graf
                   ` (104 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX floating point test for software square
root instructions defined by V2.06 of the PowerPC ISA: xstsqrtdp,
xvtsqrtdp, xvtsqrtsp.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  3 +++
 target-ppc/translate.c  |  6 ++++++
 3 files changed, 63 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index ee03942..73227b7 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2095,3 +2095,57 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                     \
 VSX_TDIV(xstdivdp, 1, float64, f64, -1022, 1023, 52)
 VSX_TDIV(xvtdivdp, 2, float64, f64, -1022, 1023, 52)
 VSX_TDIV(xvtdivsp, 4, float32, f32, -126, 127, 23)
+
+/* VSX_TSQRT - VSX floating point test for square root
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   emin  - minimum unbiased exponent
+ *   emax  - maximum unbiased exponent
+ *   nbits - number of fraction bits
+ */
+#define VSX_TSQRT(op, nels, tp, fld, emin, nbits)                       \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                     \
+{                                                                       \
+    ppc_vsr_t xa, xb;                                                   \
+    int i;                                                              \
+    int fe_flag = 0;                                                    \
+    int fg_flag = 0;                                                    \
+                                                                        \
+    getVSR(xA(opcode), &xa, env);                                       \
+    getVSR(xB(opcode), &xb, env);                                       \
+                                                                        \
+    for (i = 0; i < nels; i++) {                                        \
+        if (unlikely(tp##_is_infinity(xb.fld[i]) ||                     \
+                     tp##_is_zero(xb.fld[i]))) {                        \
+            fe_flag = 1;                                                \
+            fg_flag = 1;                                                \
+        } else {                                                        \
+            int e_b = ppc_##tp##_get_unbiased_exp(xb.fld[i]);           \
+                                                                        \
+            if (unlikely(tp##_is_any_nan(xb.fld[i]))) {                 \
+                fe_flag = 1;                                            \
+            } else if (unlikely(tp##_is_zero(xb.fld[i]))) {             \
+                fe_flag = 1;                                            \
+            } else if (unlikely(tp##_is_neg(xb.fld[i]))) {              \
+                fe_flag = 1;                                            \
+            } else if (!tp##_is_zero(xb.fld[i]) &&                      \
+                      (e_b <= (emin+nbits))) {                          \
+                fe_flag = 1;                                            \
+            }                                                           \
+                                                                        \
+            if (unlikely(tp##_is_zero_or_denormal(xb.fld[i]))) {        \
+                /* XB is not zero because of the above check and */     \
+                /* therefore must be denormalized.               */     \
+                fg_flag = 1;                                            \
+            }                                                           \
+        }                                                               \
+    }                                                                   \
+                                                                        \
+    env->crf[BF(opcode)] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); \
+}
+
+VSX_TSQRT(xstsqrtdp, 1, float64, f64, -1022, 52)
+VSX_TSQRT(xvtsqrtdp, 2, float64, f64, -1022, 52)
+VSX_TSQRT(xvtsqrtsp, 4, float32, f32, -126, 23)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 80cffc9..c413c98 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -259,6 +259,7 @@ DEF_HELPER_2(xsredp, void, env, i32)
 DEF_HELPER_2(xssqrtdp, void, env, i32)
 DEF_HELPER_2(xsrsqrtedp, void, env, i32)
 DEF_HELPER_2(xstdivdp, void, env, i32)
+DEF_HELPER_2(xstsqrtdp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
@@ -268,6 +269,7 @@ DEF_HELPER_2(xvredp, void, env, i32)
 DEF_HELPER_2(xvsqrtdp, void, env, i32)
 DEF_HELPER_2(xvrsqrtedp, void, env, i32)
 DEF_HELPER_2(xvtdivdp, void, env, i32)
+DEF_HELPER_2(xvtsqrtdp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
@@ -277,6 +279,7 @@ DEF_HELPER_2(xvresp, void, env, i32)
 DEF_HELPER_2(xvsqrtsp, void, env, i32)
 DEF_HELPER_2(xvrsqrtesp, void, env, i32)
 DEF_HELPER_2(xvtdivsp, void, env, i32)
+DEF_HELPER_2(xvtsqrtsp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ded5f19..4898005 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7312,6 +7312,7 @@ GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xstdivdp, 0x14, 0x07, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xstsqrtdp, 0x14, 0x06, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -7321,6 +7322,7 @@ GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvtdivdp, 0x14, 0x0F, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvtsqrtdp, 0x14, 0x0E, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
@@ -7330,6 +7332,7 @@ GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvtdivsp, 0x14, 0x0B, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvtsqrtsp, 0x14, 0x0A, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10020,6 +10023,7 @@ GEN_XX2FORM(xsredp,  0x14, 0x05, PPC2_VSX),
 GEN_XX2FORM(xssqrtdp,  0x16, 0x04, PPC2_VSX),
 GEN_XX2FORM(xsrsqrtedp,  0x14, 0x04, PPC2_VSX),
 GEN_XX3FORM(xstdivdp,  0x14, 0x07, PPC2_VSX),
+GEN_XX2FORM(xstsqrtdp,  0x14, 0x06, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
@@ -10029,6 +10033,7 @@ GEN_XX2FORM(xvredp,  0x14, 0x0D, PPC2_VSX),
 GEN_XX2FORM(xvsqrtdp,  0x16, 0x0C, PPC2_VSX),
 GEN_XX2FORM(xvrsqrtedp,  0x14, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvtdivdp, 0x14, 0x0F, PPC2_VSX),
+GEN_XX2FORM(xvtsqrtdp, 0x14, 0x0E, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
@@ -10038,6 +10043,7 @@ GEN_XX2FORM(xvresp, 0x14, 0x09, PPC2_VSX),
 GEN_XX2FORM(xvsqrtsp, 0x16, 0x08, PPC2_VSX),
 GEN_XX2FORM(xvrsqrtesp, 0x14, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvtdivsp, 0x14, 0x0B, PPC2_VSX),
+GEN_XX2FORM(xvtsqrtsp, 0x14, 0x0A, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 027/130] target-ppc: Add VSX ISA2.06 Multiply Add Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (25 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 026/130] target-ppc: Add VSX ISA2.06 xtsqrt Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 028/130] target-ppc: Add VSX xscmp*dp Instructions Alexander Graf
                   ` (103 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX floating point multiply/add instructions
defined by V2.06 of the PowerPC ISA:

  - xsmaddadp,  xvmaddadp,  xvmaddasp
  - xsmaddmdp,  xvmaddmdp,  xvmaddmsp
  - xsmsubadp,  xvmsubadp,  xvmsubasp
  - xsmsubmdp,  xvmsubmdp,  xvmsubmsp
  - xsnmaddadp, xvnmaddadp, xvnmaddasp
  - xsnmaddmdp, xvnmaddmdp, xvnmaddmsp
  - xsnmsubadp, xvnmsubadp, xvnmsubasp
  - xsnmsubmdp, xvnmsubmdp, xvnmsubmsp

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  24 ++++++++++++
 target-ppc/translate.c  |  48 +++++++++++++++++++++++
 3 files changed, 172 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 73227b7..54c47c8 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2149,3 +2149,103 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                     \
 VSX_TSQRT(xstsqrtdp, 1, float64, f64, -1022, 52)
 VSX_TSQRT(xvtsqrtdp, 2, float64, f64, -1022, 52)
 VSX_TSQRT(xvtsqrtsp, 4, float32, f32, -126, 23)
+
+/* VSX_MADD - VSX floating point muliply/add variations
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   maddflgs - flags for the float*muladd routine that control the
+ *           various forms (madd, msub, nmadd, nmsub)
+ *   afrm  - A form (1=A, 0=M)
+ *   sfprf - set FPRF
+ */
+#define VSX_MADD(op, nels, tp, fld, maddflgs, afrm, sfprf)                    \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
+{                                                                             \
+    ppc_vsr_t xt_in, xa, xb, xt_out;                                          \
+    ppc_vsr_t *b, *c;                                                         \
+    int i;                                                                    \
+                                                                              \
+    if (afrm) { /* AxB + T */                                                 \
+        b = &xb;                                                              \
+        c = &xt_in;                                                           \
+    } else { /* AxT + B */                                                    \
+        b = &xt_in;                                                           \
+        c = &xb;                                                              \
+    }                                                                         \
+                                                                              \
+    getVSR(xA(opcode), &xa, env);                                             \
+    getVSR(xB(opcode), &xb, env);                                             \
+    getVSR(xT(opcode), &xt_in, env);                                          \
+                                                                              \
+    xt_out = xt_in;                                                           \
+                                                                              \
+    helper_reset_fpstatus(env);                                               \
+                                                                              \
+    for (i = 0; i < nels; i++) {                                              \
+        float_status tstat = env->fp_status;                                  \
+        set_float_exception_flags(0, &tstat);                                 \
+        xt_out.fld[i] = tp##_muladd(xa.fld[i], b->fld[i], c->fld[i],          \
+                                     maddflgs, &tstat);                       \
+        env->fp_status.float_exception_flags |= tstat.float_exception_flags;  \
+                                                                              \
+        if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {     \
+            if (tp##_is_signaling_nan(xa.fld[i]) ||                           \
+                tp##_is_signaling_nan(b->fld[i]) ||                           \
+                tp##_is_signaling_nan(c->fld[i])) {                           \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);    \
+                tstat.float_exception_flags &= ~float_flag_invalid;           \
+            }                                                                 \
+            if ((tp##_is_infinity(xa.fld[i]) && tp##_is_zero(b->fld[i])) ||   \
+                (tp##_is_zero(xa.fld[i]) && tp##_is_infinity(b->fld[i]))) {   \
+                xt_out.fld[i] = float64_to_##tp(fload_invalid_op_excp(env,    \
+                    POWERPC_EXCP_FP_VXIMZ, sfprf), &env->fp_status);          \
+                tstat.float_exception_flags &= ~float_flag_invalid;           \
+            }                                                                 \
+            if ((tstat.float_exception_flags & float_flag_invalid) &&         \
+                ((tp##_is_infinity(xa.fld[i]) ||                              \
+                  tp##_is_infinity(b->fld[i])) &&                             \
+                  tp##_is_infinity(c->fld[i]))) {                             \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf);     \
+            }                                                                 \
+        }                                                                     \
+        if (sfprf) {                                                          \
+            helper_compute_fprf(env, xt_out.fld[i], sfprf);                   \
+        }                                                                     \
+    }                                                                         \
+    putVSR(xT(opcode), &xt_out, env);                                         \
+    helper_float_check_status(env);                                           \
+}
+
+#define MADD_FLGS 0
+#define MSUB_FLGS float_muladd_negate_c
+#define NMADD_FLGS float_muladd_negate_result
+#define NMSUB_FLGS (float_muladd_negate_c | float_muladd_negate_result)
+
+VSX_MADD(xsmaddadp, 1, float64, f64, MADD_FLGS, 1, 1)
+VSX_MADD(xsmaddmdp, 1, float64, f64, MADD_FLGS, 0, 1)
+VSX_MADD(xsmsubadp, 1, float64, f64, MSUB_FLGS, 1, 1)
+VSX_MADD(xsmsubmdp, 1, float64, f64, MSUB_FLGS, 0, 1)
+VSX_MADD(xsnmaddadp, 1, float64, f64, NMADD_FLGS, 1, 1)
+VSX_MADD(xsnmaddmdp, 1, float64, f64, NMADD_FLGS, 0, 1)
+VSX_MADD(xsnmsubadp, 1, float64, f64, NMSUB_FLGS, 1, 1)
+VSX_MADD(xsnmsubmdp, 1, float64, f64, NMSUB_FLGS, 0, 1)
+
+VSX_MADD(xvmaddadp, 2, float64, f64, MADD_FLGS, 1, 0)
+VSX_MADD(xvmaddmdp, 2, float64, f64, MADD_FLGS, 0, 0)
+VSX_MADD(xvmsubadp, 2, float64, f64, MSUB_FLGS, 1, 0)
+VSX_MADD(xvmsubmdp, 2, float64, f64, MSUB_FLGS, 0, 0)
+VSX_MADD(xvnmaddadp, 2, float64, f64, NMADD_FLGS, 1, 0)
+VSX_MADD(xvnmaddmdp, 2, float64, f64, NMADD_FLGS, 0, 0)
+VSX_MADD(xvnmsubadp, 2, float64, f64, NMSUB_FLGS, 1, 0)
+VSX_MADD(xvnmsubmdp, 2, float64, f64, NMSUB_FLGS, 0, 0)
+
+VSX_MADD(xvmaddasp, 4, float32, f32, MADD_FLGS, 1, 0)
+VSX_MADD(xvmaddmsp, 4, float32, f32, MADD_FLGS, 0, 0)
+VSX_MADD(xvmsubasp, 4, float32, f32, MSUB_FLGS, 1, 0)
+VSX_MADD(xvmsubmsp, 4, float32, f32, MSUB_FLGS, 0, 0)
+VSX_MADD(xvnmaddasp, 4, float32, f32, NMADD_FLGS, 1, 0)
+VSX_MADD(xvnmaddmsp, 4, float32, f32, NMADD_FLGS, 0, 0)
+VSX_MADD(xvnmsubasp, 4, float32, f32, NMSUB_FLGS, 1, 0)
+VSX_MADD(xvnmsubmsp, 4, float32, f32, NMSUB_FLGS, 0, 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index c413c98..7368908 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -260,6 +260,14 @@ DEF_HELPER_2(xssqrtdp, void, env, i32)
 DEF_HELPER_2(xsrsqrtedp, void, env, i32)
 DEF_HELPER_2(xstdivdp, void, env, i32)
 DEF_HELPER_2(xstsqrtdp, void, env, i32)
+DEF_HELPER_2(xsmaddadp, void, env, i32)
+DEF_HELPER_2(xsmaddmdp, void, env, i32)
+DEF_HELPER_2(xsmsubadp, void, env, i32)
+DEF_HELPER_2(xsmsubmdp, void, env, i32)
+DEF_HELPER_2(xsnmaddadp, void, env, i32)
+DEF_HELPER_2(xsnmaddmdp, void, env, i32)
+DEF_HELPER_2(xsnmsubadp, void, env, i32)
+DEF_HELPER_2(xsnmsubmdp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
@@ -270,6 +278,14 @@ DEF_HELPER_2(xvsqrtdp, void, env, i32)
 DEF_HELPER_2(xvrsqrtedp, void, env, i32)
 DEF_HELPER_2(xvtdivdp, void, env, i32)
 DEF_HELPER_2(xvtsqrtdp, void, env, i32)
+DEF_HELPER_2(xvmaddadp, void, env, i32)
+DEF_HELPER_2(xvmaddmdp, void, env, i32)
+DEF_HELPER_2(xvmsubadp, void, env, i32)
+DEF_HELPER_2(xvmsubmdp, void, env, i32)
+DEF_HELPER_2(xvnmaddadp, void, env, i32)
+DEF_HELPER_2(xvnmaddmdp, void, env, i32)
+DEF_HELPER_2(xvnmsubadp, void, env, i32)
+DEF_HELPER_2(xvnmsubmdp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
@@ -280,6 +296,14 @@ DEF_HELPER_2(xvsqrtsp, void, env, i32)
 DEF_HELPER_2(xvrsqrtesp, void, env, i32)
 DEF_HELPER_2(xvtdivsp, void, env, i32)
 DEF_HELPER_2(xvtsqrtsp, void, env, i32)
+DEF_HELPER_2(xvmaddasp, void, env, i32)
+DEF_HELPER_2(xvmaddmsp, void, env, i32)
+DEF_HELPER_2(xvmsubasp, void, env, i32)
+DEF_HELPER_2(xvmsubmsp, void, env, i32)
+DEF_HELPER_2(xvnmaddasp, void, env, i32)
+DEF_HELPER_2(xvnmaddmsp, void, env, i32)
+DEF_HELPER_2(xvnmsubasp, void, env, i32)
+DEF_HELPER_2(xvnmsubmsp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 4898005..9e13ed7 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7313,6 +7313,14 @@ GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xstdivdp, 0x14, 0x07, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xstsqrtdp, 0x14, 0x06, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsmaddadp, 0x04, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsmaddmdp, 0x04, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsmsubadp, 0x04, 0x06, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsmsubmdp, 0x04, 0x07, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsnmaddadp, 0x04, 0x14, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsnmaddmdp, 0x04, 0x15, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsnmsubadp, 0x04, 0x16, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsnmsubmdp, 0x04, 0x17, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -7323,6 +7331,14 @@ GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvtdivdp, 0x14, 0x0F, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvtsqrtdp, 0x14, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmaddadp, 0x04, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmaddmdp, 0x04, 0x0D, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmsubadp, 0x04, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmsubmdp, 0x04, 0x0F, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvnmaddadp, 0x04, 0x1C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvnmaddmdp, 0x04, 0x1D, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvnmsubadp, 0x04, 0x1E, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvnmsubmdp, 0x04, 0x1F, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
@@ -7333,6 +7349,14 @@ GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvtdivsp, 0x14, 0x0B, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvtsqrtsp, 0x14, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmaddasp, 0x04, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmaddmsp, 0x04, 0x09, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmsubasp, 0x04, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmsubmsp, 0x04, 0x0B, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvnmaddasp, 0x04, 0x18, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvnmaddmsp, 0x04, 0x19, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvnmsubasp, 0x04, 0x1A, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvnmsubmsp, 0x04, 0x1B, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10024,6 +10048,14 @@ GEN_XX2FORM(xssqrtdp,  0x16, 0x04, PPC2_VSX),
 GEN_XX2FORM(xsrsqrtedp,  0x14, 0x04, PPC2_VSX),
 GEN_XX3FORM(xstdivdp,  0x14, 0x07, PPC2_VSX),
 GEN_XX2FORM(xstsqrtdp,  0x14, 0x06, PPC2_VSX),
+GEN_XX3FORM(xsmaddadp, 0x04, 0x04, PPC2_VSX),
+GEN_XX3FORM(xsmaddmdp, 0x04, 0x05, PPC2_VSX),
+GEN_XX3FORM(xsmsubadp, 0x04, 0x06, PPC2_VSX),
+GEN_XX3FORM(xsmsubmdp, 0x04, 0x07, PPC2_VSX),
+GEN_XX3FORM(xsnmaddadp, 0x04, 0x14, PPC2_VSX),
+GEN_XX3FORM(xsnmaddmdp, 0x04, 0x15, PPC2_VSX),
+GEN_XX3FORM(xsnmsubadp, 0x04, 0x16, PPC2_VSX),
+GEN_XX3FORM(xsnmsubmdp, 0x04, 0x17, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
@@ -10034,6 +10066,14 @@ GEN_XX2FORM(xvsqrtdp,  0x16, 0x0C, PPC2_VSX),
 GEN_XX2FORM(xvrsqrtedp,  0x14, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvtdivdp, 0x14, 0x0F, PPC2_VSX),
 GEN_XX2FORM(xvtsqrtdp, 0x14, 0x0E, PPC2_VSX),
+GEN_XX3FORM(xvmaddadp, 0x04, 0x0C, PPC2_VSX),
+GEN_XX3FORM(xvmaddmdp, 0x04, 0x0D, PPC2_VSX),
+GEN_XX3FORM(xvmsubadp, 0x04, 0x0E, PPC2_VSX),
+GEN_XX3FORM(xvmsubmdp, 0x04, 0x0F, PPC2_VSX),
+GEN_XX3FORM(xvnmaddadp, 0x04, 0x1C, PPC2_VSX),
+GEN_XX3FORM(xvnmaddmdp, 0x04, 0x1D, PPC2_VSX),
+GEN_XX3FORM(xvnmsubadp, 0x04, 0x1E, PPC2_VSX),
+GEN_XX3FORM(xvnmsubmdp, 0x04, 0x1F, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
@@ -10044,6 +10084,14 @@ GEN_XX2FORM(xvsqrtsp, 0x16, 0x08, PPC2_VSX),
 GEN_XX2FORM(xvrsqrtesp, 0x14, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvtdivsp, 0x14, 0x0B, PPC2_VSX),
 GEN_XX2FORM(xvtsqrtsp, 0x14, 0x0A, PPC2_VSX),
+GEN_XX3FORM(xvmaddasp, 0x04, 0x08, PPC2_VSX),
+GEN_XX3FORM(xvmaddmsp, 0x04, 0x09, PPC2_VSX),
+GEN_XX3FORM(xvmsubasp, 0x04, 0x0A, PPC2_VSX),
+GEN_XX3FORM(xvmsubmsp, 0x04, 0x0B, PPC2_VSX),
+GEN_XX3FORM(xvnmaddasp, 0x04, 0x18, PPC2_VSX),
+GEN_XX3FORM(xvnmaddmsp, 0x04, 0x19, PPC2_VSX),
+GEN_XX3FORM(xvnmsubasp, 0x04, 0x1A, PPC2_VSX),
+GEN_XX3FORM(xvnmsubmsp, 0x04, 0x1B, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 028/130] target-ppc: Add VSX xscmp*dp Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (26 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 027/130] target-ppc: Add VSX ISA2.06 Multiply Add Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 029/130] target-ppc: Add VSX xmax/xmin Instructions Alexander Graf
                   ` (102 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX scalar floating point compare ordered
and unordered instructions.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 39 +++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  2 ++
 target-ppc/translate.c  |  4 ++++
 3 files changed, 45 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 54c47c8..eb5d878 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2249,3 +2249,42 @@ VSX_MADD(xvnmaddasp, 4, float32, f32, NMADD_FLGS, 1, 0)
 VSX_MADD(xvnmaddmsp, 4, float32, f32, NMADD_FLGS, 0, 0)
 VSX_MADD(xvnmsubasp, 4, float32, f32, NMSUB_FLGS, 1, 0)
 VSX_MADD(xvnmsubmsp, 4, float32, f32, NMSUB_FLGS, 0, 0)
+
+#define VSX_SCALAR_CMP(op, ordered)                                      \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                      \
+{                                                                        \
+    ppc_vsr_t xa, xb;                                                    \
+    uint32_t cc = 0;                                                     \
+                                                                         \
+    getVSR(xA(opcode), &xa, env);                                        \
+    getVSR(xB(opcode), &xb, env);                                        \
+                                                                         \
+    if (unlikely(float64_is_any_nan(xa.f64[0]) ||                        \
+                 float64_is_any_nan(xb.f64[0]))) {                       \
+        if (float64_is_signaling_nan(xa.f64[0]) ||                       \
+            float64_is_signaling_nan(xb.f64[0])) {                       \
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);       \
+        }                                                                \
+        if (ordered) {                                                   \
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0);         \
+        }                                                                \
+        cc = 1;                                                          \
+    } else {                                                             \
+        if (float64_lt(xa.f64[0], xb.f64[0], &env->fp_status)) {         \
+            cc = 8;                                                      \
+        } else if (!float64_le(xa.f64[0], xb.f64[0], &env->fp_status)) { \
+            cc = 4;                                                      \
+        } else {                                                         \
+            cc = 2;                                                      \
+        }                                                                \
+    }                                                                    \
+                                                                         \
+    env->fpscr &= ~(0x0F << FPSCR_FPRF);                                 \
+    env->fpscr |= cc << FPSCR_FPRF;                                      \
+    env->crf[BF(opcode)] = cc;                                           \
+                                                                         \
+    helper_float_check_status(env);                                      \
+}
+
+VSX_SCALAR_CMP(xscmpodp, 1)
+VSX_SCALAR_CMP(xscmpudp, 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 7368908..cd72388 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -268,6 +268,8 @@ DEF_HELPER_2(xsnmaddadp, void, env, i32)
 DEF_HELPER_2(xsnmaddmdp, void, env, i32)
 DEF_HELPER_2(xsnmsubadp, void, env, i32)
 DEF_HELPER_2(xsnmsubmdp, void, env, i32)
+DEF_HELPER_2(xscmpodp, void, env, i32)
+DEF_HELPER_2(xscmpudp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 9e13ed7..1685678 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7321,6 +7321,8 @@ GEN_VSX_HELPER_2(xsnmaddadp, 0x04, 0x14, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsnmaddmdp, 0x04, 0x15, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsnmsubadp, 0x04, 0x16, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsnmsubmdp, 0x04, 0x17, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -10056,6 +10058,8 @@ GEN_XX3FORM(xsnmaddadp, 0x04, 0x14, PPC2_VSX),
 GEN_XX3FORM(xsnmaddmdp, 0x04, 0x15, PPC2_VSX),
 GEN_XX3FORM(xsnmsubadp, 0x04, 0x16, PPC2_VSX),
 GEN_XX3FORM(xsnmsubmdp, 0x04, 0x17, PPC2_VSX),
+GEN_XX2FORM(xscmpodp,  0x0C, 0x05, PPC2_VSX),
+GEN_XX2FORM(xscmpudp,  0x0C, 0x04, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 029/130] target-ppc: Add VSX xmax/xmin Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (27 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 028/130] target-ppc: Add VSX xscmp*dp Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 030/130] target-ppc: Add VSX Vector Compare Instructions Alexander Graf
                   ` (101 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX floating point maximum and minimum
instructions:

  - xsmaxdp, xvmaxdp, xvmaxsp
  - xsmindp, xvmindp, xvminsp

Because of the Power ISA definitions of maximum and minimum
on various boundary cases, the standard softfloat comparison
routines (e.g. float64_lt) do not work as well as one might
think.  Therefore specific routines for comparing 64 and 32
bit floating point numbers are implemented in the PowerPC
helper code.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 39 +++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  6 ++++++
 target-ppc/translate.c  | 12 ++++++++++++
 3 files changed, 57 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index eb5d878..8ece966 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2288,3 +2288,42 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                      \
 
 VSX_SCALAR_CMP(xscmpodp, 1)
 VSX_SCALAR_CMP(xscmpudp, 0)
+
+#define float64_snan_to_qnan(x) ((x) | 0x0008000000000000ul)
+#define float32_snan_to_qnan(x) ((x) | 0x00400000)
+
+/* VSX_MAX_MIN - VSX floating point maximum/minimum
+ *   name  - instruction mnemonic
+ *   op    - operation (max or min)
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ */
+#define VSX_MAX_MIN(name, op, nels, tp, fld)                                  \
+void helper_##name(CPUPPCState *env, uint32_t opcode)                         \
+{                                                                             \
+    ppc_vsr_t xt, xa, xb;                                                     \
+    int i;                                                                    \
+                                                                              \
+    getVSR(xA(opcode), &xa, env);                                             \
+    getVSR(xB(opcode), &xb, env);                                             \
+    getVSR(xT(opcode), &xt, env);                                             \
+                                                                              \
+    for (i = 0; i < nels; i++) {                                              \
+        xt.fld[i] = tp##_##op(xa.fld[i], xb.fld[i], &env->fp_status);         \
+        if (unlikely(tp##_is_signaling_nan(xa.fld[i]) ||                      \
+                     tp##_is_signaling_nan(xb.fld[i]))) {                     \
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);            \
+        }                                                                     \
+    }                                                                         \
+                                                                              \
+    putVSR(xT(opcode), &xt, env);                                             \
+    helper_float_check_status(env);                                           \
+}
+
+VSX_MAX_MIN(xsmaxdp, maxnum, 1, float64, f64)
+VSX_MAX_MIN(xvmaxdp, maxnum, 2, float64, f64)
+VSX_MAX_MIN(xvmaxsp, maxnum, 4, float32, f32)
+VSX_MAX_MIN(xsmindp, minnum, 1, float64, f64)
+VSX_MAX_MIN(xvmindp, minnum, 2, float64, f64)
+VSX_MAX_MIN(xvminsp, minnum, 4, float32, f32)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index cd72388..4a65d39 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -270,6 +270,8 @@ DEF_HELPER_2(xsnmsubadp, void, env, i32)
 DEF_HELPER_2(xsnmsubmdp, void, env, i32)
 DEF_HELPER_2(xscmpodp, void, env, i32)
 DEF_HELPER_2(xscmpudp, void, env, i32)
+DEF_HELPER_2(xsmaxdp, void, env, i32)
+DEF_HELPER_2(xsmindp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
@@ -288,6 +290,8 @@ DEF_HELPER_2(xvnmaddadp, void, env, i32)
 DEF_HELPER_2(xvnmaddmdp, void, env, i32)
 DEF_HELPER_2(xvnmsubadp, void, env, i32)
 DEF_HELPER_2(xvnmsubmdp, void, env, i32)
+DEF_HELPER_2(xvmaxdp, void, env, i32)
+DEF_HELPER_2(xvmindp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
@@ -306,6 +310,8 @@ DEF_HELPER_2(xvnmaddasp, void, env, i32)
 DEF_HELPER_2(xvnmaddmsp, void, env, i32)
 DEF_HELPER_2(xvnmsubasp, void, env, i32)
 DEF_HELPER_2(xvnmsubmsp, void, env, i32)
+DEF_HELPER_2(xvmaxsp, void, env, i32)
+DEF_HELPER_2(xvminsp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 1685678..cb68dcd 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7323,6 +7323,8 @@ GEN_VSX_HELPER_2(xsnmsubadp, 0x04, 0x16, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsnmsubmdp, 0x04, 0x17, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -7341,6 +7343,8 @@ GEN_VSX_HELPER_2(xvnmaddadp, 0x04, 0x1C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvnmaddmdp, 0x04, 0x1D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvnmsubadp, 0x04, 0x1E, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvnmsubmdp, 0x04, 0x1F, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmaxdp, 0x00, 0x1C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmindp, 0x00, 0x1D, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
@@ -7359,6 +7363,8 @@ GEN_VSX_HELPER_2(xvnmaddasp, 0x04, 0x18, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvnmaddmsp, 0x04, 0x19, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvnmsubasp, 0x04, 0x1A, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvnmsubmsp, 0x04, 0x1B, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvmaxsp, 0x00, 0x18, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvminsp, 0x00, 0x19, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10060,6 +10066,8 @@ GEN_XX3FORM(xsnmsubadp, 0x04, 0x16, PPC2_VSX),
 GEN_XX3FORM(xsnmsubmdp, 0x04, 0x17, PPC2_VSX),
 GEN_XX2FORM(xscmpodp,  0x0C, 0x05, PPC2_VSX),
 GEN_XX2FORM(xscmpudp,  0x0C, 0x04, PPC2_VSX),
+GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX),
+GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
@@ -10078,6 +10086,8 @@ GEN_XX3FORM(xvnmaddadp, 0x04, 0x1C, PPC2_VSX),
 GEN_XX3FORM(xvnmaddmdp, 0x04, 0x1D, PPC2_VSX),
 GEN_XX3FORM(xvnmsubadp, 0x04, 0x1E, PPC2_VSX),
 GEN_XX3FORM(xvnmsubmdp, 0x04, 0x1F, PPC2_VSX),
+GEN_XX3FORM(xvmaxdp, 0x00, 0x1C, PPC2_VSX),
+GEN_XX3FORM(xvmindp, 0x00, 0x1D, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
@@ -10096,6 +10106,8 @@ GEN_XX3FORM(xvnmaddasp, 0x04, 0x18, PPC2_VSX),
 GEN_XX3FORM(xvnmaddmsp, 0x04, 0x19, PPC2_VSX),
 GEN_XX3FORM(xvnmsubasp, 0x04, 0x1A, PPC2_VSX),
 GEN_XX3FORM(xvnmsubmsp, 0x04, 0x1B, PPC2_VSX),
+GEN_XX3FORM(xvmaxsp, 0x00, 0x18, PPC2_VSX),
+GEN_XX3FORM(xvminsp, 0x00, 0x19, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 030/130] target-ppc: Add VSX Vector Compare Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (28 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 029/130] target-ppc: Add VSX xmax/xmin Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 031/130] target-ppc: Add VSX Floating Point to Floating Point Conversion Instructions Alexander Graf
                   ` (100 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX floating point compare vector instructions:

  - xvcmpeqdp[.], xvcmpgedp[.], xvcmpgtdp[.]
  - xvcmpeqsp[.], xvcmpgesp[.], xvcmpgtsp[.]

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  6 ++++++
 target-ppc/translate.c  | 23 ++++++++++++++++++++
 3 files changed, 86 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 8ece966..128605e 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2327,3 +2327,60 @@ VSX_MAX_MIN(xvmaxsp, maxnum, 4, float32, f32)
 VSX_MAX_MIN(xsmindp, minnum, 1, float64, f64)
 VSX_MAX_MIN(xvmindp, minnum, 2, float64, f64)
 VSX_MAX_MIN(xvminsp, minnum, 4, float32, f32)
+
+/* VSX_CMP - VSX floating point compare
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   cmp   - comparison operation
+ *   svxvc - set VXVC bit
+ */
+#define VSX_CMP(op, nels, tp, fld, cmp, svxvc)                            \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                       \
+{                                                                         \
+    ppc_vsr_t xt, xa, xb;                                                 \
+    int i;                                                                \
+    int all_true = 1;                                                     \
+    int all_false = 1;                                                    \
+                                                                          \
+    getVSR(xA(opcode), &xa, env);                                         \
+    getVSR(xB(opcode), &xb, env);                                         \
+    getVSR(xT(opcode), &xt, env);                                         \
+                                                                          \
+    for (i = 0; i < nels; i++) {                                          \
+        if (unlikely(tp##_is_any_nan(xa.fld[i]) ||                        \
+                     tp##_is_any_nan(xb.fld[i]))) {                       \
+            if (tp##_is_signaling_nan(xa.fld[i]) ||                       \
+                tp##_is_signaling_nan(xb.fld[i])) {                       \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);    \
+            }                                                             \
+            if (svxvc) {                                                  \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0);      \
+            }                                                             \
+            xt.fld[i] = 0;                                                \
+            all_true = 0;                                                 \
+        } else {                                                          \
+            if (tp##_##cmp(xb.fld[i], xa.fld[i], &env->fp_status) == 1) { \
+                xt.fld[i] = -1;                                           \
+                all_false = 0;                                            \
+            } else {                                                      \
+                xt.fld[i] = 0;                                            \
+                all_true = 0;                                             \
+            }                                                             \
+        }                                                                 \
+    }                                                                     \
+                                                                          \
+    putVSR(xT(opcode), &xt, env);                                         \
+    if ((opcode >> (31-21)) & 1) {                                        \
+        env->crf[6] = (all_true ? 0x8 : 0) | (all_false ? 0x2 : 0);       \
+    }                                                                     \
+    helper_float_check_status(env);                                       \
+ }
+
+VSX_CMP(xvcmpeqdp, 2, float64, f64, eq, 0)
+VSX_CMP(xvcmpgedp, 2, float64, f64, le, 1)
+VSX_CMP(xvcmpgtdp, 2, float64, f64, lt, 1)
+VSX_CMP(xvcmpeqsp, 4, float32, f32, eq, 0)
+VSX_CMP(xvcmpgesp, 4, float32, f32, le, 1)
+VSX_CMP(xvcmpgtsp, 4, float32, f32, lt, 1)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 4a65d39..35389c5 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -292,6 +292,9 @@ DEF_HELPER_2(xvnmsubadp, void, env, i32)
 DEF_HELPER_2(xvnmsubmdp, void, env, i32)
 DEF_HELPER_2(xvmaxdp, void, env, i32)
 DEF_HELPER_2(xvmindp, void, env, i32)
+DEF_HELPER_2(xvcmpeqdp, void, env, i32)
+DEF_HELPER_2(xvcmpgedp, void, env, i32)
+DEF_HELPER_2(xvcmpgtdp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
@@ -312,6 +315,9 @@ DEF_HELPER_2(xvnmsubasp, void, env, i32)
 DEF_HELPER_2(xvnmsubmsp, void, env, i32)
 DEF_HELPER_2(xvmaxsp, void, env, i32)
 DEF_HELPER_2(xvminsp, void, env, i32)
+DEF_HELPER_2(xvcmpeqsp, void, env, i32)
+DEF_HELPER_2(xvcmpgesp, void, env, i32)
+DEF_HELPER_2(xvcmpgtsp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index cb68dcd..2fae1f3 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7345,6 +7345,9 @@ GEN_VSX_HELPER_2(xvnmsubadp, 0x04, 0x1E, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvnmsubmdp, 0x04, 0x1F, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvmaxdp, 0x00, 0x1C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvmindp, 0x00, 0x1D, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcmpgedp, 0x0C, 0x0E, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
@@ -7365,6 +7368,9 @@ GEN_VSX_HELPER_2(xvnmsubasp, 0x04, 0x1A, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvnmsubmsp, 0x04, 0x1B, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvmaxsp, 0x00, 0x18, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvminsp, 0x00, 0x19, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcmpeqsp, 0x0C, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10014,6 +10020,17 @@ GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2), \
 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 0, PPC_NONE, fl2), \
 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 0, PPC_NONE, fl2)
 
+#undef GEN_XX3_RC_FORM
+#define GEN_XX3_RC_FORM(name, opc2, opc3, fl2)                          \
+GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x00, 0, PPC_NONE, fl2), \
+GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x01, opc3 | 0x00, 0, PPC_NONE, fl2), \
+GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x02, opc3 | 0x00, 0, PPC_NONE, fl2), \
+GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x03, opc3 | 0x00, 0, PPC_NONE, fl2), \
+GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x10, 0, PPC_NONE, fl2), \
+GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x01, opc3 | 0x10, 0, PPC_NONE, fl2), \
+GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x02, opc3 | 0x10, 0, PPC_NONE, fl2), \
+GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x03, opc3 | 0x10, 0, PPC_NONE, fl2)
+
 #undef GEN_XX3FORM_DM
 #define GEN_XX3FORM_DM(name, opc2, opc3) \
 GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
@@ -10088,6 +10105,9 @@ GEN_XX3FORM(xvnmsubadp, 0x04, 0x1E, PPC2_VSX),
 GEN_XX3FORM(xvnmsubmdp, 0x04, 0x1F, PPC2_VSX),
 GEN_XX3FORM(xvmaxdp, 0x00, 0x1C, PPC2_VSX),
 GEN_XX3FORM(xvmindp, 0x00, 0x1D, PPC2_VSX),
+GEN_XX3_RC_FORM(xvcmpeqdp, 0x0C, 0x0C, PPC2_VSX),
+GEN_XX3_RC_FORM(xvcmpgtdp, 0x0C, 0x0D, PPC2_VSX),
+GEN_XX3_RC_FORM(xvcmpgedp, 0x0C, 0x0E, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
@@ -10108,6 +10128,9 @@ GEN_XX3FORM(xvnmsubasp, 0x04, 0x1A, PPC2_VSX),
 GEN_XX3FORM(xvnmsubmsp, 0x04, 0x1B, PPC2_VSX),
 GEN_XX3FORM(xvmaxsp, 0x00, 0x18, PPC2_VSX),
 GEN_XX3FORM(xvminsp, 0x00, 0x19, PPC2_VSX),
+GEN_XX3_RC_FORM(xvcmpeqsp, 0x0C, 0x08, PPC2_VSX),
+GEN_XX3_RC_FORM(xvcmpgtsp, 0x0C, 0x09, PPC2_VSX),
+GEN_XX3_RC_FORM(xvcmpgesp, 0x0C, 0x0A, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 031/130] target-ppc: Add VSX Floating Point to Floating Point Conversion Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (29 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 030/130] target-ppc: Add VSX Vector Compare Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 032/130] target-ppc: Add VSX ISA2.06 Integer " Alexander Graf
                   ` (99 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX instructions that convert between floating
point formats: xscvdpsp, xscvspdp, xvcvdpsp, xvcvspdp.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  4 ++++
 target-ppc/translate.c  |  8 ++++++++
 3 files changed, 58 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 128605e..6a428c9 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2384,3 +2384,49 @@ VSX_CMP(xvcmpgtdp, 2, float64, f64, lt, 1)
 VSX_CMP(xvcmpeqsp, 4, float32, f32, eq, 0)
 VSX_CMP(xvcmpgesp, 4, float32, f32, le, 1)
 VSX_CMP(xvcmpgtsp, 4, float32, f32, lt, 1)
+
+#if defined(HOST_WORDS_BIGENDIAN)
+#define JOFFSET 0
+#else
+#define JOFFSET 1
+#endif
+
+/* VSX_CVT_FP_TO_FP - VSX floating point/floating point conversion
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   stp   - source type (float32 or float64)
+ *   ttp   - target type (float32 or float64)
+ *   sfld  - source vsr_t field
+ *   tfld  - target vsr_t field (f32 or f64)
+ *   sfprf - set FPRF
+ */
+#define VSX_CVT_FP_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf)    \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                \
+{                                                                  \
+    ppc_vsr_t xt, xb;                                              \
+    int i;                                                         \
+                                                                   \
+    getVSR(xB(opcode), &xb, env);                                  \
+    getVSR(xT(opcode), &xt, env);                                  \
+                                                                   \
+    for (i = 0; i < nels; i++) {                                   \
+        int j = 2*i + JOFFSET;                                     \
+        xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status);        \
+        if (unlikely(stp##_is_signaling_nan(xb.sfld))) {           \
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
+            xt.tfld = ttp##_snan_to_qnan(xt.tfld);                 \
+        }                                                          \
+        if (sfprf) {                                               \
+            helper_compute_fprf(env, ttp##_to_float64(xt.tfld,     \
+                                &env->fp_status), sfprf);          \
+        }                                                          \
+    }                                                              \
+                                                                   \
+    putVSR(xT(opcode), &xt, env);                                  \
+    helper_float_check_status(env);                                \
+}
+
+VSX_CVT_FP_TO_FP(xscvdpsp, 1, float64, float32, f64[i], f32[j], 1)
+VSX_CVT_FP_TO_FP(xscvspdp, 1, float32, float64, f32[j], f64[i], 1)
+VSX_CVT_FP_TO_FP(xvcvdpsp, 2, float64, float32, f64[i], f32[j], 0)
+VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, f32[j], f64[i], 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 35389c5..dd9518c 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -272,6 +272,8 @@ DEF_HELPER_2(xscmpodp, void, env, i32)
 DEF_HELPER_2(xscmpudp, void, env, i32)
 DEF_HELPER_2(xsmaxdp, void, env, i32)
 DEF_HELPER_2(xsmindp, void, env, i32)
+DEF_HELPER_2(xscvdpsp, void, env, i32)
+DEF_HELPER_2(xscvspdp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
@@ -295,6 +297,7 @@ DEF_HELPER_2(xvmindp, void, env, i32)
 DEF_HELPER_2(xvcmpeqdp, void, env, i32)
 DEF_HELPER_2(xvcmpgedp, void, env, i32)
 DEF_HELPER_2(xvcmpgtdp, void, env, i32)
+DEF_HELPER_2(xvcvdpsp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
@@ -318,6 +321,7 @@ DEF_HELPER_2(xvminsp, void, env, i32)
 DEF_HELPER_2(xvcmpeqsp, void, env, i32)
 DEF_HELPER_2(xvcmpgesp, void, env, i32)
 DEF_HELPER_2(xvcmpgtsp, void, env, i32)
+DEF_HELPER_2(xvcvspdp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 2fae1f3..9344f38 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7325,6 +7325,8 @@ GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -7348,6 +7350,7 @@ GEN_VSX_HELPER_2(xvmindp, 0x00, 0x1D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgedp, 0x0C, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvdpsp, 0x12, 0x18, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
@@ -7371,6 +7374,7 @@ GEN_VSX_HELPER_2(xvminsp, 0x00, 0x19, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpeqsp, 0x0C, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvspdp, 0x12, 0x1C, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10085,6 +10089,8 @@ GEN_XX2FORM(xscmpodp,  0x0C, 0x05, PPC2_VSX),
 GEN_XX2FORM(xscmpudp,  0x0C, 0x04, PPC2_VSX),
 GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX),
 GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX),
+GEN_XX2FORM(xscvdpsp, 0x12, 0x10, PPC2_VSX),
+GEN_XX2FORM(xscvspdp, 0x12, 0x14, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
@@ -10108,6 +10114,7 @@ GEN_XX3FORM(xvmindp, 0x00, 0x1D, PPC2_VSX),
 GEN_XX3_RC_FORM(xvcmpeqdp, 0x0C, 0x0C, PPC2_VSX),
 GEN_XX3_RC_FORM(xvcmpgtdp, 0x0C, 0x0D, PPC2_VSX),
 GEN_XX3_RC_FORM(xvcmpgedp, 0x0C, 0x0E, PPC2_VSX),
+GEN_XX2FORM(xvcvdpsp, 0x12, 0x18, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
@@ -10131,6 +10138,7 @@ GEN_XX3FORM(xvminsp, 0x00, 0x19, PPC2_VSX),
 GEN_XX3_RC_FORM(xvcmpeqsp, 0x0C, 0x08, PPC2_VSX),
 GEN_XX3_RC_FORM(xvcmpgtsp, 0x0C, 0x09, PPC2_VSX),
 GEN_XX3_RC_FORM(xvcmpgesp, 0x0C, 0x0A, PPC2_VSX),
+GEN_XX2FORM(xvcvspdp, 0x12, 0x1C, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 032/130] target-ppc: Add VSX ISA2.06 Integer Conversion Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (30 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 031/130] target-ppc: Add VSX Floating Point to Floating Point Conversion Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 033/130] target-ppc: Add VSX Rounding Instructions Alexander Graf
                   ` (98 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX Integer Conversion instructions defined by
V2.06 of the PowerPC ISA:

  - xscvdpsxds, xscvdpsxws, xscvdpuxds, xscvdpuxws
  - xvcvdpsxds, xvcvdpsxws, xvcvdpuxds, xvcvdpuxws
  - xvcvspsxds, xvcvspsxws, xvcvspuxds, xvcvspuxws
  - xscvsxddp, xscvuxddp
  - xvcvsxddp, xscvsxwdp, xvcvuxddp, xvcvuxwdp
  - xvcvsxdsp, xscvsxwsp, xvcvuxdsp, xvcvuxwsp

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  22 ++++++++++
 target-ppc/translate.c  |  44 ++++++++++++++++++++
 3 files changed, 173 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 6a428c9..3970652 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2430,3 +2430,110 @@ VSX_CVT_FP_TO_FP(xscvdpsp, 1, float64, float32, f64[i], f32[j], 1)
 VSX_CVT_FP_TO_FP(xscvspdp, 1, float32, float64, f32[j], f64[i], 1)
 VSX_CVT_FP_TO_FP(xvcvdpsp, 2, float64, float32, f64[i], f32[j], 0)
 VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, f32[j], f64[i], 0)
+
+/* VSX_CVT_FP_TO_INT - VSX floating point to integer conversion
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   stp   - source type (float32 or float64)
+ *   ttp   - target type (int32, uint32, int64 or uint64)
+ *   sfld  - source vsr_t field
+ *   tfld  - target vsr_t field
+ *   jdef  - definition of the j index (i or 2*i)
+ *   rnan  - resulting NaN
+ */
+#define VSX_CVT_FP_TO_INT(op, nels, stp, ttp, sfld, tfld, jdef, rnan)        \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
+{                                                                            \
+    ppc_vsr_t xt, xb;                                                        \
+    int i;                                                                   \
+                                                                             \
+    getVSR(xB(opcode), &xb, env);                                            \
+    getVSR(xT(opcode), &xt, env);                                            \
+                                                                             \
+    for (i = 0; i < nels; i++) {                                             \
+        int j = jdef;                                                        \
+        if (unlikely(stp##_is_any_nan(xb.sfld))) {                           \
+            if (stp##_is_signaling_nan(xb.sfld)) {                           \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);       \
+            }                                                                \
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0);            \
+            xt.tfld = rnan;                                                  \
+        } else {                                                             \
+            xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status);              \
+            if (env->fp_status.float_exception_flags & float_flag_invalid) { \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0);        \
+            }                                                                \
+        }                                                                    \
+    }                                                                        \
+                                                                             \
+    putVSR(xT(opcode), &xt, env);                                            \
+    helper_float_check_status(env);                                          \
+}
+
+VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, f64[j], u64[i], i, \
+                  0x8000000000000000ul)
+VSX_CVT_FP_TO_INT(xscvdpsxws, 1, float64, int32, f64[i], u32[j], \
+                  2*i + JOFFSET, 0x80000000l)
+VSX_CVT_FP_TO_INT(xscvdpuxds, 1, float64, uint64, f64[j], u64[i], i, 0ul)
+VSX_CVT_FP_TO_INT(xscvdpuxws, 1, float64, uint32, f64[i], u32[j], \
+                  2*i + JOFFSET, 0)
+VSX_CVT_FP_TO_INT(xvcvdpsxds, 2, float64, int64, f64[j], u64[i], i, \
+                  0x8000000000000000ul)
+VSX_CVT_FP_TO_INT(xvcvdpsxws, 2, float64, int32, f64[i], u32[j], \
+                  2*i + JOFFSET, 0x80000000l)
+VSX_CVT_FP_TO_INT(xvcvdpuxds, 2, float64, uint64, f64[j], u64[i], i, 0ul)
+VSX_CVT_FP_TO_INT(xvcvdpuxws, 2, float64, uint32, f64[i], u32[j], \
+                  2*i + JOFFSET, 0)
+VSX_CVT_FP_TO_INT(xvcvspsxds, 2, float32, int64, f32[j], u64[i], \
+                  2*i + JOFFSET, 0x8000000000000000ul)
+VSX_CVT_FP_TO_INT(xvcvspsxws, 4, float32, int32, f32[j], u32[j], i, \
+                  0x80000000l)
+VSX_CVT_FP_TO_INT(xvcvspuxds, 2, float32, uint64, f32[j], u64[i], \
+                  2*i + JOFFSET, 0ul)
+VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, f32[j], u32[i], i, 0)
+
+/* VSX_CVT_INT_TO_FP - VSX integer to floating point conversion
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   stp   - source type (int32, uint32, int64 or uint64)
+ *   ttp   - target type (float32 or float64)
+ *   sfld  - source vsr_t field
+ *   tfld  - target vsr_t field
+ *   jdef  - definition of the j index (i or 2*i)
+ *   sfprf - set FPRF
+ */
+#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, jdef, sfprf)  \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                     \
+{                                                                       \
+    ppc_vsr_t xt, xb;                                                   \
+    int i;                                                              \
+                                                                        \
+    getVSR(xB(opcode), &xb, env);                                       \
+    getVSR(xT(opcode), &xt, env);                                       \
+                                                                        \
+    for (i = 0; i < nels; i++) {                                        \
+        int j = jdef;                                                   \
+        xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status);             \
+        if (sfprf) {                                                    \
+            helper_compute_fprf(env, xt.tfld, sfprf);                   \
+        }                                                               \
+    }                                                                   \
+                                                                        \
+    putVSR(xT(opcode), &xt, env);                                       \
+    helper_float_check_status(env);                                     \
+}
+
+VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, u64[j], f64[i], i, 1)
+VSX_CVT_INT_TO_FP(xscvuxddp, 1, uint64, float64, u64[j], f64[i], i, 1)
+VSX_CVT_INT_TO_FP(xvcvsxddp, 2, int64, float64, u64[j], f64[i], i, 0)
+VSX_CVT_INT_TO_FP(xvcvuxddp, 2, uint64, float64, u64[j], f64[i], i, 0)
+VSX_CVT_INT_TO_FP(xvcvsxwdp, 2, int32, float64, u32[j], f64[i], \
+                  2*i + JOFFSET, 0)
+VSX_CVT_INT_TO_FP(xvcvuxwdp, 2, uint64, float64, u32[j], f64[i], \
+                  2*i + JOFFSET, 0)
+VSX_CVT_INT_TO_FP(xvcvsxdsp, 2, int64, float32, u64[i], f32[j], \
+                  2*i + JOFFSET, 0)
+VSX_CVT_INT_TO_FP(xvcvuxdsp, 2, uint64, float32, u64[i], f32[j], \
+                  2*i + JOFFSET, 0)
+VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, u32[j], f32[i], i, 0)
+VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, u32[j], f32[i], i, 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index dd9518c..de46b6f 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -274,6 +274,12 @@ DEF_HELPER_2(xsmaxdp, void, env, i32)
 DEF_HELPER_2(xsmindp, void, env, i32)
 DEF_HELPER_2(xscvdpsp, void, env, i32)
 DEF_HELPER_2(xscvspdp, void, env, i32)
+DEF_HELPER_2(xscvdpsxds, void, env, i32)
+DEF_HELPER_2(xscvdpsxws, void, env, i32)
+DEF_HELPER_2(xscvdpuxds, void, env, i32)
+DEF_HELPER_2(xscvdpuxws, void, env, i32)
+DEF_HELPER_2(xscvsxddp, void, env, i32)
+DEF_HELPER_2(xscvuxddp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
@@ -298,6 +304,14 @@ DEF_HELPER_2(xvcmpeqdp, void, env, i32)
 DEF_HELPER_2(xvcmpgedp, void, env, i32)
 DEF_HELPER_2(xvcmpgtdp, void, env, i32)
 DEF_HELPER_2(xvcvdpsp, void, env, i32)
+DEF_HELPER_2(xvcvdpsxds, void, env, i32)
+DEF_HELPER_2(xvcvdpsxws, void, env, i32)
+DEF_HELPER_2(xvcvdpuxds, void, env, i32)
+DEF_HELPER_2(xvcvdpuxws, void, env, i32)
+DEF_HELPER_2(xvcvsxddp, void, env, i32)
+DEF_HELPER_2(xvcvuxddp, void, env, i32)
+DEF_HELPER_2(xvcvsxwdp, void, env, i32)
+DEF_HELPER_2(xvcvuxwdp, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
@@ -322,6 +336,14 @@ DEF_HELPER_2(xvcmpeqsp, void, env, i32)
 DEF_HELPER_2(xvcmpgesp, void, env, i32)
 DEF_HELPER_2(xvcmpgtsp, void, env, i32)
 DEF_HELPER_2(xvcvspdp, void, env, i32)
+DEF_HELPER_2(xvcvspsxds, void, env, i32)
+DEF_HELPER_2(xvcvspsxws, void, env, i32)
+DEF_HELPER_2(xvcvspuxds, void, env, i32)
+DEF_HELPER_2(xvcvspuxws, void, env, i32)
+DEF_HELPER_2(xvcvsxdsp, void, env, i32)
+DEF_HELPER_2(xvcvuxdsp, void, env, i32)
+DEF_HELPER_2(xvcvsxwsp, void, env, i32)
+DEF_HELPER_2(xvcvuxwsp, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 9344f38..6926250 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7327,6 +7327,12 @@ GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xscvdpsxds, 0x10, 0x15, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xscvdpsxws, 0x10, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xscvdpuxds, 0x10, 0x14, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xscvdpuxws, 0x10, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xscvsxddp, 0x10, 0x17, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xscvuxddp, 0x10, 0x16, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -7351,6 +7357,14 @@ GEN_VSX_HELPER_2(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgedp, 0x0C, 0x0E, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvdpsp, 0x12, 0x18, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvdpsxds, 0x10, 0x1D, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvdpsxws, 0x10, 0x0D, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvdpuxds, 0x10, 0x1C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvdpuxws, 0x10, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvsxddp, 0x10, 0x1F, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvuxddp, 0x10, 0x1E, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvsxwdp, 0x10, 0x0F, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvuxwdp, 0x10, 0x0E, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
@@ -7375,6 +7389,14 @@ GEN_VSX_HELPER_2(xvcmpeqsp, 0x0C, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvspdp, 0x12, 0x1C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvspsxds, 0x10, 0x19, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvspsxws, 0x10, 0x09, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvspuxds, 0x10, 0x18, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvspuxws, 0x10, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvsxdsp, 0x10, 0x1B, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvuxdsp, 0x10, 0x1A, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvsxwsp, 0x10, 0x0B, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvcvuxwsp, 0x10, 0x0A, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10091,6 +10113,12 @@ GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX),
 GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX),
 GEN_XX2FORM(xscvdpsp, 0x12, 0x10, PPC2_VSX),
 GEN_XX2FORM(xscvspdp, 0x12, 0x14, PPC2_VSX),
+GEN_XX2FORM(xscvdpsxds, 0x10, 0x15, PPC2_VSX),
+GEN_XX2FORM(xscvdpsxws, 0x10, 0x05, PPC2_VSX),
+GEN_XX2FORM(xscvdpuxds, 0x10, 0x14, PPC2_VSX),
+GEN_XX2FORM(xscvdpuxws, 0x10, 0x04, PPC2_VSX),
+GEN_XX2FORM(xscvsxddp, 0x10, 0x17, PPC2_VSX),
+GEN_XX2FORM(xscvuxddp, 0x10, 0x16, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
@@ -10115,6 +10143,14 @@ GEN_XX3_RC_FORM(xvcmpeqdp, 0x0C, 0x0C, PPC2_VSX),
 GEN_XX3_RC_FORM(xvcmpgtdp, 0x0C, 0x0D, PPC2_VSX),
 GEN_XX3_RC_FORM(xvcmpgedp, 0x0C, 0x0E, PPC2_VSX),
 GEN_XX2FORM(xvcvdpsp, 0x12, 0x18, PPC2_VSX),
+GEN_XX2FORM(xvcvdpsxds, 0x10, 0x1D, PPC2_VSX),
+GEN_XX2FORM(xvcvdpsxws, 0x10, 0x0D, PPC2_VSX),
+GEN_XX2FORM(xvcvdpuxds, 0x10, 0x1C, PPC2_VSX),
+GEN_XX2FORM(xvcvdpuxws, 0x10, 0x0C, PPC2_VSX),
+GEN_XX2FORM(xvcvsxddp, 0x10, 0x1F, PPC2_VSX),
+GEN_XX2FORM(xvcvuxddp, 0x10, 0x1E, PPC2_VSX),
+GEN_XX2FORM(xvcvsxwdp, 0x10, 0x0F, PPC2_VSX),
+GEN_XX2FORM(xvcvuxwdp, 0x10, 0x0E, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
@@ -10139,6 +10175,14 @@ GEN_XX3_RC_FORM(xvcmpeqsp, 0x0C, 0x08, PPC2_VSX),
 GEN_XX3_RC_FORM(xvcmpgtsp, 0x0C, 0x09, PPC2_VSX),
 GEN_XX3_RC_FORM(xvcmpgesp, 0x0C, 0x0A, PPC2_VSX),
 GEN_XX2FORM(xvcvspdp, 0x12, 0x1C, PPC2_VSX),
+GEN_XX2FORM(xvcvspsxds, 0x10, 0x19, PPC2_VSX),
+GEN_XX2FORM(xvcvspsxws, 0x10, 0x09, PPC2_VSX),
+GEN_XX2FORM(xvcvspuxds, 0x10, 0x18, PPC2_VSX),
+GEN_XX2FORM(xvcvspuxws, 0x10, 0x08, PPC2_VSX),
+GEN_XX2FORM(xvcvsxdsp, 0x10, 0x1B, PPC2_VSX),
+GEN_XX2FORM(xvcvuxdsp, 0x10, 0x1A, PPC2_VSX),
+GEN_XX2FORM(xvcvsxwsp, 0x10, 0x0B, PPC2_VSX),
+GEN_XX2FORM(xvcvuxwsp, 0x10, 0x0A, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 033/130] target-ppc: Add VSX Rounding Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (31 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 032/130] target-ppc: Add VSX ISA2.06 Integer " Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 034/130] target-ppc: VSX Stage 4: Add VSX 2.07 Flag Alexander Graf
                   ` (97 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX Round to Floating Point Integer instructions:

  - xsrdpi, xsrdpic, xsrdpim, xsrdpip, xsrdpiz
  - xvrdpi, xvrdpic, xvrdpim, xvrdpip, xvrdpiz
  - xvrspi, xvrspic, xvrspim, xvrspip, xvrspiz

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/helper.h     | 15 +++++++++++
 target-ppc/translate.c  | 30 ++++++++++++++++++++++
 3 files changed, 113 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 3970652..3165ef0 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2537,3 +2537,71 @@ VSX_CVT_INT_TO_FP(xvcvuxdsp, 2, uint64, float32, u64[i], f32[j], \
                   2*i + JOFFSET, 0)
 VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, u32[j], f32[i], i, 0)
 VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, u32[j], f32[i], i, 0)
+
+/* For "use current rounding mode", define a value that will not be one of
+ * the existing rounding model enums.
+ */
+#define FLOAT_ROUND_CURRENT (float_round_nearest_even + float_round_down + \
+  float_round_up + float_round_to_zero)
+
+/* VSX_ROUND - VSX floating point round
+ *   op    - instruction mnemonic
+ *   nels  - number of elements (1, 2 or 4)
+ *   tp    - type (float32 or float64)
+ *   fld   - vsr_t field (f32 or f64)
+ *   rmode - rounding mode
+ *   sfprf - set FPRF
+ */
+#define VSX_ROUND(op, nels, tp, fld, rmode, sfprf)                     \
+void helper_##op(CPUPPCState *env, uint32_t opcode)                    \
+{                                                                      \
+    ppc_vsr_t xt, xb;                                                  \
+    int i;                                                             \
+    getVSR(xB(opcode), &xb, env);                                      \
+    getVSR(xT(opcode), &xt, env);                                      \
+                                                                       \
+    if (rmode != FLOAT_ROUND_CURRENT) {                                \
+        set_float_rounding_mode(rmode, &env->fp_status);               \
+    }                                                                  \
+                                                                       \
+    for (i = 0; i < nels; i++) {                                       \
+        if (unlikely(tp##_is_signaling_nan(xb.fld[i]))) {              \
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0);     \
+            xt.fld[i] = tp##_snan_to_qnan(xb.fld[i]);                  \
+        } else {                                                       \
+            xt.fld[i] = tp##_round_to_int(xb.fld[i], &env->fp_status); \
+        }                                                              \
+        if (sfprf) {                                                   \
+            helper_compute_fprf(env, xt.fld[i], sfprf);                \
+        }                                                              \
+    }                                                                  \
+                                                                       \
+    /* If this is not a "use current rounding mode" instruction,       \
+     * then inhibit setting of the XX bit and restore rounding         \
+     * mode from FPSCR */                                              \
+    if (rmode != FLOAT_ROUND_CURRENT) {                                \
+        fpscr_set_rounding_mode(env);                                  \
+        env->fp_status.float_exception_flags &= ~float_flag_inexact;   \
+    }                                                                  \
+                                                                       \
+    putVSR(xT(opcode), &xt, env);                                      \
+    helper_float_check_status(env);                                    \
+}
+
+VSX_ROUND(xsrdpi, 1, float64, f64, float_round_nearest_even, 1)
+VSX_ROUND(xsrdpic, 1, float64, f64, FLOAT_ROUND_CURRENT, 1)
+VSX_ROUND(xsrdpim, 1, float64, f64, float_round_down, 1)
+VSX_ROUND(xsrdpip, 1, float64, f64, float_round_up, 1)
+VSX_ROUND(xsrdpiz, 1, float64, f64, float_round_to_zero, 1)
+
+VSX_ROUND(xvrdpi, 2, float64, f64, float_round_nearest_even, 0)
+VSX_ROUND(xvrdpic, 2, float64, f64, FLOAT_ROUND_CURRENT, 0)
+VSX_ROUND(xvrdpim, 2, float64, f64, float_round_down, 0)
+VSX_ROUND(xvrdpip, 2, float64, f64, float_round_up, 0)
+VSX_ROUND(xvrdpiz, 2, float64, f64, float_round_to_zero, 0)
+
+VSX_ROUND(xvrspi, 4, float32, f32, float_round_nearest_even, 0)
+VSX_ROUND(xvrspic, 4, float32, f32, FLOAT_ROUND_CURRENT, 0)
+VSX_ROUND(xvrspim, 4, float32, f32, float_round_down, 0)
+VSX_ROUND(xvrspip, 4, float32, f32, float_round_up, 0)
+VSX_ROUND(xvrspiz, 4, float32, f32, float_round_to_zero, 0)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index de46b6f..0276b02 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -280,6 +280,11 @@ DEF_HELPER_2(xscvdpuxds, void, env, i32)
 DEF_HELPER_2(xscvdpuxws, void, env, i32)
 DEF_HELPER_2(xscvsxddp, void, env, i32)
 DEF_HELPER_2(xscvuxddp, void, env, i32)
+DEF_HELPER_2(xsrdpi, void, env, i32)
+DEF_HELPER_2(xsrdpic, void, env, i32)
+DEF_HELPER_2(xsrdpim, void, env, i32)
+DEF_HELPER_2(xsrdpip, void, env, i32)
+DEF_HELPER_2(xsrdpiz, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
@@ -312,6 +317,11 @@ DEF_HELPER_2(xvcvsxddp, void, env, i32)
 DEF_HELPER_2(xvcvuxddp, void, env, i32)
 DEF_HELPER_2(xvcvsxwdp, void, env, i32)
 DEF_HELPER_2(xvcvuxwdp, void, env, i32)
+DEF_HELPER_2(xvrdpi, void, env, i32)
+DEF_HELPER_2(xvrdpic, void, env, i32)
+DEF_HELPER_2(xvrdpim, void, env, i32)
+DEF_HELPER_2(xvrdpip, void, env, i32)
+DEF_HELPER_2(xvrdpiz, void, env, i32)
 
 DEF_HELPER_2(xvaddsp, void, env, i32)
 DEF_HELPER_2(xvsubsp, void, env, i32)
@@ -344,6 +354,11 @@ DEF_HELPER_2(xvcvsxdsp, void, env, i32)
 DEF_HELPER_2(xvcvuxdsp, void, env, i32)
 DEF_HELPER_2(xvcvsxwsp, void, env, i32)
 DEF_HELPER_2(xvcvuxwsp, void, env, i32)
+DEF_HELPER_2(xvrspi, void, env, i32)
+DEF_HELPER_2(xvrspic, void, env, i32)
+DEF_HELPER_2(xvrspim, void, env, i32)
+DEF_HELPER_2(xvrspip, void, env, i32)
+DEF_HELPER_2(xvrspiz, void, env, i32)
 
 DEF_HELPER_2(efscfsi, i32, env, i32)
 DEF_HELPER_2(efscfui, i32, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 6926250..2ae5d20 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7333,6 +7333,11 @@ GEN_VSX_HELPER_2(xscvdpuxds, 0x10, 0x14, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscvdpuxws, 0x10, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscvsxddp, 0x10, 0x17, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscvuxddp, 0x10, 0x16, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsrdpi, 0x12, 0x04, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsrdpic, 0x16, 0x06, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsrdpim, 0x12, 0x07, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsrdpip, 0x12, 0x06, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -7365,6 +7370,11 @@ GEN_VSX_HELPER_2(xvcvsxddp, 0x10, 0x1F, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvuxddp, 0x10, 0x1E, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvsxwdp, 0x10, 0x0F, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvuxwdp, 0x10, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrdpi, 0x12, 0x0C, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrdpic, 0x16, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrdpim, 0x12, 0x0F, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrdpip, 0x12, 0x0E, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrdpiz, 0x12, 0x0D, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
@@ -7397,6 +7407,11 @@ GEN_VSX_HELPER_2(xvcvsxdsp, 0x10, 0x1B, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvuxdsp, 0x10, 0x1A, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvsxwsp, 0x10, 0x0B, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvcvuxwsp, 0x10, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrspi, 0x12, 0x08, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrspic, 0x16, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrspim, 0x12, 0x0B, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrspip, 0x12, 0x0A, 0, PPC2_VSX)
+GEN_VSX_HELPER_2(xvrspiz, 0x12, 0x09, 0, PPC2_VSX)
 
 #define VSX_LOGICAL(name, tcg_op)                                    \
 static void glue(gen_, name)(DisasContext * ctx)                     \
@@ -10119,6 +10134,11 @@ GEN_XX2FORM(xscvdpuxds, 0x10, 0x14, PPC2_VSX),
 GEN_XX2FORM(xscvdpuxws, 0x10, 0x04, PPC2_VSX),
 GEN_XX2FORM(xscvsxddp, 0x10, 0x17, PPC2_VSX),
 GEN_XX2FORM(xscvuxddp, 0x10, 0x16, PPC2_VSX),
+GEN_XX2FORM(xsrdpi, 0x12, 0x04, PPC2_VSX),
+GEN_XX2FORM(xsrdpic, 0x16, 0x06, PPC2_VSX),
+GEN_XX2FORM(xsrdpim, 0x12, 0x07, PPC2_VSX),
+GEN_XX2FORM(xsrdpip, 0x12, 0x06, PPC2_VSX),
+GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
@@ -10151,6 +10171,11 @@ GEN_XX2FORM(xvcvsxddp, 0x10, 0x1F, PPC2_VSX),
 GEN_XX2FORM(xvcvuxddp, 0x10, 0x1E, PPC2_VSX),
 GEN_XX2FORM(xvcvsxwdp, 0x10, 0x0F, PPC2_VSX),
 GEN_XX2FORM(xvcvuxwdp, 0x10, 0x0E, PPC2_VSX),
+GEN_XX2FORM(xvrdpi, 0x12, 0x0C, PPC2_VSX),
+GEN_XX2FORM(xvrdpic, 0x16, 0x0E, PPC2_VSX),
+GEN_XX2FORM(xvrdpim, 0x12, 0x0F, PPC2_VSX),
+GEN_XX2FORM(xvrdpip, 0x12, 0x0E, PPC2_VSX),
+GEN_XX2FORM(xvrdpiz, 0x12, 0x0D, PPC2_VSX),
 
 GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
 GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
@@ -10183,6 +10208,11 @@ GEN_XX2FORM(xvcvsxdsp, 0x10, 0x1B, PPC2_VSX),
 GEN_XX2FORM(xvcvuxdsp, 0x10, 0x1A, PPC2_VSX),
 GEN_XX2FORM(xvcvsxwsp, 0x10, 0x0B, PPC2_VSX),
 GEN_XX2FORM(xvcvuxwsp, 0x10, 0x0A, PPC2_VSX),
+GEN_XX2FORM(xvrspi, 0x12, 0x08, PPC2_VSX),
+GEN_XX2FORM(xvrspic, 0x16, 0x0A, PPC2_VSX),
+GEN_XX2FORM(xvrspim, 0x12, 0x0B, PPC2_VSX),
+GEN_XX2FORM(xvrspip, 0x12, 0x0A, PPC2_VSX),
+GEN_XX2FORM(xvrspiz, 0x12, 0x09, PPC2_VSX),
 
 #undef VSX_LOGICAL
 #define VSX_LOGICAL(name, opc2, opc3, fl2) \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 034/130] target-ppc: VSX Stage 4: Add VSX 2.07 Flag
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (32 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 033/130] target-ppc: Add VSX Rounding Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 035/130] target-ppc: VSX Stage 4: Refactor lxsdx Alexander Graf
                   ` (96 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds a flag to identify those VSX instructions that are
new to Power ISA V2.07.  The flag is added to the Power 8 processor
initialization so that the P8 models understand how to decode and
emulate instructions in this category.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            | 4 +++-
 target-ppc/translate_init.c | 2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 51bcd4a..c7bbbe3 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1875,9 +1875,11 @@ enum {
     PPC2_DBRX          = 0x0000000000000010ULL,
     /* Book I 2.05 PowerPC specification                                     */
     PPC2_ISA205        = 0x0000000000000020ULL,
+    /* VSX additions in ISA 2.07                                             */
+    PPC2_VSX207        = 0x0000000000000040ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
-  PPC2_ISA205)
+                        PPC2_ISA205 | PPC2_VSX207)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 02f5867..60ec9cd 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7144,7 +7144,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_64B | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
-    pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX;
+    pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX;
     pcc->msr_mask = 0x800000000284FF36ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 035/130] target-ppc: VSX Stage 4: Refactor lxsdx
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (33 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 034/130] target-ppc: VSX Stage 4: Add VSX 2.07 Flag Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 036/130] target-ppc: VSX Stage 4: Add lxsiwax, lxsiwzx and lxsspx Alexander Graf
                   ` (95 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch refactors the lxsdx generator. Resuable code is isolated
into a macro.  The macro will be used in subsequent patches in this
series to implement other scalar load instructions.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 2ae5d20..bed679c 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7022,20 +7022,23 @@ static inline TCGv_i64 cpu_vsrl(int n)
     }
 }
 
-static void gen_lxsdx(DisasContext *ctx)
-{
-    TCGv EA;
-    if (unlikely(!ctx->vsx_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_VSXU);
-        return;
-    }
-    gen_set_access_type(ctx, ACCESS_INT);
-    EA = tcg_temp_new();
-    gen_addr_reg_index(ctx, EA);
-    gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
-    /* NOTE: cpu_vsrl is undefined */
-    tcg_temp_free(EA);
-}
+#define VSX_LOAD_SCALAR(name, operation)                      \
+static void gen_##name(DisasContext *ctx)                     \
+{                                                             \
+    TCGv EA;                                                  \
+    if (unlikely(!ctx->vsx_enabled)) {                        \
+        gen_exception(ctx, POWERPC_EXCP_VSXU);                \
+        return;                                               \
+    }                                                         \
+    gen_set_access_type(ctx, ACCESS_INT);                     \
+    EA = tcg_temp_new();                                      \
+    gen_addr_reg_index(ctx, EA);                              \
+    gen_qemu_##operation(ctx, cpu_vsrh(xT(ctx->opcode)), EA); \
+    /* NOTE: cpu_vsrl is undefined */                         \
+    tcg_temp_free(EA);                                        \
+}
+
+VSX_LOAD_SCALAR(lxsdx, ld64)
 
 static void gen_lxvd2x(DisasContext *ctx)
 {
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 036/130] target-ppc: VSX Stage 4: Add lxsiwax, lxsiwzx and lxsspx
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (34 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 035/130] target-ppc: VSX Stage 4: Refactor lxsdx Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 037/130] target-ppc: VSX Stage 4: Refactor stxsdx Alexander Graf
                   ` (94 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the scalar load instructions introduced in ISA
V2.07:

  - Load VSX Scalar as Integer Word Algebraic Indexd (lxsiwax)
  - Load VSX Scalar as Integer Word and Zero Indexed (lxsiwzx)
  - Load VSX Scalar Single-Precision Indexed (lxsspx)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index bed679c..18ff8f7 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -2585,6 +2585,14 @@ static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
         tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
 }
 
+static void gen_qemu_ld32s_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
+{
+    TCGv tmp = tcg_temp_new();
+    gen_qemu_ld32s(ctx, tmp, addr);
+    tcg_gen_ext_tl_i64(val, tmp);
+    tcg_temp_free(tmp);
+}
+
 static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
 {
     tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
@@ -7039,6 +7047,9 @@ static void gen_##name(DisasContext *ctx)                     \
 }
 
 VSX_LOAD_SCALAR(lxsdx, ld64)
+VSX_LOAD_SCALAR(lxsiwax, ld32s_i64)
+VSX_LOAD_SCALAR(lxsiwzx, ld32u_i64)
+VSX_LOAD_SCALAR(lxsspx, ld32fs)
 
 static void gen_lxvd2x(DisasContext *ctx)
 {
@@ -10044,6 +10055,9 @@ GEN_VAFORM_PAIRED(vsel, vperm, 21),
 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
 
 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
+GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
+GEN_HANDLER_E(lxsiwzx, 0x1F, 0x0C, 0x00, 0, PPC_NONE, PPC2_VSX207),
+GEN_HANDLER_E(lxsspx, 0x1F, 0x0C, 0x10, 0, PPC_NONE, PPC2_VSX207),
 GEN_HANDLER_E(lxvd2x, 0x1F, 0x0C, 0x1A, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxvdsx, 0x1F, 0x0C, 0x0A, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 037/130] target-ppc: VSX Stage 4: Refactor stxsdx
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (35 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 036/130] target-ppc: VSX Stage 4: Add lxsiwax, lxsiwzx and lxsspx Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 038/130] target-ppc: VSX Stage 4: Add stxsiwx and stxsspx Alexander Graf
                   ` (93 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch refactors the stxsdx instruction.  Reusable code is
extracted into a macro which will be used in subsequent patches
in this series.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 18ff8f7..2dfdf6c 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7112,20 +7112,23 @@ static void gen_lxvw4x(DisasContext *ctx)
     tcg_temp_free_i64(tmp);
 }
 
-static void gen_stxsdx(DisasContext *ctx)
-{
-    TCGv EA;
-    if (unlikely(!ctx->vsx_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_VSXU);
-        return;
-    }
-    gen_set_access_type(ctx, ACCESS_INT);
-    EA = tcg_temp_new();
-    gen_addr_reg_index(ctx, EA);
-    gen_qemu_st64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
-    tcg_temp_free(EA);
+#define VSX_STORE_SCALAR(name, operation)                     \
+static void gen_##name(DisasContext *ctx)                     \
+{                                                             \
+    TCGv EA;                                                  \
+    if (unlikely(!ctx->vsx_enabled)) {                        \
+        gen_exception(ctx, POWERPC_EXCP_VSXU);                \
+        return;                                               \
+    }                                                         \
+    gen_set_access_type(ctx, ACCESS_INT);                     \
+    EA = tcg_temp_new();                                      \
+    gen_addr_reg_index(ctx, EA);                              \
+    gen_qemu_##operation(ctx, cpu_vsrh(xS(ctx->opcode)), EA); \
+    tcg_temp_free(EA);                                        \
 }
 
+VSX_STORE_SCALAR(stxsdx, st64)
+
 static void gen_stxvd2x(DisasContext *ctx)
 {
     TCGv EA;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 038/130] target-ppc: VSX Stage 4: Add stxsiwx and stxsspx
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (36 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 037/130] target-ppc: VSX Stage 4: Refactor stxsdx Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 039/130] target-ppc: VSX Stage 4: Add xsaddsp and xssubsp Alexander Graf
                   ` (92 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds two store scalar instructions:

  - Store VSX Scalar as Integer Word Indexed (stxsiwx)
  - Store VSX Scalar Single-Precision Indexed (stxsspx)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 2dfdf6c..d67bf2d 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7128,6 +7128,8 @@ static void gen_##name(DisasContext *ctx)                     \
 }
 
 VSX_STORE_SCALAR(stxsdx, st64)
+VSX_STORE_SCALAR(stxsiwx, st32_i64)
+VSX_STORE_SCALAR(stxsspx, st32fs)
 
 static void gen_stxvd2x(DisasContext *ctx)
 {
@@ -10066,6 +10068,8 @@ GEN_HANDLER_E(lxvdsx, 0x1F, 0x0C, 0x0A, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX),
 
 GEN_HANDLER_E(stxsdx, 0x1F, 0xC, 0x16, 0, PPC_NONE, PPC2_VSX),
+GEN_HANDLER_E(stxsiwx, 0x1F, 0xC, 0x04, 0, PPC_NONE, PPC2_VSX207),
+GEN_HANDLER_E(stxsspx, 0x1F, 0xC, 0x14, 0, PPC_NONE, PPC2_VSX207),
 GEN_HANDLER_E(stxvd2x, 0x1F, 0xC, 0x1E, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(stxvw4x, 0x1F, 0xC, 0x1C, 0, PPC_NONE, PPC2_VSX),
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 039/130] target-ppc: VSX Stage 4: Add xsaddsp and xssubsp
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (37 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 038/130] target-ppc: VSX Stage 4: Add stxsiwx and stxsspx Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 040/130] target-ppc: VSX Stage 4: Add xsmulsp Alexander Graf
                   ` (91 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX Scalar Add Single-Precision (xsaddsp) and
VSX Scalar Subtract Single-Precision (xssubsp) instructions.

The existing VSX_ADD_SUB macro is modified to support the rounding
of the (intermediate) result to single-precision.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 20 +++++++++++++-------
 target-ppc/helper.h     |  3 +++
 target-ppc/translate.c  |  6 ++++++
 3 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 3165ef0..f047640 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1768,7 +1768,7 @@ static void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
  *   fld   - vsr_t field (f32 or f64)
  *   sfprf - set FPRF
  */
-#define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf)                          \
+#define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf, r2sp)                    \
 void helper_##name(CPUPPCState *env, uint32_t opcode)                        \
 {                                                                            \
     ppc_vsr_t xt, xa, xb;                                                    \
@@ -1794,6 +1794,10 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)                        \
             }                                                                \
         }                                                                    \
                                                                              \
+        if (r2sp) {                                                          \
+            xt.fld[i] = helper_frsp(env, xt.fld[i]);                         \
+        }                                                                    \
+                                                                             \
         if (sfprf) {                                                         \
             helper_compute_fprf(env, xt.fld[i], sfprf);                      \
         }                                                                    \
@@ -1802,12 +1806,14 @@ void helper_##name(CPUPPCState *env, uint32_t opcode)                        \
     helper_float_check_status(env);                                          \
 }
 
-VSX_ADD_SUB(xsadddp, add, 1, float64, f64, 1)
-VSX_ADD_SUB(xvadddp, add, 2, float64, f64, 0)
-VSX_ADD_SUB(xvaddsp, add, 4, float32, f32, 0)
-VSX_ADD_SUB(xssubdp, sub, 1, float64, f64, 1)
-VSX_ADD_SUB(xvsubdp, sub, 2, float64, f64, 0)
-VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0)
+VSX_ADD_SUB(xsadddp, add, 1, float64, f64, 1, 0)
+VSX_ADD_SUB(xsaddsp, add, 1, float64, f64, 1, 1)
+VSX_ADD_SUB(xvadddp, add, 2, float64, f64, 0, 0)
+VSX_ADD_SUB(xvaddsp, add, 4, float32, f32, 0, 0)
+VSX_ADD_SUB(xssubdp, sub, 1, float64, f64, 1, 0)
+VSX_ADD_SUB(xssubsp, sub, 1, float64, f64, 1, 1)
+VSX_ADD_SUB(xvsubdp, sub, 2, float64, f64, 0, 0)
+VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0, 0)
 
 /* VSX_MUL - VSX floating point multiply
  *   op    - instruction mnemonic
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 0276b02..696b9d3 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -286,6 +286,9 @@ DEF_HELPER_2(xsrdpim, void, env, i32)
 DEF_HELPER_2(xsrdpip, void, env, i32)
 DEF_HELPER_2(xsrdpiz, void, env, i32)
 
+DEF_HELPER_2(xsaddsp, void, env, i32)
+DEF_HELPER_2(xssubsp, void, env, i32)
+
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
 DEF_HELPER_2(xvmuldp, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index d67bf2d..f0925d5 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7358,6 +7358,9 @@ GEN_VSX_HELPER_2(xsrdpim, 0x12, 0x07, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsrdpip, 0x12, 0x06, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
 
+GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
+
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
@@ -10164,6 +10167,9 @@ GEN_XX2FORM(xsrdpim, 0x12, 0x07, PPC2_VSX),
 GEN_XX2FORM(xsrdpip, 0x12, 0x06, PPC2_VSX),
 GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX),
 
+GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207),
+GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207),
+
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
 GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 040/130] target-ppc: VSX Stage 4: Add xsmulsp
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (38 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 039/130] target-ppc: VSX Stage 4: Add xsaddsp and xssubsp Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 041/130] target-ppc: VSX Stage 4: Add xsdivsp Alexander Graf
                   ` (90 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX Scalar Multiply Single-Precision (xsmulsp)
instruction.

The existing VSX_MUL macro is modified to support rounding of the
intermediate result to single precision.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 13 +++++++++----
 target-ppc/helper.h     |  1 +
 target-ppc/translate.c  |  2 ++
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index f047640..dc9849f 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1822,7 +1822,7 @@ VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0, 0)
  *   fld   - vsr_t field (f32 or f64)
  *   sfprf - set FPRF
  */
-#define VSX_MUL(op, nels, tp, fld, sfprf)                                    \
+#define VSX_MUL(op, nels, tp, fld, sfprf, r2sp)                              \
 void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
 {                                                                            \
     ppc_vsr_t xt, xa, xb;                                                    \
@@ -1849,6 +1849,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
             }                                                                \
         }                                                                    \
                                                                              \
+        if (r2sp) {                                                          \
+            xt.fld[i] = helper_frsp(env, xt.fld[i]);                         \
+        }                                                                    \
+                                                                             \
         if (sfprf) {                                                         \
             helper_compute_fprf(env, xt.fld[i], sfprf);                      \
         }                                                                    \
@@ -1858,9 +1862,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
     helper_float_check_status(env);                                          \
 }
 
-VSX_MUL(xsmuldp, 1, float64, f64, 1)
-VSX_MUL(xvmuldp, 2, float64, f64, 0)
-VSX_MUL(xvmulsp, 4, float32, f32, 0)
+VSX_MUL(xsmuldp, 1, float64, f64, 1, 0)
+VSX_MUL(xsmulsp, 1, float64, f64, 1, 1)
+VSX_MUL(xvmuldp, 2, float64, f64, 0, 0)
+VSX_MUL(xvmulsp, 4, float32, f32, 0, 0)
 
 /* VSX_DIV - VSX floating point divide
  *   op    - instruction mnemonic
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 696b9d3..0ccdc96 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -288,6 +288,7 @@ DEF_HELPER_2(xsrdpiz, void, env, i32)
 
 DEF_HELPER_2(xsaddsp, void, env, i32)
 DEF_HELPER_2(xssubsp, void, env, i32)
+DEF_HELPER_2(xsmulsp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f0925d5..87817c2 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7360,6 +7360,7 @@ GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
 
 GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -10169,6 +10170,7 @@ GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX),
 
 GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207),
 GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207),
+GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 041/130] target-ppc: VSX Stage 4: Add xsdivsp
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (39 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 040/130] target-ppc: VSX Stage 4: Add xsmulsp Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 042/130] target-ppc: VSX Stage 4: Add xsresp Alexander Graf
                   ` (89 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX Scalar Divide Single Precision (xsdivsp)
instruction.

The existing VSX_DIV macro is modified to support rounding of the
intermediate double precision result to single precision.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 13 +++++++++----
 target-ppc/helper.h     |  1 +
 target-ppc/translate.c  |  2 ++
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index dc9849f..49cf09a 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1874,7 +1874,7 @@ VSX_MUL(xvmulsp, 4, float32, f32, 0, 0)
  *   fld   - vsr_t field (f32 or f64)
  *   sfprf - set FPRF
  */
-#define VSX_DIV(op, nels, tp, fld, sfprf)                                     \
+#define VSX_DIV(op, nels, tp, fld, sfprf, r2sp)                               \
 void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
 {                                                                             \
     ppc_vsr_t xt, xa, xb;                                                     \
@@ -1903,6 +1903,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
             }                                                                 \
         }                                                                     \
                                                                               \
+        if (r2sp) {                                                           \
+            xt.fld[i] = helper_frsp(env, xt.fld[i]);                          \
+        }                                                                     \
+                                                                              \
         if (sfprf) {                                                          \
             helper_compute_fprf(env, xt.fld[i], sfprf);                       \
         }                                                                     \
@@ -1912,9 +1916,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
     helper_float_check_status(env);                                           \
 }
 
-VSX_DIV(xsdivdp, 1, float64, f64, 1)
-VSX_DIV(xvdivdp, 2, float64, f64, 0)
-VSX_DIV(xvdivsp, 4, float32, f32, 0)
+VSX_DIV(xsdivdp, 1, float64, f64, 1, 0)
+VSX_DIV(xsdivsp, 1, float64, f64, 1, 1)
+VSX_DIV(xvdivdp, 2, float64, f64, 0, 0)
+VSX_DIV(xvdivsp, 4, float32, f32, 0, 0)
 
 /* VSX_RE  - VSX floating point reciprocal estimate
  *   op    - instruction mnemonic
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 0ccdc96..308f97c 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -289,6 +289,7 @@ DEF_HELPER_2(xsrdpiz, void, env, i32)
 DEF_HELPER_2(xsaddsp, void, env, i32)
 DEF_HELPER_2(xssubsp, void, env, i32)
 DEF_HELPER_2(xsmulsp, void, env, i32)
+DEF_HELPER_2(xsdivsp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 87817c2..dd4ddad 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7361,6 +7361,7 @@ GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -10171,6 +10172,7 @@ GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX),
 GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207),
 GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207),
 GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207),
+GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 042/130] target-ppc: VSX Stage 4: Add xsresp
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (40 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 041/130] target-ppc: VSX Stage 4: Add xsdivsp Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 043/130] target-ppc: VSX Stage 4: Add xssqrtsp Alexander Graf
                   ` (88 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX Scalar Reciprocal Estimate Single Precision
(xsresp) instruction.

The existing VSX_RE macro is modified to support rounding of the
intermediate double precision result to single precision.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 14 ++++++++++----
 target-ppc/helper.h     |  1 +
 target-ppc/translate.c  |  2 ++
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 49cf09a..ac52c23 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1928,7 +1928,7 @@ VSX_DIV(xvdivsp, 4, float32, f32, 0, 0)
  *   fld   - vsr_t field (f32 or f64)
  *   sfprf - set FPRF
  */
-#define VSX_RE(op, nels, tp, fld, sfprf)                                      \
+#define VSX_RE(op, nels, tp, fld, sfprf, r2sp)                                \
 void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
 {                                                                             \
     ppc_vsr_t xt, xb;                                                         \
@@ -1943,6 +1943,11 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);    \
         }                                                                     \
         xt.fld[i] = tp##_div(tp##_one, xb.fld[i], &env->fp_status);           \
+                                                                              \
+        if (r2sp) {                                                           \
+            xt.fld[i] = helper_frsp(env, xt.fld[i]);                          \
+        }                                                                     \
+                                                                              \
         if (sfprf) {                                                          \
             helper_compute_fprf(env, xt.fld[0], sfprf);                       \
         }                                                                     \
@@ -1952,9 +1957,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
     helper_float_check_status(env);                                           \
 }
 
-VSX_RE(xsredp, 1, float64, f64, 1)
-VSX_RE(xvredp, 2, float64, f64, 0)
-VSX_RE(xvresp, 4, float32, f32, 0)
+VSX_RE(xsredp, 1, float64, f64, 1, 0)
+VSX_RE(xsresp, 1, float64, f64, 1, 1)
+VSX_RE(xvredp, 2, float64, f64, 0, 0)
+VSX_RE(xvresp, 4, float32, f32, 0, 0)
 
 /* VSX_SQRT - VSX floating point square root
  *   op    - instruction mnemonic
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 308f97c..b1cf3c0 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -290,6 +290,7 @@ DEF_HELPER_2(xsaddsp, void, env, i32)
 DEF_HELPER_2(xssubsp, void, env, i32)
 DEF_HELPER_2(xsmulsp, void, env, i32)
 DEF_HELPER_2(xsdivsp, void, env, i32)
+DEF_HELPER_2(xsresp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index dd4ddad..0dd6220 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7362,6 +7362,7 @@ GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -10173,6 +10174,7 @@ GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207),
 GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207),
 GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207),
 GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207),
+GEN_XX2FORM(xsresp,  0x14, 0x01, PPC2_VSX207),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 043/130] target-ppc: VSX Stage 4: Add xssqrtsp
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (41 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 042/130] target-ppc: VSX Stage 4: Add xsresp Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 044/130] target-ppc: VSX Stage 4: add xsrsqrtesp Alexander Graf
                   ` (87 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX Scalar Square Root Single Precision (xssqrtsp)
instruction.

The existing VSX_SQRT() macro is modified to support rounding of the
intermediate double-precision result to single-precision.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 13 +++++++++----
 target-ppc/helper.h     |  1 +
 target-ppc/translate.c  |  2 ++
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index ac52c23..fec9d1b 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1969,7 +1969,7 @@ VSX_RE(xvresp, 4, float32, f32, 0, 0)
  *   fld   - vsr_t field (f32 or f64)
  *   sfprf - set FPRF
  */
-#define VSX_SQRT(op, nels, tp, fld, sfprf)                                   \
+#define VSX_SQRT(op, nels, tp, fld, sfprf, r2sp)                             \
 void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
 {                                                                            \
     ppc_vsr_t xt, xb;                                                        \
@@ -1993,6 +1993,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
             }                                                                \
         }                                                                    \
                                                                              \
+        if (r2sp) {                                                          \
+            xt.fld[i] = helper_frsp(env, xt.fld[i]);                         \
+        }                                                                    \
+                                                                             \
         if (sfprf) {                                                         \
             helper_compute_fprf(env, xt.fld[i], sfprf);                      \
         }                                                                    \
@@ -2002,9 +2006,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
     helper_float_check_status(env);                                          \
 }
 
-VSX_SQRT(xssqrtdp, 1, float64, f64, 1)
-VSX_SQRT(xvsqrtdp, 2, float64, f64, 0)
-VSX_SQRT(xvsqrtsp, 4, float32, f32, 0)
+VSX_SQRT(xssqrtdp, 1, float64, f64, 1, 0)
+VSX_SQRT(xssqrtsp, 1, float64, f64, 1, 1)
+VSX_SQRT(xvsqrtdp, 2, float64, f64, 0, 0)
+VSX_SQRT(xvsqrtsp, 4, float32, f32, 0, 0)
 
 /* VSX_RSQRTE - VSX floating point reciprocal square root estimate
  *   op    - instruction mnemonic
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index b1cf3c0..0192043 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -291,6 +291,7 @@ DEF_HELPER_2(xssubsp, void, env, i32)
 DEF_HELPER_2(xsmulsp, void, env, i32)
 DEF_HELPER_2(xsdivsp, void, env, i32)
 DEF_HELPER_2(xsresp, void, env, i32)
+DEF_HELPER_2(xssqrtsp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 0dd6220..13099fc 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7363,6 +7363,7 @@ GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -10175,6 +10176,7 @@ GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207),
 GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207),
 GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207),
 GEN_XX2FORM(xsresp,  0x14, 0x01, PPC2_VSX207),
+GEN_XX2FORM(xssqrtsp,  0x16, 0x00, PPC2_VSX207),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 044/130] target-ppc: VSX Stage 4: add xsrsqrtesp
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (42 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 043/130] target-ppc: VSX Stage 4: Add xssqrtsp Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 045/130] target-ppc: VSX Stage 4: Add Scalar SP Fused Multiply-Adds Alexander Graf
                   ` (86 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX Scalar Reciprocal Square Root Estimate
Single Precision (xsrsqrtesp) instruction.

The existing VSX_RSQRTE() macro is modified to support rounding
of the intermediate double-precision result to single precision.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 13 +++++++++----
 target-ppc/helper.h     |  1 +
 target-ppc/translate.c  |  2 ++
 3 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index fec9d1b..33da462 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2018,7 +2018,7 @@ VSX_SQRT(xvsqrtsp, 4, float32, f32, 0, 0)
  *   fld   - vsr_t field (f32 or f64)
  *   sfprf - set FPRF
  */
-#define VSX_RSQRTE(op, nels, tp, fld, sfprf)                                 \
+#define VSX_RSQRTE(op, nels, tp, fld, sfprf, r2sp)                           \
 void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
 {                                                                            \
     ppc_vsr_t xt, xb;                                                        \
@@ -2043,6 +2043,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
             }                                                                \
         }                                                                    \
                                                                              \
+        if (r2sp) {                                                          \
+            xt.fld[i] = helper_frsp(env, xt.fld[i]);                         \
+        }                                                                    \
+                                                                             \
         if (sfprf) {                                                         \
             helper_compute_fprf(env, xt.fld[i], sfprf);                      \
         }                                                                    \
@@ -2052,9 +2056,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
     helper_float_check_status(env);                                          \
 }
 
-VSX_RSQRTE(xsrsqrtedp, 1, float64, f64, 1)
-VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0)
-VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0)
+VSX_RSQRTE(xsrsqrtedp, 1, float64, f64, 1, 0)
+VSX_RSQRTE(xsrsqrtesp, 1, float64, f64, 1, 1)
+VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0, 0)
+VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0, 0)
 
 static inline int ppc_float32_get_unbiased_exp(float32 f)
 {
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 0192043..84c6ee1 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -292,6 +292,7 @@ DEF_HELPER_2(xsmulsp, void, env, i32)
 DEF_HELPER_2(xsdivsp, void, env, i32)
 DEF_HELPER_2(xsresp, void, env, i32)
 DEF_HELPER_2(xssqrtsp, void, env, i32)
+DEF_HELPER_2(xsrsqrtesp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 13099fc..fcf9517 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7364,6 +7364,7 @@ GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -10177,6 +10178,7 @@ GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207),
 GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207),
 GEN_XX2FORM(xsresp,  0x14, 0x01, PPC2_VSX207),
 GEN_XX2FORM(xssqrtsp,  0x16, 0x00, PPC2_VSX207),
+GEN_XX2FORM(xsrsqrtesp,  0x14, 0x00, PPC2_VSX207),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 045/130] target-ppc: VSX Stage 4: Add Scalar SP Fused Multiply-Adds
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (43 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 044/130] target-ppc: VSX Stage 4: add xsrsqrtesp Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 046/130] target-ppc: VSX Stage 4: Add xscvsxdsp and xscvuxdsp Alexander Graf
                   ` (85 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Single Precision VSX Scalar Fused Multiply-Add
instructions: xsmaddasp, xsmaddmsp, xssubasp, xssubmsp, xsnmaddasp,
xsnmaddmsp, xsnmsubasp, xsnmsubmsp.

The existing VSX_MADD() macro is modified to support rounding of the
intermediate double precision result to single precision.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 82 ++++++++++++++++++++++++++++++++-----------------
 target-ppc/helper.h     |  8 +++++
 target-ppc/translate.c  | 16 ++++++++++
 3 files changed, 77 insertions(+), 29 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 33da462..7e5003a 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2192,7 +2192,7 @@ VSX_TSQRT(xvtsqrtsp, 4, float32, f32, -126, 23)
  *   afrm  - A form (1=A, 0=M)
  *   sfprf - set FPRF
  */
-#define VSX_MADD(op, nels, tp, fld, maddflgs, afrm, sfprf)                    \
+#define VSX_MADD(op, nels, tp, fld, maddflgs, afrm, sfprf, r2sp)              \
 void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
 {                                                                             \
     ppc_vsr_t xt_in, xa, xb, xt_out;                                          \
@@ -2218,8 +2218,18 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
     for (i = 0; i < nels; i++) {                                              \
         float_status tstat = env->fp_status;                                  \
         set_float_exception_flags(0, &tstat);                                 \
-        xt_out.fld[i] = tp##_muladd(xa.fld[i], b->fld[i], c->fld[i],          \
-                                     maddflgs, &tstat);                       \
+        if (r2sp && (tstat.float_rounding_mode == float_round_nearest_even)) {\
+            /* Avoid double rounding errors by rounding the intermediate */   \
+            /* result to odd.                                            */   \
+            set_float_rounding_mode(float_round_to_zero, &tstat);             \
+            xt_out.fld[i] = tp##_muladd(xa.fld[i], b->fld[i], c->fld[i],      \
+                                       maddflgs, &tstat);                     \
+            xt_out.fld[i] |= (get_float_exception_flags(&tstat) &             \
+                              float_flag_inexact) != 0;                       \
+        } else {                                                              \
+            xt_out.fld[i] = tp##_muladd(xa.fld[i], b->fld[i], c->fld[i],      \
+                                        maddflgs, &tstat);                    \
+        }                                                                     \
         env->fp_status.float_exception_flags |= tstat.float_exception_flags;  \
                                                                               \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {     \
@@ -2242,6 +2252,11 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
                 fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf);     \
             }                                                                 \
         }                                                                     \
+                                                                              \
+        if (r2sp) {                                                           \
+            xt_out.fld[i] = helper_frsp(env, xt_out.fld[i]);                  \
+        }                                                                     \
+                                                                              \
         if (sfprf) {                                                          \
             helper_compute_fprf(env, xt_out.fld[i], sfprf);                   \
         }                                                                     \
@@ -2255,32 +2270,41 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                           \
 #define NMADD_FLGS float_muladd_negate_result
 #define NMSUB_FLGS (float_muladd_negate_c | float_muladd_negate_result)
 
-VSX_MADD(xsmaddadp, 1, float64, f64, MADD_FLGS, 1, 1)
-VSX_MADD(xsmaddmdp, 1, float64, f64, MADD_FLGS, 0, 1)
-VSX_MADD(xsmsubadp, 1, float64, f64, MSUB_FLGS, 1, 1)
-VSX_MADD(xsmsubmdp, 1, float64, f64, MSUB_FLGS, 0, 1)
-VSX_MADD(xsnmaddadp, 1, float64, f64, NMADD_FLGS, 1, 1)
-VSX_MADD(xsnmaddmdp, 1, float64, f64, NMADD_FLGS, 0, 1)
-VSX_MADD(xsnmsubadp, 1, float64, f64, NMSUB_FLGS, 1, 1)
-VSX_MADD(xsnmsubmdp, 1, float64, f64, NMSUB_FLGS, 0, 1)
-
-VSX_MADD(xvmaddadp, 2, float64, f64, MADD_FLGS, 1, 0)
-VSX_MADD(xvmaddmdp, 2, float64, f64, MADD_FLGS, 0, 0)
-VSX_MADD(xvmsubadp, 2, float64, f64, MSUB_FLGS, 1, 0)
-VSX_MADD(xvmsubmdp, 2, float64, f64, MSUB_FLGS, 0, 0)
-VSX_MADD(xvnmaddadp, 2, float64, f64, NMADD_FLGS, 1, 0)
-VSX_MADD(xvnmaddmdp, 2, float64, f64, NMADD_FLGS, 0, 0)
-VSX_MADD(xvnmsubadp, 2, float64, f64, NMSUB_FLGS, 1, 0)
-VSX_MADD(xvnmsubmdp, 2, float64, f64, NMSUB_FLGS, 0, 0)
-
-VSX_MADD(xvmaddasp, 4, float32, f32, MADD_FLGS, 1, 0)
-VSX_MADD(xvmaddmsp, 4, float32, f32, MADD_FLGS, 0, 0)
-VSX_MADD(xvmsubasp, 4, float32, f32, MSUB_FLGS, 1, 0)
-VSX_MADD(xvmsubmsp, 4, float32, f32, MSUB_FLGS, 0, 0)
-VSX_MADD(xvnmaddasp, 4, float32, f32, NMADD_FLGS, 1, 0)
-VSX_MADD(xvnmaddmsp, 4, float32, f32, NMADD_FLGS, 0, 0)
-VSX_MADD(xvnmsubasp, 4, float32, f32, NMSUB_FLGS, 1, 0)
-VSX_MADD(xvnmsubmsp, 4, float32, f32, NMSUB_FLGS, 0, 0)
+VSX_MADD(xsmaddadp, 1, float64, f64, MADD_FLGS, 1, 1, 0)
+VSX_MADD(xsmaddmdp, 1, float64, f64, MADD_FLGS, 0, 1, 0)
+VSX_MADD(xsmsubadp, 1, float64, f64, MSUB_FLGS, 1, 1, 0)
+VSX_MADD(xsmsubmdp, 1, float64, f64, MSUB_FLGS, 0, 1, 0)
+VSX_MADD(xsnmaddadp, 1, float64, f64, NMADD_FLGS, 1, 1, 0)
+VSX_MADD(xsnmaddmdp, 1, float64, f64, NMADD_FLGS, 0, 1, 0)
+VSX_MADD(xsnmsubadp, 1, float64, f64, NMSUB_FLGS, 1, 1, 0)
+VSX_MADD(xsnmsubmdp, 1, float64, f64, NMSUB_FLGS, 0, 1, 0)
+
+VSX_MADD(xsmaddasp, 1, float64, f64, MADD_FLGS, 1, 1, 1)
+VSX_MADD(xsmaddmsp, 1, float64, f64, MADD_FLGS, 0, 1, 1)
+VSX_MADD(xsmsubasp, 1, float64, f64, MSUB_FLGS, 1, 1, 1)
+VSX_MADD(xsmsubmsp, 1, float64, f64, MSUB_FLGS, 0, 1, 1)
+VSX_MADD(xsnmaddasp, 1, float64, f64, NMADD_FLGS, 1, 1, 1)
+VSX_MADD(xsnmaddmsp, 1, float64, f64, NMADD_FLGS, 0, 1, 1)
+VSX_MADD(xsnmsubasp, 1, float64, f64, NMSUB_FLGS, 1, 1, 1)
+VSX_MADD(xsnmsubmsp, 1, float64, f64, NMSUB_FLGS, 0, 1, 1)
+
+VSX_MADD(xvmaddadp, 2, float64, f64, MADD_FLGS, 1, 0, 0)
+VSX_MADD(xvmaddmdp, 2, float64, f64, MADD_FLGS, 0, 0, 0)
+VSX_MADD(xvmsubadp, 2, float64, f64, MSUB_FLGS, 1, 0, 0)
+VSX_MADD(xvmsubmdp, 2, float64, f64, MSUB_FLGS, 0, 0, 0)
+VSX_MADD(xvnmaddadp, 2, float64, f64, NMADD_FLGS, 1, 0, 0)
+VSX_MADD(xvnmaddmdp, 2, float64, f64, NMADD_FLGS, 0, 0, 0)
+VSX_MADD(xvnmsubadp, 2, float64, f64, NMSUB_FLGS, 1, 0, 0)
+VSX_MADD(xvnmsubmdp, 2, float64, f64, NMSUB_FLGS, 0, 0, 0)
+
+VSX_MADD(xvmaddasp, 4, float32, f32, MADD_FLGS, 1, 0, 0)
+VSX_MADD(xvmaddmsp, 4, float32, f32, MADD_FLGS, 0, 0, 0)
+VSX_MADD(xvmsubasp, 4, float32, f32, MSUB_FLGS, 1, 0, 0)
+VSX_MADD(xvmsubmsp, 4, float32, f32, MSUB_FLGS, 0, 0, 0)
+VSX_MADD(xvnmaddasp, 4, float32, f32, NMADD_FLGS, 1, 0, 0)
+VSX_MADD(xvnmaddmsp, 4, float32, f32, NMADD_FLGS, 0, 0, 0)
+VSX_MADD(xvnmsubasp, 4, float32, f32, NMSUB_FLGS, 1, 0, 0)
+VSX_MADD(xvnmsubmsp, 4, float32, f32, NMSUB_FLGS, 0, 0, 0)
 
 #define VSX_SCALAR_CMP(op, ordered)                                      \
 void helper_##op(CPUPPCState *env, uint32_t opcode)                      \
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 84c6ee1..655b670 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -293,6 +293,14 @@ DEF_HELPER_2(xsdivsp, void, env, i32)
 DEF_HELPER_2(xsresp, void, env, i32)
 DEF_HELPER_2(xssqrtsp, void, env, i32)
 DEF_HELPER_2(xsrsqrtesp, void, env, i32)
+DEF_HELPER_2(xsmaddasp, void, env, i32)
+DEF_HELPER_2(xsmaddmsp, void, env, i32)
+DEF_HELPER_2(xsmsubasp, void, env, i32)
+DEF_HELPER_2(xsmsubmsp, void, env, i32)
+DEF_HELPER_2(xsnmaddasp, void, env, i32)
+DEF_HELPER_2(xsnmaddmsp, void, env, i32)
+DEF_HELPER_2(xsnmsubasp, void, env, i32)
+DEF_HELPER_2(xsnmsubmsp, void, env, i32)
 
 DEF_HELPER_2(xvadddp, void, env, i32)
 DEF_HELPER_2(xvsubdp, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fcf9517..b2a610c 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7365,6 +7365,14 @@ GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsmaddasp, 0x04, 0x00, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsmaddmsp, 0x04, 0x01, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsmsubasp, 0x04, 0x02, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsmsubmsp, 0x04, 0x03, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsnmaddasp, 0x04, 0x10, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsnmaddmsp, 0x04, 0x11, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsnmsubasp, 0x04, 0x12, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xsnmsubmsp, 0x04, 0x13, 0, PPC2_VSX207)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -10179,6 +10187,14 @@ GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207),
 GEN_XX2FORM(xsresp,  0x14, 0x01, PPC2_VSX207),
 GEN_XX2FORM(xssqrtsp,  0x16, 0x00, PPC2_VSX207),
 GEN_XX2FORM(xsrsqrtesp,  0x14, 0x00, PPC2_VSX207),
+GEN_XX3FORM(xsmaddasp, 0x04, 0x00, PPC2_VSX207),
+GEN_XX3FORM(xsmaddmsp, 0x04, 0x01, PPC2_VSX207),
+GEN_XX3FORM(xsmsubasp, 0x04, 0x02, PPC2_VSX207),
+GEN_XX3FORM(xsmsubmsp, 0x04, 0x03, PPC2_VSX207),
+GEN_XX3FORM(xsnmaddasp, 0x04, 0x10, PPC2_VSX207),
+GEN_XX3FORM(xsnmaddmsp, 0x04, 0x11, PPC2_VSX207),
+GEN_XX3FORM(xsnmsubasp, 0x04, 0x12, PPC2_VSX207),
+GEN_XX3FORM(xsnmsubmsp, 0x04, 0x13, PPC2_VSX207),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 046/130] target-ppc: VSX Stage 4: Add xscvsxdsp and xscvuxdsp
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (44 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 045/130] target-ppc: VSX Stage 4: Add Scalar SP Fused Multiply-Adds Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 047/130] target-ppc: VSX Stage 4: Add xxleqv, xxlnand and xxlorc Alexander Graf
                   ` (84 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX Scalar Convert Unsigned Integer Doubleword
to Floating Point Format and Round to Single Precision (xscvuxdsp)
and VSX Scalar Convert Signed Integer Douglbeword to Floating Point
Format and Round to Single Precision (xscvsxdsp) instructions.

The existing integer to floating point conversion macro (VSX_CVT_INT_TO_FP)
is modified to support the rounding of the intermediate floating point
result to single precision.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 27 ++++++++++++++++-----------
 target-ppc/helper.h     |  2 ++
 target-ppc/translate.c  |  4 ++++
 3 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 7e5003a..1dfb3c0 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2558,7 +2558,7 @@ VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, f32[j], u32[i], i, 0)
  *   jdef  - definition of the j index (i or 2*i)
  *   sfprf - set FPRF
  */
-#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, jdef, sfprf)  \
+#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, jdef, sfprf, r2sp) \
 void helper_##op(CPUPPCState *env, uint32_t opcode)                     \
 {                                                                       \
     ppc_vsr_t xt, xb;                                                   \
@@ -2570,6 +2570,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                     \
     for (i = 0; i < nels; i++) {                                        \
         int j = jdef;                                                   \
         xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status);             \
+        if (r2sp) {                                                     \
+            xt.tfld = helper_frsp(env, xt.tfld);                        \
+        }                                                               \
         if (sfprf) {                                                    \
             helper_compute_fprf(env, xt.tfld, sfprf);                   \
         }                                                               \
@@ -2579,20 +2582,22 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                     \
     helper_float_check_status(env);                                     \
 }
 
-VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, u64[j], f64[i], i, 1)
-VSX_CVT_INT_TO_FP(xscvuxddp, 1, uint64, float64, u64[j], f64[i], i, 1)
-VSX_CVT_INT_TO_FP(xvcvsxddp, 2, int64, float64, u64[j], f64[i], i, 0)
-VSX_CVT_INT_TO_FP(xvcvuxddp, 2, uint64, float64, u64[j], f64[i], i, 0)
+VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, u64[j], f64[i], i, 1, 0)
+VSX_CVT_INT_TO_FP(xscvuxddp, 1, uint64, float64, u64[j], f64[i], i, 1, 0)
+VSX_CVT_INT_TO_FP(xscvsxdsp, 1, int64, float64, u64[j], f64[i], i, 1, 1)
+VSX_CVT_INT_TO_FP(xscvuxdsp, 1, uint64, float64, u64[j], f64[i], i, 1, 1)
+VSX_CVT_INT_TO_FP(xvcvsxddp, 2, int64, float64, u64[j], f64[i], i, 0, 0)
+VSX_CVT_INT_TO_FP(xvcvuxddp, 2, uint64, float64, u64[j], f64[i], i, 0, 0)
 VSX_CVT_INT_TO_FP(xvcvsxwdp, 2, int32, float64, u32[j], f64[i], \
-                  2*i + JOFFSET, 0)
+                  2*i + JOFFSET, 0, 0)
 VSX_CVT_INT_TO_FP(xvcvuxwdp, 2, uint64, float64, u32[j], f64[i], \
-                  2*i + JOFFSET, 0)
+                  2*i + JOFFSET, 0, 0)
 VSX_CVT_INT_TO_FP(xvcvsxdsp, 2, int64, float32, u64[i], f32[j], \
-                  2*i + JOFFSET, 0)
+                  2*i + JOFFSET, 0, 0)
 VSX_CVT_INT_TO_FP(xvcvuxdsp, 2, uint64, float32, u64[i], f32[j], \
-                  2*i + JOFFSET, 0)
-VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, u32[j], f32[i], i, 0)
-VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, u32[j], f32[i], i, 0)
+                  2*i + JOFFSET, 0, 0)
+VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, u32[j], f32[i], i, 0, 0)
+VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, u32[j], f32[i], i, 0, 0)
 
 /* For "use current rounding mode", define a value that will not be one of
  * the existing rounding model enums.
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 655b670..6250eba 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -279,6 +279,8 @@ DEF_HELPER_2(xscvdpsxws, void, env, i32)
 DEF_HELPER_2(xscvdpuxds, void, env, i32)
 DEF_HELPER_2(xscvdpuxws, void, env, i32)
 DEF_HELPER_2(xscvsxddp, void, env, i32)
+DEF_HELPER_2(xscvuxdsp, void, env, i32)
+DEF_HELPER_2(xscvsxdsp, void, env, i32)
 DEF_HELPER_2(xscvuxddp, void, env, i32)
 DEF_HELPER_2(xsrdpi, void, env, i32)
 DEF_HELPER_2(xsrdpic, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index b2a610c..61271e1 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7373,6 +7373,8 @@ GEN_VSX_HELPER_2(xsnmaddasp, 0x04, 0x10, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsnmaddmsp, 0x04, 0x11, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsnmsubasp, 0x04, 0x12, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xsnmsubmsp, 0x04, 0x13, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xscvsxdsp, 0x10, 0x13, 0, PPC2_VSX207)
+GEN_VSX_HELPER_2(xscvuxdsp, 0x10, 0x12, 0, PPC2_VSX207)
 
 GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
@@ -10195,6 +10197,8 @@ GEN_XX3FORM(xsnmaddasp, 0x04, 0x10, PPC2_VSX207),
 GEN_XX3FORM(xsnmaddmsp, 0x04, 0x11, PPC2_VSX207),
 GEN_XX3FORM(xsnmsubasp, 0x04, 0x12, PPC2_VSX207),
 GEN_XX3FORM(xsnmsubmsp, 0x04, 0x13, PPC2_VSX207),
+GEN_XX2FORM(xscvsxdsp, 0x10, 0x13, PPC2_VSX207),
+GEN_XX2FORM(xscvuxdsp, 0x10, 0x12, PPC2_VSX207),
 
 GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
 GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 047/130] target-ppc: VSX Stage 4: Add xxleqv, xxlnand and xxlorc
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (45 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 046/130] target-ppc: VSX Stage 4: Add xscvsxdsp and xscvuxdsp Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 048/130] target-ppc: Move To/From VSR Instructions Alexander Graf
                   ` (83 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patchs adds the VSX Logical instructions that are new with
ISA V2.07:

  - VSX Logical Equivalence (xxleqv)
  - VSX Logical NAND (xxlnand)
  - VSX Logical ORC (xxlorc)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 61271e1..19b6756 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7468,6 +7468,9 @@ VSX_LOGICAL(xxlandc, tcg_gen_andc_i64)
 VSX_LOGICAL(xxlor, tcg_gen_or_i64)
 VSX_LOGICAL(xxlxor, tcg_gen_xor_i64)
 VSX_LOGICAL(xxlnor, tcg_gen_nor_i64)
+VSX_LOGICAL(xxleqv, tcg_gen_eqv_i64)
+VSX_LOGICAL(xxlnand, tcg_gen_nand_i64)
+VSX_LOGICAL(xxlorc, tcg_gen_orc_i64)
 
 #define VSX_XXMRG(name, high)                               \
 static void glue(gen_, name)(DisasContext * ctx)            \
@@ -10283,6 +10286,9 @@ VSX_LOGICAL(xxlandc, 0x8, 0x11, PPC2_VSX),
 VSX_LOGICAL(xxlor, 0x8, 0x12, PPC2_VSX),
 VSX_LOGICAL(xxlxor, 0x8, 0x13, PPC2_VSX),
 VSX_LOGICAL(xxlnor, 0x8, 0x14, PPC2_VSX),
+VSX_LOGICAL(xxleqv, 0x8, 0x17, PPC2_VSX207),
+VSX_LOGICAL(xxlnand, 0x8, 0x16, PPC2_VSX207),
+VSX_LOGICAL(xxlorc, 0x8, 0x15, PPC2_VSX207),
 GEN_XX3FORM(xxmrghw, 0x08, 0x02, PPC2_VSX),
 GEN_XX3FORM(xxmrglw, 0x08, 0x06, PPC2_VSX),
 GEN_XX2FORM(xxspltw, 0x08, 0x0A, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 048/130] target-ppc: Move To/From VSR Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (46 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 047/130] target-ppc: VSX Stage 4: Add xxleqv, xxlnand and xxlorc Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 049/130] target-ppc: Floating Merge Word Instructions Alexander Graf
                   ` (82 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Move To VSR instructions (mfvsrd, mfvsrwz)
and Move From VSR instructions (mtvsrd, mtvsrwa, mtvsrwz).  These
instructions are unusual in that they are considered a floating
point instruction if the indexed VSR is in the first half of the
array (0-31) but they are considered vector instructions if the
indexed VSR is in the second half of the array (32-63).

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 19b6756..bc608ee 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7175,6 +7175,57 @@ static void gen_stxvw4x(DisasContext *ctx)
     tcg_temp_free_i64(tmp);
 }
 
+#define MV_VSRW(name, tcgop1, tcgop2, target, source)           \
+static void gen_##name(DisasContext *ctx)                       \
+{                                                               \
+    if (xS(ctx->opcode) < 32) {                                 \
+        if (unlikely(!ctx->fpu_enabled)) {                      \
+            gen_exception(ctx, POWERPC_EXCP_FPU);               \
+            return;                                             \
+        }                                                       \
+    } else {                                                    \
+        if (unlikely(!ctx->altivec_enabled)) {                  \
+            gen_exception(ctx, POWERPC_EXCP_VPU);               \
+            return;                                             \
+        }                                                       \
+    }                                                           \
+    TCGv_i64 tmp = tcg_temp_new_i64();                          \
+    tcg_gen_##tcgop1(tmp, source);                              \
+    tcg_gen_##tcgop2(target, tmp);                              \
+    tcg_temp_free_i64(tmp);                                     \
+}
+
+
+MV_VSRW(mfvsrwz, ext32u_i64, trunc_i64_tl, cpu_gpr[rA(ctx->opcode)], \
+        cpu_vsrh(xS(ctx->opcode)))
+MV_VSRW(mtvsrwa, extu_tl_i64, ext32s_i64, cpu_vsrh(xT(ctx->opcode)), \
+        cpu_gpr[rA(ctx->opcode)])
+MV_VSRW(mtvsrwz, extu_tl_i64, ext32u_i64, cpu_vsrh(xT(ctx->opcode)), \
+        cpu_gpr[rA(ctx->opcode)])
+
+#if defined(TARGET_PPC64)
+#define MV_VSRD(name, target, source)                           \
+static void gen_##name(DisasContext *ctx)                       \
+{                                                               \
+    if (xS(ctx->opcode) < 32) {                                 \
+        if (unlikely(!ctx->fpu_enabled)) {                      \
+            gen_exception(ctx, POWERPC_EXCP_FPU);               \
+            return;                                             \
+        }                                                       \
+    } else {                                                    \
+        if (unlikely(!ctx->altivec_enabled)) {                  \
+            gen_exception(ctx, POWERPC_EXCP_VPU);               \
+            return;                                             \
+        }                                                       \
+    }                                                           \
+    tcg_gen_mov_i64(target, source);                            \
+}
+
+MV_VSRD(mfvsrd, cpu_gpr[rA(ctx->opcode)], cpu_vsrh(xS(ctx->opcode)))
+MV_VSRD(mtvsrd, cpu_vsrh(xT(ctx->opcode)), cpu_gpr[rA(ctx->opcode)])
+
+#endif
+
 static void gen_xxpermdi(DisasContext *ctx)
 {
     if (unlikely(!ctx->vsx_enabled)) {
@@ -10094,6 +10145,14 @@ GEN_HANDLER_E(stxsspx, 0x1F, 0xC, 0x14, 0, PPC_NONE, PPC2_VSX207),
 GEN_HANDLER_E(stxvd2x, 0x1F, 0xC, 0x1E, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(stxvw4x, 0x1F, 0xC, 0x1C, 0, PPC_NONE, PPC2_VSX),
 
+GEN_HANDLER_E(mfvsrwz, 0x1F, 0x13, 0x03, 0x0000F800, PPC_NONE, PPC2_VSX207),
+GEN_HANDLER_E(mtvsrwa, 0x1F, 0x13, 0x06, 0x0000F800, PPC_NONE, PPC2_VSX207),
+GEN_HANDLER_E(mtvsrwz, 0x1F, 0x13, 0x07, 0x0000F800, PPC_NONE, PPC2_VSX207),
+#if defined(TARGET_PPC64)
+GEN_HANDLER_E(mfvsrd, 0x1F, 0x13, 0x01, 0x0000F800, PPC_NONE, PPC2_VSX207),
+GEN_HANDLER_E(mtvsrd, 0x1F, 0x13, 0x05, 0x0000F800, PPC_NONE, PPC2_VSX207),
+#endif
+
 #undef GEN_XX2FORM
 #define GEN_XX2FORM(name, opc2, opc3, fl2)                           \
 GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 049/130] target-ppc: Floating Merge Word Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (47 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 048/130] target-ppc: Move To/From VSR Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 050/130] target-ppc: Scalar Round to Single Precision Alexander Graf
                   ` (81 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Floating Merge Even Word (fmrgew) and Floating
Merge Odd Word (fmrgow) instructions.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index bc608ee..c6a357a 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -2294,6 +2294,32 @@ static void gen_fcpsgn(DisasContext *ctx)
     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
 }
 
+static void gen_fmrgew(DisasContext *ctx)
+{
+    TCGv_i64 b0;
+    if (unlikely(!ctx->fpu_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_FPU);
+        return;
+    }
+    b0 = tcg_temp_new_i64();
+    tcg_gen_shri_i64(b0, cpu_fpr[rB(ctx->opcode)], 32);
+    tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
+                        b0, 0, 32);
+    tcg_temp_free_i64(b0);
+}
+
+static void gen_fmrgow(DisasContext *ctx)
+{
+    if (unlikely(!ctx->fpu_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_FPU);
+        return;
+    }
+    tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)],
+                        cpu_fpr[rB(ctx->opcode)],
+                        cpu_fpr[rA(ctx->opcode)],
+                        32, 32);
+}
+
 /***                  Floating-Point status & ctrl register                ***/
 
 /* mcrfs */
@@ -9414,6 +9440,8 @@ GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
 GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT),
 GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT),
 GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205),
+GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207),
+GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207),
 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
 GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 050/130] target-ppc: Scalar Round to Single Precision
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (48 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 049/130] target-ppc: Floating Merge Word Instructions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 051/130] target-ppc: Scalar Non-Signalling Conversions Alexander Graf
                   ` (80 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the VSX Scalar Round to Single Precision (xsrsp)
instruction.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 11 +++++++++++
 target-ppc/helper.h     |  1 +
 target-ppc/translate.c  | 17 +++++++++++++++++
 3 files changed, 29 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 1dfb3c0..c35135e 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2666,3 +2666,14 @@ VSX_ROUND(xvrspic, 4, float32, f32, FLOAT_ROUND_CURRENT, 0)
 VSX_ROUND(xvrspim, 4, float32, f32, float_round_down, 0)
 VSX_ROUND(xvrspip, 4, float32, f32, float_round_up, 0)
 VSX_ROUND(xvrspiz, 4, float32, f32, float_round_to_zero, 0)
+
+uint64_t helper_xsrsp(CPUPPCState *env, uint64_t xb)
+{
+    helper_reset_fpstatus(env);
+
+    uint64_t xt = helper_frsp(env, xb);
+
+    helper_compute_fprf(env, xt, 1);
+    helper_float_check_status(env);
+    return xt;
+}
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 6250eba..1654589 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -293,6 +293,7 @@ DEF_HELPER_2(xssubsp, void, env, i32)
 DEF_HELPER_2(xsmulsp, void, env, i32)
 DEF_HELPER_2(xsdivsp, void, env, i32)
 DEF_HELPER_2(xsresp, void, env, i32)
+DEF_HELPER_2(xsrsp, i64, env, i64)
 DEF_HELPER_2(xssqrtsp, void, env, i32)
 DEF_HELPER_2(xsrsqrtesp, void, env, i32)
 DEF_HELPER_2(xsmaddasp, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c6a357a..c307f24 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7400,6 +7400,21 @@ static void gen_##name(DisasContext * ctx)                                    \
     tcg_temp_free_i32(opc);                                                   \
 }
 
+#define GEN_VSX_HELPER_XT_XB_ENV(name, op1, op2, inval, type) \
+static void gen_##name(DisasContext * ctx)                    \
+{                                                             \
+    if (unlikely(!ctx->vsx_enabled)) {                        \
+        gen_exception(ctx, POWERPC_EXCP_VSXU);                \
+        return;                                               \
+    }                                                         \
+    /* NIP cannot be restored if the exception comes */       \
+    /* from a helper. */                                      \
+    gen_update_nip(ctx, ctx->nip - 4);                        \
+                                                              \
+    gen_helper_##name(cpu_vsrh(xT(ctx->opcode)), cpu_env,     \
+                      cpu_vsrh(xB(ctx->opcode)));             \
+}
+
 GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
@@ -7434,6 +7449,7 @@ GEN_VSX_HELPER_2(xsrdpic, 0x16, 0x06, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsrdpim, 0x12, 0x07, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsrdpip, 0x12, 0x06, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
+GEN_VSX_HELPER_XT_XB_ENV(xsrsp, 0x12, 0x11, 0, PPC2_VSX207)
 
 GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
@@ -10277,6 +10293,7 @@ GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207),
 GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207),
 GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207),
 GEN_XX2FORM(xsresp,  0x14, 0x01, PPC2_VSX207),
+GEN_XX2FORM(xsrsp, 0x12, 0x11, PPC2_VSX207),
 GEN_XX2FORM(xssqrtsp,  0x16, 0x00, PPC2_VSX207),
 GEN_XX2FORM(xsrsqrtesp,  0x14, 0x00, PPC2_VSX207),
 GEN_XX3FORM(xsmaddasp, 0x04, 0x00, PPC2_VSX207),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 051/130] target-ppc: Scalar Non-Signalling Conversions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (49 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 050/130] target-ppc: Scalar Round to Single Precision Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:32 ` [Qemu-devel] [PULL 052/130] target-ppc: Add ISA2.06 bpermd Instruction Alexander Graf
                   ` (79 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the non-signalling scalar conversion instructions:

  - VSX Scalar Convert Single Precision to Double Precision
    Non-Signalling (xscvspdpn)
  - VSX Scalar Convert Double Precision to Single Precision
    Non-Signalling (xscvdpspn)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 16 ++++++++++++++++
 target-ppc/helper.h     |  2 ++
 target-ppc/translate.c  |  4 ++++
 3 files changed, 22 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index c35135e..dfd9b80 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -2487,6 +2487,22 @@ VSX_CVT_FP_TO_FP(xscvspdp, 1, float32, float64, f32[j], f64[i], 1)
 VSX_CVT_FP_TO_FP(xvcvdpsp, 2, float64, float32, f64[i], f32[j], 0)
 VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, f32[j], f64[i], 0)
 
+uint64_t helper_xscvdpspn(CPUPPCState *env, uint64_t xb)
+{
+    float_status tstat = env->fp_status;
+    set_float_exception_flags(0, &tstat);
+
+    return (uint64_t)float64_to_float32(xb, &tstat) << 32;
+}
+
+uint64_t helper_xscvspdpn(CPUPPCState *env, uint64_t xb)
+{
+    float_status tstat = env->fp_status;
+    set_float_exception_flags(0, &tstat);
+
+    return float32_to_float64(xb >> 32, &tstat);
+}
+
 /* VSX_CVT_FP_TO_INT - VSX floating point to integer conversion
  *   op    - instruction mnemonic
  *   nels  - number of elements (1, 2 or 4)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 1654589..0976930 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -273,7 +273,9 @@ DEF_HELPER_2(xscmpudp, void, env, i32)
 DEF_HELPER_2(xsmaxdp, void, env, i32)
 DEF_HELPER_2(xsmindp, void, env, i32)
 DEF_HELPER_2(xscvdpsp, void, env, i32)
+DEF_HELPER_2(xscvdpspn, i64, env, i64)
 DEF_HELPER_2(xscvspdp, void, env, i32)
+DEF_HELPER_2(xscvspdpn, i64, env, i64)
 DEF_HELPER_2(xscvdpsxds, void, env, i32)
 DEF_HELPER_2(xscvdpsxws, void, env, i32)
 DEF_HELPER_2(xscvdpuxds, void, env, i32)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c307f24..d57d683 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7437,7 +7437,9 @@ GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX)
+GEN_VSX_HELPER_XT_XB_ENV(xscvdpspn, 0x16, 0x10, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX)
+GEN_VSX_HELPER_XT_XB_ENV(xscvspdpn, 0x16, 0x14, 0, PPC2_VSX207)
 GEN_VSX_HELPER_2(xscvdpsxds, 0x10, 0x15, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscvdpsxws, 0x10, 0x05, 0, PPC2_VSX)
 GEN_VSX_HELPER_2(xscvdpuxds, 0x10, 0x14, 0, PPC2_VSX)
@@ -10275,7 +10277,9 @@ GEN_XX2FORM(xscmpudp,  0x0C, 0x04, PPC2_VSX),
 GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX),
 GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX),
 GEN_XX2FORM(xscvdpsp, 0x12, 0x10, PPC2_VSX),
+GEN_XX2FORM(xscvdpspn, 0x16, 0x10, PPC2_VSX207),
 GEN_XX2FORM(xscvspdp, 0x12, 0x14, PPC2_VSX),
+GEN_XX2FORM(xscvspdpn, 0x16, 0x14, PPC2_VSX207),
 GEN_XX2FORM(xscvdpsxds, 0x10, 0x15, PPC2_VSX),
 GEN_XX2FORM(xscvdpsxws, 0x10, 0x05, PPC2_VSX),
 GEN_XX2FORM(xscvdpuxds, 0x10, 0x14, PPC2_VSX),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 052/130] target-ppc: Add ISA2.06 bpermd Instruction
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (50 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 051/130] target-ppc: Scalar Non-Signalling Conversions Alexander Graf
@ 2014-03-06 23:32 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 053/130] target-ppc: Add Flag for ISA2.06 Divide Extended Instructions Alexander Graf
                   ` (78 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:32 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Bit Permute Doubleword (bpermd) instruction,
which was introduced in Power ISA 2.06 as part of the base 64-bit
architecture.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            |  4 +++-
 target-ppc/helper.h         |  1 +
 target-ppc/int_helper.c     | 20 ++++++++++++++++++++
 target-ppc/translate.c      | 10 ++++++++++
 target-ppc/translate_init.c | 11 +++++++----
 5 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index c7bbbe3..74ff4c6 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1877,9 +1877,11 @@ enum {
     PPC2_ISA205        = 0x0000000000000020ULL,
     /* VSX additions in ISA 2.07                                             */
     PPC2_VSX207        = 0x0000000000000040ULL,
+    /* ISA 2.06B bpermd                                                      */
+    PPC2_PERM_ISA206   = 0x0000000000000080ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
-                        PPC2_ISA205 | PPC2_VSX207)
+                        PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 0976930..a7833db 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -41,6 +41,7 @@ DEF_HELPER_3(sraw, tl, env, tl, tl)
 #if defined(TARGET_PPC64)
 DEF_HELPER_FLAGS_1(cntlzd, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(popcntd, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_2(bpermd, TCG_CALL_NO_RWG_SE, i64, i64, i64)
 DEF_HELPER_3(srad, tl, env, tl, tl)
 #endif
 
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index e50bdd2..0e7afb3 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -53,6 +53,26 @@ target_ulong helper_cntlzd(target_ulong t)
 }
 #endif
 
+#if defined(TARGET_PPC64)
+
+uint64_t helper_bpermd(uint64_t rs, uint64_t rb)
+{
+    int i;
+    uint64_t ra = 0;
+
+    for (i = 0; i < 8; i++) {
+        int index = (rs >> (i*8)) & 0xFF;
+        if (index < 64) {
+            if (rb & (1ull << (63-index))) {
+                ra |= 1 << i;
+            }
+        }
+    }
+    return ra;
+}
+
+#endif
+
 target_ulong helper_cmpb(target_ulong rs, target_ulong rb)
 {
     target_ulong mask = 0xff;
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index d57d683..f00384b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1525,6 +1525,15 @@ static void gen_prtyd(DisasContext *ctx)
 #endif
 
 #if defined(TARGET_PPC64)
+/* bpermd */
+static void gen_bpermd(DisasContext *ctx)
+{
+    gen_helper_bpermd(cpu_gpr[rA(ctx->opcode)],
+                      cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+}
+#endif
+
+#if defined(TARGET_PPC64)
 /* extsw & extsw. */
 GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
 
@@ -9433,6 +9442,7 @@ GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
 GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
 GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
 GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205),
+GEN_HANDLER_E(bpermd, 0x1F, 0x1C, 0x07, 0x00000001, PPC_NONE, PPC2_PERM_ISA206),
 #endif
 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 60ec9cd..53fa424 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -4722,7 +4722,7 @@ POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
                        PPC_FLOAT_STFIWX | PPC_WAIT |
                        PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
                        PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
-    pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
+    pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206;
     pcc->msr_mask = 0x000000009402FB36ULL;
     pcc->mmu_model = POWERPC_MMU_BOOKE206;
     pcc->excp_model = POWERPC_EXCP_BOOKE;
@@ -7068,7 +7068,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                        PPC_64B | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
-    pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205;
+    pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
+                        PPC2_PERM_ISA206;
     pcc->msr_mask = 0x800000000284FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7106,7 +7107,8 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
                        PPC_64B | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
-    pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205;
+    pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
+                        PPC2_PERM_ISA206;
     pcc->msr_mask = 0x800000000204FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7144,7 +7146,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_64B | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
-    pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX;
+    pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
+                        PPC2_PERM_ISA206;
     pcc->msr_mask = 0x800000000284FF36ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 053/130] target-ppc: Add Flag for ISA2.06 Divide Extended Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (51 preceding siblings ...)
  2014-03-06 23:32 ` [Qemu-devel] [PULL 052/130] target-ppc: Add ISA2.06 bpermd Instruction Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 054/130] target-ppc: Add ISA2.06 divdeu[o] Instructions Alexander Graf
                   ` (77 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds a flag for the Divide Extended instructions that
were introduced in Power ISA V2.06B.  The flag is added to the
Power7 and Power8 models.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            | 5 ++++-
 target-ppc/translate_init.c | 6 +++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 74ff4c6..ab900a4 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1879,9 +1879,12 @@ enum {
     PPC2_VSX207        = 0x0000000000000040ULL,
     /* ISA 2.06B bpermd                                                      */
     PPC2_PERM_ISA206   = 0x0000000000000080ULL,
+    /* ISA 2.06B divide extended variants                                    */
+    PPC2_DIVE_ISA206   = 0x0000000000000100ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
-                        PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206)
+                        PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
+                        PPC2_DIVE_ISA206)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 53fa424..76f326d 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7069,7 +7069,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
-                        PPC2_PERM_ISA206;
+                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206;
     pcc->msr_mask = 0x800000000284FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7108,7 +7108,7 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
-                        PPC2_PERM_ISA206;
+                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206;
     pcc->msr_mask = 0x800000000204FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7147,7 +7147,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
-                        PPC2_PERM_ISA206;
+                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206;
     pcc->msr_mask = 0x800000000284FF36ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 054/130] target-ppc: Add ISA2.06 divdeu[o] Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (52 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 053/130] target-ppc: Add Flag for ISA2.06 Divide Extended Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 055/130] target-ppc: Add ISA2.06 divde[o] Instructions Alexander Graf
                   ` (76 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Divide Doubleword Extended Unsigned
instructions.  This instruction requires dividing a 128-bit
value by a 64 bit value.  Since 128 bit integer division is
not supported in TCG, a helper is used.  An architecture
independent 128-bit division routine is added to host-utils.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
[agraf: use ||]
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 include/qemu/host-utils.h | 14 ++++++++++++++
 target-ppc/helper.h       |  1 +
 target-ppc/int_helper.c   | 27 +++++++++++++++++++++++++++
 target-ppc/translate.c    | 21 +++++++++++++++++++++
 util/host-utils.c         | 38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 101 insertions(+)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 285c5fb..402b53f 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -44,9 +44,23 @@ static inline void muls64(uint64_t *plow, uint64_t *phigh,
     *plow = r;
     *phigh = r >> 64;
 }
+
+static inline int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+{
+    if (divisor == 0) {
+        return 1;
+    } else {
+        __uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
+        __uint128_t result = dividend / divisor;
+        *plow = result;
+        *phigh = dividend % divisor;
+        return result > UINT64_MAX;
+    }
+}
 #else
 void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
 void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
+int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
 #endif
 
 /**
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index a7833db..9865e17 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -31,6 +31,7 @@ DEF_HELPER_5(lscbx, tl, env, tl, i32, i32, i32)
 
 #if defined(TARGET_PPC64)
 DEF_HELPER_3(mulldo, i64, env, i64, i64)
+DEF_HELPER_4(divdeu, i64, env, i64, i64, i32)
 #endif
 
 DEF_HELPER_FLAGS_1(cntlzw, TCG_CALL_NO_RWG_SE, tl, tl)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 0e7afb3..6f3d8fd 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -41,6 +41,33 @@ uint64_t helper_mulldo(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
 }
 #endif
 
+#if defined(TARGET_PPC64)
+
+uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, uint64_t rb, uint32_t oe)
+{
+    uint64_t rt = 0;
+    int overflow = 0;
+
+    overflow = divu128(&rt, &ra, rb);
+
+    if (unlikely(overflow)) {
+        rt = 0; /* Undefined */
+    }
+
+    if (oe) {
+        if (unlikely(overflow)) {
+            env->so = env->ov = 1;
+        } else {
+            env->ov = 0;
+        }
+    }
+
+    return rt;
+}
+
+#endif
+
+
 target_ulong helper_cntlzw(target_ulong t)
 {
     return clz32(t);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f00384b..55f259b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -984,6 +984,20 @@ GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
 /* divw  divw.  divwo  divwo.   */
 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
+
+/* div[wd]eu[o][.] */
+#define GEN_DIVE(name, hlpr, compute_ov)                                      \
+static void gen_##name(DisasContext *ctx)                                     \
+{                                                                             \
+    TCGv_i32 t0 = tcg_const_i32(compute_ov);                                  \
+    gen_helper_##hlpr(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
+                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0); \
+    tcg_temp_free_i32(t0);                                                    \
+    if (unlikely(Rc(ctx->opcode) != 0)) {                                     \
+        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
+    }                                                                         \
+}
+
 #if defined(TARGET_PPC64)
 static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
                                      TCGv arg2, int sign, int compute_ov)
@@ -1032,6 +1046,10 @@ GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
 /* divw  divw.  divwo  divwo.   */
 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
+
+GEN_DIVE(divdeu, divdeu, 0);
+GEN_DIVE(divdeuo, divdeu, 1);
+
 #endif
 
 /* mulhw  mulhw. */
@@ -9707,6 +9725,9 @@ GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
 GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
 GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
 
+GEN_HANDLER_E(divdeu, 0x1F, 0x09, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
+GEN_HANDLER_E(divdeuo, 0x1F, 0x09, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
+
 #undef GEN_INT_ARITH_MUL_HELPER
 #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
diff --git a/util/host-utils.c b/util/host-utils.c
index f0784d6..37c1706 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -86,4 +86,42 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a, int64_t b)
     }
     *phigh = rh;
 }
+
+/* Unsigned 128x64 division.  Returns 1 if overflow (divide by zero or */
+/* quotient exceeds 64 bits).  Otherwise returns quotient via plow and */
+/* remainder via phigh. */
+int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
+{
+    uint64_t dhi = *phigh;
+    uint64_t dlo = *plow;
+    unsigned i;
+    uint64_t carry = 0;
+
+    if (divisor == 0) {
+        return 1;
+    } else if (dhi == 0) {
+        *plow  = dlo / divisor;
+        *phigh = dlo % divisor;
+        return 0;
+    } else if (dhi > divisor) {
+        return 1;
+    } else {
+
+        for (i = 0; i < 64; i++) {
+            carry = dhi >> 63;
+            dhi = (dhi << 1) | (dlo >> 63);
+            if (carry || (dhi >= divisor)) {
+                dhi -= divisor;
+                carry = 1;
+            } else {
+                carry = 0;
+            }
+            dlo = (dlo << 1) | carry;
+        }
+
+        *plow = dlo;
+        *phigh = dhi;
+        return 0;
+    }
+}
 #endif /* !CONFIG_INT128 */
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 055/130] target-ppc: Add ISA2.06 divde[o] Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (53 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 054/130] target-ppc: Add ISA2.06 divdeu[o] Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 056/130] target-ppc: Add ISA 2.06 divweu[o] Instructions Alexander Graf
                   ` (75 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Divide Doubleword Extended instructions.
The implementation builds on the unsigned helper provided in
the previous patch.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 include/qemu/host-utils.h | 14 ++++++++++++++
 target-ppc/helper.h       |  1 +
 target-ppc/int_helper.c   | 23 +++++++++++++++++++++++
 target-ppc/translate.c    |  5 ++++-
 util/host-utils.c         | 37 +++++++++++++++++++++++++++++++++++++
 5 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 402b53f..d4f21c9 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -57,10 +57,24 @@ static inline int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
         return result > UINT64_MAX;
     }
 }
+
+static inline int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+{
+    if (divisor == 0) {
+        return 1;
+    } else {
+        __int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
+        __int128_t result = dividend / divisor;
+        *plow = result;
+        *phigh = dividend % divisor;
+        return result != *plow;
+    }
+}
 #else
 void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
 void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
 int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
+int divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
 #endif
 
 /**
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 9865e17..a09a618 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -32,6 +32,7 @@ DEF_HELPER_5(lscbx, tl, env, tl, i32, i32, i32)
 #if defined(TARGET_PPC64)
 DEF_HELPER_3(mulldo, i64, env, i64, i64)
 DEF_HELPER_4(divdeu, i64, env, i64, i64, i32)
+DEF_HELPER_4(divde, i64, env, i64, i64, i32)
 #endif
 
 DEF_HELPER_FLAGS_1(cntlzw, TCG_CALL_NO_RWG_SE, tl, tl)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 6f3d8fd..920dba7 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -65,6 +65,29 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, uint64_t rb, uint32_t oe)
     return rt;
 }
 
+uint64_t helper_divde(CPUPPCState *env, uint64_t rau, uint64_t rbu, uint32_t oe)
+{
+    int64_t rt = 0;
+    int64_t ra = (int64_t)rau;
+    int64_t rb = (int64_t)rbu;
+    int overflow = divs128(&rt, &ra, rb);
+
+    if (unlikely(overflow)) {
+        rt = 0; /* Undefined */
+    }
+
+    if (oe) {
+
+        if (unlikely(overflow)) {
+            env->so = env->ov = 1;
+        } else {
+            env->ov = 0;
+        }
+    }
+
+    return rt;
+}
+
 #endif
 
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 55f259b..7751b29 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1049,7 +1049,8 @@ GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
 
 GEN_DIVE(divdeu, divdeu, 0);
 GEN_DIVE(divdeuo, divdeu, 1);
-
+GEN_DIVE(divde, divde, 0);
+GEN_DIVE(divdeo, divde, 1);
 #endif
 
 /* mulhw  mulhw. */
@@ -9727,6 +9728,8 @@ GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
 
 GEN_HANDLER_E(divdeu, 0x1F, 0x09, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
 GEN_HANDLER_E(divdeuo, 0x1F, 0x09, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
+GEN_HANDLER_E(divde, 0x1F, 0x09, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
+GEN_HANDLER_E(divdeo, 0x1F, 0x09, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
 
 #undef GEN_INT_ARITH_MUL_HELPER
 #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
diff --git a/util/host-utils.c b/util/host-utils.c
index 37c1706..ee57ef5 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -124,4 +124,41 @@ int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
         return 0;
     }
 }
+
+int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+{
+    int sgn_dvdnd = *phigh < 0;
+    int sgn_divsr = divisor < 0;
+    int overflow = 0;
+
+    if (sgn_dvdnd) {
+        *plow = ~(*plow);
+        *phigh = ~(*phigh);
+        if (*plow == (int64_t)-1) {
+            *plow = 0;
+            (*phigh)++;
+         } else {
+            (*plow)++;
+         }
+    }
+
+    if (sgn_divsr) {
+        divisor = 0 - divisor;
+    }
+
+    overflow = divu128((uint64_t *)plow, (uint64_t *)phigh, (uint64_t)divisor);
+
+    if (sgn_dvdnd  ^ sgn_divsr) {
+        *plow = 0 - *plow;
+    }
+
+    if (!overflow) {
+        if ((*plow < 0) ^ (sgn_dvdnd ^ sgn_divsr)) {
+            overflow = 1;
+        }
+    }
+
+    return overflow;
+}
+
 #endif /* !CONFIG_INT128 */
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 056/130] target-ppc: Add ISA 2.06 divweu[o] Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (54 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 055/130] target-ppc: Add ISA2.06 divde[o] Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 057/130] target-ppc: Add ISA 2.06 divwe[o] Instructions Alexander Graf
                   ` (74 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch addes the Unsigned Divide Word Extended instructions
which were introduced in Power ISA 2.06B.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |  1 +
 target-ppc/int_helper.c | 31 +++++++++++++++++++++++++++++++
 target-ppc/translate.c  |  5 +++++
 3 files changed, 37 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index a09a618..52e49f1 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -34,6 +34,7 @@ DEF_HELPER_3(mulldo, i64, env, i64, i64)
 DEF_HELPER_4(divdeu, i64, env, i64, i64, i32)
 DEF_HELPER_4(divde, i64, env, i64, i64, i32)
 #endif
+DEF_HELPER_4(divweu, tl, env, tl, tl, i32)
 
 DEF_HELPER_FLAGS_1(cntlzw, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(popcntb, TCG_CALL_NO_RWG_SE, tl, tl)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 920dba7..45586be 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -41,6 +41,37 @@ uint64_t helper_mulldo(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
 }
 #endif
 
+target_ulong helper_divweu(CPUPPCState *env, target_ulong ra, target_ulong rb,
+                           uint32_t oe)
+{
+    uint64_t rt = 0;
+    int overflow = 0;
+
+    uint64_t dividend = (uint64_t)ra << 32;
+    uint64_t divisor = (uint32_t)rb;
+
+    if (unlikely(divisor == 0)) {
+        overflow = 1;
+    } else {
+        rt = dividend / divisor;
+        overflow = rt > UINT32_MAX;
+    }
+
+    if (unlikely(overflow)) {
+        rt = 0; /* Undefined */
+    }
+
+    if (oe) {
+        if (unlikely(overflow)) {
+            env->so = env->ov = 1;
+        } else {
+            env->ov = 0;
+        }
+    }
+
+    return (target_ulong)rt;
+}
+
 #if defined(TARGET_PPC64)
 
 uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, uint64_t rb, uint32_t oe)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 7751b29..e361d49 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -998,6 +998,9 @@ static void gen_##name(DisasContext *ctx)                                     \
     }                                                                         \
 }
 
+GEN_DIVE(divweu, divweu, 0);
+GEN_DIVE(divweuo, divweu, 1);
+
 #if defined(TARGET_PPC64)
 static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
                                      TCGv arg2, int sign, int compute_ov)
@@ -9716,6 +9719,8 @@ GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
+GEN_HANDLER_E(divweu, 0x1F, 0x0B, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
+GEN_HANDLER_E(divweuo, 0x1F, 0x0B, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
 
 #if defined(TARGET_PPC64)
 #undef GEN_INT_ARITH_DIVD
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 057/130] target-ppc: Add ISA 2.06 divwe[o] Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (55 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 056/130] target-ppc: Add ISA 2.06 divweu[o] Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 058/130] target-ppc: Add Flag for ISA2.06 Atomic Instructions Alexander Graf
                   ` (73 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch addes the signed Divide Word Extended instructions
which were introduced in Power ISA 2.06B.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |  1 +
 target-ppc/int_helper.c | 32 ++++++++++++++++++++++++++++++++
 target-ppc/translate.c  |  4 ++++
 3 files changed, 37 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 52e49f1..cbff496 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -35,6 +35,7 @@ DEF_HELPER_4(divdeu, i64, env, i64, i64, i32)
 DEF_HELPER_4(divde, i64, env, i64, i64, i32)
 #endif
 DEF_HELPER_4(divweu, tl, env, tl, tl, i32)
+DEF_HELPER_4(divwe, tl, env, tl, tl, i32)
 
 DEF_HELPER_FLAGS_1(cntlzw, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(popcntb, TCG_CALL_NO_RWG_SE, tl, tl)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 45586be..71db3fb 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -72,6 +72,38 @@ target_ulong helper_divweu(CPUPPCState *env, target_ulong ra, target_ulong rb,
     return (target_ulong)rt;
 }
 
+target_ulong helper_divwe(CPUPPCState *env, target_ulong ra, target_ulong rb,
+                          uint32_t oe)
+{
+    int64_t rt = 0;
+    int overflow = 0;
+
+    int64_t dividend = (int64_t)ra << 32;
+    int64_t divisor = (int64_t)((int32_t)rb);
+
+    if (unlikely((divisor == 0) ||
+                 ((divisor == -1ull) && (dividend == INT64_MIN)))) {
+        overflow = 1;
+    } else {
+        rt = dividend / divisor;
+        overflow = rt != (int32_t)rt;
+    }
+
+    if (unlikely(overflow)) {
+        rt = 0; /* Undefined */
+    }
+
+    if (oe) {
+        if (unlikely(overflow)) {
+            env->so = env->ov = 1;
+        } else {
+            env->ov = 0;
+        }
+    }
+
+    return (target_ulong)rt;
+}
+
 #if defined(TARGET_PPC64)
 
 uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, uint64_t rb, uint32_t oe)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index e361d49..fed957e 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1000,6 +1000,8 @@ static void gen_##name(DisasContext *ctx)                                     \
 
 GEN_DIVE(divweu, divweu, 0);
 GEN_DIVE(divweuo, divweu, 1);
+GEN_DIVE(divwe, divwe, 0);
+GEN_DIVE(divweo, divwe, 1);
 
 #if defined(TARGET_PPC64)
 static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
@@ -9719,6 +9721,8 @@ GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
 GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
 GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
 GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
+GEN_HANDLER_E(divwe, 0x1F, 0x0B, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
+GEN_HANDLER_E(divweo, 0x1F, 0x0B, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
 GEN_HANDLER_E(divweu, 0x1F, 0x0B, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
 GEN_HANDLER_E(divweuo, 0x1F, 0x0B, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 058/130] target-ppc: Add Flag for ISA2.06 Atomic Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (56 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 057/130] target-ppc: Add ISA 2.06 divwe[o] Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 059/130] target-ppc: Add ISA2.06 lbarx, lharx Instructions Alexander Graf
                   ` (72 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds a flag for the atomic instructions introduced
in Power ISA V2.06B.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            | 5 ++++-
 target-ppc/translate_init.c | 9 ++++++---
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index ab900a4..bf2b64f 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1881,10 +1881,13 @@ enum {
     PPC2_PERM_ISA206   = 0x0000000000000080ULL,
     /* ISA 2.06B divide extended variants                                    */
     PPC2_DIVE_ISA206   = 0x0000000000000100ULL,
+    /* ISA 2.06B larx/stcx. instructions                                     */
+    PPC2_ATOMIC_ISA206 = 0x0000000000000200ULL,
+
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
-                        PPC2_DIVE_ISA206)
+                        PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 76f326d..abe0a21 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7069,7 +7069,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
-                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206;
+                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
+                        PPC2_ATOMIC_ISA206;
     pcc->msr_mask = 0x800000000284FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7108,7 +7109,8 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
-                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206;
+                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
+                        PPC2_ATOMIC_ISA206;
     pcc->msr_mask = 0x800000000204FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7147,7 +7149,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
-                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206;
+                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
+                        PPC2_ATOMIC_ISA206;
     pcc->msr_mask = 0x800000000284FF36ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 059/130] target-ppc: Add ISA2.06 lbarx, lharx Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (57 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 058/130] target-ppc: Add Flag for ISA2.06 Atomic Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 060/130] target-ppc: Add ISA 2.06 stbcx. and sthcx. Instructions Alexander Graf
                   ` (71 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the byte and halfword variants of the Load and
Reserve instructions.   Since there is much commonality among
all forms of Load and Reserve, a macro is provided and the existing
implementations of lwarx and ldarx are refactoried to use this
macro.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 50 ++++++++++++++++++++++++--------------------------
 1 file changed, 24 insertions(+), 26 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fed957e..de7de76 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3207,21 +3207,29 @@ static void gen_isync(DisasContext *ctx)
     gen_stop_exception(ctx);
 }
 
-/* lwarx */
-static void gen_lwarx(DisasContext *ctx)
-{
-    TCGv t0;
-    TCGv gpr = cpu_gpr[rD(ctx->opcode)];
-    gen_set_access_type(ctx, ACCESS_RES);
-    t0 = tcg_temp_local_new();
-    gen_addr_reg_index(ctx, t0);
-    gen_check_align(ctx, t0, 0x03);
-    gen_qemu_ld32u(ctx, gpr, t0);
-    tcg_gen_mov_tl(cpu_reserve, t0);
-    tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val));
-    tcg_temp_free(t0);
+#define LARX(name, len, loadop)                                      \
+static void gen_##name(DisasContext *ctx)                            \
+{                                                                    \
+    TCGv t0;                                                         \
+    TCGv gpr = cpu_gpr[rD(ctx->opcode)];                             \
+    gen_set_access_type(ctx, ACCESS_RES);                            \
+    t0 = tcg_temp_local_new();                                       \
+    gen_addr_reg_index(ctx, t0);                                     \
+    if ((len) > 1) {                                                 \
+        gen_check_align(ctx, t0, (len)-1);                           \
+    }                                                                \
+    gen_qemu_##loadop(ctx, gpr, t0);                                 \
+    tcg_gen_mov_tl(cpu_reserve, t0);                                 \
+    tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val)); \
+    tcg_temp_free(t0);                                               \
 }
 
+/* lwarx */
+LARX(lbarx, 1, ld8u);
+LARX(lharx, 2, ld16u);
+LARX(lwarx, 4, ld32u);
+
+
 #if defined(CONFIG_USER_ONLY)
 static void gen_conditional_store (DisasContext *ctx, TCGv EA,
                                    int reg, int size)
@@ -3268,19 +3276,7 @@ static void gen_stwcx_(DisasContext *ctx)
 
 #if defined(TARGET_PPC64)
 /* ldarx */
-static void gen_ldarx(DisasContext *ctx)
-{
-    TCGv t0;
-    TCGv gpr = cpu_gpr[rD(ctx->opcode)];
-    gen_set_access_type(ctx, ACCESS_RES);
-    t0 = tcg_temp_local_new();
-    gen_addr_reg_index(ctx, t0);
-    gen_check_align(ctx, t0, 0x07);
-    gen_qemu_ld64(ctx, gpr, t0);
-    tcg_gen_mov_tl(cpu_reserve, t0);
-    tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val));
-    tcg_temp_free(t0);
-}
+LARX(ldarx, 8, ld64);
 
 /* stdcx. */
 static void gen_stdcx_(DisasContext *ctx)
@@ -9513,6 +9509,8 @@ GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
 GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
 GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
+GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
+GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
 #if defined(TARGET_PPC64)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 060/130] target-ppc: Add ISA 2.06 stbcx. and sthcx. Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (58 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 059/130] target-ppc: Add ISA2.06 lbarx, lharx Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 061/130] target-ppc: Add Flag for ISA V2.06 Floating Point Conversion Alexander Graf
                   ` (70 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the byte and halfword variants of the Store Conditional
instructions.   A common macro is introduced and the existing implementations
of stwcx. and stdcx. are refactored to use this macro.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 91 ++++++++++++++++++++++++--------------------------
 1 file changed, 44 insertions(+), 47 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index de7de76..9014134 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3231,8 +3231,8 @@ LARX(lwarx, 4, ld32u);
 
 
 #if defined(CONFIG_USER_ONLY)
-static void gen_conditional_store (DisasContext *ctx, TCGv EA,
-                                   int reg, int size)
+static void gen_conditional_store(DisasContext *ctx, TCGv EA,
+                                  int reg, int size)
 {
     TCGv t0 = tcg_temp_new();
     uint32_t save_exception = ctx->exception;
@@ -3246,62 +3246,57 @@ static void gen_conditional_store (DisasContext *ctx, TCGv EA,
     gen_exception(ctx, POWERPC_EXCP_STCX);
     ctx->exception = save_exception;
 }
-#endif
-
-/* stwcx. */
-static void gen_stwcx_(DisasContext *ctx)
-{
-    TCGv t0;
-    gen_set_access_type(ctx, ACCESS_RES);
-    t0 = tcg_temp_local_new();
-    gen_addr_reg_index(ctx, t0);
-    gen_check_align(ctx, t0, 0x03);
-#if defined(CONFIG_USER_ONLY)
-    gen_conditional_store(ctx, t0, rS(ctx->opcode), 4);
 #else
-    {
-        int l1;
+static void gen_conditional_store(DisasContext *ctx, TCGv EA,
+                                  int reg, int size)
+{
+    int l1;
 
-        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
-        l1 = gen_new_label();
-        tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
-        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
-        gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
-        gen_set_label(l1);
-        tcg_gen_movi_tl(cpu_reserve, -1);
+    tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
+    l1 = gen_new_label();
+    tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
+    tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
+#if defined(TARGET_PPC64)
+    if (size == 8) {
+        gen_qemu_st64(ctx, cpu_gpr[reg], EA);
+    } else
+#endif
+    if (size == 4) {
+        gen_qemu_st32(ctx, cpu_gpr[reg], EA);
+    } else if (size == 2) {
+        gen_qemu_st16(ctx, cpu_gpr[reg], EA);
+    } else {
+        gen_qemu_st8(ctx, cpu_gpr[reg], EA);
     }
+    gen_set_label(l1);
+    tcg_gen_movi_tl(cpu_reserve, -1);
+}
 #endif
-    tcg_temp_free(t0);
+
+#define STCX(name, len)                                   \
+static void gen_##name(DisasContext *ctx)                 \
+{                                                         \
+    TCGv t0;                                              \
+    gen_set_access_type(ctx, ACCESS_RES);                 \
+    t0 = tcg_temp_local_new();                            \
+    gen_addr_reg_index(ctx, t0);                          \
+    if (len > 1) {                                        \
+        gen_check_align(ctx, t0, (len)-1);                \
+    }                                                     \
+    gen_conditional_store(ctx, t0, rS(ctx->opcode), len); \
+    tcg_temp_free(t0);                                    \
 }
 
+STCX(stbcx_, 1);
+STCX(sthcx_, 2);
+STCX(stwcx_, 4);
+
 #if defined(TARGET_PPC64)
 /* ldarx */
 LARX(ldarx, 8, ld64);
 
 /* stdcx. */
-static void gen_stdcx_(DisasContext *ctx)
-{
-    TCGv t0;
-    gen_set_access_type(ctx, ACCESS_RES);
-    t0 = tcg_temp_local_new();
-    gen_addr_reg_index(ctx, t0);
-    gen_check_align(ctx, t0, 0x07);
-#if defined(CONFIG_USER_ONLY)
-    gen_conditional_store(ctx, t0, rS(ctx->opcode), 8);
-#else
-    {
-        int l1;
-        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
-        l1 = gen_new_label();
-        tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
-        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
-        gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
-        gen_set_label(l1);
-        tcg_gen_movi_tl(cpu_reserve, -1);
-    }
-#endif
-    tcg_temp_free(t0);
-}
+STCX(stdcx_, 8);
 #endif /* defined(TARGET_PPC64) */
 
 /* sync */
@@ -9512,6 +9507,8 @@ GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
 GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
 GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
 GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
+GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
+GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
 #if defined(TARGET_PPC64)
 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 061/130] target-ppc: Add Flag for ISA V2.06 Floating Point Conversion
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (59 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 060/130] target-ppc: Add ISA 2.06 stbcx. and sthcx. Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 062/130] target-ppc: Add ISA2.06 Float to Integer Instructions Alexander Graf
                   ` (69 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds a flag for the floating point conversion instructions
introduced in Power ISA 2.06B.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            | 5 ++++-
 target-ppc/translate_init.c | 6 +++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index bf2b64f..1dbeb81 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1883,11 +1883,14 @@ enum {
     PPC2_DIVE_ISA206   = 0x0000000000000100ULL,
     /* ISA 2.06B larx/stcx. instructions                                     */
     PPC2_ATOMIC_ISA206 = 0x0000000000000200ULL,
+    /* ISA 2.06B floating point integer conversion                           */
+    PPC2_FP_CVT_ISA206 = 0x0000000000000400ULL,
 
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
-                        PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206)
+                        PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | \
+                        PPC2_FP_CVT_ISA206)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index abe0a21..6dd0f84 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7070,7 +7070,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
-                        PPC2_ATOMIC_ISA206;
+                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206;
     pcc->msr_mask = 0x800000000284FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7110,7 +7110,7 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
-                        PPC2_ATOMIC_ISA206;
+                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206;
     pcc->msr_mask = 0x800000000204FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7150,7 +7150,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
-                        PPC2_ATOMIC_ISA206;
+                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206;
     pcc->msr_mask = 0x800000000284FF36ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 062/130] target-ppc: Add ISA2.06 Float to Integer Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (60 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 061/130] target-ppc: Add Flag for ISA V2.06 Floating Point Conversion Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 063/130] target-ppc: Add ISA 2.06 fcfid[u][s] Instructions Alexander Graf
                   ` (68 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the four floating point to integer conversion instructions
introduced by Power ISA V2.06:

  - Floating Convert to Integer Word Unsigned (fctiwu)
  - Floating Convert to Integer Word Unsigned with Round Toward
    Zero (fctiwuz)
  - Floating Convert to Integer Doubleword Unsigned (fctidu)
  - Floating Convert to Integer Doubleword Unsigned with Round
    Toward Zero (fctiduz)

A common macro is developed to eliminate repetitious code.  Existing instructions
are also refactoried to use this macro (fctiw, fctiwz, fctid, fctidz).

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 120 +++++++++++++-----------------------------------
 target-ppc/helper.h     |   4 ++
 target-ppc/translate.c  |  12 +++++
 3 files changed, 49 insertions(+), 87 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index dfd9b80..2f9f4dc 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -600,55 +600,41 @@ uint64_t helper_fdiv(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
     return farg1.ll;
 }
 
-/* fctiw - fctiw. */
-uint64_t helper_fctiw(CPUPPCState *env, uint64_t arg)
-{
-    CPU_DoubleU farg;
-
-    farg.ll = arg;
-
-    if (unlikely(float64_is_signaling_nan(farg.d))) {
-        /* sNaN conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                        POWERPC_EXCP_FP_VXCVI, 1);
-    } else if (unlikely(float64_is_quiet_nan(farg.d) ||
-                        float64_is_infinity(farg.d))) {
-        /* qNan / infinity conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);
-    } else {
-        farg.ll = float64_to_int32(farg.d, &env->fp_status);
-        /* XXX: higher bits are not supposed to be significant.
-         *     to make tests easier, return the same as a real PowerPC 750
-         */
-        farg.ll |= 0xFFF80000ULL << 32;
-    }
-    return farg.ll;
-}
-
-/* fctiwz - fctiwz. */
-uint64_t helper_fctiwz(CPUPPCState *env, uint64_t arg)
-{
-    CPU_DoubleU farg;
 
-    farg.ll = arg;
+#define FPU_FCTI(op, cvt, nanval)                                      \
+uint64_t helper_##op(CPUPPCState *env, uint64_t arg)                   \
+{                                                                      \
+    CPU_DoubleU farg;                                                  \
+                                                                       \
+    farg.ll = arg;                                                     \
+    farg.ll = float64_to_##cvt(farg.d, &env->fp_status);               \
+                                                                       \
+    if (unlikely(env->fp_status.float_exception_flags)) {              \
+        if (float64_is_any_nan(arg)) {                                 \
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);      \
+            if (float64_is_signaling_nan(arg)) {                       \
+                fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \
+            }                                                          \
+            farg.ll = nanval;                                          \
+        } else if (env->fp_status.float_exception_flags &              \
+                   float_flag_invalid) {                               \
+            fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);      \
+        }                                                              \
+        helper_float_check_status(env);                                \
+    }                                                                  \
+    return farg.ll;                                                    \
+ }
 
-    if (unlikely(float64_is_signaling_nan(farg.d))) {
-        /* sNaN conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                        POWERPC_EXCP_FP_VXCVI, 1);
-    } else if (unlikely(float64_is_quiet_nan(farg.d) ||
-                        float64_is_infinity(farg.d))) {
-        /* qNan / infinity conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);
-    } else {
-        farg.ll = float64_to_int32_round_to_zero(farg.d, &env->fp_status);
-        /* XXX: higher bits are not supposed to be significant.
-         *     to make tests easier, return the same as a real PowerPC 750
-         */
-        farg.ll |= 0xFFF80000ULL << 32;
-    }
-    return farg.ll;
-}
+FPU_FCTI(fctiw, int32, 0x80000000)
+FPU_FCTI(fctiwz, int32_round_to_zero, 0x80000000)
+FPU_FCTI(fctiwu, uint32, 0x00000000)
+FPU_FCTI(fctiwuz, uint32_round_to_zero, 0x00000000)
+#if defined(TARGET_PPC64)
+FPU_FCTI(fctid, int64, 0x8000000000000000)
+FPU_FCTI(fctidz, int64_round_to_zero, 0x8000000000000000)
+FPU_FCTI(fctidu, uint64, 0x0000000000000000)
+FPU_FCTI(fctiduz, uint64_round_to_zero, 0x0000000000000000)
+#endif
 
 #if defined(TARGET_PPC64)
 /* fcfid - fcfid. */
@@ -660,47 +646,7 @@ uint64_t helper_fcfid(CPUPPCState *env, uint64_t arg)
     return farg.ll;
 }
 
-/* fctid - fctid. */
-uint64_t helper_fctid(CPUPPCState *env, uint64_t arg)
-{
-    CPU_DoubleU farg;
 
-    farg.ll = arg;
-
-    if (unlikely(float64_is_signaling_nan(farg.d))) {
-        /* sNaN conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                        POWERPC_EXCP_FP_VXCVI, 1);
-    } else if (unlikely(float64_is_quiet_nan(farg.d) ||
-                        float64_is_infinity(farg.d))) {
-        /* qNan / infinity conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);
-    } else {
-        farg.ll = float64_to_int64(farg.d, &env->fp_status);
-    }
-    return farg.ll;
-}
-
-/* fctidz - fctidz. */
-uint64_t helper_fctidz(CPUPPCState *env, uint64_t arg)
-{
-    CPU_DoubleU farg;
-
-    farg.ll = arg;
-
-    if (unlikely(float64_is_signaling_nan(farg.d))) {
-        /* sNaN conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                        POWERPC_EXCP_FP_VXCVI, 1);
-    } else if (unlikely(float64_is_quiet_nan(farg.d) ||
-                        float64_is_infinity(farg.d))) {
-        /* qNan / infinity conversion */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);
-    } else {
-        farg.ll = float64_to_int64_round_to_zero(farg.d, &env->fp_status);
-    }
-    return farg.ll;
-}
 
 #endif
 
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index cbff496..a32a75a 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -66,11 +66,15 @@ DEF_HELPER_4(fcmpo, void, env, i64, i64, i32)
 DEF_HELPER_4(fcmpu, void, env, i64, i64, i32)
 
 DEF_HELPER_2(fctiw, i64, env, i64)
+DEF_HELPER_2(fctiwu, i64, env, i64)
 DEF_HELPER_2(fctiwz, i64, env, i64)
+DEF_HELPER_2(fctiwuz, i64, env, i64)
 #if defined(TARGET_PPC64)
 DEF_HELPER_2(fcfid, i64, env, i64)
 DEF_HELPER_2(fctid, i64, env, i64)
+DEF_HELPER_2(fctidu, i64, env, i64)
 DEF_HELPER_2(fctidz, i64, env, i64)
+DEF_HELPER_2(fctiduz, i64, env, i64)
 #endif
 DEF_HELPER_2(frsp, i64, env, i64)
 DEF_HELPER_2(frin, i64, env, i64)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 9014134..f13cda6 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -2202,8 +2202,12 @@ GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
 /***                     Floating-Point round & convert                    ***/
 /* fctiw */
 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
+/* fctiwu */
+GEN_FLOAT_B(ctiwu, 0x0E, 0x04, 0, PPC2_FP_CVT_ISA206);
 /* fctiwz */
 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
+/* fctiwuz */
+GEN_FLOAT_B(ctiwuz, 0x0F, 0x04, 0, PPC2_FP_CVT_ISA206);
 /* frsp */
 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
 #if defined(TARGET_PPC64)
@@ -2211,8 +2215,12 @@ GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
 GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
 /* fctid */
 GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
+/* fctidu */
+GEN_FLOAT_B(ctidu, 0x0E, 0x1D, 0, PPC2_FP_CVT_ISA206);
 /* fctidz */
 GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
+/* fctidu */
+GEN_FLOAT_B(ctiduz, 0x0F, 0x1D, 0, PPC2_FP_CVT_ISA206);
 #endif
 
 /* frin */
@@ -9843,12 +9851,16 @@ GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
+GEN_HANDLER_E(fctiwu, 0x3F, 0x0E, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
+GEN_HANDLER_E(fctiwuz, 0x3F, 0x0F, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
 #if defined(TARGET_PPC64)
 GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B),
 GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B),
+GEN_HANDLER_E(fctidu, 0x3F, 0x0E, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
 GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B),
+GEN_HANDLER_E(fctiduz, 0x3F, 0x0F, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
 #endif
 GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
 GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 063/130] target-ppc: Add ISA 2.06 fcfid[u][s] Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (61 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 062/130] target-ppc: Add ISA2.06 Float to Integer Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 064/130] target-ppc: Fix and enable fri[mnpz] Alexander Graf
                   ` (67 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the fcfids, fcfidu and fcfidus instructions which
were introduced in Power ISA 2.06B.  A common macro is provided to
eliminate repetitious code, and the existing fcfid instruction is
refactored to use this macro.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 28 +++++++++++++++++++---------
 target-ppc/helper.h     |  3 +++
 target-ppc/translate.c  |  9 +++++++++
 3 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 2f9f4dc..eb56082 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -637,16 +637,26 @@ FPU_FCTI(fctiduz, uint64_round_to_zero, 0x0000000000000000)
 #endif
 
 #if defined(TARGET_PPC64)
-/* fcfid - fcfid. */
-uint64_t helper_fcfid(CPUPPCState *env, uint64_t arg)
-{
-    CPU_DoubleU farg;
-
-    farg.d = int64_to_float64(arg, &env->fp_status);
-    return farg.ll;
-}
-
 
+#define FPU_FCFI(op, cvtr, is_single)                      \
+uint64_t helper_##op(CPUPPCState *env, uint64_t arg)       \
+{                                                          \
+    CPU_DoubleU farg;                                      \
+                                                           \
+    if (is_single) {                                       \
+        float32 tmp = cvtr(arg, &env->fp_status);          \
+        farg.d = float32_to_float64(tmp, &env->fp_status); \
+    } else {                                               \
+        farg.d = cvtr(arg, &env->fp_status);               \
+    }                                                      \
+    helper_float_check_status(env);                        \
+    return farg.ll;                                        \
+}
+
+FPU_FCFI(fcfid, int64_to_float64, 0)
+FPU_FCFI(fcfids, int64_to_float32, 1)
+FPU_FCFI(fcfidu, uint64_to_float64, 0)
+FPU_FCFI(fcfidus, uint64_to_float32, 1)
 
 #endif
 
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index a32a75a..c7c915f 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -71,6 +71,9 @@ DEF_HELPER_2(fctiwz, i64, env, i64)
 DEF_HELPER_2(fctiwuz, i64, env, i64)
 #if defined(TARGET_PPC64)
 DEF_HELPER_2(fcfid, i64, env, i64)
+DEF_HELPER_2(fcfidu, i64, env, i64)
+DEF_HELPER_2(fcfids, i64, env, i64)
+DEF_HELPER_2(fcfidus, i64, env, i64)
 DEF_HELPER_2(fctid, i64, env, i64)
 DEF_HELPER_2(fctidu, i64, env, i64)
 DEF_HELPER_2(fctidz, i64, env, i64)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f13cda6..4c08fe5 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -2213,6 +2213,12 @@ GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
 #if defined(TARGET_PPC64)
 /* fcfid */
 GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
+/* fcfids */
+GEN_FLOAT_B(cfids, 0x0E, 0x1A, 0, PPC2_FP_CVT_ISA206);
+/* fcfidu */
+GEN_FLOAT_B(cfidu, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206);
+/* fcfidus */
+GEN_FLOAT_B(cfidus, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206);
 /* fctid */
 GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
 /* fctidu */
@@ -9857,6 +9863,9 @@ GEN_HANDLER_E(fctiwuz, 0x3F, 0x0F, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
 GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
 #if defined(TARGET_PPC64)
 GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B),
+GEN_HANDLER_E(fcfids, 0x3B, 0x0E, 0x1A, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
+GEN_HANDLER_E(fcfidu, 0x3F, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
+GEN_HANDLER_E(fcfidus, 0x3B, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
 GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B),
 GEN_HANDLER_E(fctidu, 0x3F, 0x0E, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
 GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 064/130] target-ppc: Fix and enable fri[mnpz]
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (62 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 063/130] target-ppc: Add ISA 2.06 fcfid[u][s] Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 065/130] target-ppc: Add Flag for Power ISA V2.06 Floating Point Test Instructions Alexander Graf
                   ` (66 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

The fri* series of instructions was introduced prior to ISA 2.06 and
is supported on Power7 and Power8 hardware.  However, the instruction
is still considered illegal in the P7 and P8 QEMU emulation models.
This patch enables these instructions for the P7 and P8 machines.

Also, the existing helper is modified to correctly handle some of
the boundary cases (NaNs and the inexact flag).

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c     | 18 +++++++++++-------
 target-ppc/translate_init.c |  3 +++
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index eb56082..87ff60f 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -669,24 +669,28 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg,
 
     if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN round */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
-                                        POWERPC_EXCP_FP_VXCVI, 1);
-    } else if (unlikely(float64_is_quiet_nan(farg.d) ||
-                        float64_is_infinity(farg.d))) {
-        /* qNan / infinity round */
-        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1);
+        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
+        farg.ll = arg | 0x0008000000000000ul;
     } else {
+        int inexact = get_float_exception_flags(&env->fp_status) &
+                      float_flag_inexact;
         set_float_rounding_mode(rounding_mode, &env->fp_status);
         farg.ll = float64_round_to_int(farg.d, &env->fp_status);
         /* Restore rounding mode from FPSCR */
         fpscr_set_rounding_mode(env);
+
+        /* fri* does not set FPSCR[XX] */
+        if (!inexact) {
+            env->fp_status.float_exception_flags &= ~float_flag_inexact;
+        }
     }
+    helper_float_check_status(env);
     return farg.ll;
 }
 
 uint64_t helper_frin(CPUPPCState *env, uint64_t arg)
 {
-    return do_fri(env, arg, float_round_nearest_even);
+    return do_fri(env, arg, float_round_ties_away);
 }
 
 uint64_t helper_friz(CPUPPCState *env, uint64_t arg)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 6dd0f84..21c56e6 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7062,6 +7062,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
                        PPC_FLOAT_STFIWX |
+                       PPC_FLOAT_EXT |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
@@ -7102,6 +7103,7 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
                        PPC_FLOAT_STFIWX |
+                       PPC_FLOAT_EXT |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
@@ -7142,6 +7144,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
                        PPC_FLOAT_STFIWX |
+                       PPC_FLOAT_EXT |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 065/130] target-ppc: Add Flag for Power ISA V2.06 Floating Point Test Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (63 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 064/130] target-ppc: Fix and enable fri[mnpz] Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 066/130] target-ppc: Add ISA 2.06 ftdiv Instruction Alexander Graf
                   ` (65 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds a flag for Floating Point Test instructions that were
introduced in Power ISA V2.06B.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            | 4 +++-
 target-ppc/translate_init.c | 9 ++++++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 1dbeb81..bb299d7 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1885,12 +1885,14 @@ enum {
     PPC2_ATOMIC_ISA206 = 0x0000000000000200ULL,
     /* ISA 2.06B floating point integer conversion                           */
     PPC2_FP_CVT_ISA206 = 0x0000000000000400ULL,
+    /* ISA 2.06B floating point test instructions                            */
+    PPC2_FP_TST_ISA206 = 0x0000000000000800ULL,
 
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
                         PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | \
-                        PPC2_FP_CVT_ISA206)
+                        PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 21c56e6..6947934 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7071,7 +7071,8 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
-                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206;
+                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
+                        PPC2_FP_TST_ISA206;
     pcc->msr_mask = 0x800000000284FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7112,7 +7113,8 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
-                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206;
+                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
+                        PPC2_FP_TST_ISA206;
     pcc->msr_mask = 0x800000000204FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
@@ -7153,7 +7155,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
-                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206;
+                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
+                        PPC2_FP_TST_ISA206;
     pcc->msr_mask = 0x800000000284FF36ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 066/130] target-ppc: Add ISA 2.06 ftdiv Instruction
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (64 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 065/130] target-ppc: Add Flag for Power ISA V2.06 Floating Point Test Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 067/130] target-ppc: Add ISA 2.06 ftsqrt Alexander Graf
                   ` (64 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Floating Point Test for Divide instruction which
was introduced in Power ISA 2.06B.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 56 ++++++++++++++++++++++++++++++++++++++++---------
 target-ppc/helper.h     |  2 ++
 target-ppc/translate.c  | 13 ++++++++++++
 3 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 87ff60f..772b135 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -50,6 +50,16 @@ static inline int isden(float64 d)
     return ((u.ll >> 52) & 0x7FF) == 0;
 }
 
+static inline int ppc_float32_get_unbiased_exp(float32 f)
+{
+    return ((f >> 23) & 0xFF) - 127;
+}
+
+static inline int ppc_float64_get_unbiased_exp(float64 f)
+{
+    return ((f >> 52) & 0x7FF) - 1023;
+}
+
 uint32_t helper_compute_fprf(CPUPPCState *env, uint64_t arg, uint32_t set_fprf)
 {
     CPU_DoubleU farg;
@@ -993,6 +1003,42 @@ uint64_t helper_fsel(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
     }
 }
 
+uint32_t helper_ftdiv(uint64_t fra, uint64_t frb)
+{
+    int fe_flag = 0;
+    int fg_flag = 0;
+
+    if (unlikely(float64_is_infinity(fra) ||
+                 float64_is_infinity(frb) ||
+                 float64_is_zero(frb))) {
+        fe_flag = 1;
+        fg_flag = 1;
+    } else {
+        int e_a = ppc_float64_get_unbiased_exp(fra);
+        int e_b = ppc_float64_get_unbiased_exp(frb);
+
+        if (unlikely(float64_is_any_nan(fra) ||
+                     float64_is_any_nan(frb))) {
+            fe_flag = 1;
+        } else if ((e_b <= -1022) || (e_b >= 1021)) {
+            fe_flag = 1;
+        } else if (!float64_is_zero(fra) &&
+                   (((e_a - e_b) >= 1023) ||
+                    ((e_a - e_b) <= -1021) ||
+                    (e_a <= -970))) {
+            fe_flag = 1;
+        }
+
+        if (unlikely(float64_is_zero_or_denormal(frb))) {
+            /* XB is not zero because of the above check and */
+            /* so must be denormalized.                      */
+            fg_flag = 1;
+        }
+    }
+
+    return 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0);
+}
+
 void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
                   uint32_t crfD)
 {
@@ -2021,16 +2067,6 @@ VSX_RSQRTE(xsrsqrtesp, 1, float64, f64, 1, 1)
 VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0, 0)
 VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0, 0)
 
-static inline int ppc_float32_get_unbiased_exp(float32 f)
-{
-    return ((f >> 23) & 0xFF) - 127;
-}
-
-static inline int ppc_float64_get_unbiased_exp(float64 f)
-{
-    return ((f >> 52) & 0x7FF) - 1023;
-}
-
 /* VSX_TDIV - VSX floating point test for divide
  *   op    - instruction mnemonic
  *   nels  - number of elements (1, 2 or 4)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index c7c915f..2fb337c 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -99,6 +99,8 @@ DEF_HELPER_2(fres, i64, env, i64)
 DEF_HELPER_2(frsqrte, i64, env, i64)
 DEF_HELPER_4(fsel, i64, env, i64, i64, i64)
 
+DEF_HELPER_FLAGS_2(ftdiv, TCG_CALL_NO_RWG_SE, i32, i64, i64)
+
 #define dh_alias_avr ptr
 #define dh_ctype_avr ppc_avr_t *
 #define dh_is_signed_avr dh_is_signed_ptr
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 4c08fe5..f372742 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -2238,6 +2238,18 @@ GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
 /* frim */
 GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
 
+static void gen_ftdiv(DisasContext *ctx)
+{
+    if (unlikely(!ctx->fpu_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_FPU);
+        return;
+    }
+    gen_helper_ftdiv(cpu_crf[crfD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
+                     cpu_fpr[rB(ctx->opcode)]);
+}
+
+
+
 /***                         Floating-Point compare                        ***/
 
 /* fcmpo */
@@ -9856,6 +9868,7 @@ GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
 GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
+GEN_HANDLER_E(ftdiv, 0x3F, 0x00, 0x04, 1, PPC_NONE, PPC2_FP_TST_ISA206),
 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
 GEN_HANDLER_E(fctiwu, 0x3F, 0x0E, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 067/130] target-ppc: Add ISA 2.06 ftsqrt
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (65 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 066/130] target-ppc: Add ISA 2.06 ftdiv Instruction Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 068/130] target-ppc: Enable frsqrtes on Power7 and Power8 Alexander Graf
                   ` (63 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Floating Point Test for Square Root instruction
which was introduced in Power ISA 2.06.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 31 +++++++++++++++++++++++++++++++
 target-ppc/helper.h     |  1 +
 target-ppc/translate.c  | 10 ++++++++++
 3 files changed, 42 insertions(+)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 772b135..4ef3e2f 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -1039,6 +1039,37 @@ uint32_t helper_ftdiv(uint64_t fra, uint64_t frb)
     return 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0);
 }
 
+uint32_t helper_ftsqrt(uint64_t frb)
+{
+    int fe_flag = 0;
+    int fg_flag = 0;
+
+    if (unlikely(float64_is_infinity(frb) || float64_is_zero(frb))) {
+        fe_flag = 1;
+        fg_flag = 1;
+    } else {
+        int e_b = ppc_float64_get_unbiased_exp(frb);
+
+        if (unlikely(float64_is_any_nan(frb))) {
+            fe_flag = 1;
+        } else if (unlikely(float64_is_zero(frb))) {
+            fe_flag = 1;
+        } else if (unlikely(float64_is_neg(frb))) {
+            fe_flag = 1;
+        } else if (!float64_is_zero(frb) && (e_b <= (-1022+52))) {
+            fe_flag = 1;
+        }
+
+        if (unlikely(float64_is_zero_or_denormal(frb))) {
+            /* XB is not zero because of the above check and */
+            /* therefore must be denormalized.               */
+            fg_flag = 1;
+        }
+    }
+
+    return 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0);
+}
+
 void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
                   uint32_t crfD)
 {
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 2fb337c..a4480e8 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -100,6 +100,7 @@ DEF_HELPER_2(frsqrte, i64, env, i64)
 DEF_HELPER_4(fsel, i64, env, i64, i64, i64)
 
 DEF_HELPER_FLAGS_2(ftdiv, TCG_CALL_NO_RWG_SE, i32, i64, i64)
+DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64)
 
 #define dh_alias_avr ptr
 #define dh_ctype_avr ppc_avr_t *
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f372742..c9aebc5 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -2248,6 +2248,15 @@ static void gen_ftdiv(DisasContext *ctx)
                      cpu_fpr[rB(ctx->opcode)]);
 }
 
+static void gen_ftsqrt(DisasContext *ctx)
+{
+    if (unlikely(!ctx->fpu_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_FPU);
+        return;
+    }
+    gen_helper_ftsqrt(cpu_crf[crfD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
+}
+
 
 
 /***                         Floating-Point compare                        ***/
@@ -9869,6 +9878,7 @@ GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
 GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
 GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
 GEN_HANDLER_E(ftdiv, 0x3F, 0x00, 0x04, 1, PPC_NONE, PPC2_FP_TST_ISA206),
+GEN_HANDLER_E(ftsqrt, 0x3F, 0x00, 0x05, 1, PPC_NONE, PPC2_FP_TST_ISA206),
 GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
 GEN_HANDLER_E(fctiwu, 0x3F, 0x0E, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
 GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 068/130] target-ppc: Enable frsqrtes on Power7 and Power8
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (66 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 067/130] target-ppc: Add ISA 2.06 ftsqrt Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 069/130] target-ppc: Add ISA2.06 lfiwzx Instruction Alexander Graf
                   ` (62 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

The frsqrtes instruction was introduced prior to ISA 2.06 and is
support on both the Power7 and Power8 processors.  However, this
instruction is handled as illegal in the current QEMU emulation
machines.  This patch enables the existing implemention of frsqrtes
in the P7 and P8 machines.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate_init.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 6947934..52a4f4f 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7061,6 +7061,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+                       PPC_FLOAT_FRSQRTES |
                        PPC_FLOAT_STFIWX |
                        PPC_FLOAT_EXT |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
@@ -7103,6 +7104,7 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
     pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+                       PPC_FLOAT_FRSQRTES |
                        PPC_FLOAT_STFIWX |
                        PPC_FLOAT_EXT |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
@@ -7145,6 +7147,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
                        PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+                       PPC_FLOAT_FRSQRTES |
                        PPC_FLOAT_STFIWX |
                        PPC_FLOAT_EXT |
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 069/130] target-ppc: Add ISA2.06 lfiwzx Instruction
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (67 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 068/130] target-ppc: Enable frsqrtes on Power7 and Power8 Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 070/130] PPC: KVM: store SLB slot number Alexander Graf
                   ` (61 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Load Floating Point as Integer Word and
Zero Indexed (lfiwzx) instruction which was introduced in
Power ISA 2.06.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c9aebc5..951f15e 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3508,6 +3508,20 @@ static void gen_lfiwax(DisasContext *ctx)
     tcg_temp_free(t0);
 }
 
+/* lfiwzx */
+static void gen_lfiwzx(DisasContext *ctx)
+{
+    TCGv EA;
+    if (unlikely(!ctx->fpu_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_FPU);
+        return;
+    }
+    gen_set_access_type(ctx, ACCESS_FLOAT);
+    EA = tcg_temp_new();
+    gen_addr_reg_index(ctx, EA);
+    gen_qemu_ld32u_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
+    tcg_temp_free(EA);
+}
 /***                         Floating-point store                          ***/
 #define GEN_STF(name, stop, opc, type)                                        \
 static void glue(gen_, name)(DisasContext *ctx)                                       \
@@ -9984,6 +9998,7 @@ GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
 GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
 GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
 GEN_HANDLER_E(lfiwax, 0x1f, 0x17, 0x1a, 0x00000001, PPC_NONE, PPC2_ISA205),
+GEN_HANDLER_E(lfiwzx, 0x1f, 0x17, 0x1b, 0x1, PPC_NONE, PPC2_FP_CVT_ISA206),
 GEN_HANDLER_E(lfdp, 0x39, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
 GEN_HANDLER_E(lfdpx, 0x1F, 0x17, 0x18, 0x00200001, PPC_NONE, PPC2_ISA205),
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 070/130] PPC: KVM: store SLB slot number
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (68 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 069/130] target-ppc: Add ISA2.06 lfiwzx Instruction Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 071/130] virtex_ml507: Add support for loading initrd images Alexander Graf
                   ` (60 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, qemu-stable, blauwirbel,
	qemu-ppc, aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

When ppc_store_slb() is called from kvm_arch_get_registers(), it stores
a SLB in CPUPPCState::slb[slot]. However it drops the slot number from
ESID so when kvm_arch_put_registers() puts SLBs back to KVM, they do not
have correct "index" field anymore. This broke migration with LPCR_AIR
enabled as now the guest is handling interrupts in virtual mode and unable
to reconstruct correct SLBs anymore.

This adds "index" field for valid SLBs when putting them to KVM.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/kvm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 7af3fe2..e4a1a35 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -820,6 +820,9 @@ int kvm_arch_put_registers(CPUState *cs, int level)
 #ifdef TARGET_PPC64
         for (i = 0; i < ARRAY_SIZE(env->slb); i++) {
             sregs.u.s.ppc64.slb[i].slbe = env->slb[i].esid;
+            if (env->slb[i].esid & SLB_ESID_V) {
+                sregs.u.s.ppc64.slb[i].slbe |= i;
+            }
             sregs.u.s.ppc64.slb[i].slbv = env->slb[i].vsid;
         }
 #endif
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 071/130] virtex_ml507: Add support for loading initrd images
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (69 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 070/130] PPC: KVM: store SLB slot number Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 072/130] PPC: KVM: suppress warnings about not supported SPRs Alexander Graf
                   ` (59 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Edgar E. Iglesias, Peter Maydell, blauwirbel, qemu-ppc, aliguori,
	aurelien

From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
[agraf: fix up stray quotes and newlines in strings]
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/virtex_ml507.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 85a0e53..ce8ea91 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -174,6 +174,19 @@ static int xilinx_load_device_tree(hwaddr addr,
     if (!fdt) {
         return 0;
     }
+
+    r = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
+                              initrd_base);
+    if (r < 0) {
+        error_report("couldn't set /chosen/linux,initrd-start");
+    }
+
+    r = qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+                              (initrd_base + initrd_size));
+    if (r < 0) {
+        error_report("couldn't set /chosen/linux,initrd-end");
+    }
+
     r = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline);
     if (r < 0)
         fprintf(stderr, "couldn't set /chosen/bootargs\n");
@@ -187,6 +200,8 @@ static void virtex_init(QEMUMachineInitArgs *args)
     const char *cpu_model = args->cpu_model;
     const char *kernel_filename = args->kernel_filename;
     const char *kernel_cmdline = args->kernel_cmdline;
+    hwaddr initrd_base = 0;
+    int initrd_size = 0;
     MemoryRegion *address_space_mem = get_system_memory();
     DeviceState *dev;
     PowerPCCPU *cpu;
@@ -259,10 +274,27 @@ static void virtex_init(QEMUMachineInitArgs *args)
 
         boot_info.ima_size = kernel_size;
 
+        /* Load initrd. */
+        if (args->initrd_filename) {
+            initrd_base = high = ROUND_UP(high, 4);
+            initrd_size = load_image_targphys(args->initrd_filename,
+                                              high, ram_size - high);
+
+            if (initrd_size < 0) {
+                error_report("couldn't load ram disk '%s'",
+                             args->initrd_filename);
+                exit(1);
+            }
+            high = ROUND_UP(high + initrd_size, 4);
+        }
+
         /* Provide a device-tree.  */
         boot_info.fdt = high + (8192 * 2);
         boot_info.fdt &= ~8191;
-        xilinx_load_device_tree(boot_info.fdt, ram_size, 0, 0, kernel_cmdline);
+
+        xilinx_load_device_tree(boot_info.fdt, ram_size,
+                                initrd_base, initrd_size,
+                                kernel_cmdline);
     }
     env->load_info = &boot_info;
 }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 072/130] PPC: KVM: suppress warnings about not supported SPRs
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (70 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 071/130] virtex_ml507: Add support for loading initrd images Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC) Alexander Graf
                   ` (58 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

PR KVM lacks support of many SPRs in set/get one register API but it does
really break PR KVM. So convert them to switchable traces for now.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/kvm.c | 7 +++----
 trace-events     | 2 ++
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index e4a1a35..33d69d2 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -36,6 +36,7 @@
 #include "hw/ppc/spapr.h"
 #include "hw/ppc/spapr_vio.h"
 #include "sysemu/watchdog.h"
+#include "trace.h"
 
 //#define DEBUG_KVM
 
@@ -480,8 +481,7 @@ static void kvm_get_one_spr(CPUState *cs, uint64_t id, int spr)
 
     ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
     if (ret != 0) {
-        fprintf(stderr, "Warning: Unable to retrieve SPR %d from KVM: %s\n",
-                spr, strerror(errno));
+        trace_kvm_failed_spr_get(spr, strerror(errno));
     } else {
         switch (id & KVM_REG_SIZE_MASK) {
         case KVM_REG_SIZE_U32:
@@ -529,8 +529,7 @@ static void kvm_put_one_spr(CPUState *cs, uint64_t id, int spr)
 
     ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
     if (ret != 0) {
-        fprintf(stderr, "Warning: Unable to set SPR %d to KVM: %s\n",
-                spr, strerror(errno));
+        trace_kvm_failed_spr_set(spr, strerror(errno));
     }
 }
 
diff --git a/trace-events b/trace-events
index d86f98c..bd9a1cf 100644
--- a/trace-events
+++ b/trace-events
@@ -1176,6 +1176,8 @@ kvm_vm_ioctl(int type, void *arg) "type 0x%x, arg %p"
 kvm_vcpu_ioctl(int cpu_index, int type, void *arg) "cpu_index %d, type 0x%x, arg %p"
 kvm_run_exit(int cpu_index, uint32_t reason) "cpu_index %d, reason %d"
 kvm_device_ioctl(int fd, int type, void *arg) "dev fd %d, type 0x%x, arg %p"
+kvm_failed_spr_set(int str, const char *msg) "Warning: Unable to set SPR %d to KVM: %s"
+kvm_failed_spr_get(int str, const char *msg) "Warning: Unable to retrieve SPR %d from KVM: %s"
 
 # memory.c
 memory_region_ops_read(void *mr, uint64_t addr, uint64_t value, unsigned size) "mr %p addr %#"PRIx64" value %#"PRIx64" size %u"
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC)
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (71 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 072/130] PPC: KVM: suppress warnings about not supported SPRs Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-09  8:02   ` Paolo Bonzini
  2014-03-14 11:23   ` Paolo Bonzini
  2014-03-06 23:33 ` [Qemu-devel] [PULL 074/130] spapr: support only ELF kernel images Alexander Graf
                   ` (57 subsequent siblings)
  130 siblings, 2 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Fabien Chouteau, blauwirbel, qemu-ppc, aliguori, aurelien

From: Fabien Chouteau <chouteau@adacore.com>

This implementation doesn't include ring priority, TCP/IP Off-Load, QoS.

Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 default-configs/ppc-softmmu.mak |   1 +
 hw/net/Makefile.objs            |   3 +
 hw/net/fsl_etsec/etsec.c        | 465 ++++++++++++++++++++++++++++
 hw/net/fsl_etsec/etsec.h        | 174 +++++++++++
 hw/net/fsl_etsec/miim.c         | 146 +++++++++
 hw/net/fsl_etsec/registers.c    | 295 ++++++++++++++++++
 hw/net/fsl_etsec/registers.h    | 320 ++++++++++++++++++++
 hw/net/fsl_etsec/rings.c        | 650 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 2054 insertions(+)
 create mode 100644 hw/net/fsl_etsec/etsec.c
 create mode 100644 hw/net/fsl_etsec/etsec.h
 create mode 100644 hw/net/fsl_etsec/miim.c
 create mode 100644 hw/net/fsl_etsec/registers.c
 create mode 100644 hw/net/fsl_etsec/registers.h
 create mode 100644 hw/net/fsl_etsec/rings.c

diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index e5f9d36..07c51ce 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -47,4 +47,5 @@ CONFIG_E500=y
 CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
 # For PReP
 CONFIG_MC146818RTC=y
+CONFIG_ETSEC=y
 CONFIG_ISA_TESTDEV=y
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 75e80c2..ea93293 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -32,3 +32,6 @@ obj-$(CONFIG_XILINX_ETHLITE) += xilinx_ethlite.o
 
 obj-$(CONFIG_VIRTIO) += virtio-net.o
 obj-y += vhost_net.o
+
+obj-$(CONFIG_ETSEC) += fsl_etsec/etsec.o fsl_etsec/registers.o \
+			fsl_etsec/rings.o fsl_etsec/miim.o
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
new file mode 100644
index 0000000..d4b4429
--- /dev/null
+++ b/hw/net/fsl_etsec/etsec.c
@@ -0,0 +1,465 @@
+/*
+ * QEMU Freescale eTSEC Emulator
+ *
+ * Copyright (c) 2011-2013 AdaCore
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * This implementation doesn't include ring priority, TCP/IP Off-Load, QoS.
+ */
+
+#include "sysemu/sysemu.h"
+#include "hw/sysbus.h"
+#include "trace.h"
+#include "hw/ptimer.h"
+#include "etsec.h"
+#include "registers.h"
+
+/* #define HEX_DUMP */
+/* #define DEBUG_REGISTER */
+
+#ifdef DEBUG_REGISTER
+static const int debug_etsec = 1;
+#else
+static const int debug_etsec;
+#endif
+
+#define DPRINTF(fmt, ...) do {                 \
+    if (debug_etsec) {                         \
+        qemu_log(fmt , ## __VA_ARGS__);        \
+    }                                          \
+    } while (0)
+
+static uint64_t etsec_read(void *opaque, hwaddr addr, unsigned size)
+{
+    eTSEC          *etsec     = opaque;
+    uint32_t        reg_index = addr / 4;
+    eTSEC_Register *reg       = NULL;
+    uint32_t        ret       = 0x0;
+
+    assert(reg_index < ETSEC_REG_NUMBER);
+
+    reg = &etsec->regs[reg_index];
+
+
+    switch (reg->access) {
+    case ACC_WO:
+        ret = 0x00000000;
+        break;
+
+    case ACC_RW:
+    case ACC_W1C:
+    case ACC_RO:
+    default:
+        ret = reg->value;
+        break;
+    }
+
+    DPRINTF("Read  0x%08x @ 0x" TARGET_FMT_plx
+            "                            : %s (%s)\n",
+            ret, addr, reg->name, reg->desc);
+
+    return ret;
+}
+
+static void write_tstat(eTSEC          *etsec,
+                        eTSEC_Register *reg,
+                        uint32_t        reg_index,
+                        uint32_t        value)
+{
+    int i = 0;
+
+    for (i = 0; i < 8; i++) {
+        /* Check THLTi flag in TSTAT */
+        if (value & (1 << (31 - i))) {
+            etsec_walk_tx_ring(etsec, i);
+        }
+    }
+
+    /* Write 1 to clear */
+    reg->value &= ~value;
+}
+
+static void write_rstat(eTSEC          *etsec,
+                        eTSEC_Register *reg,
+                        uint32_t        reg_index,
+                        uint32_t        value)
+{
+    int i = 0;
+
+    for (i = 0; i < 8; i++) {
+        /* Check QHLTi flag in RSTAT */
+        if (value & (1 << (23 - i)) && !(reg->value & (1 << (23 - i)))) {
+            etsec_walk_rx_ring(etsec, i);
+        }
+    }
+
+    /* Write 1 to clear */
+    reg->value &= ~value;
+}
+
+static void write_tbasex(eTSEC          *etsec,
+                         eTSEC_Register *reg,
+                         uint32_t        reg_index,
+                         uint32_t        value)
+{
+    reg->value = value & ~0x7;
+
+    /* Copy this value in the ring's TxBD pointer */
+    etsec->regs[TBPTR0 + (reg_index - TBASE0)].value = value & ~0x7;
+}
+
+static void write_rbasex(eTSEC          *etsec,
+                         eTSEC_Register *reg,
+                         uint32_t        reg_index,
+                         uint32_t        value)
+{
+    reg->value = value & ~0x7;
+
+    /* Copy this value in the ring's RxBD pointer */
+    etsec->regs[RBPTR0 + (reg_index - RBASE0)].value = value & ~0x7;
+}
+
+static void write_ievent(eTSEC          *etsec,
+                         eTSEC_Register *reg,
+                         uint32_t        reg_index,
+                         uint32_t        value)
+{
+    /* Write 1 to clear */
+    reg->value &= ~value;
+
+    if (!(reg->value & (IEVENT_TXF | IEVENT_TXF))) {
+        qemu_irq_lower(etsec->tx_irq);
+    }
+    if (!(reg->value & (IEVENT_RXF | IEVENT_RXF))) {
+        qemu_irq_lower(etsec->rx_irq);
+    }
+
+    if (!(reg->value & (IEVENT_MAG | IEVENT_GTSC | IEVENT_GRSC | IEVENT_TXC |
+                        IEVENT_RXC | IEVENT_BABR | IEVENT_BABT | IEVENT_LC |
+                        IEVENT_CRL | IEVENT_FGPI | IEVENT_FIR | IEVENT_FIQ |
+                        IEVENT_DPE | IEVENT_PERR | IEVENT_EBERR | IEVENT_TXE |
+                        IEVENT_XFUN | IEVENT_BSY | IEVENT_MSRO | IEVENT_MMRD |
+                        IEVENT_MMRW))) {
+        qemu_irq_lower(etsec->err_irq);
+    }
+}
+
+static void write_dmactrl(eTSEC          *etsec,
+                          eTSEC_Register *reg,
+                          uint32_t        reg_index,
+                          uint32_t        value)
+{
+    reg->value = value;
+
+    if (value & DMACTRL_GRS) {
+
+        if (etsec->rx_buffer_len != 0) {
+            /* Graceful receive stop delayed until end of frame */
+        } else {
+            /* Graceful receive stop now */
+            etsec->regs[IEVENT].value |= IEVENT_GRSC;
+            if (etsec->regs[IMASK].value & IMASK_GRSCEN) {
+                qemu_irq_raise(etsec->err_irq);
+            }
+        }
+    }
+
+    if (value & DMACTRL_GTS) {
+
+        if (etsec->tx_buffer_len != 0) {
+            /* Graceful transmit stop delayed until end of frame */
+        } else {
+            /* Graceful transmit stop now */
+            etsec->regs[IEVENT].value |= IEVENT_GTSC;
+            if (etsec->regs[IMASK].value & IMASK_GTSCEN) {
+                qemu_irq_raise(etsec->err_irq);
+            }
+        }
+    }
+
+    if (!(value & DMACTRL_WOP)) {
+        /* Start polling */
+        ptimer_stop(etsec->ptimer);
+        ptimer_set_count(etsec->ptimer, 1);
+        ptimer_run(etsec->ptimer, 1);
+    }
+}
+
+static void etsec_write(void     *opaque,
+                        hwaddr    addr,
+                        uint64_t  value,
+                        unsigned  size)
+{
+    eTSEC          *etsec     = opaque;
+    uint32_t        reg_index = addr / 4;
+    eTSEC_Register *reg       = NULL;
+    uint32_t        before    = 0x0;
+
+    assert(reg_index < ETSEC_REG_NUMBER);
+
+    reg = &etsec->regs[reg_index];
+    before = reg->value;
+
+    switch (reg_index) {
+    case IEVENT:
+        write_ievent(etsec, reg, reg_index, value);
+        break;
+
+    case DMACTRL:
+        write_dmactrl(etsec, reg, reg_index, value);
+        break;
+
+    case TSTAT:
+        write_tstat(etsec, reg, reg_index, value);
+        break;
+
+    case RSTAT:
+        write_rstat(etsec, reg, reg_index, value);
+        break;
+
+    case TBASE0 ... TBASE7:
+        write_tbasex(etsec, reg, reg_index, value);
+        break;
+
+    case RBASE0 ... RBASE7:
+        write_rbasex(etsec, reg, reg_index, value);
+        break;
+
+    case MIIMCFG ... MIIMIND:
+        etsec_write_miim(etsec, reg, reg_index, value);
+        break;
+
+    default:
+        /* Default handling */
+        switch (reg->access) {
+
+        case ACC_RW:
+        case ACC_WO:
+            reg->value = value;
+            break;
+
+        case ACC_W1C:
+            reg->value &= ~value;
+            break;
+
+        case ACC_RO:
+        default:
+            /* Read Only or Unknown register */
+            break;
+        }
+    }
+
+    DPRINTF("Write 0x%08x @ 0x" TARGET_FMT_plx
+            " val:0x%08x->0x%08x : %s (%s)\n",
+            (unsigned int)value, addr, before, reg->value,
+            reg->name, reg->desc);
+}
+
+static const MemoryRegionOps etsec_ops = {
+    .read = etsec_read,
+    .write = etsec_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+
+static void etsec_timer_hit(void *opaque)
+{
+    eTSEC *etsec = opaque;
+
+    ptimer_stop(etsec->ptimer);
+
+    if (!(etsec->regs[DMACTRL].value & DMACTRL_WOP)) {
+
+        if (!(etsec->regs[DMACTRL].value & DMACTRL_GTS)) {
+            etsec_walk_tx_ring(etsec, 0);
+        }
+        ptimer_set_count(etsec->ptimer, 1);
+        ptimer_run(etsec->ptimer, 1);
+    }
+}
+
+static void etsec_reset(DeviceState *d)
+{
+    eTSEC *etsec = ETSEC_COMMON(d);
+    int i = 0;
+    int reg_index = 0;
+
+    /* Default value for all registers */
+    for (i = 0; i < ETSEC_REG_NUMBER; i++) {
+        etsec->regs[i].name   = "Reserved";
+        etsec->regs[i].desc   = "";
+        etsec->regs[i].access = ACC_UNKNOWN;
+        etsec->regs[i].value  = 0x00000000;
+    }
+
+    /* Set-up known registers */
+    for (i = 0; eTSEC_registers_def[i].name != NULL; i++) {
+
+        reg_index = eTSEC_registers_def[i].offset / 4;
+
+        etsec->regs[reg_index].name   = eTSEC_registers_def[i].name;
+        etsec->regs[reg_index].desc   = eTSEC_registers_def[i].desc;
+        etsec->regs[reg_index].access = eTSEC_registers_def[i].access;
+        etsec->regs[reg_index].value  = eTSEC_registers_def[i].reset;
+    }
+
+    etsec->tx_buffer     = NULL;
+    etsec->tx_buffer_len = 0;
+    etsec->rx_buffer     = NULL;
+    etsec->rx_buffer_len = 0;
+
+    etsec->phy_status =
+        MII_SR_EXTENDED_CAPS    | MII_SR_LINK_STATUS   | MII_SR_AUTONEG_CAPS  |
+        MII_SR_AUTONEG_COMPLETE | MII_SR_PREAMBLE_SUPPRESS |
+        MII_SR_EXTENDED_STATUS  | MII_SR_100T2_HD_CAPS | MII_SR_100T2_FD_CAPS |
+        MII_SR_10T_HD_CAPS      | MII_SR_10T_FD_CAPS   | MII_SR_100X_HD_CAPS  |
+        MII_SR_100X_FD_CAPS     | MII_SR_100T4_CAPS;
+}
+
+static void etsec_cleanup(NetClientState *nc)
+{
+    /* qemu_log("eTSEC cleanup\n"); */
+}
+
+static int etsec_can_receive(NetClientState *nc)
+{
+    eTSEC *etsec = qemu_get_nic_opaque(nc);
+
+    return etsec->rx_buffer_len == 0;
+}
+
+static ssize_t etsec_receive(NetClientState *nc,
+                             const uint8_t  *buf,
+                             size_t          size)
+{
+    eTSEC *etsec = qemu_get_nic_opaque(nc);
+
+#if defined(HEX_DUMP)
+    fprintf(stderr, "%s receive size:%d\n", etsec->nic->nc.name, size);
+    qemu_hexdump(buf, stderr, "", size);
+#endif
+    etsec_rx_ring_write(etsec, buf, size);
+    return size;
+}
+
+
+static void etsec_set_link_status(NetClientState *nc)
+{
+    eTSEC *etsec = qemu_get_nic_opaque(nc);
+
+    etsec_miim_link_status(etsec, nc);
+}
+
+static NetClientInfo net_etsec_info = {
+    .type = NET_CLIENT_OPTIONS_KIND_NIC,
+    .size = sizeof(NICState),
+    .can_receive = etsec_can_receive,
+    .receive = etsec_receive,
+    .cleanup = etsec_cleanup,
+    .link_status_changed = etsec_set_link_status,
+};
+
+static void etsec_realize(DeviceState *dev, Error **errp)
+{
+    eTSEC        *etsec = ETSEC_COMMON(dev);
+
+    etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf,
+                              object_get_typename(OBJECT(dev)), dev->id, etsec);
+    qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);
+
+
+    etsec->bh     = qemu_bh_new(etsec_timer_hit, etsec);
+    etsec->ptimer = ptimer_init(etsec->bh);
+    ptimer_set_freq(etsec->ptimer, 100);
+}
+
+static void etsec_instance_init(Object *obj)
+{
+    eTSEC        *etsec = ETSEC_COMMON(obj);
+    SysBusDevice *sbd   = SYS_BUS_DEVICE(obj);
+
+    memory_region_init_io(&etsec->io_area, OBJECT(etsec), &etsec_ops, etsec,
+                          "eTSEC", 0x1000);
+    sysbus_init_mmio(sbd, &etsec->io_area);
+
+    sysbus_init_irq(sbd, &etsec->tx_irq);
+    sysbus_init_irq(sbd, &etsec->rx_irq);
+    sysbus_init_irq(sbd, &etsec->err_irq);
+}
+
+static Property etsec_properties[] = {
+    DEFINE_NIC_PROPERTIES(eTSEC, conf),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void etsec_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = etsec_realize;
+    dc->reset = etsec_reset;
+    dc->props = etsec_properties;
+}
+
+static TypeInfo etsec_info = {
+    .name                  = "eTSEC",
+    .parent                = TYPE_SYS_BUS_DEVICE,
+    .instance_size         = sizeof(eTSEC),
+    .class_init            = etsec_class_init,
+    .instance_init         = etsec_instance_init,
+};
+
+static void etsec_register_types(void)
+{
+    type_register_static(&etsec_info);
+}
+
+type_init(etsec_register_types)
+
+DeviceState *etsec_create(hwaddr         base,
+                          MemoryRegion * mr,
+                          NICInfo      * nd,
+                          qemu_irq       tx_irq,
+                          qemu_irq       rx_irq,
+                          qemu_irq       err_irq)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(NULL, "eTSEC");
+    qdev_set_nic_properties(dev, nd);
+
+    if (qdev_init(dev)) {
+        return NULL;
+    }
+
+    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, tx_irq);
+    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, rx_irq);
+    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, err_irq);
+
+    memory_region_add_subregion(mr, base,
+                                SYS_BUS_DEVICE(dev)->mmio[0].memory);
+
+    return dev;
+}
diff --git a/hw/net/fsl_etsec/etsec.h b/hw/net/fsl_etsec/etsec.h
new file mode 100644
index 0000000..78d2c57
--- /dev/null
+++ b/hw/net/fsl_etsec/etsec.h
@@ -0,0 +1,174 @@
+/*
+ * QEMU Freescale eTSEC Emulator
+ *
+ * Copyright (c) 2011-2013 AdaCore
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef _ETSEC_H_
+#define _ETSEC_H_
+
+#include "hw/qdev.h"
+#include "hw/sysbus.h"
+#include "net/net.h"
+#include "hw/ptimer.h"
+
+/* Buffer Descriptors */
+
+typedef struct eTSEC_rxtx_bd {
+    uint16_t flags;
+    uint16_t length;
+    uint32_t bufptr;
+} eTSEC_rxtx_bd;
+
+#define BD_WRAP       (1 << 13)
+#define BD_INTERRUPT  (1 << 12)
+#define BD_LAST       (1 << 11)
+
+#define BD_TX_READY     (1 << 15)
+#define BD_TX_PADCRC    (1 << 14)
+#define BD_TX_TC        (1 << 10)
+#define BD_TX_PREDEF    (1 << 9)
+#define BD_TX_HFELC     (1 << 7)
+#define BD_TX_CFRL      (1 << 6)
+#define BD_TX_RC_MASK   0xF
+#define BD_TX_RC_OFFSET 0x2
+#define BD_TX_TOEUN     (1 << 1)
+#define BD_TX_TR        (1 << 0)
+
+#define BD_RX_EMPTY     (1 << 15)
+#define BD_RX_RO1       (1 << 14)
+#define BD_RX_FIRST     (1 << 10)
+#define BD_RX_MISS      (1 << 8)
+#define BD_RX_BROADCAST (1 << 7)
+#define BD_RX_MULTICAST (1 << 6)
+#define BD_RX_LG        (1 << 5)
+#define BD_RX_NO        (1 << 4)
+#define BD_RX_SH        (1 << 3)
+#define BD_RX_CR        (1 << 2)
+#define BD_RX_OV        (1 << 1)
+#define BD_RX_TR        (1 << 0)
+
+/* Tx FCB flags */
+#define FCB_TX_VLN     (1 << 7)
+#define FCB_TX_IP      (1 << 6)
+#define FCB_TX_IP6     (1 << 5)
+#define FCB_TX_TUP     (1 << 4)
+#define FCB_TX_UDP     (1 << 3)
+#define FCB_TX_CIP     (1 << 2)
+#define FCB_TX_CTU     (1 << 1)
+#define FCB_TX_NPH     (1 << 0)
+
+/* PHY Status Register */
+#define MII_SR_EXTENDED_CAPS     0x0001    /* Extended register capabilities */
+#define MII_SR_JABBER_DETECT     0x0002    /* Jabber Detected */
+#define MII_SR_LINK_STATUS       0x0004    /* Link Status 1 = link */
+#define MII_SR_AUTONEG_CAPS      0x0008    /* Auto Neg Capable */
+#define MII_SR_REMOTE_FAULT      0x0010    /* Remote Fault Detect */
+#define MII_SR_AUTONEG_COMPLETE  0x0020    /* Auto Neg Complete */
+#define MII_SR_PREAMBLE_SUPPRESS 0x0040    /* Preamble may be suppressed */
+#define MII_SR_EXTENDED_STATUS   0x0100    /* Ext. status info in Reg 0x0F */
+#define MII_SR_100T2_HD_CAPS     0x0200    /* 100T2 Half Duplex Capable */
+#define MII_SR_100T2_FD_CAPS     0x0400    /* 100T2 Full Duplex Capable */
+#define MII_SR_10T_HD_CAPS       0x0800    /* 10T   Half Duplex Capable */
+#define MII_SR_10T_FD_CAPS       0x1000    /* 10T   Full Duplex Capable */
+#define MII_SR_100X_HD_CAPS      0x2000    /* 100X  Half Duplex Capable */
+#define MII_SR_100X_FD_CAPS      0x4000    /* 100X  Full Duplex Capable */
+#define MII_SR_100T4_CAPS        0x8000    /* 100T4 Capable */
+
+/* eTSEC */
+
+/* Number of register in the device */
+#define ETSEC_REG_NUMBER 1024
+
+typedef struct eTSEC_Register {
+    const char *name;
+    const char *desc;
+    uint32_t    access;
+    uint32_t    value;
+} eTSEC_Register;
+
+typedef struct eTSEC {
+    SysBusDevice  busdev;
+
+    MemoryRegion  io_area;
+
+    eTSEC_Register regs[ETSEC_REG_NUMBER];
+
+    NICState *nic;
+    NICConf   conf;
+
+    /* Tx */
+
+    uint8_t       *tx_buffer;
+    uint32_t       tx_buffer_len;
+    eTSEC_rxtx_bd  first_bd;
+
+    /* Rx */
+
+    uint8_t       *rx_buffer;
+    uint32_t       rx_buffer_len;
+    uint32_t       rx_remaining_data;
+    uint8_t        rx_first_in_frame;
+    uint8_t        rx_fcb_size;
+    eTSEC_rxtx_bd  rx_first_bd;
+    uint8_t        rx_fcb[10];
+    uint32_t       rx_padding;
+
+    /* IRQs */
+    qemu_irq     tx_irq;
+    qemu_irq     rx_irq;
+    qemu_irq     err_irq;
+
+
+    uint16_t phy_status;
+    uint16_t phy_control;
+
+    /* Polling */
+    QEMUBH *bh;
+    struct ptimer_state *ptimer;
+
+} eTSEC;
+
+#define TYPE_ETSEC_COMMON "eTSEC"
+#define ETSEC_COMMON(obj) \
+     OBJECT_CHECK(eTSEC, (obj), TYPE_ETSEC_COMMON)
+
+#define eTSEC_TRANSMIT 1
+#define eTSEC_RECEIVE  2
+
+DeviceState *etsec_create(hwaddr        base,
+                          MemoryRegion *mr,
+                          NICInfo      *nd,
+                          qemu_irq      tx_irq,
+                          qemu_irq      rx_irq,
+                          qemu_irq      err_irq);
+
+void etsec_walk_tx_ring(eTSEC *etsec, int ring_nbr);
+void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr);
+void etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size);
+
+void etsec_write_miim(eTSEC          *etsec,
+                      eTSEC_Register *reg,
+                      uint32_t        reg_index,
+                      uint32_t        value);
+
+void etsec_miim_link_status(eTSEC *etsec, NetClientState *nc);
+
+#endif /* ! _ETSEC_H_ */
diff --git a/hw/net/fsl_etsec/miim.c b/hw/net/fsl_etsec/miim.c
new file mode 100644
index 0000000..1931b74
--- /dev/null
+++ b/hw/net/fsl_etsec/miim.c
@@ -0,0 +1,146 @@
+/*
+ * QEMU Freescale eTSEC Emulator
+ *
+ * Copyright (c) 2011-2013 AdaCore
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "etsec.h"
+#include "registers.h"
+
+/* #define DEBUG_MIIM */
+
+#define MIIM_CONTROL    0
+#define MIIM_STATUS     1
+#define MIIM_PHY_ID_1   2
+#define MIIM_PHY_ID_2   3
+#define MIIM_T2_STATUS  10
+#define MIIM_EXT_STATUS 15
+
+static void miim_read_cycle(eTSEC *etsec)
+{
+    uint8_t  phy;
+    uint8_t  addr;
+    uint16_t value;
+
+    phy  = (etsec->regs[MIIMADD].value >> 8) & 0x1F;
+    (void)phy; /* Unreferenced */
+    addr = etsec->regs[MIIMADD].value & 0x1F;
+
+    switch (addr) {
+    case MIIM_CONTROL:
+        value = etsec->phy_control;
+        break;
+    case MIIM_STATUS:
+        value = etsec->phy_status;
+        break;
+    case MIIM_T2_STATUS:
+        value = 0x1800;           /* Local and remote receivers OK */
+        break;
+    default:
+        value = 0x0;
+        break;
+    };
+
+#ifdef DEBUG_MIIM
+    qemu_log("%s phy:%d addr:0x%x value:0x%x\n", __func__, phy, addr, value);
+#endif
+
+    etsec->regs[MIIMSTAT].value = value;
+}
+
+static void miim_write_cycle(eTSEC *etsec)
+{
+    uint8_t  phy;
+    uint8_t  addr;
+    uint16_t value;
+
+    phy   = (etsec->regs[MIIMADD].value >> 8) & 0x1F;
+    (void)phy; /* Unreferenced */
+    addr  = etsec->regs[MIIMADD].value & 0x1F;
+    value = etsec->regs[MIIMCON].value & 0xffff;
+
+#ifdef DEBUG_MIIM
+    qemu_log("%s phy:%d addr:0x%x value:0x%x\n", __func__, phy, addr, value);
+#endif
+
+    switch (addr) {
+    case MIIM_CONTROL:
+        etsec->phy_control = value & ~(0x8100);
+        break;
+    default:
+        break;
+    };
+}
+
+void etsec_write_miim(eTSEC          *etsec,
+                      eTSEC_Register *reg,
+                      uint32_t        reg_index,
+                      uint32_t        value)
+{
+
+    switch (reg_index) {
+
+    case MIIMCOM:
+        /* Read and scan cycle */
+
+        if ((!(reg->value & MIIMCOM_READ)) && (value & MIIMCOM_READ)) {
+            /* Read */
+            miim_read_cycle(etsec);
+        }
+        reg->value = value;
+        break;
+
+    case MIIMCON:
+        reg->value = value & 0xffff;
+        miim_write_cycle(etsec);
+        break;
+
+    default:
+        /* Default handling */
+        switch (reg->access) {
+
+        case ACC_RW:
+        case ACC_WO:
+            reg->value = value;
+            break;
+
+        case ACC_W1C:
+            reg->value &= ~value;
+            break;
+
+        case ACC_RO:
+        default:
+            /* Read Only or Unknown register */
+            break;
+        }
+    }
+
+}
+
+void etsec_miim_link_status(eTSEC *etsec, NetClientState *nc)
+{
+    /* Set link status */
+    if (nc->link_down) {
+        etsec->phy_status &= ~MII_SR_LINK_STATUS;
+    } else {
+        etsec->phy_status |= MII_SR_LINK_STATUS;
+    }
+}
diff --git a/hw/net/fsl_etsec/registers.c b/hw/net/fsl_etsec/registers.c
new file mode 100644
index 0000000..a7bbfa1
--- /dev/null
+++ b/hw/net/fsl_etsec/registers.c
@@ -0,0 +1,295 @@
+/*
+ * QEMU Freescale eTSEC Emulator
+ *
+ * Copyright (c) 2011-2013 AdaCore
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "registers.h"
+
+const eTSEC_Register_Definition eTSEC_registers_def[] = {
+{0x000, "TSEC_ID",  "Controller ID register",    ACC_RO,  0x01240000},
+{0x004, "TSEC_ID2", "Controller ID register 2",  ACC_RO,  0x003000F0},
+{0x010, "IEVENT",   "Interrupt event register",  ACC_W1C, 0x00000000},
+{0x014, "IMASK",    "Interrupt mask register",   ACC_RW,  0x00000000},
+{0x018, "EDIS",     "Error disabled register",   ACC_RW,  0x00000000},
+{0x020, "ECNTRL",   "Ethernet control register", ACC_RW,  0x00000040},
+{0x028, "PTV",      "Pause time value register", ACC_RW,  0x00000000},
+{0x02C, "DMACTRL",  "DMA control register",      ACC_RW,  0x00000000},
+{0x030, "TBIPA",    "TBI PHY address register",  ACC_RW,  0x00000000},
+
+/* eTSEC FIFO Control and Status Registers */
+
+{0x058, "FIFO_RX_ALARM",          "FIFO receive alarm start threshold register",    ACC_RW, 0x00000040},
+{0x05C, "FIFO_RX_ALARM_SHUTOFF",  "FIFO receive alarm shut-off threshold register", ACC_RW, 0x00000080},
+{0x08C, "FIFO_TX_THR",            "FIFO transmit threshold register",               ACC_RW, 0x00000080},
+{0x098, "FIFO_TX_STARVE",         "FIFO transmit starve register",                  ACC_RW, 0x00000040},
+{0x09C, "FIFO_TX_STARVE_SHUTOFF", "FIFO transmit starve shut-off register",         ACC_RW, 0x00000080},
+
+/* eTSEC Transmit Control and Status Registers */
+
+{0x100, "TCTRL",        "Transmit control register",                ACC_RW,  0x00000000},
+{0x104, "TSTAT",        "Transmit status register",                 ACC_W1C, 0x00000000},
+{0x108, "DFVLAN",       "Default VLAN control word",                ACC_RW,  0x81000000},
+{0x110, "TXIC",         "Transmit interrupt coalescing register",   ACC_RW,  0x00000000},
+{0x114, "TQUEUE",       "Transmit queue control register",          ACC_RW,  0x00008000},
+{0x140, "TR03WT",       "TxBD Rings 0-3 round-robin weightings",    ACC_RW,  0x00000000},
+{0x144, "TR47WT",       "TxBD Rings 4-7 round-robin weightings",    ACC_RW,  0x00000000},
+{0x180, "TBDBPH",       "Tx data buffer pointer high bits",         ACC_RW,  0x00000000},
+{0x184, "TBPTR0",       "TxBD pointer for ring 0",                  ACC_RW,  0x00000000},
+{0x18C, "TBPTR1",       "TxBD pointer for ring 1",                  ACC_RW,  0x00000000},
+{0x194, "TBPTR2",       "TxBD pointer for ring 2",                  ACC_RW,  0x00000000},
+{0x19C, "TBPTR3",       "TxBD pointer for ring 3",                  ACC_RW,  0x00000000},
+{0x1A4, "TBPTR4",       "TxBD pointer for ring 4",                  ACC_RW,  0x00000000},
+{0x1AC, "TBPTR5",       "TxBD pointer for ring 5",                  ACC_RW,  0x00000000},
+{0x1B4, "TBPTR6",       "TxBD pointer for ring 6",                  ACC_RW,  0x00000000},
+{0x1BC, "TBPTR7",       "TxBD pointer for ring 7",                  ACC_RW,  0x00000000},
+{0x200, "TBASEH",       "TxBD base address high bits",              ACC_RW,  0x00000000},
+{0x204, "TBASE0",       "TxBD base address of ring 0",              ACC_RW,  0x00000000},
+{0x20C, "TBASE1",       "TxBD base address of ring 1",              ACC_RW,  0x00000000},
+{0x214, "TBASE2",       "TxBD base address of ring 2",              ACC_RW,  0x00000000},
+{0x21C, "TBASE3",       "TxBD base address of ring 3",              ACC_RW,  0x00000000},
+{0x224, "TBASE4",       "TxBD base address of ring 4",              ACC_RW,  0x00000000},
+{0x22C, "TBASE5",       "TxBD base address of ring 5",              ACC_RW,  0x00000000},
+{0x234, "TBASE6",       "TxBD base address of ring 6",              ACC_RW,  0x00000000},
+{0x23C, "TBASE7",       "TxBD base address of ring 7",              ACC_RW,  0x00000000},
+{0x280, "TMR_TXTS1_ID", "Tx time stamp identification tag (set 1)", ACC_RO,  0x00000000},
+{0x284, "TMR_TXTS2_ID", "Tx time stamp identification tag (set 2)", ACC_RO,  0x00000000},
+{0x2C0, "TMR_TXTS1_H",  "Tx time stamp high (set 1)",               ACC_RO,  0x00000000},
+{0x2C4, "TMR_TXTS1_L",  "Tx time stamp high (set 1)",               ACC_RO,  0x00000000},
+{0x2C8, "TMR_TXTS2_H",  "Tx time stamp high (set 2)",               ACC_RO,  0x00000000},
+{0x2CC, "TMR_TXTS2_L",  "Tx time stamp high (set 2)",               ACC_RO,  0x00000000},
+
+/* eTSEC Receive Control and Status Registers */
+
+{0x300, "RCTRL",      "Receive control register",                     ACC_RW,  0x00000000},
+{0x304, "RSTAT",      "Receive status register",                      ACC_W1C, 0x00000000},
+{0x310, "RXIC",       "Receive interrupt coalescing register",        ACC_RW,  0x00000000},
+{0x314, "RQUEUE",     "Receive queue control register.",              ACC_RW,  0x00800080},
+{0x330, "RBIFX",      "Receive bit field extract control register",   ACC_RW,  0x00000000},
+{0x334, "RQFAR",      "Receive queue filing table address register",  ACC_RW,  0x00000000},
+{0x338, "RQFCR",      "Receive queue filing table control register",  ACC_RW,  0x00000000},
+{0x33C, "RQFPR",      "Receive queue filing table property register", ACC_RW,  0x00000000},
+{0x340, "MRBLR",      "Maximum receive buffer length register",       ACC_RW,  0x00000000},
+{0x380, "RBDBPH",     "Rx data buffer pointer high bits",             ACC_RW,  0x00000000},
+{0x384, "RBPTR0",     "RxBD pointer for ring 0",                      ACC_RW,  0x00000000},
+{0x38C, "RBPTR1",     "RxBD pointer for ring 1",                      ACC_RW,  0x00000000},
+{0x394, "RBPTR2",     "RxBD pointer for ring 2",                      ACC_RW,  0x00000000},
+{0x39C, "RBPTR3",     "RxBD pointer for ring 3",                      ACC_RW,  0x00000000},
+{0x3A4, "RBPTR4",     "RxBD pointer for ring 4",                      ACC_RW,  0x00000000},
+{0x3AC, "RBPTR5",     "RxBD pointer for ring 5",                      ACC_RW,  0x00000000},
+{0x3B4, "RBPTR6",     "RxBD pointer for ring 6",                      ACC_RW,  0x00000000},
+{0x3BC, "RBPTR7",     "RxBD pointer for ring 7",                      ACC_RW,  0x00000000},
+{0x400, "RBASEH",     "RxBD base address high bits",                  ACC_RW,  0x00000000},
+{0x404, "RBASE0",     "RxBD base address of ring 0",                  ACC_RW,  0x00000000},
+{0x40C, "RBASE1",     "RxBD base address of ring 1",                  ACC_RW,  0x00000000},
+{0x414, "RBASE2",     "RxBD base address of ring 2",                  ACC_RW,  0x00000000},
+{0x41C, "RBASE3",     "RxBD base address of ring 3",                  ACC_RW,  0x00000000},
+{0x424, "RBASE4",     "RxBD base address of ring 4",                  ACC_RW,  0x00000000},
+{0x42C, "RBASE5",     "RxBD base address of ring 5",                  ACC_RW,  0x00000000},
+{0x434, "RBASE6",     "RxBD base address of ring 6",                  ACC_RW,  0x00000000},
+{0x43C, "RBASE7",     "RxBD base address of ring 7",                  ACC_RW,  0x00000000},
+{0x4C0, "TMR_RXTS_H", "Rx timer time stamp register high",            ACC_RW,  0x00000000},
+{0x4C4, "TMR_RXTS_L", "Rx timer time stamp register low",             ACC_RW,  0x00000000},
+
+/* eTSEC MAC Registers */
+
+{0x500, "MACCFG1",     "MAC configuration register 1",          ACC_RW, 0x00000000},
+{0x504, "MACCFG2",     "MAC configuration register 2",          ACC_RW, 0x00007000},
+{0x508, "IPGIFG",      "Inter-packet/inter-frame gap register", ACC_RW, 0x40605060},
+{0x50C, "HAFDUP",      "Half-duplex control",                   ACC_RW, 0x00A1F037},
+{0x510, "MAXFRM",      "Maximum frame length",                  ACC_RW, 0x00000600},
+{0x520, "MIIMCFG",     "MII management configuration",          ACC_RW, 0x00000007},
+{0x524, "MIIMCOM",     "MII management command",                ACC_RW, 0x00000000},
+{0x528, "MIIMADD",     "MII management address",                ACC_RW, 0x00000000},
+{0x52C, "MIIMCON",     "MII management control",                ACC_WO, 0x00000000},
+{0x530, "MIIMSTAT",    "MII management status",                 ACC_RO, 0x00000000},
+{0x534, "MIIMIND",     "MII management indicator",              ACC_RO, 0x00000000},
+{0x53C, "IFSTAT",      "Interface status",                      ACC_RO, 0x00000000},
+{0x540, "MACSTNADDR1", "MAC station address register 1",        ACC_RW, 0x00000000},
+{0x544, "MACSTNADDR2", "MAC station address register 2",        ACC_RW, 0x00000000},
+{0x548, "MAC01ADDR1",  "MAC exact match address 1, part 1",     ACC_RW, 0x00000000},
+{0x54C, "MAC01ADDR2",  "MAC exact match address 1, part 2",     ACC_RW, 0x00000000},
+{0x550, "MAC02ADDR1",  "MAC exact match address 2, part 1",     ACC_RW, 0x00000000},
+{0x554, "MAC02ADDR2",  "MAC exact match address 2, part 2",     ACC_RW, 0x00000000},
+{0x558, "MAC03ADDR1",  "MAC exact match address 3, part 1",     ACC_RW, 0x00000000},
+{0x55C, "MAC03ADDR2",  "MAC exact match address 3, part 2",     ACC_RW, 0x00000000},
+{0x560, "MAC04ADDR1",  "MAC exact match address 4, part 1",     ACC_RW, 0x00000000},
+{0x564, "MAC04ADDR2",  "MAC exact match address 4, part 2",     ACC_RW, 0x00000000},
+{0x568, "MAC05ADDR1",  "MAC exact match address 5, part 1",     ACC_RW, 0x00000000},
+{0x56C, "MAC05ADDR2",  "MAC exact match address 5, part 2",     ACC_RW, 0x00000000},
+{0x570, "MAC06ADDR1",  "MAC exact match address 6, part 1",     ACC_RW, 0x00000000},
+{0x574, "MAC06ADDR2",  "MAC exact match address 6, part 2",     ACC_RW, 0x00000000},
+{0x578, "MAC07ADDR1",  "MAC exact match address 7, part 1",     ACC_RW, 0x00000000},
+{0x57C, "MAC07ADDR2",  "MAC exact match address 7, part 2",     ACC_RW, 0x00000000},
+{0x580, "MAC08ADDR1",  "MAC exact match address 8, part 1",     ACC_RW, 0x00000000},
+{0x584, "MAC08ADDR2",  "MAC exact match address 8, part 2",     ACC_RW, 0x00000000},
+{0x588, "MAC09ADDR1",  "MAC exact match address 9, part 1",     ACC_RW, 0x00000000},
+{0x58C, "MAC09ADDR2",  "MAC exact match address 9, part 2",     ACC_RW, 0x00000000},
+{0x590, "MAC10ADDR1",  "MAC exact match address 10, part 1",    ACC_RW, 0x00000000},
+{0x594, "MAC10ADDR2",  "MAC exact match address 10, part 2",    ACC_RW, 0x00000000},
+{0x598, "MAC11ADDR1",  "MAC exact match address 11, part 1",    ACC_RW, 0x00000000},
+{0x59C, "MAC11ADDR2",  "MAC exact match address 11, part 2",    ACC_RW, 0x00000000},
+{0x5A0, "MAC12ADDR1",  "MAC exact match address 12, part 1",    ACC_RW, 0x00000000},
+{0x5A4, "MAC12ADDR2",  "MAC exact match address 12, part 2",    ACC_RW, 0x00000000},
+{0x5A8, "MAC13ADDR1",  "MAC exact match address 13, part 1",    ACC_RW, 0x00000000},
+{0x5AC, "MAC13ADDR2",  "MAC exact match address 13, part 2",    ACC_RW, 0x00000000},
+{0x5B0, "MAC14ADDR1",  "MAC exact match address 14, part 1",    ACC_RW, 0x00000000},
+{0x5B4, "MAC14ADDR2",  "MAC exact match address 14, part 2",    ACC_RW, 0x00000000},
+{0x5B8, "MAC15ADDR1",  "MAC exact match address 15, part 1",    ACC_RW, 0x00000000},
+{0x5BC, "MAC15ADDR2",  "MAC exact match address 15, part 2",    ACC_RW, 0x00000000},
+
+/* eTSEC, "Transmit", "and", Receive, Counters */
+
+{0x680, "TR64",  "Transmit and receive 64-byte frame counter ",                   ACC_RW, 0x00000000},
+{0x684, "TR127", "Transmit and receive 65- to 127-byte frame counter",            ACC_RW, 0x00000000},
+{0x688, "TR255", "Transmit and receive 128- to 255-byte frame counter",           ACC_RW, 0x00000000},
+{0x68C, "TR511", "Transmit and receive 256- to 511-byte frame counter",           ACC_RW, 0x00000000},
+{0x690, "TR1K",  "Transmit and receive 512- to 1023-byte frame counter",          ACC_RW, 0x00000000},
+{0x694, "TRMAX", "Transmit and receive 1024- to 1518-byte frame counter",         ACC_RW, 0x00000000},
+{0x698, "TRMGV", "Transmit and receive 1519- to 1522-byte good VLAN frame count", ACC_RW, 0x00000000},
+
+/* eTSEC Receive Counters */
+
+{0x69C, "RBYT", "Receive byte counter",                  ACC_RW, 0x00000000},
+{0x6A0, "RPKT", "Receive packet counter",                ACC_RW, 0x00000000},
+{0x6A4, "RFCS", "Receive FCS error counter",             ACC_RW, 0x00000000},
+{0x6A8, "RMCA", "Receive multicast packet counter",      ACC_RW, 0x00000000},
+{0x6AC, "RBCA", "Receive broadcast packet counter",      ACC_RW, 0x00000000},
+{0x6B0, "RXCF", "Receive control frame packet counter ", ACC_RW, 0x00000000},
+{0x6B4, "RXPF", "Receive PAUSE frame packet counter",    ACC_RW, 0x00000000},
+{0x6B8, "RXUO", "Receive unknown OP code counter ",      ACC_RW, 0x00000000},
+{0x6BC, "RALN", "Receive alignment error counter ",      ACC_RW, 0x00000000},
+{0x6C0, "RFLR", "Receive frame length error counter ",   ACC_RW, 0x00000000},
+{0x6C4, "RCDE", "Receive code error counter ",           ACC_RW, 0x00000000},
+{0x6C8, "RCSE", "Receive carrier sense error counter",   ACC_RW, 0x00000000},
+{0x6CC, "RUND", "Receive undersize packet counter",      ACC_RW, 0x00000000},
+{0x6D0, "ROVR", "Receive oversize packet counter ",      ACC_RW, 0x00000000},
+{0x6D4, "RFRG", "Receive fragments counter",             ACC_RW, 0x00000000},
+{0x6D8, "RJBR", "Receive jabber counter ",               ACC_RW, 0x00000000},
+{0x6DC, "RDRP", "Receive drop counter",                  ACC_RW, 0x00000000},
+
+/* eTSEC Transmit Counters */
+
+{0x6E0, "TBYT", "Transmit byte counter",                       ACC_RW, 0x00000000},
+{0x6E4, "TPKT", "Transmit packet counter",                     ACC_RW, 0x00000000},
+{0x6E8, "TMCA", "Transmit multicast packet counter ",          ACC_RW, 0x00000000},
+{0x6EC, "TBCA", "Transmit broadcast packet counter ",          ACC_RW, 0x00000000},
+{0x6F0, "TXPF", "Transmit PAUSE control frame counter ",       ACC_RW, 0x00000000},
+{0x6F4, "TDFR", "Transmit deferral packet counter ",           ACC_RW, 0x00000000},
+{0x6F8, "TEDF", "Transmit excessive deferral packet counter ", ACC_RW, 0x00000000},
+{0x6FC, "TSCL", "Transmit single collision packet counter",    ACC_RW, 0x00000000},
+{0x700, "TMCL", "Transmit multiple collision packet counter",  ACC_RW, 0x00000000},
+{0x704, "TLCL", "Transmit late collision packet counter",      ACC_RW, 0x00000000},
+{0x708, "TXCL", "Transmit excessive collision packet counter", ACC_RW, 0x00000000},
+{0x70C, "TNCL", "Transmit total collision counter ",           ACC_RW, 0x00000000},
+{0x714, "TDRP", "Transmit drop frame counter",                 ACC_RW, 0x00000000},
+{0x718, "TJBR", "Transmit jabber frame counter ",              ACC_RW, 0x00000000},
+{0x71C, "TFCS", "Transmit FCS error counter",                  ACC_RW, 0x00000000},
+{0x720, "TXCF", "Transmit control frame counter ",             ACC_RW, 0x00000000},
+{0x724, "TOVR", "Transmit oversize frame counter",             ACC_RW, 0x00000000},
+{0x728, "TUND", "Transmit undersize frame counter ",           ACC_RW, 0x00000000},
+{0x72C, "TFRG", "Transmit fragments frame counter ",           ACC_RW, 0x00000000},
+
+/* eTSEC Counter Control and TOE Statistics Registers */
+
+{0x730, "CAR1", "Carry register one register",           ACC_W1C, 0x00000000},
+{0x734, "CAR2", "Carry register two register ",          ACC_W1C, 0x00000000},
+{0x738, "CAM1", "Carry register one mask register ",     ACC_RW,  0xFE03FFFF},
+{0x73C, "CAM2", "Carry register two mask register ",     ACC_RW,  0x000FFFFD},
+{0x740, "RREJ", "Receive filer rejected packet counter", ACC_RW,  0x00000000},
+
+/* Hash Function Registers */
+
+{0x800, "IGADDR0", "Individual/group address register 0", ACC_RW, 0x00000000},
+{0x804, "IGADDR1", "Individual/group address register 1", ACC_RW, 0x00000000},
+{0x808, "IGADDR2", "Individual/group address register 2", ACC_RW, 0x00000000},
+{0x80C, "IGADDR3", "Individual/group address register 3", ACC_RW, 0x00000000},
+{0x810, "IGADDR4", "Individual/group address register 4", ACC_RW, 0x00000000},
+{0x814, "IGADDR5", "Individual/group address register 5", ACC_RW, 0x00000000},
+{0x818, "IGADDR6", "Individual/group address register 6", ACC_RW, 0x00000000},
+{0x81C, "IGADDR7", "Individual/group address register 7", ACC_RW, 0x00000000},
+{0x880, "GADDR0",  "Group address register 0",            ACC_RW, 0x00000000},
+{0x884, "GADDR1",  "Group address register 1",            ACC_RW, 0x00000000},
+{0x888, "GADDR2",  "Group address register 2",            ACC_RW, 0x00000000},
+{0x88C, "GADDR3",  "Group address register 3",            ACC_RW, 0x00000000},
+{0x890, "GADDR4",  "Group address register 4",            ACC_RW, 0x00000000},
+{0x894, "GADDR5",  "Group address register 5",            ACC_RW, 0x00000000},
+{0x898, "GADDR6",  "Group address register 6",            ACC_RW, 0x00000000},
+{0x89C, "GADDR7",  "Group address register 7",            ACC_RW, 0x00000000},
+
+/* eTSEC DMA Attribute Registers */
+
+{0xBF8, "ATTR",    "Attribute register",                                  ACC_RW, 0x00000000},
+{0xBFC, "ATTRELI", "Attribute extract length and extract index register", ACC_RW, 0x00000000},
+
+
+/* eTSEC Lossless Flow Control Registers */
+
+{0xC00, "RQPRM0",  "Receive Queue Parameters register 0 ", ACC_RW, 0x00000000},
+{0xC04, "RQPRM1",  "Receive Queue Parameters register 1 ", ACC_RW, 0x00000000},
+{0xC08, "RQPRM2",  "Receive Queue Parameters register 2 ", ACC_RW, 0x00000000},
+{0xC0C, "RQPRM3",  "Receive Queue Parameters register 3 ", ACC_RW, 0x00000000},
+{0xC10, "RQPRM4",  "Receive Queue Parameters register 4 ", ACC_RW, 0x00000000},
+{0xC14, "RQPRM5",  "Receive Queue Parameters register 5 ", ACC_RW, 0x00000000},
+{0xC18, "RQPRM6",  "Receive Queue Parameters register 6 ", ACC_RW, 0x00000000},
+{0xC1C, "RQPRM7",  "Receive Queue Parameters register 7 ", ACC_RW, 0x00000000},
+{0xC44, "RFBPTR0", "Last Free RxBD pointer for ring 0",    ACC_RW, 0x00000000},
+{0xC4C, "RFBPTR1", "Last Free RxBD pointer for ring 1",    ACC_RW, 0x00000000},
+{0xC54, "RFBPTR2", "Last Free RxBD pointer for ring 2",    ACC_RW, 0x00000000},
+{0xC5C, "RFBPTR3", "Last Free RxBD pointer for ring 3",    ACC_RW, 0x00000000},
+{0xC64, "RFBPTR4", "Last Free RxBD pointer for ring 4",    ACC_RW, 0x00000000},
+{0xC6C, "RFBPTR5", "Last Free RxBD pointer for ring 5",    ACC_RW, 0x00000000},
+{0xC74, "RFBPTR6", "Last Free RxBD pointer for ring 6",    ACC_RW, 0x00000000},
+{0xC7C, "RFBPTR7", "Last Free RxBD pointer for ring 7",    ACC_RW, 0x00000000},
+
+/* eTSEC Future Expansion Space */
+
+/* Reserved*/
+
+/* eTSEC IEEE 1588 Registers */
+
+{0xE00, "TMR_CTRL",     "Timer control register",                          ACC_RW,  0x00010001},
+{0xE04, "TMR_TEVENT",   "time stamp event register",                       ACC_W1C, 0x00000000},
+{0xE08, "TMR_TEMASK",   "Timer event mask register",                       ACC_RW,  0x00000000},
+{0xE0C, "TMR_PEVENT",   "time stamp event register",                       ACC_RW,  0x00000000},
+{0xE10, "TMR_PEMASK",   "Timer event mask register",                       ACC_RW,  0x00000000},
+{0xE14, "TMR_STAT",     "time stamp status register",                      ACC_RW,  0x00000000},
+{0xE18, "TMR_CNT_H",    "timer counter high register",                     ACC_RW,  0x00000000},
+{0xE1C, "TMR_CNT_L",    "timer counter low register",                      ACC_RW,  0x00000000},
+{0xE20, "TMR_ADD",      "Timer drift compensation addend register",        ACC_RW,  0x00000000},
+{0xE24, "TMR_ACC",      "Timer accumulator register",                      ACC_RW,  0x00000000},
+{0xE28, "TMR_PRSC",     "Timer prescale",                                  ACC_RW,  0x00000002},
+{0xE30, "TMROFF_H",     "Timer offset high",                               ACC_RW,  0x00000000},
+{0xE34, "TMROFF_L",     "Timer offset low",                                ACC_RW,  0x00000000},
+{0xE40, "TMR_ALARM1_H", "Timer alarm 1 high register",                     ACC_RW,  0xFFFFFFFF},
+{0xE44, "TMR_ALARM1_L", "Timer alarm 1 high register",                     ACC_RW,  0xFFFFFFFF},
+{0xE48, "TMR_ALARM2_H", "Timer alarm 2 high register",                     ACC_RW,  0xFFFFFFFF},
+{0xE4C, "TMR_ALARM2_L", "Timer alarm 2 high register",                     ACC_RW,  0xFFFFFFFF},
+{0xE80, "TMR_FIPER1",   "Timer fixed period interval",                     ACC_RW,  0xFFFFFFFF},
+{0xE84, "TMR_FIPER2",   "Timer fixed period interval",                     ACC_RW,  0xFFFFFFFF},
+{0xE88, "TMR_FIPER3",   "Timer fixed period interval",                     ACC_RW,  0xFFFFFFFF},
+{0xEA0, "TMR_ETTS1_H",  "Time stamp of general purpose external trigger ", ACC_RW,  0x00000000},
+{0xEA4, "TMR_ETTS1_L",  "Time stamp of general purpose external trigger",  ACC_RW,  0x00000000},
+{0xEA8, "TMR_ETTS2_H",  "Time stamp of general purpose external trigger ", ACC_RW,  0x00000000},
+{0xEAC, "TMR_ETTS2_L",  "Time stamp of general purpose external trigger",  ACC_RW,  0x00000000},
+
+/* End Of Table */
+{0x0, 0x0, 0x0, 0x0, 0x0}
+};
diff --git a/hw/net/fsl_etsec/registers.h b/hw/net/fsl_etsec/registers.h
new file mode 100644
index 0000000..7ad7686
--- /dev/null
+++ b/hw/net/fsl_etsec/registers.h
@@ -0,0 +1,320 @@
+/*
+ * QEMU Freescale eTSEC Emulator
+ *
+ * Copyright (c) 2011-2013 AdaCore
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef _ETSEC_REGISTERS_H_
+#define _ETSEC_REGISTERS_H_
+
+#include <stdint.h>
+
+enum eTSEC_Register_Access_Type {
+    ACC_RW      = 1,            /* Read/Write */
+    ACC_RO      = 2,            /* Read Only */
+    ACC_WO      = 3,            /* Write Only */
+    ACC_W1C     = 4,            /* Write 1 to clear */
+    ACC_UNKNOWN = 5             /* Unknown register*/
+};
+
+typedef struct eTSEC_Register_Definition {
+    uint32_t                         offset;
+    const char                      *name;
+    const char                      *desc;
+    enum eTSEC_Register_Access_Type  access;
+    uint32_t                         reset;
+} eTSEC_Register_Definition;
+
+extern const eTSEC_Register_Definition eTSEC_registers_def[];
+
+#define DMACTRL_LE  (1 << 15)
+#define DMACTRL_GRS (1 <<  4)
+#define DMACTRL_GTS (1 <<  3)
+#define DMACTRL_WOP (1 <<  0)
+
+#define IEVENT_PERR  (1 <<  0)
+#define IEVENT_DPE   (1 <<  1)
+#define IEVENT_FIQ   (1 <<  2)
+#define IEVENT_FIR   (1 <<  3)
+#define IEVENT_FGPI  (1 <<  4)
+#define IEVENT_RXF   (1 <<  7)
+#define IEVENT_GRSC  (1 <<  8)
+#define IEVENT_MMRW  (1 <<  9)
+#define IEVENT_MMRD  (1 << 10)
+#define IEVENT_MAG   (1 << 11)
+#define IEVENT_RXB   (1 << 15)
+#define IEVENT_XFUN  (1 << 16)
+#define IEVENT_CRL   (1 << 17)
+#define IEVENT_LC    (1 << 18)
+#define IEVENT_TXF   (1 << 20)
+#define IEVENT_TXB   (1 << 21)
+#define IEVENT_TXE   (1 << 22)
+#define IEVENT_TXC   (1 << 23)
+#define IEVENT_BABT  (1 << 24)
+#define IEVENT_GTSC  (1 << 25)
+#define IEVENT_MSRO  (1 << 26)
+#define IEVENT_EBERR (1 << 28)
+#define IEVENT_BSY   (1 << 29)
+#define IEVENT_RXC   (1 << 30)
+#define IEVENT_BABR  (1 << 31)
+
+#define IMASK_RXFEN  (1 <<  7)
+#define IMASK_GRSCEN (1 <<  8)
+#define IMASK_RXBEN  (1 << 15)
+#define IMASK_TXFEN  (1 << 20)
+#define IMASK_TXBEN  (1 << 21)
+#define IMASK_GTSCEN (1 << 25)
+
+#define MACCFG1_TX_EN  (1 << 0)
+#define MACCFG1_RX_EN  (1 << 2)
+
+#define MACCFG2_CRC_EN  (1 << 1)
+#define MACCFG2_PADCRC  (1 << 2)
+
+#define MIIMCOM_READ (1 << 0)
+#define MIIMCOM_SCAN (1 << 1)
+
+#define RCTRL_PRSDEP_MASK   (0x3)
+#define RCTRL_PRSDEP_OFFSET (6)
+#define RCTRL_RSF           (1 << 2)
+
+/* Index of each register */
+
+#define TSEC_ID      (0x000 / 4)
+#define TSEC_ID2     (0x004 / 4)
+#define IEVENT       (0x010 / 4)
+#define IMASK        (0x014 / 4)
+#define EDIS         (0x018 / 4)
+#define ECNTRL       (0x020 / 4)
+#define PTV          (0x028 / 4)
+#define DMACTRL      (0x02C / 4)
+#define TBIPA        (0x030 / 4)
+#define TCTRL        (0x100 / 4)
+#define TSTAT        (0x104 / 4)
+#define DFVLAN       (0x108 / 4)
+#define TXIC         (0x110 / 4)
+#define TQUEUE       (0x114 / 4)
+#define TR03WT       (0x140 / 4)
+#define TR47WT       (0x144 / 4)
+#define TBDBPH       (0x180 / 4)
+#define TBPTR0       (0x184 / 4)
+#define TBPTR1       (0x18C / 4)
+#define TBPTR2       (0x194 / 4)
+#define TBPTR3       (0x19C / 4)
+#define TBPTR4       (0x1A4 / 4)
+#define TBPTR5       (0x1AC / 4)
+#define TBPTR6       (0x1B4 / 4)
+#define TBPTR7       (0x1BC / 4)
+#define TBASEH       (0x200 / 4)
+#define TBASE0       (0x204 / 4)
+#define TBASE1       (0x20C / 4)
+#define TBASE2       (0x214 / 4)
+#define TBASE3       (0x21C / 4)
+#define TBASE4       (0x224 / 4)
+#define TBASE5       (0x22C / 4)
+#define TBASE6       (0x234 / 4)
+#define TBASE7       (0x23C / 4)
+#define TMR_TXTS1_ID (0x280 / 4)
+#define TMR_TXTS2_ID (0x284 / 4)
+#define TMR_TXTS1_H  (0x2C0 / 4)
+#define TMR_TXTS1_L  (0x2C4 / 4)
+#define TMR_TXTS2_H  (0x2C8 / 4)
+#define TMR_TXTS2_L  (0x2CC / 4)
+#define RCTRL        (0x300 / 4)
+#define RSTAT        (0x304 / 4)
+#define RXIC         (0x310 / 4)
+#define RQUEUE       (0x314 / 4)
+#define RBIFX        (0x330 / 4)
+#define RQFAR        (0x334 / 4)
+#define RQFCR        (0x338 / 4)
+#define RQFPR        (0x33C / 4)
+#define MRBLR        (0x340 / 4)
+#define RBDBPH       (0x380 / 4)
+#define RBPTR0       (0x384 / 4)
+#define RBPTR1       (0x38C / 4)
+#define RBPTR2       (0x394 / 4)
+#define RBPTR3       (0x39C / 4)
+#define RBPTR4       (0x3A4 / 4)
+#define RBPTR5       (0x3AC / 4)
+#define RBPTR6       (0x3B4 / 4)
+#define RBPTR7       (0x3BC / 4)
+#define RBASEH       (0x400 / 4)
+#define RBASE0       (0x404 / 4)
+#define RBASE1       (0x40C / 4)
+#define RBASE2       (0x414 / 4)
+#define RBASE3       (0x41C / 4)
+#define RBASE4       (0x424 / 4)
+#define RBASE5       (0x42C / 4)
+#define RBASE6       (0x434 / 4)
+#define RBASE7       (0x43C / 4)
+#define TMR_RXTS_H   (0x4C0 / 4)
+#define TMR_RXTS_L   (0x4C4 / 4)
+#define MACCFG1      (0x500 / 4)
+#define MACCFG2      (0x504 / 4)
+#define IPGIFG       (0x508 / 4)
+#define HAFDUP       (0x50C / 4)
+#define MAXFRM       (0x510 / 4)
+#define MIIMCFG      (0x520 / 4)
+#define MIIMCOM      (0x524 / 4)
+#define MIIMADD      (0x528 / 4)
+#define MIIMCON      (0x52C / 4)
+#define MIIMSTAT     (0x530 / 4)
+#define MIIMIND      (0x534 / 4)
+#define IFSTAT       (0x53C / 4)
+#define MACSTNADDR1  (0x540 / 4)
+#define MACSTNADDR2  (0x544 / 4)
+#define MAC01ADDR1   (0x548 / 4)
+#define MAC01ADDR2   (0x54C / 4)
+#define MAC02ADDR1   (0x550 / 4)
+#define MAC02ADDR2   (0x554 / 4)
+#define MAC03ADDR1   (0x558 / 4)
+#define MAC03ADDR2   (0x55C / 4)
+#define MAC04ADDR1   (0x560 / 4)
+#define MAC04ADDR2   (0x564 / 4)
+#define MAC05ADDR1   (0x568 / 4)
+#define MAC05ADDR2   (0x56C / 4)
+#define MAC06ADDR1   (0x570 / 4)
+#define MAC06ADDR2   (0x574 / 4)
+#define MAC07ADDR1   (0x578 / 4)
+#define MAC07ADDR2   (0x57C / 4)
+#define MAC08ADDR1   (0x580 / 4)
+#define MAC08ADDR2   (0x584 / 4)
+#define MAC09ADDR1   (0x588 / 4)
+#define MAC09ADDR2   (0x58C / 4)
+#define MAC10ADDR1   (0x590 / 4)
+#define MAC10ADDR2   (0x594 / 4)
+#define MAC11ADDR1   (0x598 / 4)
+#define MAC11ADDR2   (0x59C / 4)
+#define MAC12ADDR1   (0x5A0 / 4)
+#define MAC12ADDR2   (0x5A4 / 4)
+#define MAC13ADDR1   (0x5A8 / 4)
+#define MAC13ADDR2   (0x5AC / 4)
+#define MAC14ADDR1   (0x5B0 / 4)
+#define MAC14ADDR2   (0x5B4 / 4)
+#define MAC15ADDR1   (0x5B8 / 4)
+#define MAC15ADDR2   (0x5BC / 4)
+#define TR64         (0x680 / 4)
+#define TR127        (0x684 / 4)
+#define TR255        (0x688 / 4)
+#define TR511        (0x68C / 4)
+#define TR1K         (0x690 / 4)
+#define TRMAX        (0x694 / 4)
+#define TRMGV        (0x698 / 4)
+#define RBYT         (0x69C / 4)
+#define RPKT         (0x6A0 / 4)
+#define RFCS         (0x6A4 / 4)
+#define RMCA         (0x6A8 / 4)
+#define RBCA         (0x6AC / 4)
+#define RXCF         (0x6B0 / 4)
+#define RXPF         (0x6B4 / 4)
+#define RXUO         (0x6B8 / 4)
+#define RALN         (0x6BC / 4)
+#define RFLR         (0x6C0 / 4)
+#define RCDE         (0x6C4 / 4)
+#define RCSE         (0x6C8 / 4)
+#define RUND         (0x6CC / 4)
+#define ROVR         (0x6D0 / 4)
+#define RFRG         (0x6D4 / 4)
+#define RJBR         (0x6D8 / 4)
+#define RDRP         (0x6DC / 4)
+#define TBYT         (0x6E0 / 4)
+#define TPKT         (0x6E4 / 4)
+#define TMCA         (0x6E8 / 4)
+#define TBCA         (0x6EC / 4)
+#define TXPF         (0x6F0 / 4)
+#define TDFR         (0x6F4 / 4)
+#define TEDF         (0x6F8 / 4)
+#define TSCL         (0x6FC / 4)
+#define TMCL         (0x700 / 4)
+#define TLCL         (0x704 / 4)
+#define TXCL         (0x708 / 4)
+#define TNCL         (0x70C / 4)
+#define TDRP         (0x714 / 4)
+#define TJBR         (0x718 / 4)
+#define TFCS         (0x71C / 4)
+#define TXCF         (0x720 / 4)
+#define TOVR         (0x724 / 4)
+#define TUND         (0x728 / 4)
+#define TFRG         (0x72C / 4)
+#define CAR1         (0x730 / 4)
+#define CAR2         (0x734 / 4)
+#define CAM1         (0x738 / 4)
+#define CAM2         (0x73C / 4)
+#define RREJ         (0x740 / 4)
+#define IGADDR0      (0x800 / 4)
+#define IGADDR1      (0x804 / 4)
+#define IGADDR2      (0x808 / 4)
+#define IGADDR3      (0x80C / 4)
+#define IGADDR4      (0x810 / 4)
+#define IGADDR5      (0x814 / 4)
+#define IGADDR6      (0x818 / 4)
+#define IGADDR7      (0x81C / 4)
+#define GADDR0       (0x880 / 4)
+#define GADDR1       (0x884 / 4)
+#define GADDR2       (0x888 / 4)
+#define GADDR3       (0x88C / 4)
+#define GADDR4       (0x890 / 4)
+#define GADDR5       (0x894 / 4)
+#define GADDR6       (0x898 / 4)
+#define GADDR7       (0x89C / 4)
+#define ATTR         (0xBF8 / 4)
+#define ATTRELI      (0xBFC / 4)
+#define RQPRM0       (0xC00 / 4)
+#define RQPRM1       (0xC04 / 4)
+#define RQPRM2       (0xC08 / 4)
+#define RQPRM3       (0xC0C / 4)
+#define RQPRM4       (0xC10 / 4)
+#define RQPRM5       (0xC14 / 4)
+#define RQPRM6       (0xC18 / 4)
+#define RQPRM7       (0xC1C / 4)
+#define RFBPTR0      (0xC44 / 4)
+#define RFBPTR1      (0xC4C / 4)
+#define RFBPTR2      (0xC54 / 4)
+#define RFBPTR3      (0xC5C / 4)
+#define RFBPTR4      (0xC64 / 4)
+#define RFBPTR5      (0xC6C / 4)
+#define RFBPTR6      (0xC74 / 4)
+#define RFBPTR7      (0xC7C / 4)
+#define TMR_CTRL     (0xE00 / 4)
+#define TMR_TEVENT   (0xE04 / 4)
+#define TMR_TEMASK   (0xE08 / 4)
+#define TMR_PEVENT   (0xE0C / 4)
+#define TMR_PEMASK   (0xE10 / 4)
+#define TMR_STAT     (0xE14 / 4)
+#define TMR_CNT_H    (0xE18 / 4)
+#define TMR_CNT_L    (0xE1C / 4)
+#define TMR_ADD      (0xE20 / 4)
+#define TMR_ACC      (0xE24 / 4)
+#define TMR_PRSC     (0xE28 / 4)
+#define TMROFF_H     (0xE30 / 4)
+#define TMROFF_L     (0xE34 / 4)
+#define TMR_ALARM1_H (0xE40 / 4)
+#define TMR_ALARM1_L (0xE44 / 4)
+#define TMR_ALARM2_H (0xE48 / 4)
+#define TMR_ALARM2_L (0xE4C / 4)
+#define TMR_FIPER1   (0xE80 / 4)
+#define TMR_FIPER2   (0xE84 / 4)
+#define TMR_FIPER3   (0xE88 / 4)
+#define TMR_ETTS1_H  (0xEA0 / 4)
+#define TMR_ETTS1_L  (0xEA4 / 4)
+#define TMR_ETTS2_H  (0xEA8 / 4)
+#define TMR_ETTS2_L  (0xEAC / 4)
+
+#endif /* ! _ETSEC_REGISTERS_H_ */
diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c
new file mode 100644
index 0000000..7760272
--- /dev/null
+++ b/hw/net/fsl_etsec/rings.c
@@ -0,0 +1,650 @@
+/*
+ * QEMU Freescale eTSEC Emulator
+ *
+ * Copyright (c) 2011-2013 AdaCore
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "net/checksum.h"
+
+#include "etsec.h"
+#include "registers.h"
+
+/* #define ETSEC_RING_DEBUG */
+/* #define HEX_DUMP */
+/* #define DEBUG_BD */
+
+#ifdef ETSEC_RING_DEBUG
+static const int debug_etsec = 1;
+#else
+static const int debug_etsec;
+#endif
+
+#define RING_DEBUG(fmt, ...) do {              \
+ if (debug_etsec) {                            \
+        qemu_log(fmt , ## __VA_ARGS__);        \
+    }                                          \
+    } while (0)
+
+#ifdef DEBUG_BD
+
+static void print_tx_bd_flags(uint16_t flags)
+{
+    qemu_log("      Ready: %d\n", !!(flags & BD_TX_READY));
+    qemu_log("      PAD/CRC: %d\n", !!(flags & BD_TX_PADCRC));
+    qemu_log("      Wrap: %d\n", !!(flags & BD_WRAP));
+    qemu_log("      Interrupt: %d\n", !!(flags & BD_INTERRUPT));
+    qemu_log("      Last in frame: %d\n", !!(flags & BD_LAST));
+    qemu_log("      Tx CRC: %d\n", !!(flags & BD_TX_TC));
+    qemu_log("      User-defined preamble / defer: %d\n",
+           !!(flags & BD_TX_PREDEF));
+    qemu_log("      Huge frame enable / Late collision: %d\n",
+           !!(flags & BD_TX_HFELC));
+    qemu_log("      Control frame / Retransmission Limit: %d\n",
+           !!(flags & BD_TX_CFRL));
+    qemu_log("      Retry count: %d\n",
+           (flags >> BD_TX_RC_OFFSET) & BD_TX_RC_MASK);
+    qemu_log("      Underrun / TCP/IP off-load enable: %d\n",
+           !!(flags & BD_TX_TOEUN));
+    qemu_log("      Truncation: %d\n", !!(flags & BD_TX_TR));
+}
+
+static void print_rx_bd_flags(uint16_t flags)
+{
+    qemu_log("      Empty: %d\n", !!(flags & BD_RX_EMPTY));
+    qemu_log("      Receive software ownership: %d\n", !!(flags & BD_RX_RO1));
+    qemu_log("      Wrap: %d\n", !!(flags & BD_WRAP));
+    qemu_log("      Interrupt: %d\n", !!(flags & BD_INTERRUPT));
+    qemu_log("      Last in frame: %d\n", !!(flags & BD_LAST));
+    qemu_log("      First in frame: %d\n", !!(flags & BD_RX_FIRST));
+    qemu_log("      Miss: %d\n", !!(flags & BD_RX_MISS));
+    qemu_log("      Broadcast: %d\n", !!(flags & BD_RX_BROADCAST));
+    qemu_log("      Multicast: %d\n", !!(flags & BD_RX_MULTICAST));
+    qemu_log("      Rx frame length violation: %d\n", !!(flags & BD_RX_LG));
+    qemu_log("      Rx non-octet aligned frame: %d\n", !!(flags & BD_RX_NO));
+    qemu_log("      Short frame: %d\n", !!(flags & BD_RX_SH));
+    qemu_log("      Rx CRC Error: %d\n", !!(flags & BD_RX_CR));
+    qemu_log("      Overrun: %d\n", !!(flags & BD_RX_OV));
+    qemu_log("      Truncation: %d\n", !!(flags & BD_RX_TR));
+}
+
+
+static void print_bd(eTSEC_rxtx_bd bd, int mode, uint32_t index)
+{
+    qemu_log("eTSEC %s Data Buffer Descriptor (%u)\n",
+           mode == eTSEC_TRANSMIT ? "Transmit" : "Receive",
+           index);
+    qemu_log("   Flags   : 0x%04x\n", bd.flags);
+    if (mode == eTSEC_TRANSMIT) {
+        print_tx_bd_flags(bd.flags);
+    } else {
+        print_rx_bd_flags(bd.flags);
+    }
+    qemu_log("   Length  : 0x%04x\n", bd.length);
+    qemu_log("   Pointer : 0x%08x\n", bd.bufptr);
+}
+
+#endif  /* DEBUG_BD */
+
+static void read_buffer_descriptor(eTSEC         *etsec,
+                                   hwaddr         addr,
+                                   eTSEC_rxtx_bd *bd)
+{
+    assert(bd != NULL);
+
+    RING_DEBUG("READ Buffer Descriptor @ 0x" TARGET_FMT_plx"\n", addr);
+    cpu_physical_memory_read(addr,
+                             bd,
+                             sizeof(eTSEC_rxtx_bd));
+
+    if (etsec->regs[DMACTRL].value & DMACTRL_LE) {
+        bd->flags  = lduw_le_p(&bd->flags);
+        bd->length = lduw_le_p(&bd->length);
+        bd->bufptr = ldl_le_p(&bd->bufptr);
+    } else {
+        bd->flags  = lduw_be_p(&bd->flags);
+        bd->length = lduw_be_p(&bd->length);
+        bd->bufptr = ldl_be_p(&bd->bufptr);
+    }
+}
+
+static void write_buffer_descriptor(eTSEC         *etsec,
+                                    hwaddr         addr,
+                                    eTSEC_rxtx_bd *bd)
+{
+    assert(bd != NULL);
+
+    if (etsec->regs[DMACTRL].value & DMACTRL_LE) {
+        stw_le_p(&bd->flags, bd->flags);
+        stw_le_p(&bd->length, bd->length);
+        stl_le_p(&bd->bufptr, bd->bufptr);
+    } else {
+        stw_be_p(&bd->flags, bd->flags);
+        stw_be_p(&bd->length, bd->length);
+        stl_be_p(&bd->bufptr, bd->bufptr);
+    }
+
+    RING_DEBUG("Write Buffer Descriptor @ 0x" TARGET_FMT_plx"\n", addr);
+    cpu_physical_memory_write(addr,
+                              bd,
+                              sizeof(eTSEC_rxtx_bd));
+}
+
+static void ievent_set(eTSEC    *etsec,
+                       uint32_t  flags)
+{
+    etsec->regs[IEVENT].value |= flags;
+
+    if ((flags & IEVENT_TXB && etsec->regs[IMASK].value & IMASK_TXBEN)
+        || (flags & IEVENT_TXF && etsec->regs[IMASK].value & IMASK_TXFEN)) {
+        qemu_irq_raise(etsec->tx_irq);
+        RING_DEBUG("%s Raise Tx IRQ\n", __func__);
+    }
+
+    if ((flags & IEVENT_RXB && etsec->regs[IMASK].value & IMASK_RXBEN)
+        || (flags & IEVENT_RXF && etsec->regs[IMASK].value & IMASK_RXFEN)) {
+        qemu_irq_pulse(etsec->rx_irq);
+        RING_DEBUG("%s Raise Rx IRQ\n", __func__);
+    }
+}
+
+static void tx_padding_and_crc(eTSEC *etsec, uint32_t min_frame_len)
+{
+    int add = min_frame_len - etsec->tx_buffer_len;
+
+    /* Padding */
+    if (add > 0) {
+        RING_DEBUG("pad:%u\n", add);
+        etsec->tx_buffer = g_realloc(etsec->tx_buffer,
+                                        etsec->tx_buffer_len + add);
+
+        memset(etsec->tx_buffer + etsec->tx_buffer_len, 0x0, add);
+        etsec->tx_buffer_len += add;
+    }
+
+    /* Never add CRC in QEMU */
+}
+
+static void process_tx_fcb(eTSEC *etsec)
+{
+    uint8_t flags = (uint8_t)(*etsec->tx_buffer);
+    /* L3 header offset from start of frame */
+    uint8_t l3_header_offset = (uint8_t)*(etsec->tx_buffer + 3);
+    /* L4 header offset from start of L3 header */
+    uint8_t l4_header_offset = (uint8_t)*(etsec->tx_buffer + 2);
+    /* L3 header */
+    uint8_t *l3_header = etsec->tx_buffer + 8 + l3_header_offset;
+    /* L4 header */
+    uint8_t *l4_header = l3_header + l4_header_offset;
+
+    /* if packet is IP4 and IP checksum is requested */
+    if (flags & FCB_TX_IP && flags & FCB_TX_CIP) {
+        /* do IP4 checksum (TODO This funtion does TCP/UDP checksum but not sure
+         * if it also does IP4 checksum. */
+        net_checksum_calculate(etsec->tx_buffer + 8,
+                etsec->tx_buffer_len - 8);
+    }
+    /* TODO Check the correct usage of the PHCS field of the FCB in case the NPH
+     * flag is on */
+
+    /* if packet is IP4 and TCP or UDP */
+    if (flags & FCB_TX_IP && flags & FCB_TX_TUP) {
+        /* if UDP */
+        if (flags & FCB_TX_UDP) {
+            /* if checksum is requested */
+            if (flags & FCB_TX_CTU) {
+                /* do UDP checksum */
+
+                net_checksum_calculate(etsec->tx_buffer + 8,
+                        etsec->tx_buffer_len - 8);
+            } else {
+                /* set checksum field to 0 */
+                l4_header[6] = 0;
+                l4_header[7] = 0;
+            }
+        } else if (flags & FCB_TX_CTU) { /* if TCP and checksum is requested */
+            /* do TCP checksum */
+            net_checksum_calculate(etsec->tx_buffer + 8,
+                                   etsec->tx_buffer_len - 8);
+        }
+    }
+}
+
+static void process_tx_bd(eTSEC         *etsec,
+                          eTSEC_rxtx_bd *bd)
+{
+    uint8_t *tmp_buff = NULL;
+    hwaddr tbdbth     = (hwaddr)(etsec->regs[TBDBPH].value & 0xF) << 32;
+
+    if (bd->length == 0) {
+        /* ERROR */
+        return;
+    }
+
+    if (etsec->tx_buffer_len == 0) {
+        /* It's the first BD */
+        etsec->first_bd = *bd;
+    }
+
+    /* TODO: if TxBD[TOE/UN] skip the Tx Frame Control Block*/
+
+    /* Load this Data Buffer */
+    etsec->tx_buffer = g_realloc(etsec->tx_buffer,
+                                    etsec->tx_buffer_len + bd->length);
+    tmp_buff = etsec->tx_buffer + etsec->tx_buffer_len;
+    cpu_physical_memory_read(bd->bufptr + tbdbth, tmp_buff, bd->length);
+
+    /* Update buffer length */
+    etsec->tx_buffer_len += bd->length;
+
+
+    if (etsec->tx_buffer_len != 0 && (bd->flags & BD_LAST)) {
+        if (etsec->regs[MACCFG1].value & MACCFG1_TX_EN) {
+            /* MAC Transmit enabled */
+
+            /* Process offload Tx FCB */
+            if (etsec->first_bd.flags & BD_TX_TOEUN) {
+                process_tx_fcb(etsec);
+            }
+
+            if (etsec->first_bd.flags & BD_TX_PADCRC
+                || etsec->regs[MACCFG2].value & MACCFG2_PADCRC) {
+
+                /* Padding and CRC (Padding implies CRC) */
+                tx_padding_and_crc(etsec, 64);
+
+            } else if (etsec->first_bd.flags & BD_TX_TC
+                       || etsec->regs[MACCFG2].value & MACCFG2_CRC_EN) {
+
+                /* Only CRC */
+                /* Never add CRC in QEMU */
+            }
+
+#if defined(HEX_DUMP)
+            qemu_log("eTSEC Send packet size:%d\n", etsec->tx_buffer_len);
+            qemu_hexdump(etsec->tx_buffer, stderr, "", etsec->tx_buffer_len);
+#endif  /* ETSEC_RING_DEBUG */
+
+            if (etsec->first_bd.flags & BD_TX_TOEUN) {
+                qemu_send_packet(qemu_get_queue(etsec->nic),
+                        etsec->tx_buffer + 8,
+                        etsec->tx_buffer_len - 8);
+            } else {
+                qemu_send_packet(qemu_get_queue(etsec->nic),
+                        etsec->tx_buffer,
+                        etsec->tx_buffer_len);
+            }
+
+        }
+
+        etsec->tx_buffer_len = 0;
+
+        if (bd->flags & BD_INTERRUPT) {
+            ievent_set(etsec, IEVENT_TXF);
+        }
+    } else {
+        if (bd->flags & BD_INTERRUPT) {
+            ievent_set(etsec, IEVENT_TXB);
+        }
+    }
+
+    /* Update DB flags */
+
+    /* Clear Ready */
+    bd->flags &= ~BD_TX_READY;
+
+    /* Clear Defer */
+    bd->flags &= ~BD_TX_PREDEF;
+
+    /* Clear Late Collision */
+    bd->flags &= ~BD_TX_HFELC;
+
+    /* Clear Retransmission Limit */
+    bd->flags &= ~BD_TX_CFRL;
+
+    /* Clear Retry Count */
+    bd->flags &= ~(BD_TX_RC_MASK << BD_TX_RC_OFFSET);
+
+    /* Clear Underrun */
+    bd->flags &= ~BD_TX_TOEUN;
+
+    /* Clear Truncation */
+    bd->flags &= ~BD_TX_TR;
+}
+
+void etsec_walk_tx_ring(eTSEC *etsec, int ring_nbr)
+{
+    hwaddr        ring_base = 0;
+    hwaddr        bd_addr   = 0;
+    eTSEC_rxtx_bd bd;
+    uint16_t      bd_flags;
+
+    if (!(etsec->regs[MACCFG1].value & MACCFG1_TX_EN)) {
+        RING_DEBUG("%s: MAC Transmit not enabled\n", __func__);
+        return;
+    }
+
+    ring_base = (hwaddr)(etsec->regs[TBASEH].value & 0xF) << 32;
+    ring_base += etsec->regs[TBASE0 + ring_nbr].value & ~0x7;
+    bd_addr    = etsec->regs[TBPTR0 + ring_nbr].value & ~0x7;
+
+    do {
+        read_buffer_descriptor(etsec, bd_addr, &bd);
+
+#ifdef DEBUG_BD
+        print_bd(bd,
+                 eTSEC_TRANSMIT,
+                 (bd_addr - ring_base) / sizeof(eTSEC_rxtx_bd));
+
+#endif  /* DEBUG_BD */
+
+        /* Save flags before BD update */
+        bd_flags = bd.flags;
+
+        if (bd_flags & BD_TX_READY) {
+            process_tx_bd(etsec, &bd);
+
+            /* Write back BD after update */
+            write_buffer_descriptor(etsec, bd_addr, &bd);
+        }
+
+        /* Wrap or next BD */
+        if (bd_flags & BD_WRAP) {
+            bd_addr = ring_base;
+        } else {
+            bd_addr += sizeof(eTSEC_rxtx_bd);
+        }
+
+    } while (bd_addr != ring_base);
+
+    bd_addr = ring_base;
+
+    /* Save the Buffer Descriptor Pointers to current bd */
+    etsec->regs[TBPTR0 + ring_nbr].value = bd_addr;
+
+    /* Set transmit halt THLTx */
+    etsec->regs[TSTAT].value |= 1 << (31 - ring_nbr);
+}
+
+static void fill_rx_bd(eTSEC          *etsec,
+                       eTSEC_rxtx_bd  *bd,
+                       const uint8_t **buf,
+                       size_t         *size)
+{
+    uint16_t to_write;
+    hwaddr   bufptr = bd->bufptr +
+        ((hwaddr)(etsec->regs[TBDBPH].value & 0xF) << 32);
+    uint8_t  padd[etsec->rx_padding];
+    uint8_t  rem;
+
+    RING_DEBUG("eTSEC fill Rx buffer @ 0x%016" HWADDR_PRIx
+               " size:%zu(padding + crc:%u) + fcb:%u\n",
+               bufptr, *size, etsec->rx_padding, etsec->rx_fcb_size);
+
+    bd->length = 0;
+
+    /* This operation will only write FCB */
+    if (etsec->rx_fcb_size != 0) {
+
+        cpu_physical_memory_write(bufptr, etsec->rx_fcb, etsec->rx_fcb_size);
+
+        bufptr             += etsec->rx_fcb_size;
+        bd->length         += etsec->rx_fcb_size;
+        etsec->rx_fcb_size  = 0;
+
+    }
+
+    /* We remove padding from the computation of to_write because it is not
+     * allocated in the buffer.
+     */
+    to_write = MIN(*size - etsec->rx_padding,
+                   etsec->regs[MRBLR].value - etsec->rx_fcb_size);
+
+    /* This operation can only write packet data and no padding */
+    if (to_write > 0) {
+        cpu_physical_memory_write(bufptr, *buf, to_write);
+
+        *buf   += to_write;
+        bufptr += to_write;
+        *size  -= to_write;
+
+        bd->flags  &= ~BD_RX_EMPTY;
+        bd->length += to_write;
+    }
+
+    if (*size == etsec->rx_padding) {
+        /* The remaining bytes are only for padding which is not actually
+         * allocated in the data buffer.
+         */
+
+        rem = MIN(etsec->regs[MRBLR].value - bd->length, etsec->rx_padding);
+
+        if (rem > 0) {
+            memset(padd, 0x0, sizeof(padd));
+            etsec->rx_padding -= rem;
+            *size             -= rem;
+            bd->length        += rem;
+            cpu_physical_memory_write(bufptr, padd, rem);
+        }
+    }
+}
+
+static void rx_init_frame(eTSEC *etsec, const uint8_t *buf, size_t size)
+{
+    uint32_t fcb_size = 0;
+    uint8_t  prsdep   = (etsec->regs[RCTRL].value >> RCTRL_PRSDEP_OFFSET)
+        & RCTRL_PRSDEP_MASK;
+
+    if (prsdep != 0) {
+        /* Prepend FCB (FCB size + RCTRL[PAL]) */
+        fcb_size = 8 + ((etsec->regs[RCTRL].value >> 16) & 0x1F);
+
+        etsec->rx_fcb_size = fcb_size;
+
+        /* TODO: fill_FCB(etsec); */
+        memset(etsec->rx_fcb, 0x0, sizeof(etsec->rx_fcb));
+
+    } else {
+        etsec->rx_fcb_size = 0;
+    }
+
+    if (etsec->rx_buffer != NULL) {
+        g_free(etsec->rx_buffer);
+    }
+
+    /* Do not copy the frame for now */
+    etsec->rx_buffer     = (uint8_t *)buf;
+    etsec->rx_buffer_len = size;
+
+    /* CRC padding (We don't have to compute the CRC) */
+    etsec->rx_padding = 4;
+
+    etsec->rx_first_in_frame = 1;
+    etsec->rx_remaining_data = etsec->rx_buffer_len;
+    RING_DEBUG("%s: rx_buffer_len:%u rx_padding+crc:%u\n", __func__,
+               etsec->rx_buffer_len, etsec->rx_padding);
+}
+
+void etsec_rx_ring_write(eTSEC *etsec, const uint8_t *buf, size_t size)
+{
+    int ring_nbr = 0;           /* Always use ring0 (no filer) */
+
+    if (etsec->rx_buffer_len != 0) {
+        RING_DEBUG("%s: We can't receive now,"
+                   " a buffer is already in the pipe\n", __func__);
+        return;
+    }
+
+    if (etsec->regs[RSTAT].value & 1 << (23 - ring_nbr)) {
+        RING_DEBUG("%s: The ring is halted\n", __func__);
+        return;
+    }
+
+    if (etsec->regs[DMACTRL].value & DMACTRL_GRS) {
+        RING_DEBUG("%s: Graceful receive stop\n", __func__);
+        return;
+    }
+
+    if (!(etsec->regs[MACCFG1].value & MACCFG1_RX_EN)) {
+        RING_DEBUG("%s: MAC Receive not enabled\n", __func__);
+        return;
+    }
+
+    if ((etsec->regs[RCTRL].value & RCTRL_RSF) && (size < 60)) {
+        /* CRC is not in the packet yet, so short frame is below 60 bytes */
+        RING_DEBUG("%s: Drop short frame\n", __func__);
+        return;
+    }
+
+    rx_init_frame(etsec, buf, size);
+
+    etsec_walk_rx_ring(etsec, ring_nbr);
+}
+
+void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
+{
+    hwaddr         ring_base     = 0;
+    hwaddr         bd_addr       = 0;
+    hwaddr         start_bd_addr = 0;
+    eTSEC_rxtx_bd  bd;
+    uint16_t       bd_flags;
+    size_t         remaining_data;
+    const uint8_t *buf;
+    uint8_t       *tmp_buf;
+    size_t         size;
+
+    if (etsec->rx_buffer_len == 0) {
+        /* No frame to send */
+        RING_DEBUG("No frame to send\n");
+        return;
+    }
+
+    remaining_data = etsec->rx_remaining_data + etsec->rx_padding;
+    buf            = etsec->rx_buffer
+        + (etsec->rx_buffer_len - etsec->rx_remaining_data);
+    size           = etsec->rx_buffer_len + etsec->rx_padding;
+
+    ring_base = (hwaddr)(etsec->regs[RBASEH].value & 0xF) << 32;
+    ring_base += etsec->regs[RBASE0 + ring_nbr].value & ~0x7;
+    start_bd_addr  = bd_addr = etsec->regs[RBPTR0 + ring_nbr].value & ~0x7;
+
+    do {
+        read_buffer_descriptor(etsec, bd_addr, &bd);
+
+#ifdef DEBUG_BD
+        print_bd(bd,
+                 eTSEC_RECEIVE,
+                 (bd_addr - ring_base) / sizeof(eTSEC_rxtx_bd));
+
+#endif  /* DEBUG_BD */
+
+        /* Save flags before BD update */
+        bd_flags = bd.flags;
+
+        if (bd_flags & BD_RX_EMPTY) {
+            fill_rx_bd(etsec, &bd, &buf, &remaining_data);
+
+            if (etsec->rx_first_in_frame) {
+                bd.flags |= BD_RX_FIRST;
+                etsec->rx_first_in_frame = 0;
+                etsec->rx_first_bd = bd;
+            }
+
+            /* Last in frame */
+            if (remaining_data == 0) {
+
+                /* Clear flags */
+
+                bd.flags &= ~0x7ff;
+
+                bd.flags |= BD_LAST;
+
+                /* NOTE: non-octet aligned frame is impossible in qemu */
+
+                if (size >= etsec->regs[MAXFRM].value) {
+                    /* frame length violation */
+                    qemu_log("%s frame length violation: size:%zu MAXFRM:%d\n",
+                           __func__, size, etsec->regs[MAXFRM].value);
+
+                    bd.flags |= BD_RX_LG;
+                }
+
+                if (size  < 64) {
+                    /* Short frame */
+                    bd.flags |= BD_RX_SH;
+                }
+
+                /* TODO: Broadcast and Multicast */
+
+                if (bd.flags | BD_INTERRUPT) {
+                    /* Set RXFx */
+                    etsec->regs[RSTAT].value |= 1 << (7 - ring_nbr);
+
+                    /* Set IEVENT */
+                    ievent_set(etsec, IEVENT_RXF);
+                }
+
+            } else {
+                if (bd.flags | BD_INTERRUPT) {
+                    /* Set IEVENT */
+                    ievent_set(etsec, IEVENT_RXB);
+                }
+            }
+
+            /* Write back BD after update */
+            write_buffer_descriptor(etsec, bd_addr, &bd);
+        }
+
+        /* Wrap or next BD */
+        if (bd_flags & BD_WRAP) {
+            bd_addr = ring_base;
+        } else {
+            bd_addr += sizeof(eTSEC_rxtx_bd);
+        }
+    } while (remaining_data != 0
+             && (bd_flags & BD_RX_EMPTY)
+             && bd_addr != start_bd_addr);
+
+    /* Reset ring ptr */
+    etsec->regs[RBPTR0 + ring_nbr].value = bd_addr;
+
+    /* The frame is too large to fit in the Rx ring */
+    if (remaining_data > 0) {
+
+        /* Set RSTAT[QHLTx] */
+        etsec->regs[RSTAT].value |= 1 << (23 - ring_nbr);
+
+        /* Save remaining data to send the end of the frame when the ring will
+         * be restarted
+         */
+        etsec->rx_remaining_data = remaining_data;
+
+        /* Copy the frame */
+        tmp_buf = g_malloc(size);
+        memcpy(tmp_buf, etsec->rx_buffer, size);
+        etsec->rx_buffer = tmp_buf;
+
+        RING_DEBUG("no empty RxBD available any more\n");
+    } else {
+        etsec->rx_buffer_len = 0;
+        etsec->rx_buffer     = NULL;
+    }
+
+    RING_DEBUG("eTSEC End of ring_write: remaining_data:%zu\n", remaining_data);
+}
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 074/130] spapr: support only ELF kernel images
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (72 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC) Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 075/130] moxie: fix load_elf() usage Alexander Graf
                   ` (56 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

Currently everybody uses ELF kernel images with "-kernel" option on
pseries machine but QEMU still tries to boot from an image even it
fails to recognize it is ELF. This produces undefined behaviour if
the user tries a kernel image compiled for another architecture.

This removes support of raw kernel images.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 5b21562..851ce4b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1313,11 +1313,6 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
             kernel_le = kernel_size > 0;
         }
         if (kernel_size < 0) {
-            kernel_size = load_image_targphys(kernel_filename,
-                                              KERNEL_LOAD_ADDR,
-                                              load_limit - KERNEL_LOAD_ADDR);
-        }
-        if (kernel_size < 0) {
             fprintf(stderr, "qemu: could not load kernel '%s'\n",
                     kernel_filename);
             exit(1);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 075/130] moxie: fix load_elf() usage
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (73 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 074/130] spapr: support only ELF kernel images Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 076/130] elf-loader: add more return codes Alexander Graf
                   ` (55 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

At the moment in the case of error, load_elf() returns -1 so load_kernel()
will not signal error at all.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/moxie/moxiesim.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
index ef4f3a8..a87ca6d 100644
--- a/hw/moxie/moxiesim.c
+++ b/hw/moxie/moxiesim.c
@@ -55,7 +55,7 @@ static void load_kernel(MoxieCPU *cpu, LoaderParams *loader_params)
                            &entry, &kernel_low, &kernel_high, 1,
                            ELF_MACHINE, 0);
 
-    if (!kernel_size) {
+    if (kernel_size <= 0) {
         fprintf(stderr, "qemu: could not load kernel '%s'\n",
                 loader_params->kernel_filename);
         exit(1);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 076/130] elf-loader: add more return codes
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (74 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 075/130] moxie: fix load_elf() usage Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 077/130] spapr: print more detailed error message on failed load_elf() Alexander Graf
                   ` (54 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

The existing load_elf() just returns -1 if it fails to load ELF. However
it could be smarter than this and tell more about the failure such as
wrong endianness or incompatible platform.

This adds additional return codes for wrong architecture, wrong
endianness and if the image is not ELF at all.

This adds a load_elf_strerror() helper to convert return codes into
string messages.

This fixes handling of what load_elf() returns for s390x, other
callers just check the return value for <0 and this remains unchanged.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/core/loader.c     | 30 ++++++++++++++++++++++++------
 hw/s390x/ipl.c       |  4 ++--
 include/hw/elf_ops.h | 19 ++++++++++++++-----
 include/hw/loader.h  |  6 ++++++
 4 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/hw/core/loader.c b/hw/core/loader.c
index e1c3f3a..b323c0c 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -284,12 +284,30 @@ static void *load_at(int fd, int offset, int size)
 #define SZ		64
 #include "hw/elf_ops.h"
 
+const char *load_elf_strerror(int error)
+{
+    switch (error) {
+    case 0:
+        return "No error";
+    case ELF_LOAD_FAILED:
+        return "Failed to load ELF";
+    case ELF_LOAD_NOT_ELF:
+        return "The image is not ELF";
+    case ELF_LOAD_WRONG_ARCH:
+        return "The image is from incompatible architecture";
+    case ELF_LOAD_WRONG_ENDIAN:
+        return "The image has incorrect endianness";
+    default:
+        return "Unknown error";
+    }
+}
+
 /* return < 0 if error, otherwise the number of bytes loaded in memory */
 int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
              void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
              uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb)
 {
-    int fd, data_order, target_data_order, must_swab, ret;
+    int fd, data_order, target_data_order, must_swab, ret = ELF_LOAD_FAILED;
     uint8_t e_ident[EI_NIDENT];
 
     fd = open(filename, O_RDONLY | O_BINARY);
@@ -302,8 +320,10 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
     if (e_ident[0] != ELFMAG0 ||
         e_ident[1] != ELFMAG1 ||
         e_ident[2] != ELFMAG2 ||
-        e_ident[3] != ELFMAG3)
+        e_ident[3] != ELFMAG3) {
+        ret = ELF_LOAD_NOT_ELF;
         goto fail;
+    }
 #ifdef HOST_WORDS_BIGENDIAN
     data_order = ELFDATA2MSB;
 #else
@@ -317,6 +337,7 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
     }
 
     if (target_data_order != e_ident[EI_DATA]) {
+        ret = ELF_LOAD_WRONG_ENDIAN;
         goto fail;
     }
 
@@ -329,12 +350,9 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
                          pentry, lowaddr, highaddr, elf_machine, clear_lsb);
     }
 
-    close(fd);
-    return ret;
-
  fail:
     close(fd);
-    return -1;
+    return ret;
 }
 
 static void bswap_uboot_header(uboot_image_header_t *hdr)
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 04fb1a8..32d38a0 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -98,10 +98,10 @@ static int s390_ipl_init(SysBusDevice *dev)
         uint64_t pentry = KERN_IMAGE_START;
         kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL,
                                NULL, 1, ELF_MACHINE, 0);
-        if (kernel_size == -1) {
+        if (kernel_size < 0) {
             kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);
         }
-        if (kernel_size == -1) {
+        if (kernel_size < 0) {
             fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);
             return -1;
         }
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index acc701e..c6b5129 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -201,6 +201,7 @@ static int glue(load_elf, SZ)(const char *name, int fd,
     uint64_t addr, low = (uint64_t)-1, high = 0;
     uint8_t *data = NULL;
     char label[128];
+    int ret = ELF_LOAD_FAILED;
 
     if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
         goto fail;
@@ -211,22 +212,30 @@ static int glue(load_elf, SZ)(const char *name, int fd,
     switch (elf_machine) {
         case EM_PPC64:
             if (EM_PPC64 != ehdr.e_machine)
-                if (EM_PPC != ehdr.e_machine)
+                if (EM_PPC != ehdr.e_machine) {
+                    ret = ELF_LOAD_WRONG_ARCH;
                     goto fail;
+                }
             break;
         case EM_X86_64:
             if (EM_X86_64 != ehdr.e_machine)
-                if (EM_386 != ehdr.e_machine)
+                if (EM_386 != ehdr.e_machine) {
+                    ret = ELF_LOAD_WRONG_ARCH;
                     goto fail;
+                }
             break;
         case EM_MICROBLAZE:
             if (EM_MICROBLAZE != ehdr.e_machine)
-                if (EM_MICROBLAZE_OLD != ehdr.e_machine)
+                if (EM_MICROBLAZE_OLD != ehdr.e_machine) {
+                    ret = ELF_LOAD_WRONG_ARCH;
                     goto fail;
+                }
             break;
         default:
-            if (elf_machine != ehdr.e_machine)
+            if (elf_machine != ehdr.e_machine) {
+                ret = ELF_LOAD_WRONG_ARCH;
                 goto fail;
+            }
     }
 
     if (pentry)
@@ -305,5 +314,5 @@ static int glue(load_elf, SZ)(const char *name, int fd,
  fail:
     g_free(data);
     g_free(phdr);
-    return -1;
+    return ret;
 }
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 91b0122..aaf08c3 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -15,6 +15,12 @@ int get_image_size(const char *filename);
 int load_image(const char *filename, uint8_t *addr); /* deprecated */
 int load_image_targphys(const char *filename, hwaddr,
                         uint64_t max_sz);
+
+#define ELF_LOAD_FAILED       -1
+#define ELF_LOAD_NOT_ELF      -2
+#define ELF_LOAD_WRONG_ARCH   -3
+#define ELF_LOAD_WRONG_ENDIAN -4
+const char *load_elf_strerror(int error);
 int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
              void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
              uint64_t *highaddr, int big_endian, int elf_machine,
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 077/130] spapr: print more detailed error message on failed load_elf()
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (75 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 076/130] elf-loader: add more return codes Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 078/130] target-ppc: Update external_htab even when HTAB is managed by kernel Alexander Graf
                   ` (53 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

This makes use of new error codes which load_elf() can return and
prints more informative error message.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 851ce4b..c9dfc6c 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1306,15 +1306,15 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
 
         kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,
                                NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);
-        if (kernel_size < 0) {
+        if (kernel_size == ELF_LOAD_WRONG_ENDIAN) {
             kernel_size = load_elf(kernel_filename,
                                    translate_kernel_address, NULL,
                                    NULL, &lowaddr, NULL, 0, ELF_MACHINE, 0);
             kernel_le = kernel_size > 0;
         }
         if (kernel_size < 0) {
-            fprintf(stderr, "qemu: could not load kernel '%s'\n",
-                    kernel_filename);
+            fprintf(stderr, "qemu: error loading %s: %s\n",
+                    kernel_filename, load_elf_strerror(kernel_size));
             exit(1);
         }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 078/130] target-ppc: Update external_htab even when HTAB is managed by kernel
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (76 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 077/130] spapr: print more detailed error message on failed load_elf() Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 079/130] qdev: Keep global allocation counter per bus Alexander Graf
                   ` (52 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, qemu-ppc, Aneesh Kumar K.V, aliguori,
	aurelien

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

We will use this in later patches to make sure we use the right load
functions when copying hpte entries.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index c9dfc6c..0989ed6 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -741,6 +741,13 @@ static void spapr_cpu_reset(void *opaque)
     env->spr[SPR_HIOR] = 0;
 
     env->external_htab = (uint8_t *)spapr->htab;
+    if (kvm_enabled() && !env->external_htab) {
+        /*
+         * HV KVM, set external_htab to 1 so our ppc_hash64_load_hpte*
+         * functions do the right thing.
+         */
+        env->external_htab = (void *)1;
+    }
     env->htab_base = -1;
     env->htab_mask = HTAB_SIZE(spapr) - 1;
     env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab |
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 079/130] qdev: Keep global allocation counter per bus
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (77 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 078/130] target-ppc: Update external_htab even when HTAB is managed by kernel Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 080/130] target-ppc: add extended opcodes for dcbt/dcbtst Alexander Graf
                   ` (51 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Markus Armbruster, blauwirbel, qemu-ppc, aliguori,
	aurelien

When we have 2 separate qdev devices that both create a qbus of the
same type without specifying a bus name or device name, we end up
with two buses of the same name, such as ide.0 on the Mac machines:

  dev: macio-ide, id ""
    bus: ide.0
      type IDE
  dev: macio-ide, id ""
    bus: ide.0
      type IDE

If we now spawn a device that connects to a ide.0 the last created
bus gets the device, with the first created bus inaccessible to the
command line.

After some discussion on IRC we concluded that the best quick fix way
forward for this is to make automated bus-class type based allocation
count a global counter. That's what this patch implements. With this
we instead get

  dev: macio-ide, id ""
    bus: ide.1
      type IDE
  dev: macio-ide, id ""
    bus: ide.0
      type IDE

on the example mentioned above.

This also means that if you did -device ...,bus=ide.0 you got a device
on the first bus (the last created one) before this patch and get that
device on the second one (the first created one) now.  Breaks
migration unless you change bus=ide.0 to bus=ide.1 on the destination.

This is intended and makes the bus enumeration work as expected.

As per review request follows a list of otherwise affected boards and
the reasoning for the conclusion that they are ok:

   target      machine         bus id              times
   ------      -------         ------              -----

   aarch64     n800            i2c-bus.0           2
   aarch64     n810            i2c-bus.0           2
   arm         n800            i2c-bus.0           2
   arm         n810            i2c-bus.0           2

-> Devices are only created explicitly on one of the two buses, using
   s->mpu->i2c[0], so no change to the guest.

   aarch64     vexpress-a15    virtio-mmio-bus.0   4
   aarch64     vexpress-a9     virtio-mmio-bus.0   4
   aarch64     virt            virtio-mmio-bus.0   32
   arm         vexpress-a15    virtio-mmio-bus.0   4
   arm         vexpress-a9     virtio-mmio-bus.0   4
   arm         virt            virtio-mmio-bus.0   32

-> Makes -device bus= work for all virtio-mmio buses.  Breaks
   migration.  Workaround for migration from old to new: specify
   virtio-mmio-bus.4 or .32 respectively rather than .0 on the
   destination.

   aarch64     xilinx-zynq-a9  usb-bus.0           2
   arm         xilinx-zynq-a9  usb-bus.0           2
   mips64el    fulong2e        usb-bus.0           2

-> Normal USB operation not affected. Migration driver needs command
   line to use the other bus.

   i386        isapc           ide.0               2
   x86_64      isapc           ide.0               2
   mips        mips            ide.0               2
   mips64      mips            ide.0               2
   mips64el    mips            ide.0               2
   mipsel      mips            ide.0               2
   ppc         g3beige         ide.0               2
   ppc         mac99           ide.0               2
   ppc         prep            ide.0               2
   ppc64       g3beige         ide.0               2
   ppc64       mac99           ide.0               2
   ppc64       prep            ide.0               2

-> Makes -device bus= work for all IDE buses.  Breaks migration.
   Workaround for migration from old to new: specify ide.1 rather than
   ide.0 on the destination.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Andreas Faerber <afaerber@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/core/qdev.c         | 20 +++++++++++++-------
 hw/i386/pc_piix.c      |  8 +++++++-
 include/hw/qdev-core.h |  2 ++
 3 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index c0b857f..380976a 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -440,27 +440,33 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id)
 static void qbus_realize(BusState *bus, DeviceState *parent, const char *name)
 {
     const char *typename = object_get_typename(OBJECT(bus));
+    BusClass *bc;
     char *buf;
-    int i,len;
+    int i, len, bus_id;
 
     bus->parent = parent;
 
     if (name) {
         bus->name = g_strdup(name);
     } else if (bus->parent && bus->parent->id) {
-        /* parent device has id -> use it for bus name */
+        /* parent device has id -> use it plus parent-bus-id for bus name */
+        bus_id = bus->parent->num_child_bus;
+
         len = strlen(bus->parent->id) + 16;
         buf = g_malloc(len);
-        snprintf(buf, len, "%s.%d", bus->parent->id, bus->parent->num_child_bus);
+        snprintf(buf, len, "%s.%d", bus->parent->id, bus_id);
         bus->name = buf;
     } else {
-        /* no id -> use lowercase bus type for bus name */
+        /* no id -> use lowercase bus type plus global bus-id for bus name */
+        bc = BUS_GET_CLASS(bus);
+        bus_id = bc->automatic_ids++;
+
         len = strlen(typename) + 16;
         buf = g_malloc(len);
-        len = snprintf(buf, len, "%s.%d", typename,
-                       bus->parent ? bus->parent->num_child_bus : 0);
-        for (i = 0; i < len; i++)
+        len = snprintf(buf, len, "%s.%d", typename, bus_id);
+        for (i = 0; i < len; i++) {
             buf[i] = qemu_tolower(buf[i]);
+        }
         bus->name = buf;
     }
 
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index d5dc1ef..ae1699d 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -221,10 +221,16 @@ static void pc_init1(QEMUMachineInitArgs *args,
     } else {
         for(i = 0; i < MAX_IDE_BUS; i++) {
             ISADevice *dev;
+            char busname[] = "ide.0";
             dev = isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i],
                                ide_irq[i],
                                hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
-            idebus[i] = qdev_get_child_bus(DEVICE(dev), "ide.0");
+            /*
+             * The ide bus name is ide.0 for the first bus and ide.1 for the
+             * second one.
+             */
+            busname[4] = '0' + i;
+            idebus[i] = qdev_get_child_bus(DEVICE(dev), busname);
         }
     }
 
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 276b336..1ed0691 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -176,6 +176,8 @@ struct BusClass {
     void (*reset)(BusState *bus);
     /* maximum devices allowed on the bus, 0: no limit. */
     int max_dev;
+    /* number of automatically allocated bus ids (e.g. ide.0) */
+    int automatic_ids;
 };
 
 typedef struct BusChild {
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 080/130] target-ppc: add extended opcodes for dcbt/dcbtst
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (78 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 079/130] qdev: Keep global allocation counter per bus Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 081/130] target-ppc: Fix xxpermdi When T==A or T==B Alexander Graf
                   ` (50 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, Cédric Le Goater, qemu-ppc,
	aliguori, aurelien

From: Cédric Le Goater <clg@fr.ibm.com>

The latest glibc provides a memrchr routine using an extended opcode
of the 'dcbt' instruction :

00000000000a7cc0 <memrchr>:
   a7cc0:       11 00 4c 3c     addis   r2,r12,17
   a7cc4:       b8 f8 42 38     addi    r2,r2,-1864
   a7cc8:       14 2a e3 7c     add     r7,r3,r5
   a7ccc:       d0 00 07 7c     neg     r0,r7
   a7cd0:       ff ff e7 38     addi    r7,r7,-1
   a7cd4:       78 1b 6a 7c     mr      r10,r3
   a7cd8:       24 06 e6 78     rldicr  r6,r7,0,56
   a7cdc:       60 00 20 39     li      r9,96
   a7ce0:       2c 32 09 7e     dcbtt   r9,r6
   ....

which breaks grep, and other commands, in TCG mode :

   invalid bits: 02000000 for opcode: 1f - 16 - 08 (7e09322c) 00003fff799feca0

This patch adds the extended opcodes for dcbt/dcbtst as no-ops just
like the 'dcbt' instruction.

Signed-off-by: Cédric Le Goater <clg@fr.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 951f15e..8885490 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9596,8 +9596,8 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
-GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE),
-GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE),
+GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE),
+GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
 GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
 GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 081/130] target-ppc: Fix xxpermdi When T==A or T==B
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (79 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 080/130] target-ppc: add extended opcodes for dcbt/dcbtst Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 082/130] target-ppc: Add Flag for bctar Alexander Graf
                   ` (49 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

The existing implementation of xxpermdi is defective if the target
VSR is also a source VSR.  This patch fixes the defect in this case
but also preserves the simpler, two TCG operation implementation
when the target is not once of the two sources.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 41 +++++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 8885490..655aca6 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7332,15 +7332,40 @@ static void gen_xxpermdi(DisasContext *ctx)
         return;
     }
 
-    if ((DM(ctx->opcode) & 2) == 0) {
-        tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)));
-    } else {
-        tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)));
-    }
-    if ((DM(ctx->opcode) & 1) == 0) {
-        tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xB(ctx->opcode)));
+    if (unlikely((xT(ctx->opcode) == xA(ctx->opcode)) ||
+                 (xT(ctx->opcode) == xB(ctx->opcode)))) {
+        TCGv_i64 xh, xl;
+
+        xh = tcg_temp_new_i64();
+        xl = tcg_temp_new_i64();
+
+        if ((DM(ctx->opcode) & 2) == 0) {
+            tcg_gen_mov_i64(xh, cpu_vsrh(xA(ctx->opcode)));
+        } else {
+            tcg_gen_mov_i64(xh, cpu_vsrl(xA(ctx->opcode)));
+        }
+        if ((DM(ctx->opcode) & 1) == 0) {
+            tcg_gen_mov_i64(xl, cpu_vsrh(xB(ctx->opcode)));
+        } else {
+            tcg_gen_mov_i64(xl, cpu_vsrl(xB(ctx->opcode)));
+        }
+
+        tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xh);
+        tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xl);
+
+        tcg_temp_free_i64(xh);
+        tcg_temp_free_i64(xl);
     } else {
-        tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xB(ctx->opcode)));
+        if ((DM(ctx->opcode) & 2) == 0) {
+            tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)));
+        } else {
+            tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)));
+        }
+        if ((DM(ctx->opcode) & 1) == 0) {
+            tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xB(ctx->opcode)));
+        } else {
+            tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xB(ctx->opcode)));
+        }
     }
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 082/130] target-ppc: Add Flag for bctar
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (80 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 081/130] target-ppc: Fix xxpermdi When T==A or T==B Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 083/130] target-ppc: Add Target Address SPR (TAR) to Power8 Alexander Graf
                   ` (48 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds a flag for the bctar instruction.  This instruction
is being introduced via Power ISA 2.07.

Also, the flag is added to the Power8 machine model since the P8
processor supports this instruction.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            | 6 ++++--
 target-ppc/translate_init.c | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index bb299d7..9a40d20 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1887,12 +1887,14 @@ enum {
     PPC2_FP_CVT_ISA206 = 0x0000000000000400ULL,
     /* ISA 2.06B floating point test instructions                            */
     PPC2_FP_TST_ISA206 = 0x0000000000000800ULL,
-
+    /* ISA 2.07 bctar instruction                                            */
+    PPC2_BCTAR_ISA207  = 0x0000000000001000ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
                         PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | \
-                        PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206)
+                        PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | \
+                        PPC2_BCTAR_ISA207)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 52a4f4f..b4328f6 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7159,7 +7159,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
     pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
-                        PPC2_FP_TST_ISA206;
+                        PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207;
     pcc->msr_mask = 0x800000000284FF36ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 083/130] target-ppc: Add Target Address SPR (TAR) to Power8
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (81 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 082/130] target-ppc: Add Flag for bctar Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 084/130] target-ppc: Add bctar Instruction Alexander Graf
                   ` (47 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds support for the Target Address Register (TAR) to the Power8
model.

Because supported SPRs are typically identified in an init_proc_*()
function and because the Power8 model is currently just using the
init_proc_POWER7() function, a new init_proc_POWER8() function
is added and plugged into the P8 model.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            |  1 +
 target-ppc/translate_init.c | 14 +++++++++++++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 9a40d20..d02fd04 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1508,6 +1508,7 @@ static inline int cpu_mmu_index (CPUPPCState *env)
 #define SPR_RCPU_L2U_RA2      (0x32A)
 #define SPR_MPC_MD_DBRAM1     (0x32A)
 #define SPR_RCPU_L2U_RA3      (0x32B)
+#define SPR_TAR               (0x32F)
 #define SPR_440_INV0          (0x370)
 #define SPR_440_INV1          (0x371)
 #define SPR_440_INV2          (0x372)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index b4328f6..cb84a8f 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7133,6 +7133,18 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data)
     pcc->l1_icache_size = 0x8000;
 }
 
+static void init_proc_POWER8(CPUPPCState *env)
+{
+    /* inherit P7 */
+    init_proc_POWER7(env);
+
+    /* P8 supports the TAR */
+    spr_register(env, SPR_TAR, "TAR",
+                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+}
+
 POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -7142,7 +7154,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
     dc->desc = "POWER8";
     pcc->pvr = CPU_POWERPC_POWER8_BASE;
     pcc->pvr_mask = CPU_POWERPC_POWER8_MASK;
-    pcc->init_proc = init_proc_POWER7;
+    pcc->init_proc = init_proc_POWER8;
     pcc->check_pow = check_pow_nocheck;
     pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
                        PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 084/130] target-ppc: Add bctar Instruction
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (82 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 083/130] target-ppc: Add Target Address SPR (TAR) to Power8 Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 085/130] target-ppc: Add Flag for ISA 2.07 Load/Store Quadword Instructions Alexander Graf
                   ` (46 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Branch Conditional to Address Register (bctar)
instruction.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 655aca6..6abe71a 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3745,6 +3745,7 @@ static void gen_b(DisasContext *ctx)
 #define BCOND_IM  0
 #define BCOND_LR  1
 #define BCOND_CTR 2
+#define BCOND_TAR 3
 
 static inline void gen_bcond(DisasContext *ctx, int type)
 {
@@ -3753,10 +3754,12 @@ static inline void gen_bcond(DisasContext *ctx, int type)
     TCGv target;
 
     ctx->exception = POWERPC_EXCP_BRANCH;
-    if (type == BCOND_LR || type == BCOND_CTR) {
+    if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
         target = tcg_temp_local_new();
         if (type == BCOND_CTR)
             tcg_gen_mov_tl(target, cpu_ctr);
+        else if (type == BCOND_TAR)
+            gen_load_spr(target, SPR_TAR);
         else
             tcg_gen_mov_tl(target, cpu_lr);
     } else {
@@ -3838,6 +3841,11 @@ static void gen_bclr(DisasContext *ctx)
     gen_bcond(ctx, BCOND_LR);
 }
 
+static void gen_bctar(DisasContext *ctx)
+{
+    gen_bcond(ctx, BCOND_TAR);
+}
+
 /***                      Condition register logical                       ***/
 #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
 static void glue(gen_, name)(DisasContext *ctx)                                       \
@@ -9594,6 +9602,7 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
 GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
 GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
+GEN_HANDLER_E(bctar, 0x13, 0x10, 0x11, 0, PPC_NONE, PPC2_BCTAR_ISA207),
 GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
 #if defined(TARGET_PPC64)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 085/130] target-ppc: Add Flag for ISA 2.07 Load/Store Quadword Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (83 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 084/130] target-ppc: Add bctar Instruction Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 086/130] target-ppc: Add is_user_mode Utility Routine Alexander Graf
                   ` (45 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds a flag to identify the load/store quadword instructions
that are introduced with Power ISA 2.07.

The flag is added to the Power8 model since P8 supports these
instructions.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            | 4 +++-
 target-ppc/translate_init.c | 3 ++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index d02fd04..365627b 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1890,12 +1890,14 @@ enum {
     PPC2_FP_TST_ISA206 = 0x0000000000000800ULL,
     /* ISA 2.07 bctar instruction                                            */
     PPC2_BCTAR_ISA207  = 0x0000000000001000ULL,
+    /* ISA 2.07 load/store quadword                                          */
+    PPC2_LSQ_ISA207    = 0x0000000000002000ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
                         PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | \
                         PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | \
-                        PPC2_BCTAR_ISA207)
+                        PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index cb84a8f..64f56de 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7171,7 +7171,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
     pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
-                        PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207;
+                        PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
+                        PPC2_LSQ_ISA207;
     pcc->msr_mask = 0x800000000284FF36ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 086/130] target-ppc: Add is_user_mode Utility Routine
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (84 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 085/130] target-ppc: Add Flag for ISA 2.07 Load/Store Quadword Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 087/130] target-ppc: Load Quadword Alexander Graf
                   ` (44 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds a boolean function is_user_mode that can be re-used
in translation code that is sensitive to the MSR[PR] (user-mode)
state.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 6abe71a..f6ff248 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -622,6 +622,20 @@ static opc_handler_t invalid_handler = {
     .handler = gen_invalid,
 };
 
+#if defined(TARGET_PPC64)
+/* NOTE: as this time, the only use of is_user_mode() is in 64 bit code.  And */
+/*       so the function is wrapped in the standard 64-bit ifdef in order to  */
+/*       avoid compiler warnings in 32-bit implementations.                   */
+static bool is_user_mode(DisasContext *ctx)
+{
+#if defined(CONFIG_USER_ONLY)
+    return true;
+#else
+    return ctx->mem_idx == 0;
+#endif
+}
+#endif
+
 /***                           Integer comparison                          ***/
 
 static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 087/130] target-ppc: Load Quadword
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (85 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 086/130] target-ppc: Add is_user_mode Utility Routine Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 088/130] target-ppc: Store Quadword Alexander Graf
                   ` (43 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Book I (user space) Load Quadword (lq) instruction.
This instruction was introduced into Book I in Power ISA V2.07.  Previous
versions of the architecture supported this as a privileged instruction.
Previous versions of the architecture also did not support Little Endian
mode.

Note that this patch also adds the PPC_64BX flag to the Power8 model,
which enables the lq instruction.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c      | 36 ++++++++++++++++++++++--------------
 target-ppc/translate_init.c |  2 +-
 2 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f6ff248..06372b9 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -2872,36 +2872,44 @@ static void gen_ld(DisasContext *ctx)
 /* lq */
 static void gen_lq(DisasContext *ctx)
 {
-#if defined(CONFIG_USER_ONLY)
-    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
     int ra, rd;
     TCGv EA;
 
-    /* Restore CPU state */
-    if (unlikely(ctx->mem_idx == 0)) {
+    /* lq is a legal user mode instruction starting in ISA 2.07 */
+    bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
+    bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
+
+    if (!legal_in_user_mode && is_user_mode(ctx)) {
         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
         return;
     }
+
+    if (!le_is_supported && ctx->le_mode) {
+        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
+        return;
+    }
+
     ra = rA(ctx->opcode);
     rd = rD(ctx->opcode);
     if (unlikely((rd & 1) || rd == ra)) {
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         return;
     }
-    if (unlikely(ctx->le_mode)) {
-        /* Little-endian mode is not handled */
-        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
-        return;
-    }
+
     gen_set_access_type(ctx, ACCESS_INT);
     EA = tcg_temp_new();
     gen_addr_imm_index(ctx, EA, 0x0F);
-    gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
-    gen_addr_add(ctx, EA, EA, 8);
-    gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
+
+    if (unlikely(ctx->le_mode)) {
+        gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
+        gen_addr_add(ctx, EA, EA, 8);
+        gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
+    } else {
+        gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
+        gen_addr_add(ctx, EA, EA, 8);
+        gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
+    }
     tcg_temp_free(EA);
-#endif
 }
 #endif
 
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 64f56de..b9576ac 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7165,7 +7165,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                        PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
                        PPC_MEM_SYNC | PPC_MEM_EIEIO |
                        PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
-                       PPC_64B | PPC_ALTIVEC |
+                       PPC_64B | PPC_64BX | PPC_ALTIVEC |
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 088/130] target-ppc: Store Quadword
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (86 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 087/130] target-ppc: Load Quadword Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 089/130] target-ppc: Add Load Quadword and Reserve Alexander Graf
                   ` (42 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds support for the Store Quadword instruction in user mode.  Prior
to Power ISA 2.07, stq was legal only in privileged mode.  Support for Little
Endian mode is also new in ISA 2.07.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 06372b9..72eff90 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -2995,34 +2995,41 @@ static void gen_std(DisasContext *ctx)
     TCGv EA;
 
     rs = rS(ctx->opcode);
-    if ((ctx->opcode & 0x3) == 0x2) {
-#if defined(CONFIG_USER_ONLY)
-        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
-#else
-        /* stq */
-        if (unlikely(ctx->mem_idx == 0)) {
+    if ((ctx->opcode & 0x3) == 0x2) { /* stq */
+
+        bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
+        bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
+
+        if (!legal_in_user_mode && is_user_mode(ctx)) {
             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
             return;
         }
-        if (unlikely(rs & 1)) {
-            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
+
+        if (!le_is_supported && ctx->le_mode) {
+            gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
             return;
         }
-        if (unlikely(ctx->le_mode)) {
-            /* Little-endian mode is not handled */
-            gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
+
+        if (unlikely(rs & 1)) {
+            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
             return;
         }
         gen_set_access_type(ctx, ACCESS_INT);
         EA = tcg_temp_new();
         gen_addr_imm_index(ctx, EA, 0x03);
-        gen_qemu_st64(ctx, cpu_gpr[rs], EA);
-        gen_addr_add(ctx, EA, EA, 8);
-        gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
+
+        if (unlikely(ctx->le_mode)) {
+            gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
+            gen_addr_add(ctx, EA, EA, 8);
+            gen_qemu_st64(ctx, cpu_gpr[rs], EA);
+        } else {
+            gen_qemu_st64(ctx, cpu_gpr[rs], EA);
+            gen_addr_add(ctx, EA, EA, 8);
+            gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
+        }
         tcg_temp_free(EA);
-#endif
     } else {
-        /* std / stdu */
+        /* std / stdu*/
         if (Rc(ctx->opcode)) {
             if (unlikely(rA(ctx->opcode) == 0)) {
                 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 089/130] target-ppc: Add Load Quadword and Reserve
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (87 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 088/130] target-ppc: Store Quadword Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 090/130] target-ppc: Add Store Quadword Conditional Alexander Graf
                   ` (41 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Load Quadword and Reserve (lqarx) instruction,
which is new in Power ISA 2.07.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h       |  1 +
 target-ppc/translate.c | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 365627b..7cf7255 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -926,6 +926,7 @@ struct CPUPPCState {
     target_ulong reserve_addr;
     /* Reservation value */
     target_ulong reserve_val;
+    target_ulong reserve_val2;
     /* Reservation store address */
     target_ulong reserve_ea;
     /* Reserved store source register and size */
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 72eff90..13c9802 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3359,6 +3359,42 @@ STCX(stwcx_, 4);
 /* ldarx */
 LARX(ldarx, 8, ld64);
 
+/* lqarx */
+static void gen_lqarx(DisasContext *ctx)
+{
+    TCGv EA;
+    int rd = rD(ctx->opcode);
+    TCGv gpr1, gpr2;
+
+    if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) ||
+                 (rd == rB(ctx->opcode)))) {
+        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
+        return;
+    }
+
+    gen_set_access_type(ctx, ACCESS_RES);
+    EA = tcg_temp_local_new();
+    gen_addr_reg_index(ctx, EA);
+    gen_check_align(ctx, EA, 15);
+    if (unlikely(ctx->le_mode)) {
+        gpr1 = cpu_gpr[rd+1];
+        gpr2 = cpu_gpr[rd];
+    } else {
+        gpr1 = cpu_gpr[rd];
+        gpr2 = cpu_gpr[rd+1];
+    }
+    gen_qemu_ld64(ctx, gpr1, EA);
+    tcg_gen_mov_tl(cpu_reserve, EA);
+
+    gen_addr_add(ctx, EA, EA, 8);
+    gen_qemu_ld64(ctx, gpr2, EA);
+
+    tcg_gen_st_tl(gpr1, cpu_env, offsetof(CPUPPCState, reserve_val));
+    tcg_gen_st_tl(gpr2, cpu_env, offsetof(CPUPPCState, reserve_val2));
+
+    tcg_temp_free(EA);
+}
+
 /* stdcx. */
 STCX(stdcx_, 8);
 #endif /* defined(TARGET_PPC64) */
@@ -9623,6 +9659,7 @@ GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
 GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
 #if defined(TARGET_PPC64)
 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
+GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207),
 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
 #endif
 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 090/130] target-ppc: Add Store Quadword Conditional
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (88 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 089/130] target-ppc: Add Load Quadword and Reserve Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 091/130] target-ppc: Altivec 2.07: Add Instruction Flag Alexander Graf
                   ` (40 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Store Quadword Conditionl (stqcx.) instruction
which is introduced in Power ISA 2.07.

Signed-off-by: Tom Musta <tommusta@gmail.com>
[agraf: fix compile error when !TARGET_PPC64]
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 linux-user/main.c      | 18 +++++++++++++++++-
 target-ppc/translate.c | 21 +++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/linux-user/main.c b/linux-user/main.c
index 9192977..be9491b 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1492,7 +1492,7 @@ static int do_store_exclusive(CPUPPCState *env)
 {
     target_ulong addr;
     target_ulong page_addr;
-    target_ulong val;
+    target_ulong val, val2 __attribute__((unused));
     int flags;
     int segv = 0;
 
@@ -1515,6 +1515,13 @@ static int do_store_exclusive(CPUPPCState *env)
             case 4: segv = get_user_u32(val, addr); break;
 #if defined(TARGET_PPC64)
             case 8: segv = get_user_u64(val, addr); break;
+            case 16: {
+                segv = get_user_u64(val, addr);
+                if (!segv) {
+                    segv = get_user_u64(val2, addr + 8);
+                }
+                break;
+            }
 #endif
             default: abort();
             }
@@ -1526,6 +1533,15 @@ static int do_store_exclusive(CPUPPCState *env)
                 case 4: segv = put_user_u32(val, addr); break;
 #if defined(TARGET_PPC64)
                 case 8: segv = put_user_u64(val, addr); break;
+                case 16: {
+                    if (val2 == env->reserve_val2) {
+                        segv = put_user_u64(val, addr);
+                        if (!segv) {
+                            segv = put_user_u64(val2, addr + 8);
+                        }
+                    }
+                    break;
+                }
 #endif
                 default: abort();
                 }
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 13c9802..5839b6c 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3329,6 +3329,20 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
         gen_qemu_st32(ctx, cpu_gpr[reg], EA);
     } else if (size == 2) {
         gen_qemu_st16(ctx, cpu_gpr[reg], EA);
+#if defined(TARGET_PPC64)
+    } else if (size == 16) {
+        TCGv gpr1, gpr2;
+        if (unlikely(ctx->le_mode)) {
+            gpr1 = cpu_gpr[reg+1];
+            gpr2 = cpu_gpr[reg];
+        } else {
+            gpr1 = cpu_gpr[reg];
+            gpr2 = cpu_gpr[reg+1];
+        }
+        gen_qemu_st64(ctx, gpr1, EA);
+        gen_addr_add(ctx, EA, EA, 8);
+        gen_qemu_st64(ctx, gpr2, EA);
+#endif
     } else {
         gen_qemu_st8(ctx, cpu_gpr[reg], EA);
     }
@@ -3341,6 +3355,11 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
 static void gen_##name(DisasContext *ctx)                 \
 {                                                         \
     TCGv t0;                                              \
+    if (unlikely((len == 16) && (rD(ctx->opcode) & 1))) { \
+        gen_inval_exception(ctx,                          \
+                            POWERPC_EXCP_INVAL_INVAL);    \
+        return;                                           \
+    }                                                     \
     gen_set_access_type(ctx, ACCESS_RES);                 \
     t0 = tcg_temp_local_new();                            \
     gen_addr_reg_index(ctx, t0);                          \
@@ -3397,6 +3416,7 @@ static void gen_lqarx(DisasContext *ctx)
 
 /* stdcx. */
 STCX(stdcx_, 8);
+STCX(stqcx_, 16);
 #endif /* defined(TARGET_PPC64) */
 
 /* sync */
@@ -9661,6 +9681,7 @@ GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
 GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
 GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207),
 GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
+GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207),
 #endif
 GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
 GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 091/130] target-ppc: Altivec 2.07: Add Instruction Flag
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (89 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 090/130] target-ppc: Add Store Quadword Conditional Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 092/130] target-ppc: Altivec 2.07: Update AVR Structure Alexander Graf
                   ` (39 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds a flag that will be used to tag the Altivec instructions
introduced in Power ISA Version 2.07.

The flag is added to Power8 model since P8 supports these instructions.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h            | 5 ++++-
 target-ppc/translate_init.c | 2 +-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 7cf7255..88c2788 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1893,12 +1893,15 @@ enum {
     PPC2_BCTAR_ISA207  = 0x0000000000001000ULL,
     /* ISA 2.07 load/store quadword                                          */
     PPC2_LSQ_ISA207    = 0x0000000000002000ULL,
+    /* ISA 2.07 Altivec                                                      */
+    PPC2_ALTIVEC_207   = 0x0000000000004000ULL,
 
 #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
                         PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
                         PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | \
                         PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | \
-                        PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207)
+                        PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | \
+                        PPC2_ALTIVEC_207)
 };
 
 /*****************************************************************************/
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index b9576ac..9dd8c1c 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7172,7 +7172,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
                         PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
                         PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
                         PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |
-                        PPC2_LSQ_ISA207;
+                        PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207;
     pcc->msr_mask = 0x800000000284FF36ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 092/130] target-ppc: Altivec 2.07: Update AVR Structure
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (90 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 091/130] target-ppc: Altivec 2.07: Add Instruction Flag Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 093/130] target-ppc: Altivec 2.07: Add GEN_VXFORM3 Alexander Graf
                   ` (38 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch updates the ppc_avr_t data structure to include elements for
signed 64-bit integers and (conditionally) unsigned 128 bit integers.
These elements will be in instructions models later on in this patch series.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/cpu.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 88c2788..7ccf4c6 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -352,6 +352,10 @@ union ppc_avr_t {
     int16_t s16[8];
     int32_t s32[4];
     uint64_t u64[2];
+    int64_t s64[2];
+#ifdef CONFIG_INT128
+    __uint128_t u128;
+#endif
 };
 
 #if !defined(CONFIG_USER_ONLY)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 093/130] target-ppc: Altivec 2.07: Add GEN_VXFORM3
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (91 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 092/130] target-ppc: Altivec 2.07: Update AVR Structure Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 094/130] target-ppc: Altivec 2.07: Add Support for Dual Altivec Instructions Alexander Graf
                   ` (37 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds generator macro for Altivec instructions that have 3
source AVR operands.  The macro is similar to the 2 operand form.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 5839b6c..85dad7f 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6885,6 +6885,25 @@ static void glue(gen_, name)(DisasContext *ctx)                         \
     tcg_temp_free_ptr(rd);                                              \
 }
 
+#define GEN_VXFORM3(name, opc2, opc3)                                   \
+static void glue(gen_, name)(DisasContext *ctx)                         \
+{                                                                       \
+    TCGv_ptr ra, rb, rc, rd;                                            \
+    if (unlikely(!ctx->altivec_enabled)) {                              \
+        gen_exception(ctx, POWERPC_EXCP_VPU);                           \
+        return;                                                         \
+    }                                                                   \
+    ra = gen_avr_ptr(rA(ctx->opcode));                                  \
+    rb = gen_avr_ptr(rB(ctx->opcode));                                  \
+    rc = gen_avr_ptr(rC(ctx->opcode));                                  \
+    rd = gen_avr_ptr(rD(ctx->opcode));                                  \
+    gen_helper_##name(rd, ra, rb, rc);                                  \
+    tcg_temp_free_ptr(ra);                                              \
+    tcg_temp_free_ptr(rb);                                              \
+    tcg_temp_free_ptr(rc);                                              \
+    tcg_temp_free_ptr(rd);                                              \
+}
+
 GEN_VXFORM(vaddubm, 0, 0);
 GEN_VXFORM(vadduhm, 0, 1);
 GEN_VXFORM(vadduwm, 0, 2);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 094/130] target-ppc: Altivec 2.07: Add Support for Dual Altivec Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (92 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 093/130] target-ppc: Altivec 2.07: Add GEN_VXFORM3 Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 095/130] target-ppc: Altivec 2.07: Add Opcode Macro for VX Form Instructions Alexander Graf
                   ` (36 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

Some Alitvec instructions introduced in Power ISA Version 2.07 use bit 31
(aka the "Rc" bit) as an opcode bit.  However, QEMU for PowerPC uses
bits 0-5 and 21-30 for opcodes and not bit 31.

This patch introduces macros that will handle this situation by injecting
an auxiliary handler which decodes bit 31 in invokes one of two standard
handlers.  Since the instructions are not, in general, from the same version
of the ISA, two sets of PPC_*/PPC2_* instruction tags are supported.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 85dad7f..ffcee7f 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6904,6 +6904,26 @@ static void glue(gen_, name)(DisasContext *ctx)                         \
     tcg_temp_free_ptr(rd);                                              \
 }
 
+/*
+ * Support for Altivec instruction pairs that use bit 31 (Rc) as
+ * an opcode bit.  In general, these pairs come from different
+ * versions of the ISA, so we must also support a pair of flags for
+ * each instruction.
+ */
+#define GEN_VXFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1)          \
+static void glue(gen_, name0##_##name1)(DisasContext *ctx)             \
+{                                                                      \
+    if ((Rc(ctx->opcode) == 0) &&                                      \
+        ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
+        gen_##name0(ctx);                                              \
+    } else if ((Rc(ctx->opcode) == 1) &&                               \
+        ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
+        gen_##name1(ctx);                                              \
+    } else {                                                           \
+        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);            \
+    }                                                                  \
+}
+
 GEN_VXFORM(vaddubm, 0, 0);
 GEN_VXFORM(vadduhm, 0, 1);
 GEN_VXFORM(vadduwm, 0, 2);
@@ -10260,6 +10280,10 @@ GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
 #undef GEN_VXFORM
 #define GEN_VXFORM(name, opc2, opc3)                                    \
 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
+#undef GEN_VXFORM_DUAL
+#define GEN_VXFORM_DUAL(name0, name1, opc2, opc3, type0, type1) \
+GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, type0, type1)
+
 GEN_VXFORM(vaddubm, 0, 0),
 GEN_VXFORM(vadduhm, 0, 1),
 GEN_VXFORM(vadduwm, 0, 2),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 095/130] target-ppc: Altivec 2.07: Add Opcode Macro for VX Form Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (93 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 094/130] target-ppc: Altivec 2.07: Add Support for Dual Altivec Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 096/130] target-ppc: Altivec 2.07: Add Support for R-Form Dual Instructions Alexander Graf
                   ` (35 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds a macro to insert an entry into the opcode table for Altivec
Power ISA Version 2.07 instructions.  The macro is similar to the GEN_VXFORM macro
except that it tags the entry with the PPC2_ALTIVEC_207 flag rather than
PPC_ALTIVEC.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ffcee7f..a55789f 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -10280,6 +10280,11 @@ GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
 #undef GEN_VXFORM
 #define GEN_VXFORM(name, opc2, opc3)                                    \
 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
+
+#undef GEN_VXFORM_207
+#define GEN_VXFORM_207(name, opc2, opc3) \
+GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
+
 #undef GEN_VXFORM_DUAL
 #define GEN_VXFORM_DUAL(name0, name1, opc2, opc3, type0, type1) \
 GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, type0, type1)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 096/130] target-ppc: Altivec 2.07: Add Support for R-Form Dual Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (94 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 095/130] target-ppc: Altivec 2.07: Add Opcode Macro for VX Form Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 097/130] target-ppc: Altivec 2.07: Vector Logical Instructions Alexander Graf
                   ` (34 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

Some Alitvec instructions introduced in Power ISA Version 2.07 use bit 31
(aka the "Rc" bit) as an opcode but also use bit 21 as an actual Rc
bit.  QEMU for PowerPC typically uses bits 0-5 and 21-30 for opcodes.

This patch introduces a generator macro that injects an auxiliary handler
which decodes both bits 21 and 31 and invokes one of four standard
handlers.  Since the instructions are not, in general, from the same version
of the ISA, two sets of PPC_*/PPC2_* flags are supported.

This patch also introduces a macro to insert two entries into the opcode
table -- one for bit 21 equal to 0 and one for bit 21 equal to 1.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index a55789f..75ab70b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -387,6 +387,8 @@ EXTRACT_HELPER(opc2, 1, 5);
 EXTRACT_HELPER(opc3, 6, 5);
 /* Update Cr0 flags */
 EXTRACT_HELPER(Rc, 0, 1);
+/* Update Cr6 flags (Altivec) */
+EXTRACT_HELPER(Rc21, 10, 1);
 /* Destination */
 EXTRACT_HELPER(rD, 21, 5);
 /* Source */
@@ -7032,6 +7034,34 @@ static void glue(gen_, name)(DisasContext *ctx)                         \
     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
 
+/*
+ * Support for Altivec instructions that use bit 31 (Rc) as an opcode
+ * bit but also use bit 21 as an actual Rc bit.  In general, thse pairs
+ * come from different versions of the ISA, so we must also support a
+ * pair of flags for each instruction.
+ */
+#define GEN_VXRFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1)     \
+static void glue(gen_, name0##_##name1)(DisasContext *ctx)             \
+{                                                                      \
+    if ((Rc(ctx->opcode) == 0) &&                                      \
+        ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
+        if (Rc21(ctx->opcode) == 0) {                                  \
+            gen_##name0(ctx);                                          \
+        } else {                                                       \
+            gen_##name0##_(ctx);                                       \
+        }                                                              \
+    } else if ((Rc(ctx->opcode) == 1) &&                               \
+        ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
+        if (Rc21(ctx->opcode) == 0) {                                  \
+            gen_##name1(ctx);                                          \
+        } else {                                                       \
+            gen_##name1##_(ctx);                                       \
+        }                                                              \
+    } else {                                                           \
+        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);            \
+    }                                                                  \
+}
+
 GEN_VXRFORM(vcmpequb, 3, 0)
 GEN_VXRFORM(vcmpequh, 3, 1)
 GEN_VXRFORM(vcmpequw, 3, 2)
@@ -10289,6 +10319,11 @@ GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
 #define GEN_VXFORM_DUAL(name0, name1, opc2, opc3, type0, type1) \
 GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, type0, type1)
 
+#undef GEN_VXRFORM_DUAL
+#define GEN_VXRFORM_DUAL(name0, name1, opc2, opc3, tp0, tp1) \
+GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, tp0, tp1), \
+GEN_HANDLER_E(name0##_##name1, 0x4, opc2, (opc3 | 0x10), 0x00000000, tp0, tp1),
+
 GEN_VXFORM(vaddubm, 0, 0),
 GEN_VXFORM(vadduhm, 0, 1),
 GEN_VXFORM(vadduwm, 0, 2),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 097/130] target-ppc: Altivec 2.07: Vector Logical Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (95 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 096/130] target-ppc: Altivec 2.07: Add Support for R-Form Dual Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 098/130] target-ppc: Altivec 2.07: Add/Subtract Unsigned Doubleword Modulo Alexander Graf
                   ` (33 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Logical Instructions that are introduced
in Power ISA Version 2.07: veqv, vnand and vorc.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 75ab70b..ed1cf1d 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6852,6 +6852,9 @@ GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
+GEN_VX_LOGICAL(veqv, tcg_gen_eqv_i64, 2, 26);
+GEN_VX_LOGICAL(vnand, tcg_gen_nand_i64, 2, 22);
+GEN_VX_LOGICAL(vorc, tcg_gen_orc_i64, 2, 21);
 
 #define GEN_VXFORM(name, opc2, opc3)                                    \
 static void glue(gen_, name)(DisasContext *ctx)                                 \
@@ -10301,11 +10304,19 @@ GEN_VR_STVE(wx, 0x07, 0x06),
 #undef GEN_VX_LOGICAL
 #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
+
+#undef GEN_VX_LOGICAL_207
+#define GEN_VX_LOGICAL_207(name, tcg_op, opc2, opc3) \
+GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
+
 GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
 GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
 GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
 GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
 GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
+GEN_VX_LOGICAL_207(veqv, tcg_gen_eqv_i64, 2, 26),
+GEN_VX_LOGICAL_207(vnand, tcg_gen_nand_i64, 2, 22),
+GEN_VX_LOGICAL_207(vorc, tcg_gen_orc_i64, 2, 21),
 
 #undef GEN_VXFORM
 #define GEN_VXFORM(name, opc2, opc3)                                    \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 098/130] target-ppc: Altivec 2.07: Add/Subtract Unsigned Doubleword Modulo
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (96 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 097/130] target-ppc: Altivec 2.07: Vector Logical Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 099/130] target-ppc: Altivec 2.07: Change VMUL_DO to Support 64-bit Integers Alexander Graf
                   ` (32 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds two Altivec unsigned doublword modulo instructions that
are introduced in Power ISA Version V2.07:

  - vaddudm : Vector Add Unsigned Doubleword Modulo
  - vsubudm : Vector Subtrace Unsigned Doubleword Modulo

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     | 2 ++
 target-ppc/int_helper.c | 1 +
 target-ppc/translate.c  | 4 ++++
 3 files changed, 7 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index a4480e8..1106e29 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -109,9 +109,11 @@ DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64)
 DEF_HELPER_3(vaddubm, void, avr, avr, avr)
 DEF_HELPER_3(vadduhm, void, avr, avr, avr)
 DEF_HELPER_3(vadduwm, void, avr, avr, avr)
+DEF_HELPER_3(vaddudm, void, avr, avr, avr)
 DEF_HELPER_3(vsububm, void, avr, avr, avr)
 DEF_HELPER_3(vsubuhm, void, avr, avr, avr)
 DEF_HELPER_3(vsubuwm, void, avr, avr, avr)
+DEF_HELPER_3(vsubudm, void, avr, avr, avr)
 DEF_HELPER_3(vavgub, void, avr, avr, avr)
 DEF_HELPER_3(vavguh, void, avr, avr, avr)
 DEF_HELPER_3(vavguw, void, avr, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 71db3fb..3e36c0a 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -504,6 +504,7 @@ void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
 VARITH(ubm, u8)
 VARITH(uhm, u16)
 VARITH(uwm, u32)
+VARITH(udm, u64)
 #undef VARITH_DO
 #undef VARITH
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ed1cf1d..b1986f4 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6932,9 +6932,11 @@ static void glue(gen_, name0##_##name1)(DisasContext *ctx)             \
 GEN_VXFORM(vaddubm, 0, 0);
 GEN_VXFORM(vadduhm, 0, 1);
 GEN_VXFORM(vadduwm, 0, 2);
+GEN_VXFORM(vaddudm, 0, 3);
 GEN_VXFORM(vsububm, 0, 16);
 GEN_VXFORM(vsubuhm, 0, 17);
 GEN_VXFORM(vsubuwm, 0, 18);
+GEN_VXFORM(vsubudm, 0, 19);
 GEN_VXFORM(vmaxub, 1, 0);
 GEN_VXFORM(vmaxuh, 1, 1);
 GEN_VXFORM(vmaxuw, 1, 2);
@@ -10338,9 +10340,11 @@ GEN_HANDLER_E(name0##_##name1, 0x4, opc2, (opc3 | 0x10), 0x00000000, tp0, tp1),
 GEN_VXFORM(vaddubm, 0, 0),
 GEN_VXFORM(vadduhm, 0, 1),
 GEN_VXFORM(vadduwm, 0, 2),
+GEN_VXFORM_207(vaddudm, 0, 3),
 GEN_VXFORM(vsububm, 0, 16),
 GEN_VXFORM(vsubuhm, 0, 17),
 GEN_VXFORM(vsubuwm, 0, 18),
+GEN_VXFORM_207(vsubudm, 0, 19),
 GEN_VXFORM(vmaxub, 1, 0),
 GEN_VXFORM(vmaxuh, 1, 1),
 GEN_VXFORM(vmaxuw, 1, 2),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 099/130] target-ppc: Altivec 2.07: Change VMUL_DO to Support 64-bit Integers
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (97 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 098/130] target-ppc: Altivec 2.07: Add/Subtract Unsigned Doubleword Modulo Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 100/130] target-ppc: Altivec 2.07: Multiply Even/Odd Word Instructions Alexander Graf
                   ` (31 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This VMUL_DO macro provides support for the various vmule* and vmulo*
instructions.  These instructions multiply vector elements, producing
products that are one size larger; e.g. vmuleub multiplies unsigned 8-bit
elements and produces a 16 bit unsigned element.

The existing macro works correctly for the existing instructions (8-bit,
and 16-bit source elements) but does not work correctly for 32-bit
source elements.

This patch adds an explicit cast to the multiplicands, forcing them to be
of the target element type.  This is required for the forthcoming patches
that add the vmul[eo][us]w instructions.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/int_helper.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 3e36c0a..20d34e6 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -983,28 +983,30 @@ void helper_vmsumuhs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
     }
 }
 
-#define VMUL_DO(name, mul_element, prod_element, evenp)                 \
+#define VMUL_DO(name, mul_element, prod_element, cast, evenp)           \
     void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)       \
     {                                                                   \
         int i;                                                          \
                                                                         \
         VECTOR_FOR_INORDER_I(i, prod_element) {                         \
             if (evenp) {                                                \
-                r->prod_element[i] = a->mul_element[i * 2 + HI_IDX] *   \
-                    b->mul_element[i * 2 + HI_IDX];                     \
+                r->prod_element[i] =                                    \
+                    (cast)a->mul_element[i * 2 + HI_IDX] *              \
+                    (cast)b->mul_element[i * 2 + HI_IDX];               \
             } else {                                                    \
-                r->prod_element[i] = a->mul_element[i * 2 + LO_IDX] *   \
-                    b->mul_element[i * 2 + LO_IDX];                     \
+                r->prod_element[i] =                                    \
+                    (cast)a->mul_element[i * 2 + LO_IDX] *              \
+                    (cast)b->mul_element[i * 2 + LO_IDX];               \
             }                                                           \
         }                                                               \
     }
-#define VMUL(suffix, mul_element, prod_element)         \
-    VMUL_DO(mule##suffix, mul_element, prod_element, 1) \
-    VMUL_DO(mulo##suffix, mul_element, prod_element, 0)
-VMUL(sb, s8, s16)
-VMUL(sh, s16, s32)
-VMUL(ub, u8, u16)
-VMUL(uh, u16, u32)
+#define VMUL(suffix, mul_element, prod_element, cast)            \
+    VMUL_DO(mule##suffix, mul_element, prod_element, cast, 1)    \
+    VMUL_DO(mulo##suffix, mul_element, prod_element, cast, 0)
+VMUL(sb, s8, s16, int16_t)
+VMUL(sh, s16, s32, int32_t)
+VMUL(ub, u8, u16, uint16_t)
+VMUL(uh, u16, u32, uint32_t)
 #undef VMUL_DO
 #undef VMUL
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 100/130] target-ppc: Altivec 2.07: Multiply Even/Odd Word Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (98 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 099/130] target-ppc: Altivec 2.07: Change VMUL_DO to Support 64-bit Integers Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 101/130] target-ppc: Altivec 2.07: vmuluw Instruction Alexander Graf
                   ` (30 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Multilpy Even/Odd Word instructions that are introduced
in Power ISA Version 2.07:

  - Vector Multiply Even Unsigned Word (vmuleuw)
  - Vector Multiply Even Signed Word (vmulesw)
  - Vector Multiply Odd Unsigned Word (vmulouw)
  - Vector Multiply Odd Signed Word (vmulosw)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     | 4 ++++
 target-ppc/int_helper.c | 2 ++
 target-ppc/translate.c  | 8 ++++++++
 3 files changed, 14 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 1106e29..ca18447 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -166,12 +166,16 @@ DEF_HELPER_3(vmrghh, void, avr, avr, avr)
 DEF_HELPER_3(vmrghw, void, avr, avr, avr)
 DEF_HELPER_3(vmulesb, void, avr, avr, avr)
 DEF_HELPER_3(vmulesh, void, avr, avr, avr)
+DEF_HELPER_3(vmulesw, void, avr, avr, avr)
 DEF_HELPER_3(vmuleub, void, avr, avr, avr)
 DEF_HELPER_3(vmuleuh, void, avr, avr, avr)
+DEF_HELPER_3(vmuleuw, void, avr, avr, avr)
 DEF_HELPER_3(vmulosb, void, avr, avr, avr)
 DEF_HELPER_3(vmulosh, void, avr, avr, avr)
+DEF_HELPER_3(vmulosw, void, avr, avr, avr)
 DEF_HELPER_3(vmuloub, void, avr, avr, avr)
 DEF_HELPER_3(vmulouh, void, avr, avr, avr)
+DEF_HELPER_3(vmulouw, void, avr, avr, avr)
 DEF_HELPER_3(vsrab, void, avr, avr, avr)
 DEF_HELPER_3(vsrah, void, avr, avr, avr)
 DEF_HELPER_3(vsraw, void, avr, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 20d34e6..09590c7 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1005,8 +1005,10 @@ void helper_vmsumuhs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
     VMUL_DO(mulo##suffix, mul_element, prod_element, cast, 0)
 VMUL(sb, s8, s16, int16_t)
 VMUL(sh, s16, s32, int32_t)
+VMUL(sw, s32, s64, int64_t)
 VMUL(ub, u8, u16, uint16_t)
 VMUL(uh, u16, u32, uint32_t)
+VMUL(uw, u32, u64, uint64_t)
 #undef VMUL_DO
 #undef VMUL
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index b1986f4..4d2579d 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6963,12 +6963,16 @@ GEN_VXFORM(vmrglh, 6, 5);
 GEN_VXFORM(vmrglw, 6, 6);
 GEN_VXFORM(vmuloub, 4, 0);
 GEN_VXFORM(vmulouh, 4, 1);
+GEN_VXFORM(vmulouw, 4, 2);
 GEN_VXFORM(vmulosb, 4, 4);
 GEN_VXFORM(vmulosh, 4, 5);
+GEN_VXFORM(vmulosw, 4, 6);
 GEN_VXFORM(vmuleub, 4, 8);
 GEN_VXFORM(vmuleuh, 4, 9);
+GEN_VXFORM(vmuleuw, 4, 10);
 GEN_VXFORM(vmulesb, 4, 12);
 GEN_VXFORM(vmulesh, 4, 13);
+GEN_VXFORM(vmulesw, 4, 14);
 GEN_VXFORM(vslb, 2, 4);
 GEN_VXFORM(vslh, 2, 5);
 GEN_VXFORM(vslw, 2, 6);
@@ -10371,12 +10375,16 @@ GEN_VXFORM(vmrglh, 6, 5),
 GEN_VXFORM(vmrglw, 6, 6),
 GEN_VXFORM(vmuloub, 4, 0),
 GEN_VXFORM(vmulouh, 4, 1),
+GEN_VXFORM_207(vmulouw, 4, 2),
 GEN_VXFORM(vmulosb, 4, 4),
 GEN_VXFORM(vmulosh, 4, 5),
+GEN_VXFORM_207(vmulosw, 4, 6),
 GEN_VXFORM(vmuleub, 4, 8),
 GEN_VXFORM(vmuleuh, 4, 9),
+GEN_VXFORM_207(vmuleuw, 4, 10),
 GEN_VXFORM(vmulesb, 4, 12),
 GEN_VXFORM(vmulesh, 4, 13),
+GEN_VXFORM_207(vmulesw, 4, 14),
 GEN_VXFORM(vslb, 2, 4),
 GEN_VXFORM(vslh, 2, 5),
 GEN_VXFORM(vslw, 2, 6),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 101/130] target-ppc: Altivec 2.07: vmuluw Instruction
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (99 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 100/130] target-ppc: Altivec 2.07: Multiply Even/Odd Word Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 102/130] target-ppc: Altivec 2.07: Add Vector Count Leading Zeroes Alexander Graf
                   ` (29 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Multiply Unsigned Word Modulo (vmuluwm)
instruction.

The existing VARITH_DO macro is re-used to (trivially) instantiate
the helper code.

Since bits 21-31 of any vmuluwm instruction is 137, the instruction
is coded as a dual to vmulouw (bits 21-31 = 136).

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     | 1 +
 target-ppc/int_helper.c | 1 +
 target-ppc/translate.c  | 5 ++++-
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index ca18447..c20d50e 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -176,6 +176,7 @@ DEF_HELPER_3(vmulosw, void, avr, avr, avr)
 DEF_HELPER_3(vmuloub, void, avr, avr, avr)
 DEF_HELPER_3(vmulouh, void, avr, avr, avr)
 DEF_HELPER_3(vmulouw, void, avr, avr, avr)
+DEF_HELPER_3(vmuluwm, void, avr, avr, avr)
 DEF_HELPER_3(vsrab, void, avr, avr, avr)
 DEF_HELPER_3(vsrah, void, avr, avr, avr)
 DEF_HELPER_3(vsraw, void, avr, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 09590c7..7a50f4a 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -505,6 +505,7 @@ VARITH(ubm, u8)
 VARITH(uhm, u16)
 VARITH(uwm, u32)
 VARITH(udm, u64)
+VARITH_DO(muluwm, *, u32)
 #undef VARITH_DO
 #undef VARITH
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 4d2579d..ca253e0 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6964,6 +6964,9 @@ GEN_VXFORM(vmrglw, 6, 6);
 GEN_VXFORM(vmuloub, 4, 0);
 GEN_VXFORM(vmulouh, 4, 1);
 GEN_VXFORM(vmulouw, 4, 2);
+GEN_VXFORM(vmuluwm, 4, 2);
+GEN_VXFORM_DUAL(vmulouw, PPC_ALTIVEC, PPC_NONE,
+                vmuluwm, PPC_NONE, PPC2_ALTIVEC_207)
 GEN_VXFORM(vmulosb, 4, 4);
 GEN_VXFORM(vmulosh, 4, 5);
 GEN_VXFORM(vmulosw, 4, 6);
@@ -10375,7 +10378,7 @@ GEN_VXFORM(vmrglh, 6, 5),
 GEN_VXFORM(vmrglw, 6, 6),
 GEN_VXFORM(vmuloub, 4, 0),
 GEN_VXFORM(vmulouh, 4, 1),
-GEN_VXFORM_207(vmulouw, 4, 2),
+GEN_VXFORM_DUAL(vmulouw, vmuluwm, 4, 2, PPC_ALTIVEC, PPC_NONE),
 GEN_VXFORM(vmulosb, 4, 4),
 GEN_VXFORM(vmulosh, 4, 5),
 GEN_VXFORM_207(vmulosw, 4, 6),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 102/130] target-ppc: Altivec 2.07: Add Vector Count Leading Zeroes
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (100 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 101/130] target-ppc: Altivec 2.07: vmuluw Instruction Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 103/130] target-ppc: Altivec 2.07: Vector Population Count Instructions Alexander Graf
                   ` (28 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Count Leading Zeroes instructions introduced
in Power ISA Version 2.07 - vclzb, vclzh, vclzw and vclzd.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |  5 +++++
 target-ppc/int_helper.c | 29 +++++++++++++++++++++++++++++
 target-ppc/translate.c  |  9 +++++++++
 3 files changed, 43 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index c20d50e..7ca219f 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -273,6 +273,11 @@ DEF_HELPER_4(vcfsx, void, env, avr, avr, i32)
 DEF_HELPER_4(vctuxs, void, env, avr, avr, i32)
 DEF_HELPER_4(vctsxs, void, env, avr, avr, i32)
 
+DEF_HELPER_2(vclzb, void, avr, avr)
+DEF_HELPER_2(vclzh, void, avr, avr)
+DEF_HELPER_2(vclzw, void, avr, avr)
+DEF_HELPER_2(vclzd, void, avr, avr)
+
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
 DEF_HELPER_2(xsmuldp, void, env, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 7a50f4a..7fca9f0 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1524,6 +1524,35 @@ VUPK(lsh, s32, s16, UPKLO)
 #undef UPKHI
 #undef UPKLO
 
+#define VGENERIC_DO(name, element)                                      \
+    void helper_v##name(ppc_avr_t *r, ppc_avr_t *b)                     \
+    {                                                                   \
+        int i;                                                          \
+                                                                        \
+        VECTOR_FOR_INORDER_I(i, element) {                              \
+            r->element[i] = name(b->element[i]);                        \
+        }                                                               \
+    }
+
+#define clzb(v) ((v) ? clz32((uint32_t)(v) << 24) : 8)
+#define clzh(v) ((v) ? clz32((uint32_t)(v) << 16) : 16)
+#define clzw(v) clz32((v))
+#define clzd(v) clz64((v))
+
+VGENERIC_DO(clzb, u8)
+VGENERIC_DO(clzh, u16)
+VGENERIC_DO(clzw, u32)
+VGENERIC_DO(clzd, u64)
+
+#undef clzb
+#undef clzh
+#undef clzw
+#undef clzd
+
+
+#undef VGENERIC_DO
+
+
 #undef VECTOR_FOR_INORDER_I
 #undef HI_IDX
 #undef LO_IDX
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ca253e0..a1b85b5 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7283,6 +7283,10 @@ GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
 GEN_VAFORM_PAIRED(vsel, vperm, 21)
 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
 
+GEN_VXFORM_NOA(vclzb, 1, 28)
+GEN_VXFORM_NOA(vclzh, 1, 29)
+GEN_VXFORM_NOA(vclzw, 1, 30)
+GEN_VXFORM_NOA(vclzd, 1, 31)
 /***                           VSX extension                               ***/
 
 static inline TCGv_i64 cpu_vsrh(int n)
@@ -10504,6 +10508,11 @@ GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
 GEN_VAFORM_PAIRED(vsel, vperm, 21),
 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
 
+GEN_VXFORM_207(vclzb, 1, 28),
+GEN_VXFORM_207(vclzh, 1, 29),
+GEN_VXFORM_207(vclzw, 1, 30),
+GEN_VXFORM_207(vclzd, 1, 31),
+
 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
 GEN_HANDLER_E(lxsiwzx, 0x1F, 0x0C, 0x00, 0, PPC_NONE, PPC2_VSX207),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 103/130] target-ppc: Altivec 2.07: Vector Population Count Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (101 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 102/130] target-ppc: Altivec 2.07: Add Vector Count Leading Zeroes Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 104/130] target-ppc: Altivec 2.07: Vector Min/Max Doubleword Instructions Alexander Graf
                   ` (27 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Population Count instructions introduced in Power
ISA Version 2.07: vpopcntb, vpopcnth, vpopcntw and vpopcntd.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |  4 ++++
 target-ppc/int_helper.c | 14 ++++++++++++++
 target-ppc/translate.c  | 22 ++++++++++++++++++----
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 7ca219f..793877d 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -277,6 +277,10 @@ DEF_HELPER_2(vclzb, void, avr, avr)
 DEF_HELPER_2(vclzh, void, avr, avr)
 DEF_HELPER_2(vclzw, void, avr, avr)
 DEF_HELPER_2(vclzd, void, avr, avr)
+DEF_HELPER_2(vpopcntb, void, avr, avr)
+DEF_HELPER_2(vpopcnth, void, avr, avr)
+DEF_HELPER_2(vpopcntw, void, avr, avr)
+DEF_HELPER_2(vpopcntd, void, avr, avr)
 
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 7fca9f0..3b67ae3 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1549,6 +1549,20 @@ VGENERIC_DO(clzd, u64)
 #undef clzw
 #undef clzd
 
+#define popcntb(v) ctpop8(v)
+#define popcnth(v) ctpop16(v)
+#define popcntw(v) ctpop32(v)
+#define popcntd(v) ctpop64(v)
+
+VGENERIC_DO(popcntb, u8)
+VGENERIC_DO(popcnth, u16)
+VGENERIC_DO(popcntw, u32)
+VGENERIC_DO(popcntd, u64)
+
+#undef popcntb
+#undef popcnth
+#undef popcntw
+#undef popcntd
 
 #undef VGENERIC_DO
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index a1b85b5..e1f39e9 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7287,6 +7287,19 @@ GEN_VXFORM_NOA(vclzb, 1, 28)
 GEN_VXFORM_NOA(vclzh, 1, 29)
 GEN_VXFORM_NOA(vclzw, 1, 30)
 GEN_VXFORM_NOA(vclzd, 1, 31)
+GEN_VXFORM_NOA(vpopcntb, 1, 28)
+GEN_VXFORM_NOA(vpopcnth, 1, 29)
+GEN_VXFORM_NOA(vpopcntw, 1, 30)
+GEN_VXFORM_NOA(vpopcntd, 1, 31)
+GEN_VXFORM_DUAL(vclzb, PPC_NONE, PPC2_ALTIVEC_207, \
+                vpopcntb, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vclzh, PPC_NONE, PPC2_ALTIVEC_207, \
+                vpopcnth, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vclzw, PPC_NONE, PPC2_ALTIVEC_207, \
+                vpopcntw, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \
+                vpopcntd, PPC_NONE, PPC2_ALTIVEC_207)
+
 /***                           VSX extension                               ***/
 
 static inline TCGv_i64 cpu_vsrh(int n)
@@ -10508,10 +10521,11 @@ GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
 GEN_VAFORM_PAIRED(vsel, vperm, 21),
 GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
 
-GEN_VXFORM_207(vclzb, 1, 28),
-GEN_VXFORM_207(vclzh, 1, 29),
-GEN_VXFORM_207(vclzw, 1, 30),
-GEN_VXFORM_207(vclzd, 1, 31),
+GEN_VXFORM_DUAL(vclzb, vpopcntb, 1, 28, PPC_NONE, PPC2_ALTIVEC_207),
+GEN_VXFORM_DUAL(vclzh, vpopcnth, 1, 29, PPC_NONE, PPC2_ALTIVEC_207),
+GEN_VXFORM_DUAL(vclzw, vpopcntw, 1, 30, PPC_NONE, PPC2_ALTIVEC_207),
+GEN_VXFORM_DUAL(vclzd, vpopcntd, 1, 31, PPC_NONE, PPC2_ALTIVEC_207),
+
 
 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 104/130] target-ppc: Altivec 2.07: Vector Min/Max Doubleword Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (102 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 103/130] target-ppc: Altivec 2.07: Vector Population Count Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 105/130] target-ppc: Altivec 2.07: Pack " Alexander Graf
                   ` (26 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Minimum and Maximum Doubleword instructions
that are introduced in Power ISA Version 2.07.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     | 4 ++++
 target-ppc/int_helper.c | 2 ++
 target-ppc/translate.c  | 8 ++++++++
 3 files changed, 14 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 793877d..38bebea 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -123,15 +123,19 @@ DEF_HELPER_3(vavgsw, void, avr, avr, avr)
 DEF_HELPER_3(vminsb, void, avr, avr, avr)
 DEF_HELPER_3(vminsh, void, avr, avr, avr)
 DEF_HELPER_3(vminsw, void, avr, avr, avr)
+DEF_HELPER_3(vminsd, void, avr, avr, avr)
 DEF_HELPER_3(vmaxsb, void, avr, avr, avr)
 DEF_HELPER_3(vmaxsh, void, avr, avr, avr)
 DEF_HELPER_3(vmaxsw, void, avr, avr, avr)
+DEF_HELPER_3(vmaxsd, void, avr, avr, avr)
 DEF_HELPER_3(vminub, void, avr, avr, avr)
 DEF_HELPER_3(vminuh, void, avr, avr, avr)
 DEF_HELPER_3(vminuw, void, avr, avr, avr)
+DEF_HELPER_3(vminud, void, avr, avr, avr)
 DEF_HELPER_3(vmaxub, void, avr, avr, avr)
 DEF_HELPER_3(vmaxuh, void, avr, avr, avr)
 DEF_HELPER_3(vmaxuw, void, avr, avr, avr)
+DEF_HELPER_3(vmaxud, void, avr, avr, avr)
 DEF_HELPER_4(vcmpequb, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpequh, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpequw, void, env, avr, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 3b67ae3..fc2bff1 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -824,9 +824,11 @@ void helper_vmhraddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
 VMINMAX(sb, s8)
 VMINMAX(sh, s16)
 VMINMAX(sw, s32)
+VMINMAX(sd, s64)
 VMINMAX(ub, u8)
 VMINMAX(uh, u16)
 VMINMAX(uw, u32)
+VMINMAX(ud, u64)
 #undef VMINMAX_DO
 #undef VMINMAX
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index e1f39e9..95a751c 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6940,15 +6940,19 @@ GEN_VXFORM(vsubudm, 0, 19);
 GEN_VXFORM(vmaxub, 1, 0);
 GEN_VXFORM(vmaxuh, 1, 1);
 GEN_VXFORM(vmaxuw, 1, 2);
+GEN_VXFORM(vmaxud, 1, 3);
 GEN_VXFORM(vmaxsb, 1, 4);
 GEN_VXFORM(vmaxsh, 1, 5);
 GEN_VXFORM(vmaxsw, 1, 6);
+GEN_VXFORM(vmaxsd, 1, 7);
 GEN_VXFORM(vminub, 1, 8);
 GEN_VXFORM(vminuh, 1, 9);
 GEN_VXFORM(vminuw, 1, 10);
+GEN_VXFORM(vminud, 1, 11);
 GEN_VXFORM(vminsb, 1, 12);
 GEN_VXFORM(vminsh, 1, 13);
 GEN_VXFORM(vminsw, 1, 14);
+GEN_VXFORM(vminsd, 1, 15);
 GEN_VXFORM(vavgub, 1, 16);
 GEN_VXFORM(vavguh, 1, 17);
 GEN_VXFORM(vavguw, 1, 18);
@@ -10372,15 +10376,19 @@ GEN_VXFORM_207(vsubudm, 0, 19),
 GEN_VXFORM(vmaxub, 1, 0),
 GEN_VXFORM(vmaxuh, 1, 1),
 GEN_VXFORM(vmaxuw, 1, 2),
+GEN_VXFORM_207(vmaxud, 1, 3),
 GEN_VXFORM(vmaxsb, 1, 4),
 GEN_VXFORM(vmaxsh, 1, 5),
 GEN_VXFORM(vmaxsw, 1, 6),
+GEN_VXFORM_207(vmaxsd, 1, 7),
 GEN_VXFORM(vminub, 1, 8),
 GEN_VXFORM(vminuh, 1, 9),
 GEN_VXFORM(vminuw, 1, 10),
+GEN_VXFORM_207(vminud, 1, 11),
 GEN_VXFORM(vminsb, 1, 12),
 GEN_VXFORM(vminsh, 1, 13),
 GEN_VXFORM(vminsw, 1, 14),
+GEN_VXFORM_207(vminsd, 1, 15),
 GEN_VXFORM(vavgub, 1, 16),
 GEN_VXFORM(vavguh, 1, 17),
 GEN_VXFORM(vavguw, 1, 18),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 105/130] target-ppc: Altivec 2.07: Pack Doubleword Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (103 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 104/130] target-ppc: Altivec 2.07: Vector Min/Max Doubleword Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 106/130] target-ppc: Altivec 2.07: Unpack Signed Word Instructions Alexander Graf
                   ` (25 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Pack Doubleword instructions introduced in
Power ISA Version 2.07:

 - Vector Pack Signed Doubleword Signed Saturate (vpksdss)
 - Vector Pack Signed Doubleword Unsigned Saturate (vpksdus)
 - Vector Pack Unsigned Doubleword Unsigned Modulo (vpkudum)
 - Vector Pack Unsigned Doubleword Unsigned Saturate (vpkudus)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     | 4 ++++
 target-ppc/int_helper.c | 4 ++++
 target-ppc/translate.c  | 8 ++++++++
 3 files changed, 16 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 38bebea..080142c 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -234,10 +234,14 @@ DEF_HELPER_4(vpkshss, void, env, avr, avr, avr)
 DEF_HELPER_4(vpkshus, void, env, avr, avr, avr)
 DEF_HELPER_4(vpkswss, void, env, avr, avr, avr)
 DEF_HELPER_4(vpkswus, void, env, avr, avr, avr)
+DEF_HELPER_4(vpksdss, void, env, avr, avr, avr)
+DEF_HELPER_4(vpksdus, void, env, avr, avr, avr)
 DEF_HELPER_4(vpkuhus, void, env, avr, avr, avr)
 DEF_HELPER_4(vpkuwus, void, env, avr, avr, avr)
+DEF_HELPER_4(vpkudus, void, env, avr, avr, avr)
 DEF_HELPER_4(vpkuhum, void, env, avr, avr, avr)
 DEF_HELPER_4(vpkuwum, void, env, avr, avr, avr)
+DEF_HELPER_4(vpkudum, void, env, avr, avr, avr)
 DEF_HELPER_3(vpkpx, void, avr, avr, avr)
 DEF_HELPER_5(vmhaddshs, void, env, avr, avr, avr, avr)
 DEF_HELPER_5(vmhraddshs, void, env, avr, avr, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index fc2bff1..534efb5 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1089,10 +1089,14 @@ VPK(shss, s16, s8, cvtshsb, 1)
 VPK(shus, s16, u8, cvtshub, 1)
 VPK(swss, s32, s16, cvtswsh, 1)
 VPK(swus, s32, u16, cvtswuh, 1)
+VPK(sdss, s64, s32, cvtsdsw, 1)
+VPK(sdus, s64, u32, cvtsduw, 1)
 VPK(uhus, u16, u8, cvtuhub, 1)
 VPK(uwus, u32, u16, cvtuwuh, 1)
+VPK(udus, u64, u32, cvtuduw, 1)
 VPK(uhum, u16, u8, I, 0)
 VPK(uwum, u32, u16, I, 0)
+VPK(udum, u64, u32, I, 0)
 #undef I
 #undef VPK
 #undef PKBIG
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 95a751c..14d7985 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7012,12 +7012,16 @@ GEN_VXFORM(vsl, 2, 7);
 GEN_VXFORM(vsr, 2, 11);
 GEN_VXFORM_ENV(vpkuhum, 7, 0);
 GEN_VXFORM_ENV(vpkuwum, 7, 1);
+GEN_VXFORM_ENV(vpkudum, 7, 17);
 GEN_VXFORM_ENV(vpkuhus, 7, 2);
 GEN_VXFORM_ENV(vpkuwus, 7, 3);
+GEN_VXFORM_ENV(vpkudus, 7, 19);
 GEN_VXFORM_ENV(vpkshus, 7, 4);
 GEN_VXFORM_ENV(vpkswus, 7, 5);
+GEN_VXFORM_ENV(vpksdus, 7, 21);
 GEN_VXFORM_ENV(vpkshss, 7, 6);
 GEN_VXFORM_ENV(vpkswss, 7, 7);
+GEN_VXFORM_ENV(vpksdss, 7, 23);
 GEN_VXFORM(vpkpx, 7, 12);
 GEN_VXFORM_ENV(vsum4ubs, 4, 24);
 GEN_VXFORM_ENV(vsum4sbs, 4, 28);
@@ -10445,12 +10449,16 @@ GEN_VXFORM(vsl, 2, 7),
 GEN_VXFORM(vsr, 2, 11),
 GEN_VXFORM(vpkuhum, 7, 0),
 GEN_VXFORM(vpkuwum, 7, 1),
+GEN_VXFORM_207(vpkudum, 7, 17),
 GEN_VXFORM(vpkuhus, 7, 2),
 GEN_VXFORM(vpkuwus, 7, 3),
+GEN_VXFORM_207(vpkudus, 7, 19),
 GEN_VXFORM(vpkshus, 7, 4),
 GEN_VXFORM(vpkswus, 7, 5),
+GEN_VXFORM_207(vpksdus, 7, 21),
 GEN_VXFORM(vpkshss, 7, 6),
 GEN_VXFORM(vpkswss, 7, 7),
+GEN_VXFORM_207(vpksdss, 7, 23),
 GEN_VXFORM(vpkpx, 7, 12),
 GEN_VXFORM(vsum4ubs, 4, 24),
 GEN_VXFORM(vsum4sbs, 4, 28),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 106/130] target-ppc: Altivec 2.07: Unpack Signed Word Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (104 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 105/130] target-ppc: Altivec 2.07: Pack " Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 107/130] target-ppc: Altivec 2.07: Vector Merge Instructions Alexander Graf
                   ` (24 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Unpack Signed Word instructions introduced in
Power ISA Version 2.07:

  - Vector Unpack High Signed Word (vupkusw)
  - Vector Unpack Low Signed Word (vupklsw)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     | 2 ++
 target-ppc/int_helper.c | 2 ++
 target-ppc/translate.c  | 4 ++++
 3 files changed, 8 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 080142c..6a7e99f 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -224,8 +224,10 @@ DEF_HELPER_2(vupkhpx, void, avr, avr)
 DEF_HELPER_2(vupklpx, void, avr, avr)
 DEF_HELPER_2(vupkhsb, void, avr, avr)
 DEF_HELPER_2(vupkhsh, void, avr, avr)
+DEF_HELPER_2(vupkhsw, void, avr, avr)
 DEF_HELPER_2(vupklsb, void, avr, avr)
 DEF_HELPER_2(vupklsh, void, avr, avr)
+DEF_HELPER_2(vupklsw, void, avr, avr)
 DEF_HELPER_5(vmsumubm, void, env, avr, avr, avr, avr)
 DEF_HELPER_5(vmsummbm, void, env, avr, avr, avr, avr)
 DEF_HELPER_5(vsel, void, env, avr, avr, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 534efb5..56e8d9a 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1524,8 +1524,10 @@ VUPKPX(hpx, UPKHI)
     }
 VUPK(hsb, s16, s8, UPKHI)
 VUPK(hsh, s32, s16, UPKHI)
+VUPK(hsw, s64, s32, UPKHI)
 VUPK(lsb, s16, s8, UPKLO)
 VUPK(lsh, s32, s16, UPKLO)
+VUPK(lsw, s64, s32, UPKLO)
 #undef VUPK
 #undef UPKHI
 #undef UPKLO
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 14d7985..07c0c39 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7149,8 +7149,10 @@ static void glue(gen_, name)(DisasContext *ctx)                         \
 
 GEN_VXFORM_NOA(vupkhsb, 7, 8);
 GEN_VXFORM_NOA(vupkhsh, 7, 9);
+GEN_VXFORM_NOA(vupkhsw, 7, 25);
 GEN_VXFORM_NOA(vupklsb, 7, 10);
 GEN_VXFORM_NOA(vupklsh, 7, 11);
+GEN_VXFORM_NOA(vupklsw, 7, 27);
 GEN_VXFORM_NOA(vupkhpx, 7, 13);
 GEN_VXFORM_NOA(vupklpx, 7, 15);
 GEN_VXFORM_NOA_ENV(vrefp, 5, 4);
@@ -10503,8 +10505,10 @@ GEN_VXFORM_SIMM(vspltisw, 6, 14),
     GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
 GEN_VXFORM_NOA(vupkhsb, 7, 8),
 GEN_VXFORM_NOA(vupkhsh, 7, 9),
+GEN_VXFORM_207(vupkhsw, 7, 25),
 GEN_VXFORM_NOA(vupklsb, 7, 10),
 GEN_VXFORM_NOA(vupklsh, 7, 11),
+GEN_VXFORM_207(vupklsw, 7, 27),
 GEN_VXFORM_NOA(vupkhpx, 7, 13),
 GEN_VXFORM_NOA(vupklpx, 7, 15),
 GEN_VXFORM_NOA(vrefp, 5, 4),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 107/130] target-ppc: Altivec 2.07: Vector Merge Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (105 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 106/130] target-ppc: Altivec 2.07: Unpack Signed Word Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 108/130] target-ppc: Altivec 2.07: Change Bit Masks to Support 64-bit Rotates and Shifts Alexander Graf
                   ` (23 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Merge Even Word (vmrgew) and Vector
Merge Odd Word (vmrgow) instructions introduced in Power ISA
Version 2.07.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 07c0c39..ec32771 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6965,6 +6965,41 @@ GEN_VXFORM(vmrghw, 6, 2);
 GEN_VXFORM(vmrglb, 6, 4);
 GEN_VXFORM(vmrglh, 6, 5);
 GEN_VXFORM(vmrglw, 6, 6);
+
+static void gen_vmrgew(DisasContext *ctx)
+{
+    TCGv_i64 tmp;
+    int VT, VA, VB;
+    if (unlikely(!ctx->altivec_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_VPU);
+        return;
+    }
+    VT = rD(ctx->opcode);
+    VA = rA(ctx->opcode);
+    VB = rB(ctx->opcode);
+    tmp = tcg_temp_new_i64();
+    tcg_gen_shri_i64(tmp, cpu_avrh[VB], 32);
+    tcg_gen_deposit_i64(cpu_avrh[VT], cpu_avrh[VA], tmp, 0, 32);
+    tcg_gen_shri_i64(tmp, cpu_avrl[VB], 32);
+    tcg_gen_deposit_i64(cpu_avrl[VT], cpu_avrl[VA], tmp, 0, 32);
+    tcg_temp_free_i64(tmp);
+}
+
+static void gen_vmrgow(DisasContext *ctx)
+{
+    int VT, VA, VB;
+    if (unlikely(!ctx->altivec_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_VPU);
+        return;
+    }
+    VT = rD(ctx->opcode);
+    VA = rA(ctx->opcode);
+    VB = rB(ctx->opcode);
+
+    tcg_gen_deposit_i64(cpu_avrh[VT], cpu_avrh[VB], cpu_avrh[VA], 32, 32);
+    tcg_gen_deposit_i64(cpu_avrl[VT], cpu_avrl[VB], cpu_avrl[VA], 32, 32);
+}
+
 GEN_VXFORM(vmuloub, 4, 0);
 GEN_VXFORM(vmulouh, 4, 1);
 GEN_VXFORM(vmulouw, 4, 2);
@@ -10407,6 +10442,8 @@ GEN_VXFORM(vmrghw, 6, 2),
 GEN_VXFORM(vmrglb, 6, 4),
 GEN_VXFORM(vmrglh, 6, 5),
 GEN_VXFORM(vmrglw, 6, 6),
+GEN_VXFORM_207(vmrgew, 6, 30),
+GEN_VXFORM_207(vmrgow, 6, 26),
 GEN_VXFORM(vmuloub, 4, 0),
 GEN_VXFORM(vmulouh, 4, 1),
 GEN_VXFORM_DUAL(vmulouw, vmuluwm, 4, 2, PPC_ALTIVEC, PPC_NONE),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 108/130] target-ppc: Altivec 2.07: Change Bit Masks to Support 64-bit Rotates and Shifts
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (106 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 107/130] target-ppc: Altivec 2.07: Vector Merge Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 109/130] target-ppc: Altivec 2.07: Vector Doubleword Rotate and Shift Instructions Alexander Graf
                   ` (22 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

Existing code in the VROTATE, VSL and VSR macros for the Altivec rotate and shift
helpers uses a formula to compute a bit mask used to extract the rotate/shift
amount from the VRB register.  What is desired is:

    mask = (1 << (3 + log2(sizeof(element)))) - 1

but what is implemented is:

    mask = (1 << (3 + (sizeof(element)/2))) - 1

This produces correct answers when "element" is uint8_t, uint16_t or uint_32t.  But
it breaks down when element is uint64_t.

This patch corrects the situation.  Since the mask is known at compile time, the
macros are changed to simply accept the mask as an argument.

Subsequent patches in this series will add double-word variants of rotates and
shifts and thus take advantage of this fix.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/int_helper.c | 40 +++++++++++++++-------------------------
 1 file changed, 15 insertions(+), 25 deletions(-)

diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 56e8d9a..59b5a1f 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1128,23 +1128,20 @@ VRFI(p, float_round_up)
 VRFI(z, float_round_to_zero)
 #undef VRFI
 
-#define VROTATE(suffix, element)                                        \
+#define VROTATE(suffix, element, mask)                                  \
     void helper_vrl##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)   \
     {                                                                   \
         int i;                                                          \
                                                                         \
         for (i = 0; i < ARRAY_SIZE(r->element); i++) {                  \
-            unsigned int mask = ((1 <<                                  \
-                                  (3 + (sizeof(a->element[0]) >> 1)))   \
-                                 - 1);                                  \
             unsigned int shift = b->element[i] & mask;                  \
             r->element[i] = (a->element[i] << shift) |                  \
                 (a->element[i] >> (sizeof(a->element[0]) * 8 - shift)); \
         }                                                               \
     }
-VROTATE(b, u8)
-VROTATE(h, u16)
-VROTATE(w, u32)
+VROTATE(b, u8, 0x7)
+VROTATE(h, u16, 0xF)
+VROTATE(w, u32, 0x1F)
 #undef VROTATE
 
 void helper_vrsqrtefp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *b)
@@ -1225,23 +1222,20 @@ VSHIFT(r, RIGHT)
 #undef LEFT
 #undef RIGHT
 
-#define VSL(suffix, element)                                            \
+#define VSL(suffix, element, mask)                                      \
     void helper_vsl##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)   \
     {                                                                   \
         int i;                                                          \
                                                                         \
         for (i = 0; i < ARRAY_SIZE(r->element); i++) {                  \
-            unsigned int mask = ((1 <<                                  \
-                                  (3 + (sizeof(a->element[0]) >> 1)))   \
-                                 - 1);                                  \
             unsigned int shift = b->element[i] & mask;                  \
                                                                         \
             r->element[i] = a->element[i] << shift;                     \
         }                                                               \
     }
-VSL(b, u8)
-VSL(h, u16)
-VSL(w, u32)
+VSL(b, u8, 0x7)
+VSL(h, u16, 0x0F)
+VSL(w, u32, 0x1F)
 #undef VSL
 
 void helper_vsldoi(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t shift)
@@ -1325,26 +1319,22 @@ VSPLTI(h, s16, int16_t)
 VSPLTI(w, s32, int32_t)
 #undef VSPLTI
 
-#define VSR(suffix, element)                                            \
+#define VSR(suffix, element, mask)                                      \
     void helper_vsr##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)   \
     {                                                                   \
         int i;                                                          \
                                                                         \
         for (i = 0; i < ARRAY_SIZE(r->element); i++) {                  \
-            unsigned int mask = ((1 <<                                  \
-                                  (3 + (sizeof(a->element[0]) >> 1)))   \
-                                 - 1);                                  \
             unsigned int shift = b->element[i] & mask;                  \
-                                                                        \
             r->element[i] = a->element[i] >> shift;                     \
         }                                                               \
     }
-VSR(ab, s8)
-VSR(ah, s16)
-VSR(aw, s32)
-VSR(b, u8)
-VSR(h, u16)
-VSR(w, u32)
+VSR(ab, s8, 0x7)
+VSR(ah, s16, 0xF)
+VSR(aw, s32, 0x1F)
+VSR(b, u8, 0x7)
+VSR(h, u16, 0xF)
+VSR(w, u32, 0x1F)
 #undef VSR
 
 void helper_vsro(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 109/130] target-ppc: Altivec 2.07: Vector Doubleword Rotate and Shift Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (107 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 108/130] target-ppc: Altivec 2.07: Change Bit Masks to Support 64-bit Rotates and Shifts Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 110/130] target-ppc: Altivec 2.07: Quadword Addition and Subtracation Alexander Graf
                   ` (21 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the vector doublword rotate and shift instructions
introduced in Power ISA Version 2.07:

  - Vector Rotate Left Doubleword instruction (vrld)
  - Vector Shift Left Doubleword (vsld)
  - Vector Shift Right Doubleword (vsrd)
  - Vector Shift Right Algegbraic Doubleword (vsrad)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     | 4 ++++
 target-ppc/int_helper.c | 4 ++++
 target-ppc/translate.c  | 8 ++++++++
 3 files changed, 16 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 6a7e99f..3201268 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -184,12 +184,15 @@ DEF_HELPER_3(vmuluwm, void, avr, avr, avr)
 DEF_HELPER_3(vsrab, void, avr, avr, avr)
 DEF_HELPER_3(vsrah, void, avr, avr, avr)
 DEF_HELPER_3(vsraw, void, avr, avr, avr)
+DEF_HELPER_3(vsrad, void, avr, avr, avr)
 DEF_HELPER_3(vsrb, void, avr, avr, avr)
 DEF_HELPER_3(vsrh, void, avr, avr, avr)
 DEF_HELPER_3(vsrw, void, avr, avr, avr)
+DEF_HELPER_3(vsrd, void, avr, avr, avr)
 DEF_HELPER_3(vslb, void, avr, avr, avr)
 DEF_HELPER_3(vslh, void, avr, avr, avr)
 DEF_HELPER_3(vslw, void, avr, avr, avr)
+DEF_HELPER_3(vsld, void, avr, avr, avr)
 DEF_HELPER_3(vslo, void, avr, avr, avr)
 DEF_HELPER_3(vsro, void, avr, avr, avr)
 DEF_HELPER_3(vaddcuw, void, avr, avr, avr)
@@ -211,6 +214,7 @@ DEF_HELPER_4(vsubuws, void, env, avr, avr, avr)
 DEF_HELPER_3(vrlb, void, avr, avr, avr)
 DEF_HELPER_3(vrlh, void, avr, avr, avr)
 DEF_HELPER_3(vrlw, void, avr, avr, avr)
+DEF_HELPER_3(vrld, void, avr, avr, avr)
 DEF_HELPER_3(vsl, void, avr, avr, avr)
 DEF_HELPER_3(vsr, void, avr, avr, avr)
 DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 59b5a1f..b4a7298 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1142,6 +1142,7 @@ VRFI(z, float_round_to_zero)
 VROTATE(b, u8, 0x7)
 VROTATE(h, u16, 0xF)
 VROTATE(w, u32, 0x1F)
+VROTATE(d, u64, 0x3F)
 #undef VROTATE
 
 void helper_vrsqrtefp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *b)
@@ -1236,6 +1237,7 @@ VSHIFT(r, RIGHT)
 VSL(b, u8, 0x7)
 VSL(h, u16, 0x0F)
 VSL(w, u32, 0x1F)
+VSL(d, u64, 0x3F)
 #undef VSL
 
 void helper_vsldoi(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t shift)
@@ -1332,9 +1334,11 @@ VSPLTI(w, s32, int32_t)
 VSR(ab, s8, 0x7)
 VSR(ah, s16, 0xF)
 VSR(aw, s32, 0x1F)
+VSR(ad, s64, 0x3F)
 VSR(b, u8, 0x7)
 VSR(h, u16, 0xF)
 VSR(w, u32, 0x1F)
+VSR(d, u64, 0x3F)
 #undef VSR
 
 void helper_vsro(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index ec32771..3d38a25 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7018,12 +7018,15 @@ GEN_VXFORM(vmulesw, 4, 14);
 GEN_VXFORM(vslb, 2, 4);
 GEN_VXFORM(vslh, 2, 5);
 GEN_VXFORM(vslw, 2, 6);
+GEN_VXFORM(vsld, 2, 23);
 GEN_VXFORM(vsrb, 2, 8);
 GEN_VXFORM(vsrh, 2, 9);
 GEN_VXFORM(vsrw, 2, 10);
+GEN_VXFORM(vsrd, 2, 27);
 GEN_VXFORM(vsrab, 2, 12);
 GEN_VXFORM(vsrah, 2, 13);
 GEN_VXFORM(vsraw, 2, 14);
+GEN_VXFORM(vsrad, 2, 15);
 GEN_VXFORM(vslo, 6, 16);
 GEN_VXFORM(vsro, 6, 17);
 GEN_VXFORM(vaddcuw, 0, 6);
@@ -7043,6 +7046,7 @@ GEN_VXFORM_ENV(vsubsws, 0, 30);
 GEN_VXFORM(vrlb, 2, 0);
 GEN_VXFORM(vrlh, 2, 1);
 GEN_VXFORM(vrlw, 2, 2);
+GEN_VXFORM(vrld, 2, 3);
 GEN_VXFORM(vsl, 2, 7);
 GEN_VXFORM(vsr, 2, 11);
 GEN_VXFORM_ENV(vpkuhum, 7, 0);
@@ -10459,12 +10463,15 @@ GEN_VXFORM_207(vmulesw, 4, 14),
 GEN_VXFORM(vslb, 2, 4),
 GEN_VXFORM(vslh, 2, 5),
 GEN_VXFORM(vslw, 2, 6),
+GEN_VXFORM_207(vsld, 2, 23),
 GEN_VXFORM(vsrb, 2, 8),
 GEN_VXFORM(vsrh, 2, 9),
 GEN_VXFORM(vsrw, 2, 10),
+GEN_VXFORM_207(vsrd, 2, 27),
 GEN_VXFORM(vsrab, 2, 12),
 GEN_VXFORM(vsrah, 2, 13),
 GEN_VXFORM(vsraw, 2, 14),
+GEN_VXFORM_207(vsrad, 2, 15),
 GEN_VXFORM(vslo, 6, 16),
 GEN_VXFORM(vsro, 6, 17),
 GEN_VXFORM(vaddcuw, 0, 6),
@@ -10484,6 +10491,7 @@ GEN_VXFORM(vsubsws, 0, 30),
 GEN_VXFORM(vrlb, 2, 0),
 GEN_VXFORM(vrlh, 2, 1),
 GEN_VXFORM(vrlw, 2, 2),
+GEN_VXFORM_207(vrld, 2, 3),
 GEN_VXFORM(vsl, 2, 7),
 GEN_VXFORM(vsr, 2, 11),
 GEN_VXFORM(vpkuhum, 7, 0),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 110/130] target-ppc: Altivec 2.07: Quadword Addition and Subtracation
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (108 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 109/130] target-ppc: Altivec 2.07: Vector Doubleword Rotate and Shift Instructions Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 111/130] target-ppc: Altivec 2.07: vbpermq Instruction Alexander Graf
                   ` (20 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Quadword Addition and Subtraction instructions
introduced in Power ISA Version 2.07:

  - Vector Add Unsigned Quadword Modulo (vadduqm)
  - Vector Add & Write Carry Unsigned Quadword (vaddcuq)
  - Vector Add Extended Unsigned Quadword (vaddeuqm)
  - Vector Add Extended & Write Carry Unsigned Quadword (vaddecuq)
  - Vector Subtract Unsigned Quadword Modulo (vsubuqm)
  - Vector Subtract & Write Carry Unsigned Quadword (vsubcuq)
  - Vector Subtract Extended Unsigned Quadword (vsubeuqm)
  - Vector Subtract Extended & Write Carry Unsigned Quadword (vsubecuq)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |   8 +++
 target-ppc/int_helper.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/translate.c  |  18 +++++
 3 files changed, 211 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 3201268..1483930 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -211,6 +211,14 @@ DEF_HELPER_4(vadduws, void, env, avr, avr, avr)
 DEF_HELPER_4(vsububs, void, env, avr, avr, avr)
 DEF_HELPER_4(vsubuhs, void, env, avr, avr, avr)
 DEF_HELPER_4(vsubuws, void, env, avr, avr, avr)
+DEF_HELPER_3(vadduqm, void, avr, avr, avr)
+DEF_HELPER_4(vaddecuq, void, avr, avr, avr, avr)
+DEF_HELPER_4(vaddeuqm, void, avr, avr, avr, avr)
+DEF_HELPER_3(vaddcuq, void, avr, avr, avr)
+DEF_HELPER_3(vsubuqm, void, avr, avr, avr)
+DEF_HELPER_4(vsubecuq, void, avr, avr, avr, avr)
+DEF_HELPER_4(vsubeuqm, void, avr, avr, avr, avr)
+DEF_HELPER_3(vsubcuq, void, avr, avr, avr)
 DEF_HELPER_3(vrlb, void, avr, avr, avr)
 DEF_HELPER_3(vrlh, void, avr, avr, avr)
 DEF_HELPER_3(vrlw, void, avr, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index b4a7298..72fb13c 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1568,6 +1568,191 @@ VGENERIC_DO(popcntd, u64)
 
 #undef VGENERIC_DO
 
+#if defined(HOST_WORDS_BIGENDIAN)
+#define QW_ONE { .u64 = { 0, 1 } }
+#else
+#define QW_ONE { .u64 = { 1, 0 } }
+#endif
+
+#ifndef CONFIG_INT128
+
+static inline void avr_qw_not(ppc_avr_t *t, ppc_avr_t a)
+{
+    t->u64[0] = ~a.u64[0];
+    t->u64[1] = ~a.u64[1];
+}
+
+static int avr_qw_cmpu(ppc_avr_t a, ppc_avr_t b)
+{
+    if (a.u64[HI_IDX] < b.u64[HI_IDX]) {
+        return -1;
+    } else if (a.u64[HI_IDX] > b.u64[HI_IDX]) {
+        return 1;
+    } else if (a.u64[LO_IDX] < b.u64[LO_IDX]) {
+        return -1;
+    } else if (a.u64[LO_IDX] > b.u64[LO_IDX]) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+static void avr_qw_add(ppc_avr_t *t, ppc_avr_t a, ppc_avr_t b)
+{
+    t->u64[LO_IDX] = a.u64[LO_IDX] + b.u64[LO_IDX];
+    t->u64[HI_IDX] = a.u64[HI_IDX] + b.u64[HI_IDX] +
+                     (~a.u64[LO_IDX] < b.u64[LO_IDX]);
+}
+
+static int avr_qw_addc(ppc_avr_t *t, ppc_avr_t a, ppc_avr_t b)
+{
+    ppc_avr_t not_a;
+    t->u64[LO_IDX] = a.u64[LO_IDX] + b.u64[LO_IDX];
+    t->u64[HI_IDX] = a.u64[HI_IDX] + b.u64[HI_IDX] +
+                     (~a.u64[LO_IDX] < b.u64[LO_IDX]);
+    avr_qw_not(&not_a, a);
+    return avr_qw_cmpu(not_a, b) < 0;
+}
+
+#endif
+
+void helper_vadduqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+#ifdef CONFIG_INT128
+    r->u128 = a->u128 + b->u128;
+#else
+    avr_qw_add(r, *a, *b);
+#endif
+}
+
+void helper_vaddeuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
+{
+#ifdef CONFIG_INT128
+    r->u128 = a->u128 + b->u128 + (c->u128 & 1);
+#else
+
+    if (c->u64[LO_IDX] & 1) {
+        ppc_avr_t tmp;
+
+        tmp.u64[HI_IDX] = 0;
+        tmp.u64[LO_IDX] = c->u64[LO_IDX] & 1;
+        avr_qw_add(&tmp, *a, tmp);
+        avr_qw_add(r, tmp, *b);
+    } else {
+        avr_qw_add(r, *a, *b);
+    }
+#endif
+}
+
+void helper_vaddcuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+#ifdef CONFIG_INT128
+    r->u128 = (~a->u128 < b->u128);
+#else
+    ppc_avr_t not_a;
+
+    avr_qw_not(&not_a, *a);
+
+    r->u64[HI_IDX] = 0;
+    r->u64[LO_IDX] = (avr_qw_cmpu(not_a, *b) < 0);
+#endif
+}
+
+void helper_vaddecuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
+{
+#ifdef CONFIG_INT128
+    int carry_out = (~a->u128 < b->u128);
+    if (!carry_out && (c->u128 & 1)) {
+        carry_out = ((a->u128 + b->u128 + 1) == 0) &&
+                    ((a->u128 != 0) || (b->u128 != 0));
+    }
+    r->u128 = carry_out;
+#else
+
+    int carry_in = c->u64[LO_IDX] & 1;
+    int carry_out = 0;
+    ppc_avr_t tmp;
+
+    carry_out = avr_qw_addc(&tmp, *a, *b);
+
+    if (!carry_out && carry_in) {
+        ppc_avr_t one = QW_ONE;
+        carry_out = avr_qw_addc(&tmp, tmp, one);
+    }
+    r->u64[HI_IDX] = 0;
+    r->u64[LO_IDX] = carry_out;
+#endif
+}
+
+void helper_vsubuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+#ifdef CONFIG_INT128
+    r->u128 = a->u128 - b->u128;
+#else
+    ppc_avr_t tmp;
+    ppc_avr_t one = QW_ONE;
+
+    avr_qw_not(&tmp, *b);
+    avr_qw_add(&tmp, *a, tmp);
+    avr_qw_add(r, tmp, one);
+#endif
+}
+
+void helper_vsubeuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
+{
+#ifdef CONFIG_INT128
+    r->u128 = a->u128 + ~b->u128 + (c->u128 & 1);
+#else
+    ppc_avr_t tmp, sum;
+
+    avr_qw_not(&tmp, *b);
+    avr_qw_add(&sum, *a, tmp);
+
+    tmp.u64[HI_IDX] = 0;
+    tmp.u64[LO_IDX] = c->u64[LO_IDX] & 1;
+    avr_qw_add(r, sum, tmp);
+#endif
+}
+
+void helper_vsubcuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+#ifdef CONFIG_INT128
+    r->u128 = (~a->u128 < ~b->u128) ||
+                 (a->u128 + ~b->u128 == (__uint128_t)-1);
+#else
+    int carry = (avr_qw_cmpu(*a, *b) > 0);
+    if (!carry) {
+        ppc_avr_t tmp;
+        avr_qw_not(&tmp, *b);
+        avr_qw_add(&tmp, *a, tmp);
+        carry = ((tmp.s64[HI_IDX] == -1ull) && (tmp.s64[LO_IDX] == -1ull));
+    }
+    r->u64[HI_IDX] = 0;
+    r->u64[LO_IDX] = carry;
+#endif
+}
+
+void helper_vsubecuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
+{
+#ifdef CONFIG_INT128
+    r->u128 =
+        (~a->u128 < ~b->u128) ||
+        ((c->u128 & 1) && (a->u128 + ~b->u128 == (__uint128_t)-1));
+#else
+    int carry_in = c->u64[LO_IDX] & 1;
+    int carry_out = (avr_qw_cmpu(*a, *b) > 0);
+    if (!carry_out && carry_in) {
+        ppc_avr_t tmp;
+        avr_qw_not(&tmp, *b);
+        avr_qw_add(&tmp, *a, tmp);
+        carry_out = ((tmp.u64[HI_IDX] == -1ull) && (tmp.u64[LO_IDX] == -1ull));
+    }
+
+    r->u64[HI_IDX] = 0;
+    r->u64[LO_IDX] = carry_out;
+#endif
+}
+
 
 #undef VECTOR_FOR_INORDER_I
 #undef HI_IDX
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 3d38a25..c4d7f0f 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7043,6 +7043,18 @@ GEN_VXFORM_ENV(vsubuws, 0, 26);
 GEN_VXFORM_ENV(vsubsbs, 0, 28);
 GEN_VXFORM_ENV(vsubshs, 0, 29);
 GEN_VXFORM_ENV(vsubsws, 0, 30);
+GEN_VXFORM(vadduqm, 0, 4);
+GEN_VXFORM(vaddcuq, 0, 5);
+GEN_VXFORM3(vaddeuqm, 30, 0);
+GEN_VXFORM3(vaddecuq, 30, 0);
+GEN_VXFORM_DUAL(vaddeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
+            vaddecuq, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM(vsubuqm, 0, 20);
+GEN_VXFORM(vsubcuq, 0, 21);
+GEN_VXFORM3(vsubeuqm, 31, 0);
+GEN_VXFORM3(vsubecuq, 31, 0);
+GEN_VXFORM_DUAL(vsubeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
+            vsubecuq, PPC_NONE, PPC2_ALTIVEC_207)
 GEN_VXFORM(vrlb, 2, 0);
 GEN_VXFORM(vrlh, 2, 1);
 GEN_VXFORM(vrlw, 2, 2);
@@ -10488,6 +10500,12 @@ GEN_VXFORM(vsubuws, 0, 26),
 GEN_VXFORM(vsubsbs, 0, 28),
 GEN_VXFORM(vsubshs, 0, 29),
 GEN_VXFORM(vsubsws, 0, 30),
+GEN_VXFORM_207(vadduqm, 0, 4),
+GEN_VXFORM_207(vaddcuq, 0, 5),
+GEN_VXFORM_DUAL(vaddeuqm, vaddecuq, 30, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
+GEN_VXFORM_207(vsubuqm, 0, 20),
+GEN_VXFORM_207(vsubcuq, 0, 21),
+GEN_VXFORM_DUAL(vsubeuqm, vsubecuq, 31, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
 GEN_VXFORM(vrlb, 2, 0),
 GEN_VXFORM(vrlh, 2, 1),
 GEN_VXFORM(vrlw, 2, 2),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 111/130] target-ppc: Altivec 2.07: vbpermq Instruction
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (109 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 110/130] target-ppc: Altivec 2.07: Quadword Addition and Subtracation Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:33 ` [Qemu-devel] [PULL 112/130] target-ppc: Altivec 2.07: Doubleword Compares Alexander Graf
                   ` (19 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Bit Permute Quadword (vbpermq) instruction
introduced in Power ISA Version 2.07.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |  1 +
 target-ppc/int_helper.c | 31 +++++++++++++++++++++++++++++++
 target-ppc/translate.c  |  2 ++
 3 files changed, 34 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 1483930..ca1dc83 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -303,6 +303,7 @@ DEF_HELPER_2(vpopcntb, void, avr, avr)
 DEF_HELPER_2(vpopcnth, void, avr, avr)
 DEF_HELPER_2(vpopcntw, void, avr, avr)
 DEF_HELPER_2(vpopcntd, void, avr, avr)
+DEF_HELPER_3(vbpermq, void, avr, avr, avr)
 
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 72fb13c..5885b7e 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1039,6 +1039,37 @@ void helper_vperm(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b,
 }
 
 #if defined(HOST_WORDS_BIGENDIAN)
+#define VBPERMQ_INDEX(avr, i) ((avr)->u8[(i)])
+#define VBPERMQ_DW(index) (((index) & 0x40) != 0)
+#else
+#define VBPERMQ_INDEX(avr, i) ((avr)->u8[15-(i)])
+#define VBPERMQ_DW(index) (((index) & 0x40) == 0)
+#endif
+
+void helper_vbpermq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+    int i;
+    uint64_t perm = 0;
+
+    VECTOR_FOR_INORDER_I(i, u8) {
+        int index = VBPERMQ_INDEX(b, i);
+
+        if (index < 128) {
+            uint64_t mask = (1ull << (63-(index & 0x3F)));
+            if (a->u64[VBPERMQ_DW(index)] & mask) {
+                perm |= (0x8000 >> i);
+            }
+        }
+    }
+
+    r->u64[HI_IDX] = perm;
+    r->u64[LO_IDX] = 0;
+}
+
+#undef VBPERMQ_INDEX
+#undef VBPERMQ_DW
+
+#if defined(HOST_WORDS_BIGENDIAN)
 #define PKBIG 1
 #else
 #define PKBIG 0
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c4d7f0f..fb7bcbe 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7360,6 +7360,7 @@ GEN_VXFORM_DUAL(vclzw, PPC_NONE, PPC2_ALTIVEC_207, \
                 vpopcntw, PPC_NONE, PPC2_ALTIVEC_207)
 GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \
                 vpopcntd, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM(vbpermq, 6, 21);
 
 /***                           VSX extension                               ***/
 
@@ -10609,6 +10610,7 @@ GEN_VXFORM_DUAL(vclzh, vpopcnth, 1, 29, PPC_NONE, PPC2_ALTIVEC_207),
 GEN_VXFORM_DUAL(vclzw, vpopcntw, 1, 30, PPC_NONE, PPC2_ALTIVEC_207),
 GEN_VXFORM_DUAL(vclzd, vpopcntd, 1, 31, PPC_NONE, PPC2_ALTIVEC_207),
 
+GEN_VXFORM_207(vbpermq, 6, 21),
 
 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 112/130] target-ppc: Altivec 2.07: Doubleword Compares
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (110 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 111/130] target-ppc: Altivec 2.07: vbpermq Instruction Alexander Graf
@ 2014-03-06 23:33 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 113/130] target-ppc: Altivec 2.07: Vector Gather Bits by Bytes Alexander Graf
                   ` (18 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:33 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Compare Doubleword instructions introduced
by Power ISA Version 2.07:

  - Vector Compare Equal to Unsigned Doubleword (vcmpequd)
  - Vector Compare Greater Than Signed Doubleword (vcmpgtsd)
  - Vector Compare Greater Than Unsigned Doubleword (vcmpgtud)

These instructions are encoded with bit 31 set to 1 and so are duals with
vcmpeqfp, vcmpgtfp and vcmpbfp respectively.

The helper macro for integer compares is enhanced to account for 64-bit
operands.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |  6 ++++++
 target-ppc/int_helper.c | 14 ++++++++++----
 target-ppc/translate.c  | 16 +++++++++++++---
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index ca1dc83..9613654 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -139,12 +139,15 @@ DEF_HELPER_3(vmaxud, void, avr, avr, avr)
 DEF_HELPER_4(vcmpequb, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpequh, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpequw, void, env, avr, avr, avr)
+DEF_HELPER_4(vcmpequd, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtub, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtuh, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtuw, void, env, avr, avr, avr)
+DEF_HELPER_4(vcmpgtud, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtsb, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtsh, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtsw, void, env, avr, avr, avr)
+DEF_HELPER_4(vcmpgtsd, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpeqfp, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgefp, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtfp, void, env, avr, avr, avr)
@@ -152,12 +155,15 @@ DEF_HELPER_4(vcmpbfp, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpequb_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpequh_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpequw_dot, void, env, avr, avr, avr)
+DEF_HELPER_4(vcmpequd_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtub_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtuh_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtuw_dot, void, env, avr, avr, avr)
+DEF_HELPER_4(vcmpgtud_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtsb_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtsh_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtsw_dot, void, env, avr, avr, avr)
+DEF_HELPER_4(vcmpgtsd_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpeqfp_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgefp_dot, void, env, avr, avr, avr)
 DEF_HELPER_4(vcmpgtfp_dot, void, env, avr, avr, avr)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 5885b7e..27a34c0 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -626,15 +626,18 @@ VCF(sx, int32_to_float32, s32)
     void helper_vcmp##suffix(CPUPPCState *env, ppc_avr_t *r,            \
                              ppc_avr_t *a, ppc_avr_t *b)                \
     {                                                                   \
-        uint32_t ones = (uint32_t)-1;                                   \
-        uint32_t all = ones;                                            \
-        uint32_t none = 0;                                              \
+        uint64_t ones = (uint64_t)-1;                                   \
+        uint64_t all = ones;                                            \
+        uint64_t none = 0;                                              \
         int i;                                                          \
                                                                         \
         for (i = 0; i < ARRAY_SIZE(r->element); i++) {                  \
-            uint32_t result = (a->element[i] compare b->element[i] ?    \
+            uint64_t result = (a->element[i] compare b->element[i] ?    \
                                ones : 0x0);                             \
             switch (sizeof(a->element[0])) {                            \
+            case 8:                                                     \
+                r->u64[i] = result;                                     \
+                break;                                                  \
             case 4:                                                     \
                 r->u32[i] = result;                                     \
                 break;                                                  \
@@ -658,12 +661,15 @@ VCF(sx, int32_to_float32, s32)
 VCMP(equb, ==, u8)
 VCMP(equh, ==, u16)
 VCMP(equw, ==, u32)
+VCMP(equd, ==, u64)
 VCMP(gtub, >, u8)
 VCMP(gtuh, >, u16)
 VCMP(gtuw, >, u32)
+VCMP(gtud, >, u64)
 VCMP(gtsb, >, s8)
 VCMP(gtsh, >, s16)
 VCMP(gtsw, >, s32)
+VCMP(gtsd, >, s64)
 #undef VCMP_DO
 #undef VCMP
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fb7bcbe..c6242c8 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7136,17 +7136,27 @@ static void glue(gen_, name0##_##name1)(DisasContext *ctx)             \
 GEN_VXRFORM(vcmpequb, 3, 0)
 GEN_VXRFORM(vcmpequh, 3, 1)
 GEN_VXRFORM(vcmpequw, 3, 2)
+GEN_VXRFORM(vcmpequd, 3, 3)
 GEN_VXRFORM(vcmpgtsb, 3, 12)
 GEN_VXRFORM(vcmpgtsh, 3, 13)
 GEN_VXRFORM(vcmpgtsw, 3, 14)
+GEN_VXRFORM(vcmpgtsd, 3, 15)
 GEN_VXRFORM(vcmpgtub, 3, 8)
 GEN_VXRFORM(vcmpgtuh, 3, 9)
 GEN_VXRFORM(vcmpgtuw, 3, 10)
+GEN_VXRFORM(vcmpgtud, 3, 11)
 GEN_VXRFORM(vcmpeqfp, 3, 3)
 GEN_VXRFORM(vcmpgefp, 3, 7)
 GEN_VXRFORM(vcmpgtfp, 3, 11)
 GEN_VXRFORM(vcmpbfp, 3, 15)
 
+GEN_VXRFORM_DUAL(vcmpeqfp, PPC_ALTIVEC, PPC_NONE, \
+                 vcmpequd, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXRFORM_DUAL(vcmpbfp, PPC_ALTIVEC, PPC_NONE, \
+                 vcmpgtsd, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXRFORM_DUAL(vcmpgtfp, PPC_ALTIVEC, PPC_NONE, \
+                 vcmpgtud, PPC_NONE, PPC2_ALTIVEC_207)
+
 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
 static void glue(gen_, name)(DisasContext *ctx)                         \
     {                                                                   \
@@ -10552,10 +10562,10 @@ GEN_VXRFORM(vcmpgtsw, 3, 14)
 GEN_VXRFORM(vcmpgtub, 3, 8)
 GEN_VXRFORM(vcmpgtuh, 3, 9)
 GEN_VXRFORM(vcmpgtuw, 3, 10)
-GEN_VXRFORM(vcmpeqfp, 3, 3)
+GEN_VXRFORM_DUAL(vcmpeqfp, vcmpequd, 3, 3, PPC_ALTIVEC, PPC_NONE)
 GEN_VXRFORM(vcmpgefp, 3, 7)
-GEN_VXRFORM(vcmpgtfp, 3, 11)
-GEN_VXRFORM(vcmpbfp, 3, 15)
+GEN_VXRFORM_DUAL(vcmpgtfp, vcmpgtud, 3, 11, PPC_ALTIVEC, PPC_NONE)
+GEN_VXRFORM_DUAL(vcmpbfp, vcmpgtsd, 3, 15, PPC_ALTIVEC, PPC_NONE)
 
 #undef GEN_VXFORM_SIMM
 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 113/130] target-ppc: Altivec 2.07: Vector Gather Bits by Bytes
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (111 preceding siblings ...)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 112/130] target-ppc: Altivec 2.07: Doubleword Compares Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 114/130] target-ppc: Altivec 2.07: Vector Polynomial Multiply Sum Alexander Graf
                   ` (17 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Gather Bits by Bytes Doubleword (vgbbd)
instruction which is introduced in Power ISA Version 2.07.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |   1 +
 target-ppc/int_helper.c | 276 ++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/translate.c  |   2 +
 3 files changed, 279 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 9613654..aca712f 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -310,6 +310,7 @@ DEF_HELPER_2(vpopcnth, void, avr, avr)
 DEF_HELPER_2(vpopcntw, void, avr, avr)
 DEF_HELPER_2(vpopcntd, void, avr, avr)
 DEF_HELPER_3(vbpermq, void, avr, avr, avr)
+DEF_HELPER_2(vgbbd, void, avr, avr)
 
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 27a34c0..cd0b88a 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1075,6 +1075,282 @@ void helper_vbpermq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
 #undef VBPERMQ_INDEX
 #undef VBPERMQ_DW
 
+uint64_t VGBBD_MASKS[256] = {
+    0x0000000000000000ull, /* 00 */
+    0x0000000000000080ull, /* 01 */
+    0x0000000000008000ull, /* 02 */
+    0x0000000000008080ull, /* 03 */
+    0x0000000000800000ull, /* 04 */
+    0x0000000000800080ull, /* 05 */
+    0x0000000000808000ull, /* 06 */
+    0x0000000000808080ull, /* 07 */
+    0x0000000080000000ull, /* 08 */
+    0x0000000080000080ull, /* 09 */
+    0x0000000080008000ull, /* 0A */
+    0x0000000080008080ull, /* 0B */
+    0x0000000080800000ull, /* 0C */
+    0x0000000080800080ull, /* 0D */
+    0x0000000080808000ull, /* 0E */
+    0x0000000080808080ull, /* 0F */
+    0x0000008000000000ull, /* 10 */
+    0x0000008000000080ull, /* 11 */
+    0x0000008000008000ull, /* 12 */
+    0x0000008000008080ull, /* 13 */
+    0x0000008000800000ull, /* 14 */
+    0x0000008000800080ull, /* 15 */
+    0x0000008000808000ull, /* 16 */
+    0x0000008000808080ull, /* 17 */
+    0x0000008080000000ull, /* 18 */
+    0x0000008080000080ull, /* 19 */
+    0x0000008080008000ull, /* 1A */
+    0x0000008080008080ull, /* 1B */
+    0x0000008080800000ull, /* 1C */
+    0x0000008080800080ull, /* 1D */
+    0x0000008080808000ull, /* 1E */
+    0x0000008080808080ull, /* 1F */
+    0x0000800000000000ull, /* 20 */
+    0x0000800000000080ull, /* 21 */
+    0x0000800000008000ull, /* 22 */
+    0x0000800000008080ull, /* 23 */
+    0x0000800000800000ull, /* 24 */
+    0x0000800000800080ull, /* 25 */
+    0x0000800000808000ull, /* 26 */
+    0x0000800000808080ull, /* 27 */
+    0x0000800080000000ull, /* 28 */
+    0x0000800080000080ull, /* 29 */
+    0x0000800080008000ull, /* 2A */
+    0x0000800080008080ull, /* 2B */
+    0x0000800080800000ull, /* 2C */
+    0x0000800080800080ull, /* 2D */
+    0x0000800080808000ull, /* 2E */
+    0x0000800080808080ull, /* 2F */
+    0x0000808000000000ull, /* 30 */
+    0x0000808000000080ull, /* 31 */
+    0x0000808000008000ull, /* 32 */
+    0x0000808000008080ull, /* 33 */
+    0x0000808000800000ull, /* 34 */
+    0x0000808000800080ull, /* 35 */
+    0x0000808000808000ull, /* 36 */
+    0x0000808000808080ull, /* 37 */
+    0x0000808080000000ull, /* 38 */
+    0x0000808080000080ull, /* 39 */
+    0x0000808080008000ull, /* 3A */
+    0x0000808080008080ull, /* 3B */
+    0x0000808080800000ull, /* 3C */
+    0x0000808080800080ull, /* 3D */
+    0x0000808080808000ull, /* 3E */
+    0x0000808080808080ull, /* 3F */
+    0x0080000000000000ull, /* 40 */
+    0x0080000000000080ull, /* 41 */
+    0x0080000000008000ull, /* 42 */
+    0x0080000000008080ull, /* 43 */
+    0x0080000000800000ull, /* 44 */
+    0x0080000000800080ull, /* 45 */
+    0x0080000000808000ull, /* 46 */
+    0x0080000000808080ull, /* 47 */
+    0x0080000080000000ull, /* 48 */
+    0x0080000080000080ull, /* 49 */
+    0x0080000080008000ull, /* 4A */
+    0x0080000080008080ull, /* 4B */
+    0x0080000080800000ull, /* 4C */
+    0x0080000080800080ull, /* 4D */
+    0x0080000080808000ull, /* 4E */
+    0x0080000080808080ull, /* 4F */
+    0x0080008000000000ull, /* 50 */
+    0x0080008000000080ull, /* 51 */
+    0x0080008000008000ull, /* 52 */
+    0x0080008000008080ull, /* 53 */
+    0x0080008000800000ull, /* 54 */
+    0x0080008000800080ull, /* 55 */
+    0x0080008000808000ull, /* 56 */
+    0x0080008000808080ull, /* 57 */
+    0x0080008080000000ull, /* 58 */
+    0x0080008080000080ull, /* 59 */
+    0x0080008080008000ull, /* 5A */
+    0x0080008080008080ull, /* 5B */
+    0x0080008080800000ull, /* 5C */
+    0x0080008080800080ull, /* 5D */
+    0x0080008080808000ull, /* 5E */
+    0x0080008080808080ull, /* 5F */
+    0x0080800000000000ull, /* 60 */
+    0x0080800000000080ull, /* 61 */
+    0x0080800000008000ull, /* 62 */
+    0x0080800000008080ull, /* 63 */
+    0x0080800000800000ull, /* 64 */
+    0x0080800000800080ull, /* 65 */
+    0x0080800000808000ull, /* 66 */
+    0x0080800000808080ull, /* 67 */
+    0x0080800080000000ull, /* 68 */
+    0x0080800080000080ull, /* 69 */
+    0x0080800080008000ull, /* 6A */
+    0x0080800080008080ull, /* 6B */
+    0x0080800080800000ull, /* 6C */
+    0x0080800080800080ull, /* 6D */
+    0x0080800080808000ull, /* 6E */
+    0x0080800080808080ull, /* 6F */
+    0x0080808000000000ull, /* 70 */
+    0x0080808000000080ull, /* 71 */
+    0x0080808000008000ull, /* 72 */
+    0x0080808000008080ull, /* 73 */
+    0x0080808000800000ull, /* 74 */
+    0x0080808000800080ull, /* 75 */
+    0x0080808000808000ull, /* 76 */
+    0x0080808000808080ull, /* 77 */
+    0x0080808080000000ull, /* 78 */
+    0x0080808080000080ull, /* 79 */
+    0x0080808080008000ull, /* 7A */
+    0x0080808080008080ull, /* 7B */
+    0x0080808080800000ull, /* 7C */
+    0x0080808080800080ull, /* 7D */
+    0x0080808080808000ull, /* 7E */
+    0x0080808080808080ull, /* 7F */
+    0x8000000000000000ull, /* 80 */
+    0x8000000000000080ull, /* 81 */
+    0x8000000000008000ull, /* 82 */
+    0x8000000000008080ull, /* 83 */
+    0x8000000000800000ull, /* 84 */
+    0x8000000000800080ull, /* 85 */
+    0x8000000000808000ull, /* 86 */
+    0x8000000000808080ull, /* 87 */
+    0x8000000080000000ull, /* 88 */
+    0x8000000080000080ull, /* 89 */
+    0x8000000080008000ull, /* 8A */
+    0x8000000080008080ull, /* 8B */
+    0x8000000080800000ull, /* 8C */
+    0x8000000080800080ull, /* 8D */
+    0x8000000080808000ull, /* 8E */
+    0x8000000080808080ull, /* 8F */
+    0x8000008000000000ull, /* 90 */
+    0x8000008000000080ull, /* 91 */
+    0x8000008000008000ull, /* 92 */
+    0x8000008000008080ull, /* 93 */
+    0x8000008000800000ull, /* 94 */
+    0x8000008000800080ull, /* 95 */
+    0x8000008000808000ull, /* 96 */
+    0x8000008000808080ull, /* 97 */
+    0x8000008080000000ull, /* 98 */
+    0x8000008080000080ull, /* 99 */
+    0x8000008080008000ull, /* 9A */
+    0x8000008080008080ull, /* 9B */
+    0x8000008080800000ull, /* 9C */
+    0x8000008080800080ull, /* 9D */
+    0x8000008080808000ull, /* 9E */
+    0x8000008080808080ull, /* 9F */
+    0x8000800000000000ull, /* A0 */
+    0x8000800000000080ull, /* A1 */
+    0x8000800000008000ull, /* A2 */
+    0x8000800000008080ull, /* A3 */
+    0x8000800000800000ull, /* A4 */
+    0x8000800000800080ull, /* A5 */
+    0x8000800000808000ull, /* A6 */
+    0x8000800000808080ull, /* A7 */
+    0x8000800080000000ull, /* A8 */
+    0x8000800080000080ull, /* A9 */
+    0x8000800080008000ull, /* AA */
+    0x8000800080008080ull, /* AB */
+    0x8000800080800000ull, /* AC */
+    0x8000800080800080ull, /* AD */
+    0x8000800080808000ull, /* AE */
+    0x8000800080808080ull, /* AF */
+    0x8000808000000000ull, /* B0 */
+    0x8000808000000080ull, /* B1 */
+    0x8000808000008000ull, /* B2 */
+    0x8000808000008080ull, /* B3 */
+    0x8000808000800000ull, /* B4 */
+    0x8000808000800080ull, /* B5 */
+    0x8000808000808000ull, /* B6 */
+    0x8000808000808080ull, /* B7 */
+    0x8000808080000000ull, /* B8 */
+    0x8000808080000080ull, /* B9 */
+    0x8000808080008000ull, /* BA */
+    0x8000808080008080ull, /* BB */
+    0x8000808080800000ull, /* BC */
+    0x8000808080800080ull, /* BD */
+    0x8000808080808000ull, /* BE */
+    0x8000808080808080ull, /* BF */
+    0x8080000000000000ull, /* C0 */
+    0x8080000000000080ull, /* C1 */
+    0x8080000000008000ull, /* C2 */
+    0x8080000000008080ull, /* C3 */
+    0x8080000000800000ull, /* C4 */
+    0x8080000000800080ull, /* C5 */
+    0x8080000000808000ull, /* C6 */
+    0x8080000000808080ull, /* C7 */
+    0x8080000080000000ull, /* C8 */
+    0x8080000080000080ull, /* C9 */
+    0x8080000080008000ull, /* CA */
+    0x8080000080008080ull, /* CB */
+    0x8080000080800000ull, /* CC */
+    0x8080000080800080ull, /* CD */
+    0x8080000080808000ull, /* CE */
+    0x8080000080808080ull, /* CF */
+    0x8080008000000000ull, /* D0 */
+    0x8080008000000080ull, /* D1 */
+    0x8080008000008000ull, /* D2 */
+    0x8080008000008080ull, /* D3 */
+    0x8080008000800000ull, /* D4 */
+    0x8080008000800080ull, /* D5 */
+    0x8080008000808000ull, /* D6 */
+    0x8080008000808080ull, /* D7 */
+    0x8080008080000000ull, /* D8 */
+    0x8080008080000080ull, /* D9 */
+    0x8080008080008000ull, /* DA */
+    0x8080008080008080ull, /* DB */
+    0x8080008080800000ull, /* DC */
+    0x8080008080800080ull, /* DD */
+    0x8080008080808000ull, /* DE */
+    0x8080008080808080ull, /* DF */
+    0x8080800000000000ull, /* E0 */
+    0x8080800000000080ull, /* E1 */
+    0x8080800000008000ull, /* E2 */
+    0x8080800000008080ull, /* E3 */
+    0x8080800000800000ull, /* E4 */
+    0x8080800000800080ull, /* E5 */
+    0x8080800000808000ull, /* E6 */
+    0x8080800000808080ull, /* E7 */
+    0x8080800080000000ull, /* E8 */
+    0x8080800080000080ull, /* E9 */
+    0x8080800080008000ull, /* EA */
+    0x8080800080008080ull, /* EB */
+    0x8080800080800000ull, /* EC */
+    0x8080800080800080ull, /* ED */
+    0x8080800080808000ull, /* EE */
+    0x8080800080808080ull, /* EF */
+    0x8080808000000000ull, /* F0 */
+    0x8080808000000080ull, /* F1 */
+    0x8080808000008000ull, /* F2 */
+    0x8080808000008080ull, /* F3 */
+    0x8080808000800000ull, /* F4 */
+    0x8080808000800080ull, /* F5 */
+    0x8080808000808000ull, /* F6 */
+    0x8080808000808080ull, /* F7 */
+    0x8080808080000000ull, /* F8 */
+    0x8080808080000080ull, /* F9 */
+    0x8080808080008000ull, /* FA */
+    0x8080808080008080ull, /* FB */
+    0x8080808080800000ull, /* FC */
+    0x8080808080800080ull, /* FD */
+    0x8080808080808000ull, /* FE */
+    0x8080808080808080ull, /* FF */
+};
+
+void helper_vgbbd(ppc_avr_t *r, ppc_avr_t *b)
+{
+    int i;
+    uint64_t t[2] = { 0, 0 };
+
+    VECTOR_FOR_INORDER_I(i, u8) {
+#if defined(HOST_WORDS_BIGENDIAN)
+        t[i>>3] |= VGBBD_MASKS[b->u8[i]] >> (i & 7);
+#else
+        t[i>>3] |= VGBBD_MASKS[b->u8[i]] >> (7-(i & 7));
+#endif
+    }
+
+    r->u64[0] = t[0];
+    r->u64[1] = t[1];
+}
+
 #if defined(HOST_WORDS_BIGENDIAN)
 #define PKBIG 1
 #else
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c6242c8..75e7f95 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7371,6 +7371,7 @@ GEN_VXFORM_DUAL(vclzw, PPC_NONE, PPC2_ALTIVEC_207, \
 GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \
                 vpopcntd, PPC_NONE, PPC2_ALTIVEC_207)
 GEN_VXFORM(vbpermq, 6, 21);
+GEN_VXFORM_NOA(vgbbd, 6, 20);
 
 /***                           VSX extension                               ***/
 
@@ -10621,6 +10622,7 @@ GEN_VXFORM_DUAL(vclzw, vpopcntw, 1, 30, PPC_NONE, PPC2_ALTIVEC_207),
 GEN_VXFORM_DUAL(vclzd, vpopcntd, 1, 31, PPC_NONE, PPC2_ALTIVEC_207),
 
 GEN_VXFORM_207(vbpermq, 6, 21),
+GEN_VXFORM_207(vgbbd, 6, 20),
 
 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 114/130] target-ppc: Altivec 2.07: Vector Polynomial Multiply Sum
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (112 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 113/130] target-ppc: Altivec 2.07: Vector Gather Bits by Bytes Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 115/130] target-ppc: Altivec 2.07: Binary Coded Decimal Instructions Alexander Graf
                   ` (16 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vectory Polynomial Multiply Sum instructions
introduced in Power ISA Version 2.07:

  - Vectory Polynomial Multiply Sum Byte (vpmsumb)
  - Vectory Polynomial Multiply Sum Halfword (vpmsumh)
  - Vectory Polynomial Multiply Sum Word (vpmsumw)
  - Vectory Polynomial Multiply Sum Doubleword (vpmsumd)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |  4 +++
 target-ppc/int_helper.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/translate.c  |  8 ++++++
 3 files changed, 82 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index aca712f..ca9eba5 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -311,6 +311,10 @@ DEF_HELPER_2(vpopcntw, void, avr, avr)
 DEF_HELPER_2(vpopcntd, void, avr, avr)
 DEF_HELPER_3(vbpermq, void, avr, avr, avr)
 DEF_HELPER_2(vgbbd, void, avr, avr)
+DEF_HELPER_3(vpmsumb, void, avr, avr, avr)
+DEF_HELPER_3(vpmsumh, void, avr, avr, avr)
+DEF_HELPER_3(vpmsumw, void, avr, avr, avr)
+DEF_HELPER_3(vpmsumd, void, avr, avr, avr)
 
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index cd0b88a..4e8e507 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -1351,6 +1351,76 @@ void helper_vgbbd(ppc_avr_t *r, ppc_avr_t *b)
     r->u64[1] = t[1];
 }
 
+#define PMSUM(name, srcfld, trgfld, trgtyp)                   \
+void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)  \
+{                                                             \
+    int i, j;                                                 \
+    trgtyp prod[sizeof(ppc_avr_t)/sizeof(a->srcfld[0])];      \
+                                                              \
+    VECTOR_FOR_INORDER_I(i, srcfld) {                         \
+        prod[i] = 0;                                          \
+        for (j = 0; j < sizeof(a->srcfld[0]) * 8; j++) {      \
+            if (a->srcfld[i] & (1ull<<j)) {                   \
+                prod[i] ^= ((trgtyp)b->srcfld[i] << j);       \
+            }                                                 \
+        }                                                     \
+    }                                                         \
+                                                              \
+    VECTOR_FOR_INORDER_I(i, trgfld) {                         \
+        r->trgfld[i] = prod[2*i] ^ prod[2*i+1];               \
+    }                                                         \
+}
+
+PMSUM(vpmsumb, u8, u16, uint16_t)
+PMSUM(vpmsumh, u16, u32, uint32_t)
+PMSUM(vpmsumw, u32, u64, uint64_t)
+
+void helper_vpmsumd(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+
+#ifdef CONFIG_INT128
+    int i, j;
+    __uint128_t prod[2];
+
+    VECTOR_FOR_INORDER_I(i, u64) {
+        prod[i] = 0;
+        for (j = 0; j < 64; j++) {
+            if (a->u64[i] & (1ull<<j)) {
+                prod[i] ^= (((__uint128_t)b->u64[i]) << j);
+            }
+        }
+    }
+
+    r->u128 = prod[0] ^ prod[1];
+
+#else
+    int i, j;
+    ppc_avr_t prod[2];
+
+    VECTOR_FOR_INORDER_I(i, u64) {
+        prod[i].u64[LO_IDX] = prod[i].u64[HI_IDX] = 0;
+        for (j = 0; j < 64; j++) {
+            if (a->u64[i] & (1ull<<j)) {
+                ppc_avr_t bshift;
+                if (j == 0) {
+                    bshift.u64[HI_IDX] = 0;
+                    bshift.u64[LO_IDX] = b->u64[i];
+                } else {
+                    bshift.u64[HI_IDX] = b->u64[i] >> (64-j);
+                    bshift.u64[LO_IDX] = b->u64[i] << j;
+                }
+                prod[i].u64[LO_IDX] ^= bshift.u64[LO_IDX];
+                prod[i].u64[HI_IDX] ^= bshift.u64[HI_IDX];
+            }
+        }
+    }
+
+    r->u64[LO_IDX] = prod[0].u64[LO_IDX] ^ prod[1].u64[LO_IDX];
+    r->u64[HI_IDX] = prod[0].u64[HI_IDX] ^ prod[1].u64[HI_IDX];
+#endif
+}
+
+
 #if defined(HOST_WORDS_BIGENDIAN)
 #define PKBIG 1
 #else
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 75e7f95..706bd5d 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7372,6 +7372,10 @@ GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \
                 vpopcntd, PPC_NONE, PPC2_ALTIVEC_207)
 GEN_VXFORM(vbpermq, 6, 21);
 GEN_VXFORM_NOA(vgbbd, 6, 20);
+GEN_VXFORM(vpmsumb, 4, 16)
+GEN_VXFORM(vpmsumh, 4, 17)
+GEN_VXFORM(vpmsumw, 4, 18)
+GEN_VXFORM(vpmsumd, 4, 19)
 
 /***                           VSX extension                               ***/
 
@@ -10623,6 +10627,10 @@ GEN_VXFORM_DUAL(vclzd, vpopcntd, 1, 31, PPC_NONE, PPC2_ALTIVEC_207),
 
 GEN_VXFORM_207(vbpermq, 6, 21),
 GEN_VXFORM_207(vgbbd, 6, 20),
+GEN_VXFORM_207(vpmsumb, 4, 16),
+GEN_VXFORM_207(vpmsumh, 4, 17),
+GEN_VXFORM_207(vpmsumw, 4, 18),
+GEN_VXFORM_207(vpmsumd, 4, 19),
 
 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 115/130] target-ppc: Altivec 2.07: Binary Coded Decimal Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (113 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 114/130] target-ppc: Altivec 2.07: Vector Polynomial Multiply Sum Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 116/130] target-ppc: Altivec 2.07: AES Instructions Alexander Graf
                   ` (15 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch add the Binary Coded Decimal instructions bcdadd. and
bcdsub.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |   3 +
 target-ppc/int_helper.c | 201 ++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/translate.c  |  45 ++++++++++-
 3 files changed, 245 insertions(+), 4 deletions(-)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index ca9eba5..ef6aa58 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -316,6 +316,9 @@ DEF_HELPER_3(vpmsumh, void, avr, avr, avr)
 DEF_HELPER_3(vpmsumw, void, avr, avr, avr)
 DEF_HELPER_3(vpmsumd, void, avr, avr, avr)
 
+DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32)
+DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32)
+
 DEF_HELPER_2(xsadddp, void, env, i32)
 DEF_HELPER_2(xssubdp, void, env, i32)
 DEF_HELPER_2(xsmuldp, void, env, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 4e8e507..ce7c6a0 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -2136,6 +2136,207 @@ void helper_vsubecuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
 #endif
 }
 
+#define BCD_PLUS_PREF_1 0xC
+#define BCD_PLUS_PREF_2 0xF
+#define BCD_PLUS_ALT_1  0xA
+#define BCD_NEG_PREF    0xD
+#define BCD_NEG_ALT     0xB
+#define BCD_PLUS_ALT_2  0xE
+
+#if defined(HOST_WORDS_BIGENDIAN)
+#define BCD_DIG_BYTE(n) (15 - (n/2))
+#else
+#define BCD_DIG_BYTE(n) (n/2)
+#endif
+
+static int bcd_get_sgn(ppc_avr_t *bcd)
+{
+    switch (bcd->u8[BCD_DIG_BYTE(0)] & 0xF) {
+    case BCD_PLUS_PREF_1:
+    case BCD_PLUS_PREF_2:
+    case BCD_PLUS_ALT_1:
+    case BCD_PLUS_ALT_2:
+    {
+        return 1;
+    }
+
+    case BCD_NEG_PREF:
+    case BCD_NEG_ALT:
+    {
+        return -1;
+    }
+
+    default:
+    {
+        return 0;
+    }
+    }
+}
+
+static int bcd_preferred_sgn(int sgn, int ps)
+{
+    if (sgn >= 0) {
+        return (ps == 0) ? BCD_PLUS_PREF_1 : BCD_PLUS_PREF_2;
+    } else {
+        return BCD_NEG_PREF;
+    }
+}
+
+static uint8_t bcd_get_digit(ppc_avr_t *bcd, int n, int *invalid)
+{
+    uint8_t result;
+    if (n & 1) {
+        result = bcd->u8[BCD_DIG_BYTE(n)] >> 4;
+    } else {
+       result = bcd->u8[BCD_DIG_BYTE(n)] & 0xF;
+    }
+
+    if (unlikely(result > 9)) {
+        *invalid = true;
+    }
+    return result;
+}
+
+static void bcd_put_digit(ppc_avr_t *bcd, uint8_t digit, int n)
+{
+    if (n & 1) {
+        bcd->u8[BCD_DIG_BYTE(n)] &= 0x0F;
+        bcd->u8[BCD_DIG_BYTE(n)] |= (digit<<4);
+    } else {
+        bcd->u8[BCD_DIG_BYTE(n)] &= 0xF0;
+        bcd->u8[BCD_DIG_BYTE(n)] |= digit;
+    }
+}
+
+static int bcd_cmp_mag(ppc_avr_t *a, ppc_avr_t *b)
+{
+    int i;
+    int invalid = 0;
+    for (i = 31; i > 0; i--) {
+        uint8_t dig_a = bcd_get_digit(a, i, &invalid);
+        uint8_t dig_b = bcd_get_digit(b, i, &invalid);
+        if (unlikely(invalid)) {
+            return 0; /* doesnt matter */
+        } else if (dig_a > dig_b) {
+            return 1;
+        } else if (dig_a < dig_b) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+static int bcd_add_mag(ppc_avr_t *t, ppc_avr_t *a, ppc_avr_t *b, int *invalid,
+                       int *overflow)
+{
+    int carry = 0;
+    int i;
+    int is_zero = 1;
+    for (i = 1; i <= 31; i++) {
+        uint8_t digit = bcd_get_digit(a, i, invalid) +
+                        bcd_get_digit(b, i, invalid) + carry;
+        is_zero &= (digit == 0);
+        if (digit > 9) {
+            carry = 1;
+            digit -= 10;
+        } else {
+            carry = 0;
+        }
+
+        bcd_put_digit(t, digit, i);
+
+        if (unlikely(*invalid)) {
+            return -1;
+        }
+    }
+
+    *overflow = carry;
+    return is_zero;
+}
+
+static int bcd_sub_mag(ppc_avr_t *t, ppc_avr_t *a, ppc_avr_t *b, int *invalid,
+                       int *overflow)
+{
+    int carry = 0;
+    int i;
+    int is_zero = 1;
+    for (i = 1; i <= 31; i++) {
+        uint8_t digit = bcd_get_digit(a, i, invalid) -
+                        bcd_get_digit(b, i, invalid) + carry;
+        is_zero &= (digit == 0);
+        if (digit & 0x80) {
+            carry = -1;
+            digit += 10;
+        } else {
+            carry = 0;
+        }
+
+        bcd_put_digit(t, digit, i);
+
+        if (unlikely(*invalid)) {
+            return -1;
+        }
+    }
+
+    *overflow = carry;
+    return is_zero;
+}
+
+uint32_t helper_bcdadd(ppc_avr_t *r,  ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
+{
+
+    int sgna = bcd_get_sgn(a);
+    int sgnb = bcd_get_sgn(b);
+    int invalid = (sgna == 0) || (sgnb == 0);
+    int overflow = 0;
+    int zero = 0;
+    uint32_t cr = 0;
+    ppc_avr_t result = { .u64 = { 0, 0 } };
+
+    if (!invalid) {
+        if (sgna == sgnb) {
+            result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgna, ps);
+            zero = bcd_add_mag(&result, a, b, &invalid, &overflow);
+            cr = (sgna > 0) ? 4 : 8;
+        } else if (bcd_cmp_mag(a, b) > 0) {
+            result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgna, ps);
+            zero = bcd_sub_mag(&result, a, b, &invalid, &overflow);
+            cr = (sgna > 0) ? 4 : 8;
+        } else {
+            result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgnb, ps);
+            zero = bcd_sub_mag(&result, b, a, &invalid, &overflow);
+            cr = (sgnb > 0) ? 4 : 8;
+        }
+    }
+
+    if (unlikely(invalid)) {
+        result.u64[HI_IDX] = result.u64[LO_IDX] = -1;
+        cr = 1;
+    } else if (overflow) {
+        cr |= 1;
+    } else if (zero) {
+        cr = 2;
+    }
+
+    *r = result;
+
+    return cr;
+}
+
+uint32_t helper_bcdsub(ppc_avr_t *r,  ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
+{
+    ppc_avr_t bcopy = *b;
+    int sgnb = bcd_get_sgn(b);
+    if (sgnb < 0) {
+        bcd_put_digit(&bcopy, BCD_PLUS_PREF_1, 0);
+    } else if (sgnb > 0) {
+        bcd_put_digit(&bcopy, BCD_NEG_PREF, 0);
+    }
+    /* else invalid ... defer to bcdadd code for proper handling */
+
+    return helper_bcdadd(r, a, &bcopy, ps);
+}
 
 #undef VECTOR_FOR_INORDER_I
 #undef HI_IDX
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 706bd5d..2b46cd6 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7377,6 +7377,43 @@ GEN_VXFORM(vpmsumh, 4, 17)
 GEN_VXFORM(vpmsumw, 4, 18)
 GEN_VXFORM(vpmsumd, 4, 19)
 
+#define GEN_BCD(op)                                 \
+static void gen_##op(DisasContext *ctx)             \
+{                                                   \
+    TCGv_ptr ra, rb, rd;                            \
+    TCGv_i32 ps;                                    \
+                                                    \
+    if (unlikely(!ctx->altivec_enabled)) {          \
+        gen_exception(ctx, POWERPC_EXCP_VPU);       \
+        return;                                     \
+    }                                               \
+                                                    \
+    ra = gen_avr_ptr(rA(ctx->opcode));              \
+    rb = gen_avr_ptr(rB(ctx->opcode));              \
+    rd = gen_avr_ptr(rD(ctx->opcode));              \
+                                                    \
+    ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \
+                                                    \
+    gen_helper_##op(cpu_crf[6], rd, ra, rb, ps);    \
+                                                    \
+    tcg_temp_free_ptr(ra);                          \
+    tcg_temp_free_ptr(rb);                          \
+    tcg_temp_free_ptr(rd);                          \
+    tcg_temp_free_i32(ps);                          \
+}
+
+GEN_BCD(bcdadd)
+GEN_BCD(bcdsub)
+
+GEN_VXFORM_DUAL(vsububm, PPC_ALTIVEC, PPC_NONE, \
+                bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vsububs, PPC_ALTIVEC, PPC_NONE, \
+                bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vsubuhm, PPC_ALTIVEC, PPC_NONE, \
+                bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vsubuhs, PPC_ALTIVEC, PPC_NONE, \
+                bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
+
 /***                           VSX extension                               ***/
 
 static inline TCGv_i64 cpu_vsrh(int n)
@@ -10442,8 +10479,8 @@ GEN_VXFORM(vaddubm, 0, 0),
 GEN_VXFORM(vadduhm, 0, 1),
 GEN_VXFORM(vadduwm, 0, 2),
 GEN_VXFORM_207(vaddudm, 0, 3),
-GEN_VXFORM(vsububm, 0, 16),
-GEN_VXFORM(vsubuhm, 0, 17),
+GEN_VXFORM_DUAL(vsububm, bcdadd, 0, 16, PPC_ALTIVEC, PPC_NONE),
+GEN_VXFORM_DUAL(vsubuhm, bcdsub, 0, 17, PPC_ALTIVEC, PPC_NONE),
 GEN_VXFORM(vsubuwm, 0, 18),
 GEN_VXFORM_207(vsubudm, 0, 19),
 GEN_VXFORM(vmaxub, 1, 0),
@@ -10510,8 +10547,8 @@ GEN_VXFORM(vadduws, 0, 10),
 GEN_VXFORM(vaddsbs, 0, 12),
 GEN_VXFORM(vaddshs, 0, 13),
 GEN_VXFORM(vaddsws, 0, 14),
-GEN_VXFORM(vsububs, 0, 24),
-GEN_VXFORM(vsubuhs, 0, 25),
+GEN_VXFORM_DUAL(vsububs, bcdadd, 0, 24, PPC_ALTIVEC, PPC_NONE),
+GEN_VXFORM_DUAL(vsubuhs, bcdsub, 0, 25, PPC_ALTIVEC, PPC_NONE),
 GEN_VXFORM(vsubuws, 0, 26),
 GEN_VXFORM(vsubsbs, 0, 28),
 GEN_VXFORM(vsubshs, 0, 29),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 116/130] target-ppc: Altivec 2.07: AES Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (114 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 115/130] target-ppc: Altivec 2.07: Binary Coded Decimal Instructions Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 117/130] target-ppc: Altivec 2.07: Vector SHA Sigma Instructions Alexander Graf
                   ` (14 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector AES instructions introduced in Power ISA
Version 2.07:

   - Vector AES Cipher (vcipher)
   - Vector AES Cipher Last (vcipherlast)
   - Vector AES Inverse Cipher (vncipher)
   - Vector AES Inverse Cipher Last (vncipherlast)
   - Vector AES SubBytes (vsbox)

Note that the implementation of vncipher deviates from the RTL in
ISA V2.07.  However it does match the verbal description in the
third paragraph.  The RTL will be fixed in ISA V2.07B.  The
implementation here has been tested against actual P8 hardware.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |   6 ++
 target-ppc/int_helper.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/translate.c  |  29 +++++
 3 files changed, 315 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index ef6aa58..93e549e 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -316,6 +316,12 @@ DEF_HELPER_3(vpmsumh, void, avr, avr, avr)
 DEF_HELPER_3(vpmsumw, void, avr, avr, avr)
 DEF_HELPER_3(vpmsumd, void, avr, avr, avr)
 
+DEF_HELPER_2(vsbox, void, avr, avr)
+DEF_HELPER_3(vcipher, void, avr, avr, avr)
+DEF_HELPER_3(vcipherlast, void, avr, avr, avr)
+DEF_HELPER_3(vncipher, void, avr, avr, avr)
+DEF_HELPER_3(vncipherlast, void, avr, avr, avr)
+
 DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32)
 DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32)
 
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index ce7c6a0..cd04e8a 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -2338,6 +2338,286 @@ uint32_t helper_bcdsub(ppc_avr_t *r,  ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
     return helper_bcdadd(r, a, &bcopy, ps);
 }
 
+static uint8_t SBOX[256] = {
+0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
+0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
+0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
+0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
+0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
+0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
+0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
+0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
+0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
+0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
+0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
+0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16,
+};
+
+static void SubBytes(ppc_avr_t *r, ppc_avr_t *a)
+{
+    int i;
+    VECTOR_FOR_INORDER_I(i, u8) {
+        r->u8[i] = SBOX[a->u8[i]];
+    }
+}
+
+static uint8_t InvSBOX[256] = {
+0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
+0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
+0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
+0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
+0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
+0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
+0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
+0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
+0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
+0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
+0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
+0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D,
+};
+
+static void InvSubBytes(ppc_avr_t *r, ppc_avr_t *a)
+{
+    int i;
+    VECTOR_FOR_INORDER_I(i, u8) {
+        r->u8[i] = InvSBOX[a->u8[i]];
+    }
+}
+
+static uint8_t ROTL8(uint8_t x, int n)
+{
+    return (x << n) | (x >> (8-n));
+}
+
+static inline int BIT8(uint8_t x, int n)
+{
+    return (x & (0x80 >> n)) != 0;
+}
+
+static uint8_t GFx02(uint8_t x)
+{
+    return ROTL8(x, 1) ^ (BIT8(x, 0) ? 0x1A : 0);
+}
+
+static uint8_t GFx03(uint8_t x)
+{
+    return x ^ ROTL8(x, 1) ^ (BIT8(x, 0) ? 0x1A : 0);
+}
+
+static uint8_t GFx09(uint8_t x)
+{
+    uint8_t term2 = ROTL8(x, 3);
+    uint8_t term3 = (BIT8(x, 0) ? 0x68 : 0) | (BIT8(x, 1) ? 0x14 : 0) |
+                    (BIT8(x, 2) ? 0x02 : 0);
+    uint8_t term4 = (BIT8(x, 1) ? 0x20 : 0) | (BIT8(x, 2) ? 0x18 : 0);
+    return x ^ term2 ^ term3 ^ term4;
+}
+
+static uint8_t GFx0B(uint8_t x)
+{
+    uint8_t term2 = ROTL8(x, 1);
+    uint8_t term3 = (x << 3) | (BIT8(x, 0) ? 0x06 : 0) |
+                    (BIT8(x, 2) ? 0x01 : 0);
+    uint8_t term4 = (BIT8(x, 0) ? 0x70 : 0) | (BIT8(x, 1) ? 0x06 : 0) |
+                    (BIT8(x, 2) ? 0x08 : 0);
+    uint8_t term5 = (BIT8(x, 1) ? 0x30 : 0) | (BIT8(x, 2) ? 0x02 : 0);
+    uint8_t term6 = BIT8(x, 2) ? 0x10 : 0;
+    return x ^ term2 ^ term3 ^ term4 ^ term5 ^ term6;
+}
+
+static uint8_t GFx0D(uint8_t x)
+{
+    uint8_t term2 = ROTL8(x, 2);
+    uint8_t term3 = (x << 3) | (BIT8(x, 1) ? 0x04 : 0) |
+                    (BIT8(x, 2) ? 0x03 : 0);
+    uint8_t term4 = (BIT8(x, 0) ? 0x58 : 0) | (BIT8(x, 1) ? 0x20 : 0);
+    uint8_t term5 = (BIT8(x, 1) ? 0x08 : 0) | (BIT8(x, 2) ? 0x10 : 0);
+    uint8_t term6 = BIT8(x, 2) ? 0x08 : 0;
+    return x ^ term2 ^ term3 ^ term4 ^ term5 ^ term6;
+}
+
+static uint8_t GFx0E(uint8_t x)
+{
+    uint8_t term1 = ROTL8(x, 1);
+    uint8_t term2 = (x << 2) | (BIT8(x, 2) ? 0x02 : 0) |
+                    (BIT8(x, 1) ? 0x01 : 0);
+    uint8_t term3 = (x << 3) | (BIT8(x, 1) ? 0x04 : 0) |
+                    (BIT8(x, 2) ? 0x01 : 0);
+    uint8_t term4 = (BIT8(x, 0) ? 0x40 : 0) | (BIT8(x, 1) ? 0x28 : 0) |
+                    (BIT8(x, 2) ? 0x10 : 0);
+    uint8_t term5 = (BIT8(x, 2) ? 0x08 : 0);
+    return term1 ^ term2 ^ term3 ^ term4 ^ term5;
+}
+
+#if defined(HOST_WORDS_BIGENDIAN)
+#define MCB(x, i, b) ((x)->u8[(i)*4 + (b)])
+#else
+#define MCB(x, i, b) ((x)->u8[15 - ((i)*4 + (b))])
+#endif
+
+static void MixColumns(ppc_avr_t *r, ppc_avr_t *x)
+{
+    int i;
+    for (i = 0; i < 4; i++) {
+        MCB(r, i, 0) = GFx02(MCB(x, i, 0)) ^ GFx03(MCB(x, i, 1)) ^
+                       MCB(x, i, 2) ^ MCB(x, i, 3);
+        MCB(r, i, 1) = MCB(x, i, 0) ^ GFx02(MCB(x, i, 1)) ^
+                       GFx03(MCB(x, i, 2)) ^ MCB(x, i, 3);
+        MCB(r, i, 2) = MCB(x, i, 0) ^ MCB(x, i, 1) ^
+                       GFx02(MCB(x, i, 2)) ^ GFx03(MCB(x, i, 3));
+        MCB(r, i, 3) = GFx03(MCB(x, i, 0)) ^ MCB(x, i, 1) ^
+                       MCB(x, i, 2) ^ GFx02(MCB(x, i, 3));
+    }
+}
+
+static void InvMixColumns(ppc_avr_t *r, ppc_avr_t *x)
+{
+    int i;
+    for (i = 0; i < 4; i++) {
+        MCB(r, i, 0) = GFx0E(MCB(x, i, 0)) ^ GFx0B(MCB(x, i, 1)) ^
+                       GFx0D(MCB(x, i, 2)) ^ GFx09(MCB(x, i, 3));
+        MCB(r, i, 1) = GFx09(MCB(x, i, 0)) ^ GFx0E(MCB(x, i, 1)) ^
+                       GFx0B(MCB(x, i, 2)) ^ GFx0D(MCB(x, i, 3));
+        MCB(r, i, 2) = GFx0D(MCB(x, i, 0)) ^ GFx09(MCB(x, i, 1)) ^
+                       GFx0E(MCB(x, i, 2)) ^ GFx0B(MCB(x, i, 3));
+        MCB(r, i, 3) = GFx0B(MCB(x, i, 0)) ^ GFx0D(MCB(x, i, 1)) ^
+                       GFx09(MCB(x, i, 2)) ^ GFx0E(MCB(x, i, 3));
+    }
+}
+
+static void ShiftRows(ppc_avr_t *r, ppc_avr_t *x)
+{
+    MCB(r, 0, 0) = MCB(x, 0, 0);
+    MCB(r, 1, 0) = MCB(x, 1, 0);
+    MCB(r, 2, 0) = MCB(x, 2, 0);
+    MCB(r, 3, 0) = MCB(x, 3, 0);
+
+    MCB(r, 0, 1) = MCB(x, 1, 1);
+    MCB(r, 1, 1) = MCB(x, 2, 1);
+    MCB(r, 2, 1) = MCB(x, 3, 1);
+    MCB(r, 3, 1) = MCB(x, 0, 1);
+
+    MCB(r, 0, 2) = MCB(x, 2, 2);
+    MCB(r, 1, 2) = MCB(x, 3, 2);
+    MCB(r, 2, 2) = MCB(x, 0, 2);
+    MCB(r, 3, 2) = MCB(x, 1, 2);
+
+    MCB(r, 0, 3) = MCB(x, 3, 3);
+    MCB(r, 1, 3) = MCB(x, 0, 3);
+    MCB(r, 2, 3) = MCB(x, 1, 3);
+    MCB(r, 3, 3) = MCB(x, 2, 3);
+}
+
+static void InvShiftRows(ppc_avr_t *r, ppc_avr_t *x)
+{
+    MCB(r, 0, 0) = MCB(x, 0, 0);
+    MCB(r, 1, 0) = MCB(x, 1, 0);
+    MCB(r, 2, 0) = MCB(x, 2, 0);
+    MCB(r, 3, 0) = MCB(x, 3, 0);
+
+    MCB(r, 0, 1) = MCB(x, 3, 1);
+    MCB(r, 1, 1) = MCB(x, 0, 1);
+    MCB(r, 2, 1) = MCB(x, 1, 1);
+    MCB(r, 3, 1) = MCB(x, 2, 1);
+
+    MCB(r, 0, 2) = MCB(x, 2, 2);
+    MCB(r, 1, 2) = MCB(x, 3, 2);
+    MCB(r, 2, 2) = MCB(x, 0, 2);
+    MCB(r, 3, 2) = MCB(x, 1, 2);
+
+    MCB(r, 0, 3) = MCB(x, 1, 3);
+    MCB(r, 1, 3) = MCB(x, 2, 3);
+    MCB(r, 2, 3) = MCB(x, 3, 3);
+    MCB(r, 3, 3) = MCB(x, 0, 3);
+}
+
+#undef MCB
+
+void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a)
+{
+    SubBytes(r, a);
+}
+
+void helper_vcipher(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+    ppc_avr_t vtemp1, vtemp2, vtemp3;
+    SubBytes(&vtemp1, a);
+    ShiftRows(&vtemp2, &vtemp1);
+    MixColumns(&vtemp3, &vtemp2);
+    r->u64[0] = vtemp3.u64[0] ^ b->u64[0];
+    r->u64[1] = vtemp3.u64[1] ^ b->u64[1];
+}
+
+void helper_vcipherlast(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+    ppc_avr_t vtemp1, vtemp2;
+    SubBytes(&vtemp1, a);
+    ShiftRows(&vtemp2, &vtemp1);
+    r->u64[0] = vtemp2.u64[0] ^ b->u64[0];
+    r->u64[1] = vtemp2.u64[1] ^ b->u64[1];
+}
+
+void helper_vncipher(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+    /* This differs from what is written in ISA V2.07.  The RTL is */
+    /* incorrect and will be fixed in V2.07B.                      */
+    ppc_avr_t vtemp1, vtemp2, vtemp3;
+    InvShiftRows(&vtemp1, a);
+    InvSubBytes(&vtemp2, &vtemp1);
+    vtemp3.u64[0] = vtemp2.u64[0] ^ b->u64[0];
+    vtemp3.u64[1] = vtemp2.u64[1] ^ b->u64[1];
+    InvMixColumns(r, &vtemp3);
+}
+
+void helper_vncipherlast(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+    ppc_avr_t vtemp1, vtemp2;
+    InvShiftRows(&vtemp1, a);
+    InvSubBytes(&vtemp2, &vtemp1);
+    r->u64[0] = vtemp2.u64[0] ^ b->u64[0];
+    r->u64[1] = vtemp2.u64[1] ^ b->u64[1];
+}
+
 #undef VECTOR_FOR_INORDER_I
 #undef HI_IDX
 #undef LO_IDX
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 2b46cd6..0d43b1c 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7414,6 +7414,30 @@ GEN_VXFORM_DUAL(vsubuhm, PPC_ALTIVEC, PPC_NONE, \
 GEN_VXFORM_DUAL(vsubuhs, PPC_ALTIVEC, PPC_NONE, \
                 bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
 
+static void gen_vsbox(DisasContext *ctx)
+{
+    TCGv_ptr ra, rd;
+    if (unlikely(!ctx->altivec_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_VPU);
+        return;
+    }
+    ra = gen_avr_ptr(rA(ctx->opcode));
+    rd = gen_avr_ptr(rD(ctx->opcode));
+    gen_helper_vsbox(rd, ra);
+    tcg_temp_free_ptr(ra);
+    tcg_temp_free_ptr(rd);
+}
+
+GEN_VXFORM(vcipher, 4, 20)
+GEN_VXFORM(vcipherlast, 4, 20)
+GEN_VXFORM(vncipher, 4, 21)
+GEN_VXFORM(vncipherlast, 4, 21)
+
+GEN_VXFORM_DUAL(vcipher, PPC_NONE, PPC2_ALTIVEC_207,
+                vcipherlast, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vncipher, PPC_NONE, PPC2_ALTIVEC_207,
+                vncipherlast, PPC_NONE, PPC2_ALTIVEC_207)
+
 /***                           VSX extension                               ***/
 
 static inline TCGv_i64 cpu_vsrh(int n)
@@ -10669,6 +10693,11 @@ GEN_VXFORM_207(vpmsumh, 4, 17),
 GEN_VXFORM_207(vpmsumw, 4, 18),
 GEN_VXFORM_207(vpmsumd, 4, 19),
 
+GEN_VXFORM_207(vsbox, 4, 23),
+
+GEN_VXFORM_DUAL(vcipher, vcipherlast, 4, 20, PPC_NONE, PPC2_ALTIVEC_207),
+GEN_VXFORM_DUAL(vncipher, vncipherlast, 4, 21, PPC_NONE, PPC2_ALTIVEC_207),
+
 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
 GEN_HANDLER_E(lxsiwzx, 0x1F, 0x0C, 0x00, 0, PPC_NONE, PPC2_VSX207),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 117/130] target-ppc: Altivec 2.07: Vector SHA Sigma Instructions
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (115 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 116/130] target-ppc: Altivec 2.07: AES Instructions Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 118/130] target-ppc: Altivec 2.07: Vector Permute and Exclusive OR Alexander Graf
                   ` (13 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector SHA Sigma instructions introduced in Power
ISA Version 2.07:

  - Vector SHA-512 Sigma Doubleword (vshasigmad)
  - Vector SHA-256 Sigma Word (vshasigmaw)

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |  2 ++
 target-ppc/int_helper.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/translate.c  | 24 +++++++++++++++
 3 files changed, 108 insertions(+)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 93e549e..dc0527b 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -321,6 +321,8 @@ DEF_HELPER_3(vcipher, void, avr, avr, avr)
 DEF_HELPER_3(vcipherlast, void, avr, avr, avr)
 DEF_HELPER_3(vncipher, void, avr, avr, avr)
 DEF_HELPER_3(vncipherlast, void, avr, avr, avr)
+DEF_HELPER_3(vshasigmaw, void, avr, avr, i32)
+DEF_HELPER_3(vshasigmad, void, avr, avr, i32)
 
 DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32)
 DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index cd04e8a..e6a7ad0 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -2618,6 +2618,88 @@ void helper_vncipherlast(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
     r->u64[1] = vtemp2.u64[1] ^ b->u64[1];
 }
 
+#define ROTRu32(v, n) (((v) >> (n)) | ((v) << (32-n)))
+#if defined(HOST_WORDS_BIGENDIAN)
+#define EL_IDX(i) (i)
+#else
+#define EL_IDX(i) (3 - (i))
+#endif
+
+void helper_vshasigmaw(ppc_avr_t *r,  ppc_avr_t *a, uint32_t st_six)
+{
+    int st = (st_six & 0x10) != 0;
+    int six = st_six & 0xF;
+    int i;
+
+    VECTOR_FOR_INORDER_I(i, u32) {
+        if (st == 0) {
+            if ((six & (0x8 >> i)) == 0) {
+                r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 7) ^
+                                    ROTRu32(a->u32[EL_IDX(i)], 18) ^
+                                    (a->u32[EL_IDX(i)] >> 3);
+            } else { /* six.bit[i] == 1 */
+                r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 17) ^
+                                    ROTRu32(a->u32[EL_IDX(i)], 19) ^
+                                    (a->u32[EL_IDX(i)] >> 10);
+            }
+        } else { /* st == 1 */
+            if ((six & (0x8 >> i)) == 0) {
+                r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 2) ^
+                                    ROTRu32(a->u32[EL_IDX(i)], 13) ^
+                                    ROTRu32(a->u32[EL_IDX(i)], 22);
+            } else { /* six.bit[i] == 1 */
+                r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 6) ^
+                                    ROTRu32(a->u32[EL_IDX(i)], 11) ^
+                                    ROTRu32(a->u32[EL_IDX(i)], 25);
+            }
+        }
+    }
+}
+
+#undef ROTRu32
+#undef EL_IDX
+
+#define ROTRu64(v, n) (((v) >> (n)) | ((v) << (64-n)))
+#if defined(HOST_WORDS_BIGENDIAN)
+#define EL_IDX(i) (i)
+#else
+#define EL_IDX(i) (1 - (i))
+#endif
+
+void helper_vshasigmad(ppc_avr_t *r,  ppc_avr_t *a, uint32_t st_six)
+{
+    int st = (st_six & 0x10) != 0;
+    int six = st_six & 0xF;
+    int i;
+
+    VECTOR_FOR_INORDER_I(i, u64) {
+        if (st == 0) {
+            if ((six & (0x8 >> (2*i))) == 0) {
+                r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 1) ^
+                                    ROTRu64(a->u64[EL_IDX(i)], 8) ^
+                                    (a->u64[EL_IDX(i)] >> 7);
+            } else { /* six.bit[2*i] == 1 */
+                r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 19) ^
+                                    ROTRu64(a->u64[EL_IDX(i)], 61) ^
+                                    (a->u64[EL_IDX(i)] >> 6);
+            }
+        } else { /* st == 1 */
+            if ((six & (0x8 >> (2*i))) == 0) {
+                r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 28) ^
+                                    ROTRu64(a->u64[EL_IDX(i)], 34) ^
+                                    ROTRu64(a->u64[EL_IDX(i)], 39);
+            } else { /* six.bit[2*i] == 1 */
+                r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 14) ^
+                                    ROTRu64(a->u64[EL_IDX(i)], 18) ^
+                                    ROTRu64(a->u64[EL_IDX(i)], 41);
+            }
+        }
+    }
+}
+
+#undef ROTRu64
+#undef EL_IDX
+
 #undef VECTOR_FOR_INORDER_I
 #undef HI_IDX
 #undef LO_IDX
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 0d43b1c..e1dffdf 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7438,6 +7438,27 @@ GEN_VXFORM_DUAL(vcipher, PPC_NONE, PPC2_ALTIVEC_207,
 GEN_VXFORM_DUAL(vncipher, PPC_NONE, PPC2_ALTIVEC_207,
                 vncipherlast, PPC_NONE, PPC2_ALTIVEC_207)
 
+#define VSHASIGMA(op)                         \
+static void gen_##op(DisasContext *ctx)       \
+{                                             \
+    TCGv_ptr ra, rd;                          \
+    TCGv_i32 st_six;                          \
+    if (unlikely(!ctx->altivec_enabled)) {    \
+        gen_exception(ctx, POWERPC_EXCP_VPU); \
+        return;                               \
+    }                                         \
+    ra = gen_avr_ptr(rA(ctx->opcode));        \
+    rd = gen_avr_ptr(rD(ctx->opcode));        \
+    st_six = tcg_const_i32(rB(ctx->opcode));  \
+    gen_helper_##op(rd, ra, st_six);          \
+    tcg_temp_free_ptr(ra);                    \
+    tcg_temp_free_ptr(rd);                    \
+    tcg_temp_free_i32(st_six);                \
+}
+
+VSHASIGMA(vshasigmaw)
+VSHASIGMA(vshasigmad)
+
 /***                           VSX extension                               ***/
 
 static inline TCGv_i64 cpu_vsrh(int n)
@@ -10698,6 +10719,9 @@ GEN_VXFORM_207(vsbox, 4, 23),
 GEN_VXFORM_DUAL(vcipher, vcipherlast, 4, 20, PPC_NONE, PPC2_ALTIVEC_207),
 GEN_VXFORM_DUAL(vncipher, vncipherlast, 4, 21, PPC_NONE, PPC2_ALTIVEC_207),
 
+GEN_VXFORM_207(vshasigmaw, 1, 26),
+GEN_VXFORM_207(vshasigmad, 1, 27),
+
 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
 GEN_HANDLER_E(lxsiwzx, 0x1F, 0x0C, 0x00, 0, PPC_NONE, PPC2_VSX207),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 118/130] target-ppc: Altivec 2.07: Vector Permute and Exclusive OR
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (116 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 117/130] target-ppc: Altivec 2.07: Vector SHA Sigma Instructions Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 119/130] spapr-vlan: flush queue whenever can_receive can go from false to true Alexander Graf
                   ` (12 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch adds the Vector Permuate and Exclusive OR (vpermxor)
instruction introduced in Power ISA Version 2.07.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/helper.h     |  1 +
 target-ppc/int_helper.c | 14 ++++++++++++++
 target-ppc/translate.c  |  7 ++++++-
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index dc0527b..99f10de 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -323,6 +323,7 @@ DEF_HELPER_3(vncipher, void, avr, avr, avr)
 DEF_HELPER_3(vncipherlast, void, avr, avr, avr)
 DEF_HELPER_3(vshasigmaw, void, avr, avr, i32)
 DEF_HELPER_3(vshasigmad, void, avr, avr, i32)
+DEF_HELPER_4(vpermxor, void, avr, avr, avr, avr)
 
 DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32)
 DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index e6a7ad0..63dde94 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -2700,6 +2700,20 @@ void helper_vshasigmad(ppc_avr_t *r,  ppc_avr_t *a, uint32_t st_six)
 #undef ROTRu64
 #undef EL_IDX
 
+void helper_vpermxor(ppc_avr_t *r,  ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
+{
+    int i;
+    VECTOR_FOR_INORDER_I(i, u8) {
+        int indexA = c->u8[i] >> 4;
+        int indexB = c->u8[i] & 0xF;
+#if defined(HOST_WORDS_BIGENDIAN)
+        r->u8[i] = a->u8[indexA] ^ b->u8[indexB];
+#else
+        r->u8[i] = a->u8[15-indexA] ^ b->u8[15-indexB];
+#endif
+    }
+}
+
 #undef VECTOR_FOR_INORDER_I
 #undef HI_IDX
 #undef LO_IDX
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index e1dffdf..cf8f98a 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7459,6 +7459,10 @@ static void gen_##op(DisasContext *ctx)       \
 VSHASIGMA(vshasigmaw)
 VSHASIGMA(vshasigmad)
 
+GEN_VXFORM3(vpermxor, 22, 0xFF)
+GEN_VXFORM_DUAL(vsldoi, PPC_ALTIVEC, PPC_NONE,
+                vpermxor, PPC_NONE, PPC2_ALTIVEC_207)
+
 /***                           VSX extension                               ***/
 
 static inline TCGv_i64 cpu_vsrh(int n)
@@ -10111,7 +10115,6 @@ GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
 GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
-GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC),
 GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
 GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
 GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
@@ -10722,6 +10725,8 @@ GEN_VXFORM_DUAL(vncipher, vncipherlast, 4, 21, PPC_NONE, PPC2_ALTIVEC_207),
 GEN_VXFORM_207(vshasigmaw, 1, 26),
 GEN_VXFORM_207(vshasigmad, 1, 27),
 
+GEN_VXFORM_DUAL(vsldoi, vpermxor, 22, 0xFF, PPC_ALTIVEC, PPC_NONE),
+
 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
 GEN_HANDLER_E(lxsiwzx, 0x1F, 0x0C, 0x00, 0, PPC_NONE, PPC2_VSX207),
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 119/130] spapr-vlan: flush queue whenever can_receive can go from false to true
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (117 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 118/130] target-ppc: Altivec 2.07: Vector Permute and Exclusive OR Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 120/130] target-ppc/translate.c: Use ULL suffix for 64 bit constants Alexander Graf
                   ` (11 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

When the guests adds buffers to receive queue, the network device
should flush its queue of pending packets. This is done with
qemu_flush_queued_packets.

This adds a call to qemu_flush_queued_packets() which wakes up the main
loop and let QEMU update the network device status which now is "can
receive". The patch basically does the same thing as e8b4c68 does.

Suggested-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/net/spapr_llan.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 1bd6f50..f6fbcb5 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -405,6 +405,8 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu,
 
     dev->rx_bufs++;
 
+    qemu_flush_queued_packets(qemu_get_queue(dev->nic));
+
     DPRINTF("h_add_logical_lan_buffer():  Added buf  ptr=%d  rx_bufs=%d"
             " bd=0x%016llx\n", dev->add_buf_ptr, dev->rx_bufs,
             (unsigned long long)buf);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 120/130] target-ppc/translate.c: Use ULL suffix for 64 bit constants
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (118 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 119/130] spapr-vlan: flush queue whenever can_receive can go from false to true Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 121/130] PPC: sPAPR: Only use getpagesize() when we run with kvm Alexander Graf
                   ` (10 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Peter Maydell, qemu-ppc, aurelien, aliguori

From: Peter Maydell <peter.maydell@linaro.org>

64 bit constants need the "ULL" suffix, not just "UL", because
on 32 bit platforms 'long' is not large enough and this will
cause a compiler warning.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index cf8f98a..051693b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -7727,8 +7727,8 @@ static void gen_xxpermdi(DisasContext *ctx)
 #define OP_NABS 2
 #define OP_NEG 3
 #define OP_CPSGN 4
-#define SGN_MASK_DP  0x8000000000000000ul
-#define SGN_MASK_SP 0x8000000080000000ul
+#define SGN_MASK_DP  0x8000000000000000ull
+#define SGN_MASK_SP 0x8000000080000000ull
 
 #define VSX_SCALAR_MOVE(name, op, sgn_mask)                       \
 static void glue(gen_, name)(DisasContext * ctx)                  \
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 121/130] PPC: sPAPR: Only use getpagesize() when we run with kvm
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (119 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 120/130] target-ppc/translate.c: Use ULL suffix for 64 bit constants Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 122/130] target-ppc: Fix Compiler Warnings Due to 64-Bit Constants Declared as UL Alexander Graf
                   ` (9 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel; +Cc: blauwirbel, Peter Maydell, qemu-ppc, aurelien, aliguori

We currently size the msi window trap page according to the host's page
size so that we poke a working hole into a memory slot in case we overlap.

However, this is only ever necessary with KVM active. Without KVM, we should
rather try to be host platform agnostic and use a constant size: 4k.

This fixes a build breakage on win32 hosts.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_pci.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 3956328..cea9469 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -469,6 +469,8 @@ static const MemoryRegionOps spapr_msi_ops = {
 
 void spapr_pci_msi_init(sPAPREnvironment *spapr, hwaddr addr)
 {
+    uint64_t window_size = 4096;
+
     /*
      * As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors,
      * we need to allocate some memory to catch those writes coming
@@ -476,10 +478,19 @@ void spapr_pci_msi_init(sPAPREnvironment *spapr, hwaddr addr)
      * As MSIMessage:addr is going to be the same and MSIMessage:data
      * is going to be a VIRQ number, 4 bytes of the MSI MR will only
      * be used.
+     *
+     * For KVM we want to ensure that this memory is a full page so that
+     * our memory slot is of page size granularity.
      */
+#ifdef CONFIG_KVM
+    if (kvm_enabled()) {
+        window_size = getpagesize();
+    }
+#endif
+
     spapr->msi_win_addr = addr;
     memory_region_init_io(&spapr->msiwindow, NULL, &spapr_msi_ops, spapr,
-                          "msi", getpagesize());
+                          "msi", window_size);
     memory_region_add_subregion(get_system_memory(), spapr->msi_win_addr,
                                 &spapr->msiwindow);
 }
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 122/130] target-ppc: Fix Compiler Warnings Due to 64-Bit Constants Declared as UL
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (120 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 121/130] PPC: sPAPR: Only use getpagesize() when we run with kvm Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 123/130] target-ppc: Use Additional Temporary in stqcx Case Alexander Graf
                   ` (8 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

This patch fixes 64 bit constants that were erroneously declared as "ul" instead of
"ull".  The preferred form "ULL" is used.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/fpu_helper.c | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index 4ef3e2f..e7f3295 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -635,15 +635,15 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg)                   \
     return farg.ll;                                                    \
  }
 
-FPU_FCTI(fctiw, int32, 0x80000000)
-FPU_FCTI(fctiwz, int32_round_to_zero, 0x80000000)
-FPU_FCTI(fctiwu, uint32, 0x00000000)
-FPU_FCTI(fctiwuz, uint32_round_to_zero, 0x00000000)
+FPU_FCTI(fctiw, int32, 0x80000000U)
+FPU_FCTI(fctiwz, int32_round_to_zero, 0x80000000U)
+FPU_FCTI(fctiwu, uint32, 0x00000000U)
+FPU_FCTI(fctiwuz, uint32_round_to_zero, 0x00000000U)
 #if defined(TARGET_PPC64)
-FPU_FCTI(fctid, int64, 0x8000000000000000)
-FPU_FCTI(fctidz, int64_round_to_zero, 0x8000000000000000)
-FPU_FCTI(fctidu, uint64, 0x0000000000000000)
-FPU_FCTI(fctiduz, uint64_round_to_zero, 0x0000000000000000)
+FPU_FCTI(fctid, int64, 0x8000000000000000ULL)
+FPU_FCTI(fctidz, int64_round_to_zero, 0x8000000000000000ULL)
+FPU_FCTI(fctidu, uint64, 0x0000000000000000ULL)
+FPU_FCTI(fctiduz, uint64_round_to_zero, 0x0000000000000000ULL)
 #endif
 
 #if defined(TARGET_PPC64)
@@ -680,7 +680,7 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg,
     if (unlikely(float64_is_signaling_nan(farg.d))) {
         /* sNaN round */
         fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
-        farg.ll = arg | 0x0008000000000000ul;
+        farg.ll = arg | 0x0008000000000000ULL;
     } else {
         int inexact = get_float_exception_flags(&env->fp_status) &
                       float_flag_inexact;
@@ -2372,7 +2372,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                      \
 VSX_SCALAR_CMP(xscmpodp, 1)
 VSX_SCALAR_CMP(xscmpudp, 0)
 
-#define float64_snan_to_qnan(x) ((x) | 0x0008000000000000ul)
+#define float64_snan_to_qnan(x) ((x) | 0x0008000000000000ULL)
 #define float32_snan_to_qnan(x) ((x) | 0x00400000)
 
 /* VSX_MAX_MIN - VSX floating point maximum/minimum
@@ -2570,26 +2570,26 @@ void helper_##op(CPUPPCState *env, uint32_t opcode)                          \
 }
 
 VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, f64[j], u64[i], i, \
-                  0x8000000000000000ul)
+                  0x8000000000000000ULL)
 VSX_CVT_FP_TO_INT(xscvdpsxws, 1, float64, int32, f64[i], u32[j], \
-                  2*i + JOFFSET, 0x80000000l)
-VSX_CVT_FP_TO_INT(xscvdpuxds, 1, float64, uint64, f64[j], u64[i], i, 0ul)
+                  2*i + JOFFSET, 0x80000000U)
+VSX_CVT_FP_TO_INT(xscvdpuxds, 1, float64, uint64, f64[j], u64[i], i, 0ULL)
 VSX_CVT_FP_TO_INT(xscvdpuxws, 1, float64, uint32, f64[i], u32[j], \
-                  2*i + JOFFSET, 0)
+                  2*i + JOFFSET, 0U)
 VSX_CVT_FP_TO_INT(xvcvdpsxds, 2, float64, int64, f64[j], u64[i], i, \
-                  0x8000000000000000ul)
+                  0x8000000000000000ULL)
 VSX_CVT_FP_TO_INT(xvcvdpsxws, 2, float64, int32, f64[i], u32[j], \
-                  2*i + JOFFSET, 0x80000000l)
-VSX_CVT_FP_TO_INT(xvcvdpuxds, 2, float64, uint64, f64[j], u64[i], i, 0ul)
+                  2*i + JOFFSET, 0x80000000U)
+VSX_CVT_FP_TO_INT(xvcvdpuxds, 2, float64, uint64, f64[j], u64[i], i, 0ULL)
 VSX_CVT_FP_TO_INT(xvcvdpuxws, 2, float64, uint32, f64[i], u32[j], \
-                  2*i + JOFFSET, 0)
+                  2*i + JOFFSET, 0U)
 VSX_CVT_FP_TO_INT(xvcvspsxds, 2, float32, int64, f32[j], u64[i], \
-                  2*i + JOFFSET, 0x8000000000000000ul)
+                  2*i + JOFFSET, 0x8000000000000000ULL)
 VSX_CVT_FP_TO_INT(xvcvspsxws, 4, float32, int32, f32[j], u32[j], i, \
-                  0x80000000l)
+                  0x80000000U)
 VSX_CVT_FP_TO_INT(xvcvspuxds, 2, float32, uint64, f32[j], u64[i], \
-                  2*i + JOFFSET, 0ul)
-VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, f32[j], u32[i], i, 0)
+                  2*i + JOFFSET, 0ULL)
+VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, f32[j], u32[i], i, 0U)
 
 /* VSX_CVT_INT_TO_FP - VSX integer to floating point conversion
  *   op    - instruction mnemonic
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 123/130] target-ppc: Use Additional Temporary in stqcx Case
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (121 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 122/130] target-ppc: Fix Compiler Warnings Due to 64-Bit Constants Declared as UL Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 124/130] target-ppc: Fix htab_mask calculation Alexander Graf
                   ` (7 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Tom Musta, blauwirbel, qemu-ppc, aliguori, aurelien

From: Tom Musta <tommusta@gmail.com>

Per Alex Graf's suggestion, the recently added case to gen_conditional_store
for stqcx should use an additional temporary when accessing the second
doubleword.  This avoids the mutation of the EA argument to the function,
which is counter intuitive.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/translate.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 051693b..91c33dc 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3333,7 +3333,7 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
         gen_qemu_st16(ctx, cpu_gpr[reg], EA);
 #if defined(TARGET_PPC64)
     } else if (size == 16) {
-        TCGv gpr1, gpr2;
+        TCGv gpr1, gpr2 , EA8;
         if (unlikely(ctx->le_mode)) {
             gpr1 = cpu_gpr[reg+1];
             gpr2 = cpu_gpr[reg];
@@ -3342,8 +3342,10 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
             gpr2 = cpu_gpr[reg+1];
         }
         gen_qemu_st64(ctx, gpr1, EA);
-        gen_addr_add(ctx, EA, EA, 8);
-        gen_qemu_st64(ctx, gpr2, EA);
+        EA8 = tcg_temp_local_new();
+        gen_addr_add(ctx, EA8, EA, 8);
+        gen_qemu_st64(ctx, gpr2, EA8);
+        tcg_temp_free(EA8);
 #endif
     } else {
         gen_qemu_st8(ctx, cpu_gpr[reg], EA);
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 124/130] target-ppc: Fix htab_mask calculation
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (122 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 123/130] target-ppc: Use Additional Temporary in stqcx Case Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 125/130] target-ppc: Fix page table lookup with kvm enabled Alexander Graf
                   ` (6 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, qemu-ppc, Aneesh Kumar K.V, aliguori,
	aurelien, Greg Kurz

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

Correctly update the htab_mask using the return value of
KVM_PPC_ALLOCATE_HTAB ioctl. Also we don't update sdr1
on GET_SREGS for HV. We check for external htab and if
found true, we don't need to update sdr1

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
[ fixed pte group offset computation in ppc_hash64_htab_lookup() that
  caused TCG to fail, Greg Kurz <gkurz@linux.vnet.ibm.com> ]
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c           |  8 +++++++-
 hw/ppc/spapr_hcall.c     | 19 +++++++++++++++----
 target-ppc/cpu.h         |  1 +
 target-ppc/kvm.c         |  4 +++-
 target-ppc/machine.c     | 11 +++++++----
 target-ppc/misc_helper.c |  4 +++-
 target-ppc/mmu-hash64.c  |  4 ++--
 target-ppc/mmu_helper.c  |  3 ++-
 8 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 0989ed6..8ac4d8a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -749,7 +749,13 @@ static void spapr_cpu_reset(void *opaque)
         env->external_htab = (void *)1;
     }
     env->htab_base = -1;
-    env->htab_mask = HTAB_SIZE(spapr) - 1;
+    /*
+     * htab_mask is the mask used to normalize hash value to PTEG index.
+     * htab_shift is log2 of hash table size.
+     * We have 8 hpte per group, and each hpte is 16 bytes.
+     * ie have 128 bytes per hpte entry.
+     */
+    env->htab_mask = (1ULL << ((spapr)->htab_shift - 7)) - 1;
     env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab |
         (spapr->htab_shift - 18);
 }
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 3ffcc65..d19e3fc 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -40,6 +40,17 @@ static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,
     return rb;
 }
 
+static inline bool valid_pte_index(CPUPPCState *env, target_ulong pte_index)
+{
+    /*
+     * hash value/pteg group index is normalized by htab_mask
+     */
+    if (((pte_index & ~7ULL) / HPTES_PER_GROUP) & ~env->htab_mask) {
+        return false;
+    }
+    return true;
+}
+
 static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                             target_ulong opcode, target_ulong *args)
 {
@@ -91,7 +102,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 
     pteh &= ~0x60ULL;
 
-    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
+    if (!valid_pte_index(env, pte_index)) {
         return H_PARAMETER;
     }
     if (likely((flags & H_EXACT) == 0)) {
@@ -136,7 +147,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
     hwaddr hpte;
     target_ulong v, r, rb;
 
-    if ((ptex * HASH_PTE_SIZE_64) & ~env->htab_mask) {
+    if (!valid_pte_index(env, ptex)) {
         return REMOVE_PARM;
     }
 
@@ -262,7 +273,7 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     hwaddr hpte;
     target_ulong v, r, rb;
 
-    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
+    if (!valid_pte_index(env, pte_index)) {
         return H_PARAMETER;
     }
 
@@ -299,7 +310,7 @@ static target_ulong h_read(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     uint8_t *hpte;
     int i, ridx, n_entries = 1;
 
-    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {
+    if (!valid_pte_index(env, pte_index)) {
         return H_PARAMETER;
     }
 
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 7ccf4c6..44ade0c 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -966,6 +966,7 @@ struct CPUPPCState {
 #endif
     /* segment registers */
     hwaddr htab_base;
+    /* mask used to normalize hash value to PTEG index */
     hwaddr htab_mask;
     target_ulong sr[32];
     /* externally stored hash table */
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 33d69d2..969ebdd 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1031,7 +1031,9 @@ int kvm_arch_get_registers(CPUState *cs)
             return ret;
         }
 
-        ppc_store_sdr1(env, sregs.u.s.sdr1);
+        if (!env->external_htab) {
+            ppc_store_sdr1(env, sregs.u.s.sdr1);
+        }
 
         /* Sync SLB */
 #ifdef TARGET_PPC64
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 12c174f..2d46cec 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -70,7 +70,9 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
         qemu_get_betls(f, &env->pb[i]);
     for (i = 0; i < 1024; i++)
         qemu_get_betls(f, &env->spr[i]);
-    ppc_store_sdr1(env, sdr1);
+    if (!env->external_htab) {
+        ppc_store_sdr1(env, sdr1);
+    }
     qemu_get_be32s(f, &env->vscr);
     qemu_get_be64s(f, &env->spe_acc);
     qemu_get_be32s(f, &env->spe_fscr);
@@ -179,9 +181,10 @@ static int cpu_post_load(void *opaque, int version_id)
         env->IBAT[1][i+4] = env->spr[SPR_IBAT4U + 2*i + 1];
     }
 
-    /* Restore htab_base and htab_mask variables */
-    ppc_store_sdr1(env, env->spr[SPR_SDR1]);
-
+    if (!env->external_htab) {
+        /* Restore htab_base and htab_mask variables */
+        ppc_store_sdr1(env, env->spr[SPR_SDR1]);
+    }
     hreg_compute_hflags(env);
     hreg_compute_mem_idx(env);
 
diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c
index 616aab6..dc2ebfc 100644
--- a/target-ppc/misc_helper.c
+++ b/target-ppc/misc_helper.c
@@ -38,7 +38,9 @@ void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn)
 
 void helper_store_sdr1(CPUPPCState *env, target_ulong val)
 {
-    ppc_store_sdr1(env, val);
+    if (!env->external_htab) {
+        ppc_store_sdr1(env, val);
+    }
 }
 
 void helper_store_hid0_601(CPUPPCState *env, target_ulong val)
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index c1c33b0..739dece 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -375,7 +375,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
             " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
             " hash=" TARGET_FMT_plx "\n",
             env->htab_base, env->htab_mask, vsid, ptem,  hash);
-    pteg_off = (hash * HASH_PTEG_SIZE_64) & env->htab_mask;
+    pteg_off = (hash & env->htab_mask) * HASH_PTEG_SIZE_64;
     pte_offset = ppc_hash64_pteg_search(env, pteg_off, 0, ptem, pte);
 
     if (pte_offset == -1) {
@@ -385,7 +385,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
                 " hash=" TARGET_FMT_plx "\n", env->htab_base,
                 env->htab_mask, vsid, ptem, ~hash);
 
-        pteg_off = (~hash * HASH_PTEG_SIZE_64) & env->htab_mask;
+        pteg_off = (~hash & env->htab_mask) * HASH_PTEG_SIZE_64;
         pte_offset = ppc_hash64_pteg_search(env, pteg_off, 1, ptem, pte);
     }
 
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 04a840b..8e2f8e7 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -2014,6 +2014,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
 void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
 {
     LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
+    assert(!env->external_htab);
     if (env->spr[SPR_SDR1] != value) {
         env->spr[SPR_SDR1] = value;
 #if defined(TARGET_PPC64)
@@ -2025,7 +2026,7 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
                         " stored in SDR1\n", htabsize);
                 htabsize = 28;
             }
-            env->htab_mask = (1ULL << (htabsize + 18)) - 1;
+            env->htab_mask = (1ULL << (htabsize + 18 - 7)) - 1;
             env->htab_base = value & SDR_64_HTABORG;
         } else
 #endif /* defined(TARGET_PPC64) */
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 125/130] target-ppc: Fix page table lookup with kvm enabled
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (123 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 124/130] target-ppc: Fix htab_mask calculation Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-14 11:26   ` Paolo Bonzini
  2014-03-06 23:34 ` [Qemu-devel] [PULL 126/130] target-ppc: Change the hpte store API Alexander Graf
                   ` (5 subsequent siblings)
  130 siblings, 1 reply; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, qemu-ppc, Aneesh Kumar K.V, aliguori,
	aurelien, Greg Kurz

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

With kvm enabled, we store the hash page table information in the hypervisor.
Use ioctl to read the htab contents. Without this we get the below error when
trying to read the guest address

 (gdb) x/10 do_fork
 0xc000000000098660 <do_fork>:   Cannot access memory at address 0xc000000000098660
 (gdb)

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
[ fixes for 32 bit build (casts!), ldq_phys() API change,
  Greg Kurz <gkurz@linux.vnet.ibm.com ]
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr.c          |  1 +
 hw/ppc/spapr_hcall.c    | 50 +++++++++++++++++++------------
 target-ppc/kvm.c        | 54 ++++++++++++++++++++++++++++++++++
 target-ppc/kvm_ppc.h    | 19 ++++++++++++
 target-ppc/mmu-hash64.c | 78 ++++++++++++++++++++++++++++++++++++++++---------
 target-ppc/mmu-hash64.h | 22 +++++++++-----
 6 files changed, 184 insertions(+), 40 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 8ac4d8a..94cf520 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -686,6 +686,7 @@ static void spapr_reset_htab(sPAPREnvironment *spapr)
     if (shift > 0) {
         /* Kernel handles htab, we don't need to allocate one */
         spapr->htab_shift = shift;
+        kvmppc_kern_htab = true;
     } else {
         if (!spapr->htab) {
             /* Allocate an htab if we don't yet have one */
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index d19e3fc..7493302 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -61,8 +61,9 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     target_ulong ptel = args[3];
     target_ulong page_shift = 12;
     target_ulong raddr;
-    target_ulong i;
+    target_ulong index;
     hwaddr hpte;
+    uint64_t token;
 
     /* only handle 4k and 16M pages for now */
     if (pteh & HPTE64_V_LARGE) {
@@ -105,30 +106,37 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     if (!valid_pte_index(env, pte_index)) {
         return H_PARAMETER;
     }
+
+    index = 0;
+    hpte = pte_index * HASH_PTE_SIZE_64;
     if (likely((flags & H_EXACT) == 0)) {
         pte_index &= ~7ULL;
-        hpte = pte_index * HASH_PTE_SIZE_64;
-        for (i = 0; ; ++i) {
-            if (i == 8) {
+        token = ppc_hash64_start_access(cpu, pte_index);
+        do {
+            if (index == 8) {
+                ppc_hash64_stop_access(token);
                 return H_PTEG_FULL;
             }
-            if ((ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) == 0) {
+            if ((ppc_hash64_load_hpte0(env, token, index) & HPTE64_V_VALID) == 0) {
                 break;
             }
-            hpte += HASH_PTE_SIZE_64;
-        }
+        } while (index++);
+        ppc_hash64_stop_access(token);
     } else {
-        i = 0;
-        hpte = pte_index * HASH_PTE_SIZE_64;
-        if (ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) {
+        token = ppc_hash64_start_access(cpu, pte_index);
+        if (ppc_hash64_load_hpte0(env, token, 0) & HPTE64_V_VALID) {
+            ppc_hash64_stop_access(token);
             return H_PTEG_FULL;
         }
+        ppc_hash64_stop_access(token);
     }
+    hpte += index * HASH_PTE_SIZE_64;
+
     ppc_hash64_store_hpte1(env, hpte, ptel);
     /* eieio();  FIXME: need some sort of barrier for smp? */
     ppc_hash64_store_hpte0(env, hpte, pteh | HPTE64_V_HPTE_DIRTY);
 
-    args[0] = pte_index + i;
+    args[0] = pte_index + index;
     return H_SUCCESS;
 }
 
@@ -145,16 +153,17 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
                                 target_ulong *vp, target_ulong *rp)
 {
     hwaddr hpte;
+    uint64_t token;
     target_ulong v, r, rb;
 
     if (!valid_pte_index(env, ptex)) {
         return REMOVE_PARM;
     }
 
-    hpte = ptex * HASH_PTE_SIZE_64;
-
-    v = ppc_hash64_load_hpte0(env, hpte);
-    r = ppc_hash64_load_hpte1(env, hpte);
+    token = ppc_hash64_start_access(ppc_env_get_cpu(env), ptex);
+    v = ppc_hash64_load_hpte0(env, token, 0);
+    r = ppc_hash64_load_hpte1(env, token, 0);
+    ppc_hash64_stop_access(token);
 
     if ((v & HPTE64_V_VALID) == 0 ||
         ((flags & H_AVPN) && (v & ~0x7fULL) != avpn) ||
@@ -163,6 +172,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
     }
     *vp = v;
     *rp = r;
+    hpte = ptex * HASH_PTE_SIZE_64;
     ppc_hash64_store_hpte0(env, hpte, HPTE64_V_HPTE_DIRTY);
     rb = compute_tlbie_rb(v, r, ptex);
     ppc_tlb_invalidate_one(env, rb);
@@ -271,16 +281,17 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     target_ulong pte_index = args[1];
     target_ulong avpn = args[2];
     hwaddr hpte;
+    uint64_t token;
     target_ulong v, r, rb;
 
     if (!valid_pte_index(env, pte_index)) {
         return H_PARAMETER;
     }
 
-    hpte = pte_index * HASH_PTE_SIZE_64;
-
-    v = ppc_hash64_load_hpte0(env, hpte);
-    r = ppc_hash64_load_hpte1(env, hpte);
+    token = ppc_hash64_start_access(cpu, pte_index);
+    v = ppc_hash64_load_hpte0(env, token, 0);
+    r = ppc_hash64_load_hpte1(env, token, 0);
+    ppc_hash64_stop_access(token);
 
     if ((v & HPTE64_V_VALID) == 0 ||
         ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {
@@ -293,6 +304,7 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     r |= (flags << 48) & HPTE64_R_KEY_HI;
     r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
     rb = compute_tlbie_rb(v, r, pte_index);
+    hpte = pte_index * HASH_PTE_SIZE_64;
     ppc_hash64_store_hpte0(env, hpte, (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY);
     ppc_tlb_invalidate_one(env, rb);
     ppc_hash64_store_hpte1(env, hpte, r);
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 969ebdd..e009919 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1788,6 +1788,11 @@ bool kvmppc_has_cap_epr(void)
     return cap_epr;
 }
 
+bool kvmppc_has_cap_htab_fd(void)
+{
+    return cap_htab_fd;
+}
+
 static int kvm_ppc_register_host_cpu_type(void)
 {
     TypeInfo type_info = {
@@ -1938,3 +1943,52 @@ void kvm_arch_remove_all_hw_breakpoints(void)
 void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg)
 {
 }
+
+struct kvm_get_htab_buf {
+    struct kvm_get_htab_header header;
+    /*
+     * We require one extra byte for read
+     */
+    target_ulong hpte[(HPTES_PER_GROUP * 2) + 1];
+};
+
+uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index)
+{
+    int htab_fd;
+    struct kvm_get_htab_fd ghf;
+    struct kvm_get_htab_buf  *hpte_buf;
+
+    ghf.flags = 0;
+    ghf.start_index = pte_index;
+    htab_fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf);
+    if (htab_fd < 0) {
+        goto error_out;
+    }
+
+    hpte_buf = g_malloc0(sizeof(*hpte_buf));
+    /*
+     * Read the hpte group
+     */
+    if (read(htab_fd, hpte_buf, sizeof(*hpte_buf)) < 0) {
+        goto out_close;
+    }
+
+    close(htab_fd);
+    return (uint64_t)(uintptr_t) hpte_buf->hpte;
+
+out_close:
+    g_free(hpte_buf);
+    close(htab_fd);
+error_out:
+    return 0;
+}
+
+void kvmppc_hash64_free_pteg(uint64_t token)
+{
+    struct kvm_get_htab_buf *htab_buf;
+
+    htab_buf = container_of((void *)(uintptr_t) token, struct kvm_get_htab_buf,
+                            hpte);
+    g_free(htab_buf);
+    return;
+}
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 5f78e4b..800e1ad 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -39,10 +39,13 @@ uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift);
 int kvmppc_fixup_cpu(PowerPCCPU *cpu);
 bool kvmppc_has_cap_epr(void);
 int kvmppc_define_rtas_kernel_token(uint32_t token, const char *function);
+bool kvmppc_has_cap_htab_fd(void);
 int kvmppc_get_htab_fd(bool write);
 int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns);
 int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
                            uint16_t n_valid, uint16_t n_invalid);
+uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index);
+void kvmppc_hash64_free_pteg(uint64_t token);
 
 #else
 
@@ -171,6 +174,11 @@ static inline int kvmppc_define_rtas_kernel_token(uint32_t token,
     return -1;
 }
 
+static inline bool kvmppc_has_cap_htab_fd(void)
+{
+    return false;
+}
+
 static inline int kvmppc_get_htab_fd(bool write)
 {
     return -1;
@@ -188,6 +196,17 @@ static inline int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
     abort();
 }
 
+static inline uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu,
+                                               target_ulong pte_index)
+{
+    abort();
+}
+
+static inline void kvmppc_hash64_free_pteg(uint64_t token)
+{
+    abort();
+}
+
 #endif
 
 #ifndef CONFIG_KVM
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 739dece..68a6f69 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -41,6 +41,11 @@
 #endif
 
 /*
+ * Used to indicate whether we have allocated htab in the
+ * host kernel
+ */
+bool kvmppc_kern_htab;
+/*
  * SLB handling
  */
 
@@ -310,29 +315,76 @@ static int ppc_hash64_amr_prot(CPUPPCState *env, ppc_hash_pte64_t pte)
     return prot;
 }
 
-static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr pteg_off,
+uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong pte_index)
+{
+    uint64_t token = 0;
+    hwaddr pte_offset;
+
+    pte_offset = pte_index * HASH_PTE_SIZE_64;
+    if (kvmppc_kern_htab) {
+        /*
+         * HTAB is controlled by KVM. Fetch the PTEG into a new buffer.
+         */
+        token = kvmppc_hash64_read_pteg(cpu, pte_index);
+        if (token) {
+            return token;
+        }
+        /*
+         * pteg read failed, even though we have allocated htab via
+         * kvmppc_reset_htab.
+         */
+        return 0;
+    }
+    /*
+     * HTAB is controlled by QEMU. Just point to the internally
+     * accessible PTEG.
+     */
+    if (cpu->env.external_htab) {
+        token = (uint64_t)(uintptr_t) cpu->env.external_htab + pte_offset;
+    } else if (cpu->env.htab_base) {
+        token = cpu->env.htab_base + pte_offset;
+    }
+    return token;
+}
+
+void ppc_hash64_stop_access(uint64_t token)
+{
+    if (kvmppc_kern_htab) {
+        return kvmppc_hash64_free_pteg(token);
+    }
+}
+
+static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, hwaddr hash,
                                      bool secondary, target_ulong ptem,
                                      ppc_hash_pte64_t *pte)
 {
-    hwaddr pte_offset = pteg_off;
-    target_ulong pte0, pte1;
     int i;
+    uint64_t token;
+    target_ulong pte0, pte1;
+    target_ulong pte_index;
 
+    pte_index = (hash & env->htab_mask) * HPTES_PER_GROUP;
+    token = ppc_hash64_start_access(ppc_env_get_cpu(env), pte_index);
+    if (!token) {
+        return -1;
+    }
     for (i = 0; i < HPTES_PER_GROUP; i++) {
-        pte0 = ppc_hash64_load_hpte0(env, pte_offset);
-        pte1 = ppc_hash64_load_hpte1(env, pte_offset);
+        pte0 = ppc_hash64_load_hpte0(env, token, i);
+        pte1 = ppc_hash64_load_hpte1(env, token, i);
 
         if ((pte0 & HPTE64_V_VALID)
             && (secondary == !!(pte0 & HPTE64_V_SECONDARY))
             && HPTE64_V_COMPARE(pte0, ptem)) {
             pte->pte0 = pte0;
             pte->pte1 = pte1;
-            return pte_offset;
+            ppc_hash64_stop_access(token);
+            return (pte_index + i) * HASH_PTE_SIZE_64;
         }
-
-        pte_offset += HASH_PTE_SIZE_64;
     }
-
+    ppc_hash64_stop_access(token);
+    /*
+     * We didn't find a valid entry.
+     */
     return -1;
 }
 
@@ -340,7 +392,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
                                      ppc_slb_t *slb, target_ulong eaddr,
                                      ppc_hash_pte64_t *pte)
 {
-    hwaddr pteg_off, pte_offset;
+    hwaddr pte_offset;
     hwaddr hash;
     uint64_t vsid, epnshift, epnmask, epn, ptem;
 
@@ -375,8 +427,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
             " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
             " hash=" TARGET_FMT_plx "\n",
             env->htab_base, env->htab_mask, vsid, ptem,  hash);
-    pteg_off = (hash & env->htab_mask) * HASH_PTEG_SIZE_64;
-    pte_offset = ppc_hash64_pteg_search(env, pteg_off, 0, ptem, pte);
+    pte_offset = ppc_hash64_pteg_search(env, hash, 0, ptem, pte);
 
     if (pte_offset == -1) {
         /* Secondary PTEG lookup */
@@ -385,8 +436,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
                 " hash=" TARGET_FMT_plx "\n", env->htab_base,
                 env->htab_mask, vsid, ptem, ~hash);
 
-        pteg_off = (~hash & env->htab_mask) * HASH_PTEG_SIZE_64;
-        pte_offset = ppc_hash64_pteg_search(env, pteg_off, 1, ptem, pte);
+        pte_offset = ppc_hash64_pteg_search(env, ~hash, 1, ptem, pte);
     }
 
     return pte_offset;
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index a8da558..e7cb96f 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -75,26 +75,34 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
 #define HPTE64_V_1TB_SEG        0x4000000000000000ULL
 #define HPTE64_V_VRMA_MASK      0x4001ffffff000000ULL
 
+
+extern bool kvmppc_kern_htab;
+uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong pte_index);
+void ppc_hash64_stop_access(uint64_t token);
+
 static inline target_ulong ppc_hash64_load_hpte0(CPUPPCState *env,
-                                                 hwaddr pte_offset)
+                                                 uint64_t token, int index)
 {
     CPUState *cs = ENV_GET_CPU(env);
+    uint64_t addr;
+    addr = token + (index * HASH_PTE_SIZE_64);
     if (env->external_htab) {
-        return  ldq_p(env->external_htab + pte_offset);
+        return  ldq_p((const void *)(uintptr_t)addr);
     } else {
-        return ldq_phys(cs->as, env->htab_base + pte_offset);
+        return ldq_phys(cs->as, addr);
     }
 }
 
 static inline target_ulong ppc_hash64_load_hpte1(CPUPPCState *env,
-                                                 hwaddr pte_offset)
+                                                 uint64_t token, int index)
 {
     CPUState *cs = ENV_GET_CPU(env);
+    uint64_t addr;
+    addr = token + (index * HASH_PTE_SIZE_64) + HASH_PTE_SIZE_64/2;
     if (env->external_htab) {
-        return ldq_p(env->external_htab + pte_offset + HASH_PTE_SIZE_64/2);
+        return  ldq_p((const void *)(uintptr_t)addr);
     } else {
-        return ldq_phys(cs->as,
-                        env->htab_base + pte_offset + HASH_PTE_SIZE_64/2);
+        return ldq_phys(cs->as, addr);
     }
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 126/130] target-ppc: Change the hpte store API
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (124 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 125/130] target-ppc: Fix page table lookup with kvm enabled Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 127/130] target-ppc: Update ppc_hash64_store_hpte to support updating in-kernel htab Alexander Graf
                   ` (4 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, qemu-ppc, Aneesh Kumar K.V, aliguori,
	aurelien, Greg Kurz

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

For updating in kernel htab we need to provide both pte0 and pte1, hence update
the interface to take pte0 and pte1 together

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
[ ldq_phys() API change, Greg Kurz <gkurz@linux.vnet.ibm.com> ]
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_hcall.c    | 20 ++++++--------------
 target-ppc/mmu-hash64.c |  3 ++-
 target-ppc/mmu-hash64.h | 24 ++++++++----------------
 3 files changed, 16 insertions(+), 31 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 7493302..b0f2529 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -62,7 +62,6 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     target_ulong page_shift = 12;
     target_ulong raddr;
     target_ulong index;
-    hwaddr hpte;
     uint64_t token;
 
     /* only handle 4k and 16M pages for now */
@@ -108,7 +107,6 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     }
 
     index = 0;
-    hpte = pte_index * HASH_PTE_SIZE_64;
     if (likely((flags & H_EXACT) == 0)) {
         pte_index &= ~7ULL;
         token = ppc_hash64_start_access(cpu, pte_index);
@@ -130,11 +128,9 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
         }
         ppc_hash64_stop_access(token);
     }
-    hpte += index * HASH_PTE_SIZE_64;
 
-    ppc_hash64_store_hpte1(env, hpte, ptel);
-    /* eieio();  FIXME: need some sort of barrier for smp? */
-    ppc_hash64_store_hpte0(env, hpte, pteh | HPTE64_V_HPTE_DIRTY);
+    ppc_hash64_store_hpte(env, pte_index + index,
+                          pteh | HPTE64_V_HPTE_DIRTY, ptel);
 
     args[0] = pte_index + index;
     return H_SUCCESS;
@@ -152,7 +148,6 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
                                 target_ulong flags,
                                 target_ulong *vp, target_ulong *rp)
 {
-    hwaddr hpte;
     uint64_t token;
     target_ulong v, r, rb;
 
@@ -172,8 +167,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex,
     }
     *vp = v;
     *rp = r;
-    hpte = ptex * HASH_PTE_SIZE_64;
-    ppc_hash64_store_hpte0(env, hpte, HPTE64_V_HPTE_DIRTY);
+    ppc_hash64_store_hpte(env, ptex, HPTE64_V_HPTE_DIRTY, 0);
     rb = compute_tlbie_rb(v, r, ptex);
     ppc_tlb_invalidate_one(env, rb);
     return REMOVE_SUCCESS;
@@ -280,7 +274,6 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     target_ulong flags = args[0];
     target_ulong pte_index = args[1];
     target_ulong avpn = args[2];
-    hwaddr hpte;
     uint64_t token;
     target_ulong v, r, rb;
 
@@ -304,12 +297,11 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     r |= (flags << 48) & HPTE64_R_KEY_HI;
     r |= flags & (HPTE64_R_PP | HPTE64_R_N | HPTE64_R_KEY_LO);
     rb = compute_tlbie_rb(v, r, pte_index);
-    hpte = pte_index * HASH_PTE_SIZE_64;
-    ppc_hash64_store_hpte0(env, hpte, (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY);
+    ppc_hash64_store_hpte(env, pte_index,
+                          (v & ~HPTE64_V_VALID) | HPTE64_V_HPTE_DIRTY, 0);
     ppc_tlb_invalidate_one(env, rb);
-    ppc_hash64_store_hpte1(env, hpte, r);
     /* Don't need a memory barrier, due to qemu's global lock */
-    ppc_hash64_store_hpte0(env, hpte, v | HPTE64_V_HPTE_DIRTY);
+    ppc_hash64_store_hpte(env, pte_index, v | HPTE64_V_HPTE_DIRTY, r);
     return H_SUCCESS;
 }
 
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 68a6f69..8dd5d22 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -566,7 +566,8 @@ int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong eaddr,
     }
 
     if (new_pte1 != pte.pte1) {
-        ppc_hash64_store_hpte1(env, pte_offset, new_pte1);
+        ppc_hash64_store_hpte(env, pte_offset / HASH_PTE_SIZE_64,
+                              pte.pte0, new_pte1);
     }
 
     /* 7. Determine the real address from the PTE */
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index e7cb96f..49d866b 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -106,26 +106,18 @@ static inline target_ulong ppc_hash64_load_hpte1(CPUPPCState *env,
     }
 }
 
-static inline void ppc_hash64_store_hpte0(CPUPPCState *env,
-                                          hwaddr pte_offset, target_ulong pte0)
+static inline void ppc_hash64_store_hpte(CPUPPCState *env,
+                                         target_ulong pte_index,
+                                         target_ulong pte0, target_ulong pte1)
 {
     CPUState *cs = ENV_GET_CPU(env);
+    pte_index *= HASH_PTE_SIZE_64;
     if (env->external_htab) {
-        stq_p(env->external_htab + pte_offset, pte0);
+        stq_p(env->external_htab + pte_index, pte0);
+        stq_p(env->external_htab + pte_index + HASH_PTE_SIZE_64/2, pte1);
     } else {
-        stq_phys(cs->as, env->htab_base + pte_offset, pte0);
-    }
-}
-
-static inline void ppc_hash64_store_hpte1(CPUPPCState *env,
-                                          hwaddr pte_offset, target_ulong pte1)
-{
-    CPUState *cs = ENV_GET_CPU(env);
-    if (env->external_htab) {
-        stq_p(env->external_htab + pte_offset + HASH_PTE_SIZE_64/2, pte1);
-    } else {
-        stq_phys(cs->as,
-                 env->htab_base + pte_offset + HASH_PTE_SIZE_64/2, pte1);
+        stq_phys(cs->as, env->htab_base + pte_index, pte0);
+        stq_phys(cs->as, env->htab_base + pte_index + HASH_PTE_SIZE_64/2, pte1);
     }
 }
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 127/130] target-ppc: Update ppc_hash64_store_hpte to support updating in-kernel htab
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (125 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 126/130] target-ppc: Change the hpte store API Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 128/130] target-ppc: Introduce hypervisor call H_GET_TCE Alexander Graf
                   ` (3 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, qemu-ppc, Aneesh Kumar K.V, aliguori,
	aurelien, Greg Kurz

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

This support updating htab managed by the hypervisor. Currently we don't have
any user for this feature. This actually bring the store_hpte interface
in-line with the load_hpte one. We may want to use this when we want to
emulate henter hcall in qemu for HV kvm.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
[ folded fix for the "warn_unused_result" build break in
  kvmppc_hash64_write_pte(), Greg Kurz <gkurz@linux.vnet.ibm.com> ]
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-ppc/kvm.c        | 36 ++++++++++++++++++++++++++++++++++++
 target-ppc/kvm_ppc.h    | 10 ++++++++++
 target-ppc/mmu-hash64.c | 20 ++++++++++++++++++++
 target-ppc/mmu-hash64.h | 17 ++---------------
 4 files changed, 68 insertions(+), 15 deletions(-)

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index e009919..b5fff70 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1992,3 +1992,39 @@ void kvmppc_hash64_free_pteg(uint64_t token)
     g_free(htab_buf);
     return;
 }
+
+void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index,
+                             target_ulong pte0, target_ulong pte1)
+{
+    int htab_fd;
+    struct kvm_get_htab_fd ghf;
+    struct kvm_get_htab_buf hpte_buf;
+
+    ghf.flags = 0;
+    ghf.start_index = 0;     /* Ignored */
+    htab_fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf);
+    if (htab_fd < 0) {
+        goto error_out;
+    }
+
+    hpte_buf.header.n_valid = 1;
+    hpte_buf.header.n_invalid = 0;
+    hpte_buf.header.index = pte_index;
+    hpte_buf.hpte[0] = pte0;
+    hpte_buf.hpte[1] = pte1;
+    /*
+     * Write the hpte entry.
+     * CAUTION: write() has the warn_unused_result attribute. Hence we
+     * need to check the return value, even though we do nothing.
+     */
+    if (write(htab_fd, &hpte_buf, sizeof(hpte_buf)) < 0) {
+        goto out_close;
+    }
+
+out_close:
+    close(htab_fd);
+    return;
+
+error_out:
+    return;
+}
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 800e1ad..a65d345 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -47,6 +47,9 @@ int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
 uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index);
 void kvmppc_hash64_free_pteg(uint64_t token);
 
+void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index,
+                             target_ulong pte0, target_ulong pte1);
+
 #else
 
 static inline uint32_t kvmppc_get_tbfreq(void)
@@ -207,6 +210,13 @@ static inline void kvmppc_hash64_free_pteg(uint64_t token)
     abort();
 }
 
+static inline void kvmppc_hash64_write_pte(CPUPPCState *env,
+                                           target_ulong pte_index,
+                                           target_ulong pte0, target_ulong pte1)
+{
+    abort();
+}
+
 #endif
 
 #ifndef CONFIG_KVM
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 8dd5d22..f2af4fb 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -603,3 +603,23 @@ hwaddr ppc_hash64_get_phys_page_debug(CPUPPCState *env, target_ulong addr)
 
     return ppc_hash64_pte_raddr(slb, pte, addr) & TARGET_PAGE_MASK;
 }
+
+void ppc_hash64_store_hpte(CPUPPCState *env,
+                           target_ulong pte_index,
+                           target_ulong pte0, target_ulong pte1)
+{
+    CPUState *cs = ENV_GET_CPU(env);
+
+    if (kvmppc_kern_htab) {
+        return kvmppc_hash64_write_pte(env, pte_index, pte0, pte1);
+    }
+
+    pte_index *= HASH_PTE_SIZE_64;
+    if (env->external_htab) {
+        stq_p(env->external_htab + pte_index, pte0);
+        stq_p(env->external_htab + pte_index + HASH_PTE_SIZE_64/2, pte1);
+    } else {
+        stq_phys(cs->as, env->htab_base + pte_index, pte0);
+        stq_phys(cs->as, env->htab_base + pte_index + HASH_PTE_SIZE_64/2, pte1);
+    }
+}
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index 49d866b..1746b3e 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -9,6 +9,8 @@ int ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs);
 hwaddr ppc_hash64_get_phys_page_debug(CPUPPCState *env, target_ulong addr);
 int ppc_hash64_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,
                                 int mmu_idx);
+void ppc_hash64_store_hpte(CPUPPCState *env, target_ulong index,
+                           target_ulong pte0, target_ulong pte1);
 #endif
 
 /*
@@ -106,21 +108,6 @@ static inline target_ulong ppc_hash64_load_hpte1(CPUPPCState *env,
     }
 }
 
-static inline void ppc_hash64_store_hpte(CPUPPCState *env,
-                                         target_ulong pte_index,
-                                         target_ulong pte0, target_ulong pte1)
-{
-    CPUState *cs = ENV_GET_CPU(env);
-    pte_index *= HASH_PTE_SIZE_64;
-    if (env->external_htab) {
-        stq_p(env->external_htab + pte_index, pte0);
-        stq_p(env->external_htab + pte_index + HASH_PTE_SIZE_64/2, pte1);
-    } else {
-        stq_phys(cs->as, env->htab_base + pte_index, pte0);
-        stq_phys(cs->as, env->htab_base + pte_index + HASH_PTE_SIZE_64/2, pte1);
-    }
-}
-
 typedef struct {
     uint64_t pte0, pte1;
 } ppc_hash_pte64_t;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 128/130] target-ppc: Introduce hypervisor call H_GET_TCE
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (126 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 127/130] target-ppc: Update ppc_hash64_store_hpte to support updating in-kernel htab Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 129/130] target-ppc: add PowerPCCPU::cpu_dt_id Alexander Graf
                   ` (2 subsequent siblings)
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, blauwirbel, qemu-ppc, aliguori, Laurent Dufour, aurelien

From: Laurent Dufour <ldufour@linux.vnet.ibm.com>

This patch introduces the hypervisor call H_GET_TCE which is basically the
reverse of H_PUT_TCE, as defined in the Power Architecture Platform
Requirements (PAPR).

The hcall H_GET_TCE is required by the kdump kernel which is calling it to
retrieve the TCE set up by the panicing kernel.

Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/spapr_iommu.c | 37 +++++++++++++++++++++++++++++++++++++
 trace-events         |  1 +
 2 files changed, 38 insertions(+)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index ef45f4f..d9fe946 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -243,6 +243,42 @@ static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return ret;
 }
 
+static target_ulong get_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
+                                target_ulong *tce)
+{
+    if (ioba >= tcet->window_size) {
+        hcall_dprintf("spapr_iommu_get_tce on out-of-bounds IOBA 0x"
+                      TARGET_FMT_lx "\n", ioba);
+        return H_PARAMETER;
+    }
+
+    *tce = tcet->table[ioba >> SPAPR_TCE_PAGE_SHIFT];
+
+    return H_SUCCESS;
+}
+
+static target_ulong h_get_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+                              target_ulong opcode, target_ulong *args)
+{
+    target_ulong liobn = args[0];
+    target_ulong ioba = args[1];
+    target_ulong tce = 0;
+    target_ulong ret = H_PARAMETER;
+    sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
+
+    ioba &= ~(SPAPR_TCE_PAGE_SIZE - 1);
+
+    if (tcet) {
+        ret = get_tce_emu(tcet, ioba, &tce);
+        if (!ret) {
+            args[0] = tce;
+        }
+    }
+    trace_spapr_iommu_get(liobn, ioba, ret, tce);
+
+    return ret;
+}
+
 int spapr_dma_dt(void *fdt, int node_off, const char *propname,
                  uint32_t liobn, uint64_t window, uint32_t size)
 {
@@ -295,6 +331,7 @@ static void spapr_tce_table_class_init(ObjectClass *klass, void *data)
 
     /* hcall-tce */
     spapr_register_hypercall(H_PUT_TCE, h_put_tce);
+    spapr_register_hypercall(H_GET_TCE, h_get_tce);
 }
 
 static TypeInfo spapr_tce_table_info = {
diff --git a/trace-events b/trace-events
index bd9a1cf..777f703 100644
--- a/trace-events
+++ b/trace-events
@@ -1136,6 +1136,7 @@ xics_ics_eoi(int nr) "ics_eoi: irq %#x"
 
 # hw/ppc/spapr_iommu.c
 spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64
+spapr_iommu_get(uint64_t liobn, uint64_t ioba, uint64_t ret, uint64_t tce) "liobn=%"PRIx64" ioba=0x%"PRIx64" ret=%"PRId64" tce=0x%"PRIx64
 spapr_iommu_xlate(uint64_t liobn, uint64_t ioba, uint64_t tce, unsigned perm, unsigned pgsize) "liobn=%"PRIx64" 0x%"PRIx64" -> 0x%"PRIx64" perm=%u mask=%x"
 spapr_iommu_new_table(uint64_t liobn, void *tcet, void *table, int fd) "liobn=%"PRIx64" tcet=%p table=%p fd=%d"
 
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 129/130] target-ppc: add PowerPCCPU::cpu_dt_id
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (127 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 128/130] target-ppc: Introduce hypervisor call H_GET_TCE Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-06 23:34 ` [Qemu-devel] [PULL 130/130] target-ppc: spapr: e500: fix to use cpu_dt_id Alexander Graf
  2014-03-07 17:16 ` [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Peter Maydell
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

Normally CPUState::cpu_index is used to pick the right CPU for various
operations. However default consecutive numbering does not always work
for POWERPC.

These indexes are reflected in /proc/device-tree/cpus/PowerPC,POWER7@XX
and used to call KVM VCPU's ioctls. In order to achieve this,
kvmppc_fixup_cpu() was introduced. Roughly speaking, it multiplies
cpu_index by the number of threads per core.

This approach has disadvantages such as:
1. NUMA configuration stays broken after the fixup;
2. CPU-targeted commands from the QEMU Monitor do not work properly as
CPU indexes have been fixed and there is no clear way for the user to
know what the new CPU indexes are.

This introduces a @cpu_dt_id field in the CPUPPCState struct which
is initialized from @cpu_index by default and can be fixed later
to meet the device tree requirements.

This adds an API to handle @cpu_dt_id.

This removes kvmppc_fixup_cpu() as it is not more needed, @cpu_dt_id
is calculated in ppc_cpu_realize().

This will be used later in machine code.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Acked-by: Mike Day <ncmike@ncultra.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/ppc/ppc.c                | 22 ++++++++++++++++++++++
 target-ppc/cpu-qom.h        |  2 ++
 target-ppc/cpu.h            | 18 ++++++++++++++++++
 target-ppc/kvm.c            | 13 -------------
 target-ppc/kvm_ppc.h        |  6 ------
 target-ppc/translate_init.c | 10 ++++------
 6 files changed, 46 insertions(+), 25 deletions(-)

diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 114be64..0e82719 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -26,6 +26,7 @@
 #include "hw/ppc/ppc_e500.h"
 #include "qemu/timer.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/cpus.h"
 #include "hw/timer/m48t59.h"
 #include "qemu/log.h"
 #include "hw/loader.h"
@@ -1362,3 +1363,24 @@ int PPC_NVRAM_set_params (nvram_t *nvram, uint16_t NVRAM_size,
 
     return 0;
 }
+
+/* CPU device-tree ID helpers */
+int ppc_get_vcpu_dt_id(PowerPCCPU *cpu)
+{
+    return cpu->cpu_dt_id;
+}
+
+PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
+{
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+        if (cpu->cpu_dt_id == cpu_dt_id) {
+            return cpu;
+        }
+    }
+
+    return NULL;
+}
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 72b2232..b17c024 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -79,6 +79,7 @@ typedef struct PowerPCCPUClass {
 /**
  * PowerPCCPU:
  * @env: #CPUPPCState
+ * @cpu_dt_id: CPU index used in the device tree. KVM uses this index too
  *
  * A PowerPC CPU.
  */
@@ -88,6 +89,7 @@ typedef struct PowerPCCPU {
     /*< public >*/
 
     CPUPPCState env;
+    int cpu_dt_id;
 } PowerPCCPU;
 
 static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 44ade0c..afab267 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -2183,4 +2183,22 @@ static inline bool cpu_has_work(CPUState *cpu)
 
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
 
+/**
+ * ppc_get_vcpu_dt_id:
+ * @cs: a PowerPCCPU struct.
+ *
+ * Returns a device-tree ID for a CPU.
+ */
+int ppc_get_vcpu_dt_id(PowerPCCPU *cpu);
+
+/**
+ * ppc_get_vcpu_by_dt_id:
+ * @cpu_dt_id: a device tree id
+ *
+ * Searches for a CPU by @cpu_dt_id.
+ *
+ * Returns: a PowerPCCPU struct
+ */
+PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id);
+
 #endif /* !defined (__CPU_PPC_H__) */
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index b5fff70..a483322 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -1770,19 +1770,6 @@ static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
     }
 }
 
-int kvmppc_fixup_cpu(PowerPCCPU *cpu)
-{
-    CPUState *cs = CPU(cpu);
-    int smt;
-
-    /* Adjust cpu index for SMT */
-    smt = kvmppc_smt_threads();
-    cs->cpu_index = (cs->cpu_index / smp_threads) * smt
-        + (cs->cpu_index % smp_threads);
-
-    return 0;
-}
-
 bool kvmppc_has_cap_epr(void)
 {
     return cap_epr;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index a65d345..ff077ec 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -36,7 +36,6 @@ int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
 int kvmppc_reset_htab(int shift_hint);
 uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift);
 #endif /* !CONFIG_USER_ONLY */
-int kvmppc_fixup_cpu(PowerPCCPU *cpu);
 bool kvmppc_has_cap_epr(void);
 int kvmppc_define_rtas_kernel_token(uint32_t token, const char *function);
 bool kvmppc_has_cap_htab_fd(void);
@@ -161,11 +160,6 @@ static inline int kvmppc_update_sdr1(CPUPPCState *env)
 
 #endif /* !CONFIG_USER_ONLY */
 
-static inline int kvmppc_fixup_cpu(PowerPCCPU *cpu)
-{
-    return -1;
-}
-
 static inline bool kvmppc_has_cap_epr(void)
 {
     return false;
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 9dd8c1c..ef74d94 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7847,14 +7847,12 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
                    max_smt, kvm_enabled() ? "KVM" : "TCG");
         return;
     }
+
+    cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
+        + (cs->cpu_index % smp_threads);
 #endif
 
-    if (kvm_enabled()) {
-        if (kvmppc_fixup_cpu(cpu) != 0) {
-            error_setg(errp, "Unable to virtualize selected CPU with KVM");
-            return;
-        }
-    } else if (tcg_enabled()) {
+    if (tcg_enabled()) {
         if (ppc_fixup_cpu(cpu) != 0) {
             error_setg(errp, "Unable to emulate selected CPU with TCG");
             return;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [Qemu-devel] [PULL 130/130] target-ppc: spapr: e500: fix to use cpu_dt_id
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (128 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 129/130] target-ppc: add PowerPCCPU::cpu_dt_id Alexander Graf
@ 2014-03-06 23:34 ` Alexander Graf
  2014-03-07 17:16 ` [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Peter Maydell
  130 siblings, 0 replies; 142+ messages in thread
From: Alexander Graf @ 2014-03-06 23:34 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, Alexey Kardashevskiy, blauwirbel, qemu-ppc,
	aliguori, aurelien

From: Alexey Kardashevskiy <aik@ozlabs.ru>

This makes use of @cpu_dt_id and related API in:
1. emulated XICS hypercall handlers as they receive fixed CPU indexes;
2. XICS-KVM to enable in-kernel XICS on right CPU;
3. device-tree renderer.

This removes @cpu_index fixup as @cpu_dt_id is used instead so QEMU monitor
can accept command-line CPU indexes again.

This changes kvm_arch_vcpu_id() to use ppc_get_vcpu_dt_id() as at the moment
KVM CPU id and device tree ID are calculated using the same algorithm.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Acked-by: Mike Day <ncmike@ncultra.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 hw/intc/openpic_kvm.c       |  2 +-
 hw/intc/xics.c              | 15 +++++++++++++--
 hw/intc/xics_kvm.c          | 10 +++++-----
 hw/ppc/e500.c               |  7 +++++--
 hw/ppc/spapr.c              |  9 +++++----
 hw/ppc/spapr_hcall.c        |  6 +++---
 hw/ppc/spapr_rtas.c         | 14 +++++++-------
 target-ppc/kvm.c            |  2 +-
 target-ppc/translate_init.c |  1 +
 9 files changed, 41 insertions(+), 25 deletions(-)

diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c
index c7f7b84..87fdb12 100644
--- a/hw/intc/openpic_kvm.c
+++ b/hw/intc/openpic_kvm.c
@@ -228,7 +228,7 @@ int kvm_openpic_connect_vcpu(DeviceState *d, CPUState *cs)
 
     encap.cap = KVM_CAP_IRQ_MPIC;
     encap.args[0] = opp->fd;
-    encap.args[1] = cs->cpu_index;
+    encap.args[1] = kvm_arch_vcpu_id(cs);
 
     return kvm_vcpu_ioctl(cs, KVM_ENABLE_CAP, &encap);
 }
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index b437563..64aabe7 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -33,6 +33,17 @@
 #include "qemu/error-report.h"
 #include "qapi/visitor.h"
 
+static int get_cpu_index_by_dt_id(int cpu_dt_id)
+{
+    PowerPCCPU *cpu = ppc_get_vcpu_by_dt_id(cpu_dt_id);
+
+    if (cpu) {
+        return cpu->parent_obj.cpu_index;
+    }
+
+    return -1;
+}
+
 void xics_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
 {
     CPUState *cs = CPU(cpu);
@@ -659,7 +670,7 @@ static target_ulong h_cppr(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 static target_ulong h_ipi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                           target_ulong opcode, target_ulong *args)
 {
-    target_ulong server = args[0];
+    target_ulong server = get_cpu_index_by_dt_id(args[0]);
     target_ulong mfrr = args[1];
 
     if (server >= spapr->icp->nr_servers) {
@@ -728,7 +739,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     }
 
     nr = rtas_ld(args, 0);
-    server = rtas_ld(args, 1);
+    server = get_cpu_index_by_dt_id(rtas_ld(args, 1));
     priority = rtas_ld(args, 2);
 
     if (!ics_valid_irq(ics, nr) || (server >= ics->icp->nr_servers)
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index c203646..a5bbc24 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -65,7 +65,7 @@ static void icp_get_kvm_state(ICPState *ss)
     ret = kvm_vcpu_ioctl(ss->cs, KVM_GET_ONE_REG, &reg);
     if (ret != 0) {
         error_report("Unable to retrieve KVM interrupt controller state"
-                " for CPU %d: %s", ss->cs->cpu_index, strerror(errno));
+                " for CPU %ld: %s", kvm_arch_vcpu_id(ss->cs), strerror(errno));
         exit(1);
     }
 
@@ -97,7 +97,7 @@ static int icp_set_kvm_state(ICPState *ss, int version_id)
     ret = kvm_vcpu_ioctl(ss->cs, KVM_SET_ONE_REG, &reg);
     if (ret != 0) {
         error_report("Unable to restore KVM interrupt controller state (0x%"
-                PRIx64 ") for CPU %d: %s", state, ss->cs->cpu_index,
+                PRIx64 ") for CPU %ld: %s", state, kvm_arch_vcpu_id(ss->cs),
                 strerror(errno));
         return ret;
     }
@@ -325,15 +325,15 @@ static void xics_kvm_cpu_setup(XICSState *icp, PowerPCCPU *cpu)
         struct kvm_enable_cap xics_enable_cap = {
             .cap = KVM_CAP_IRQ_XICS,
             .flags = 0,
-            .args = {icpkvm->kernel_xics_fd, cs->cpu_index, 0, 0},
+            .args = {icpkvm->kernel_xics_fd, kvm_arch_vcpu_id(cs), 0, 0},
         };
 
         ss->cs = cs;
 
         ret = kvm_vcpu_ioctl(ss->cs, KVM_ENABLE_CAP, &xics_enable_cap);
         if (ret < 0) {
-            error_report("Unable to connect CPU%d to kernel XICS: %s",
-                    cs->cpu_index, strerror(errno));
+            error_report("Unable to connect CPU%ld to kernel XICS: %s",
+                    kvm_arch_vcpu_id(cs), strerror(errno));
             exit(1);
         }
     }
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index b37ce9d..8a08752 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -238,6 +238,7 @@ static int ppce500_load_device_tree(QEMUMachineInitArgs *args,
        the first node as boot node and be happy */
     for (i = smp_cpus - 1; i >= 0; i--) {
         CPUState *cpu;
+        PowerPCCPU *pcpu;
         char cpu_name[128];
         uint64_t cpu_release_addr = MPC8544_SPIN_BASE + (i * 0x20);
 
@@ -246,14 +247,16 @@ static int ppce500_load_device_tree(QEMUMachineInitArgs *args,
             continue;
         }
         env = cpu->env_ptr;
+        pcpu = POWERPC_CPU(cpu);
 
         snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x",
-                 cpu->cpu_index);
+                 ppc_get_vcpu_dt_id(pcpu));
         qemu_fdt_add_subnode(fdt, cpu_name);
         qemu_fdt_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
         qemu_fdt_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
         qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
-        qemu_fdt_setprop_cell(fdt, cpu_name, "reg", cpu->cpu_index);
+        qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
+                              ppc_get_vcpu_dt_id(pcpu));
         qemu_fdt_setprop_cell(fdt, cpu_name, "d-cache-line-size",
                               env->dcache_line_size);
         qemu_fdt_setprop_cell(fdt, cpu_name, "i-cache-line-size",
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 94cf520..bf46c38 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -207,19 +207,20 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
 
     CPU_FOREACH(cpu) {
         DeviceClass *dc = DEVICE_GET_CLASS(cpu);
+        int index = ppc_get_vcpu_dt_id(POWERPC_CPU(cpu));
         uint32_t associativity[] = {cpu_to_be32(0x5),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(cpu->numa_node),
-                                    cpu_to_be32(cpu->cpu_index)};
+                                    cpu_to_be32(index)};
 
-        if ((cpu->cpu_index % smt) != 0) {
+        if ((index % smt) != 0) {
             continue;
         }
 
         snprintf(cpu_model, 32, "/cpus/%s@%x", dc->fw_name,
-                 cpu->cpu_index);
+                 index);
 
         offset = fdt_path_offset(fdt, cpu_model);
         if (offset < 0) {
@@ -368,7 +369,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
         CPUPPCState *env = &cpu->env;
         DeviceClass *dc = DEVICE_GET_CLASS(cs);
         PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
-        int index = cs->cpu_index;
+        int index = ppc_get_vcpu_dt_id(cpu);
         uint32_t servers_prop[smp_threads];
         uint32_t gservers_prop[smp_threads * 2];
         char *nodename;
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index b0f2529..d918780 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -482,13 +482,13 @@ static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     target_ulong vpa = args[2];
     target_ulong ret = H_PARAMETER;
     CPUPPCState *tenv;
-    CPUState *tcpu;
+    PowerPCCPU *tcpu;
 
-    tcpu = qemu_get_cpu(procno);
+    tcpu = ppc_get_vcpu_by_dt_id(procno);
     if (!tcpu) {
         return H_PARAMETER;
     }
-    tenv = tcpu->env_ptr;
+    tenv = &tcpu->env;
 
     switch (flags) {
     case FLAGS_REGISTER_VPA:
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 1cb276d..73860d0 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -131,7 +131,7 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
                                          uint32_t nret, target_ulong rets)
 {
     target_ulong id;
-    CPUState *cpu;
+    PowerPCCPU *cpu;
 
     if (nargs != 1 || nret != 2) {
         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -139,9 +139,9 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
     }
 
     id = rtas_ld(args, 0);
-    cpu = qemu_get_cpu(id);
+    cpu = ppc_get_vcpu_by_dt_id(id);
     if (cpu != NULL) {
-        if (cpu->halted) {
+        if (CPU(cpu)->halted) {
             rtas_st(rets, 1, 0);
         } else {
             rtas_st(rets, 1, 2);
@@ -161,7 +161,7 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr,
                            uint32_t nret, target_ulong rets)
 {
     target_ulong id, start, r3;
-    CPUState *cs;
+    PowerPCCPU *cpu;
 
     if (nargs != 3 || nret != 1) {
         rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
@@ -172,9 +172,9 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr,
     start = rtas_ld(args, 1);
     r3 = rtas_ld(args, 2);
 
-    cs = qemu_get_cpu(id);
-    if (cs != NULL) {
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
+    cpu = ppc_get_vcpu_by_dt_id(id);
+    if (cpu != NULL) {
+        CPUState *cs = CPU(cpu);
         CPUPPCState *env = &cpu->env;
 
         if (!cs->halted) {
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index a483322..32e7a8c 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -402,7 +402,7 @@ static inline void kvm_fixup_page_sizes(PowerPCCPU *cpu)
 
 unsigned long kvm_arch_vcpu_id(CPUState *cpu)
 {
-    return cpu->cpu_index;
+    return ppc_get_vcpu_dt_id(POWERPC_CPU(cpu));
 }
 
 int kvm_arch_init_vcpu(CPUState *cs)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index ef74d94..3eafbb0 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -8457,6 +8457,7 @@ static void ppc_cpu_initfn(Object *obj)
 
     cs->env_ptr = env;
     cpu_exec_init(env);
+    cpu->cpu_dt_id = cs->cpu_index;
 
     env->msr_mask = pcc->msr_mask;
     env->mmu_model = pcc->mmu_model;
-- 
1.8.1.4

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 007/130] KVM: Split QEMUMachine typedef into separate header
  2014-03-06 23:32 ` [Qemu-devel] [PULL 007/130] KVM: Split QEMUMachine typedef into separate header Alexander Graf
@ 2014-03-07  7:31   ` Paolo Bonzini
  0 siblings, 0 replies; 142+ messages in thread
From: Paolo Bonzini @ 2014-03-07  7:31 UTC (permalink / raw)
  To: Alexander Graf, qemu-devel
  Cc: blauwirbel, Peter Maydell, qemu-ppc, aliguori, aurelien

Il 07/03/2014 00:32, Alexander Graf ha scritto:
> Older gcc versions (such as the one in SLES11) get confused when you declare
> a typedef on the same struct twice.
>
> To work around that limitation, let's extract the QEMUMachine typedef into a
> separate header file that is guarded by preprocessor duplicate include checks.
>
> This fixes the following type of compile errors for me:
>
>   In file included from vl.c:125:
>   include/hw/xen/xen.h:39: error: redefinition of typedef "QEMUMachine"
>   include/sysemu/kvm.h:155: error: previous declaration of "QEMUMachine" was here
>
> Signed-off-by: Alexander Graf <agraf@suse.de>

When was this posted to the list?

This is exactly the purpose of include/qemu/typedefs.h.

Paolo

> ---
>  include/hw/boards.h          |  3 +--
>  include/hw/xen/xen.h         |  1 +
>  include/sysemu/kvm.h         |  1 +
>  include/sysemu/qemumachine.h | 16 ++++++++++++++++
>  include/sysemu/qtest.h       |  1 +
>  kvm-stub.c                   |  1 +
>  6 files changed, 21 insertions(+), 2 deletions(-)
>  create mode 100644 include/sysemu/qemumachine.h
>
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index 2151460..ed6d9f8 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -4,10 +4,9 @@
>  #define HW_BOARDS_H
>
>  #include "sysemu/blockdev.h"
> +#include "sysemu/qemumachine.h"
>  #include "hw/qdev.h"
>
> -typedef struct QEMUMachine QEMUMachine;
> -
>  typedef struct QEMUMachineInitArgs {
>      const QEMUMachine *machine;
>      ram_addr_t ram_size;
> diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
> index e1f88bf..81e5bb1 100644
> --- a/include/hw/xen/xen.h
> +++ b/include/hw/xen/xen.h
> @@ -10,6 +10,7 @@
>
>  #include "hw/irq.h"
>  #include "qemu-common.h"
> +#include "sysemu/qemumachine.h"
>
>  /* xen-machine.c */
>  enum xen_mode {
> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> index a02d67c..c982570 100644
> --- a/include/sysemu/kvm.h
> +++ b/include/sysemu/kvm.h
> @@ -18,6 +18,7 @@
>  #include "config-host.h"
>  #include "qemu/queue.h"
>  #include "qom/cpu.h"
> +#include "sysemu/qemumachine.h"
>
>  #ifdef CONFIG_KVM
>  #include <linux/kvm.h>
> diff --git a/include/sysemu/qemumachine.h b/include/sysemu/qemumachine.h
> new file mode 100644
> index 0000000..4cefd56
> --- /dev/null
> +++ b/include/sysemu/qemumachine.h
> @@ -0,0 +1,16 @@
> +/*
> + * QEMU Machine typedef
> + *
> + * Copyright Alexander Graf <agraf@suse.de>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + *
> + */
> +
> +#ifndef QEMUMACHINE_H
> +#define QEMUMACHINE_H
> +
> +typedef struct QEMUMachine QEMUMachine;
> +
> +#endif /* !QEMUMACHINE_H */
> diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h
> index 28f4875..d6434cd 100644
> --- a/include/sysemu/qtest.h
> +++ b/include/sysemu/qtest.h
> @@ -16,6 +16,7 @@
>
>  #include "qemu-common.h"
>  #include "qapi/error.h"
> +#include "sysemu/qemumachine.h"
>
>  extern bool qtest_allowed;
>
> diff --git a/kvm-stub.c b/kvm-stub.c
> index e979f76..b1c4429 100644
> --- a/kvm-stub.c
> +++ b/kvm-stub.c
> @@ -14,6 +14,7 @@
>  #include "hw/hw.h"
>  #include "cpu.h"
>  #include "sysemu/kvm.h"
> +#include "sysemu/qemumachine.h"
>
>  #ifndef CONFIG_USER_ONLY
>  #include "hw/pci/msi.h"
>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05
  2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
                   ` (129 preceding siblings ...)
  2014-03-06 23:34 ` [Qemu-devel] [PULL 130/130] target-ppc: spapr: e500: fix to use cpu_dt_id Alexander Graf
@ 2014-03-07 17:16 ` Peter Maydell
  130 siblings, 0 replies; 142+ messages in thread
From: Peter Maydell @ 2014-03-07 17:16 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Blue Swirl, Aurelien Jarno, qemu-ppc, QEMU Developers, Anthony Liguori

On 6 March 2014 23:32, Alexander Graf <agraf@suse.de> wrote:
> Hi Blue / Aurelien / Anthony / Peter,
>
> This is my current patch queue for ppc.  Please pull.
>
> This pull request includes:
>
>   - VSX emulation support
>   - book3s pr/hv selection
>   - some bug fixes
>   - qdev stable numbering
>   - eTSEC emulation
>

Applied, thanks (Paolo, Andreas and I agreed on
IRC that we'd fix up the minor issue Paolo spotted
afterwards rather than rerolling this enormous queue).

In future, flushing your queue before it builds up
to this size would make things easier :-)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC) Alexander Graf
@ 2014-03-09  8:02   ` Paolo Bonzini
  2014-03-12 11:41     ` Fabien Chouteau
  2014-03-14 11:23   ` Paolo Bonzini
  1 sibling, 1 reply; 142+ messages in thread
From: Paolo Bonzini @ 2014-03-09  8:02 UTC (permalink / raw)
  To: Alexander Graf, qemu-devel
  Cc: Peter Maydell, Fabien Chouteau, blauwirbel, qemu-ppc, aliguori, aurelien

Il 07/03/2014 00:33, Alexander Graf ha scritto:
> From: Fabien Chouteau <chouteau@adacore.com>
>
> This implementation doesn't include ring priority, TCP/IP Off-Load, QoS.
>
> Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
> Signed-off-by: Alexander Graf <agraf@suse.de>
> ---

Is this code dead?  Who uses it?  A quick "git grep etsec_create" gave 
no results.

Paolo

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC)
  2014-03-09  8:02   ` Paolo Bonzini
@ 2014-03-12 11:41     ` Fabien Chouteau
  2014-03-12 18:22       ` Paolo Bonzini
  0 siblings, 1 reply; 142+ messages in thread
From: Fabien Chouteau @ 2014-03-12 11:41 UTC (permalink / raw)
  To: Paolo Bonzini, Alexander Graf, qemu-devel
  Cc: blauwirbel, Peter Maydell, qemu-ppc, aurelien, aliguori

On 03/09/2014 09:02 AM, Paolo Bonzini wrote:
> Il 07/03/2014 00:33, Alexander Graf ha scritto:
>> From: Fabien Chouteau <chouteau@adacore.com>
>>
>> This implementation doesn't include ring priority, TCP/IP Off-Load, QoS.
>>
>> Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
>> Signed-off-by: Alexander Graf <agraf@suse.de>
>> ---
> 
> Is this code dead?  Who uses it?  A quick "git grep etsec_create" gave no results.
>


I guess it could be integrated in hw/ppc/mpc8544ds.c

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC)
  2014-03-12 11:41     ` Fabien Chouteau
@ 2014-03-12 18:22       ` Paolo Bonzini
  2014-03-12 18:39         ` Andreas Färber
  0 siblings, 1 reply; 142+ messages in thread
From: Paolo Bonzini @ 2014-03-12 18:22 UTC (permalink / raw)
  To: Fabien Chouteau, Alexander Graf, qemu-devel
  Cc: blauwirbel, Peter Maydell, qemu-ppc, aurelien, aliguori

Il 12/03/2014 12:41, Fabien Chouteau ha scritto:
> On 03/09/2014 09:02 AM, Paolo Bonzini wrote:
>> Il 07/03/2014 00:33, Alexander Graf ha scritto:
>>> From: Fabien Chouteau <chouteau@adacore.com>
>>>
>>> This implementation doesn't include ring priority, TCP/IP Off-Load, QoS.
>>>
>>> Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
>>> Signed-off-by: Alexander Graf <agraf@suse.de>
>>> ---
>>
>> Is this code dead?  Who uses it?  A quick "git grep etsec_create" gave no results.
>
> I guess it could be integrated in hw/ppc/mpc8544ds.c

So it is indeed unused right now in the tree?

Paolo

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC)
  2014-03-12 18:22       ` Paolo Bonzini
@ 2014-03-12 18:39         ` Andreas Färber
  0 siblings, 0 replies; 142+ messages in thread
From: Andreas Färber @ 2014-03-12 18:39 UTC (permalink / raw)
  To: Paolo Bonzini, Fabien Chouteau, Alexander Graf, qemu-devel
  Cc: blauwirbel, Peter Maydell, qemu-ppc, aliguori, aurelien

Am 12.03.2014 19:22, schrieb Paolo Bonzini:
> Il 12/03/2014 12:41, Fabien Chouteau ha scritto:
>> On 03/09/2014 09:02 AM, Paolo Bonzini wrote:
>>> Il 07/03/2014 00:33, Alexander Graf ha scritto:
>>>> From: Fabien Chouteau <chouteau@adacore.com>
>>>>
>>>> This implementation doesn't include ring priority, TCP/IP Off-Load,
>>>> QoS.
>>>>
>>>> Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
>>>> Signed-off-by: Alexander Graf <agraf@suse.de>
>>>> ---
>>>
>>> Is this code dead?  Who uses it?  A quick "git grep etsec_create"
>>> gave no results.
>>
>> I guess it could be integrated in hw/ppc/mpc8544ds.c
> 
> So it is indeed unused right now in the tree?

Looks like it, git grep eTSEC doesn't come up with any manual use.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC)
  2014-03-06 23:33 ` [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC) Alexander Graf
  2014-03-09  8:02   ` Paolo Bonzini
@ 2014-03-14 11:23   ` Paolo Bonzini
  2014-03-14 16:42     ` Fabien Chouteau
  1 sibling, 1 reply; 142+ messages in thread
From: Paolo Bonzini @ 2014-03-14 11:23 UTC (permalink / raw)
  To: Alexander Graf, qemu-devel, Fabien Chouteau; +Cc: Peter Maydell

Il 07/03/2014 00:33, Alexander Graf ha scritto:
> +                if (bd.flags | BD_INTERRUPT) {
> +                    /* Set RXFx */
> +                    etsec->regs[RSTAT].value |= 1 << (7 - ring_nbr);
> +
> +                    /* Set IEVENT */
> +                    ievent_set(etsec, IEVENT_RXF);
> +                }
> +
> +            } else {
> +                if (bd.flags | BD_INTERRUPT) {
> +                    /* Set IEVENT */
> +                    ievent_set(etsec, IEVENT_RXB);
> +                }
> +            }

Coverity flags this "bd.flags | BD_INTERRUPT" idiom... What did you 
mean?  Can you send a fix to qemu-trivial?

Paolo

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 125/130] target-ppc: Fix page table lookup with kvm enabled
  2014-03-06 23:34 ` [Qemu-devel] [PULL 125/130] target-ppc: Fix page table lookup with kvm enabled Alexander Graf
@ 2014-03-14 11:26   ` Paolo Bonzini
  2014-03-14 13:13     ` Aneesh Kumar K.V
  0 siblings, 1 reply; 142+ messages in thread
From: Paolo Bonzini @ 2014-03-14 11:26 UTC (permalink / raw)
  To: Alexander Graf, qemu-devel, Aneesh Kumar K.V
  Cc: Alexey Kardashevskiy, Peter Maydell, qemu-ppc, Greg Kurz

Il 07/03/2014 00:34, Alexander Graf ha scritto:
> @@ -105,30 +106,37 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>      if (!valid_pte_index(env, pte_index)) {
>          return H_PARAMETER;
>      }
> +
> +    index = 0;
> +    hpte = pte_index * HASH_PTE_SIZE_64;
>      if (likely((flags & H_EXACT) == 0)) {
>          pte_index &= ~7ULL;
> -        hpte = pte_index * HASH_PTE_SIZE_64;
> -        for (i = 0; ; ++i) {
> -            if (i == 8) {
> +        token = ppc_hash64_start_access(cpu, pte_index);
> +        do {
> +            if (index == 8) {
> +                ppc_hash64_stop_access(token);
>                  return H_PTEG_FULL;
>              }
> -            if ((ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) == 0) {
> +            if ((ppc_hash64_load_hpte0(env, token, index) & HPTE64_V_VALID) == 0) {
>                  break;
>              }
> -            hpte += HASH_PTE_SIZE_64;
> -        }
> +        } while (index++);
> +        ppc_hash64_stop_access(token);

I'm afraid you have a bug here, as spotted by Coverity.  The do...while 
loop only loops once.  I'm not sure what you meant, could you rewrite it 
with a "for (index = 0; index < 8; i++)" instead?

Paolo

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 125/130] target-ppc: Fix page table lookup with kvm enabled
  2014-03-14 11:26   ` Paolo Bonzini
@ 2014-03-14 13:13     ` Aneesh Kumar K.V
  2014-03-14 13:23       ` Paolo Bonzini
  0 siblings, 1 reply; 142+ messages in thread
From: Aneesh Kumar K.V @ 2014-03-14 13:13 UTC (permalink / raw)
  To: Paolo Bonzini, Alexander Graf, qemu-devel
  Cc: Alexey Kardashevskiy, Peter Maydell, qemu-ppc, Greg Kurz

Paolo Bonzini <pbonzini@redhat.com> writes:

> Il 07/03/2014 00:34, Alexander Graf ha scritto:
>> @@ -105,30 +106,37 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>>      if (!valid_pte_index(env, pte_index)) {
>>          return H_PARAMETER;
>>      }
>> +
>> +    index = 0;
>> +    hpte = pte_index * HASH_PTE_SIZE_64;
>>      if (likely((flags & H_EXACT) == 0)) {
>>          pte_index &= ~7ULL;
>> -        hpte = pte_index * HASH_PTE_SIZE_64;
>> -        for (i = 0; ; ++i) {
>> -            if (i == 8) {
>> +        token = ppc_hash64_start_access(cpu, pte_index);
>> +        do {
>> +            if (index == 8) {
>> +                ppc_hash64_stop_access(token);
>>                  return H_PTEG_FULL;
>>              }
>> -            if ((ppc_hash64_load_hpte0(env, hpte) & HPTE64_V_VALID) == 0) {
>> +            if ((ppc_hash64_load_hpte0(env, token, index) & HPTE64_V_VALID) == 0) {
>>                  break;
>>              }
>> -            hpte += HASH_PTE_SIZE_64;
>> -        }
>> +        } while (index++);
>> +        ppc_hash64_stop_access(token);
>
> I'm afraid you have a bug here, as spotted by Coverity.  The do...while 
> loop only loops once.  I'm not sure what you meant, could you rewrite it 
> with a "for (index = 0; index < 8; i++)" instead?

good find. how about

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index e999bbaea062..e079be050fc7 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -118,7 +118,8 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
             if ((ppc_hash64_load_hpte0(env, token, index) & HPTE64_V_VALID) == 0) {
                 break;
             }
-        } while (index++);
+            index++;
+        } while (1);
         ppc_hash64_stop_access(token);
     } else {
         token = ppc_hash64_start_access(cpu, pte_index);

         -aneesh

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 125/130] target-ppc: Fix page table lookup with kvm enabled
  2014-03-14 13:13     ` Aneesh Kumar K.V
@ 2014-03-14 13:23       ` Paolo Bonzini
  0 siblings, 0 replies; 142+ messages in thread
From: Paolo Bonzini @ 2014-03-14 13:23 UTC (permalink / raw)
  To: Aneesh Kumar K.V, Alexander Graf, qemu-devel
  Cc: Alexey Kardashevskiy, Peter Maydell, qemu-ppc, Greg Kurz

Il 14/03/2014 14:13, Aneesh Kumar K.V ha scritto:
> diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
> index e999bbaea062..e079be050fc7 100644
> --- a/hw/ppc/spapr_hcall.c
> +++ b/hw/ppc/spapr_hcall.c
> @@ -118,7 +118,8 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr,
>              if ((ppc_hash64_load_hpte0(env, token, index) & HPTE64_V_VALID) == 0) {
>                  break;
>              }
> -        } while (index++);
> +            index++;
> +        } while (1);

Better use for or while() than do...while, or it could also be

	token = ppc_hash64_start_access(cpu, pte_index);
	for (; index < 8; i++, hpte += HASH_PTE_SIZE_64) {
	   ...
	}
	ppc_hash64_stop_access(token);
	if (index == 8) {
	    return H_PTEG_FULL;
	}

Paolo

>          ppc_hash64_stop_access(token);
>      } else {
>          token = ppc_hash64_start_access(cpu, pte_index);
>
>          -aneesh
>

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC)
  2014-03-14 11:23   ` Paolo Bonzini
@ 2014-03-14 16:42     ` Fabien Chouteau
  0 siblings, 0 replies; 142+ messages in thread
From: Fabien Chouteau @ 2014-03-14 16:42 UTC (permalink / raw)
  To: Paolo Bonzini, Alexander Graf, qemu-devel; +Cc: Peter Maydell

On 03/14/2014 12:23 PM, Paolo Bonzini wrote:
> Il 07/03/2014 00:33, Alexander Graf ha scritto:
>> +                if (bd.flags | BD_INTERRUPT) {
>> +                    /* Set RXFx */
>> +                    etsec->regs[RSTAT].value |= 1 << (7 - ring_nbr);
>> +
>> +                    /* Set IEVENT */
>> +                    ievent_set(etsec, IEVENT_RXF);
>> +                }
>> +
>> +            } else {
>> +                if (bd.flags | BD_INTERRUPT) {
>> +                    /* Set IEVENT */
>> +                    ievent_set(etsec, IEVENT_RXB);
>> +                }
>> +            }
> 
> Coverity flags this "bd.flags | BD_INTERRUPT" idiom... What did you mean?  Can you send a fix to qemu-trivial?
> 

That's a very bad mistake indeed, it's supposed to be a "bd.flags & BD_INTERRUPT"...

^ permalink raw reply	[flat|nested] 142+ messages in thread

end of thread, other threads:[~2014-03-14 16:42 UTC | newest]

Thread overview: 142+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-06 23:32 [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 001/130] target-ppc: fix compile error when PPC_DUMP_CPU is enabled Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 002/130] target-ppc: fix LPCR SPR number Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 003/130] target-ppc: remove powerpc 970gx Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 004/130] target-ppc: fix SPR_CTRL/SPR_UCTRL register numbers Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 005/130] target-ppc: remove embedded MMU SPRs from 970, P5+/7/7+/8 Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 006/130] target-ppc: remove unsupported SPRs from 970 and P5+ Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 007/130] KVM: Split QEMUMachine typedef into separate header Alexander Graf
2014-03-07  7:31   ` Paolo Bonzini
2014-03-06 23:32 ` [Qemu-devel] [PULL 008/130] kvm: Add a new machine option kvm-type Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 009/130] target-ppc: dump DAR and DSISR Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 010/130] target-ppc: fix Authority Mask Register init value Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 011/130] mmu-hash64: fix Virtual Page Class Key Protection Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 012/130] PPC: KVM: fix "set one register" Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 013/130] PPC: KVM: add support for LPCR Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 014/130] spapr-pci: enable adding PHB via -device Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 015/130] spapr_vscsi: Fix REPORT_LUNS handling Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 016/130] target-ppc: disable unsupported modes for SPR_CTRL/SPR_UCTRL Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 017/130] target-ppc: Add set_fprf Argument to fload_invalid_op_excp() Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 018/130] target-ppc: General Support for VSX Helpers Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 019/130] target-ppc: Add VSX ISA2.06 xadd/xsub Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 020/130] target-ppc: Add VSX ISA2.06 xmul Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 021/130] target-ppc: Add VSX ISA2.06 xdiv Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 022/130] target-ppc: Add VSX ISA2.06 xre Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 023/130] target-ppc: Add VSX ISA2.06 xsqrt Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 024/130] target-ppc: Add VSX ISA2.06 xrsqrte Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 025/130] target-ppc: Add VSX ISA2.06 xtdiv Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 026/130] target-ppc: Add VSX ISA2.06 xtsqrt Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 027/130] target-ppc: Add VSX ISA2.06 Multiply Add Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 028/130] target-ppc: Add VSX xscmp*dp Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 029/130] target-ppc: Add VSX xmax/xmin Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 030/130] target-ppc: Add VSX Vector Compare Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 031/130] target-ppc: Add VSX Floating Point to Floating Point Conversion Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 032/130] target-ppc: Add VSX ISA2.06 Integer " Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 033/130] target-ppc: Add VSX Rounding Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 034/130] target-ppc: VSX Stage 4: Add VSX 2.07 Flag Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 035/130] target-ppc: VSX Stage 4: Refactor lxsdx Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 036/130] target-ppc: VSX Stage 4: Add lxsiwax, lxsiwzx and lxsspx Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 037/130] target-ppc: VSX Stage 4: Refactor stxsdx Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 038/130] target-ppc: VSX Stage 4: Add stxsiwx and stxsspx Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 039/130] target-ppc: VSX Stage 4: Add xsaddsp and xssubsp Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 040/130] target-ppc: VSX Stage 4: Add xsmulsp Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 041/130] target-ppc: VSX Stage 4: Add xsdivsp Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 042/130] target-ppc: VSX Stage 4: Add xsresp Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 043/130] target-ppc: VSX Stage 4: Add xssqrtsp Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 044/130] target-ppc: VSX Stage 4: add xsrsqrtesp Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 045/130] target-ppc: VSX Stage 4: Add Scalar SP Fused Multiply-Adds Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 046/130] target-ppc: VSX Stage 4: Add xscvsxdsp and xscvuxdsp Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 047/130] target-ppc: VSX Stage 4: Add xxleqv, xxlnand and xxlorc Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 048/130] target-ppc: Move To/From VSR Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 049/130] target-ppc: Floating Merge Word Instructions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 050/130] target-ppc: Scalar Round to Single Precision Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 051/130] target-ppc: Scalar Non-Signalling Conversions Alexander Graf
2014-03-06 23:32 ` [Qemu-devel] [PULL 052/130] target-ppc: Add ISA2.06 bpermd Instruction Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 053/130] target-ppc: Add Flag for ISA2.06 Divide Extended Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 054/130] target-ppc: Add ISA2.06 divdeu[o] Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 055/130] target-ppc: Add ISA2.06 divde[o] Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 056/130] target-ppc: Add ISA 2.06 divweu[o] Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 057/130] target-ppc: Add ISA 2.06 divwe[o] Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 058/130] target-ppc: Add Flag for ISA2.06 Atomic Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 059/130] target-ppc: Add ISA2.06 lbarx, lharx Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 060/130] target-ppc: Add ISA 2.06 stbcx. and sthcx. Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 061/130] target-ppc: Add Flag for ISA V2.06 Floating Point Conversion Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 062/130] target-ppc: Add ISA2.06 Float to Integer Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 063/130] target-ppc: Add ISA 2.06 fcfid[u][s] Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 064/130] target-ppc: Fix and enable fri[mnpz] Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 065/130] target-ppc: Add Flag for Power ISA V2.06 Floating Point Test Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 066/130] target-ppc: Add ISA 2.06 ftdiv Instruction Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 067/130] target-ppc: Add ISA 2.06 ftsqrt Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 068/130] target-ppc: Enable frsqrtes on Power7 and Power8 Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 069/130] target-ppc: Add ISA2.06 lfiwzx Instruction Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 070/130] PPC: KVM: store SLB slot number Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 071/130] virtex_ml507: Add support for loading initrd images Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 072/130] PPC: KVM: suppress warnings about not supported SPRs Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 073/130] Add Enhanced Three-Speed Ethernet Controller (eTSEC) Alexander Graf
2014-03-09  8:02   ` Paolo Bonzini
2014-03-12 11:41     ` Fabien Chouteau
2014-03-12 18:22       ` Paolo Bonzini
2014-03-12 18:39         ` Andreas Färber
2014-03-14 11:23   ` Paolo Bonzini
2014-03-14 16:42     ` Fabien Chouteau
2014-03-06 23:33 ` [Qemu-devel] [PULL 074/130] spapr: support only ELF kernel images Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 075/130] moxie: fix load_elf() usage Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 076/130] elf-loader: add more return codes Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 077/130] spapr: print more detailed error message on failed load_elf() Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 078/130] target-ppc: Update external_htab even when HTAB is managed by kernel Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 079/130] qdev: Keep global allocation counter per bus Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 080/130] target-ppc: add extended opcodes for dcbt/dcbtst Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 081/130] target-ppc: Fix xxpermdi When T==A or T==B Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 082/130] target-ppc: Add Flag for bctar Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 083/130] target-ppc: Add Target Address SPR (TAR) to Power8 Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 084/130] target-ppc: Add bctar Instruction Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 085/130] target-ppc: Add Flag for ISA 2.07 Load/Store Quadword Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 086/130] target-ppc: Add is_user_mode Utility Routine Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 087/130] target-ppc: Load Quadword Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 088/130] target-ppc: Store Quadword Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 089/130] target-ppc: Add Load Quadword and Reserve Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 090/130] target-ppc: Add Store Quadword Conditional Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 091/130] target-ppc: Altivec 2.07: Add Instruction Flag Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 092/130] target-ppc: Altivec 2.07: Update AVR Structure Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 093/130] target-ppc: Altivec 2.07: Add GEN_VXFORM3 Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 094/130] target-ppc: Altivec 2.07: Add Support for Dual Altivec Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 095/130] target-ppc: Altivec 2.07: Add Opcode Macro for VX Form Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 096/130] target-ppc: Altivec 2.07: Add Support for R-Form Dual Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 097/130] target-ppc: Altivec 2.07: Vector Logical Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 098/130] target-ppc: Altivec 2.07: Add/Subtract Unsigned Doubleword Modulo Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 099/130] target-ppc: Altivec 2.07: Change VMUL_DO to Support 64-bit Integers Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 100/130] target-ppc: Altivec 2.07: Multiply Even/Odd Word Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 101/130] target-ppc: Altivec 2.07: vmuluw Instruction Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 102/130] target-ppc: Altivec 2.07: Add Vector Count Leading Zeroes Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 103/130] target-ppc: Altivec 2.07: Vector Population Count Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 104/130] target-ppc: Altivec 2.07: Vector Min/Max Doubleword Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 105/130] target-ppc: Altivec 2.07: Pack " Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 106/130] target-ppc: Altivec 2.07: Unpack Signed Word Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 107/130] target-ppc: Altivec 2.07: Vector Merge Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 108/130] target-ppc: Altivec 2.07: Change Bit Masks to Support 64-bit Rotates and Shifts Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 109/130] target-ppc: Altivec 2.07: Vector Doubleword Rotate and Shift Instructions Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 110/130] target-ppc: Altivec 2.07: Quadword Addition and Subtracation Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 111/130] target-ppc: Altivec 2.07: vbpermq Instruction Alexander Graf
2014-03-06 23:33 ` [Qemu-devel] [PULL 112/130] target-ppc: Altivec 2.07: Doubleword Compares Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 113/130] target-ppc: Altivec 2.07: Vector Gather Bits by Bytes Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 114/130] target-ppc: Altivec 2.07: Vector Polynomial Multiply Sum Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 115/130] target-ppc: Altivec 2.07: Binary Coded Decimal Instructions Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 116/130] target-ppc: Altivec 2.07: AES Instructions Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 117/130] target-ppc: Altivec 2.07: Vector SHA Sigma Instructions Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 118/130] target-ppc: Altivec 2.07: Vector Permute and Exclusive OR Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 119/130] spapr-vlan: flush queue whenever can_receive can go from false to true Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 120/130] target-ppc/translate.c: Use ULL suffix for 64 bit constants Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 121/130] PPC: sPAPR: Only use getpagesize() when we run with kvm Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 122/130] target-ppc: Fix Compiler Warnings Due to 64-Bit Constants Declared as UL Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 123/130] target-ppc: Use Additional Temporary in stqcx Case Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 124/130] target-ppc: Fix htab_mask calculation Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 125/130] target-ppc: Fix page table lookup with kvm enabled Alexander Graf
2014-03-14 11:26   ` Paolo Bonzini
2014-03-14 13:13     ` Aneesh Kumar K.V
2014-03-14 13:23       ` Paolo Bonzini
2014-03-06 23:34 ` [Qemu-devel] [PULL 126/130] target-ppc: Change the hpte store API Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 127/130] target-ppc: Update ppc_hash64_store_hpte to support updating in-kernel htab Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 128/130] target-ppc: Introduce hypervisor call H_GET_TCE Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 129/130] target-ppc: add PowerPCCPU::cpu_dt_id Alexander Graf
2014-03-06 23:34 ` [Qemu-devel] [PULL 130/130] target-ppc: spapr: e500: fix to use cpu_dt_id Alexander Graf
2014-03-07 17:16 ` [Qemu-devel] [PULL 00/130] ppc patch queue 2014-03-05 Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.