[Spice-commits] 67 commits - .gitignore .travis.yml Makefile block.c block/nbd-client.c block/vhdx.h configure hw/audio hw/char hw/intc hw/net hw/s390x hw/scsi hw/timer include/hw include/migration include/ui qemu-nbd.c qemu-options.hx qemu.sasl rules.mak scripts/make-release stubs/Makefile.objs stubs/runstate-check.c target-alpha/translate.c target-arm/helper.c target-ppc/int_helper.c tcg/aarch64 tcg/sparc tests/qemu-iotests tests/tcg ui/gtk.c vl.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Tue Mar 18 00:49:10 PDT 2014


 .gitignore                               |    1 
 .travis.yml                              |   53 +-
 Makefile                                 |    5 
 block.c                                  |    9 
 block/nbd-client.c                       |   33 -
 block/vhdx.h                             |    6 
 configure                                |    5 
 hw/audio/fmopl.c                         |    6 
 hw/char/sclpconsole-lm.c                 |   27 -
 hw/char/sclpconsole.c                    |   30 -
 hw/intc/arm_gic_kvm.c                    |    2 
 hw/net/fsl_etsec/rings.c                 |    8 
 hw/s390x/ipl.c                           |    2 
 hw/s390x/sclpcpu.c                       |    6 
 hw/scsi/scsi-bus.c                       |   30 +
 hw/scsi/spapr_vscsi.c                    |    4 
 hw/scsi/virtio-scsi.c                    |    4 
 hw/timer/grlib_gptimer.c                 |    4 
 include/hw/scsi/scsi.h                   |    1 
 include/migration/vmstate.h              |    3 
 include/ui/console.h                     |    2 
 qemu-nbd.c                               |   17 
 qemu-options.hx                          |    5 
 qemu.sasl                                |    4 
 rules.mak                                |    4 
 scripts/make-release                     |    2 
 stubs/Makefile.objs                      |    1 
 stubs/runstate-check.c                   |    6 
 target-alpha/translate.c                 |    3 
 target-arm/helper.c                      |    2 
 target-ppc/int_helper.c                  |    2 
 tcg/aarch64/tcg-target.c                 |  801 ++++++++++++++++++++++---------
 tcg/aarch64/tcg-target.h                 |   48 -
 tcg/sparc/tcg-target.c                   |  599 +++++++++++------------
 tcg/sparc/tcg-target.h                   |    6 
 tests/qemu-iotests/083                   |  129 ++++
 tests/qemu-iotests/083.out               |  163 ++++++
 tests/qemu-iotests/087                   |   17 
 tests/qemu-iotests/087.out               |   11 
 tests/qemu-iotests/group                 |    5 
 tests/qemu-iotests/nbd-fault-injector.py |  264 ++++++++++
 tests/tcg/test_path.c                    |   13 
 ui/gtk.c                                 |   15 
 vl.c                                     |   45 +
 44 files changed, 1706 insertions(+), 697 deletions(-)

New commits:
commit 315b59344126beab85a62b53582794b14436a5a4
Merge: cdf0592 4f3ed19
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Mar 17 22:31:32 2014 +0000

    Merge remote-tracking branch 'remotes/borntraeger/tags/kvm-s390-20140317' into staging
    
    4 small patches:
    - Fixing findings of valgrind regarding minor memory leaks:
      Currently we forget the pointer of qemu_allocate_irqs. Since we never
      free the irqs, this is not critical, but obviously not good programming
      style. While we are at it, we dont need the irq infrastructure for
      the sclp consoles.
    - Handle new ELF error codes for BIOS loading
    
    # gpg: Signature made Mon 17 Mar 2014 21:34:12 GMT using RSA key ID B5A61C7C
    # gpg: Can't check signature: public key not found
    
    * remotes/borntraeger/tags/kvm-s390-20140317:
      s390x/sclpconsole-lm: Fix and simplify irq setup
      s390x/sclpconsole: Fix and simplify interrupt injection
      s390x/cpu hotplug: Fix memory leak
      s390/ipl: Fix error path on BIOS loading
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit cdf0592cb888d071e4b4f37048ad8646ac9fbc8c
Merge: 87f6396 cab0a7e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Mar 17 22:15:52 2014 +0000

    Merge remote-tracking branch 'remotes/rth/tcg-v8p-2' into staging
    
    * remotes/rth/tcg-v8p-2:
      tcg-sparc: Convert to new ldst opcodes
      tcg-sparc: Convert to new ldst helpers
      tcg-sparc: Tidy tcg_out_tlb_load interface
      tcg-sparc: Use TCGMemOp within qemu_ldst routines
      tcg-sparc: Improve tcg_out_movi
      tcg-sparc: Dont handle constant arguments to ext32 ops
      tcg-sparc: Don't handle remainder
      tcg-sparc: Use intptr_t as appropriate
      tcg-sparc: Tidy call+jump patterns
      tcg-sparc: Fix tlb read
      tcg-sparc: Fix ld64 for 32-bit mode
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 4f3ed190a673c0020c3ccebb4882ae4675cb5f4d
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Mon Mar 10 14:19:52 2014 +0100

    s390x/sclpconsole-lm: Fix and simplify irq setup
    
    valgrind complains about a memory leak in irq setup of sclpconsole:
    
    ==42117== 8 bytes in 1 blocks are definitely lost in loss record 89of 833
    ==42117==    at 0x4031AFE: malloc (vg_replace_malloc.c:292)
    ==42117==    by 0x8022F855: malloc_and_trace (vl.c:2715)
    ==42117==    by 0x4145569: g_malloc (in /usr/lib64/libglib-2.0.so.0.3400.2)
    ==42117==    by 0x800F696D: qemu_extend_irqs (irq.c:51)
    ==42117==    by 0x800F6AF7: qemu_allocate_irqs (irq.c:68)
    ==42117==    by 0x800F5685: console_init (sclpconsole.c:235)
    ==42117==    by 0x80297C79: event_realize (event-facility.c:386)
    ==42117==    by 0x80105071: device_set_realized (qdev.c:693)
    ==42117==    by 0x801CDC4B: property_set_bool (object.c:1337)
     ==42117==    by 0x801CBD7F: object_property_set (object.c:819)
    [...]
    
    We dont need the indirection of an qemu irq to inject an slcp interrupt.
    Fixes a valgrind error and makes the code simpler.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    Acked-by: Heinz Graalfs <graalfs at linux.vnet.ibm.com>

diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c
index 9339067..a2dc1c6 100644
--- a/hw/char/sclpconsole-lm.c
+++ b/hw/char/sclpconsole-lm.c
@@ -41,7 +41,6 @@ typedef struct SCLPConsoleLM {
     uint32_t write_errors;      /* errors writing to char layer           */
     uint32_t length;            /* length of byte stream in buffer        */
     uint8_t buf[SIZE_CONSOLE_BUFFER];
-    qemu_irq irq_console_read;
 } SCLPConsoleLM;
 
 /*
@@ -68,13 +67,15 @@ static int chr_can_read(void *opaque)
     return 0;
 }
 
-static void receive_from_chr_layer(SCLPConsoleLM *scon, const uint8_t *buf,
-                                   int size)
+static void chr_read(void *opaque, const uint8_t *buf, int size)
 {
+    SCLPConsoleLM *scon = opaque;
+
     assert(size == 1);
 
     if (*buf == '\r' || *buf == '\n') {
         scon->event.event_pending = true;
+        sclp_service_interrupt(0);
         return;
     }
     scon->buf[scon->length] = *buf;
@@ -84,20 +85,6 @@ static void receive_from_chr_layer(SCLPConsoleLM *scon, const uint8_t *buf,
     }
 }
 
-/*
- * Send data from a char device over to the guest
- */
-static void chr_read(void *opaque, const uint8_t *buf, int size)
-{
-    SCLPConsoleLM *scon = opaque;
-
-    receive_from_chr_layer(scon, buf, size);
-    if (scon->event.event_pending) {
-        /* trigger SCLP read operation */
-        qemu_irq_raise(scon->irq_console_read);
-    }
-}
-
 /* functions to be called by event facility */
 
 static bool can_handle_event(uint8_t type)
@@ -298,11 +285,6 @@ static int write_event_data(SCLPEvent *event, EventBufferHeader *ebh)
     return SCLP_RC_NORMAL_COMPLETION;
 }
 
-static void trigger_console_data(void *opaque, int n, int level)
-{
-    sclp_service_interrupt(0);
-}
-
 /* functions for live migration */
 
 static const VMStateDescription vmstate_sclplmconsole = {
@@ -338,7 +320,6 @@ static int console_init(SCLPEvent *event)
     if (scon->chr) {
         qemu_chr_add_handlers(scon->chr, chr_can_read, chr_read, NULL, scon);
     }
-    scon->irq_console_read = *qemu_allocate_irqs(trigger_console_data, NULL, 1);
 
     return 0;
 }
commit b074e6220542107afb9fad480a184775be591d2a
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Mon Mar 10 14:17:04 2014 +0100

    s390x/sclpconsole: Fix and simplify interrupt injection
    
    valgrind complains about a memory leak in irq setup of sclpconsole:
    
    ==42117== 8 bytes in 1 blocks are definitely lost in loss record 89 of 833
    ==42117==    at 0x4031AFE: malloc (vg_replace_malloc.c:292)
    ==42117==    by 0x8022F855: malloc_and_trace (vl.c:2715)
    ==42117==    by 0x4145569: g_malloc (in /usr/lib64/libglib-2.0.so.0.3400.2)
    ==42117==    by 0x800F696D: qemu_extend_irqs (irq.c:51)
    ==42117==    by 0x800F6AF7: qemu_allocate_irqs (irq.c:68)
    ==42117==    by 0x800F5685: console_init (sclpconsole.c:235)
    ==42117==    by 0x80297C79: event_realize (event-facility.c:386)
    ==42117==    by 0x80105071: device_set_realized (qdev.c:693)
    ==42117==    by 0x801CDC4B: property_set_bool (object.c:1337)
    ==42117==    by 0x801CBD7F: object_property_set (object.c:819)
    [...]
    
    Turns out that we actually dont need the indirection, so trigger the
    sclp interrupt directly.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    Acked-by: Heinz Graalfs <graalfs at linux.vnet.ibm.com>

diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index 16d77c5..ce40673 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -36,7 +36,6 @@ typedef struct SCLPConsole {
     uint32_t iov_bs;        /* offset in buf for char layer read operation */
     uint32_t iov_data_len;  /* length of byte stream in buffer             */
     uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP     */
-    qemu_irq irq_read_vt220;
 } SCLPConsole;
 
 /* character layer call-back functions */
@@ -49,11 +48,12 @@ static int chr_can_read(void *opaque)
     return SIZE_BUFFER_VT220 - scon->iov_data_len;
 }
 
-/* Receive n bytes from character layer, save in iov buffer,
- * and set event pending */
-static void receive_from_chr_layer(SCLPConsole *scon, const uint8_t *buf,
-                                   int size)
+/* Send data from a char device over to the guest */
+static void chr_read(void *opaque, const uint8_t *buf, int size)
 {
+    SCLPConsole *scon = opaque;
+
+    assert(scon);
     /* read data must fit into current buffer */
     assert(size <= SIZE_BUFFER_VT220 - scon->iov_data_len);
 
@@ -63,18 +63,7 @@ static void receive_from_chr_layer(SCLPConsole *scon, const uint8_t *buf,
     scon->iov_sclp_rest += size;
     scon->iov_bs += size;
     scon->event.event_pending = true;
-}
-
-/* Send data from a char device over to the guest */
-static void chr_read(void *opaque, const uint8_t *buf, int size)
-{
-    SCLPConsole *scon = opaque;
-
-    assert(scon);
-
-    receive_from_chr_layer(scon, buf, size);
-    /* trigger SCLP read operation */
-    qemu_irq_raise(scon->irq_read_vt220);
+    sclp_service_interrupt(0);
 }
 
 /* functions to be called by event facility */
@@ -192,11 +181,6 @@ static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
     return rc;
 }
 
-static void trigger_ascii_console_data(void *opaque, int n, int level)
-{
-    sclp_service_interrupt(0);
-}
-
 static const VMStateDescription vmstate_sclpconsole = {
     .name = "sclpconsole",
     .version_id = 0,
@@ -232,8 +216,6 @@ static int console_init(SCLPEvent *event)
         qemu_chr_add_handlers(scon->chr, chr_can_read,
                               chr_read, NULL, scon);
     }
-    scon->irq_read_vt220 = *qemu_allocate_irqs(trigger_ascii_console_data,
-                                               NULL, 1);
 
     return 0;
 }
commit 7b53f2940e3bf43ae50c929330a4837ca4da7a94
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Mon Mar 10 15:03:16 2014 +0100

    s390x/cpu hotplug: Fix memory leak
    
    valgrind complains about the following:
    ==42117== 8 bytes in 1 blocks are definitely lost in loss record 88 of 833
    ==42117==    at 0x4031AFE: malloc (vg_replace_malloc.c:292)
    ==42117==    by 0x8022F855: malloc_and_trace (vl.c:2715)
    ==42117==    by 0x4145569: g_malloc (in /usr/lib64/libglib-2.0.so.0.3400.2)
    ==42117==    by 0x800F696D: qemu_extend_irqs (irq.c:51)
    ==42117==    by 0x800F6AF7: qemu_allocate_irqs (irq.c:68)
    ==42117==    by 0x8029FA4B: irq_cpu_hotplug_init (sclpcpu.c:84)
    ==42117==    by 0x80297C79: event_realize (event-facility.c:386)
    ==42117==    by 0x80105071: device_set_realized (qdev.c:693)
    [...]
    
    Right it is. Don't drop the pointer of the irq.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    Reviewed-by: Jason J. Herne <jjherne at us.ibm.com>

diff --git a/hw/s390x/sclpcpu.c b/hw/s390x/sclpcpu.c
index b9c238a..3600fe2 100644
--- a/hw/s390x/sclpcpu.c
+++ b/hw/s390x/sclpcpu.c
@@ -25,13 +25,13 @@ typedef struct ConfigMgtData {
     uint8_t event_qualifier;
 } QEMU_PACKED ConfigMgtData;
 
-static qemu_irq irq_cpu_hotplug; /* Only used in this file */
+static qemu_irq *irq_cpu_hotplug; /* Only used in this file */
 
 #define EVENT_QUAL_CPU_CHANGE  1
 
 void raise_irq_cpu_hotplug(void)
 {
-    qemu_irq_raise(irq_cpu_hotplug);
+    qemu_irq_raise(*irq_cpu_hotplug);
 }
 
 static unsigned int send_mask(void)
@@ -81,7 +81,7 @@ static void trigger_signal(void *opaque, int n, int level)
 
 static int irq_cpu_hotplug_init(SCLPEvent *event)
 {
-    irq_cpu_hotplug = *qemu_allocate_irqs(trigger_signal, event, 1);
+    irq_cpu_hotplug = qemu_allocate_irqs(trigger_signal, event, 1);
     return 0;
 }
 
commit 0a1bec8a4e1c55bb581521c60db30e3f4867ceb1
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Fri Mar 14 13:38:57 2014 +0100

    s390/ipl: Fix error path on BIOS loading
    
    commit 18674b26788a9e47f1157170234e32ece2044367
    (elf-loader: add more return codes) enabled the elf loader to return
    other errors than -1.
    
    Lets also handle that case for our "BIOS" on s390.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    CC: Alexey Kardashevskiy <aik at ozlabs.ru>
    CC: Alexander Graf <agraf at suse.de>

diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 32d38a0..4fa9cff 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -80,7 +80,7 @@ static int s390_ipl_init(SysBusDevice *dev)
 
         bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL,
                              NULL, 1, ELF_MACHINE, 0);
-        if (bios_size == -1) {
+        if (bios_size < 0) {
             bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,
                                             4096);
             ipl->start_addr = ZIPL_IMAGE_START;
commit cab0a7ea002b0a01ebfbde5d3c8ace0b6848ffcc
Author: Richard Henderson <rth at twiddle.net>
Date:   Mon Sep 9 19:51:21 2013 -0700

    tcg-sparc: Convert to new ldst opcodes
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 754e520..152335c 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -1038,27 +1038,28 @@ static const int qemu_st_opc[16] = {
     [MO_LEQ]  = STX_LE,
 };
 
-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
+static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
 {
-    TCGReg addrlo, datalo, datahi, addr_reg;
-    TCGMemOp s_bits = memop & MO_SIZE;
+    TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused));
+    TCGMemOp memop, s_bits;
 #if defined(CONFIG_SOFTMMU)
-    TCGReg addrhi, param;
+    TCGReg addrz, param;
     uintptr_t func;
     int memi;
     uint32_t *label_ptr[2];
 #endif
 
     datalo = *args++;
-    datahi = (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64 ? *args++ : 0);
-    addr_reg = addrlo = *args++;
+    datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0);
+    addrlo = *args++;
+    addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
+    memop = *args++;
+    s_bits = memop & MO_SIZE;
 
 #if defined(CONFIG_SOFTMMU)
-    addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
     memi = *args++;
-
-    addr_reg = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
-                                offsetof(CPUTLBEntry, addr_read));
+    addrz = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
+                             offsetof(CPUTLBEntry, addr_read));
 
     if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         int reg64;
@@ -1072,7 +1073,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
         /* TLB Hit.  */
         /* Load all 64-bits into an O/G register.  */
         reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
-        tcg_out_ldst_rr(s, reg64, addr_reg, TCG_REG_O1, qemu_ld_opc[memop]);
+        tcg_out_ldst_rr(s, reg64, addrz, TCG_REG_O1, qemu_ld_opc[memop]);
 
         /* Move the two 32-bit pieces into the destination registers.  */
         tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
@@ -1094,7 +1095,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
         tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
                       | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
         /* delay slot */
-        tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_O1, qemu_ld_opc[memop]);
+        tcg_out_ldst_rr(s, datalo, addrz, TCG_REG_O1, qemu_ld_opc[memop]);
     }
 
     /* TLB Miss.  */
@@ -1143,13 +1144,13 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
                                 (unsigned long)label_ptr[1]);
 #else
     if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
-        tcg_out_arithi(s, TCG_REG_T1, addr_reg, 0, SHIFT_SRL);
-        addr_reg = TCG_REG_T1;
+        tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
+        addrlo = TCG_REG_T1;
     }
     if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
 
-        tcg_out_ldst_rr(s, reg64, addr_reg,
+        tcg_out_ldst_rr(s, reg64, addrlo,
                         (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
                         qemu_ld_opc[memop]);
 
@@ -1158,34 +1159,35 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
             tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
         }
     } else {
-        tcg_out_ldst_rr(s, datalo, addr_reg,
+        tcg_out_ldst_rr(s, datalo, addrlo,
                         (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
                         qemu_ld_opc[memop]);
     }
 #endif /* CONFIG_SOFTMMU */
 }
 
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGMemOp memop)
+static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
 {
-    TCGReg addrlo, datalo, datahi, addr_reg;
-    TCGMemOp s_bits = memop & MO_SIZE;
+    TCGReg addrlo, datalo, datahi, addrhi __attribute__((unused));
+    TCGMemOp memop, s_bits;
 #if defined(CONFIG_SOFTMMU)
-    TCGReg addrhi, datafull, param;
+    TCGReg addrz, datafull, param;
     uintptr_t func;
     int memi;
     uint32_t *label_ptr;
 #endif
 
     datalo = *args++;
-    datahi = (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64 ? *args++ : 0);
-    addr_reg = addrlo = *args++;
+    datahi = (TCG_TARGET_REG_BITS == 32 && is64 ? *args++ : 0);
+    addrlo = *args++;
+    addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
+    memop = *args++;
+    s_bits = memop & MO_SIZE;
 
 #if defined(CONFIG_SOFTMMU)
-    addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
     memi = *args++;
-
-    addr_reg = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
-                                offsetof(CPUTLBEntry, addr_write));
+    addrz = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
+                             offsetof(CPUTLBEntry, addr_write));
 
     datafull = datalo;
     if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
@@ -1203,7 +1205,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGMemOp memop)
     tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
                   | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
     /* delay slot */
-    tcg_out_ldst_rr(s, datafull, addr_reg, TCG_REG_O1, qemu_st_opc[memop]);
+    tcg_out_ldst_rr(s, datafull, addrz, TCG_REG_O1, qemu_st_opc[memop]);
 
     /* TLB Miss.  */
 
@@ -1227,8 +1229,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGMemOp memop)
                              (unsigned long)label_ptr);
 #else
     if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
-        tcg_out_arithi(s, TCG_REG_T1, addr_reg, 0, SHIFT_SRL);
-        addr_reg = TCG_REG_T1;
+        tcg_out_arithi(s, TCG_REG_T1, addrlo, 0, SHIFT_SRL);
+        addrlo = TCG_REG_T1;
     }
     if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
@@ -1236,7 +1238,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGMemOp memop)
         tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
         datalo = TCG_REG_O2;
     }
-    tcg_out_ldst_rr(s, datalo, addr_reg,
+    tcg_out_ldst_rr(s, datalo, addrlo,
                     (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
                     qemu_st_opc[memop]);
 #endif /* CONFIG_SOFTMMU */
@@ -1417,43 +1419,17 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out_rdy(s, args[1]);
         break;
 
-    case INDEX_op_qemu_ld8u:
-        tcg_out_qemu_ld(s, args, MO_UB);
-        break;
-    case INDEX_op_qemu_ld8s:
-        tcg_out_qemu_ld(s, args, MO_SB);
-        break;
-    case INDEX_op_qemu_ld16u:
-        tcg_out_qemu_ld(s, args, MO_TEUW);
-        break;
-    case INDEX_op_qemu_ld16s:
-        tcg_out_qemu_ld(s, args, MO_TESW);
-        break;
-    case INDEX_op_qemu_ld32:
-#if TCG_TARGET_REG_BITS == 64
-    case INDEX_op_qemu_ld32u:
-#endif
-        tcg_out_qemu_ld(s, args, MO_TEUL);
-        break;
-#if TCG_TARGET_REG_BITS == 64
-    case INDEX_op_qemu_ld32s:
-        tcg_out_qemu_ld(s, args, MO_TESL);
-        break;
-#endif
-    case INDEX_op_qemu_ld64:
-        tcg_out_qemu_ld(s, args, MO_TEQ);
-        break;
-    case INDEX_op_qemu_st8:
-        tcg_out_qemu_st(s, args, MO_UB);
+    case INDEX_op_qemu_ld_i32:
+        tcg_out_qemu_ld(s, args, 0);
         break;
-    case INDEX_op_qemu_st16:
-        tcg_out_qemu_st(s, args, MO_TEUW);
+    case INDEX_op_qemu_ld_i64:
+        tcg_out_qemu_ld(s, args, 1);
         break;
-    case INDEX_op_qemu_st32:
-        tcg_out_qemu_st(s, args, MO_TEUL);
+    case INDEX_op_qemu_st_i32:
+        tcg_out_qemu_st(s, args, 0);
         break;
-    case INDEX_op_qemu_st64:
-        tcg_out_qemu_st(s, args, MO_TEQ);
+    case INDEX_op_qemu_st_i64:
+        tcg_out_qemu_st(s, args, 1);
         break;
 
 #if TCG_TARGET_REG_BITS == 64
@@ -1614,43 +1590,20 @@ static const TCGTargetOpDef sparc_op_defs[] = {
 #endif
 
 #if TCG_TARGET_REG_BITS == 64
-    { INDEX_op_qemu_ld8u, { "r", "L" } },
-    { INDEX_op_qemu_ld8s, { "r", "L" } },
-    { INDEX_op_qemu_ld16u, { "r", "L" } },
-    { INDEX_op_qemu_ld16s, { "r", "L" } },
-    { INDEX_op_qemu_ld32, { "r", "L" } },
-    { INDEX_op_qemu_ld32u, { "r", "L" } },
-    { INDEX_op_qemu_ld32s, { "r", "L" } },
-    { INDEX_op_qemu_ld64, { "r", "L" } },
-
-    { INDEX_op_qemu_st8, { "L", "L" } },
-    { INDEX_op_qemu_st16, { "L", "L" } },
-    { INDEX_op_qemu_st32, { "L", "L" } },
-    { INDEX_op_qemu_st64, { "L", "L" } },
+    { INDEX_op_qemu_ld_i32, { "r", "L" } },
+    { INDEX_op_qemu_ld_i64, { "r", "L" } },
+    { INDEX_op_qemu_st_i32, { "L", "L" } },
+    { INDEX_op_qemu_st_i64, { "L", "L" } },
 #elif TARGET_LONG_BITS <= TCG_TARGET_REG_BITS
-    { INDEX_op_qemu_ld8u, { "r", "L" } },
-    { INDEX_op_qemu_ld8s, { "r", "L" } },
-    { INDEX_op_qemu_ld16u, { "r", "L" } },
-    { INDEX_op_qemu_ld16s, { "r", "L" } },
-    { INDEX_op_qemu_ld32, { "r", "L" } },
-    { INDEX_op_qemu_ld64, { "r", "r", "L" } },
-
-    { INDEX_op_qemu_st8, { "L", "L" } },
-    { INDEX_op_qemu_st16, { "L", "L" } },
-    { INDEX_op_qemu_st32, { "L", "L" } },
-    { INDEX_op_qemu_st64, { "L", "L", "L" } },
+    { INDEX_op_qemu_ld_i32, { "r", "L" } },
+    { INDEX_op_qemu_ld_i64, { "r", "r", "L" } },
+    { INDEX_op_qemu_st_i32, { "L", "L" } },
+    { INDEX_op_qemu_st_i64, { "L", "L", "L" } },
 #else
-    { INDEX_op_qemu_ld8u, { "r", "L", "L" } },
-    { INDEX_op_qemu_ld8s, { "r", "L", "L" } },
-    { INDEX_op_qemu_ld16u, { "r", "L", "L" } },
-    { INDEX_op_qemu_ld16s, { "r", "L", "L" } },
-    { INDEX_op_qemu_ld32, { "r", "L", "L" } },
-    { INDEX_op_qemu_ld64, { "L", "L", "L", "L" } },
-
-    { INDEX_op_qemu_st8, { "L", "L", "L" } },
-    { INDEX_op_qemu_st16, { "L", "L", "L" } },
-    { INDEX_op_qemu_st32, { "L", "L", "L" } },
-    { INDEX_op_qemu_st64, { "L", "L", "L", "L" } },
+    { INDEX_op_qemu_ld_i32, { "r", "L", "L" } },
+    { INDEX_op_qemu_ld_i64, { "L", "L", "L", "L" } },
+    { INDEX_op_qemu_st_i32, { "L", "L", "L" } },
+    { INDEX_op_qemu_st_i64, { "L", "L", "L", "L" } },
 #endif
 
     { -1 },
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 202b88a..3abf1b4 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -148,7 +148,7 @@ typedef enum {
 #define TCG_TARGET_HAS_mulsh_i64        0
 #endif
 
-#define TCG_TARGET_HAS_new_ldst         0
+#define TCG_TARGET_HAS_new_ldst         1
 
 #define TCG_AREG0 TCG_REG_I0
 
commit 7ea5d7256d06a04e8953b25f7766c9e32fa408e8
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Mar 5 09:42:08 2014 -0800

    tcg-sparc: Convert to new ldst helpers
    
    All of the helpers with the explicit big/little endian option
    require the return address as a parameter.  Acquire this via
    a trampoline.
    
    Move the load of areg0 into the trampoline.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 6531c30..754e520 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -806,6 +806,98 @@ static inline void tcg_out_calli(TCGContext *s, uintptr_t dest)
     }
 }
 
+#ifdef CONFIG_SOFTMMU
+static uintptr_t qemu_ld_trampoline[16];
+static uintptr_t qemu_st_trampoline[16];
+
+static void build_trampolines(TCGContext *s)
+{
+    static uintptr_t const qemu_ld_helpers[16] = {
+        [MO_UB]   = (uintptr_t)helper_ret_ldub_mmu,
+        [MO_SB]   = (uintptr_t)helper_ret_ldsb_mmu,
+        [MO_LEUW] = (uintptr_t)helper_le_lduw_mmu,
+        [MO_LESW] = (uintptr_t)helper_le_ldsw_mmu,
+        [MO_LEUL] = (uintptr_t)helper_le_ldul_mmu,
+        [MO_LEQ]  = (uintptr_t)helper_le_ldq_mmu,
+        [MO_BEUW] = (uintptr_t)helper_be_lduw_mmu,
+        [MO_BESW] = (uintptr_t)helper_be_ldsw_mmu,
+        [MO_BEUL] = (uintptr_t)helper_be_ldul_mmu,
+        [MO_BEQ]  = (uintptr_t)helper_be_ldq_mmu,
+    };
+    static uintptr_t const qemu_st_helpers[16] = {
+        [MO_UB]   = (uintptr_t)helper_ret_stb_mmu,
+        [MO_LEUW] = (uintptr_t)helper_le_stw_mmu,
+        [MO_LEUL] = (uintptr_t)helper_le_stl_mmu,
+        [MO_LEQ]  = (uintptr_t)helper_le_stq_mmu,
+        [MO_BEUW] = (uintptr_t)helper_be_stw_mmu,
+        [MO_BEUL] = (uintptr_t)helper_be_stl_mmu,
+        [MO_BEQ]  = (uintptr_t)helper_be_stq_mmu,
+    };
+
+    int i;
+    TCGReg ra;
+    uintptr_t tramp;
+
+    for (i = 0; i < 16; ++i) {
+        if (qemu_ld_helpers[i] == 0) {
+            continue;
+        }
+
+        /* May as well align the trampoline.  */
+        tramp = (uintptr_t)s->code_ptr;
+        while (tramp & 15) {
+            tcg_out_nop(s);
+            tramp += 4;
+        }
+        qemu_ld_trampoline[i] = tramp;
+
+        /* Find the retaddr argument register.  */
+        ra = TCG_REG_O3 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
+
+        /* Set the retaddr operand.  */
+        tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
+        /* Set the env operand.  */
+        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
+        /* Tail call.  */
+        tcg_out_calli(s, qemu_ld_helpers[i]);
+        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
+    }
+
+    for (i = 0; i < 16; ++i) {
+        if (qemu_st_helpers[i] == 0) {
+            continue;
+        }
+
+        /* May as well align the trampoline.  */
+        tramp = (uintptr_t)s->code_ptr;
+        while (tramp & 15) {
+            tcg_out_nop(s);
+            tramp += 4;
+        }
+        qemu_st_trampoline[i] = tramp;
+
+        /* Find the retaddr argument.  For 32-bit, this may be past the
+           last argument register, and need passing on the stack.  */
+        ra = (TCG_REG_O4
+              + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS)
+              + (TCG_TARGET_REG_BITS == 32 && (i & MO_SIZE) == MO_64));
+
+        /* Set the retaddr operand.  */
+        if (ra >= TCG_REG_O6) {
+            tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK,
+                       TCG_TARGET_CALL_STACK_OFFSET);
+            ra = TCG_REG_G1;
+        }
+        tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);
+        /* Set the env operand.  */
+        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);
+        /* Tail call.  */
+        tcg_out_calli(s, qemu_st_helpers[i]);
+        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);
+    }
+}
+#endif
+
 /* Generate global QEMU prologue and epilogue code */
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
@@ -838,28 +930,13 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     tcg_out_nop(s);
 
     /* No epilogue required.  We issue ret + restore directly in the TB.  */
+
+#ifdef CONFIG_SOFTMMU
+    build_trampolines(s);
+#endif
 }
 
 #if defined(CONFIG_SOFTMMU)
-
-/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
-   int mmu_idx) */
-static const void * const qemu_ld_helpers[4] = {
-    helper_ldb_mmu,
-    helper_ldw_mmu,
-    helper_ldl_mmu,
-    helper_ldq_mmu,
-};
-
-/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
-   uintxx_t val, int mmu_idx) */
-static const void * const qemu_st_helpers[4] = {
-    helper_stb_mmu,
-    helper_stw_mmu,
-    helper_stl_mmu,
-    helper_stq_mmu,
-};
-
 /* Perform the TLB load and compare.
 
    Inputs:
@@ -966,8 +1043,9 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
     TCGReg addrlo, datalo, datahi, addr_reg;
     TCGMemOp s_bits = memop & MO_SIZE;
 #if defined(CONFIG_SOFTMMU)
-    TCGReg addrhi;
-    int memi, n;
+    TCGReg addrhi, param;
+    uintptr_t func;
+    int memi;
     uint32_t *label_ptr[2];
 #endif
 
@@ -1025,46 +1103,39 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
         *label_ptr[0] |= INSN_OFF19((unsigned long)s->code_ptr -
                                     (unsigned long)label_ptr[0]);
     }
-    n = 0;
-    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[n++], TCG_AREG0);
+
+    param = TCG_REG_O1;
     if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
-        tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], addrhi);
+        tcg_out_mov(s, TCG_TYPE_REG, param++, addrhi);
     }
-    tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], addrlo);
+    tcg_out_mov(s, TCG_TYPE_REG, param++, addrlo);
 
-    /* qemu_ld_helper[s_bits](arg0, arg1) */
-    tcg_out_calli(s, (uintptr_t)qemu_ld_helpers[s_bits]);
+    /* We use the helpers to extend SB and SW data, leaving the case
+       of SL needing explicit extending below.  */
+    if ((memop & ~MO_BSWAP) == MO_SL) {
+        func = qemu_ld_trampoline[memop & ~MO_SIGN];
+    } else {
+        func = qemu_ld_trampoline[memop];
+    }
+    assert(func != 0);
+    tcg_out_calli(s, func);
     /* delay slot */
-    tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[n], memi);
-
-    n = tcg_target_call_oarg_regs[0];
-    /* datalo = sign_extend(arg0) */
-    switch (memop & MO_SSIZE) {
-    case MO_SB:
-        /* Recall that SRA sign extends from bit 31 through bit 63.  */
-        tcg_out_arithi(s, datalo, n, 24, SHIFT_SLL);
-        tcg_out_arithi(s, datalo, datalo, 24, SHIFT_SRA);
-        break;
-    case MO_SW:
-        tcg_out_arithi(s, datalo, n, 16, SHIFT_SLL);
-        tcg_out_arithi(s, datalo, datalo, 16, SHIFT_SRA);
-        break;
+    tcg_out_movi(s, TCG_TYPE_I32, param, memi);
+
+    switch (memop & ~MO_BSWAP) {
     case MO_SL:
-        tcg_out_arithi(s, datalo, n, 0, SHIFT_SRA);
+        tcg_out_arithi(s, datalo, TCG_REG_O0, 0, SHIFT_SRA);
         break;
     case MO_Q:
         if (TCG_TARGET_REG_BITS == 32) {
-            tcg_out_mov(s, TCG_TYPE_REG, datahi, n);
-            tcg_out_mov(s, TCG_TYPE_REG, datalo, n + 1);
+            tcg_out_mov(s, TCG_TYPE_REG, datahi, TCG_REG_O0);
+            tcg_out_mov(s, TCG_TYPE_REG, datalo, TCG_REG_O1);
             break;
         }
         /* FALLTHRU */
-    case MO_UB:
-    case MO_UW:
-    case MO_UL:
     default:
         /* mov */
-        tcg_out_mov(s, TCG_TYPE_REG, datalo, n);
+        tcg_out_mov(s, TCG_TYPE_REG, datalo, TCG_REG_O0);
         break;
     }
 
@@ -1099,8 +1170,9 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGMemOp memop)
     TCGReg addrlo, datalo, datahi, addr_reg;
     TCGMemOp s_bits = memop & MO_SIZE;
 #if defined(CONFIG_SOFTMMU)
-    TCGReg addrhi, datafull;
-    int memi, n;
+    TCGReg addrhi, datafull, param;
+    uintptr_t func;
+    int memi;
     uint32_t *label_ptr;
 #endif
 
@@ -1135,21 +1207,21 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGMemOp memop)
 
     /* TLB Miss.  */
 
-    n = 0;
-    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[n++], TCG_AREG0);
+    param = TCG_REG_O1;
     if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
-        tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], addrhi);
+        tcg_out_mov(s, TCG_TYPE_REG, param++, addrhi);
     }
-    tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], addrlo);
+    tcg_out_mov(s, TCG_TYPE_REG, param++, addrlo);
     if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
-        tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datahi);
+        tcg_out_mov(s, TCG_TYPE_REG, param++, datahi);
     }
-    tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datalo);
+    tcg_out_mov(s, TCG_TYPE_REG, param++, datalo);
 
-    /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
-    tcg_out_calli(s, (uintptr_t)qemu_st_helpers[s_bits]);
+    func = qemu_st_trampoline[memop];
+    assert(func != 0);
+    tcg_out_calli(s, func);
     /* delay slot */
-    tcg_out_movi(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n], memi);
+    tcg_out_movi(s, TCG_TYPE_REG, param, memi);
 
     *label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
                              (unsigned long)label_ptr);
commit a8b12c108c364587213396c3cd3e22d740f87e2e
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 6 15:01:14 2013 -0700

    tcg-sparc: Tidy tcg_out_tlb_load interface
    
    Pass address registers explicitly, rather than as indicies of args[].
    It's two argument registers either way.  Use more TCGReg as appropriate.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 57e4222..6531c30 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -863,8 +863,7 @@ static const void * const qemu_st_helpers[4] = {
 /* Perform the TLB load and compare.
 
    Inputs:
-   ADDRLO_IDX contains the index into ARGS of the low part of the
-   address; the high part of the address is at ADDR_LOW_IDX+1.
+   ADDRLO and ADDRHI contain the possible two parts of the address.
 
    MEM_INDEX and S_BITS are the memory context and log2 size of the load.
 
@@ -874,20 +873,19 @@ static const void * const qemu_st_helpers[4] = {
    The result of the TLB comparison is in %[ix]cc.  The sanitized address
    is in the returned register, maybe %o0.  The TLB addend is in %o1.  */
 
-static int tcg_out_tlb_load(TCGContext *s, int addrlo_idx, int mem_index,
-                            TCGMemOp s_bits, const TCGArg *args, int which)
+static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
+                               int mem_index, TCGMemOp s_bits, int which)
 {
-    const int addrlo = args[addrlo_idx];
-    const int r0 = TCG_REG_O0;
-    const int r1 = TCG_REG_O1;
-    const int r2 = TCG_REG_O2;
-    int addr = addrlo;
+    const TCGReg r0 = TCG_REG_O0;
+    const TCGReg r1 = TCG_REG_O1;
+    const TCGReg r2 = TCG_REG_O2;
+    TCGReg addr = addrlo;
     int tlb_ofs;
 
     if (TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 64) {
         /* Assemble the 64-bit address in R0.  */
         tcg_out_arithi(s, r0, addrlo, 0, SHIFT_SRL);
-        tcg_out_arithi(s, r1, args[addrlo_idx + 1], 32, SHIFT_SLLX);
+        tcg_out_arithi(s, r1, addrhi, 32, SHIFT_SLLX);
         tcg_out_arith(s, r0, r0, r1, ARITH_OR);
         addr = r0;
     }
@@ -965,24 +963,23 @@ static const int qemu_st_opc[16] = {
 
 static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
 {
-    int addrlo_idx = 1, datalo, datahi, addr_reg;
+    TCGReg addrlo, datalo, datahi, addr_reg;
     TCGMemOp s_bits = memop & MO_SIZE;
 #if defined(CONFIG_SOFTMMU)
-    int memi_idx, memi, n;
+    TCGReg addrhi;
+    int memi, n;
     uint32_t *label_ptr[2];
 #endif
 
-    datahi = datalo = args[0];
-    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
-        datahi = args[1];
-        addrlo_idx = 2;
-    }
+    datalo = *args++;
+    datahi = (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64 ? *args++ : 0);
+    addr_reg = addrlo = *args++;
 
 #if defined(CONFIG_SOFTMMU)
-    memi_idx = addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
-    memi = args[memi_idx];
+    addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
+    memi = *args++;
 
-    addr_reg = tcg_out_tlb_load(s, addrlo_idx, memi, s_bits, args,
+    addr_reg = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
                                 offsetof(CPUTLBEntry, addr_read));
 
     if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
@@ -1031,11 +1028,9 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
     n = 0;
     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[n++], TCG_AREG0);
     if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
-        tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
-                    args[addrlo_idx + 1]);
+        tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], addrhi);
     }
-    tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
-                args[addrlo_idx]);
+    tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], addrlo);
 
     /* qemu_ld_helper[s_bits](arg0, arg1) */
     tcg_out_calli(s, (uintptr_t)qemu_ld_helpers[s_bits]);
@@ -1076,7 +1071,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
     *label_ptr[1] |= INSN_OFF19((unsigned long)s->code_ptr -
                                 (unsigned long)label_ptr[1]);
 #else
-    addr_reg = args[addrlo_idx];
     if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
         tcg_out_arithi(s, TCG_REG_T1, addr_reg, 0, SHIFT_SRL);
         addr_reg = TCG_REG_T1;
@@ -1102,24 +1096,23 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
 
 static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGMemOp memop)
 {
-    int addrlo_idx = 1, datalo, datahi, addr_reg;
+    TCGReg addrlo, datalo, datahi, addr_reg;
     TCGMemOp s_bits = memop & MO_SIZE;
 #if defined(CONFIG_SOFTMMU)
-    int memi_idx, memi, n, datafull;
+    TCGReg addrhi, datafull;
+    int memi, n;
     uint32_t *label_ptr;
 #endif
 
-    datahi = datalo = args[0];
-    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
-        datahi = args[1];
-        addrlo_idx = 2;
-    }
+    datalo = *args++;
+    datahi = (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64 ? *args++ : 0);
+    addr_reg = addrlo = *args++;
 
 #if defined(CONFIG_SOFTMMU)
-    memi_idx = addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
-    memi = args[memi_idx];
+    addrhi = (TARGET_LONG_BITS > TCG_TARGET_REG_BITS ? *args++ : 0);
+    memi = *args++;
 
-    addr_reg = tcg_out_tlb_load(s, addrlo_idx, memi, s_bits, args,
+    addr_reg = tcg_out_tlb_load(s, addrlo, addrhi, memi, s_bits,
                                 offsetof(CPUTLBEntry, addr_write));
 
     datafull = datalo;
@@ -1145,11 +1138,9 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGMemOp memop)
     n = 0;
     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[n++], TCG_AREG0);
     if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) {
-        tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
-                    args[addrlo_idx + 1]);
+        tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], addrhi);
     }
-    tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
-                args[addrlo_idx]);
+    tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], addrlo);
     if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datahi);
     }
@@ -1163,7 +1154,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGMemOp memop)
     *label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
                              (unsigned long)label_ptr);
 #else
-    addr_reg = args[addrlo_idx];
     if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
         tcg_out_arithi(s, TCG_REG_T1, addr_reg, 0, SHIFT_SRL);
         addr_reg = TCG_REG_T1;
commit eef0d9e740be3fb3b8226d8dffb0871455d45ce5
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Sep 3 20:12:01 2013 -0700

    tcg-sparc: Use TCGMemOp within qemu_ldst routines
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index e5a5e02..57e4222 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -875,7 +875,7 @@ static const void * const qemu_st_helpers[4] = {
    is in the returned register, maybe %o0.  The TLB addend is in %o1.  */
 
 static int tcg_out_tlb_load(TCGContext *s, int addrlo_idx, int mem_index,
-                            int s_bits, const TCGArg *args, int which)
+                            TCGMemOp s_bits, const TCGArg *args, int which)
 {
     const int addrlo = args[addrlo_idx];
     const int r0 = TCG_REG_O0;
@@ -934,32 +934,46 @@ static int tcg_out_tlb_load(TCGContext *s, int addrlo_idx, int mem_index,
 }
 #endif /* CONFIG_SOFTMMU */
 
-static const int qemu_ld_opc[8] = {
-#ifdef TARGET_WORDS_BIGENDIAN
-    LDUB, LDUH, LDUW, LDX, LDSB, LDSH, LDSW, LDX
-#else
-    LDUB, LDUH_LE, LDUW_LE, LDX_LE, LDSB, LDSH_LE, LDSW_LE, LDX_LE
-#endif
+static const int qemu_ld_opc[16] = {
+    [MO_UB]   = LDUB,
+    [MO_SB]   = LDSB,
+
+    [MO_BEUW] = LDUH,
+    [MO_BESW] = LDSH,
+    [MO_BEUL] = LDUW,
+    [MO_BESL] = LDSW,
+    [MO_BEQ]  = LDX,
+
+    [MO_LEUW] = LDUH_LE,
+    [MO_LESW] = LDSH_LE,
+    [MO_LEUL] = LDUW_LE,
+    [MO_LESL] = LDSW_LE,
+    [MO_LEQ]  = LDX_LE,
 };
 
-static const int qemu_st_opc[4] = {
-#ifdef TARGET_WORDS_BIGENDIAN
-    STB, STH, STW, STX
-#else
-    STB, STH_LE, STW_LE, STX_LE
-#endif
+static const int qemu_st_opc[16] = {
+    [MO_UB]   = STB,
+
+    [MO_BEUW] = STH,
+    [MO_BEUL] = STW,
+    [MO_BEQ]  = STX,
+
+    [MO_LEUW] = STH_LE,
+    [MO_LEUL] = STW_LE,
+    [MO_LEQ]  = STX_LE,
 };
 
-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
+static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, TCGMemOp memop)
 {
     int addrlo_idx = 1, datalo, datahi, addr_reg;
+    TCGMemOp s_bits = memop & MO_SIZE;
 #if defined(CONFIG_SOFTMMU)
-    int memi_idx, memi, s_bits, n;
+    int memi_idx, memi, n;
     uint32_t *label_ptr[2];
 #endif
 
     datahi = datalo = args[0];
-    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
+    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         datahi = args[1];
         addrlo_idx = 2;
     }
@@ -967,12 +981,11 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
 #if defined(CONFIG_SOFTMMU)
     memi_idx = addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
     memi = args[memi_idx];
-    s_bits = sizeop & 3;
 
     addr_reg = tcg_out_tlb_load(s, addrlo_idx, memi, s_bits, args,
                                 offsetof(CPUTLBEntry, addr_read));
 
-    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
+    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         int reg64;
 
         /* bne,pn %[xi]cc, label0 */
@@ -984,7 +997,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
         /* TLB Hit.  */
         /* Load all 64-bits into an O/G register.  */
         reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
-        tcg_out_ldst_rr(s, reg64, addr_reg, TCG_REG_O1, qemu_ld_opc[sizeop]);
+        tcg_out_ldst_rr(s, reg64, addr_reg, TCG_REG_O1, qemu_ld_opc[memop]);
 
         /* Move the two 32-bit pieces into the destination registers.  */
         tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
@@ -1006,7 +1019,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
         tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
                       | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
         /* delay slot */
-        tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_O1, qemu_ld_opc[sizeop]);
+        tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_O1, qemu_ld_opc[memop]);
     }
 
     /* TLB Miss.  */
@@ -1031,29 +1044,29 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
 
     n = tcg_target_call_oarg_regs[0];
     /* datalo = sign_extend(arg0) */
-    switch (sizeop) {
-    case 0 | 4:
+    switch (memop & MO_SSIZE) {
+    case MO_SB:
         /* Recall that SRA sign extends from bit 31 through bit 63.  */
         tcg_out_arithi(s, datalo, n, 24, SHIFT_SLL);
         tcg_out_arithi(s, datalo, datalo, 24, SHIFT_SRA);
         break;
-    case 1 | 4:
+    case MO_SW:
         tcg_out_arithi(s, datalo, n, 16, SHIFT_SLL);
         tcg_out_arithi(s, datalo, datalo, 16, SHIFT_SRA);
         break;
-    case 2 | 4:
+    case MO_SL:
         tcg_out_arithi(s, datalo, n, 0, SHIFT_SRA);
         break;
-    case 3:
+    case MO_Q:
         if (TCG_TARGET_REG_BITS == 32) {
             tcg_out_mov(s, TCG_TYPE_REG, datahi, n);
             tcg_out_mov(s, TCG_TYPE_REG, datalo, n + 1);
             break;
         }
         /* FALLTHRU */
-    case 0:
-    case 1:
-    case 2:
+    case MO_UB:
+    case MO_UW:
+    case MO_UL:
     default:
         /* mov */
         tcg_out_mov(s, TCG_TYPE_REG, datalo, n);
@@ -1068,12 +1081,12 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
         tcg_out_arithi(s, TCG_REG_T1, addr_reg, 0, SHIFT_SRL);
         addr_reg = TCG_REG_T1;
     }
-    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
+    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
 
         tcg_out_ldst_rr(s, reg64, addr_reg,
                         (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
-                        qemu_ld_opc[sizeop]);
+                        qemu_ld_opc[memop]);
 
         tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
         if (reg64 != datalo) {
@@ -1082,21 +1095,22 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
     } else {
         tcg_out_ldst_rr(s, datalo, addr_reg,
                         (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
-                        qemu_ld_opc[sizeop]);
+                        qemu_ld_opc[memop]);
     }
 #endif /* CONFIG_SOFTMMU */
 }
 
-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
+static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, TCGMemOp memop)
 {
     int addrlo_idx = 1, datalo, datahi, addr_reg;
+    TCGMemOp s_bits = memop & MO_SIZE;
 #if defined(CONFIG_SOFTMMU)
     int memi_idx, memi, n, datafull;
     uint32_t *label_ptr;
 #endif
 
     datahi = datalo = args[0];
-    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
+    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         datahi = args[1];
         addrlo_idx = 2;
     }
@@ -1105,11 +1119,11 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
     memi_idx = addrlo_idx + 1 + (TARGET_LONG_BITS > TCG_TARGET_REG_BITS);
     memi = args[memi_idx];
 
-    addr_reg = tcg_out_tlb_load(s, addrlo_idx, memi, sizeop, args,
+    addr_reg = tcg_out_tlb_load(s, addrlo_idx, memi, s_bits, args,
                                 offsetof(CPUTLBEntry, addr_write));
 
     datafull = datalo;
-    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
+    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         /* Reconstruct the full 64-bit value.  */
         tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
         tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
@@ -1124,7 +1138,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
     tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
                   | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
     /* delay slot */
-    tcg_out_ldst_rr(s, datafull, addr_reg, TCG_REG_O1, qemu_st_opc[sizeop]);
+    tcg_out_ldst_rr(s, datafull, addr_reg, TCG_REG_O1, qemu_st_opc[memop]);
 
     /* TLB Miss.  */
 
@@ -1136,13 +1150,13 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
     }
     tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
                 args[addrlo_idx]);
-    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
+    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datahi);
     }
     tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datalo);
 
     /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
-    tcg_out_calli(s, (uintptr_t)qemu_st_helpers[sizeop]);
+    tcg_out_calli(s, (uintptr_t)qemu_st_helpers[s_bits]);
     /* delay slot */
     tcg_out_movi(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n], memi);
 
@@ -1154,7 +1168,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
         tcg_out_arithi(s, TCG_REG_T1, addr_reg, 0, SHIFT_SRL);
         addr_reg = TCG_REG_T1;
     }
-    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
+    if (TCG_TARGET_REG_BITS == 32 && s_bits == MO_64) {
         tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
         tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
         tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
@@ -1162,7 +1176,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
     }
     tcg_out_ldst_rr(s, datalo, addr_reg,
                     (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
-                    qemu_st_opc[sizeop]);
+                    qemu_st_opc[memop]);
 #endif /* CONFIG_SOFTMMU */
 }
 
@@ -1342,42 +1356,42 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         break;
 
     case INDEX_op_qemu_ld8u:
-        tcg_out_qemu_ld(s, args, 0);
+        tcg_out_qemu_ld(s, args, MO_UB);
         break;
     case INDEX_op_qemu_ld8s:
-        tcg_out_qemu_ld(s, args, 0 | 4);
+        tcg_out_qemu_ld(s, args, MO_SB);
         break;
     case INDEX_op_qemu_ld16u:
-        tcg_out_qemu_ld(s, args, 1);
+        tcg_out_qemu_ld(s, args, MO_TEUW);
         break;
     case INDEX_op_qemu_ld16s:
-        tcg_out_qemu_ld(s, args, 1 | 4);
+        tcg_out_qemu_ld(s, args, MO_TESW);
         break;
     case INDEX_op_qemu_ld32:
 #if TCG_TARGET_REG_BITS == 64
     case INDEX_op_qemu_ld32u:
 #endif
-        tcg_out_qemu_ld(s, args, 2);
+        tcg_out_qemu_ld(s, args, MO_TEUL);
         break;
 #if TCG_TARGET_REG_BITS == 64
     case INDEX_op_qemu_ld32s:
-        tcg_out_qemu_ld(s, args, 2 | 4);
+        tcg_out_qemu_ld(s, args, MO_TESL);
         break;
 #endif
     case INDEX_op_qemu_ld64:
-        tcg_out_qemu_ld(s, args, 3);
+        tcg_out_qemu_ld(s, args, MO_TEQ);
         break;
     case INDEX_op_qemu_st8:
-        tcg_out_qemu_st(s, args, 0);
+        tcg_out_qemu_st(s, args, MO_UB);
         break;
     case INDEX_op_qemu_st16:
-        tcg_out_qemu_st(s, args, 1);
+        tcg_out_qemu_st(s, args, MO_TEUW);
         break;
     case INDEX_op_qemu_st32:
-        tcg_out_qemu_st(s, args, 2);
+        tcg_out_qemu_st(s, args, MO_TEUL);
         break;
     case INDEX_op_qemu_st64:
-        tcg_out_qemu_st(s, args, 3);
+        tcg_out_qemu_st(s, args, MO_TEQ);
         break;
 
 #if TCG_TARGET_REG_BITS == 64
commit a9c7d27bd189c8df698fac1369f718e7fa30d9d9
Author: Richard Henderson <rth at twiddle.net>
Date:   Mon Sep 9 21:07:09 2013 -0700

    tcg-sparc: Improve tcg_out_movi
    
    If bits 31:13 are zero, reduce the insn count by one.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 3ae014d..e5a5e02 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -384,37 +384,47 @@ static inline void tcg_out_movi_imm13(TCGContext *s, int ret, uint32_t arg)
     tcg_out_arithi(s, ret, TCG_REG_G0, arg, ARITH_OR);
 }
 
-static inline void tcg_out_movi_imm32(TCGContext *s, int ret, uint32_t arg)
+static void tcg_out_movi(TCGContext *s, TCGType type,
+                         TCGReg ret, tcg_target_long arg)
 {
-    if (check_fit_tl(arg, 13))
+    tcg_target_long hi, lo;
+
+    /* A 13-bit constant sign-extended to 64-bits.  */
+    if (check_fit_tl(arg, 13)) {
         tcg_out_movi_imm13(s, ret, arg);
-    else {
-        tcg_out_sethi(s, ret, arg);
-        if (arg & 0x3ff)
-            tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
+        return;
     }
-}
 
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
-                                TCGReg ret, tcg_target_long arg)
-{
-    /* All 32-bit constants, as well as 64-bit constants with
-       no high bits set go through movi_imm32.  */
+    /* A 32-bit constant, or 32-bit zero-extended to 64-bits.  */
     if (TCG_TARGET_REG_BITS == 32
         || type == TCG_TYPE_I32
-        || (arg & ~(tcg_target_long)0xffffffff) == 0) {
-        tcg_out_movi_imm32(s, ret, arg);
-    } else if (check_fit_tl(arg, 13)) {
-        /* A 13-bit constant sign-extended to 64-bits.  */
-        tcg_out_movi_imm13(s, ret, arg);
-    } else if (check_fit_tl(arg, 32)) {
-        /* A 32-bit constant sign-extended to 64-bits.  */
+        || (arg & ~0xffffffffu) == 0) {
+        tcg_out_sethi(s, ret, arg);
+        if (arg & 0x3ff) {
+            tcg_out_arithi(s, ret, ret, arg & 0x3ff, ARITH_OR);
+        }
+        return;
+    }
+
+    /* A 32-bit constant sign-extended to 64-bits.  */
+    if (check_fit_tl(arg, 32)) {
         tcg_out_sethi(s, ret, ~arg);
         tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
+        return;
+    }
+
+    /* A 64-bit constant decomposed into 2 32-bit pieces.  */
+    lo = (int32_t)arg;
+    if (check_fit_tl(lo, 13)) {
+        hi = (arg - lo) >> 31 >> 1;
+        tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
+        tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
+        tcg_out_arithi(s, ret, ret, lo, ARITH_ADD);
     } else {
-        tcg_out_movi_imm32(s, ret, arg >> (TCG_TARGET_REG_BITS / 2));
+        hi = arg >> 31 >> 1;
+        tcg_out_movi(s, TCG_TYPE_I32, ret, hi);
+        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T2, lo);
         tcg_out_arithi(s, ret, ret, 32, SHIFT_SLLX);
-        tcg_out_movi_imm32(s, TCG_REG_T2, arg);
         tcg_out_arith(s, ret, ret, TCG_REG_T2, ARITH_OR);
     }
 }
commit 1d0a60681a287e5697fa5b537dabb77f9c9c7f04
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Mar 4 15:24:04 2014 -0800

    tcg-sparc: Dont handle constant arguments to ext32 ops
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 30a2eaa..3ae014d 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -1405,18 +1405,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         c = ARITH_UDIVX;
         goto gen_arith;
     case INDEX_op_ext32s_i64:
-        if (const_args[1]) {
-            tcg_out_movi(s, TCG_TYPE_I64, args[0], (int32_t)args[1]);
-        } else {
-            tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
-        }
+        tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRA);
         break;
     case INDEX_op_ext32u_i64:
-        if (const_args[1]) {
-            tcg_out_movi_imm32(s, args[0], args[1]);
-        } else {
-            tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
-        }
+        tcg_out_arithi(s, args[0], args[1], 0, SHIFT_SRL);
         break;
 
     case INDEX_op_brcond_i64:
@@ -1527,8 +1519,8 @@ static const TCGTargetOpDef sparc_op_defs[] = {
     { INDEX_op_neg_i64, { "r", "rJ" } },
     { INDEX_op_not_i64, { "r", "rJ" } },
 
-    { INDEX_op_ext32s_i64, { "r", "ri" } },
-    { INDEX_op_ext32u_i64, { "r", "ri" } },
+    { INDEX_op_ext32s_i64, { "r", "r" } },
+    { INDEX_op_ext32u_i64, { "r", "r" } },
 
     { INDEX_op_brcond_i64, { "rZ", "rJ" } },
     { INDEX_op_setcond_i64, { "r", "rZ", "rJ" } },
commit 5f9eb02555e743bdeb2e22ea3c43a36cb9dad72f
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 19:22:15 2013 -0700

    tcg-sparc: Don't handle remainder
    
    The generic fallback is exactly what we implemented.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index ebcba71..30a2eaa 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -1289,15 +1289,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out_div32(s, args[0], args[1], args[2], const_args[2], 1);
         break;
 
-    case INDEX_op_rem_i32:
-    case INDEX_op_remu_i32:
-        tcg_out_div32(s, TCG_REG_T1, args[1], args[2], const_args[2],
-                      opc == INDEX_op_remu_i32);
-        tcg_out_arithc(s, TCG_REG_T1, TCG_REG_T1, args[2], const_args[2],
-                       ARITH_UMUL);
-        tcg_out_arith(s, args[0], args[1], TCG_REG_T1, ARITH_SUB);
-        break;
-
     case INDEX_op_brcond_i32:
         tcg_out_brcond_i32(s, args[2], args[0], args[1], const_args[1],
                            args[3]);
@@ -1413,14 +1404,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
     case INDEX_op_divu_i64:
         c = ARITH_UDIVX;
         goto gen_arith;
-    case INDEX_op_rem_i64:
-    case INDEX_op_remu_i64:
-        tcg_out_arithc(s, TCG_REG_T1, args[1], args[2], const_args[2],
-                       opc == INDEX_op_rem_i64 ? ARITH_SDIVX : ARITH_UDIVX);
-        tcg_out_arithc(s, TCG_REG_T1, TCG_REG_T1, args[2], const_args[2],
-                       ARITH_MULX);
-        tcg_out_arith(s, args[0], args[1], TCG_REG_T1, ARITH_SUB);
-        break;
     case INDEX_op_ext32s_i64:
         if (const_args[1]) {
             tcg_out_movi(s, TCG_TYPE_I64, args[0], (int32_t)args[1]);
@@ -1484,8 +1467,6 @@ static const TCGTargetOpDef sparc_op_defs[] = {
     { INDEX_op_mul_i32, { "r", "rZ", "rJ" } },
     { INDEX_op_div_i32, { "r", "rZ", "rJ" } },
     { INDEX_op_divu_i32, { "r", "rZ", "rJ" } },
-    { INDEX_op_rem_i32, { "r", "rZ", "rJ" } },
-    { INDEX_op_remu_i32, { "r", "rZ", "rJ" } },
     { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
     { INDEX_op_and_i32, { "r", "rZ", "rJ" } },
     { INDEX_op_andc_i32, { "r", "rZ", "rJ" } },
@@ -1532,8 +1513,6 @@ static const TCGTargetOpDef sparc_op_defs[] = {
     { INDEX_op_mul_i64, { "r", "rZ", "rJ" } },
     { INDEX_op_div_i64, { "r", "rZ", "rJ" } },
     { INDEX_op_divu_i64, { "r", "rZ", "rJ" } },
-    { INDEX_op_rem_i64, { "r", "rZ", "rJ" } },
-    { INDEX_op_remu_i64, { "r", "rZ", "rJ" } },
     { INDEX_op_sub_i64, { "r", "rZ", "rJ" } },
     { INDEX_op_and_i64, { "r", "rZ", "rJ" } },
     { INDEX_op_andc_i64, { "r", "rZ", "rJ" } },
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 00f3a18..202b88a 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -94,7 +94,7 @@ typedef enum {
 
 /* optional instructions */
 #define TCG_TARGET_HAS_div_i32		1
-#define TCG_TARGET_HAS_rem_i32		1
+#define TCG_TARGET_HAS_rem_i32		0
 #define TCG_TARGET_HAS_rot_i32          0
 #define TCG_TARGET_HAS_ext8s_i32        0
 #define TCG_TARGET_HAS_ext16s_i32       0
@@ -120,7 +120,7 @@ typedef enum {
 
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_div_i64          1
-#define TCG_TARGET_HAS_rem_i64          1
+#define TCG_TARGET_HAS_rem_i64          0
 #define TCG_TARGET_HAS_rot_i64          0
 #define TCG_TARGET_HAS_ext8s_i64        0
 #define TCG_TARGET_HAS_ext16s_i64       0
commit c8fc56cedda388641a3a5e1650db9a58c2280549
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 18:31:45 2013 -0700

    tcg-sparc: Use intptr_t as appropriate
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index fe34724..ebcba71 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -449,13 +449,14 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
     tcg_out_ldst(s, arg, arg1, arg2, (type == TCG_TYPE_I32 ? STW : STX));
 }
 
-static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
-                                  tcg_target_long arg)
+static inline void tcg_out_ld_ptr(TCGContext *s, TCGReg ret, uintptr_t arg)
 {
+    TCGReg base = TCG_REG_G0;
     if (!check_fit_tl(arg, 10)) {
         tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
+        base = ret;
     }
-    tcg_out_ld(s, TCG_TYPE_PTR, ret, ret, arg & 0x3ff);
+    tcg_out_ld(s, TCG_TYPE_PTR, ret, base, arg & 0x3ff);
 }
 
 static inline void tcg_out_sety(TCGContext *s, int rs)
@@ -1176,8 +1177,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
             tcg_out32(s, CALL | (old_insn & ~INSN_OP(-1)));
         } else {
             /* indirect jump method */
-            tcg_out_ld_ptr(s, TCG_REG_T1,
-                           (tcg_target_long)(s->tb_next + args[0]));
+            tcg_out_ld_ptr(s, TCG_REG_T1, (uintptr_t)(s->tb_next + args[0]));
             tcg_out_arithi(s, TCG_REG_G0, TCG_REG_T1, 0, JMPL);
         }
         tcg_out_nop(s);
@@ -1674,7 +1674,7 @@ static DebugFrame debug_frame = {
 
 void tcg_register_jit(void *buf, size_t buf_size)
 {
-    debug_frame.fde.func_start = (tcg_target_long) buf;
+    debug_frame.fde.func_start = (uintptr_t)buf;
     debug_frame.fde.func_len = buf_size;
 
     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
@@ -1683,14 +1683,12 @@ void tcg_register_jit(void *buf, size_t buf_size)
 void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
     uint32_t *ptr = (uint32_t *)jmp_addr;
-    tcg_target_long disp = (tcg_target_long)(addr - jmp_addr) >> 2;
+    uintptr_t disp = addr - jmp_addr;
 
     /* We can reach the entire address space for 32-bit.  For 64-bit
        the code_gen_buffer can't be larger than 2GB.  */
-    if (TCG_TARGET_REG_BITS == 64 && !check_fit_tl(disp, 30)) {
-        tcg_abort();
-    }
+    assert(disp == (int32_t)disp);
 
-    *ptr = CALL | (disp & 0x3fffffff);
+    *ptr = CALL | (uint32_t)disp >> 2;
     flush_icache_range(jmp_addr, jmp_addr + 4);
 }
commit aad2f06a7f03d06945e727373e4e059997220529
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 18:25:38 2013 -0700

    tcg-sparc: Tidy call+jump patterns
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 9d461a1..fe34724 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -783,6 +783,18 @@ static void tcg_out_addsub2(TCGContext *s, TCGArg rl, TCGArg rh,
     tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
 }
 
+static inline void tcg_out_calli(TCGContext *s, uintptr_t dest)
+{
+    intptr_t disp = dest - (uintptr_t)s->code_ptr;
+
+    if (disp == (int32_t)disp) {
+        tcg_out32(s, CALL | (uint32_t)disp >> 2);
+    } else {
+        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, dest & ~0xfff);
+        tcg_out_arithi(s, TCG_REG_O7, TCG_REG_T1, dest & 0xfff, JMPL);
+    }
+}
+
 /* Generate global QEMU prologue and epilogue code */
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
@@ -810,8 +822,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     }
 #endif
 
-    tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
-              INSN_RS2(TCG_REG_G0));
+    tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I1, 0, JMPL);
     /* delay slot */
     tcg_out_nop(s);
 
@@ -1003,9 +1014,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
                 args[addrlo_idx]);
 
     /* qemu_ld_helper[s_bits](arg0, arg1) */
-    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
-                           - (tcg_target_ulong)s->code_ptr) >> 2)
-                         & 0x3fffffff));
+    tcg_out_calli(s, (uintptr_t)qemu_ld_helpers[s_bits]);
     /* delay slot */
     tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[n], memi);
 
@@ -1122,9 +1131,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
     tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++], datalo);
 
     /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
-    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[sizeop]
-                           - (tcg_target_ulong)s->code_ptr) >> 2)
-                         & 0x3fffffff));
+    tcg_out_calli(s, (uintptr_t)qemu_st_helpers[sizeop]);
     /* delay slot */
     tcg_out_movi(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n], memi);
 
@@ -1156,8 +1163,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
     switch (opc) {
     case INDEX_op_exit_tb:
         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);
-        tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I7) |
-                  INSN_IMM13(8));
+        tcg_out_arithi(s, TCG_REG_G0, TCG_REG_I7, 8, JMPL);
         tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |
                       INSN_RS2(TCG_REG_G0));
         break;
@@ -1172,22 +1178,16 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
             /* indirect jump method */
             tcg_out_ld_ptr(s, TCG_REG_T1,
                            (tcg_target_long)(s->tb_next + args[0]));
-            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_T1) |
-                      INSN_RS2(TCG_REG_G0));
+            tcg_out_arithi(s, TCG_REG_G0, TCG_REG_T1, 0, JMPL);
         }
         tcg_out_nop(s);
         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
         break;
     case INDEX_op_call:
         if (const_args[0]) {
-            tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]
-                                   - (tcg_target_ulong)s->code_ptr) >> 2)
-                                 & 0x3fffffff));
+            tcg_out_calli(s, args[0]);
         } else {
-            tcg_out_ld_ptr(s, TCG_REG_T1,
-                           (tcg_target_long)(s->tb_next + args[0]));
-            tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_T1) |
-                      INSN_RS2(TCG_REG_G0));
+            tcg_out_arithi(s, TCG_REG_O7, args[0], 0, JMPL);
         }
         /* delay slot */
         tcg_out_nop(s);
commit d801a8f2ce9b89aef6006992ea1c573be817d80b
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 6 17:19:12 2013 -0700

    tcg-sparc: Fix tlb read
    
    We were computing the full address into %o0 and then not using it.
    Adjust some of the computation to rely less on having to pull immediate
    values into registers.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index b459886..9d461a1 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -480,19 +480,6 @@ static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
     }
 }
 
-static inline void tcg_out_andi(TCGContext *s, int rd, int rs,
-                                tcg_target_long val)
-{
-    if (val != 0) {
-        if (check_fit_tl(val, 13))
-            tcg_out_arithi(s, rd, rs, val, ARITH_AND);
-        else {
-            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T1, val);
-            tcg_out_arith(s, rd, rs, TCG_REG_T1, ARITH_AND);
-        }
-    }
-}
-
 static void tcg_out_div32(TCGContext *s, int rd, int rs1,
                           int val2, int val2const, int uns)
 {
@@ -880,17 +867,24 @@ static int tcg_out_tlb_load(TCGContext *s, int addrlo_idx, int mem_index,
         tcg_out_arithi(s, r0, addrlo, 0, SHIFT_SRL);
         tcg_out_arithi(s, r1, args[addrlo_idx + 1], 32, SHIFT_SLLX);
         tcg_out_arith(s, r0, r0, r1, ARITH_OR);
+        addr = r0;
     }
 
-    /* Shift the page number down to tlb-entry.  */
-    tcg_out_arithi(s, r1, addrlo,
-                   TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS, SHIFT_SRL);
+    /* Shift the page number down.  */
+    tcg_out_arithi(s, r1, addrlo, TARGET_PAGE_BITS, SHIFT_SRL);
 
     /* Mask out the page offset, except for the required alignment.  */
-    tcg_out_andi(s, r0, addr, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
+    tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,
+                 TARGET_PAGE_MASK | ((1 << s_bits) - 1));
+
+    /* Mask the tlb index.  */
+    tcg_out_arithi(s, r1, r1, CPU_TLB_SIZE - 1, ARITH_AND);
+    
+    /* Mask page, part 2.  */
+    tcg_out_arith(s, r0, addr, TCG_REG_T1, ARITH_AND);
 
-    /* Compute tlb index, modulo tlb size.  */
-    tcg_out_andi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
+    /* Shift the tlb index into place.  */
+    tcg_out_arithi(s, r1, r1, CPU_TLB_ENTRY_BITS, SHIFT_SLL);
 
     /* Relative to the current ENV.  */
     tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
@@ -898,8 +892,8 @@ static int tcg_out_tlb_load(TCGContext *s, int addrlo_idx, int mem_index,
     /* Find a base address that can load both tlb comparator and addend.  */
     tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);
     if (!check_fit_tl(tlb_ofs + sizeof(CPUTLBEntry), 13)) {
-        tcg_out_addi(s, r1, tlb_ofs);
-        tlb_ofs = 0;
+        tcg_out_addi(s, r1, tlb_ofs & ~0x3ff);
+        tlb_ofs &= 0x3ff;
     }
 
     /* Load the tlb comparator and the addend.  */
commit e7bc9004e729d4db1fdced5ccc09a322df53723f
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 6 14:20:00 2013 -0700

    tcg-sparc: Fix ld64 for 32-bit mode
    
    Since were not using an annulled branch, we need to put a nop
    in the delay slot.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index cbd1c91..b459886 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -963,6 +963,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
         label_ptr[0] = (uint32_t *)s->code_ptr;
         tcg_out_bpcc0(s, COND_NE, BPCC_PN
                       | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
+        tcg_out_nop(s);
 
         /* TLB Hit.  */
         /* Load all 64-bits into an O/G register.  */
commit 87f639629334c4592c3ba1011af0f691db1e7ed1
Merge: 087edb5 2bda660
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Mar 17 15:51:57 2014 +0000

    Merge remote-tracking branch 'remotes/kraxel/tags/pull-gtk-3' into staging
    
    gtk: warp bugfixes.
    gtk: Allow to activate grab-on-hover from the command line
    
    # gpg: Signature made Mon 17 Mar 2014 13:35:35 GMT using RSA key ID D3E87138
    # gpg: Good signature from "Gerd Hoffmann (work) <kraxel at redhat.com>"
    # gpg:                 aka "Gerd Hoffmann <gerd at kraxel.org>"
    # gpg:                 aka "Gerd Hoffmann (private) <kraxel at gmail.com>"
    
    * remotes/kraxel/tags/pull-gtk-3:
      gtk: Don't warp absolute pointer
      gtk: Fix mouse warping with gtk3
      gtk: Allow to activate grab-on-hover from the command line
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 2bda66028b4962c36d4eabe2995edab12df93691
Author: Cole Robinson <crobinso at redhat.com>
Date:   Thu Mar 13 15:30:24 2014 -0400

    gtk: Don't warp absolute pointer
    
    This matches the behavior of SDL, and makes the mouse usable when
    using -display gtk -vga qxl
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1051724
    Signed-off-by: Cole Robinson <crobinso at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/ui/gtk.c b/ui/gtk.c
index e2394ac..baabf86 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -340,6 +340,10 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
     GdkDeviceManager *mgr;
     gint x_root, y_root;
 
+    if (qemu_input_is_absolute()) {
+        return;
+    }
+
     dpy = gtk_widget_get_display(s->drawing_area);
     mgr = gdk_display_get_device_manager(dpy);
     gdk_window_get_root_coords(gtk_widget_get_window(s->drawing_area),
@@ -355,6 +359,10 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
     GtkDisplayState *s = container_of(dcl, GtkDisplayState, dcl);
     gint x_root, y_root;
 
+    if (qemu_input_is_absolute()) {
+        return;
+    }
+
     gdk_window_get_root_coords(gtk_widget_get_window(s->drawing_area),
                                x, y, &x_root, &y_root);
     gdk_display_warp_pointer(gtk_widget_get_display(s->drawing_area),
commit 298526fe92d0b35ea343f8ddcc3a1d54cb422494
Author: Cole Robinson <crobinso at redhat.com>
Date:   Thu Mar 13 15:30:23 2014 -0400

    gtk: Fix mouse warping with gtk3
    
    We were using the wrong coordinates, this fixes things to match the
    original gtk2 implementation.
    
    You can see this error in action by using -vga qxl, however even after this
    patch the mouse warps in small increments up and to the left, -7x and -3y
    pixels at a time, until the pointer is warped off the widget. I think it's
    a qxl bug, but the next patch covers it up.
    
    Signed-off-by: Cole Robinson <crobinso at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/ui/gtk.c b/ui/gtk.c
index 016804d..e2394ac 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -346,7 +346,7 @@ static void gd_mouse_set(DisplayChangeListener *dcl,
                                x, y, &x_root, &y_root);
     gdk_device_warp(gdk_device_manager_get_client_pointer(mgr),
                     gtk_widget_get_screen(s->drawing_area),
-                    x, y);
+                    x_root, y_root);
 }
 #else
 static void gd_mouse_set(DisplayChangeListener *dcl,
commit 881249c79292b6883ecf4bdb79c11cc7dbdb4878
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Mar 12 08:33:50 2014 +0100

    gtk: Allow to activate grab-on-hover from the command line
    
    As long as we have no persistent GTK configuration, this allows to
    enable the useful grab-on-hover feature already when starting the VM.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    
    [ kraxel: fix warning with CONFIG_GTK=n ]
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/include/ui/console.h b/include/ui/console.h
index 08a38ea..8a86617 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -345,6 +345,6 @@ int index_from_key(const char *key);
 
 /* gtk.c */
 void early_gtk_display_init(void);
-void gtk_display_init(DisplayState *ds, bool full_screen);
+void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover);
 
 #endif
diff --git a/qemu-options.hx b/qemu-options.hx
index 068da2d..ee5437b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -810,6 +810,7 @@ ETEXI
 DEF("display", HAS_ARG, QEMU_OPTION_display,
     "-display sdl[,frame=on|off][,alt_grab=on|off][,ctrl_grab=on|off]\n"
     "            [,window_close=on|off]|curses|none|\n"
+    "            gtk[,grab_on_hover=on|off]|\n"
     "            vnc=<display>[,<optargs>]\n"
     "                select display type\n", QEMU_ARCH_ALL)
 STEXI
@@ -833,6 +834,10 @@ graphics card, but its output will not be displayed to the QEMU
 user. This option differs from the -nographic option in that it
 only affects what is done with video output; -nographic also changes
 the destination of the serial and parallel port data.
+ at item gtk
+Display video output in a GTK window. This interface provides drop-down
+menus and other UI elements to configure and control the VM during
+runtime.
 @item vnc
 Start a VNC server on display <arg>
 @end table
diff --git a/ui/gtk.c b/ui/gtk.c
index c3ac448..016804d 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -1438,7 +1438,7 @@ static const DisplayChangeListenerOps dcl_ops = {
     .dpy_cursor_define = gd_cursor_define,
 };
 
-void gtk_display_init(DisplayState *ds, bool full_screen)
+void gtk_display_init(DisplayState *ds, bool full_screen, bool grab_on_hover)
 {
     GtkDisplayState *s = g_malloc0(sizeof(*s));
     char *filename;
@@ -1517,6 +1517,9 @@ void gtk_display_init(DisplayState *ds, bool full_screen)
     if (full_screen) {
         gtk_menu_item_activate(GTK_MENU_ITEM(s->full_screen_item));
     }
+    if (grab_on_hover) {
+        gtk_menu_item_activate(GTK_MENU_ITEM(s->grab_on_hover_item));
+    }
 
     register_displaychangelistener(&s->dcl);
 
diff --git a/vl.c b/vl.c
index 842e897..1feb0ff 100644
--- a/vl.c
+++ b/vl.c
@@ -143,6 +143,9 @@ int vga_interface_type = VGA_NONE;
 static int full_screen = 0;
 static int no_frame = 0;
 int no_quit = 0;
+#ifdef CONFIG_GTK
+static bool grab_on_hover;
+#endif
 CharDriverState *serial_hds[MAX_SERIAL_PORTS];
 CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
 CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
@@ -2276,6 +2279,25 @@ static DisplayType select_display(const char *p)
     } else if (strstart(p, "gtk", &opts)) {
 #ifdef CONFIG_GTK
         display = DT_GTK;
+        while (*opts) {
+            const char *nextopt;
+
+            if (strstart(opts, ",grab_on_hover=", &nextopt)) {
+                opts = nextopt;
+                if (strstart(opts, "on", &nextopt)) {
+                    grab_on_hover = true;
+                } else if (strstart(opts, "off", &nextopt)) {
+                    grab_on_hover = false;
+                } else {
+                    goto invalid_gtk_args;
+                }
+            } else {
+            invalid_gtk_args:
+                fprintf(stderr, "Invalid GTK option string: %s\n", p);
+                exit(1);
+            }
+            opts = nextopt;
+        }
 #else
         fprintf(stderr, "GTK support is disabled\n");
         exit(1);
@@ -4399,7 +4421,7 @@ int main(int argc, char **argv, char **envp)
 #endif
 #if defined(CONFIG_GTK)
     case DT_GTK:
-        gtk_display_init(ds, full_screen);
+        gtk_display_init(ds, full_screen, grab_on_hover);
         break;
 #endif
     default:
commit 087edb503afebf184f07078900efc26c73035e98
Merge: f4b11ee 025172d
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Mar 17 13:05:48 2014 +0000

    Merge remote-tracking branch 'remotes/bonzini/fixes-for-2.0' into staging
    
    * remotes/bonzini/fixes-for-2.0:
      vl.c: Output error on invalid machine type
      target-alpha: fix subl and s8subl indentation
      qemu-nbd: Fix coverity issues
      rules.mak: Fix per object libs extraction
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 025172d56e11ba3d86d0937933a23aab3b8606b1
Author: Miroslav Rezanina <mrezanin at redhat.com>
Date:   Fri Mar 14 13:06:54 2014 +0100

    vl.c: Output error on invalid machine type
    
    Output error message using qemu's error_report() function when user
    provides the invalid machine type on the command line. This also saves
    time to find what issue is when you downgrade from one version of qemu
    to another that doesn't support required machine type yet (the version
    user downgraded to have to have this patch applied too, of course).
    
    Signed-off-by: Miroslav Rezanina <mrezanin at redhat.com>
    [Replace printf with error_printf, suggested by Markus Armbruster. - Paolo]
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/vl.c b/vl.c
index 842e897..b363a21 100644
--- a/vl.c
+++ b/vl.c
@@ -2651,15 +2651,20 @@ static MachineClass *machine_parse(const char *name)
     if (mc) {
         return mc;
     }
-    printf("Supported machines are:\n");
-    for (el = machines; el; el = el->next) {
-        MachineClass *mc = el->data;
-        QEMUMachine *m = mc->qemu_machine;
-        if (m->alias) {
-            printf("%-20s %s (alias of %s)\n", m->alias, m->desc, m->name);
+    if (name && !is_help_option(name)) {
+        error_report("Unsupported machine type");
+        error_printf("Use -machine help to list supported machines!\n");
+    } else {
+        printf("Supported machines are:\n");
+        for (el = machines; el; el = el->next) {
+            MachineClass *mc = el->data;
+            QEMUMachine *m = mc->qemu_machine;
+            if (m->alias) {
+                printf("%-20s %s (alias of %s)\n", m->alias, m->desc, m->name);
+            }
+            printf("%-20s %s%s\n", m->name, m->desc,
+                   m->is_default ? " (default)" : "");
         }
-        printf("%-20s %s%s\n", m->name, m->desc,
-               m->is_default ? " (default)" : "");
     }
 
     g_slist_free(machines);
commit 83d1c8ae881e88d70cf23bc8007cf5739313d23c
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Sat Mar 15 19:33:15 2014 +0100

    target-alpha: fix subl and s8subl indentation
    
    Two missing braces, one close and one open, fabulously let the code
    compile.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index a9ef1a7..e7e319b 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1927,6 +1927,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                     else {
                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
+                    }
                 }
             }
             break;
@@ -1991,7 +1992,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
                 } else {
                     if (islit)
                         tcg_gen_movi_i64(cpu_ir[rc], -lit);
-                    else
+                    else {
                         tcg_gen_neg_i64(cpu_ir[rc], cpu_ir[rb]);
                         tcg_gen_ext32s_i64(cpu_ir[rc], cpu_ir[rc]);
                     }
commit 0c544d73bbb4c8612b7754a8e1c8b0c8af1617ff
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Mar 14 18:10:54 2014 +0100

    qemu-nbd: Fix coverity issues
    
    There are two issues in qemu-nbd: a missing return value check after
    calling accept(), and file descriptor leaks in nbd_client_thread.
    
    Reviewed-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/qemu-nbd.c b/qemu-nbd.c
index bdac1f3..899e67c 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -288,19 +288,19 @@ static void *nbd_client_thread(void *arg)
     ret = nbd_receive_negotiate(sock, NULL, &nbdflags,
                                 &size, &blocksize);
     if (ret < 0) {
-        goto out;
+        goto out_socket;
     }
 
     fd = open(device, O_RDWR);
     if (fd < 0) {
         /* Linux-only, we can use %m in printf.  */
         fprintf(stderr, "Failed to open %s: %m", device);
-        goto out;
+        goto out_socket;
     }
 
     ret = nbd_init(fd, sock, nbdflags, size, blocksize);
     if (ret < 0) {
-        goto out;
+        goto out_fd;
     }
 
     /* update partition table */
@@ -316,12 +316,16 @@ static void *nbd_client_thread(void *arg)
 
     ret = nbd_client(fd);
     if (ret) {
-        goto out;
+        goto out_fd;
     }
     close(fd);
     kill(getpid(), SIGTERM);
     return (void *) EXIT_SUCCESS;
 
+out_fd:
+    close(fd);
+out_socket:
+    closesocket(sock);
 out:
     kill(getpid(), SIGTERM);
     return (void *) EXIT_FAILURE;
@@ -355,6 +359,11 @@ static void nbd_accept(void *opaque)
     socklen_t addr_len = sizeof(addr);
 
     int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
+    if (fd < 0) {
+        perror("accept");
+        return;
+    }
+
     if (state >= TERMINATE) {
         close(fd);
         return;
commit 6295b98d7b767c377d88fa787ca62603a8ca6adb
Author: Fam Zheng <famz at redhat.com>
Date:   Fri Mar 14 10:21:05 2014 +0800

    rules.mak: Fix per object libs extraction
    
    Don't sort the extracted options, sort the objects.
    
    Reported-by: Christian Mahnke <cmahnke at googlemail.com>
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/rules.mak b/rules.mak
index 9dda9f7..5c454d8 100644
--- a/rules.mak
+++ b/rules.mak
@@ -23,8 +23,8 @@ QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(*D)/$(*F).d
 QEMU_INCLUDES += -I$(<D) -I$(@D)
 
 maybe-add = $(filter-out $1, $2) $1
-extract-libs = $(strip $(sort $(foreach o,$1,$($o-libs)) \
-                  $(foreach o,$(call expand-objs,$1),$($o-libs))))
+extract-libs = $(strip $(sort $(foreach o,$1,$($o-libs))) \
+                  $(foreach o,$(call expand-objs,$1),$($o-libs)))
 expand-objs = $(strip $(sort $(filter %.o,$1)) \
                   $(foreach o,$(filter %.mo,$1),$($o-objs)) \
                   $(filter-out %.o %.mo,$1))
commit f4b11eee2f562c23b3efc33b96ba4542c9ca81aa
Author: Fam Zheng <famz at redhat.com>
Date:   Mon Mar 17 09:35:22 2014 +0800

    Makefile: Fix "make clean"
    
    This fixes a dangerous bug: "make clean" after "make distclean" will
    delete every single file including those under .git, if you do in-tree
    build!
    
    Rationale: A first "make distclean" will unset $(DSOSUF), a following
    "make distclean" or "make clean" will find all the files and delete it.
    
    Fix it by explicitly typing the file extensions here, and combine
    multiple find invocations into one.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Message-id: 1395020122-4957-1-git-send-email-famz at redhat.com
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/Makefile b/Makefile
index bd9cd4f..ec74039 100644
--- a/Makefile
+++ b/Makefile
@@ -265,10 +265,7 @@ clean:
 # avoid old build problems by removing potentially incorrect old files
 	rm -f config.mak op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
 	rm -f qemu-options.def
-	find . -name '*.[oda]' -type f -exec rm -f {} +
-	find . -name '*.l[oa]' -type f -exec rm -f {} +
-	find . -name '*$(DSOSUF)' -type f -exec rm -f {} +
-	find . -name '*.mo' -type f -exec rm -f {} +
+	find . \( -name '*.l[oa]' -o -name '*.so' -o -name '*.dll' -o -name '*.mo' -o -name '*.[oda]' \) -type f -exec rm {} +
 	rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
 	rm -f fsdev/*.pod
 	rm -rf .libs */.libs
commit 6fffa26244737f8fd8641a21fee29bd6aa9fdff5
Merge: e638308 9c749e4
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sat Mar 15 18:22:10 2014 +0000

    Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-2014-03-15' into staging
    
    trivial patches for 2014-03-15
    
    # gpg: Signature made Sat 15 Mar 2014 09:54:30 GMT using RSA key ID 74F0C838
    # gpg: Good signature from "Michael Tokarev <mjt at tls.msk.ru>"
    # gpg:                 aka "Michael Tokarev <mjt at corpit.ru>"
    # gpg:                 aka "Michael Tokarev <mjt at debian.org>"
    # gpg: WARNING: This key is not certified with a trusted signature!
    # gpg:          There is no indication that the signature belongs to the owner.
    # Primary key fingerprint: 6EE1 95D1 886E 8FFB 810D  4324 457C E0A0 8044 65C5
    #      Subkey fingerprint: E190 8639 3B10 B51B AC2C  8B73 5253 C5AD 74F0 C838
    
    * remotes/mjt/tags/trivial-patches-2014-03-15:
      FSL eTSEC: Fix typo in rx ring
      scripts/make-release: Don't distribute .git directories
      configure: Don't use __int128_t for clang versions before 3.2
      audio: Add 'static' attributes to several variables
      tests: Fix 'make test' for i686 hosts (build regression)
      misc: Fix typos in comments
      Add qga/qapi-generated to .gitignore
      hw/timer/grlib_gptimer: Avoid integer overflows
      .travis.yml: add IRC notifications for build failures
      .travis.yml: trivial whitespace fixup
      .travis.yml: re-enable lttng user space trace test
      .travis.yml: add a new build target with non-core devlibs
      sasl: Avoid 'Could not find keytab file' in syslog
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit e6383080977ef1c761a00005ed533695acbe81e1
Merge: 4191d0e 582ab77
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sat Mar 15 18:03:15 2014 +0000

    Merge remote-tracking branch 'remotes/rth/tcg-aarch-6-2' into staging
    
    * remotes/rth/tcg-aarch-6-2:
      tcg-aarch64: Introduce tcg_out_insn_3405
      tcg-aarch64: Support div, rem
      tcg-aarch64: Support muluh, mulsh
      tcg-aarch64: Support add2, sub2
      tcg-aarch64: Support deposit
      tcg-aarch64: Use tcg_out_insn for setcond
      tcg-aarch64: Support movcond
      tcg-aarch64: Support andc, orc, eqv, not, neg
      tcg-aarch64: Handle constant operands to and, or, xor
      tcg-aarch64: Handle constant operands to add, sub, and compare
      tcg-aarch64: Implement mov with tcg_out_insn
      tcg-aarch64: Introduce tcg_out_insn_3401
      tcg-aarch64: Convert shift insns to tcg_out_insn
      tcg-aarch64: Introduce tcg_out_insn
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 9c749e4dbe65e61e159ad822a4110167c2c108fe
Author: Fabien Chouteau <chouteau at adacore.com>
Date:   Fri Mar 14 17:51:41 2014 +0100

    FSL eTSEC: Fix typo in rx ring
    
    Signed-off-by: Fabien Chouteau <chouteau at adacore.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c
index 26b71f6..e36cfbe 100644
--- a/hw/net/fsl_etsec/rings.c
+++ b/hw/net/fsl_etsec/rings.c
@@ -592,7 +592,7 @@ void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
 
                 /* TODO: Broadcast and Multicast */
 
-                if (bd.flags | BD_INTERRUPT) {
+                if (bd.flags & BD_INTERRUPT) {
                     /* Set RXFx */
                     etsec->regs[RSTAT].value |= 1 << (7 - ring_nbr);
 
@@ -601,7 +601,7 @@ void etsec_walk_rx_ring(eTSEC *etsec, int ring_nbr)
                 }
 
             } else {
-                if (bd.flags | BD_INTERRUPT) {
+                if (bd.flags & BD_INTERRUPT) {
                     /* Set IEVENT */
                     ievent_set(etsec, IEVENT_RXB);
                 }
commit 379e21c258d5faf0cd7c6f9208347726e14ae241
Author: Cole Robinson <crobinso at redhat.com>
Date:   Fri Mar 14 12:49:13 2014 -0400

    scripts/make-release: Don't distribute .git directories
    
    [crobinso at localhost qemu-2.0.0-rc0]$ find . -name .git
    ./dtc/.git
    ./pixman/.git
    
    This is already done for the rom submodules.
    
    https://bugs.launchpad.net/qemu/+bug/1224414
    Signed-off-by: Cole Robinson <crobinso at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/scripts/make-release b/scripts/make-release
index 196c755..186358d 100755
--- a/scripts/make-release
+++ b/scripts/make-release
@@ -18,7 +18,7 @@ git clone "${src}" ${destination}
 pushd ${destination}
 git checkout "v${version}"
 git submodule update --init
-rm -rf .git roms/*/.git
+rm -rf .git roms/*/.git dtc/.git pixman/.git
 popd
 tar cfj ${destination}.tar.bz2 ${destination}
 rm -rf ${destination}
commit a00f66ab9b3021e781695a73c579b6292501ab37
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Mar 7 10:43:38 2014 +0100

    configure: Don't use __int128_t for clang versions before 3.2
    
    Those versions don't fully support __int128_t.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/configure b/configure
index 8c2838e..2bc6b77 100755
--- a/configure
+++ b/configure
@@ -3822,6 +3822,11 @@ fi
 
 int128=no
 cat > $TMPC << EOF
+#if defined(__clang_major__) && defined(__clang_minor__)
+# if ((__clang_major__ < 3) || (__clang_major__ == 3) && (__clang_minor__ < 2))
+#  error __int128_t does not work in CLANG before 3.2
+# endif
+#endif
 __int128_t a;
 __uint128_t b;
 int main (void) {
commit 69df1c3c9d937a2b4f005a5bad0fefd21b39f383
Author: Stefan Weil <sw at weilnetz.de>
Date:   Wed Mar 5 22:21:32 2014 +0100

    audio: Add 'static' attributes to several variables
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/audio/fmopl.c b/hw/audio/fmopl.c
index f0a0234..290a224 100644
--- a/hw/audio/fmopl.c
+++ b/hw/audio/fmopl.c
@@ -223,13 +223,13 @@ static void *cur_chip = NULL;	/* current chip point */
 /* static OPLSAMPLE  *bufL,*bufR; */
 static OPL_CH *S_CH;
 static OPL_CH *E_CH;
-OPL_SLOT *SLOT7_1,*SLOT7_2,*SLOT8_1,*SLOT8_2;
+static OPL_SLOT *SLOT7_1, *SLOT7_2, *SLOT8_1, *SLOT8_2;
 
 static INT32 outd[1];
 static INT32 ams;
 static INT32 vib;
-INT32  *ams_table;
-INT32  *vib_table;
+static INT32 *ams_table;
+static INT32 *vib_table;
 static INT32 amsIncr;
 static INT32 vibIncr;
 static INT32 feedback2;		/* connect for SLOT 2 */
commit 6d4adef48dd6bb738474ab857f4fcb240ff9d2d6
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Mar 7 11:11:22 2014 +0100

    tests: Fix 'make test' for i686 hosts (build regression)
    
    'make test' is broken at least since commit
    baacf04799ace72a9c735dd9306a1ceaf305e7cf. Several source files were moved
    to util/, and some of them there split, so add the missing prefix and new
    files to fix the compiler and linker errors.
    
    There remain more issues, but these changes allow running the test on a
    Linux i686 host.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/tests/tcg/test_path.c b/tests/tcg/test_path.c
index a064eea..f8dd36a 100644
--- a/tests/tcg/test_path.c
+++ b/tests/tcg/test_path.c
@@ -1,12 +1,15 @@
 /* Test path override code */
 #define _GNU_SOURCE
 #include "config-host.h"
-#include "iov.c"
-#include "cutils.c"
-#include "path.c"
-#include "trace.c"
+#include "util/cutils.c"
+#include "util/hexdump.c"
+#include "util/iov.c"
+#include "util/path.c"
+#include "util/qemu-timer-common.c"
+#include "trace/control.c"
+#include "../trace/generated-events.c"
 #ifdef CONFIG_TRACE_SIMPLE
-#include "../trace/simple.c"
+#include "trace/simple.c"
 #endif
 
 #include <stdarg.h>
commit 3b163b0165b1eee51afd00aeae8d2ad41d05c2a2
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Mar 7 19:48:59 2014 +0100

    misc: Fix typos in comments
    
    Codespell found and fixed these new typos:
    
    * doesnt -> doesn't
    * funtion -> function
    * perfomance -> performance
    * remaing -> remaining
    
    A coding style issue (line too long) was fixed manually.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
index 100b6bf..719d227 100644
--- a/hw/intc/arm_gic_kvm.c
+++ b/hw/intc/arm_gic_kvm.c
@@ -148,7 +148,7 @@ typedef void (*vgic_translate_fn)(GICState *s, int irq, int cpu,
                                   uint32_t *field, bool to_kernel);
 
 /* synthetic translate function used for clear/set registers to completely
- * clear a setting using a clear-register before setting the remaing bits
+ * clear a setting using a clear-register before setting the remaining bits
  * using a set-register */
 static void translate_clear(GICState *s, int irq, int cpu,
                             uint32_t *field, bool to_kernel)
diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c
index 7760272..26b71f6 100644
--- a/hw/net/fsl_etsec/rings.c
+++ b/hw/net/fsl_etsec/rings.c
@@ -195,8 +195,8 @@ static void process_tx_fcb(eTSEC *etsec)
 
     /* 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. */
+        /* do IP4 checksum (TODO This function 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);
     }
diff --git a/target-arm/helper.c b/target-arm/helper.c
index aa5f22d..f0a1fd4 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -488,7 +488,7 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
 
 static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    /* Perfomance monitor registers user accessibility is controlled
+    /* Performance monitor registers user accessibility is controlled
      * by PMUSERENR.
      */
     if (arm_current_pl(env) == 0 && !env->cp15.c9_pmuserenr) {
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 63dde94..e14e304 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -2216,7 +2216,7 @@ static int bcd_cmp_mag(ppc_avr_t *a, ppc_avr_t *b)
         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 */
+            return 0; /* doesn't matter */
         } else if (dig_a > dig_b) {
             return 1;
         } else if (dig_a < dig_b) {
commit f214530f56b99be507e40cc261c9616ec84b72d3
Author: Gabriel L. Somlo <gsomlo at gmail.com>
Date:   Mon Mar 10 14:08:59 2014 -0400

    Add qga/qapi-generated to .gitignore
    
    The folder "qga/qapi-generated" shows up after building QEMU, and
    gets in the way during e.g. "git add ."; Add it to .gitignore to
    keep it from accidentally ending up in the wrong place.
    
    Signed-off-by: Gabriel Somlo <somlo at cmu.edu>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/.gitignore b/.gitignore
index ef7019f..de90463 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@
 libdis*
 libuser
 /linux-headers/asm
+/qga/qapi-generated
 /qapi-generated
 /qapi-types.[ch]
 /qapi-visit.[ch]
commit 9d5614d582d23ec96b167583557bf3f25f64f050
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:   Sun Feb 16 12:12:38 2014 +0100

    hw/timer/grlib_gptimer: Avoid integer overflows
    
    The GPTIMER uses 32-bit registers.  Use a 64-bit operation to get the
    ptimer count, otherwise we end up with a count of 0 for GPTIMER counter
    values of 0xffffffff.
    
    Use the GPTIMER counter value for tracing to avoid an overflow of the
    32-bit value passed to trace_grlib_gptimer_enable().
    
    Reviewed-by: Fabien Chouteau <chouteau at adacore.com>
    Signed-off-by: Sebastian Huber <sebastian.huber at embedded-brains.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c
index 74c16d6..7672d3a 100644
--- a/hw/timer/grlib_gptimer.c
+++ b/hw/timer/grlib_gptimer.c
@@ -106,9 +106,9 @@ static void grlib_gptimer_enable(GPTimer *timer)
     /* ptimer is triggered when the counter reach 0 but GPTimer is triggered at
        underflow. Set count + 1 to simulate the GPTimer behavior. */
 
-    trace_grlib_gptimer_enable(timer->id, timer->counter + 1);
+    trace_grlib_gptimer_enable(timer->id, timer->counter);
 
-    ptimer_set_count(timer->ptimer, timer->counter + 1);
+    ptimer_set_count(timer->ptimer, (uint64_t)timer->counter + 1);
     ptimer_run(timer->ptimer, 1);
 }
 
commit 39d16d29c81295be72dbae6e6bc7adc58deacb41
Author: Alex Bennée <alex.bennee at linaro.org>
Date:   Wed Mar 12 14:13:53 2014 +0000

    .travis.yml: add IRC notifications for build failures
    
    I'm trying to avoid spamming the IRC channel (not overly likely as
    builds take a while). So failure will always be reported but if the
    build continues to work then the IRC notifications will be quiet.
    
    Note any GitHub based repository with Travis enabled will use this
    notification. If it proves to be too spammy we may want to ask users not
    to use Travis themselves although this seems sub-optimal.
    
    Signed-off-by: Alex Bennée <alex.bennee at linaro.org>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/.travis.yml b/.travis.yml
index 0dbf2da..04da973 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,12 @@ python:
 compiler:
   - gcc
   - clang
+notifications:
+  irc:
+    channels:
+      - "irc.oftc.net#qemu"
+    on_success: change
+    on_failure: always
 env:
   global:
     - TEST_CMD="make check"
commit cc13eead53b2e4cf5f209fec606aebf11c1dc8a8
Author: Alex Bennée <alex.bennee at linaro.org>
Date:   Wed Mar 12 14:13:52 2014 +0000

    .travis.yml: trivial whitespace fixup
    
    Purely cosmetic but satisfies my OCD.
    
    Signed-off-by: Alex Bennée <alex.bennee at linaro.org>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/.travis.yml b/.travis.yml
index 1d78421..0dbf2da 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,23 +14,23 @@ env:
     - GUI_PKGS="libgtk-3-dev libvte-2.90-dev libsdl1.2-dev libpng12-dev libpixman-1-dev"
     - EXTRA_PKGS=""
   matrix:
-  - TARGETS=alpha-softmmu,alpha-linux-user
-  - TARGETS=arm-softmmu,arm-linux-user
-  - TARGETS=aarch64-softmmu,aarch64-linux-user
-  - TARGETS=cris-softmmu
-  - TARGETS=i386-softmmu,x86_64-softmmu
-  - TARGETS=lm32-softmmu
-  - TARGETS=m68k-softmmu
-  - TARGETS=microblaze-softmmu,microblazeel-softmmu
-  - TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu
-  - TARGETS=moxie-softmmu
-  - TARGETS=or32-softmmu,
-  - TARGETS=ppc-softmmu,ppc64-softmmu,ppcemb-softmmu
-  - TARGETS=s390x-softmmu
-  - TARGETS=sh4-softmmu,sh4eb-softmmu
-  - TARGETS=sparc-softmmu,sparc64-softmmu
-  - TARGETS=unicore32-softmmu
-  - TARGETS=xtensa-softmmu,xtensaeb-softmmu
+    - TARGETS=alpha-softmmu,alpha-linux-user
+    - TARGETS=arm-softmmu,arm-linux-user
+    - TARGETS=aarch64-softmmu,aarch64-linux-user
+    - TARGETS=cris-softmmu
+    - TARGETS=i386-softmmu,x86_64-softmmu
+    - TARGETS=lm32-softmmu
+    - TARGETS=m68k-softmmu
+    - TARGETS=microblaze-softmmu,microblazeel-softmmu
+    - TARGETS=mips-softmmu,mips64-softmmu,mips64el-softmmu,mipsel-softmmu
+    - TARGETS=moxie-softmmu
+    - TARGETS=or32-softmmu,
+    - TARGETS=ppc-softmmu,ppc64-softmmu,ppcemb-softmmu
+    - TARGETS=s390x-softmmu
+    - TARGETS=sh4-softmmu,sh4eb-softmmu
+    - TARGETS=sparc-softmmu,sparc64-softmmu
+    - TARGETS=unicore32-softmmu
+    - TARGETS=xtensa-softmmu,xtensaeb-softmmu
 before_install:
   - git submodule update --init --recursive
   - sudo apt-get update -qq
commit 86c3b20a5f654ae444ba6bd1a7b0516e0a17541d
Author: Alex Bennée <alex.bennee at linaro.org>
Date:   Wed Mar 12 14:13:51 2014 +0000

    .travis.yml: re-enable lttng user space trace test
    
    This build was disabled while the lttng tracing was broken. Stefan has
    recently submitted a pull request with it re-enabled.
    
    Signed-off-by: Alex Bennée <alex.bennee at linaro.org>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/.travis.yml b/.travis.yml
index 286cf62..1d78421 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -69,8 +69,7 @@ matrix:
            EXTRA_CONFIG="--enable-trace-backend=ftrace"
            TEST_CMD=""
       compiler: gcc
-    # This disabled make check for the ftrace backend which needs more setting up
-    # Currently broken on 12.04 due to mis-packaged liburcu and changed API, will be pulled.
-    #- env: TARGETS=i386-softmmu,x86_64-softmmu
-    #       EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
-    #       EXTRA_CONFIG="--enable-trace-backend=ust"
+    - env: TARGETS=i386-softmmu,x86_64-softmmu
+          EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
+          EXTRA_CONFIG="--enable-trace-backend=ust"
+      compiler: gcc
commit 6d585ca55999aec2bcfcbf04c3cbecbb952b7302
Author: Alex Bennée <alex.bennee at linaro.org>
Date:   Wed Mar 12 14:13:50 2014 +0000

    .travis.yml: add a new build target with non-core devlibs
    
    The current builds don't include all the features which are
    auto-detected and then disabled when the appropriate test packages don't
    exist. I've added another target that enables all known additional
    packages for increased coverage. I didn't add it to the core package
    list to reduce build time.
    
    Signed-off-by: Alex Bennée <alex.bennee at linaro.org>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/.travis.yml b/.travis.yml
index c7ff4da..286cf62 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -46,6 +46,10 @@ matrix:
     - env: TARGETS=i386-softmmu,x86_64-softmmu
            EXTRA_CONFIG="--enable-debug --enable-tcg-interpreter"
       compiler: gcc
+    # All the extra -dev packages
+    - env: TARGETS=i386-softmmu,x86_64-softmmu
+           EXTRA_PKGS="libaio-dev libcap-ng-dev libattr1-dev libbrlapi-dev uuid-dev libusb-1.0.0-dev"
+      compiler: gcc
     # Currently configure doesn't force --disable-pie
     - env: TARGETS=i386-softmmu,x86_64-softmmu
            EXTRA_CONFIG="--enable-gprof --enable-gcov --disable-pie"
commit dfb3804d478bce02350bdf87534dc7dd3d1ded51
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Fri Mar 14 15:39:36 2014 +0100

    sasl: Avoid 'Could not find keytab file' in syslog
    
    The "keytab" specification in "qemu.sasl" only makes sense if "gssapi" is
    selected in "mech_list". Even if the latter is not done (ie. "gssapi" is
    not selected), the cyrus-sasl library tries to open the specified keytab
    file, although nothing has a use for it outside the gssapi backend.
    
    Since the default keytab file "/etc/qemu/krb5.tab" is usually absent, the
    cyrus-sasl library emits a warning to syslog at startup, which tends to
    annoy users (who didn't ask for gssapi in the first place).
    
    Comment out the keytab specification per default.
    
    "qemu-doc.texi" already correctly explains how to use "mech_list: gssapi"
    together with "keytab:".
    
    See also:
    - upstream libvirt commit fe772f24,
    - Red Hat Bugzilla <https://bugzilla.redhat.com/show_bug.cgi?id=1018434>.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    ACKed-By: Cole Robinson <crobinso at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/qemu.sasl b/qemu.sasl
index 9dc8323..64fdef3 100644
--- a/qemu.sasl
+++ b/qemu.sasl
@@ -22,7 +22,9 @@ mech_list: digest-md5
 # Some older builds of MIT kerberos on Linux ignore this option &
 # instead need KRB5_KTNAME env var.
 # For modern Linux, and other OS, this should be sufficient
-keytab: /etc/qemu/krb5.tab
+#
+# There is no default value here, uncomment if you need this
+#keytab: /etc/qemu/krb5.tab
 
 # If using digest-md5 for username/passwds, then this is the file
 # containing the passwds. Use 'saslpasswd2 -a qemu [username]'
commit 4191d0eb414b14bcf3eab803095566aeb9b198f0
Merge: 03d5142 46dea41
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Mar 14 18:44:22 2014 +0000

    Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
    
    Block pull request
    
    # gpg: Signature made Fri 14 Mar 2014 16:12:14 GMT using RSA key ID 81AB73C8
    # gpg: Good signature from "Stefan Hajnoczi <stefanha at redhat.com>"
    # gpg:                 aka "Stefan Hajnoczi <stefanha at gmail.com>"
    # gpg: WARNING: This key is not certified with a trusted signature!
    # gpg:          There is no indication that the signature belongs to the owner.
    # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8
    
    * remotes/stefanha/tags/block-pull-request:
      qemu-iotests: remove 085 and 087 from 'quick' group
      qemu-iotests: add 083 NBD client disconnect tests
      tests: add nbd-fault-injector.py utility
      nbd: close socket if connection breaks
      block: Explicitly specify 'unsigned long long' for VHDX 64-bit constants
      blockdev: Refuse to open encrypted image unless paused
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 03d51428e2da0188a0adea00cbd713cc1e967e7a
Merge: 5d92c74 aa7a6a3
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Mar 14 18:17:25 2014 +0000

    Merge remote-tracking branch 'remotes/bonzini/scsi-next' into staging
    
    * remotes/bonzini/scsi-next:
      virtio-scsi: actually honor sense_size from configuration space
      scsi: Fix migration of scsi sense data
      spapr-vscsi: fix CRQ status
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 582ab779c5cf9c941909faa65e092b6b492e2da6
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 15:57:36 2013 -0700

    tcg-aarch64: Introduce tcg_out_insn_3405
    
    Cleaning up the implementation of tcg_out_movi at the same time.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 23bbe95..661a5af 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -289,6 +289,11 @@ typedef enum {
     I3404_ORRI      = 0x32000000,
     I3404_EORI      = 0x52000000,
 
+    /* Move wide immediate instructions.  */
+    I3405_MOVN      = 0x12800000,
+    I3405_MOVZ      = 0x52800000,
+    I3405_MOVK      = 0x72800000,
+
     /* Add/subtract shifted register instructions (without a shift).  */
     I3502_ADD       = 0x0b000000,
     I3502_ADDS      = 0x2b000000,
@@ -443,6 +448,15 @@ static void tcg_out_insn_3403(TCGContext *s, AArch64Insn insn, TCGType ext,
               | rn << 5 | rd);
 }
 
+/* This function is used for the Move (wide immediate) instruction group.
+   Note that SHIFT is a full shift count, not the 2 bit HW field. */
+static void tcg_out_insn_3405(TCGContext *s, AArch64Insn insn, TCGType ext,
+                              TCGReg rd, uint16_t half, unsigned shift)
+{
+    assert((shift & ~0x30) == 0);
+    tcg_out32(s, insn | ext << 31 | shift << (21 - 4) | half << 5 | rd);
+}
+
 /* This function is for both 3.5.2 (Add/Subtract shifted register), for
    the rare occasion when we actually want to supply a shift amount.  */
 static inline void tcg_out_insn_3502S(TCGContext *s, AArch64Insn insn,
@@ -513,38 +527,30 @@ static void tcg_out_movr_sp(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn)
     tcg_out_insn(s, 3401, ADDI, ext, rd, rn, 0);
 }
 
-static inline void tcg_out_movi_aux(TCGContext *s,
-                                    TCGReg rd, uint64_t value)
+static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
+                         tcg_target_long value)
 {
-    uint32_t half, base, shift, movk = 0;
-    /* construct halfwords of the immediate with MOVZ/MOVK with LSL */
-    /* using MOVZ 0x52800000 | extended reg.. */
-    base = (value > 0xffffffff) ? 0xd2800000 : 0x52800000;
+    AArch64Insn insn;
+
+    if (type == TCG_TYPE_I32) {
+        value = (uint32_t)value;
+    }
+
     /* count trailing zeros in 16 bit steps, mapping 64 to 0. Emit the
        first MOVZ with the half-word immediate skipping the zeros, with a shift
-       (LSL) equal to this number. Then morph all next instructions into MOVKs.
+       (LSL) equal to this number. Then all next instructions use MOVKs.
        Zero the processed half-word in the value, continue until empty.
        We build the final result 16bits at a time with up to 4 instructions,
        but do not emit instructions for 16bit zero holes. */
+    insn = I3405_MOVZ;
     do {
-        shift = ctz64(value) & (63 & -16);
-        half = (value >> shift) & 0xffff;
-        tcg_out32(s, base | movk | shift << 17 | half << 5 | rd);
-        movk = 0x20000000; /* morph next MOVZs into MOVKs */
+        unsigned shift = ctz64(value) & (63 & -16);
+        tcg_out_insn_3405(s, insn, shift >= 32, rd, value >> shift, shift);
         value &= ~(0xffffUL << shift);
+        insn = I3405_MOVK;
     } while (value);
 }
 
-static inline void tcg_out_movi(TCGContext *s, TCGType type,
-                                TCGReg rd, tcg_target_long value)
-{
-    if (type == TCG_TYPE_I64) {
-        tcg_out_movi_aux(s, rd, value);
-    } else {
-        tcg_out_movi_aux(s, rd, value & 0xffffffff);
-    }
-}
-
 static inline void tcg_out_ldst_r(TCGContext *s,
                                   enum aarch64_ldst_op_data op_data,
                                   enum aarch64_ldst_op_type op_type,
commit 8678b71ce61a337109bca27b058a9027ff1c24ae
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 15:29:18 2013 -0700

    tcg-aarch64: Support div, rem
    
    Clean up multiply at the same time.
    
    For remainder, generic code will produce mul+sub,
    whereas we can implement with msub.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 9c50820..23bbe95 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -313,6 +313,12 @@ typedef enum {
     I3508_RORV      = 0x1ac02c00,
     I3508_SMULH     = 0x9b407c00,
     I3508_UMULH     = 0x9bc07c00,
+    I3508_UDIV      = 0x1ac00800,
+    I3508_SDIV      = 0x1ac00c00,
+
+    /* Data-processing (3 source) instructions.  */
+    I3509_MADD      = 0x1b000000,
+    I3509_MSUB      = 0x1b008000,
 
     /* Logical shifted register instructions (without a shift).  */
     I3510_AND       = 0x0a000000,
@@ -467,6 +473,12 @@ static void tcg_out_insn_3506(TCGContext *s, AArch64Insn insn, TCGType ext,
               | tcg_cond_to_aarch64[c] << 12);
 }
 
+static void tcg_out_insn_3509(TCGContext *s, AArch64Insn insn, TCGType ext,
+                              TCGReg rd, TCGReg rn, TCGReg rm, TCGReg ra)
+{
+    tcg_out32(s, insn | ext << 31 | rm << 16 | ra << 10 | rn << 5 | rd);
+}
+
 
 static inline void tcg_out_ldst_9(TCGContext *s,
                                   enum aarch64_ldst_op_data op_data,
@@ -595,14 +607,6 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
                  arg, arg1, arg2);
 }
 
-static inline void tcg_out_mul(TCGContext *s, TCGType ext,
-                               TCGReg rd, TCGReg rn, TCGReg rm)
-{
-    /* Using MADD 0x1b000000 with Ra = wzr alias MUL 0x1b007c00 */
-    unsigned int base = ext ? 0x9b007c00 : 0x1b007c00;
-    tcg_out32(s, base | rm << 16 | rn << 5 | rd);
-}
-
 static inline void tcg_out_bfm(TCGContext *s, TCGType ext, TCGReg rd,
                                TCGReg rn, unsigned int a, unsigned int b)
 {
@@ -1395,7 +1399,27 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
     case INDEX_op_mul_i64:
     case INDEX_op_mul_i32:
-        tcg_out_mul(s, ext, a0, a1, a2);
+        tcg_out_insn(s, 3509, MADD, ext, a0, a1, a2, TCG_REG_XZR);
+        break;
+
+    case INDEX_op_div_i64:
+    case INDEX_op_div_i32:
+        tcg_out_insn(s, 3508, SDIV, ext, a0, a1, a2);
+        break;
+    case INDEX_op_divu_i64:
+    case INDEX_op_divu_i32:
+        tcg_out_insn(s, 3508, UDIV, ext, a0, a1, a2);
+        break;
+
+    case INDEX_op_rem_i64:
+    case INDEX_op_rem_i32:
+        tcg_out_insn(s, 3508, SDIV, ext, TCG_REG_TMP, a1, a2);
+        tcg_out_insn(s, 3509, MSUB, ext, a0, TCG_REG_TMP, a2, a1);
+        break;
+    case INDEX_op_remu_i64:
+    case INDEX_op_remu_i32:
+        tcg_out_insn(s, 3508, UDIV, ext, TCG_REG_TMP, a1, a2);
+        tcg_out_insn(s, 3509, MSUB, ext, a0, TCG_REG_TMP, a2, a1);
         break;
 
     case INDEX_op_shl_i64:
@@ -1626,6 +1650,14 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_sub_i64, { "r", "r", "rA" } },
     { INDEX_op_mul_i32, { "r", "r", "r" } },
     { INDEX_op_mul_i64, { "r", "r", "r" } },
+    { INDEX_op_div_i32, { "r", "r", "r" } },
+    { INDEX_op_div_i64, { "r", "r", "r" } },
+    { INDEX_op_divu_i32, { "r", "r", "r" } },
+    { INDEX_op_divu_i64, { "r", "r", "r" } },
+    { INDEX_op_rem_i32, { "r", "r", "r" } },
+    { INDEX_op_rem_i64, { "r", "r", "r" } },
+    { INDEX_op_remu_i32, { "r", "r", "r" } },
+    { INDEX_op_remu_i64, { "r", "r", "r" } },
     { INDEX_op_and_i32, { "r", "r", "rwL" } },
     { INDEX_op_and_i64, { "r", "r", "rL" } },
     { INDEX_op_or_i32, { "r", "r", "rwL" } },
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index c819095..988983e 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -39,8 +39,8 @@ typedef enum {
 #define TCG_TARGET_CALL_STACK_OFFSET    0
 
 /* optional instructions */
-#define TCG_TARGET_HAS_div_i32          0
-#define TCG_TARGET_HAS_rem_i32          0
+#define TCG_TARGET_HAS_div_i32          1
+#define TCG_TARGET_HAS_rem_i32          1
 #define TCG_TARGET_HAS_ext8s_i32        1
 #define TCG_TARGET_HAS_ext16s_i32       1
 #define TCG_TARGET_HAS_ext8u_i32        1
@@ -64,8 +64,8 @@ typedef enum {
 #define TCG_TARGET_HAS_muluh_i32        0
 #define TCG_TARGET_HAS_mulsh_i32        0
 
-#define TCG_TARGET_HAS_div_i64          0
-#define TCG_TARGET_HAS_rem_i64          0
+#define TCG_TARGET_HAS_div_i64          1
+#define TCG_TARGET_HAS_rem_i64          1
 #define TCG_TARGET_HAS_ext8s_i64        1
 #define TCG_TARGET_HAS_ext16s_i64       1
 #define TCG_TARGET_HAS_ext32s_i64       1
commit 1fcc9ddfb3c42431c027eb490613b51491202daa
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 15:03:27 2013 -0700

    tcg-aarch64: Support muluh, mulsh
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index b9dc6bb..9c50820 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -311,6 +311,8 @@ typedef enum {
     I3508_LSRV      = 0x1ac02400,
     I3508_ASRV      = 0x1ac02800,
     I3508_RORV      = 0x1ac02c00,
+    I3508_SMULH     = 0x9b407c00,
+    I3508_UMULH     = 0x9bc07c00,
 
     /* Logical shifted register instructions (without a shift).  */
     I3510_AND       = 0x0a000000,
@@ -1565,6 +1567,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
                         args[5], const_args[4], const_args[5], true);
         break;
 
+    case INDEX_op_muluh_i64:
+        tcg_out_insn(s, 3508, UMULH, TCG_TYPE_I64, a0, a1, a2);
+        break;
+    case INDEX_op_mulsh_i64:
+        tcg_out_insn(s, 3508, SMULH, TCG_TYPE_I64, a0, a1, a2);
+        break;
+
     case INDEX_op_mov_i64:
     case INDEX_op_mov_i32:
     case INDEX_op_movi_i64:
@@ -1694,6 +1703,9 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rwA", "rwMZ" } },
     { INDEX_op_sub2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } },
 
+    { INDEX_op_muluh_i64, { "r", "r", "r" } },
+    { INDEX_op_mulsh_i64, { "r", "r", "r" } },
+
     { -1 },
 };
 
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index f174ebd..c819095 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -89,8 +89,8 @@ typedef enum {
 #define TCG_TARGET_HAS_sub2_i64         1
 #define TCG_TARGET_HAS_mulu2_i64        0
 #define TCG_TARGET_HAS_muls2_i64        0
-#define TCG_TARGET_HAS_muluh_i64        0
-#define TCG_TARGET_HAS_mulsh_i64        0
+#define TCG_TARGET_HAS_muluh_i64        1
+#define TCG_TARGET_HAS_mulsh_i64        1
 
 enum {
     TCG_AREG0 = TCG_REG_X19,
commit c6e929e7847cb440dbda8ae562a1fb1fdc5f0c77
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 13:30:07 2013 -0700

    tcg-aarch64: Support add2, sub2
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 26b30cb..b9dc6bb 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -114,6 +114,7 @@ static inline void patch_reloc(uint8_t *code_ptr, int type,
 #define TCG_CT_CONST_AIMM 0x200
 #define TCG_CT_CONST_LIMM 0x400
 #define TCG_CT_CONST_ZERO 0x800
+#define TCG_CT_CONST_MONE 0x1000
 
 /* parse target specific constraints */
 static int target_parse_constraint(TCGArgConstraint *ct,
@@ -147,6 +148,9 @@ static int target_parse_constraint(TCGArgConstraint *ct,
     case 'L': /* Valid for logical immediate.  */
         ct->ct |= TCG_CT_CONST_LIMM;
         break;
+    case 'M': /* minus one */
+        ct->ct |= TCG_CT_CONST_MONE;
+        break;
     case 'Z': /* zero */
         ct->ct |= TCG_CT_CONST_ZERO;
         break;
@@ -204,6 +208,9 @@ static int tcg_target_const_match(tcg_target_long val,
     if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
         return 1;
     }
+    if ((ct & TCG_CT_CONST_MONE) && val == -1) {
+        return 1;
+    }
 
     return 0;
 }
@@ -291,6 +298,10 @@ typedef enum {
     /* Add/subtract shifted register instructions (with a shift).  */
     I3502S_ADD_LSL  = I3502_ADD,
 
+    /* Add/subtract with carry instructions.  */
+    I3503_ADC       = 0x1a000000,
+    I3503_SBC       = 0x5a000000,
+
     /* Conditional select instructions.  */
     I3506_CSEL      = 0x1a800000,
     I3506_CSINC     = 0x1a800400,
@@ -862,6 +873,47 @@ static void tcg_out_logicali(TCGContext *s, AArch64Insn insn, TCGType ext,
     tcg_out_insn_3404(s, insn, ext, rd, rn, ext, r, c);
 }
 
+static inline void tcg_out_addsub2(TCGContext *s, int ext, TCGReg rl,
+                                   TCGReg rh, TCGReg al, TCGReg ah,
+                                   tcg_target_long bl, tcg_target_long bh,
+                                   bool const_bl, bool const_bh, bool sub)
+{
+    TCGReg orig_rl = rl;
+    AArch64Insn insn;
+
+    if (rl == ah || (!const_bh && rl == bh)) {
+        rl = TCG_REG_TMP;
+    }
+
+    if (const_bl) {
+        insn = I3401_ADDSI;
+        if ((bl < 0) ^ sub) {
+            insn = I3401_SUBSI;
+            bl = -bl;
+        }
+        tcg_out_insn_3401(s, insn, ext, rl, al, bl);
+    } else {
+        tcg_out_insn_3502(s, sub ? I3502_SUBS : I3502_ADDS, ext, rl, al, bl);
+    }
+
+    insn = I3503_ADC;
+    if (const_bh) {
+        /* Note that the only two constants we support are 0 and -1, and
+           that SBC = rn + ~rm + c, so adc -1 is sbc 0, and vice-versa.  */
+        if ((bh != 0) ^ sub) {
+            insn = I3503_SBC;
+        }
+        bh = TCG_REG_XZR;
+    } else if (sub) {
+        insn = I3503_SBC;
+    }
+    tcg_out_insn_3503(s, insn, ext, rh, ah, bh);
+
+    if (rl != orig_rl) {
+        tcg_out_movr(s, ext, orig_rl, rl);
+    }
+}
+
 #ifdef CONFIG_SOFTMMU
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  *                                     int mmu_idx, uintptr_t ra)
@@ -1494,6 +1546,25 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_dep(s, ext, a0, REG0(2), args[3], args[4]);
         break;
 
+    case INDEX_op_add2_i32:
+        tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, REG0(2), REG0(3),
+                        (int32_t)args[4], args[5], const_args[4],
+                        const_args[5], false);
+        break;
+    case INDEX_op_add2_i64:
+        tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, REG0(2), REG0(3), args[4],
+                        args[5], const_args[4], const_args[5], false);
+        break;
+    case INDEX_op_sub2_i32:
+        tcg_out_addsub2(s, TCG_TYPE_I32, a0, a1, REG0(2), REG0(3),
+                        (int32_t)args[4], args[5], const_args[4],
+                        const_args[5], true);
+        break;
+    case INDEX_op_sub2_i64:
+        tcg_out_addsub2(s, TCG_TYPE_I64, a0, a1, REG0(2), REG0(3), args[4],
+                        args[5], const_args[4], const_args[5], true);
+        break;
+
     case INDEX_op_mov_i64:
     case INDEX_op_mov_i32:
     case INDEX_op_movi_i64:
@@ -1618,6 +1689,11 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
     { INDEX_op_deposit_i64, { "r", "0", "rZ" } },
 
+    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rwA", "rwMZ" } },
+    { INDEX_op_add2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } },
+    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rwA", "rwMZ" } },
+    { INDEX_op_sub2_i64, { "r", "r", "rZ", "rZ", "rA", "rMZ" } },
+
     { -1 },
 };
 
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 6bcd7ee..f174ebd 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -57,8 +57,8 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i32          0
 #define TCG_TARGET_HAS_deposit_i32      1
 #define TCG_TARGET_HAS_movcond_i32      1
-#define TCG_TARGET_HAS_add2_i32         0
-#define TCG_TARGET_HAS_sub2_i32         0
+#define TCG_TARGET_HAS_add2_i32         1
+#define TCG_TARGET_HAS_sub2_i32         1
 #define TCG_TARGET_HAS_mulu2_i32        0
 #define TCG_TARGET_HAS_muls2_i32        0
 #define TCG_TARGET_HAS_muluh_i32        0
@@ -85,8 +85,8 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i64          0
 #define TCG_TARGET_HAS_deposit_i64      1
 #define TCG_TARGET_HAS_movcond_i64      1
-#define TCG_TARGET_HAS_add2_i64         0
-#define TCG_TARGET_HAS_sub2_i64         0
+#define TCG_TARGET_HAS_add2_i64         1
+#define TCG_TARGET_HAS_sub2_i64         1
 #define TCG_TARGET_HAS_mulu2_i64        0
 #define TCG_TARGET_HAS_muls2_i64        0
 #define TCG_TARGET_HAS_muluh_i64        0
commit b3c56df769c4b53b91219a0993f8ab8fcb25857b
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 13:05:07 2013 -0700

    tcg-aarch64: Support deposit
    
    Also tidy the implementation of ubfm, sbfm, extr in order to share code.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index c38e3c0..26b30cb 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -269,6 +269,14 @@ typedef enum {
     I3401_SUBI      = 0x51000000,
     I3401_SUBSI     = 0x71000000,
 
+    /* Bitfield instructions.  */
+    I3402_BFM       = 0x33000000,
+    I3402_SBFM      = 0x13000000,
+    I3402_UBFM      = 0x53000000,
+
+    /* Extract instruction.  */
+    I3403_EXTR      = 0x13800000,
+
     /* Logical immediate instructions.  */
     I3404_ANDI      = 0x12000000,
     I3404_ORRI      = 0x32000000,
@@ -409,6 +417,13 @@ static void tcg_out_insn_3402(TCGContext *s, AArch64Insn insn, TCGType ext,
 
 #define tcg_out_insn_3404  tcg_out_insn_3402
 
+static void tcg_out_insn_3403(TCGContext *s, AArch64Insn insn, TCGType ext,
+                              TCGReg rd, TCGReg rn, TCGReg rm, int imms)
+{
+    tcg_out32(s, insn | ext << 31 | ext << 22 | rm << 16 | imms << 10
+              | rn << 5 | rd);
+}
+
 /* This function is for both 3.5.2 (Add/Subtract shifted register), for
    the rare occasion when we actually want to supply a shift amount.  */
 static inline void tcg_out_insn_3502S(TCGContext *s, AArch64Insn insn,
@@ -575,36 +590,35 @@ static inline void tcg_out_mul(TCGContext *s, TCGType ext,
     tcg_out32(s, base | rm << 16 | rn << 5 | rd);
 }
 
+static inline void tcg_out_bfm(TCGContext *s, TCGType ext, TCGReg rd,
+                               TCGReg rn, unsigned int a, unsigned int b)
+{
+    tcg_out_insn(s, 3402, BFM, ext, rd, rn, ext, a, b);
+}
+
 static inline void tcg_out_ubfm(TCGContext *s, TCGType ext, TCGReg rd,
                                 TCGReg rn, unsigned int a, unsigned int b)
 {
-    /* Using UBFM 0x53000000 Wd, Wn, a, b */
-    unsigned int base = ext ? 0xd3400000 : 0x53000000;
-    tcg_out32(s, base | a << 16 | b << 10 | rn << 5 | rd);
+    tcg_out_insn(s, 3402, UBFM, ext, rd, rn, ext, a, b);
 }
 
 static inline void tcg_out_sbfm(TCGContext *s, TCGType ext, TCGReg rd,
                                 TCGReg rn, unsigned int a, unsigned int b)
 {
-    /* Using SBFM 0x13000000 Wd, Wn, a, b */
-    unsigned int base = ext ? 0x93400000 : 0x13000000;
-    tcg_out32(s, base | a << 16 | b << 10 | rn << 5 | rd);
+    tcg_out_insn(s, 3402, SBFM, ext, rd, rn, ext, a, b);
 }
 
 static inline void tcg_out_extr(TCGContext *s, TCGType ext, TCGReg rd,
                                 TCGReg rn, TCGReg rm, unsigned int a)
 {
-    /* Using EXTR 0x13800000 Wd, Wn, Wm, a */
-    unsigned int base = ext ? 0x93c00000 : 0x13800000;
-    tcg_out32(s, base | rm << 16 | a << 10 | rn << 5 | rd);
+    tcg_out_insn(s, 3403, EXTR, ext, rd, rn, rm, a);
 }
 
 static inline void tcg_out_shl(TCGContext *s, TCGType ext,
                                TCGReg rd, TCGReg rn, unsigned int m)
 {
-    int bits, max;
-    bits = ext ? 64 : 32;
-    max = bits - 1;
+    int bits = ext ? 64 : 32;
+    int max = bits - 1;
     tcg_out_ubfm(s, ext, rd, rn, bits - (m & max), max - (m & max));
 }
 
@@ -632,12 +646,20 @@ static inline void tcg_out_rotr(TCGContext *s, TCGType ext,
 static inline void tcg_out_rotl(TCGContext *s, TCGType ext,
                                 TCGReg rd, TCGReg rn, unsigned int m)
 {
-    int bits, max;
-    bits = ext ? 64 : 32;
-    max = bits - 1;
+    int bits = ext ? 64 : 32;
+    int max = bits - 1;
     tcg_out_extr(s, ext, rd, rn, rn, bits - (m & max));
 }
 
+static inline void tcg_out_dep(TCGContext *s, TCGType ext, TCGReg rd,
+                               TCGReg rn, unsigned lsb, unsigned width)
+{
+    unsigned size = ext ? 64 : 32;
+    unsigned a = (size - lsb) & (size - 1);
+    unsigned b = width - 1;
+    tcg_out_bfm(s, ext, rd, rn, a, b);
+}
+
 static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg a,
                         tcg_target_long b, bool const_b)
 {
@@ -786,8 +808,7 @@ static inline void tcg_out_rev16(TCGContext *s, TCGType ext,
 static inline void tcg_out_sxt(TCGContext *s, TCGType ext, int s_bits,
                                TCGReg rd, TCGReg rn)
 {
-    /* using ALIASes SXTB 0x13001c00, SXTH 0x13003c00, SXTW 0x93407c00
-       of SBFM Xd, Xn, #0, #7|15|31 */
+    /* Using ALIASes SXTB, SXTH, SXTW, of SBFM Xd, Xn, #0, #7|15|31 */
     int bits = 8 * (1 << s_bits) - 1;
     tcg_out_sbfm(s, ext, rd, rn, 0, bits);
 }
@@ -795,8 +816,7 @@ static inline void tcg_out_sxt(TCGContext *s, TCGType ext, int s_bits,
 static inline void tcg_out_uxt(TCGContext *s, int s_bits,
                                TCGReg rd, TCGReg rn)
 {
-    /* using ALIASes UXTB 0x53001c00, UXTH 0x53003c00
-       of UBFM Wd, Wn, #0, #7|15 */
+    /* Using ALIASes UXTB, UXTH of UBFM Wd, Wn, #0, #7|15 */
     int bits = 8 * (1 << s_bits) - 1;
     tcg_out_ubfm(s, 0, rd, rn, 0, bits);
 }
@@ -1469,6 +1489,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_movr(s, 0, a0, a1);
         break;
 
+    case INDEX_op_deposit_i64:
+    case INDEX_op_deposit_i32:
+        tcg_out_dep(s, ext, a0, REG0(2), args[3], args[4]);
+        break;
+
     case INDEX_op_mov_i64:
     case INDEX_op_mov_i32:
     case INDEX_op_movi_i64:
@@ -1590,6 +1615,9 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_ext16u_i64, { "r", "r" } },
     { INDEX_op_ext32u_i64, { "r", "r" } },
 
+    { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
+    { INDEX_op_deposit_i64, { "r", "0", "rZ" } },
+
     { -1 },
 };
 
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 862600a..6bcd7ee 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -55,7 +55,7 @@ typedef enum {
 #define TCG_TARGET_HAS_eqv_i32          1
 #define TCG_TARGET_HAS_nand_i32         0
 #define TCG_TARGET_HAS_nor_i32          0
-#define TCG_TARGET_HAS_deposit_i32      0
+#define TCG_TARGET_HAS_deposit_i32      1
 #define TCG_TARGET_HAS_movcond_i32      1
 #define TCG_TARGET_HAS_add2_i32         0
 #define TCG_TARGET_HAS_sub2_i32         0
@@ -83,7 +83,7 @@ typedef enum {
 #define TCG_TARGET_HAS_eqv_i64          1
 #define TCG_TARGET_HAS_nand_i64         0
 #define TCG_TARGET_HAS_nor_i64          0
-#define TCG_TARGET_HAS_deposit_i64      0
+#define TCG_TARGET_HAS_deposit_i64      1
 #define TCG_TARGET_HAS_movcond_i64      1
 #define TCG_TARGET_HAS_add2_i64         0
 #define TCG_TARGET_HAS_sub2_i64         0
commit ed7a0aa8bc15a5278c8e76b83c359167c021ce86
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Sep 11 18:54:46 2013 -0700

    tcg-aarch64: Use tcg_out_insn for setcond
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 7f41c75..c38e3c0 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -654,14 +654,6 @@ static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg a,
     }
 }
 
-static inline void tcg_out_cset(TCGContext *s, TCGType ext,
-                                TCGReg rd, TCGCond c)
-{
-    /* Using CSET alias of CSINC 0x1a800400 Xd, XZR, XZR, invert(cond) */
-    unsigned int base = ext ? 0x9a9f07e0 : 0x1a9f07e0;
-    tcg_out32(s, base | tcg_cond_to_aarch64[tcg_invert_cond(c)] << 12 | rd);
-}
-
 static inline void tcg_out_goto(TCGContext *s, intptr_t target)
 {
     intptr_t offset = (target - (intptr_t)s->code_ptr) / 4;
@@ -1391,7 +1383,9 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         /* FALLTHRU */
     case INDEX_op_setcond_i64:
         tcg_out_cmp(s, ext, a1, a2, c2);
-        tcg_out_cset(s, 0, a0, args[3]);
+        /* Use CSET alias of CSINC Wd, WZR, WZR, invert(cond).  */
+        tcg_out_insn(s, 3506, CSINC, TCG_TYPE_I32, a0, TCG_REG_XZR,
+                     TCG_REG_XZR, tcg_invert_cond(args[3]));
         break;
 
     case INDEX_op_movcond_i32:
commit 04ce397b337cb1f81cde54d2b5dd7d6f0e08fffd
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Aug 9 23:58:19 2013 -0400

    tcg-aarch64: Support movcond
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 5850ae4..7f41c75 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -113,6 +113,7 @@ static inline void patch_reloc(uint8_t *code_ptr, int type,
 #define TCG_CT_CONST_IS32 0x100
 #define TCG_CT_CONST_AIMM 0x200
 #define TCG_CT_CONST_LIMM 0x400
+#define TCG_CT_CONST_ZERO 0x800
 
 /* parse target specific constraints */
 static int target_parse_constraint(TCGArgConstraint *ct,
@@ -146,6 +147,9 @@ static int target_parse_constraint(TCGArgConstraint *ct,
     case 'L': /* Valid for logical immediate.  */
         ct->ct |= TCG_CT_CONST_LIMM;
         break;
+    case 'Z': /* zero */
+        ct->ct |= TCG_CT_CONST_ZERO;
+        break;
     default:
         return -1;
     }
@@ -197,6 +201,9 @@ static int tcg_target_const_match(tcg_target_long val,
     if ((ct & TCG_CT_CONST_LIMM) && is_limm(val)) {
         return 1;
     }
+    if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
+        return 1;
+    }
 
     return 0;
 }
@@ -276,6 +283,10 @@ typedef enum {
     /* Add/subtract shifted register instructions (with a shift).  */
     I3502S_ADD_LSL  = I3502_ADD,
 
+    /* Conditional select instructions.  */
+    I3506_CSEL      = 0x1a800000,
+    I3506_CSINC     = 0x1a800400,
+
     /* Data-processing (2 source) instructions.  */
     I3508_LSLV      = 0x1ac02000,
     I3508_LSRV      = 0x1ac02400,
@@ -421,6 +432,13 @@ static void tcg_out_insn_3502(TCGContext *s, AArch64Insn insn, TCGType ext,
 #define tcg_out_insn_3508  tcg_out_insn_3502
 #define tcg_out_insn_3510  tcg_out_insn_3502
 
+static void tcg_out_insn_3506(TCGContext *s, AArch64Insn insn, TCGType ext,
+                              TCGReg rd, TCGReg rn, TCGReg rm, TCGCond c)
+{
+    tcg_out32(s, insn | ext << 31 | rm << 16 | rn << 5 | rd
+              | tcg_cond_to_aarch64[c] << 12);
+}
+
 
 static inline void tcg_out_ldst_9(TCGContext *s,
                                   enum aarch64_ldst_op_data op_data,
@@ -1154,6 +1172,10 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
     TCGArg a2 = args[2];
     int c2 = const_args[2];
 
+    /* Some operands are defined with "rZ" constraint, a register or
+       the zero register.  These need not actually test args[I] == 0.  */
+#define REG0(I)  (const_args[I] ? TCG_REG_XZR : (TCGReg)args[I])
+
     switch (opc) {
     case INDEX_op_exit_tb:
         tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_X0, a0);
@@ -1372,6 +1394,14 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_cset(s, 0, a0, args[3]);
         break;
 
+    case INDEX_op_movcond_i32:
+        a2 = (int32_t)a2;
+        /* FALLTHRU */
+    case INDEX_op_movcond_i64:
+        tcg_out_cmp(s, ext, a1, a2, c2);
+        tcg_out_insn(s, 3506, CSEL, ext, a0, REG0(3), REG0(4), args[5]);
+        break;
+
     case INDEX_op_qemu_ld8u:
         tcg_out_qemu_ld(s, args, 0 | 0);
         break;
@@ -1454,6 +1484,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         /* Opcode not implemented.  */
         tcg_abort();
     }
+
+#undef REG0
 }
 
 static const TCGTargetOpDef aarch64_op_defs[] = {
@@ -1528,6 +1560,8 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_brcond_i64, { "r", "rA" } },
     { INDEX_op_setcond_i32, { "r", "r", "rwA" } },
     { INDEX_op_setcond_i64, { "r", "r", "rA" } },
+    { INDEX_op_movcond_i32, { "r", "r", "rwA", "rZ", "rZ" } },
+    { INDEX_op_movcond_i64, { "r", "r", "rA", "rZ", "rZ" } },
 
     { INDEX_op_qemu_ld8u, { "r", "l" } },
     { INDEX_op_qemu_ld8s, { "r", "l" } },
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index f2945b5..862600a 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -56,7 +56,7 @@ typedef enum {
 #define TCG_TARGET_HAS_nand_i32         0
 #define TCG_TARGET_HAS_nor_i32          0
 #define TCG_TARGET_HAS_deposit_i32      0
-#define TCG_TARGET_HAS_movcond_i32      0
+#define TCG_TARGET_HAS_movcond_i32      1
 #define TCG_TARGET_HAS_add2_i32         0
 #define TCG_TARGET_HAS_sub2_i32         0
 #define TCG_TARGET_HAS_mulu2_i32        0
@@ -84,7 +84,7 @@ typedef enum {
 #define TCG_TARGET_HAS_nand_i64         0
 #define TCG_TARGET_HAS_nor_i64          0
 #define TCG_TARGET_HAS_deposit_i64      0
-#define TCG_TARGET_HAS_movcond_i64      0
+#define TCG_TARGET_HAS_movcond_i64      1
 #define TCG_TARGET_HAS_add2_i64         0
 #define TCG_TARGET_HAS_sub2_i64         0
 #define TCG_TARGET_HAS_mulu2_i64        0
commit 14b155ddc4358342fcec7891615a4303b698221c
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Aug 9 23:15:44 2013 -0400

    tcg-aarch64: Support andc, orc, eqv, not, neg
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 9a34a15..5850ae4 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -284,8 +284,11 @@ typedef enum {
 
     /* Logical shifted register instructions (without a shift).  */
     I3510_AND       = 0x0a000000,
+    I3510_BIC       = 0x0a200000,
     I3510_ORR       = 0x2a000000,
+    I3510_ORN       = 0x2a200000,
     I3510_EOR       = 0x4a000000,
+    I3510_EON       = 0x4a200000,
     I3510_ANDS      = 0x6a000000,
 } AArch64Insn;
 
@@ -1226,6 +1229,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         }
         break;
 
+    case INDEX_op_neg_i64:
+    case INDEX_op_neg_i32:
+        tcg_out_insn(s, 3502, SUB, ext, a0, TCG_REG_XZR, a1);
+        break;
+
     case INDEX_op_and_i32:
         a2 = (int32_t)a2;
         /* FALLTHRU */
@@ -1237,6 +1245,17 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         }
         break;
 
+    case INDEX_op_andc_i32:
+        a2 = (int32_t)a2;
+        /* FALLTHRU */
+    case INDEX_op_andc_i64:
+        if (c2) {
+            tcg_out_logicali(s, I3404_ANDI, ext, a0, a1, ~a2);
+        } else {
+            tcg_out_insn(s, 3510, BIC, ext, a0, a1, a2);
+        }
+        break;
+
     case INDEX_op_or_i32:
         a2 = (int32_t)a2;
         /* FALLTHRU */
@@ -1248,6 +1267,17 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         }
         break;
 
+    case INDEX_op_orc_i32:
+        a2 = (int32_t)a2;
+        /* FALLTHRU */
+    case INDEX_op_orc_i64:
+        if (c2) {
+            tcg_out_logicali(s, I3404_ORRI, ext, a0, a1, ~a2);
+        } else {
+            tcg_out_insn(s, 3510, ORN, ext, a0, a1, a2);
+        }
+        break;
+
     case INDEX_op_xor_i32:
         a2 = (int32_t)a2;
         /* FALLTHRU */
@@ -1259,6 +1289,22 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         }
         break;
 
+    case INDEX_op_eqv_i32:
+        a2 = (int32_t)a2;
+        /* FALLTHRU */
+    case INDEX_op_eqv_i64:
+        if (c2) {
+            tcg_out_logicali(s, I3404_EORI, ext, a0, a1, ~a2);
+        } else {
+            tcg_out_insn(s, 3510, EON, ext, a0, a1, a2);
+        }
+        break;
+
+    case INDEX_op_not_i64:
+    case INDEX_op_not_i32:
+        tcg_out_insn(s, 3510, ORN, ext, a0, TCG_REG_XZR, a1);
+        break;
+
     case INDEX_op_mul_i64:
     case INDEX_op_mul_i32:
         tcg_out_mul(s, ext, a0, a1, a2);
@@ -1455,6 +1501,17 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_or_i64, { "r", "r", "rL" } },
     { INDEX_op_xor_i32, { "r", "r", "rwL" } },
     { INDEX_op_xor_i64, { "r", "r", "rL" } },
+    { INDEX_op_andc_i32, { "r", "r", "rwL" } },
+    { INDEX_op_andc_i64, { "r", "r", "rL" } },
+    { INDEX_op_orc_i32, { "r", "r", "rwL" } },
+    { INDEX_op_orc_i64, { "r", "r", "rL" } },
+    { INDEX_op_eqv_i32, { "r", "r", "rwL" } },
+    { INDEX_op_eqv_i64, { "r", "r", "rL" } },
+
+    { INDEX_op_neg_i32, { "r", "r" } },
+    { INDEX_op_neg_i64, { "r", "r" } },
+    { INDEX_op_not_i32, { "r", "r" } },
+    { INDEX_op_not_i64, { "r", "r" } },
 
     { INDEX_op_shl_i32, { "r", "r", "ri" } },
     { INDEX_op_shr_i32, { "r", "r", "ri" } },
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 82ad919..f2945b5 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -47,12 +47,12 @@ typedef enum {
 #define TCG_TARGET_HAS_ext16u_i32       1
 #define TCG_TARGET_HAS_bswap16_i32      1
 #define TCG_TARGET_HAS_bswap32_i32      1
-#define TCG_TARGET_HAS_not_i32          0
-#define TCG_TARGET_HAS_neg_i32          0
+#define TCG_TARGET_HAS_not_i32          1
+#define TCG_TARGET_HAS_neg_i32          1
 #define TCG_TARGET_HAS_rot_i32          1
-#define TCG_TARGET_HAS_andc_i32         0
-#define TCG_TARGET_HAS_orc_i32          0
-#define TCG_TARGET_HAS_eqv_i32          0
+#define TCG_TARGET_HAS_andc_i32         1
+#define TCG_TARGET_HAS_orc_i32          1
+#define TCG_TARGET_HAS_eqv_i32          1
 #define TCG_TARGET_HAS_nand_i32         0
 #define TCG_TARGET_HAS_nor_i32          0
 #define TCG_TARGET_HAS_deposit_i32      0
@@ -75,12 +75,12 @@ typedef enum {
 #define TCG_TARGET_HAS_bswap16_i64      1
 #define TCG_TARGET_HAS_bswap32_i64      1
 #define TCG_TARGET_HAS_bswap64_i64      1
-#define TCG_TARGET_HAS_not_i64          0
-#define TCG_TARGET_HAS_neg_i64          0
+#define TCG_TARGET_HAS_not_i64          1
+#define TCG_TARGET_HAS_neg_i64          1
 #define TCG_TARGET_HAS_rot_i64          1
-#define TCG_TARGET_HAS_andc_i64         0
-#define TCG_TARGET_HAS_orc_i64          0
-#define TCG_TARGET_HAS_eqv_i64          0
+#define TCG_TARGET_HAS_andc_i64         1
+#define TCG_TARGET_HAS_orc_i64          1
+#define TCG_TARGET_HAS_eqv_i64          1
 #define TCG_TARGET_HAS_nand_i64         0
 #define TCG_TARGET_HAS_nor_i64          0
 #define TCG_TARGET_HAS_deposit_i64      0
commit e029f29385d0f9116c717d2e7a9c55d4bac8fe8a
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 11:27:03 2013 -0700

    tcg-aarch64: Handle constant operands to and, or, xor
    
    Handle a simplified set of logical immediates for the moment.
    
    The way gcc and binutils do it, with 52k worth of tables, and
    a binary search depth of log2(5334) = 13, seems slow for the
    most common cases.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 6816deb..9a34a15 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -112,6 +112,7 @@ static inline void patch_reloc(uint8_t *code_ptr, int type,
 
 #define TCG_CT_CONST_IS32 0x100
 #define TCG_CT_CONST_AIMM 0x200
+#define TCG_CT_CONST_LIMM 0x400
 
 /* parse target specific constraints */
 static int target_parse_constraint(TCGArgConstraint *ct,
@@ -142,6 +143,9 @@ static int target_parse_constraint(TCGArgConstraint *ct,
     case 'A': /* Valid for arithmetic immediate (positive or negative).  */
         ct->ct |= TCG_CT_CONST_AIMM;
         break;
+    case 'L': /* Valid for logical immediate.  */
+        ct->ct |= TCG_CT_CONST_LIMM;
+        break;
     default:
         return -1;
     }
@@ -156,6 +160,26 @@ static inline bool is_aimm(uint64_t val)
     return (val & ~0xfff) == 0 || (val & ~0xfff000) == 0;
 }
 
+static inline bool is_limm(uint64_t val)
+{
+    /* Taking a simplified view of the logical immediates for now, ignoring
+       the replication that can happen across the field.  Match bit patterns
+       of the forms
+           0....01....1
+           0..01..10..0
+       and their inverses.  */
+
+    /* Make things easier below, by testing the form with msb clear. */
+    if ((int64_t)val < 0) {
+        val = ~val;
+    }
+    if (val == 0) {
+        return false;
+    }
+    val += val & -val;
+    return (val & (val - 1)) == 0;
+}
+
 static int tcg_target_const_match(tcg_target_long val,
                                   const TCGArgConstraint *arg_ct)
 {
@@ -170,6 +194,9 @@ static int tcg_target_const_match(tcg_target_long val,
     if ((ct & TCG_CT_CONST_AIMM) && (is_aimm(val) || is_aimm(-val))) {
         return 1;
     }
+    if ((ct & TCG_CT_CONST_LIMM) && is_limm(val)) {
+        return 1;
+    }
 
     return 0;
 }
@@ -235,6 +262,11 @@ typedef enum {
     I3401_SUBI      = 0x51000000,
     I3401_SUBSI     = 0x71000000,
 
+    /* Logical immediate instructions.  */
+    I3404_ANDI      = 0x12000000,
+    I3404_ORRI      = 0x32000000,
+    I3404_EORI      = 0x52000000,
+
     /* Add/subtract shifted register instructions (without a shift).  */
     I3502_ADD       = 0x0b000000,
     I3502_ADDS      = 0x2b000000,
@@ -351,6 +383,18 @@ static void tcg_out_insn_3401(TCGContext *s, AArch64Insn insn, TCGType ext,
     tcg_out32(s, insn | ext << 31 | aimm << 10 | rn << 5 | rd);
 }
 
+/* This function can be used for both 3.4.2 (Bitfield) and 3.4.4
+   (Logical immediate).  Both insn groups have N, IMMR and IMMS fields
+   that feed the DecodeBitMasks pseudo function.  */
+static void tcg_out_insn_3402(TCGContext *s, AArch64Insn insn, TCGType ext,
+                              TCGReg rd, TCGReg rn, int n, int immr, int imms)
+{
+    tcg_out32(s, insn | ext << 31 | n << 22 | immr << 16 | imms << 10
+              | rn << 5 | rd);
+}
+
+#define tcg_out_insn_3404  tcg_out_insn_3402
+
 /* This function is for both 3.5.2 (Add/Subtract shifted register), for
    the rare occasion when we actually want to supply a shift amount.  */
 static inline void tcg_out_insn_3502S(TCGContext *s, AArch64Insn insn,
@@ -665,40 +709,6 @@ static inline void tcg_out_call(TCGContext *s, intptr_t target)
     }
 }
 
-/* encode a logical immediate, mapping user parameter
-   M=set bits pattern length to S=M-1 */
-static inline unsigned int
-aarch64_limm(unsigned int m, unsigned int r)
-{
-    assert(m > 0);
-    return r << 16 | (m - 1) << 10;
-}
-
-/* test a register against an immediate bit pattern made of
-   M set bits rotated right by R.
-   Examples:
-   to test a 32/64 reg against 0x00000007, pass M = 3,  R = 0.
-   to test a 32/64 reg against 0x000000ff, pass M = 8,  R = 0.
-   to test a 32bit reg against 0xff000000, pass M = 8,  R = 8.
-   to test a 32bit reg against 0xff0000ff, pass M = 16, R = 8.
- */
-static inline void tcg_out_tst(TCGContext *s, TCGType ext, TCGReg rn,
-                               unsigned int m, unsigned int r)
-{
-    /* using TST alias of ANDS XZR, Xn,#bimm64 0x7200001f */
-    unsigned int base = ext ? 0xf240001f : 0x7200001f;
-    tcg_out32(s, base | aarch64_limm(m, r) | rn << 5);
-}
-
-/* and a register with a bit pattern, similarly to TST, no flags change */
-static inline void tcg_out_andi(TCGContext *s, TCGType ext, TCGReg rd,
-                                TCGReg rn, unsigned int m, unsigned int r)
-{
-    /* using AND 0x12000000 */
-    unsigned int base = ext ? 0x92400000 : 0x12000000;
-    tcg_out32(s, base | aarch64_limm(m, r) | rn << 5 | rd);
-}
-
 static inline void tcg_out_ret(TCGContext *s)
 {
     /* emit RET { LR } */
@@ -788,6 +798,37 @@ static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd,
     }
 }
 
+/* This function is used for the Logical (immediate) instruction group.
+   The value of LIMM must satisfy IS_LIMM.  See the comment above about
+   only supporting simplified logical immediates.  */
+static void tcg_out_logicali(TCGContext *s, AArch64Insn insn, TCGType ext,
+                             TCGReg rd, TCGReg rn, uint64_t limm)
+{
+    unsigned h, l, r, c;
+
+    assert(is_limm(limm));
+
+    h = clz64(limm);
+    l = ctz64(limm);
+    if (l == 0) {
+        r = 0;                  /* form 0....01....1 */
+        c = ctz64(~limm) - 1;
+        if (h == 0) {
+            r = clz64(~limm);   /* form 1..10..01..1 */
+            c += r;
+        }
+    } else {
+        r = 64 - l;             /* form 1....10....0 or 0..01..10..0 */
+        c = r - h - 1;
+    }
+    if (ext == TCG_TYPE_I32) {
+        r &= 31;
+        c &= 31;
+    }
+
+    tcg_out_insn_3404(s, insn, ext, rd, rn, ext, r, c);
+}
+
 #ifdef CONFIG_SOFTMMU
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  *                                     int mmu_idx, uintptr_t ra)
@@ -879,9 +920,8 @@ static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg,
     /* Store the page mask part of the address and the low s_bits into X3.
        Later this allows checking for equality and alignment at the same time.
        X3 = addr_reg & (PAGE_MASK | ((1 << s_bits) - 1)) */
-    tcg_out_andi(s, (TARGET_LONG_BITS == 64), TCG_REG_X3, addr_reg,
-                 (TARGET_LONG_BITS - TARGET_PAGE_BITS) + s_bits,
-                 (TARGET_LONG_BITS - TARGET_PAGE_BITS));
+    tcg_out_logicali(s, I3404_ANDI, TARGET_LONG_BITS == 64, TCG_REG_X3,
+                     addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
     /* Add any "high bits" from the tlb offset to the env address into X2,
        to take advantage of the LSL12 form of the ADDI instruction.
        X2 = env + (tlb_offset & 0xfff000) */
@@ -1186,19 +1226,37 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         }
         break;
 
-    case INDEX_op_and_i64:
     case INDEX_op_and_i32:
-        tcg_out_insn(s, 3510, AND, ext, a0, a1, a2);
+        a2 = (int32_t)a2;
+        /* FALLTHRU */
+    case INDEX_op_and_i64:
+        if (c2) {
+            tcg_out_logicali(s, I3404_ANDI, ext, a0, a1, a2);
+        } else {
+            tcg_out_insn(s, 3510, AND, ext, a0, a1, a2);
+        }
         break;
 
-    case INDEX_op_or_i64:
     case INDEX_op_or_i32:
-        tcg_out_insn(s, 3510, ORR, ext, a0, a1, a2);
+        a2 = (int32_t)a2;
+        /* FALLTHRU */
+    case INDEX_op_or_i64:
+        if (c2) {
+            tcg_out_logicali(s, I3404_ORRI, ext, a0, a1, a2);
+        } else {
+            tcg_out_insn(s, 3510, ORR, ext, a0, a1, a2);
+        }
         break;
 
-    case INDEX_op_xor_i64:
     case INDEX_op_xor_i32:
-        tcg_out_insn(s, 3510, EOR, ext, a0, a1, a2);
+        a2 = (int32_t)a2;
+        /* FALLTHRU */
+    case INDEX_op_xor_i64:
+        if (c2) {
+            tcg_out_logicali(s, I3404_EORI, ext, a0, a1, a2);
+        } else {
+            tcg_out_insn(s, 3510, EOR, ext, a0, a1, a2);
+        }
         break;
 
     case INDEX_op_mul_i64:
@@ -1391,12 +1449,12 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_sub_i64, { "r", "r", "rA" } },
     { INDEX_op_mul_i32, { "r", "r", "r" } },
     { INDEX_op_mul_i64, { "r", "r", "r" } },
-    { INDEX_op_and_i32, { "r", "r", "r" } },
-    { INDEX_op_and_i64, { "r", "r", "r" } },
-    { INDEX_op_or_i32, { "r", "r", "r" } },
-    { INDEX_op_or_i64, { "r", "r", "r" } },
-    { INDEX_op_xor_i32, { "r", "r", "r" } },
-    { INDEX_op_xor_i64, { "r", "r", "r" } },
+    { INDEX_op_and_i32, { "r", "r", "rwL" } },
+    { INDEX_op_and_i64, { "r", "r", "rL" } },
+    { INDEX_op_or_i32, { "r", "r", "rwL" } },
+    { INDEX_op_or_i64, { "r", "r", "rL" } },
+    { INDEX_op_xor_i32, { "r", "r", "rwL" } },
+    { INDEX_op_xor_i64, { "r", "r", "rL" } },
 
     { INDEX_op_shl_i32, { "r", "r", "ri" } },
     { INDEX_op_shr_i32, { "r", "r", "ri" } },
commit 90f1cd9138deba50a6ff15a7f520c8e35ae870ac
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 09:56:14 2013 -0700

    tcg-aarch64: Handle constant operands to add, sub, and compare
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 9b6374d..6816deb 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -110,6 +110,9 @@ static inline void patch_reloc(uint8_t *code_ptr, int type,
     }
 }
 
+#define TCG_CT_CONST_IS32 0x100
+#define TCG_CT_CONST_AIMM 0x200
+
 /* parse target specific constraints */
 static int target_parse_constraint(TCGArgConstraint *ct,
                                    const char **pct_str)
@@ -133,6 +136,12 @@ static int target_parse_constraint(TCGArgConstraint *ct,
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_X3);
 #endif
         break;
+    case 'w': /* The operand should be considered 32-bit.  */
+        ct->ct |= TCG_CT_CONST_IS32;
+        break;
+    case 'A': /* Valid for arithmetic immediate (positive or negative).  */
+        ct->ct |= TCG_CT_CONST_AIMM;
+        break;
     default:
         return -1;
     }
@@ -142,14 +151,25 @@ static int target_parse_constraint(TCGArgConstraint *ct,
     return 0;
 }
 
-static inline int tcg_target_const_match(tcg_target_long val,
-                                         const TCGArgConstraint *arg_ct)
+static inline bool is_aimm(uint64_t val)
+{
+    return (val & ~0xfff) == 0 || (val & ~0xfff000) == 0;
+}
+
+static int tcg_target_const_match(tcg_target_long val,
+                                  const TCGArgConstraint *arg_ct)
 {
     int ct = arg_ct->ct;
 
     if (ct & TCG_CT_CONST) {
         return 1;
     }
+    if (ct & TCG_CT_CONST_IS32) {
+        val = (int32_t)val;
+    }
+    if ((ct & TCG_CT_CONST_AIMM) && (is_aimm(val) || is_aimm(-val))) {
+        return 1;
+    }
 
     return 0;
 }
@@ -553,10 +573,20 @@ static inline void tcg_out_rotl(TCGContext *s, TCGType ext,
     tcg_out_extr(s, ext, rd, rn, rn, bits - (m & max));
 }
 
-static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg rn, TCGReg rm)
+static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg a,
+                        tcg_target_long b, bool const_b)
 {
-    /* Using CMP alias SUBS wzr, Wn, Wm */
-    tcg_out_insn(s, 3502, SUBS, ext, TCG_REG_XZR, rn, rm);
+    if (const_b) {
+        /* Using CMP or CMN aliases.  */
+        if (b >= 0) {
+            tcg_out_insn(s, 3401, SUBSI, ext, TCG_REG_XZR, a, b);
+        } else {
+            tcg_out_insn(s, 3401, ADDSI, ext, TCG_REG_XZR, a, -b);
+        }
+    } else {
+        /* Using CMP alias SUBS wzr, Wn, Wm */
+        tcg_out_insn(s, 3502, SUBS, ext, TCG_REG_XZR, a, b);
+    }
 }
 
 static inline void tcg_out_cset(TCGContext *s, TCGType ext,
@@ -748,6 +778,16 @@ static inline void tcg_out_uxt(TCGContext *s, int s_bits,
     tcg_out_ubfm(s, 0, rd, rn, 0, bits);
 }
 
+static void tcg_out_addsubi(TCGContext *s, int ext, TCGReg rd,
+                            TCGReg rn, int64_t aimm)
+{
+    if (aimm >= 0) {
+        tcg_out_insn(s, 3401, ADDI, ext, rd, rn, aimm);
+    } else {
+        tcg_out_insn(s, 3401, SUBI, ext, rd, rn, -aimm);
+    }
+}
+
 #ifdef CONFIG_SOFTMMU
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  *                                     int mmu_idx, uintptr_t ra)
@@ -863,7 +903,7 @@ static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg,
                  (is_read ? offsetof(CPUTLBEntry, addr_read)
                   : offsetof(CPUTLBEntry, addr_write)));
     /* Perform the address comparison. */
-    tcg_out_cmp(s, (TARGET_LONG_BITS == 64), TCG_REG_X0, TCG_REG_X3);
+    tcg_out_cmp(s, (TARGET_LONG_BITS == 64), TCG_REG_X0, TCG_REG_X3, 0);
     *label_ptr = s->code_ptr;
     /* If not equal, we jump to the slow path. */
     tcg_out_goto_cond_noaddr(s, TCG_COND_NE);
@@ -1124,14 +1164,26 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
                      a0, a1, a2);
         break;
 
-    case INDEX_op_add_i64:
     case INDEX_op_add_i32:
-        tcg_out_insn(s, 3502, ADD, ext, a0, a1, a2);
+        a2 = (int32_t)a2;
+        /* FALLTHRU */
+    case INDEX_op_add_i64:
+        if (c2) {
+            tcg_out_addsubi(s, ext, a0, a1, a2);
+        } else {
+            tcg_out_insn(s, 3502, ADD, ext, a0, a1, a2);
+        }
         break;
 
-    case INDEX_op_sub_i64:
     case INDEX_op_sub_i32:
-        tcg_out_insn(s, 3502, SUB, ext, a0, a1, a2);
+        a2 = (int32_t)a2;
+        /* FALLTHRU */
+    case INDEX_op_sub_i64:
+        if (c2) {
+            tcg_out_addsubi(s, ext, a0, a1, -a2);
+        } else {
+            tcg_out_insn(s, 3502, SUB, ext, a0, a1, a2);
+        }
         break;
 
     case INDEX_op_and_i64:
@@ -1200,15 +1252,19 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         }
         break;
 
-    case INDEX_op_brcond_i64:
     case INDEX_op_brcond_i32:
-        tcg_out_cmp(s, ext, a0, a1);
+        a1 = (int32_t)a1;
+        /* FALLTHRU */
+    case INDEX_op_brcond_i64:
+        tcg_out_cmp(s, ext, a0, a1, const_args[1]);
         tcg_out_goto_label_cond(s, a2, args[3]);
         break;
 
-    case INDEX_op_setcond_i64:
     case INDEX_op_setcond_i32:
-        tcg_out_cmp(s, ext, a1, a2);
+        a2 = (int32_t)a2;
+        /* FALLTHRU */
+    case INDEX_op_setcond_i64:
+        tcg_out_cmp(s, ext, a1, a2, c2);
         tcg_out_cset(s, 0, a0, args[3]);
         break;
 
@@ -1329,10 +1385,10 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_st32_i64, { "r", "r" } },
     { INDEX_op_st_i64, { "r", "r" } },
 
-    { INDEX_op_add_i32, { "r", "r", "r" } },
-    { INDEX_op_add_i64, { "r", "r", "r" } },
-    { INDEX_op_sub_i32, { "r", "r", "r" } },
-    { INDEX_op_sub_i64, { "r", "r", "r" } },
+    { INDEX_op_add_i32, { "r", "r", "rwA" } },
+    { INDEX_op_add_i64, { "r", "r", "rA" } },
+    { INDEX_op_sub_i32, { "r", "r", "rwA" } },
+    { INDEX_op_sub_i64, { "r", "r", "rA" } },
     { INDEX_op_mul_i32, { "r", "r", "r" } },
     { INDEX_op_mul_i64, { "r", "r", "r" } },
     { INDEX_op_and_i32, { "r", "r", "r" } },
@@ -1353,10 +1409,10 @@ static const TCGTargetOpDef aarch64_op_defs[] = {
     { INDEX_op_rotl_i64, { "r", "r", "ri" } },
     { INDEX_op_rotr_i64, { "r", "r", "ri" } },
 
-    { INDEX_op_brcond_i32, { "r", "r" } },
-    { INDEX_op_setcond_i32, { "r", "r", "r" } },
-    { INDEX_op_brcond_i64, { "r", "r" } },
-    { INDEX_op_setcond_i64, { "r", "r", "r" } },
+    { INDEX_op_brcond_i32, { "r", "rwA" } },
+    { INDEX_op_brcond_i64, { "r", "rA" } },
+    { INDEX_op_setcond_i32, { "r", "r", "rwA" } },
+    { INDEX_op_setcond_i64, { "r", "r", "rA" } },
 
     { INDEX_op_qemu_ld8u, { "r", "l" } },
     { INDEX_op_qemu_ld8s, { "r", "l" } },
commit 7d11fc7c2b853fe01b5166a9de01ca94d0787b85
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 13 14:49:18 2013 -0700

    tcg-aarch64: Implement mov with tcg_out_insn
    
    Avoid the magic numbers in the current implementation.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index b5f19ad..9b6374d 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -376,13 +376,16 @@ static inline void tcg_out_ldst_12(TCGContext *s,
               | op_type << 20 | scaled_uimm << 10 | rn << 5 | rd);
 }
 
-static inline void tcg_out_movr(TCGContext *s, TCGType ext,
-                                TCGReg rd, TCGReg src)
+/* Register to register move using ORR (shifted register with no shift). */
+static void tcg_out_movr(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rm)
 {
-    /* register to register move using MOV (shifted register with no shift) */
-    /* using MOV 0x2a0003e0 | (shift).. */
-    unsigned int base = ext ? 0xaa0003e0 : 0x2a0003e0;
-    tcg_out32(s, base | src << 16 | rd);
+    tcg_out_insn(s, 3510, ORR, ext, rd, TCG_REG_XZR, rm);
+}
+
+/* Register to register move using ADDI (move to/from SP).  */
+static void tcg_out_movr_sp(TCGContext *s, TCGType ext, TCGReg rd, TCGReg rn)
+{
+    tcg_out_insn(s, 3401, ADDI, ext, rd, rn, 0);
 }
 
 static inline void tcg_out_movi_aux(TCGContext *s,
@@ -457,15 +460,6 @@ static inline void tcg_out_ldst(TCGContext *s, enum aarch64_ldst_op_data data,
     tcg_out_ldst_r(s, data, type, rd, rn, TCG_REG_TMP);
 }
 
-/* mov alias implemented with add immediate, useful to move to/from SP */
-static inline void tcg_out_movr_sp(TCGContext *s, TCGType ext,
-                                   TCGReg rd, TCGReg rn)
-{
-    /* using ADD 0x11000000 | (ext) | rn << 5 | rd */
-    unsigned int base = ext ? 0x91000000 : 0x11000000;
-    tcg_out32(s, base | rn << 5 | rd);
-}
-
 static inline void tcg_out_mov(TCGContext *s,
                                TCGType type, TCGReg ret, TCGReg arg)
 {
commit 096c46c0ff3ad1db6048373620b44bef19f8408f
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 13 14:37:08 2013 -0700

    tcg-aarch64: Introduce tcg_out_insn_3401
    
    This merges the implementation of tcg_out_addi and tcg_out_subi.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index b52519e..b5f19ad 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -209,6 +209,12 @@ enum aarch64_ldst_op_type { /* type of operation */
    use the section number of the architecture reference manual in which the
    instruction group is described.  */
 typedef enum {
+    /* Add/subtract immediate instructions.  */
+    I3401_ADDI      = 0x11000000,
+    I3401_ADDSI     = 0x31000000,
+    I3401_SUBI      = 0x51000000,
+    I3401_SUBSI     = 0x71000000,
+
     /* Add/subtract shifted register instructions (without a shift).  */
     I3502_ADD       = 0x0b000000,
     I3502_ADDS      = 0x2b000000,
@@ -313,6 +319,18 @@ static inline uint32_t tcg_in32(TCGContext *s)
 #define tcg_out_insn(S, FMT, OP, ...) \
     glue(tcg_out_insn_,FMT)(S, glue(glue(glue(I,FMT),_),OP), ## __VA_ARGS__)
 
+static void tcg_out_insn_3401(TCGContext *s, AArch64Insn insn, TCGType ext,
+                              TCGReg rd, TCGReg rn, uint64_t aimm)
+{
+    if (aimm > 0xfff) {
+        assert((aimm & 0xfff) == 0);
+        aimm >>= 12;
+        assert(aimm <= 0xfff);
+        aimm |= 1 << 12;  /* apply LSL 12 */
+    }
+    tcg_out32(s, insn | ext << 31 | aimm << 10 | rn << 5 | rd);
+}
+
 /* This function is for both 3.5.2 (Add/Subtract shifted register), for
    the rare occasion when we actually want to supply a shift amount.  */
 static inline void tcg_out_insn_3502S(TCGContext *s, AArch64Insn insn,
@@ -736,46 +754,6 @@ static inline void tcg_out_uxt(TCGContext *s, int s_bits,
     tcg_out_ubfm(s, 0, rd, rn, 0, bits);
 }
 
-static inline void tcg_out_addi(TCGContext *s, TCGType ext,
-                                TCGReg rd, TCGReg rn, unsigned int aimm)
-{
-    /* add immediate aimm unsigned 12bit value (with LSL 0 or 12) */
-    /* using ADD 0x11000000 | (ext) | (aimm << 10) | (rn << 5) | rd */
-    unsigned int base = ext ? 0x91000000 : 0x11000000;
-
-    if (aimm <= 0xfff) {
-        aimm <<= 10;
-    } else {
-        /* we can only shift left by 12, on assert we cannot represent */
-        assert(!(aimm & 0xfff));
-        assert(aimm <= 0xfff000);
-        base |= 1 << 22; /* apply LSL 12 */
-        aimm >>= 2;
-    }
-
-    tcg_out32(s, base | aimm | (rn << 5) | rd);
-}
-
-static inline void tcg_out_subi(TCGContext *s, TCGType ext,
-                                TCGReg rd, TCGReg rn, unsigned int aimm)
-{
-    /* sub immediate aimm unsigned 12bit value (with LSL 0 or 12) */
-    /* using SUB 0x51000000 | (ext) | (aimm << 10) | (rn << 5) | rd */
-    unsigned int base = ext ? 0xd1000000 : 0x51000000;
-
-    if (aimm <= 0xfff) {
-        aimm <<= 10;
-    } else {
-        /* we can only shift left by 12, on assert we cannot represent */
-        assert(!(aimm & 0xfff));
-        assert(aimm <= 0xfff000);
-        base |= 1 << 22; /* apply LSL 12 */
-        aimm >>= 2;
-    }
-
-    tcg_out32(s, base | aimm | (rn << 5) | rd);
-}
-
 #ifdef CONFIG_SOFTMMU
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  *                                     int mmu_idx, uintptr_t ra)
@@ -871,9 +849,10 @@ static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg,
                  (TARGET_LONG_BITS - TARGET_PAGE_BITS) + s_bits,
                  (TARGET_LONG_BITS - TARGET_PAGE_BITS));
     /* Add any "high bits" from the tlb offset to the env address into X2,
-       to take advantage of the LSL12 form of the addi instruction.
+       to take advantage of the LSL12 form of the ADDI instruction.
        X2 = env + (tlb_offset & 0xfff000) */
-    tcg_out_addi(s, 1, TCG_REG_X2, base, tlb_offset & 0xfff000);
+    tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_X2, base,
+                 tlb_offset & 0xfff000);
     /* Merge the tlb index contribution into X2.
        X2 = X2 + (X0 << CPU_TLB_ENTRY_BITS) */
     tcg_out_insn(s, 3502S, ADD_LSL, 1, TCG_REG_X2, TCG_REG_X2,
@@ -1476,9 +1455,10 @@ static void tcg_target_qemu_prologue(TCGContext *s)
         tcg_out_store_pair(s, TCG_REG_FP, r, r + 1, idx);
     }
 
-    /* make stack space for TCG locals */
-    tcg_out_subi(s, 1, TCG_REG_SP, TCG_REG_SP,
+    /* Make stack space for TCG locals.  */
+    tcg_out_insn(s, 3401, SUBI, TCG_TYPE_I64, TCG_REG_SP, TCG_REG_SP,
                  frame_size_tcg_locals * TCG_TARGET_STACK_ALIGN);
+
     /* inform TCG about how to find TCG locals with register, offset, size */
     tcg_set_frame(s, TCG_REG_SP, TCG_STATIC_CALL_ARGS_SIZE,
                   CPU_TEMP_BUF_NLONGS * sizeof(long));
@@ -1495,8 +1475,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 
     tb_ret_addr = s->code_ptr;
 
-    /* remove TCG locals stack space */
-    tcg_out_addi(s, 1, TCG_REG_SP, TCG_REG_SP,
+    /* Remove TCG locals stack space.  */
+    tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_SP, TCG_REG_SP,
                  frame_size_tcg_locals * TCG_TARGET_STACK_ALIGN);
 
     /* restore registers x19..x28.
commit df9351e372cb4a9d3079fcc5c7edead10b2a288e
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 13 13:49:17 2013 -0700

    tcg-aarch64: Convert shift insns to tcg_out_insn
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 7cfe708..b52519e 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -218,6 +218,12 @@ typedef enum {
     /* Add/subtract shifted register instructions (with a shift).  */
     I3502S_ADD_LSL  = I3502_ADD,
 
+    /* Data-processing (2 source) instructions.  */
+    I3508_LSLV      = 0x1ac02000,
+    I3508_LSRV      = 0x1ac02400,
+    I3508_ASRV      = 0x1ac02800,
+    I3508_RORV      = 0x1ac02c00,
+
     /* Logical shifted register instructions (without a shift).  */
     I3510_AND       = 0x0a000000,
     I3510_ORR       = 0x2a000000,
@@ -225,13 +231,6 @@ typedef enum {
     I3510_ANDS      = 0x6a000000,
 } AArch64Insn;
 
-enum aarch64_srr_opc {
-    SRR_SHL = 0x0,
-    SRR_SHR = 0x4,
-    SRR_SAR = 0x8,
-    SRR_ROR = 0xc
-};
-
 static inline enum aarch64_ldst_op_data
 aarch64_ldst_get_data(TCGOpcode tcg_op)
 {
@@ -479,15 +478,6 @@ static inline void tcg_out_mul(TCGContext *s, TCGType ext,
     tcg_out32(s, base | rm << 16 | rn << 5 | rd);
 }
 
-static inline void tcg_out_shiftrot_reg(TCGContext *s,
-                                        enum aarch64_srr_opc opc, TCGType ext,
-                                        TCGReg rd, TCGReg rn, TCGReg rm)
-{
-    /* using 2-source data processing instructions 0x1ac02000 */
-    unsigned int base = ext ? 0x9ac02000 : 0x1ac02000;
-    tcg_out32(s, base | rm << 16 | opc << 8 | rn << 5 | rd);
-}
-
 static inline void tcg_out_ubfm(TCGContext *s, TCGType ext, TCGReg rd,
                                 TCGReg rn, unsigned int a, unsigned int b)
 {
@@ -1193,47 +1183,47 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
     case INDEX_op_shl_i64:
     case INDEX_op_shl_i32:
-        if (c2) {    /* LSL / UBFM Wd, Wn, (32 - m) */
+        if (c2) {
             tcg_out_shl(s, ext, a0, a1, a2);
-        } else {                /* LSL / LSLV */
-            tcg_out_shiftrot_reg(s, SRR_SHL, ext, a0, a1, a2);
+        } else {
+            tcg_out_insn(s, 3508, LSLV, ext, a0, a1, a2);
         }
         break;
 
     case INDEX_op_shr_i64:
     case INDEX_op_shr_i32:
-        if (c2) {    /* LSR / UBFM Wd, Wn, m, 31 */
+        if (c2) {
             tcg_out_shr(s, ext, a0, a1, a2);
-        } else {                /* LSR / LSRV */
-            tcg_out_shiftrot_reg(s, SRR_SHR, ext, a0, a1, a2);
+        } else {
+            tcg_out_insn(s, 3508, LSRV, ext, a0, a1, a2);
         }
         break;
 
     case INDEX_op_sar_i64:
     case INDEX_op_sar_i32:
-        if (c2) {    /* ASR / SBFM Wd, Wn, m, 31 */
+        if (c2) {
             tcg_out_sar(s, ext, a0, a1, a2);
-        } else {                /* ASR / ASRV */
-            tcg_out_shiftrot_reg(s, SRR_SAR, ext, a0, a1, a2);
+        } else {
+            tcg_out_insn(s, 3508, ASRV, ext, a0, a1, a2);
         }
         break;
 
     case INDEX_op_rotr_i64:
     case INDEX_op_rotr_i32:
-        if (c2) {    /* ROR / EXTR Wd, Wm, Wm, m */
+        if (c2) {
             tcg_out_rotr(s, ext, a0, a1, a2);
-        } else {                /* ROR / RORV */
-            tcg_out_shiftrot_reg(s, SRR_ROR, ext, a0, a1, a2);
+        } else {
+            tcg_out_insn(s, 3508, RORV, ext, a0, a1, a2);
         }
         break;
 
     case INDEX_op_rotl_i64:
-    case INDEX_op_rotl_i32:     /* same as rotate right by (32 - m) */
-        if (c2) {    /* ROR / EXTR Wd, Wm, Wm, 32 - m */
+    case INDEX_op_rotl_i32:
+        if (c2) {
             tcg_out_rotl(s, ext, a0, a1, a2);
         } else {
             tcg_out_insn(s, 3502, SUB, 0, TCG_REG_TMP, TCG_REG_XZR, a2);
-            tcg_out_shiftrot_reg(s, SRR_ROR, ext, a0, a1, TCG_REG_TMP);
+            tcg_out_insn(s, 3508, RORV, ext, a0, a1, TCG_REG_TMP);
         }
         break;
 
commit 50573c66ebba29e96222390645d0adeb64f814cd
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 13 12:10:08 2013 -0700

    tcg-aarch64: Introduce tcg_out_insn
    
    Converting the add/sub (3.5.2) and logical shifted (3.5.10) instruction
    groups to the new scheme.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Claudio Fontana <claudio.fontana at huawei.com>
    Tested-by: Claudio Fontana <claudio.fontana at huawei.com>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index f43eb67..7cfe708 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -203,16 +203,27 @@ enum aarch64_ldst_op_type { /* type of operation */
     LDST_LD_S_W = 0xc,  /* load and sign-extend into Wt */
 };
 
-enum aarch64_arith_opc {
-    ARITH_AND = 0x0a,
-    ARITH_ADD = 0x0b,
-    ARITH_OR = 0x2a,
-    ARITH_ADDS = 0x2b,
-    ARITH_XOR = 0x4a,
-    ARITH_SUB = 0x4b,
-    ARITH_ANDS = 0x6a,
-    ARITH_SUBS = 0x6b,
-};
+/* We encode the format of the insn into the beginning of the name, so that
+   we can have the preprocessor help "typecheck" the insn vs the output
+   function.  Arm didn't provide us with nice names for the formats, so we
+   use the section number of the architecture reference manual in which the
+   instruction group is described.  */
+typedef enum {
+    /* Add/subtract shifted register instructions (without a shift).  */
+    I3502_ADD       = 0x0b000000,
+    I3502_ADDS      = 0x2b000000,
+    I3502_SUB       = 0x4b000000,
+    I3502_SUBS      = 0x6b000000,
+
+    /* Add/subtract shifted register instructions (with a shift).  */
+    I3502S_ADD_LSL  = I3502_ADD,
+
+    /* Logical shifted register instructions (without a shift).  */
+    I3510_AND       = 0x0a000000,
+    I3510_ORR       = 0x2a000000,
+    I3510_EOR       = 0x4a000000,
+    I3510_ANDS      = 0x6a000000,
+} AArch64Insn;
 
 enum aarch64_srr_opc {
     SRR_SHL = 0x0,
@@ -299,6 +310,34 @@ static inline uint32_t tcg_in32(TCGContext *s)
     return v;
 }
 
+/* Emit an opcode with "type-checking" of the format.  */
+#define tcg_out_insn(S, FMT, OP, ...) \
+    glue(tcg_out_insn_,FMT)(S, glue(glue(glue(I,FMT),_),OP), ## __VA_ARGS__)
+
+/* This function is for both 3.5.2 (Add/Subtract shifted register), for
+   the rare occasion when we actually want to supply a shift amount.  */
+static inline void tcg_out_insn_3502S(TCGContext *s, AArch64Insn insn,
+                                      TCGType ext, TCGReg rd, TCGReg rn,
+                                      TCGReg rm, int imm6)
+{
+    tcg_out32(s, insn | ext << 31 | rm << 16 | imm6 << 10 | rn << 5 | rd);
+}
+
+/* This function is for 3.5.2 (Add/subtract shifted register),
+   and 3.5.10 (Logical shifted register), for the vast majorty of cases
+   when we don't want to apply a shift.  Thus it can also be used for
+   3.5.3 (Add/subtract with carry) and 3.5.8 (Data processing 2 source).  */
+static void tcg_out_insn_3502(TCGContext *s, AArch64Insn insn, TCGType ext,
+                              TCGReg rd, TCGReg rn, TCGReg rm)
+{
+    tcg_out32(s, insn | ext << 31 | rm << 16 | rn << 5 | rd);
+}
+
+#define tcg_out_insn_3503  tcg_out_insn_3502
+#define tcg_out_insn_3508  tcg_out_insn_3502
+#define tcg_out_insn_3510  tcg_out_insn_3502
+
+
 static inline void tcg_out_ldst_9(TCGContext *s,
                                   enum aarch64_ldst_op_data op_data,
                                   enum aarch64_ldst_op_type op_type,
@@ -432,23 +471,6 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
                  arg, arg1, arg2);
 }
 
-static inline void tcg_out_arith(TCGContext *s, enum aarch64_arith_opc opc,
-                                 TCGType ext, TCGReg rd, TCGReg rn, TCGReg rm,
-                                 int shift_imm)
-{
-    /* Using shifted register arithmetic operations */
-    /* if extended register operation (64bit) just OR with 0x80 << 24 */
-    unsigned int shift, base = ext ? (0x80 | opc) << 24 : opc << 24;
-    if (shift_imm == 0) {
-        shift = 0;
-    } else if (shift_imm > 0) {
-        shift = shift_imm << 10 | 1 << 22;
-    } else /* (shift_imm < 0) */ {
-        shift = (-shift_imm) << 10;
-    }
-    tcg_out32(s, base | rm << 16 | shift | rn << 5 | rd);
-}
-
 static inline void tcg_out_mul(TCGContext *s, TCGType ext,
                                TCGReg rd, TCGReg rn, TCGReg rm)
 {
@@ -532,7 +554,7 @@ static inline void tcg_out_rotl(TCGContext *s, TCGType ext,
 static void tcg_out_cmp(TCGContext *s, TCGType ext, TCGReg rn, TCGReg rm)
 {
     /* Using CMP alias SUBS wzr, Wn, Wm */
-    tcg_out_arith(s, ARITH_SUBS, ext, TCG_REG_XZR, rn, rm, 0);
+    tcg_out_insn(s, 3502, SUBS, ext, TCG_REG_XZR, rn, rm);
 }
 
 static inline void tcg_out_cset(TCGContext *s, TCGType ext,
@@ -864,8 +886,8 @@ static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg,
     tcg_out_addi(s, 1, TCG_REG_X2, base, tlb_offset & 0xfff000);
     /* Merge the tlb index contribution into X2.
        X2 = X2 + (X0 << CPU_TLB_ENTRY_BITS) */
-    tcg_out_arith(s, ARITH_ADD, 1, TCG_REG_X2, TCG_REG_X2,
-                  TCG_REG_X0, -CPU_TLB_ENTRY_BITS);
+    tcg_out_insn(s, 3502S, ADD_LSL, 1, TCG_REG_X2, TCG_REG_X2,
+                 TCG_REG_X0, CPU_TLB_ENTRY_BITS);
     /* Merge "low bits" from tlb offset, load the tlb comparator into X0.
        X0 = load [X2 + (tlb_offset & 0x000fff)] */
     tcg_out_ldst(s, TARGET_LONG_BITS == 64 ? LDST_64 : LDST_32,
@@ -1141,27 +1163,27 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
     case INDEX_op_add_i64:
     case INDEX_op_add_i32:
-        tcg_out_arith(s, ARITH_ADD, ext, a0, a1, a2, 0);
+        tcg_out_insn(s, 3502, ADD, ext, a0, a1, a2);
         break;
 
     case INDEX_op_sub_i64:
     case INDEX_op_sub_i32:
-        tcg_out_arith(s, ARITH_SUB, ext, a0, a1, a2, 0);
+        tcg_out_insn(s, 3502, SUB, ext, a0, a1, a2);
         break;
 
     case INDEX_op_and_i64:
     case INDEX_op_and_i32:
-        tcg_out_arith(s, ARITH_AND, ext, a0, a1, a2, 0);
+        tcg_out_insn(s, 3510, AND, ext, a0, a1, a2);
         break;
 
     case INDEX_op_or_i64:
     case INDEX_op_or_i32:
-        tcg_out_arith(s, ARITH_OR, ext, a0, a1, a2, 0);
+        tcg_out_insn(s, 3510, ORR, ext, a0, a1, a2);
         break;
 
     case INDEX_op_xor_i64:
     case INDEX_op_xor_i32:
-        tcg_out_arith(s, ARITH_XOR, ext, a0, a1, a2, 0);
+        tcg_out_insn(s, 3510, EOR, ext, a0, a1, a2);
         break;
 
     case INDEX_op_mul_i64:
@@ -1210,7 +1232,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         if (c2) {    /* ROR / EXTR Wd, Wm, Wm, 32 - m */
             tcg_out_rotl(s, ext, a0, a1, a2);
         } else {
-            tcg_out_arith(s, ARITH_SUB, 0, TCG_REG_TMP, TCG_REG_XZR, a2, 0);
+            tcg_out_insn(s, 3502, SUB, 0, TCG_REG_TMP, TCG_REG_XZR, a2);
             tcg_out_shiftrot_reg(s, SRR_ROR, ext, a0, a1, TCG_REG_TMP);
         }
         break;
commit 46dea4160d587add2f3670306c41ad9ad4064af5
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Mar 13 10:28:01 2014 +0100

    qemu-iotests: remove 085 and 087 from 'quick' group
    
    The 'quick' group in qemu-iotests are not allowed to run QEMU since we
    don't know which targets are available.  In other words, they may only
    use qemu-img, qemu-io, and qemu-nbd.
    
    Drop 085 and 087 from the 'quick' group since they run QEMU.  This
    makes "make check-block" pass again.
    
    Reported-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 40cd3b3..ee09ebc 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -86,6 +86,6 @@
 081 rw auto
 082 rw auto quick
 083 rw auto
-085 rw auto quick
+085 rw auto
 086 rw auto quick
-087 rw auto quick
+087 rw auto
commit dc668ded1009f88da5e31bc5a143cf3e9070d49b
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Feb 26 15:30:20 2014 +0100

    qemu-iotests: add 083 NBD client disconnect tests
    
    This new test case uses nbd-fault-injector.py to simulate broken TCP
    connections at each stage in the NBD protocol.  This way we can exercise
    block/nbd-client.c's socket error handling code paths.
    
    In particular, this serves as a regression test to make sure
    nbd-client.c doesn't cause an infinite loop by leaving its
    nbd_receive_reply() fd handler registered after the connection has been
    closed.  This bug was fixed in an earlier patch.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
new file mode 100755
index 0000000..f764534
--- /dev/null
+++ b/tests/qemu-iotests/083
@@ -0,0 +1,129 @@
+#!/bin/bash
+#
+# Test NBD client unexpected disconnect
+#
+# Copyright Red Hat, Inc. 2014
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=stefanha at redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt generic
+_supported_proto nbd
+_supported_os Linux
+
+# Pick a TCP port based on our pid.  This way multiple instances of this test
+# can run in parallel without conflicting.
+choose_tcp_port() {
+	echo $((($$ % 31744) + 1024)) # 1024 <= port < 32768
+}
+
+wait_for_tcp_port() {
+	while ! (netstat --tcp --listening --numeric | \
+		 grep "$1.*0.0.0.0:\*.*LISTEN") 2>&1 >/dev/null; do
+		sleep 0.1
+	done
+}
+
+filter_nbd() {
+	# nbd.c error messages contain function names and line numbers that are prone
+	# to change.  Message ordering depends on timing between send and receive
+	# callbacks sometimes, making them unreliable.
+	#
+	# Filter out the TCP port number since this changes between runs.
+	sed -e 's#^nbd.c:.*##g' \
+	    -e 's#nbd:127.0.0.1:[^:]*:#nbd:127.0.0.1:PORT:#g'
+}
+
+check_disconnect() {
+	event=$1
+	when=$2
+	negotiation=$3
+	echo "=== Check disconnect $when $event ==="
+	echo
+
+	port=$(choose_tcp_port)
+
+	cat > "$TEST_DIR/nbd-fault-injector.conf" <<EOF
+[inject-error]
+event=$event
+when=$when
+EOF
+
+	if [ "$negotiation" = "--classic-negotiation" ]; then
+		extra_args=--classic-negotiation
+		nbd_url="nbd:127.0.0.1:$port"
+	else
+		nbd_url="nbd:127.0.0.1:$port:exportname=foo"
+	fi
+
+	./nbd-fault-injector.py $extra_args "127.0.0.1:$port" "$TEST_DIR/nbd-fault-injector.conf" 2>&1 >/dev/null &
+	wait_for_tcp_port "127.0.0.1:$port"
+	$QEMU_IO -c "read 0 512" "$nbd_url" 2>&1 | _filter_qemu_io | filter_nbd
+
+	echo
+}
+
+for event in neg1 "export" neg2 request reply data; do
+	for when in before after; do
+		check_disconnect "$event" "$when"
+	done
+
+	# Also inject short replies from the NBD server
+	case "$event" in
+	neg1)
+		for when in 8 16; do
+			check_disconnect "$event" "$when"
+		done
+		;;
+	"export")
+		for when in 4 12 16; do
+			check_disconnect "$event" "$when"
+		done
+		;;
+	neg2)
+		for when in 8 10; do
+			check_disconnect "$event" "$when"
+		done
+		;;
+	reply)
+		for when in 4 8; do
+			check_disconnect "$event" "$when"
+		done
+		;;
+	esac
+done
+
+# Also check classic negotiation without export information
+for when in before 8 16 24 28 after; do
+	check_disconnect "neg-classic" "$when" --classic-negotiation
+done
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/083.out b/tests/qemu-iotests/083.out
new file mode 100644
index 0000000..85ee8d6
--- /dev/null
+++ b/tests/qemu-iotests/083.out
@@ -0,0 +1,163 @@
+QA output created by 083
+=== Check disconnect before neg1 ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect after neg1 ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect 8 neg1 ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect 16 neg1 ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect before export ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect after export ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect 4 export ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect 12 export ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect 16 export ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect before neg2 ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect after neg2 ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
+no file open, try 'help open'
+
+=== Check disconnect 8 neg2 ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect 10 neg2 ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect before request ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
+no file open, try 'help open'
+
+=== Check disconnect after request ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
+no file open, try 'help open'
+
+=== Check disconnect before reply ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
+no file open, try 'help open'
+
+=== Check disconnect after reply ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
+no file open, try 'help open'
+
+=== Check disconnect 4 reply ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
+no file open, try 'help open'
+
+=== Check disconnect 8 reply ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
+no file open, try 'help open'
+
+=== Check disconnect before data ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT:exportname=foo: Could not read image for determining its format: Input/output error
+no file open, try 'help open'
+
+=== Check disconnect after data ===
+
+
+read failed: Input/output error
+
+=== Check disconnect before neg-classic ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect 8 neg-classic ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect 16 neg-classic ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect 24 neg-classic ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect 28 neg-classic ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT: Could not open image: Invalid argument
+no file open, try 'help open'
+
+=== Check disconnect after neg-classic ===
+
+
+qemu-io: can't open device nbd:127.0.0.1:PORT: Could not read image for determining its format: Input/output error
+no file open, try 'help open'
+
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index e96eafd..40cd3b3 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -85,6 +85,7 @@
 079 rw auto
 081 rw auto
 082 rw auto quick
+083 rw auto
 085 rw auto quick
 086 rw auto quick
 087 rw auto quick
commit 1e8ece0db3e8604d3a17bbd2bd1277161851a44a
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Feb 26 15:30:19 2014 +0100

    tests: add nbd-fault-injector.py utility
    
    The nbd-fault-injector.py script is a special kind of NBD server.  It
    throws away all writes and produces zeroes for reads.  Given a list of
    fault injection rules, it can simulate NBD protocol errors and is useful
    for testing NBD client error handling code paths.
    
    See the patch for documentation.  This scripts is modelled after Kevin
    Wolf <kwolf at redhat.com>'s blkdebug block driver.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/tests/qemu-iotests/nbd-fault-injector.py b/tests/qemu-iotests/nbd-fault-injector.py
new file mode 100755
index 0000000..6c07191
--- /dev/null
+++ b/tests/qemu-iotests/nbd-fault-injector.py
@@ -0,0 +1,264 @@
+#!/usr/bin/env python
+# NBD server - fault injection utility
+#
+# Configuration file syntax:
+#   [inject-error "disconnect-neg1"]
+#   event=neg1
+#   io=readwrite
+#   when=before
+#
+# Note that Python's ConfigParser squashes together all sections with the same
+# name, so give each [inject-error] a unique name.
+#
+# inject-error options:
+#   event - name of the trigger event
+#           "neg1" - first part of negotiation struct
+#           "export" - export struct
+#           "neg2" - second part of negotiation struct
+#           "request" - NBD request struct
+#           "reply" - NBD reply struct
+#           "data" - request/reply data
+#   io    - I/O direction that triggers this rule:
+#           "read", "write", or "readwrite"
+#           default: readwrite
+#   when  - after how many bytes to inject the fault
+#           -1 - inject error after I/O
+#           0 - inject error before I/O
+#           integer - inject error after integer bytes
+#           "before" - alias for 0
+#           "after" - alias for -1
+#           default: before
+#
+# Currently the only error injection action is to terminate the server process.
+# This resets the TCP connection and thus forces the client to handle
+# unexpected connection termination.
+#
+# Other error injection actions could be added in the future.
+#
+# Copyright Red Hat, Inc. 2014
+#
+# Authors:
+#   Stefan Hajnoczi <stefanha at redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+import sys
+import socket
+import struct
+import collections
+import ConfigParser
+
+FAKE_DISK_SIZE = 8 * 1024 * 1024 * 1024 # 8 GB
+
+# Protocol constants
+NBD_CMD_READ = 0
+NBD_CMD_WRITE = 1
+NBD_CMD_DISC = 2
+NBD_REQUEST_MAGIC = 0x25609513
+NBD_REPLY_MAGIC = 0x67446698
+NBD_PASSWD = 0x4e42444d41474943
+NBD_OPTS_MAGIC = 0x49484156454F5054
+NBD_CLIENT_MAGIC = 0x0000420281861253
+NBD_OPT_EXPORT_NAME = 1 << 0
+
+# Protocol structs
+neg_classic_struct = struct.Struct('>QQQI124x')
+neg1_struct = struct.Struct('>QQH')
+export_tuple = collections.namedtuple('Export', 'reserved magic opt len')
+export_struct = struct.Struct('>IQII')
+neg2_struct = struct.Struct('>QH124x')
+request_tuple = collections.namedtuple('Request', 'magic type handle from_ len')
+request_struct = struct.Struct('>IIQQI')
+reply_struct = struct.Struct('>IIQ')
+
+def err(msg):
+    sys.stderr.write(msg + '\n')
+    sys.exit(1)
+
+def recvall(sock, bufsize):
+    received = 0
+    chunks = []
+    while received < bufsize:
+        chunk = sock.recv(bufsize - received)
+        if len(chunk) == 0:
+            raise Exception('unexpected disconnect')
+        chunks.append(chunk)
+        received += len(chunk)
+    return ''.join(chunks)
+
+class Rule(object):
+    def __init__(self, name, event, io, when):
+        self.name = name
+        self.event = event
+        self.io = io
+        self.when = when
+
+    def match(self, event, io):
+        if event != self.event:
+            return False
+        if io != self.io and self.io != 'readwrite':
+            return False
+        return True
+
+class FaultInjectionSocket(object):
+    def __init__(self, sock, rules):
+        self.sock = sock
+        self.rules = rules
+
+    def check(self, event, io, bufsize=None):
+        for rule in self.rules:
+            if rule.match(event, io):
+                if rule.when == 0 or bufsize is None:
+                    print 'Closing connection on rule match %s' % rule.name
+                    sys.exit(0)
+                if rule.when != -1:
+                    return rule.when
+        return bufsize
+
+    def send(self, buf, event):
+        bufsize = self.check(event, 'write', bufsize=len(buf))
+        self.sock.sendall(buf[:bufsize])
+        self.check(event, 'write')
+
+    def recv(self, bufsize, event):
+        bufsize = self.check(event, 'read', bufsize=bufsize)
+        data = recvall(self.sock, bufsize)
+        self.check(event, 'read')
+        return data
+
+    def close(self):
+        self.sock.close()
+
+def negotiate_classic(conn):
+    buf = neg_classic_struct.pack(NBD_PASSWD, NBD_CLIENT_MAGIC,
+                                  FAKE_DISK_SIZE, 0)
+    conn.send(buf, event='neg-classic')
+
+def negotiate_export(conn):
+    # Send negotiation part 1
+    buf = neg1_struct.pack(NBD_PASSWD, NBD_OPTS_MAGIC, 0)
+    conn.send(buf, event='neg1')
+
+    # Receive export option
+    buf = conn.recv(export_struct.size, event='export')
+    export = export_tuple._make(export_struct.unpack(buf))
+    assert export.magic == NBD_OPTS_MAGIC
+    assert export.opt == NBD_OPT_EXPORT_NAME
+    name = conn.recv(export.len, event='export-name')
+
+    # Send negotiation part 2
+    buf = neg2_struct.pack(FAKE_DISK_SIZE, 0)
+    conn.send(buf, event='neg2')
+
+def negotiate(conn, use_export):
+    '''Negotiate export with client'''
+    if use_export:
+        negotiate_export(conn)
+    else:
+        negotiate_classic(conn)
+
+def read_request(conn):
+    '''Parse NBD request from client'''
+    buf = conn.recv(request_struct.size, event='request')
+    req = request_tuple._make(request_struct.unpack(buf))
+    assert req.magic == NBD_REQUEST_MAGIC
+    return req
+
+def write_reply(conn, error, handle):
+    buf = reply_struct.pack(NBD_REPLY_MAGIC, error, handle)
+    conn.send(buf, event='reply')
+
+def handle_connection(conn, use_export):
+    negotiate(conn, use_export)
+    while True:
+        req = read_request(conn)
+        if req.type == NBD_CMD_READ:
+            write_reply(conn, 0, req.handle)
+            conn.send('\0' * req.len, event='data')
+        elif req.type == NBD_CMD_WRITE:
+            _ = conn.recv(req.len, event='data')
+            write_reply(conn, 0, req.handle)
+        elif req.type == NBD_CMD_DISC:
+            break
+        else:
+            print 'unrecognized command type %#02x' % req.type
+            break
+    conn.close()
+
+def run_server(sock, rules, use_export):
+    while True:
+        conn, _ = sock.accept()
+        handle_connection(FaultInjectionSocket(conn, rules), use_export)
+
+def parse_inject_error(name, options):
+    if 'event' not in options:
+        err('missing \"event\" option in %s' % name)
+    event = options['event']
+    if event not in ('neg-classic', 'neg1', 'export', 'neg2', 'request', 'reply', 'data'):
+        err('invalid \"event\" option value \"%s\" in %s' % (event, name))
+    io = options.get('io', 'readwrite')
+    if io not in ('read', 'write', 'readwrite'):
+        err('invalid \"io\" option value \"%s\" in %s' % (io, name))
+    when = options.get('when', 'before')
+    try:
+        when = int(when)
+    except ValueError:
+        if when == 'before':
+            when = 0
+        elif when == 'after':
+            when = -1
+        else:
+            err('invalid \"when\" option value \"%s\" in %s' % (when, name))
+    return Rule(name, event, io, when)
+
+def parse_config(config):
+    rules = []
+    for name in config.sections():
+        if name.startswith('inject-error'):
+            options = dict(config.items(name))
+            rules.append(parse_inject_error(name, options))
+        else:
+            err('invalid config section name: %s' % name)
+    return rules
+
+def load_rules(filename):
+    config = ConfigParser.RawConfigParser()
+    with open(filename, 'rt') as f:
+        config.readfp(f, filename)
+    return parse_config(config)
+
+def open_socket(path):
+    '''Open a TCP or UNIX domain listen socket'''
+    if ':' in path:
+        host, port = path.split(':', 1)
+        sock = socket.socket()
+        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        sock.bind((host, int(port)))
+    else:
+        sock = socket.socket(socket.AF_UNIX)
+        sock.bind(path)
+    sock.listen(0)
+    print 'Listening on %s' % path
+    return sock
+
+def usage(args):
+    sys.stderr.write('usage: %s [--classic-negotiation] <tcp-port>|<unix-path> <config-file>\n' % args[0])
+    sys.stderr.write('Run an fault injector NBD server with rules defined in a config file.\n')
+    sys.exit(1)
+
+def main(args):
+    if len(args) != 3 and len(args) != 4:
+        usage(args)
+    use_export = True
+    if args[1] == '--classic-negotiation':
+        use_export = False
+    elif len(args) == 4:
+        usage(args)
+    sock = open_socket(args[1 if use_export else 2])
+    rules = load_rules(args[2 if use_export else 3])
+    run_server(sock, rules, use_export)
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv))
commit 4a41a2d68a684241aca96dba066e0699941b730d
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Feb 26 15:30:18 2014 +0100

    nbd: close socket if connection breaks
    
    nbd_receive_reply() is called by the event loop whenever data is
    available or the socket has been closed by the remote side.
    
    This patch closes the socket when an error occurs to prevent the
    nbd_receive_reply() handler from being called indefinitely after the
    connection has failed.
    
    Note that we were already correctly returning EIO for pending requests
    but leaving the nbd_receive_reply() handler registered resulted in high
    CPU consumption and a flood of error messages.
    
    Reuse nbd_teardown_connection() to close the socket.
    
    Reported-by: Zhifeng Cai <bluewindow at h3c.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/nbd-client.c b/block/nbd-client.c
index 0922b78..7d698cb 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -43,6 +43,17 @@ static void nbd_recv_coroutines_enter_all(NbdClientSession *s)
     }
 }
 
+static void nbd_teardown_connection(NbdClientSession *client)
+{
+    /* finish any pending coroutines */
+    shutdown(client->sock, 2);
+    nbd_recv_coroutines_enter_all(client);
+
+    qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL);
+    closesocket(client->sock);
+    client->sock = -1;
+}
+
 static void nbd_reply_ready(void *opaque)
 {
     NbdClientSession *s = opaque;
@@ -78,7 +89,7 @@ static void nbd_reply_ready(void *opaque)
     }
 
 fail:
-    nbd_recv_coroutines_enter_all(s);
+    nbd_teardown_connection(s);
 }
 
 static void nbd_restart_write(void *opaque)
@@ -324,7 +335,7 @@ int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num,
 
 }
 
-static void nbd_teardown_connection(NbdClientSession *client)
+void nbd_client_session_close(NbdClientSession *client)
 {
     struct nbd_request request = {
         .type = NBD_CMD_DISC,
@@ -332,22 +343,14 @@ static void nbd_teardown_connection(NbdClientSession *client)
         .len = 0
     };
 
-    nbd_send_request(client->sock, &request);
-
-    /* finish any pending coroutines */
-    shutdown(client->sock, 2);
-    nbd_recv_coroutines_enter_all(client);
-
-    qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL);
-    closesocket(client->sock);
-    client->sock = -1;
-}
-
-void nbd_client_session_close(NbdClientSession *client)
-{
     if (!client->bs) {
         return;
     }
+    if (client->sock == -1) {
+        return;
+    }
+
+    nbd_send_request(client->sock, &request);
 
     nbd_teardown_connection(client);
     client->bs = NULL;
commit 62e466e84592900756f080802782d0615c6a3b5c
Author: Jeff Cody <jcody at redhat.com>
Date:   Fri Mar 14 06:50:37 2014 -0400

    block: Explicitly specify 'unsigned long long' for VHDX 64-bit constants
    
    On 32-bit hosts, some compilers will warn on too large integer constants
    for constants that are 64-bit in length.  Explicitly put a 'ULL' suffix
    on those defines.
    
    Reported-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/vhdx.h b/block/vhdx.h
index 2acd7c2..8103d4c 100644
--- a/block/vhdx.h
+++ b/block/vhdx.h
@@ -61,7 +61,7 @@
 /* These structures are ones that are defined in the VHDX specification
  * document */
 
-#define VHDX_FILE_SIGNATURE 0x656C696678646876  /* "vhdxfile" in ASCII */
+#define VHDX_FILE_SIGNATURE 0x656C696678646876ULL  /* "vhdxfile" in ASCII */
 typedef struct VHDXFileIdentifier {
     uint64_t    signature;              /* "vhdxfile" in ASCII */
     uint16_t    creator[256];           /* optional; utf-16 string to identify
@@ -238,7 +238,7 @@ typedef struct QEMU_PACKED VHDXLogDataSector {
 /* upper 44 bits are the file offset in 1MB units lower 3 bits are the state
    other bits are reserved */
 #define VHDX_BAT_STATE_BIT_MASK 0x07
-#define VHDX_BAT_FILE_OFF_MASK  0xFFFFFFFFFFF00000 /* upper 44 bits */
+#define VHDX_BAT_FILE_OFF_MASK  0xFFFFFFFFFFF00000ULL /* upper 44 bits */
 typedef uint64_t VHDXBatEntry;
 
 /* ---- METADATA REGION STRUCTURES ---- */
@@ -247,7 +247,7 @@ typedef uint64_t VHDXBatEntry;
 #define VHDX_METADATA_MAX_ENTRIES 2047  /* not including the header */
 #define VHDX_METADATA_TABLE_MAX_SIZE \
     (VHDX_METADATA_ENTRY_SIZE * (VHDX_METADATA_MAX_ENTRIES+1))
-#define VHDX_METADATA_SIGNATURE 0x617461646174656D  /* "metadata" in ASCII */
+#define VHDX_METADATA_SIGNATURE 0x617461646174656DULL  /* "metadata" in ASCII */
 typedef struct QEMU_PACKED VHDXMetadataTableHeader {
     uint64_t    signature;              /* "metadata" in ASCII */
     uint16_t    reserved;
commit c3adb58fe0b2db4942f5b2f5d19bc51a29b93a89
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Mar 14 09:22:48 2014 +0100

    blockdev: Refuse to open encrypted image unless paused
    
    Opening an encrypted image takes an additional step: setting the key.
    Between open and the key set, the image must not be used.
    
    We have some protection against accidental use in place: you can't
    unpause a guest while we're missing keys.  You can, however, hot-plug
    block devices lacking keys into a running guest just fine, or insert
    media lacking keys.  In the latter case, notifying the guest of the
    insert is delayed until the key is set, which may suffice to protect
    at least some guests in common usage.
    
    This patch makes the protection apply in more cases, in a rather
    heavy-handed way: it doesn't let you open encrypted images unless
    we're in a paused state.
    
    It doesn't extend the protection to users other than the guest (block
    jobs?).  Use of runstate_check() from block.c is disgusting.  Best I
    can do right now.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block.c b/block.c
index fae50c9..53f5b44 100644
--- a/block.c
+++ b/block.c
@@ -1388,12 +1388,19 @@ done:
         ret = -EINVAL;
         goto close_and_fail;
     }
-    QDECREF(options);
 
     if (!bdrv_key_required(bs)) {
         bdrv_dev_change_media_cb(bs, true);
+    } else if (!runstate_check(RUN_STATE_PRELAUNCH)
+               && !runstate_check(RUN_STATE_INMIGRATE)
+               && !runstate_check(RUN_STATE_PAUSED)) { /* HACK */
+        error_setg(errp,
+                   "Guest must be stopped for opening of encrypted image");
+        ret = -EBUSY;
+        goto close_and_fail;
     }
 
+    QDECREF(options);
     *pbs = bs;
     return 0;
 
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 59c5a54..5ed1d38 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -20,6 +20,7 @@ stub-obj-y += mon-set-error.o
 stub-obj-y += pci-drive-hot-add.o
 stub-obj-y += qtest.o
 stub-obj-y += reset.o
+stub-obj-y += runstate-check.o
 stub-obj-y += set-fd-handler.o
 stub-obj-y += slirp.o
 stub-obj-y += sysbus.o
diff --git a/stubs/runstate-check.c b/stubs/runstate-check.c
new file mode 100644
index 0000000..bd2e375
--- /dev/null
+++ b/stubs/runstate-check.c
@@ -0,0 +1,6 @@
+#include "sysemu/sysemu.h"
+
+bool runstate_check(RunState state)
+{
+    return state == RUN_STATE_PRELAUNCH;
+}
diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087
index 53b6c43..a38bb70 100755
--- a/tests/qemu-iotests/087
+++ b/tests/qemu-iotests/087
@@ -99,6 +99,23 @@ echo === Encrypted image ===
 echo
 
 _make_test_img -o encryption=on $size
+run_qemu -S <<EOF
+{ "execute": "qmp_capabilities" }
+{ "execute": "blockdev-add",
+  "arguments": {
+      "options": {
+        "driver": "$IMGFMT",
+        "id": "disk",
+        "file": {
+            "driver": "file",
+            "filename": "$TEST_IMG"
+        }
+      }
+    }
+  }
+{ "execute": "quit" }
+EOF
+
 run_qemu <<EOF
 { "execute": "qmp_capabilities" }
 { "execute": "blockdev-add",
diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
index b871032..e65dcdf 100644
--- a/tests/qemu-iotests/087.out
+++ b/tests/qemu-iotests/087.out
@@ -28,7 +28,7 @@ QMP_VERSION
 === Encrypted image ===
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 encryption=on 
-Testing:
+Testing: -S
 QMP_VERSION
 {"return": {}}
 {"error": {"class": "GenericError", "desc": "blockdev-add doesn't support encrypted devices"}}
@@ -37,4 +37,13 @@ QMP_VERSION
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
 {"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
 
+Testing:
+QMP_VERSION
+{"return": {}}
+{"error": {"class": "GenericError", "desc": "could not open disk image disk: Guest must be stopped for opening of encrypted image"}}
+{"return": {}}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "SHUTDOWN"}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
+{"timestamp": {"seconds":  TIMESTAMP, "microseconds":  TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
+
 *** done
commit aa7a6a399f8253d3831465b1db8544032b49f57a
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Mar 6 11:18:53 2014 +0100

    virtio-scsi: actually honor sense_size from configuration space
    
    We were always truncating the sense size to 96 bytes.
    
    Reviewed-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 6610b3a..b0d7517 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -304,6 +304,8 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
                                          size_t resid)
 {
     VirtIOSCSIReq *req = r->hba_private;
+    VirtIOSCSI *s = req->dev;
+    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);
     uint32_t sense_len;
 
     if (r->io_canceled) {
@@ -317,7 +319,7 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status,
     } else {
         req->resp.cmd->resid = 0;
         sense_len = scsi_req_get_sense(r, req->resp.cmd->sense,
-                                       VIRTIO_SCSI_SENSE_SIZE);
+                                       vs->sense_size);
         req->resp.cmd->sense_len = tswap32(sense_len);
     }
     virtio_scsi_complete_req(req);
commit 2e323f03bfa323636552b386c982412944ff86ae
Author: Fam Zheng <famz at redhat.com>
Date:   Thu Mar 6 16:26:02 2014 +0800

    scsi: Fix migration of scsi sense data
    
    c5f52875 changed the size of sense array in vmstate_scsi_device by
    mistake. This patch restores the old size, and add a subsection for the
    remaining part of the buffer size. So that migration is not broken.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 50a0acf..eaad925 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -1905,6 +1905,26 @@ static const VMStateInfo vmstate_info_scsi_requests = {
     .put  = put_scsi_requests,
 };
 
+static bool scsi_sense_state_needed(void *opaque)
+{
+    SCSIDevice *s = opaque;
+
+    return s->sense_len > SCSI_SENSE_BUF_SIZE_OLD;
+}
+
+static const VMStateDescription vmstate_scsi_sense_state = {
+    .name = "SCSIDevice/sense",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT8_SUB_ARRAY(sense, SCSIDevice,
+                                SCSI_SENSE_BUF_SIZE_OLD,
+                                SCSI_SENSE_BUF_SIZE - SCSI_SENSE_BUF_SIZE_OLD),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 const VMStateDescription vmstate_scsi_device = {
     .name = "SCSIDevice",
     .version_id = 1,
@@ -1915,7 +1935,7 @@ const VMStateDescription vmstate_scsi_device = {
         VMSTATE_UINT8(unit_attention.asc, SCSIDevice),
         VMSTATE_UINT8(unit_attention.ascq, SCSIDevice),
         VMSTATE_BOOL(sense_is_ua, SCSIDevice),
-        VMSTATE_UINT8_ARRAY(sense, SCSIDevice, SCSI_SENSE_BUF_SIZE),
+        VMSTATE_UINT8_SUB_ARRAY(sense, SCSIDevice, 0, SCSI_SENSE_BUF_SIZE_OLD),
         VMSTATE_UINT32(sense_len, SCSIDevice),
         {
             .name         = "requests",
@@ -1927,6 +1947,14 @@ const VMStateDescription vmstate_scsi_device = {
             .offset       = 0,
         },
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (VMStateSubsection []) {
+        {
+            .vmsd = &vmstate_scsi_sense_state,
+            .needed = scsi_sense_state_needed,
+        }, {
+            /* empty */
+        }
     }
 };
 
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index e5fc39d..1adb549 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -31,6 +31,7 @@ typedef struct SCSISense {
     uint8_t ascq;
 } SCSISense;
 
+#define SCSI_SENSE_BUF_SIZE_OLD 96
 #define SCSI_SENSE_BUF_SIZE 252
 
 struct SCSICommand {
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index ded8e23..e7e1705 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -650,6 +650,9 @@ extern const VMStateInfo vmstate_info_bitmap;
 #define VMSTATE_UINT8_ARRAY(_f, _s, _n)                               \
     VMSTATE_UINT8_ARRAY_V(_f, _s, _n, 0)
 
+#define VMSTATE_UINT8_SUB_ARRAY(_f, _s, _start, _num)                \
+    VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint8, uint8_t)
+
 #define VMSTATE_UINT8_2DARRAY(_f, _s, _n1, _n2)                       \
     VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, 0)
 
commit 22956a3755749b9cf6375ad024d58c1d277100bf
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed Mar 5 16:15:16 2014 +1100

    spapr-vscsi: fix CRQ status
    
    Normally VIOSRP_OK (0) means success and non-zero value means error
    except VIOSRP_OK2 (0x99) which is another success code by weird accident.
    
    This uses 0 as success code always as some guests do not cope with
    the 0x99 value well. The existing linux driver checks for both VIOSRP_OK
    and VIOSRP_OK2 since 2.6.32.
    
    This returns non-zero code (VIOSRP_ADAPTER_FAIL == 0x10) on errors which
    can only happen if DMA write failed.
    
    Suggested-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index b3835c8..34478f0 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -195,9 +195,9 @@ static int vscsi_send_iu(VSCSIState *s, vscsi_req *req,
     req->crq.s.IU_data_ptr = req->iu.srp.rsp.tag; /* right byte order */
 
     if (rc == 0) {
-        req->crq.s.status = 0x99; /* Just needs to be non-zero */
+        req->crq.s.status = VIOSRP_OK;
     } else {
-        req->crq.s.status = 0x00;
+        req->crq.s.status = VIOSRP_ADAPTER_FAIL;
     }
 
     rc1 = spapr_vio_send_crq(&s->vdev, req->crq.raw);


More information about the Spice-commits mailing list