[qemu] Pull patches queued for qemu 1.2.1

Cole Robinson crobinso at fedoraproject.org
Sun Oct 28 18:05:17 UTC 2012


commit 5544c1b492fb00740807fb6a277593e5578300e2
Author: Cole Robinson <crobinso at redhat.com>
Date:   Sun Oct 28 14:05:07 2012 -0400

    Pull patches queued for qemu 1.2.1

 ...-char-Re-connect-for-tcp_chr_write-unconn.patch |   14 -
 ...xtensa-convert-host-errno-values-to-guest.patch |  183 +
 0002-target-cris-Fix-buffer-overflow.patch         |   35 +
 ...tensa-fix-missing-errno-codes-for-mingw32.patch |   64 +
 ...c-fix-fcmp-s-d-q-instructions-wrt-excepti.patch |  133 +
 0005-target-s390x-fix-style.patch                  | 1603 +++++
 0006-target-s390x-split-FPU-ops.patch              | 1756 ++++++
 ...target-s390x-split-condition-code-helpers.patch | 1158 ++++
 0008-target-s390x-split-integer-helpers.patch      |  444 ++
 ...-target-s390x-split-memory-access-helpers.patch | 2424 ++++++++
 ...s390x-rename-op_helper.c-to-misc_helper.c.patch |  924 +++
 ...-target-s390x-avoid-AREG0-for-FPU-helpers.patch | 1218 ++++
 ...get-s390x-avoid-AREG0-for-integer-helpers.patch |  202 +
 ...0x-avoid-AREG0-for-condition-code-helpers.patch |  190 +
 ...target-s390x-avoid-AREG0-for-misc-helpers.patch |  411 ++
 0015-target-s390x-switch-to-AREG0-free-mode.patch  | 1584 +++++
 ...s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch |   64 +
 ...-target-arm-Fix-potential-buffer-overflow.patch |   47 +
 ...-optimize-split-expression-simplification.patch |   57 +
 ...-tcg-optimize-simplify-or-xor-r-a-0-cases.patch |   30 +
 0020-tcg-optimize-simplify-and-r-a-0-cases.patch   |   29 +
 ...e-simplify-shift-rot-r-0-a-movi-r-0-cases.patch |   48 +
 ...e-swap-brcond-setcond-arguments-when-poss.patch |   49 +
 ...optimize-add-constant-folding-for-setcond.patch |  114 +
 ...-optimize-add-constant-folding-for-brcond.patch |   60 +
 ...g-optimize-fix-if-else-break-coding-style.patch |  144 +
 0026-target-s390x-avoid-cpu_single_env.patch       | 1337 +++++
 0027-target-lm32-switch-to-AREG0-free-mode.patch   |  282 +
 0028-target-m68k-switch-to-AREG0-free-mode.patch   |  502 ++
 0029-target-m68k-avoid-using-cpu_single_env.patch  |  901 +++
 ...arget-unicore32-switch-to-AREG0-free-mode.patch |  437 ++
 0031-target-arm-convert-void-helpers.patch         |  181 +
 0032-target-arm-convert-remaining-helpers.patch    |  821 +++
 ...t-arm-final-conversion-to-AREG0-free-mode.patch |  179 +
 ...rget-microblaze-switch-to-AREG0-free-mode.patch |  715 +++
 0035-target-cris-Avoid-AREG0-for-helpers.patch     |  523 ++
 0036-target-cris-Switch-to-AREG0-free-mode.patch   | 1538 +++++
 0037-target-sh4-switch-to-AREG0-free-mode.patch    | 1060 ++++
 0038-target-mips-switch-to-AREG0-free-mode.patch   | 6336 ++++++++++++++++++++
 ...nused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch | 1683 ++++++
 ...cg-i386-allow-constants-in-load-store-ops.patch |  114 +
 ...g-mark-set_label-with-TCG_OPF_BB_END-flag.patch |   53 +
 0042-revert-TCG-fix-copy-propagation.patch         |   85 +
 ...-target-mips-Set-opn-in-gen_ldst_multiple.patch |   55 +
 0044-target-mips-Fix-MIPS_DEBUG.patch              |  288 +
 ...-Always-evaluate-debugging-macro-argument.patch |   70 +
 ...optimize-fix-end-of-basic-block-detection.patch |   62 +
 0047-target-xtensa-fix-extui-shift-amount.patch    |   57 +
 ...t-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch |   35 +
 0049-tcg-Introduce-movcond.patch                   |  333 +
 0050-target-alpha-Use-movcond.patch                |  160 +
 0051-tcg-i386-Implement-movcond.patch              |  118 +
 ...Optimize-movcond-for-constant-comparisons.patch |   73 +
 ...timize-two-address-commutative-operations.patch |   57 +
 ...-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch |  192 +
 0055-tcg-Fix-USE_DIRECT_JUMP.patch                 |   35 +
 0056-tcg-hppa-Fix-brcond2-and-setcond2.patch       |  108 +
 0057-tcg-hppa-Fix-broken-load-store-helpers.patch  |  249 +
 ...-tcg-mips-fix-wrong-usage-of-Z-constraint.patch |   65 +
 0059-tcg-mips-kill-warnings-in-user-mode.patch     |  166 +
 ...-mips-use-TCGArg-or-TCGReg-instead-of-int.patch |  246 +
 0061-tcg-mips-don-t-use-global-pointer.patch       |   37 +
 0062-tcg-mips-use-stack-for-TCG-temps.patch        |   47 +
 0063-tcg-mips-optimize-brcond-arg-0.patch          |   99 +
 ...mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch |  161 +
 ...-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch |   92 +
 ...tcg-mips-implement-deposit-op-on-MIPS32R2.patch |   77 +
 ...tcg-mips-implement-movcond-op-on-MIPS32R2.patch |  140 +
 0068-tcg-optimize-remove-TCG_TEMP_ANY.patch        |   62 +
 ...-optimize-check-types-in-copy-propagation.patch |   78 +
 0070-tcg-optimize-rework-copy-progagation.patch    |  377 ++
 ...ze-do-copy-propagation-for-all-operations.patch |   42 +
 0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch  |   31 +
 0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch |   46 +
 ...e-further-optimize-brcond-movcond-setcond.patch |  192 +
 ...e-prefer-the-op-a-a-b-form-for-commutativ.patch |   38 +
 ...remove-ifdef-endif-around-TCGOpcode-tests.patch |   68 +
 ...optimize-add-constant-folding-for-deposit.patch |   46 +
 ...DME-document-tcg_gen_goto_tb-restrictions.patch |   33 +
 ...Fix-TCG-helper-functions-with-5-arguments.patch |   57 +
 0080-tcg-ppc32-Implement-movcond32.patch           |  137 +
 ...tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch |   30 +
 0082-tcg-sparc-Fix-ADDX-opcode.patch               |   27 +
 ...arc-Don-t-MAP_FIXED-on-top-of-the-program.patch |   45 +
 ...ssume-v9-cpu-always-i.e.-force-v8plus-in-.patch |  286 +
 ...parc-Fix-qemu_ld-st-to-handle-32-bit-host.patch |  967 +++
 0086-tcg-sparc-Support-GUEST_BASE.patch            |  113 +
 ...parc-Change-AREG0-in-generated-code-to-i0.patch |   51 +
 ...lean-up-cruft-stemming-from-attempts-to-u.patch |  203 +
 ...ask-shift-immediates-to-avoid-illegal-ins.patch |   62 +
 0090-tcg-sparc-Use-defines-for-temporaries.patch   |  275 +
 ...cg-sparc-Add-g-o-registers-to-alloc_order.patch |   44 +
 ...g-sparc-Fix-and-enable-direct-TB-chaining.patch |   79 +
 ...reserve-branch-destinations-during-retran.patch |   60 +
 ...target-alpha-Initialize-env-cpu_model_str.patch |   33 +
 0095-tcg-mips-fix-MIPS32-R2-detection.patch        |   93 +
 0096-tcg-Adjust-descriptions-of-cond-opcodes.patch |   67 +
 0097-tcg-i386-fix-build-with-march-i686.patch      |   34 +
 0098-tcg-Fix-MAX_OPC_PARAM_IARGS.patch             |   52 +
 0099-tci-Fix-for-AREG0-free-mode.patch             |  119 +
 ...abort-on-invalid-streaming-cmdline-params.patch |    9 +-
 ...pice-notify-spice-server-on-vm-start-stop.patch |    9 +-
 ...y-on-vm-state-change-only-via-spice_serve.patch |    9 +-
 ...ration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch |   11 +-
 ...104-spice-add-migrated-flag-to-spice-info.patch |    9 +-
 ...g-seamless-migration-option-to-the-comman.patch |   10 +-
 ...ase-the-verbosity-of-spice-section-in-qem.patch |   11 +-
 ...e_area_io-guest_bug-on-invalid-parameters.patch |    9 +-
 ...0108-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch |   50 +-
 ...rint-spice-protocol-and-spice-server-vers.patch |   16 +-
 ...-fix-doc-of-using-raw-values-with-sendkey.patch |   42 +
 ...-qapi-Fix-potential-NULL-pointer-segfault.patch |   38 +
 ...arser-Fix-potential-NULL-pointer-segfault.patch |   40 +
 ...-drop-version_id-field-for-live-migration.patch |   79 +
 ...ear-cmask-for-Advanced-Error-Interrupt-Me.patch |   40 +
 ...ointer-for-ELF-kernels-loaded-with-kernel.patch |   42 +
 0116-lan9118-fix-multicast-filtering.patch         |   37 +
 ...S-user-Fix-reset-CPU-state-initialization.patch |  196 +
 0118-Add-MAINTAINERS-entry-for-leon3.patch         |   34 +
 0119-musicpal-Fix-flash-mapping.patch              |   42 +
 ...lgrind-annotations-to-mark-kvm-guest-memo.patch |   84 +
 0121-hw-wm8750-Fix-potential-buffer-overflow.patch |   43 +
 ...6-Fix-buffer-overflow-for-MBAR-read-write.patch |   87 +
 ...dir-instead-of-ignoring-it-first-and-rein.patch |   94 +
 ...t-attempt-to-reconnect-a-TCP-socket-in-se.patch |   43 +
 ...ty-to-force-enable-disable-of-tools-build.patch |   83 +
 ...lers-do-not-need-to-check-for-babble-them.patch |   10 +-
 ...n-t-set-packet-state-to-complete-on-a-nak.patch |   10 +-
 ...d-a-usb_ep_find_packet_by_id-helper-funct.patch |   10 +-
 ...low-the-first-packet-of-a-pipelined-ep-to.patch |   11 +-
 ...-ehci-don-t-flush-cache-on-doorbell-rings.patch |    9 +-
 ...te-qh-is-not-changed-unexpectedly-by-the-.patch |   10 +-
 ...-copyright-headers-to-reflect-recent-work.patch |   10 +-
 ...3-ehci-Properly-cleanup-packets-on-cancel.patch |    9 +-
 ...ly-report-completed-but-not-yet-processed.patch |   11 +-
 ...for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch |    9 +-
 ...-bugs.patch => 0136-ehci-trace-guest-bugs.patch |    9 +-
 ...ch => 0137-ehci-add-doorbell-trace-events.patch |    9 +-
 ...ome-additional-ehci_trace_guest_bug-calls.patch |   10 +-
 ...memory-leak-in-handling-of-NAK-ed-packets.patch |    9 +-
 ...Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch |    9 +-
 ...t-a-comment-in-fetchqtd-packet-processing.patch |   10 +-
 ...ever-return-USB_RET_NAK-for-async-handled.patch |   15 +-
 ...on-t-delay-handling-of-open-events-to-a-b.patch |   25 +-
 ...-redir-Get-rid-of-async-struct-get-member.patch |   19 +-
 ...et-rid-of-local-shadow-copy-of-packet-hea.patch |   24 +-
 ...Get-rid-of-unused-async-struct-dev-member.patch |   13 +-
 ...Move-to-core-packet-id-and-queue-handling.patch |   49 +-
 ...eturn-babble-when-getting-more-bulk-data-.patch |   15 +-
 ...ch => 0149-Better-name-usb-braille-device.patch |   11 +-
 ...n.patch => 0150-usb-audio-fix-usb-version.patch |    9 +-
 ...151-xhci-rip-out-background-transfer-code.patch |    9 +-
 ...ffering.patch => 0152-xhci-drop-buffering.patch |    9 +-
 ...=> 0153-xhci-fix-runtime-write-tracepoint.patch |   13 +-
 ...-allow-bytewise-capability-register-reads.patch |   23 +-
 ...atch => 0155-qxl-dont-update-invalid-area.patch |   13 +-
 ...low-emulated-non-async-control-requests-w.patch |   11 +-
 ...57-qxl-better-cleanup-for-surface-destroy.patch |   11 +-
 ... 0158-ehci-switch-to-new-style-memory-ops.patch |   11 +-
 ...terrupts-stopping-when-Interrupt-Threshol.patch |   14 +-
 ...process-too-much-frames-in-1-timer-tick-v.patch |   17 +-
 0161-sheepdog-fix-savevm-and-loadvm.patch          |   41 +
 ...or-messages-from-static-code-analysis-no-.patch |   67 +
 0163-block-curl-Fix-wrong-free-statement.patch     |   37 +
 0164-vdi-Fix-warning-from-clang.patch              |   75 +
 0165-block-fix-block-tray-status.patch             |   36 +
 0166-ahci-properly-reset-PxCMD-on-HBA-reset.patch  |   64 +
 ...re-encryption-password-for-qemu-img-info-.patch |  121 +
 ...ock-Don-t-forget-to-delete-temporary-file.patch |   36 +
 ...-fixes.patch => 0169-hw-qxl-tracing-fixes.patch |   25 +-
 ...es.patch => 0170-configure-usbredir-fixes.patch |   15 +-
 ...set-seen-to-0-when-removing-unseen-queue-.patch |   25 +-
 ...async-schedule-before-and-after-migration.patch |   18 +-
 ...-Revert-usb-redir-part-of-commit-93bfef4c.patch |   52 +-
 ...queue-up-packets-after-one-with-the-SPD-f.patch |   13 +-
 ...ove-wrong-type-casts-ins-debug-statements.patch |   37 +
 ...ix-error-reported-by-static-code-analysis.patch |   37 +
 0177-slirp-improve-TFTP-performance.patch          |  106 +
 ...e-more-than-65535-blocks-in-TFTP-transfer.patch |  121 +
 0179-slirp-Implement-TFTP-Blocksize-option.patch   |  123 +
 ...se-QEMU_PACKED-for-single-elements-of-a-s.patch |   63 +
 ...lling-fixes-in-comments-and-documentation.patch |  183 +
 ...sole-Clean-up-bytes-per-pixel-calculation.patch |   51 +
 0183-qapi-Fix-enumeration-typo-error.patch         |   54 +
 ...kvm-Fix-warning-from-static-code-analysis.patch |   49 +
 ...-add-missing-symbols-before-PRIu64-in-deb.patch |   54 +
 ...-net-notify-iothread-after-flushing-queue.patch |  105 +
 ...-queue-whenever-can_receive-can-go-from-f.patch |   51 +
 0188-xen-flush-queue-when-getting-an-event.patch   |   37 +
 ...-Fix-network-hang-when-rx-buffers-run-out.patch |   72 +
 ...ceive_disabled-logic-to-iov-delivery-path.patch |   65 +
 ...-net-do-not-report-queued-packets-as-sent.patch |  103 +
 0192-net-add-netdev-options-to-man-page.patch      |   81 +
 0193-net-clean-up-usbnet_receive.patch             |   80 +
 0194-net-fix-usbnet_receive-packet-drops.patch     |   81 +
 ...st-hub-packets-if-at-least-one-port-can-r.patch |   51 +
 ...onous-send-receive-infrastructure-for-net.patch |  133 +
 ...-net-EAGAIN-handling-for-net-socket.c-UDP.patch |   45 +
 ...-net-EAGAIN-handling-for-net-socket.c-TCP.patch |   97 +
 0199-configure-fix-seccomp-check.patch             |   45 +
 ...re-properly-check-if-lrt-and-lm-is-needed.patch |   80 +
 0201-Revert-455aa1e08-and-c3767ed0eb.patch         |   51 +
 ...UGFIX-don-t-call-FD_ISSET-with-negative-f.patch |   59 +
 ...l_memory_write_rom-needs-to-do-TB-invalid.patch |   52 +
 ...-Improve-soundhw-help-for-non-HAS_AUDIO_C.patch |   43 +
 ...xilinx_timer-Removed-comma-in-device-name.patch |   54 +
 ..._timer-Send-dbg-msgs-to-stderr-not-stdout.patch |   56 +
 0207-xilinx.h-Error-check-when-setting-links.patch |   54 +
 ...imer-Fix-a-compile-error-if-debug-enabled.patch |   41 +
 ..._cfi01-fix-vendor-specific-extended-query.patch |   49 +
 0209-qxl-disallow-unknown-revisions.patch          |   33 -
 0210-MAINTAINERS-Add-entry-for-QOM-CPU.patch       |   36 +
 ...ed-to-support-SG_IO-also-from-iscsi_ioctl.patch |   59 +
 ...nt-need-to-explicitely-call-qemu_notify_e.patch |   39 +
 0213-scsi-disk-introduce-check_lba_range.patch     |   82 +
 ...-scsi-disk-fix-check-for-out-of-range-LBA.patch |   38 +
 ...rd-INQUIRY-data-should-report-HiSup-flag-.patch |   43 +
 ...dio-Fix-warning-from-static-code-analysis.patch |   47 +
 ...-ga-Remove-unreachable-code-after-g_error.patch |   40 +
 0218-qemu-sockets-Fix-potential-memory-leak.patch  |   32 +
 0219-cadence_uart-Fix-buffer-overflow.patch        |   35 +
 0220-lm4549-Fix-buffer-overflow.patch              |   47 +
 0221-ioh3420-Remove-unreachable-code.patch         |   33 +
 ...01-Fix-warning-caused-by-unreachable-code.patch |   65 +
 ...t-initialize-curses-when-qemu-is-daemoniz.patch |   90 +
 ...-saturate-escape-parameter-in-TTY_STATE_C.patch |   36 +
 ...Remove-redundant-null-check-and-replace-f.patch |   42 +
 ...Fix-compiler-warning-regression-for-MinGW.patch |   68 +
 ...use-standard-instead-of-native-format-str.patch |   52 +
 ...dd-implementation-of-gmtime_r-localtime_r.patch |   81 +
 ...eserve-readonly-and-snapshot-states-acros.patch |   37 +
 ...ock-correctly-set-the-keep_read_only-flag.patch |  104 +
 ...llow-builds-without-any-system-or-user-em.patch |   59 +
 0232-Refactor-inet_connect_opts-function.patch     |  207 +
 ...et_connect-into-inet_connect-blocking-and.patch |  188 +
 ...ress-handling-in-inet_nonblocking_connect.patch |  369 ++
 0235-Clear-handler-only-for-valid-fd.patch         |   32 +
 0236-pl190-fix-read-of-VECTADDR.patch              |   51 +
 ...vic-Correctly-register-GIC-region-when-se.patch |   40 +
 ...xpress-Fix-NOR-flash-0-address-and-remove.patch |   56 +
 ...it-10-of-CPUID-8000_0001-.EDX-is-reserved.patch |   36 +
 ...at.c-Return-correctly-signed-values-from-.patch |   44 +
 ...-t-test-for-MSR_PR-for-hypercalls-under-K.patch |   66 +
 0242-update-VERSION-for-v1.2.1.patch               |   20 +
 ...out-tcp-socket-close-code-in-a-separate-f.patch |   16 +-
 ...QemuChrHandlers-struct-to-initialise-char.patch |   41 +-
 ...Add-enable-disable_write_fd_handler-funct.patch |   12 +-
 ...-framework-for-a-write-unblocked-callback.patch |   11 +-
 ...-send_all-to-handle-nonblocking-chardev-w.patch |   43 +-
 ...the-unix-tcp-backend-to-handle-nonblockin.patch |   17 +-
 ...har-Throttle-when-host-connection-is-down.patch |   13 +-
 ...ole-Enable-port-throttling-when-chardev-i.patch |   11 +-
 ... => 0408-spice-qemu-char.c-add-throttling.patch |    9 +-
 ...ce-qemu-char.c-remove-intermediate-buffer.patch |    9 +-
 ...> 0410-usb-redir-Add-flow-control-support.patch |   19 +-
 ...serial-bus-replay-guest_open-on-migration.patch |    9 +-
 ...e-write-callback-if-throttled-chardev-is-.patch |   11 +-
 0500-qxl-disallow-unknown-revisions.patch          |   31 +
 ...e-number-of-surfaces-runtime-configurable.patch |   32 +-
 ..._client_capabilities-interface-to-QXLInte.patch |   13 +-
 ...emove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch |   10 +-
 ...pice-switch-to-queue-for-vga-mode-updates.patch |   10 +-
 ...0505-spice-split-qemu_spice_create_update.patch |    6 +-
 ...ror.patch => 0506-spice-add-screen-mirror.patch |    6 +-
 ...d-updates-only-for-changed-screen-content.patch |    6 +-
 ...-set_client_capabilities-pre-post-migrate.patch |    8 +-
 ...> 0509-qxl-add-trace-event-for-QXL_IO_LOG.patch |   10 +-
 ...ort-client-monitor-configuration-via-devi.patch |   19 +-
 ...xl-always-update-displaysurface-on-resize.patch |    6 +-
 ...area_io-cleanup-invalid-parameters-handli.patch |   11 +-
 ...-qxl-fix-range-check-for-rev3-io-commands.patch |   10 +-
 ...-Convert-to-new-libusbredirparser-0.5-API.patch |   36 +-
 ...redir-Set-ep-max_packet_size-if-available.patch |   14 +-
 ...dd-a-usbredir_reject_device-helper-functi.patch |   13 +-
 ...nsure-our-peer-has-the-necessary-caps-whe.patch |   12 +-
 ...edir-Enable-pipelining-for-bulk-endpoints.patch |   10 +-
 ...move-device-lookup-into-xhci_setup_packet.patch |    8 +-
 ...ndex.patch => 0606-xhci-implement-mfindex.patch |   16 +-
 ...pport.patch => 0607-xhci-iso-xfer-support.patch |   16 +-
 ... => 0608-xhci-trace-cc-codes-in-cleartext.patch |   12 +-
 ...09-xhci-add-trace_usb_xhci_ep_set_dequeue.patch |   12 +-
 ...patch => 0610-xhci-update-register-layout.patch |    8 +-
 ...g.patch => 0611-xhci-update-port-handling.patch |   32 +-
 ...patch => 0612-usb3-superspeed-descriptors.patch |    6 +-
 ...> 0613-usb3-superspeed-endpoint-companion.patch |    6 +-
 ...ecriptor.patch => 0614-usb3-bos-decriptor.patch |   10 +-
 ...rt.patch => 0615-usb-storage-usb3-support.patch |    6 +-
 ...up-msi.patch => 0616-xhci-fix-cleanup-msi.patch |    8 +-
 ...ch => 0617-xhci-rework-interrupt-handling.patch |   12 +-
 ...pport.patch => 0618-xhci-add-msix-support.patch |   16 +-
 ...move-register-update-into-xhci_intr_raise.patch |    8 +-
 ...er.patch => 0620-xhci-add-XHCIInterrupter.patch |   26 +-
 ...e-xhci_runtime_-read-write-for-multiple-i.patch |   12 +-
 ...atch => 0622-xhci-pick-target-interrupter.patch |   14 +-
 ...> 0623-xhci-support-multiple-interrupters.patch |    8 +-
 ...xhci_mem_-read-write-dispatcher-functions.patch |   33 +-
 ...hange-cancelled-packet-code-into-a-generi.patch |   16 +-
 ...-Add-an-already_in_flight-packet-id-queue.patch |   20 +-
 ...-redir-Store-max_packet_size-in-endp_data.patch |   10 +-
 ... 0628-usb-redir-Add-support-for-migration.patch |   28 +-
 ...edir-Add-chardev-open-close-debug-logging.patch |   22 +-
 ...-Revert-usb-redir-part-of-commit-93bfef4c.patch |   35 +
 ...1-ehci-Fix-interrupt-packet-MULT-handling.patch |    8 +-
 ...djust-pkg-config-check-for-usbredirparser.patch |   12 +-
 ...hange-usbredir_open_chardev-into-usbredir.patch |    6 +-
 ...on-t-make-migration-fail-in-none-seamless.patch |    7 +-
 ...00-mips-Fix-link-error-with-piix4_pm_init.patch |    4 +-
 ...=> 0801-configure-Add-disable-kvm-options.patch |   16 +-
 qemu.spec                                          |  879 ++-
 309 files changed, 44377 insertions(+), 1068 deletions(-)
---
diff --git a/0001-target-xtensa-convert-host-errno-values-to-guest.patch b/0001-target-xtensa-convert-host-errno-values-to-guest.patch
new file mode 100644
index 0000000..7eb51fe
--- /dev/null
+++ b/0001-target-xtensa-convert-host-errno-values-to-guest.patch
@@ -0,0 +1,183 @@
+From 707f294ca28977968fb85bf36f10c6b37b16f557 Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc at gmail.com>
+Date: Wed, 29 Aug 2012 23:54:25 +0400
+Subject: [PATCH] target-xtensa: convert host errno values to guest
+
+Guest errno values are taken from the newlib. Convert only those errno
+values that can be returned from used system calls.
+
+Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-xtensa/xtensa-semi.c | 106 ++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 98 insertions(+), 8 deletions(-)
+
+diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
+index 6d001c2..e745bef 100644
+--- a/target-xtensa/xtensa-semi.c
++++ b/target-xtensa/xtensa-semi.c
+@@ -54,6 +54,96 @@ enum {
+     SELECT_ONE_EXCEPT = 3,
+ };
+ 
++enum {
++    TARGET_EPERM        =  1,
++    TARGET_ENOENT       =  2,
++    TARGET_ESRCH        =  3,
++    TARGET_EINTR        =  4,
++    TARGET_EIO          =  5,
++    TARGET_ENXIO        =  6,
++    TARGET_E2BIG        =  7,
++    TARGET_ENOEXEC      =  8,
++    TARGET_EBADF        =  9,
++    TARGET_ECHILD       = 10,
++    TARGET_EAGAIN       = 11,
++    TARGET_ENOMEM       = 12,
++    TARGET_EACCES       = 13,
++    TARGET_EFAULT       = 14,
++    TARGET_ENOTBLK      = 15,
++    TARGET_EBUSY        = 16,
++    TARGET_EEXIST       = 17,
++    TARGET_EXDEV        = 18,
++    TARGET_ENODEV       = 19,
++    TARGET_ENOTDIR      = 20,
++    TARGET_EISDIR       = 21,
++    TARGET_EINVAL       = 22,
++    TARGET_ENFILE       = 23,
++    TARGET_EMFILE       = 24,
++    TARGET_ENOTTY       = 25,
++    TARGET_ETXTBSY      = 26,
++    TARGET_EFBIG        = 27,
++    TARGET_ENOSPC       = 28,
++    TARGET_ESPIPE       = 29,
++    TARGET_EROFS        = 30,
++    TARGET_EMLINK       = 31,
++    TARGET_EPIPE        = 32,
++    TARGET_EDOM         = 33,
++    TARGET_ERANGE       = 34,
++    TARGET_ENOSYS       = 88,
++    TARGET_ELOOP        = 92,
++};
++
++static uint32_t errno_h2g(int host_errno)
++{
++    static const uint32_t guest_errno[] = {
++        [EPERM]         = TARGET_EPERM,
++        [ENOENT]        = TARGET_ENOENT,
++        [ESRCH]         = TARGET_ESRCH,
++        [EINTR]         = TARGET_EINTR,
++        [EIO]           = TARGET_EIO,
++        [ENXIO]         = TARGET_ENXIO,
++        [E2BIG]         = TARGET_E2BIG,
++        [ENOEXEC]       = TARGET_ENOEXEC,
++        [EBADF]         = TARGET_EBADF,
++        [ECHILD]        = TARGET_ECHILD,
++        [EAGAIN]        = TARGET_EAGAIN,
++        [ENOMEM]        = TARGET_ENOMEM,
++        [EACCES]        = TARGET_EACCES,
++        [EFAULT]        = TARGET_EFAULT,
++        [ENOTBLK]       = TARGET_ENOTBLK,
++        [EBUSY]         = TARGET_EBUSY,
++        [EEXIST]        = TARGET_EEXIST,
++        [EXDEV]         = TARGET_EXDEV,
++        [ENODEV]        = TARGET_ENODEV,
++        [ENOTDIR]       = TARGET_ENOTDIR,
++        [EISDIR]        = TARGET_EISDIR,
++        [EINVAL]        = TARGET_EINVAL,
++        [ENFILE]        = TARGET_ENFILE,
++        [EMFILE]        = TARGET_EMFILE,
++        [ENOTTY]        = TARGET_ENOTTY,
++        [ETXTBSY]       = TARGET_ETXTBSY,
++        [EFBIG]         = TARGET_EFBIG,
++        [ENOSPC]        = TARGET_ENOSPC,
++        [ESPIPE]        = TARGET_ESPIPE,
++        [EROFS]         = TARGET_EROFS,
++        [EMLINK]        = TARGET_EMLINK,
++        [EPIPE]         = TARGET_EPIPE,
++        [EDOM]          = TARGET_EDOM,
++        [ERANGE]        = TARGET_ERANGE,
++        [ENOSYS]        = TARGET_ENOSYS,
++        [ELOOP]         = TARGET_ELOOP,
++    };
++
++    if (host_errno == 0) {
++        return 0;
++    } else if (host_errno > 0 && host_errno < ARRAY_SIZE(guest_errno) &&
++            guest_errno[host_errno]) {
++        return guest_errno[host_errno];
++    } else {
++        return TARGET_EINVAL;
++    }
++}
++
+ void HELPER(simcall)(CPUXtensaState *env)
+ {
+     uint32_t *regs = env->regs;
+@@ -87,14 +177,14 @@ void HELPER(simcall)(CPUXtensaState *env)
+                     regs[2] = is_write ?
+                         write(fd, buf, io_sz) :
+                         read(fd, buf, io_sz);
+-                    regs[3] = errno;
++                    regs[3] = errno_h2g(errno);
+                     cpu_physical_memory_unmap(buf, sz, is_write, sz);
+                     if (regs[2] == -1) {
+                         break;
+                     }
+                 } else {
+                     regs[2] = -1;
+-                    regs[3] = EINVAL;
++                    regs[3] = TARGET_EINVAL;
+                     break;
+                 }
+             }
+@@ -117,10 +207,10 @@ void HELPER(simcall)(CPUXtensaState *env)
+ 
+             if (rc == 0 && i < ARRAY_SIZE(name)) {
+                 regs[2] = open(name, regs[4], regs[5]);
+-                regs[3] = errno;
++                regs[3] = errno_h2g(errno);
+             } else {
+                 regs[2] = -1;
+-                regs[3] = EINVAL;
++                regs[3] = TARGET_EINVAL;
+             }
+         }
+         break;
+@@ -130,13 +220,13 @@ void HELPER(simcall)(CPUXtensaState *env)
+             regs[2] = regs[3] = 0;
+         } else {
+             regs[2] = close(regs[3]);
+-            regs[3] = errno;
++            regs[3] = errno_h2g(errno);
+         }
+         break;
+ 
+     case TARGET_SYS_lseek:
+         regs[2] = lseek(regs[3], (off_t)(int32_t)regs[4], regs[5]);
+-        regs[3] = errno;
++        regs[3] = errno_h2g(errno);
+         break;
+ 
+     case TARGET_SYS_select_one:
+@@ -163,7 +253,7 @@ void HELPER(simcall)(CPUXtensaState *env)
+                     rq == SELECT_ONE_WRITE  ? &fdset : NULL,
+                     rq == SELECT_ONE_EXCEPT ? &fdset : NULL,
+                     target_tv ? &tv : NULL);
+-            regs[3] = errno;
++            regs[3] = errno_h2g(errno);
+         }
+         break;
+ 
+@@ -219,7 +309,7 @@ void HELPER(simcall)(CPUXtensaState *env)
+     default:
+         qemu_log("%s(%d): not implemented\n", __func__, regs[2]);
+         regs[2] = -1;
+-        regs[3] = ENOSYS;
++        regs[3] = TARGET_ENOSYS;
+         break;
+     }
+ }
+-- 
+1.7.12.1
+
diff --git a/0002-target-cris-Fix-buffer-overflow.patch b/0002-target-cris-Fix-buffer-overflow.patch
new file mode 100644
index 0000000..79640b1
--- /dev/null
+++ b/0002-target-cris-Fix-buffer-overflow.patch
@@ -0,0 +1,35 @@
+From 8057ac10e8cba3acb89c11c94f04967306e55a9f Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Fri, 7 Sep 2012 22:36:08 +0200
+Subject: [PATCH] target-cris: Fix buffer overflow
+
+Report from smatch:
+
+target-cris/translate.c:3464 cpu_dump_state(32) error:
+ buffer overflow 'env->sregs' 4 <= 255
+
+sregs is declared 'uint32_t sregs[4][16]', so the first index must be
+less than 4 or ARRAY_SIZE(env->sregs).
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-cris/translate.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/target-cris/translate.c b/target-cris/translate.c
+index 1ad9ec7..ad31877 100644
+--- a/target-cris/translate.c
++++ b/target-cris/translate.c
+@@ -3458,7 +3458,7 @@ void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf,
+ 	}
+ 	srs = env->pregs[PR_SRS];
+ 	cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
+-	if (srs < 256) {
++	if (srs < ARRAY_SIZE(env->sregs)) {
+ 		for (i = 0; i < 16; i++) {
+ 			cpu_fprintf(f, "s%2.2d=%8.8x ",
+ 				    i, env->sregs[srs][i]);
+-- 
+1.7.12.1
+
diff --git a/0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch b/0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch
new file mode 100644
index 0000000..b5fdd18
--- /dev/null
+++ b/0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch
@@ -0,0 +1,64 @@
+From 33e25a4a6c6dc7632b15ee50637d33b4c3cf729e Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc at gmail.com>
+Date: Thu, 6 Sep 2012 04:36:46 +0400
+Subject: [PATCH] target-xtensa: fix missing errno codes for mingw32
+
+Put the following errno value mappings under #ifdef:
+
+xtensa-semi.c: In function 'errno_h2g':
+xtensa-semi.c:113: error: 'ENOTBLK' undeclared (first use in this function)
+xtensa-semi.c:113: error: (Each undeclared identifier is reported only once
+xtensa-semi.c:113: error: for each function it appears in.)
+xtensa-semi.c:113: error: array index in initializer not of integer type
+xtensa-semi.c:113: error: (near initialization for 'guest_errno')
+xtensa-semi.c:124: error: 'ETXTBSY' undeclared (first use in this function)
+xtensa-semi.c:124: error: array index in initializer not of integer type
+xtensa-semi.c:124: error: (near initialization for 'guest_errno')
+xtensa-semi.c:134: error: 'ELOOP' undeclared (first use in this function)
+xtensa-semi.c:134: error: array index in initializer not of integer type
+xtensa-semi.c:134: error: (near initialization for 'guest_errno')
+
+Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-xtensa/xtensa-semi.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/target-xtensa/xtensa-semi.c b/target-xtensa/xtensa-semi.c
+index e745bef..52be07a 100644
+--- a/target-xtensa/xtensa-semi.c
++++ b/target-xtensa/xtensa-semi.c
+@@ -110,7 +110,9 @@ static uint32_t errno_h2g(int host_errno)
+         [ENOMEM]        = TARGET_ENOMEM,
+         [EACCES]        = TARGET_EACCES,
+         [EFAULT]        = TARGET_EFAULT,
++#ifdef ENOTBLK
+         [ENOTBLK]       = TARGET_ENOTBLK,
++#endif
+         [EBUSY]         = TARGET_EBUSY,
+         [EEXIST]        = TARGET_EEXIST,
+         [EXDEV]         = TARGET_EXDEV,
+@@ -121,7 +123,9 @@ static uint32_t errno_h2g(int host_errno)
+         [ENFILE]        = TARGET_ENFILE,
+         [EMFILE]        = TARGET_EMFILE,
+         [ENOTTY]        = TARGET_ENOTTY,
++#ifdef ETXTBSY
+         [ETXTBSY]       = TARGET_ETXTBSY,
++#endif
+         [EFBIG]         = TARGET_EFBIG,
+         [ENOSPC]        = TARGET_ENOSPC,
+         [ESPIPE]        = TARGET_ESPIPE,
+@@ -131,7 +135,9 @@ static uint32_t errno_h2g(int host_errno)
+         [EDOM]          = TARGET_EDOM,
+         [ERANGE]        = TARGET_ERANGE,
+         [ENOSYS]        = TARGET_ENOSYS,
++#ifdef ELOOP
+         [ELOOP]         = TARGET_ELOOP,
++#endif
+     };
+ 
+     if (host_errno == 0) {
+-- 
+1.7.12.1
+
diff --git a/0004-target-sparc-fix-fcmp-s-d-q-instructions-wrt-excepti.patch b/0004-target-sparc-fix-fcmp-s-d-q-instructions-wrt-excepti.patch
new file mode 100644
index 0000000..e6095aa
--- /dev/null
+++ b/0004-target-sparc-fix-fcmp-s-d-q-instructions-wrt-excepti.patch
@@ -0,0 +1,133 @@
+From 5e955b895d4a92cdc49c7b4e76284483d49aa4b8 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 7 Sep 2012 17:13:28 +0200
+Subject: [PATCH] target-sparc: fix fcmp{s,d,q} instructions wrt exception
+
+fcmp{s,d,q} instructions are supposed to ignore quiet NaN (contrary to
+the fcmpe{s,d,q} instructions), but the current code is wrongly setting
+the NV exception in that case. Moreover the current code is duplicated:
+first the arguments are checked for NaN to generate an exception, and
+later in case the comparison is unordered (which can only happens if one
+of the argument is a NaN), the same check is done to generate an
+exception.
+
+Fix that by calling clear_float_exceptions() followed by
+check_ieee_exceptions() as for the other floating point instructions.
+Use the _compare_quiet functions for fcmp{s,d,q} and the _compare ones
+for fcmpe{s,d,q}. Simplify the flag setting by not clearing a flag that
+is set the line just below.
+
+This fix allows the math glibc testsuite to pass.
+
+Cc: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-sparc/fop_helper.c | 67 +++++++++++++++++++----------------------------
+ 1 file changed, 27 insertions(+), 40 deletions(-)
+
+diff --git a/target-sparc/fop_helper.c b/target-sparc/fop_helper.c
+index 9c64ef8..f4b62a5 100644
+--- a/target-sparc/fop_helper.c
++++ b/target-sparc/fop_helper.c
+@@ -334,34 +334,28 @@ void helper_fsqrtq(CPUSPARCState *env)
+ }
+ 
+ #define GEN_FCMP(name, size, reg1, reg2, FS, E)                         \
+-    void glue(helper_, name) (CPUSPARCState *env)                            \
++    void glue(helper_, name) (CPUSPARCState *env)                       \
+     {                                                                   \
+-        env->fsr &= FSR_FTT_NMASK;                                      \
+-        if (E && (glue(size, _is_any_nan)(reg1) ||                      \
+-                  glue(size, _is_any_nan)(reg2)) &&                     \
+-            (env->fsr & FSR_NVM)) {                                     \
+-            env->fsr |= FSR_NVC;                                        \
+-            env->fsr |= FSR_FTT_IEEE_EXCP;                              \
+-            helper_raise_exception(env, TT_FP_EXCP);                    \
++        int ret;                                                        \
++        clear_float_exceptions(env);                                    \
++        if (E) {                                                        \
++            ret = glue(size, _compare)(reg1, reg2, &env->fp_status);    \
++        } else {                                                        \
++            ret = glue(size, _compare_quiet)(reg1, reg2,                \
++                                             &env->fp_status);          \
+         }                                                               \
+-        switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) {   \
++        check_ieee_exceptions(env);                                     \
++        switch (ret) {                                                  \
+         case float_relation_unordered:                                  \
+-            if ((env->fsr & FSR_NVM)) {                                 \
+-                env->fsr |= FSR_NVC;                                    \
+-                env->fsr |= FSR_FTT_IEEE_EXCP;                          \
+-                helper_raise_exception(env, TT_FP_EXCP);                \
+-            } else {                                                    \
+-                env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);             \
+-                env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                \
+-                env->fsr |= FSR_NVA;                                    \
+-            }                                                           \
++            env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                    \
++            env->fsr |= FSR_NVA;                                        \
+             break;                                                      \
+         case float_relation_less:                                       \
+-            env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                 \
++            env->fsr &= ~(FSR_FCC1) << FS;                              \
+             env->fsr |= FSR_FCC0 << FS;                                 \
+             break;                                                      \
+         case float_relation_greater:                                    \
+-            env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                 \
++            env->fsr &= ~(FSR_FCC0) << FS;                              \
+             env->fsr |= FSR_FCC1 << FS;                                 \
+             break;                                                      \
+         default:                                                        \
+@@ -370,34 +364,27 @@ void helper_fsqrtq(CPUSPARCState *env)
+         }                                                               \
+     }
+ #define GEN_FCMP_T(name, size, FS, E)                                   \
+-    void glue(helper_, name)(CPUSPARCState *env, size src1, size src2)       \
++    void glue(helper_, name)(CPUSPARCState *env, size src1, size src2)  \
+     {                                                                   \
+-        env->fsr &= FSR_FTT_NMASK;                                      \
+-        if (E && (glue(size, _is_any_nan)(src1) ||                      \
+-                  glue(size, _is_any_nan)(src2)) &&                     \
+-            (env->fsr & FSR_NVM)) {                                     \
+-            env->fsr |= FSR_NVC;                                        \
+-            env->fsr |= FSR_FTT_IEEE_EXCP;                              \
+-            helper_raise_exception(env, TT_FP_EXCP);                    \
++        int ret;                                                        \
++        clear_float_exceptions(env);                                    \
++        if (E) {                                                        \
++            ret = glue(size, _compare)(src1, src2, &env->fp_status);    \
++        } else {                                                        \
++            ret = glue(size, _compare_quiet)(src1, src2,                \
++                                             &env->fp_status);          \
+         }                                                               \
+-        switch (glue(size, _compare) (src1, src2, &env->fp_status)) {   \
++        check_ieee_exceptions(env);                                     \
++        switch (ret) {                                                  \
+         case float_relation_unordered:                                  \
+-            if ((env->fsr & FSR_NVM)) {                                 \
+-                env->fsr |= FSR_NVC;                                    \
+-                env->fsr |= FSR_FTT_IEEE_EXCP;                          \
+-                helper_raise_exception(env, TT_FP_EXCP);                \
+-            } else {                                                    \
+-                env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);             \
+-                env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                \
+-                env->fsr |= FSR_NVA;                                    \
+-            }                                                           \
++            env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                    \
+             break;                                                      \
+         case float_relation_less:                                       \
+-            env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                 \
++            env->fsr &= ~(FSR_FCC1 << FS);                              \
+             env->fsr |= FSR_FCC0 << FS;                                 \
+             break;                                                      \
+         case float_relation_greater:                                    \
+-            env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                 \
++            env->fsr &= ~(FSR_FCC0 << FS);                              \
+             env->fsr |= FSR_FCC1 << FS;                                 \
+             break;                                                      \
+         default:                                                        \
+-- 
+1.7.12.1
+
diff --git a/0005-target-s390x-fix-style.patch b/0005-target-s390x-fix-style.patch
new file mode 100644
index 0000000..0f0a63e
--- /dev/null
+++ b/0005-target-s390x-fix-style.patch
@@ -0,0 +1,1603 @@
+From 985b8342244b5f76ed1df75eb8757d6feff30316 Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:30 +0000
+Subject: [PATCH] target-s390x: fix style
+
+Before splitting op_helper.c and helper.c in the next patches,
+fix style issues. No functional changes.
+
+Replace also GCC specific __FUNCTION__ with
+standard __func__.
+
+Don't init static variable (cpu_s390x_init:inited) with 0.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/helper.c    |  96 ++++++-----
+ target-s390x/op_helper.c | 438 +++++++++++++++++++++++++++--------------------
+ 2 files changed, 297 insertions(+), 237 deletions(-)
+
+diff --git a/target-s390x/helper.c b/target-s390x/helper.c
+index d0a1180..d98e6d9 100644
+--- a/target-s390x/helper.c
++++ b/target-s390x/helper.c
+@@ -74,7 +74,7 @@ S390CPU *cpu_s390x_init(const char *cpu_model)
+ {
+     S390CPU *cpu;
+     CPUS390XState *env;
+-    static int inited = 0;
++    static int inited;
+ 
+     cpu = S390_CPU(object_new(TYPE_S390_CPU));
+     env = &cpu->env;
+@@ -91,25 +91,27 @@ S390CPU *cpu_s390x_init(const char *cpu_model)
+ 
+ #if defined(CONFIG_USER_ONLY)
+ 
+-void do_interrupt (CPUS390XState *env)
++void do_interrupt(CPUS390XState *env)
+ {
+     env->exception_index = -1;
+ }
+ 
+-int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw,
+-                                int mmu_idx)
++int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong address,
++                               int rw, int mmu_idx)
+ {
+-    /* fprintf(stderr,"%s: address 0x%lx rw %d mmu_idx %d\n",
+-            __FUNCTION__, address, rw, mmu_idx); */
++    /* fprintf(stderr, "%s: address 0x%lx rw %d mmu_idx %d\n",
++       __func__, address, rw, mmu_idx); */
+     env->exception_index = EXCP_ADDR;
+-    env->__excp_addr = address; /* FIXME: find out how this works on a real machine */
++    /* FIXME: find out how this works on a real machine */
++    env->__excp_addr = address;
+     return 1;
+ }
+ 
+ #else /* !CONFIG_USER_ONLY */
+ 
+ /* Ensure to exit the TB after this call! */
+-static void trigger_pgm_exception(CPUS390XState *env, uint32_t code, uint32_t ilc)
++static void trigger_pgm_exception(CPUS390XState *env, uint32_t code,
++                                  uint32_t ilc)
+ {
+     env->exception_index = EXCP_PGM;
+     env->int_pgm_code = code;
+@@ -138,19 +140,20 @@ static int trans_bits(CPUS390XState *env, uint64_t mode)
+     return bits;
+ }
+ 
+-static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr, uint64_t mode)
++static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
++                               uint64_t mode)
+ {
+     int ilc = ILC_LATER_INC_2;
+     int bits = trans_bits(env, mode) | 4;
+ 
+-    DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __FUNCTION__, vaddr, bits);
++    DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
+ 
+     stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
+     trigger_pgm_exception(env, PGM_PROTECTION, ilc);
+ }
+ 
+-static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr, uint32_t type,
+-                               uint64_t asc, int rw)
++static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
++                               uint32_t type, uint64_t asc, int rw)
+ {
+     int ilc = ILC_LATER;
+     int bits = trans_bits(env, asc);
+@@ -160,26 +163,26 @@ static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr, uint32_t
+         ilc = 2;
+     }
+ 
+-    DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __FUNCTION__, vaddr, bits);
++    DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
+ 
+     stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
+     trigger_pgm_exception(env, type, ilc);
+ }
+ 
+-static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t asc,
+-                              uint64_t asce, int level, target_ulong *raddr,
+-                              int *flags, int rw)
++static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
++                              uint64_t asc, uint64_t asce, int level,
++                              target_ulong *raddr, int *flags, int rw)
+ {
+     uint64_t offs = 0;
+     uint64_t origin;
+     uint64_t new_asce;
+ 
+-    PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __FUNCTION__, asce);
++    PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __func__, asce);
+ 
+     if (((level != _ASCE_TYPE_SEGMENT) && (asce & _REGION_ENTRY_INV)) ||
+         ((level == _ASCE_TYPE_SEGMENT) && (asce & _SEGMENT_ENTRY_INV))) {
+         /* XXX different regions have different faults */
+-        DPRINTF("%s: invalid region\n", __FUNCTION__);
++        DPRINTF("%s: invalid region\n", __func__);
+         trigger_page_fault(env, vaddr, PGM_SEGMENT_TRANS, asc, rw);
+         return -1;
+     }
+@@ -222,7 +225,7 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t a
+ 
+     new_asce = ldq_phys(origin + offs);
+     PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n",
+-                __FUNCTION__, origin, offs, new_asce);
++                __func__, origin, offs, new_asce);
+ 
+     if (level != _ASCE_TYPE_SEGMENT) {
+         /* yet another region */
+@@ -232,7 +235,7 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t a
+ 
+     /* PTE */
+     if (new_asce & _PAGE_INVALID) {
+-        DPRINTF("%s: PTE=0x%" PRIx64 " invalid\n", __FUNCTION__, new_asce);
++        DPRINTF("%s: PTE=0x%" PRIx64 " invalid\n", __func__, new_asce);
+         trigger_page_fault(env, vaddr, PGM_PAGE_TRANS, asc, rw);
+         return -1;
+     }
+@@ -243,13 +246,14 @@ static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t a
+ 
+     *raddr = new_asce & _ASCE_ORIGIN;
+ 
+-    PTE_DPRINTF("%s: PTE=0x%" PRIx64 "\n", __FUNCTION__, new_asce);
++    PTE_DPRINTF("%s: PTE=0x%" PRIx64 "\n", __func__, new_asce);
+ 
+     return 0;
+ }
+ 
+-static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t asc,
+-                             target_ulong *raddr, int *flags, int rw)
++static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr,
++                             uint64_t asc, target_ulong *raddr, int *flags,
++                             int rw)
+ {
+     uint64_t asce = 0;
+     int level, new_level;
+@@ -257,15 +261,15 @@ static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t as
+ 
+     switch (asc) {
+     case PSW_ASC_PRIMARY:
+-        PTE_DPRINTF("%s: asc=primary\n", __FUNCTION__);
++        PTE_DPRINTF("%s: asc=primary\n", __func__);
+         asce = env->cregs[1];
+         break;
+     case PSW_ASC_SECONDARY:
+-        PTE_DPRINTF("%s: asc=secondary\n", __FUNCTION__);
++        PTE_DPRINTF("%s: asc=secondary\n", __func__);
+         asce = env->cregs[7];
+         break;
+     case PSW_ASC_HOME:
+-        PTE_DPRINTF("%s: asc=home\n", __FUNCTION__);
++        PTE_DPRINTF("%s: asc=home\n", __func__);
+         asce = env->cregs[13];
+         break;
+     }
+@@ -276,8 +280,7 @@ static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t as
+     case _ASCE_TYPE_REGION2:
+         if (vaddr & 0xffe0000000000000ULL) {
+             DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64
+-                        " 0xffe0000000000000ULL\n", __FUNCTION__,
+-                        vaddr);
++                    " 0xffe0000000000000ULL\n", __func__, vaddr);
+             trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw);
+             return -1;
+         }
+@@ -285,8 +288,7 @@ static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t as
+     case _ASCE_TYPE_REGION3:
+         if (vaddr & 0xfffffc0000000000ULL) {
+             DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64
+-                        " 0xfffffc0000000000ULL\n", __FUNCTION__,
+-                        vaddr);
++                    " 0xfffffc0000000000ULL\n", __func__, vaddr);
+             trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw);
+             return -1;
+         }
+@@ -294,8 +296,7 @@ static int mmu_translate_asc(CPUS390XState *env, target_ulong vaddr, uint64_t as
+     case _ASCE_TYPE_SEGMENT:
+         if (vaddr & 0xffffffff80000000ULL) {
+             DPRINTF("%s: vaddr doesn't fit 0x%16" PRIx64
+-                        " 0xffffffff80000000ULL\n", __FUNCTION__,
+-                        vaddr);
++                    " 0xffffffff80000000ULL\n", __func__, vaddr);
+             trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw);
+             return -1;
+         }
+@@ -358,7 +359,7 @@ int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc,
+         break;
+     }
+ 
+-out:
++ out:
+     /* Convert real address -> absolute address */
+     if (*raddr < 0x2000) {
+         *raddr = *raddr + env->psa;
+@@ -378,18 +379,18 @@ out:
+     return r;
+ }
+ 
+-int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong _vaddr, int rw,
+-                                int mmu_idx)
++int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
++                               int rw, int mmu_idx)
+ {
+     uint64_t asc = env->psw.mask & PSW_MASK_ASC;
+     target_ulong vaddr, raddr;
+     int prot;
+ 
+     DPRINTF("%s: address 0x%" PRIx64 " rw %d mmu_idx %d\n",
+-            __FUNCTION__, _vaddr, rw, mmu_idx);
++            __func__, _vaddr, rw, mmu_idx);
+ 
+-    _vaddr &= TARGET_PAGE_MASK;
+-    vaddr = _vaddr;
++    orig_vaddr &= TARGET_PAGE_MASK;
++    vaddr = orig_vaddr;
+ 
+     /* 31-Bit mode */
+     if (!(env->psw.mask & PSW_MASK_64)) {
+@@ -403,22 +404,23 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong _vaddr, int rw,
+ 
+     /* check out of RAM access */
+     if (raddr > (ram_size + virtio_size)) {
+-        DPRINTF("%s: aaddr %" PRIx64 " > ram_size %" PRIx64 "\n", __FUNCTION__,
++        DPRINTF("%s: aaddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,
+                 (uint64_t)aaddr, (uint64_t)ram_size);
+         trigger_pgm_exception(env, PGM_ADDRESSING, ILC_LATER);
+         return 1;
+     }
+ 
+-    DPRINTF("%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n", __FUNCTION__,
++    DPRINTF("%s: set tlb %" PRIx64 " -> %" PRIx64 " (%x)\n", __func__,
+             (uint64_t)vaddr, (uint64_t)raddr, prot);
+ 
+-    tlb_set_page(env, _vaddr, raddr, prot,
++    tlb_set_page(env, orig_vaddr, raddr, prot,
+                  mmu_idx, TARGET_PAGE_SIZE);
+ 
+     return 0;
+ }
+ 
+-target_phys_addr_t cpu_get_phys_page_debug(CPUS390XState *env, target_ulong vaddr)
++target_phys_addr_t cpu_get_phys_page_debug(CPUS390XState *env,
++                                           target_ulong vaddr)
+ {
+     target_ulong raddr;
+     int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+@@ -509,7 +511,7 @@ static void do_program_interrupt(CPUS390XState *env)
+         break;
+     }
+ 
+-    qemu_log("%s: code=0x%x ilc=%d\n", __FUNCTION__, env->int_pgm_code, ilc);
++    qemu_log("%s: code=0x%x ilc=%d\n", __func__, env->int_pgm_code, ilc);
+ 
+     lowcore = cpu_physical_memory_map(env->psa, &len, 1);
+ 
+@@ -522,7 +524,7 @@ static void do_program_interrupt(CPUS390XState *env)
+ 
+     cpu_physical_memory_unmap(lowcore, len, 1, len);
+ 
+-    DPRINTF("%s: %x %x %" PRIx64 " %" PRIx64 "\n", __FUNCTION__,
++    DPRINTF("%s: %x %x %" PRIx64 " %" PRIx64 "\n", __func__,
+             env->int_pgm_code, ilc, env->psw.mask,
+             env->psw.addr);
+ 
+@@ -565,15 +567,15 @@ static void do_ext_interrupt(CPUS390XState *env)
+         env->pending_int &= ~INTERRUPT_EXT;
+     }
+ 
+-    DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __FUNCTION__,
++    DPRINTF("%s: %" PRIx64 " %" PRIx64 "\n", __func__,
+             env->psw.mask, env->psw.addr);
+ 
+     load_psw(env, mask, addr);
+ }
+ 
+-void do_interrupt (CPUS390XState *env)
++void do_interrupt(CPUS390XState *env)
+ {
+-    qemu_log("%s: %d at pc=%" PRIx64 "\n", __FUNCTION__, env->exception_index,
++    qemu_log("%s: %d at pc=%" PRIx64 "\n", __func__, env->exception_index,
+              env->psw.addr);
+ 
+     s390_add_running_cpu(env);
+diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
+index abc35dd..195e93e 100644
+--- a/target-s390x/op_helper.c
++++ b/target-s390x/op_helper.c
+@@ -31,13 +31,13 @@
+ #include <linux/kvm.h>
+ #endif
+ 
+-#if !defined (CONFIG_USER_ONLY)
++#if !defined(CONFIG_USER_ONLY)
+ #include "sysemu.h"
+ #endif
+ 
+ /*****************************************************************************/
+ /* Softmmu support */
+-#if !defined (CONFIG_USER_ONLY)
++#if !defined(CONFIG_USER_ONLY)
+ #include "softmmu_exec.h"
+ 
+ #define MMUSUFFIX _mmu
+@@ -95,7 +95,7 @@ void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
+ /* raise an exception */
+ void HELPER(exception)(uint32_t excp)
+ {
+-    HELPER_LOG("%s: exception %d\n", __FUNCTION__, excp);
++    HELPER_LOG("%s: exception %d\n", __func__, excp);
+     env->exception_index = excp;
+     cpu_loop_exit(env);
+ }
+@@ -164,7 +164,7 @@ uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
+     uint32_t cc = 0;
+ 
+     HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+-               __FUNCTION__, l, dest, src);
++               __func__, l, dest, src);
+     for (i = 0; i <= l; i++) {
+         x = ldub(dest + i) & ldub(src + i);
+         if (x) {
+@@ -183,7 +183,7 @@ uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
+     uint32_t cc = 0;
+ 
+     HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+-               __FUNCTION__, l, dest, src);
++               __func__, l, dest, src);
+ 
+ #ifndef CONFIG_USER_ONLY
+     /* xor with itself is the same as memset(0) */
+@@ -217,7 +217,7 @@ uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
+     uint32_t cc = 0;
+ 
+     HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+-               __FUNCTION__, l, dest, src);
++               __func__, l, dest, src);
+     for (i = 0; i <= l; i++) {
+         x = ldub(dest + i) | ldub(src + i);
+         if (x) {
+@@ -236,7 +236,7 @@ void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
+     uint32_t l_64 = (l + 1) / 8;
+ 
+     HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+-               __FUNCTION__, l, dest, src);
++               __func__, l, dest, src);
+ 
+ #ifndef CONFIG_USER_ONLY
+     if ((l > 32) &&
+@@ -278,10 +278,11 @@ void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
+ uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
+ {
+     int i;
+-    unsigned char x,y;
++    unsigned char x, y;
+     uint32_t cc;
++
+     HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
+-               __FUNCTION__, l, s1, s2);
++               __func__, l, s1, s2);
+     for (i = 0; i <= l; i++) {
+         x = ldub(s1 + i);
+         y = ldub(s2 + i);
+@@ -295,7 +296,7 @@ uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
+         }
+     }
+     cc = 0;
+-done:
++ done:
+     HELPER_LOG("\n");
+     return cc;
+ }
+@@ -303,9 +304,10 @@ done:
+ /* compare logical under mask */
+ uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
+ {
+-    uint8_t r,d;
++    uint8_t r, d;
+     uint32_t cc;
+-    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __FUNCTION__, r1,
++
++    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1,
+                mask, addr);
+     cc = 0;
+     while (mask) {
+@@ -313,7 +315,7 @@ uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
+             d = ldub(addr);
+             r = (r1 & 0xff000000UL) >> 24;
+             HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
+-                        addr);
++                       addr);
+             if (r < d) {
+                 cc = 1;
+                 break;
+@@ -334,7 +336,8 @@ uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
+ void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
+ {
+     uint8_t r;
+-    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __FUNCTION__, r1, mask,
++
++    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __func__, r1, mask,
+                addr);
+     while (mask) {
+         if (mask & 8) {
+@@ -355,6 +358,7 @@ void HELPER(mlg)(uint32_t r1, uint64_t v2)
+ #if HOST_LONG_BITS == 64 && defined(__GNUC__)
+     /* assuming 64-bit hosts have __uint128_t */
+     __uint128_t res = (__uint128_t)env->regs[r1 + 1];
++
+     res *= (__uint128_t)v2;
+     env->regs[r1] = (uint64_t)(res >> 64);
+     env->regs[r1 + 1] = (uint64_t)res;
+@@ -370,18 +374,18 @@ void HELPER(dlg)(uint32_t r1, uint64_t v2)
+ 
+     if (!env->regs[r1]) {
+         /* 64 -> 64/64 case */
+-        env->regs[r1] = env->regs[r1+1] % divisor;
+-        env->regs[r1+1] = env->regs[r1+1] / divisor;
++        env->regs[r1] = env->regs[r1 + 1] % divisor;
++        env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
+         return;
+     } else {
+-
+ #if HOST_LONG_BITS == 64 && defined(__GNUC__)
+         /* assuming 64-bit hosts have __uint128_t */
+         __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
+-                               (env->regs[r1+1]);
++            (env->regs[r1 + 1]);
+         __uint128_t quotient = dividend / divisor;
+-        env->regs[r1+1] = quotient;
+         __uint128_t remainder = dividend % divisor;
++
++        env->regs[r1 + 1] = quotient;
+         env->regs[r1] = remainder;
+ #else
+         /* 32-bit hosts would need special wrapper functionality - just abort if
+@@ -431,7 +435,7 @@ uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
+     uint64_t str = get_address_31fix(r2);
+     uint64_t end = get_address_31fix(r1);
+ 
+-    HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __FUNCTION__,
++    HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
+                c, env->regs[r1], env->regs[r2]);
+ 
+     for (i = str; i != end; i++) {
+@@ -452,11 +456,12 @@ uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
+     uint64_t s2 = get_address_31fix(r2);
+     uint8_t v1, v2;
+     uint32_t cc;
++
+     c = c & 0xff;
+ #ifdef CONFIG_USER_ONLY
+     if (!c) {
+         HELPER_LOG("%s: comparing '%s' and '%s'\n",
+-                   __FUNCTION__, (char*)g2h(s1), (char*)g2h(s2));
++                   __func__, (char *)g2h(s1), (char *)g2h(s2));
+     }
+ #endif
+     for (;;) {
+@@ -501,10 +506,11 @@ void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
+     uint64_t dest = get_address_31fix(r1);
+     uint64_t src = get_address_31fix(r2);
+     uint8_t v;
++
+     c = c & 0xff;
+ #ifdef CONFIG_USER_ONLY
+     if (!c) {
+-        HELPER_LOG("%s: copy '%s' to 0x%lx\n", __FUNCTION__, (char*)g2h(src),
++        HELPER_LOG("%s: copy '%s' to 0x%lx\n", __func__, (char *)g2h(src),
+                    dest);
+     }
+ #endif
+@@ -526,6 +532,7 @@ uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
+     /* FIXME: locking? */
+     uint32_t cc;
+     uint64_t v2 = ldq(a2);
++
+     if (env->regs[r1] == v2) {
+         cc = 0;
+         stq(a2, env->regs[r3]);
+@@ -564,8 +571,9 @@ uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+     /* FIXME: locking? */
+     uint32_t cc;
+-    HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __FUNCTION__, r1, a2, r3);
+     uint32_t v2 = ldl(a2);
++
++    HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
+     if (((uint32_t)env->regs[r1]) == v2) {
+         cc = 0;
+         stl(a2, (uint32_t)env->regs[r3]);
+@@ -612,14 +620,16 @@ static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
+    it does not change the program counter
+    in other words: tricky...
+    currently implemented by interpreting the cases it is most commonly used in
+- */
++*/
+ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+ {
+     uint16_t insn = lduw_code(addr);
+-    HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __FUNCTION__, v1, addr,
+-             insn);
++
++    HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
++               insn);
+     if ((insn & 0xf0ff) == 0xd000) {
+         uint32_t l, insn2, b1, b2, d1, d2;
++
+         l = v1 & 0xff;
+         insn2 = ldl_code(addr + 2);
+         b1 = (insn2 >> 28) & 0xf;
+@@ -645,13 +655,14 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+         }
+     } else if ((insn & 0xff00) == 0x0a00) {
+         /* supervisor call */
+-        HELPER_LOG("%s: svc %ld via execute\n", __FUNCTION__, (insn|v1) & 0xff);
++        HELPER_LOG("%s: svc %ld via execute\n", __func__, (insn | v1) & 0xff);
+         env->psw.addr = ret - 4;
+-        env->int_svc_code = (insn|v1) & 0xff;
++        env->int_svc_code = (insn | v1) & 0xff;
+         env->int_svc_ilc = 4;
+         helper_exception(EXCP_SVC);
+     } else if ((insn & 0xff00) == 0xbf00) {
+         uint32_t insn2, r1, r3, b2, d2;
++
+         insn2 = ldl_code(addr + 2);
+         r1 = (insn2 >> 20) & 0xf;
+         r3 = (insn2 >> 16) & 0xf;
+@@ -659,7 +670,7 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+         d2 = insn2 & 0xfff;
+         cc = helper_icm(r1, get_address(0, b2, d2), r3);
+     } else {
+-abort:
++    abort:
+         cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
+                   insn);
+     }
+@@ -689,7 +700,7 @@ int32_t HELPER(nabs_i32)(int32_t val)
+ /* absolute value 64-bit */
+ uint64_t HELPER(abs_i64)(int64_t val)
+ {
+-    HELPER_LOG("%s: val 0x%" PRIx64 "\n", __FUNCTION__, val);
++    HELPER_LOG("%s: val 0x%" PRIx64 "\n", __func__, val);
+ 
+     if (val < 0) {
+         return -val;
+@@ -774,9 +785,9 @@ void HELPER(ipm)(uint32_t cc, uint32_t r1)
+     uint64_t r = env->regs[r1];
+ 
+     r &= 0xffffffff00ffffffULL;
+-    r |= (cc << 28) | ( (env->psw.mask >> 40) & 0xf );
++    r |= (cc << 28) | ((env->psw.mask >> 40) & 0xf);
+     env->regs[r1] = r;
+-    HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __FUNCTION__,
++    HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __func__,
+                cc, env->psw.mask, r);
+ }
+ 
+@@ -908,7 +919,7 @@ uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+     uint64_t srclen = env->regs[r3 + 1];
+     uint64_t src = get_address_31fix(r3);
+     uint8_t pad = a2 & 0xff;
+-    uint8_t v1 = 0,v2 = 0;
++    uint8_t v1 = 0, v2 = 0;
+     uint32_t cc = 0;
+ 
+     if (!(destlen || srclen)) {
+@@ -1036,7 +1047,7 @@ static uint32_t set_cc_nz_f128(float128 v)
+ /* convert 32-bit int to 64-bit float */
+ void HELPER(cdfbr)(uint32_t f1, int32_t v2)
+ {
+-    HELPER_LOG("%s: converting %d to f%d\n", __FUNCTION__, v2, f1);
++    HELPER_LOG("%s: converting %d to f%d\n", __func__, v2, f1);
+     env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status);
+ }
+ 
+@@ -1044,6 +1055,7 @@ void HELPER(cdfbr)(uint32_t f1, int32_t v2)
+ void HELPER(cxfbr)(uint32_t f1, int32_t v2)
+ {
+     CPU_QuadU v1;
++
+     v1.q = int32_to_float128(v2, &env->fpu_status);
+     env->fregs[f1].ll = v1.ll.upper;
+     env->fregs[f1 + 2].ll = v1.ll.lower;
+@@ -1052,14 +1064,14 @@ void HELPER(cxfbr)(uint32_t f1, int32_t v2)
+ /* convert 64-bit int to 32-bit float */
+ void HELPER(cegbr)(uint32_t f1, int64_t v2)
+ {
+-    HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1);
++    HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
+     env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status);
+ }
+ 
+ /* convert 64-bit int to 64-bit float */
+ void HELPER(cdgbr)(uint32_t f1, int64_t v2)
+ {
+-    HELPER_LOG("%s: converting %ld to f%d\n", __FUNCTION__, v2, f1);
++    HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
+     env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status);
+ }
+ 
+@@ -1067,8 +1079,9 @@ void HELPER(cdgbr)(uint32_t f1, int64_t v2)
+ void HELPER(cxgbr)(uint32_t f1, int64_t v2)
+ {
+     CPU_QuadU x1;
++
+     x1.q = int64_to_float128(v2, &env->fpu_status);
+-    HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __FUNCTION__, v2,
++    HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __func__, v2,
+                x1.ll.upper, x1.ll.lower);
+     env->fregs[f1].ll = x1.ll.upper;
+     env->fregs[f1 + 2].ll = x1.ll.lower;
+@@ -1078,7 +1091,7 @@ void HELPER(cxgbr)(uint32_t f1, int64_t v2)
+ void HELPER(cefbr)(uint32_t f1, int32_t v2)
+ {
+     env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status);
+-    HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __FUNCTION__, v2,
++    HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __func__, v2,
+                env->fregs[f1].l.upper, f1);
+ }
+ 
+@@ -1088,7 +1101,7 @@ uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
+     env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
+                                          env->fregs[f2].l.upper,
+                                          &env->fpu_status);
+-    HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__,
++    HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
+                env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
+ 
+     return set_cc_nz_f32(env->fregs[f1].l.upper);
+@@ -1099,7 +1112,7 @@ uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d,
+                                    &env->fpu_status);
+-    HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __FUNCTION__,
++    HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __func__,
+                env->fregs[f2].d, env->fregs[f1].d, f1);
+ 
+     return set_cc_nz_f64(env->fregs[f1].d);
+@@ -1111,7 +1124,7 @@ uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
+     env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper,
+                                          env->fregs[f2].l.upper,
+                                          &env->fpu_status);
+-    HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __FUNCTION__,
++    HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
+                env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
+ 
+     return set_cc_nz_f32(env->fregs[f1].l.upper);
+@@ -1123,7 +1136,7 @@ uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
+     env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d,
+                                    &env->fpu_status);
+     HELPER_LOG("%s: subtracting 0x%ld resulting in 0x%ld in f%d\n",
+-               __FUNCTION__, env->fregs[f2].d, env->fregs[f1].d, f1);
++               __func__, env->fregs[f2].d, env->fregs[f1].d, f1);
+ 
+     return set_cc_nz_f64(env->fregs[f1].d);
+ }
+@@ -1140,12 +1153,13 @@ void HELPER(debr)(uint32_t f1, uint32_t f2)
+ void HELPER(dxbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
++    CPU_QuadU v2;
++    CPU_QuadU res;
++
+     v1.ll.upper = env->fregs[f1].ll;
+     v1.ll.lower = env->fregs[f1 + 2].ll;
+-    CPU_QuadU v2;
+     v2.ll.upper = env->fregs[f2].ll;
+     v2.ll.lower = env->fregs[f2 + 2].ll;
+-    CPU_QuadU res;
+     res.q = float128_div(v1.q, v2.q, &env->fpu_status);
+     env->fregs[f1].ll = res.ll.upper;
+     env->fregs[f1 + 2].ll = res.ll.lower;
+@@ -1162,12 +1176,13 @@ void HELPER(mdbr)(uint32_t f1, uint32_t f2)
+ void HELPER(mxbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
++    CPU_QuadU v2;
++    CPU_QuadU res;
++
+     v1.ll.upper = env->fregs[f1].ll;
+     v1.ll.lower = env->fregs[f1 + 2].ll;
+-    CPU_QuadU v2;
+     v2.ll.upper = env->fregs[f2].ll;
+     v2.ll.lower = env->fregs[f2 + 2].ll;
+-    CPU_QuadU res;
+     res.q = float128_mul(v1.q, v2.q, &env->fpu_status);
+     env->fregs[f1].ll = res.ll.upper;
+     env->fregs[f1 + 2].ll = res.ll.lower;
+@@ -1184,16 +1199,18 @@ void HELPER(ldebr)(uint32_t r1, uint32_t r2)
+ void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU x2;
++
+     x2.ll.upper = env->fregs[f2].ll;
+     x2.ll.lower = env->fregs[f2 + 2].ll;
+     env->fregs[f1].d = float128_to_float64(x2.q, &env->fpu_status);
+-    HELPER_LOG("%s: to 0x%ld\n", __FUNCTION__, env->fregs[f1].d);
++    HELPER_LOG("%s: to 0x%ld\n", __func__, env->fregs[f1].d);
+ }
+ 
+ /* convert 64-bit float to 128-bit float */
+ void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU res;
++
+     res.q = float64_to_float128(env->fregs[f2].d, &env->fpu_status);
+     env->fregs[f1].ll = res.ll.upper;
+     env->fregs[f1 + 2].ll = res.ll.lower;
+@@ -1203,6 +1220,7 @@ void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
+ void HELPER(ledbr)(uint32_t f1, uint32_t f2)
+ {
+     float64 d2 = env->fregs[f2].d;
++
+     env->fregs[f1].l.upper = float64_to_float32(d2, &env->fpu_status);
+ }
+ 
+@@ -1210,10 +1228,11 @@ void HELPER(ledbr)(uint32_t f1, uint32_t f2)
+ void HELPER(lexbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU x2;
++
+     x2.ll.upper = env->fregs[f2].ll;
+     x2.ll.lower = env->fregs[f2 + 2].ll;
+     env->fregs[f1].l.upper = float128_to_float32(x2.q, &env->fpu_status);
+-    HELPER_LOG("%s: to 0x%d\n", __FUNCTION__, env->fregs[f1].l.upper);
++    HELPER_LOG("%s: to 0x%d\n", __func__, env->fregs[f1].l.upper);
+ }
+ 
+ /* absolute value of 32-bit float */
+@@ -1221,6 +1240,7 @@ uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
+ {
+     float32 v1;
+     float32 v2 = env->fregs[f2].d;
++
+     v1 = float32_abs(v2);
+     env->fregs[f1].d = v1;
+     return set_cc_nz_f32(v1);
+@@ -1231,6 +1251,7 @@ uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
+ {
+     float64 v1;
+     float64 v2 = env->fregs[f2].d;
++
+     v1 = float64_abs(v2);
+     env->fregs[f1].d = v1;
+     return set_cc_nz_f64(v1);
+@@ -1241,6 +1262,7 @@ uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
+     CPU_QuadU v2;
++
+     v2.ll.upper = env->fregs[f2].ll;
+     v2.ll.lower = env->fregs[f2 + 2].ll;
+     v1.q = float128_abs(v2.q);
+@@ -1267,6 +1289,7 @@ uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2)
+ uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU x;
++
+     x.ll.upper = env->fregs[f2].ll;
+     x.ll.lower = env->fregs[f2 + 2].ll;
+     env->fregs[f1].ll = x.ll.upper;
+@@ -1294,6 +1317,7 @@ uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
+ uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU x1, x2;
++
+     x2.ll.upper = env->fregs[f2].ll;
+     x2.ll.lower = env->fregs[f2 + 2].ll;
+     x1.q = float128_chs(x2.q);
+@@ -1307,8 +1331,9 @@ void HELPER(aeb)(uint32_t f1, uint32_t val)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     CPU_FloatU v2;
++
+     v2.l = val;
+-    HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __FUNCTION__,
++    HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __func__,
+                v1, f1, v2.f);
+     env->fregs[f1].l.upper = float32_add(v1, v2.f, &env->fpu_status);
+ }
+@@ -1318,8 +1343,9 @@ void HELPER(deb)(uint32_t f1, uint32_t val)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     CPU_FloatU v2;
++
+     v2.l = val;
+-    HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __FUNCTION__,
++    HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __func__,
+                v1, f1, v2.f);
+     env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status);
+ }
+@@ -1329,8 +1355,9 @@ void HELPER(meeb)(uint32_t f1, uint32_t val)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     CPU_FloatU v2;
++
+     v2.l = val;
+-    HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __FUNCTION__,
++    HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __func__,
+                v1, f1, v2.f);
+     env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status);
+ }
+@@ -1340,7 +1367,8 @@ uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     float32 v2 = env->fregs[f2].l.upper;
+-    HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __FUNCTION__,
++
++    HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __func__,
+                v1, f1, v2);
+     return set_cc_f32(v1, v2);
+ }
+@@ -1350,7 +1378,8 @@ uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     float64 v2 = env->fregs[f2].d;
+-    HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __FUNCTION__,
++
++    HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __func__,
+                v1, f1, v2);
+     return set_cc_f64(v1, v2);
+ }
+@@ -1359,14 +1388,15 @@ uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
+ uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
++    CPU_QuadU v2;
++
+     v1.ll.upper = env->fregs[f1].ll;
+     v1.ll.lower = env->fregs[f1 + 2].ll;
+-    CPU_QuadU v2;
+     v2.ll.upper = env->fregs[f2].ll;
+     v2.ll.lower = env->fregs[f2 + 2].ll;
+ 
+     return float_comp_to_cc(float128_compare_quiet(v1.q, v2.q,
+-                            &env->fpu_status));
++                                                   &env->fpu_status));
+ }
+ 
+ /* 64-bit FP compare RM */
+@@ -1374,8 +1404,9 @@ uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     CPU_DoubleU v2;
++
+     v2.ll = ldq(a2);
+-    HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __FUNCTION__, v1,
++    HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __func__, v1,
+                f1, v2.d);
+     return set_cc_f64(v1, v2.d);
+ }
+@@ -1385,8 +1416,9 @@ uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     CPU_DoubleU v2;
++
+     v2.ll = ldq(a2);
+-    HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __FUNCTION__,
++    HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __func__,
+                v1, f1, v2.d);
+     env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status);
+     return set_cc_nz_f64(v1);
+@@ -1397,6 +1429,7 @@ void HELPER(seb)(uint32_t f1, uint32_t val)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     CPU_FloatU v2;
++
+     v2.l = val;
+     env->fregs[f1].l.upper = float32_sub(v1, v2.f, &env->fpu_status);
+ }
+@@ -1406,6 +1439,7 @@ uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     CPU_DoubleU v2;
++
+     v2.ll = ldq(a2);
+     env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status);
+     return set_cc_nz_f64(v1);
+@@ -1416,8 +1450,9 @@ void HELPER(mdb)(uint32_t f1, uint64_t a2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     CPU_DoubleU v2;
++
+     v2.ll = ldq(a2);
+-    HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __FUNCTION__,
++    HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __func__,
+                v1, f1, v2.d);
+     env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status);
+ }
+@@ -1427,8 +1462,9 @@ void HELPER(ddb)(uint32_t f1, uint64_t a2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     CPU_DoubleU v2;
++
+     v2.ll = ldq(a2);
+-    HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __FUNCTION__,
++    HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __func__,
+                v1, f1, v2.d);
+     env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status);
+ }
+@@ -1464,6 +1500,7 @@ static void set_round_mode(int m3)
+ uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ {
+     float32 v2 = env->fregs[f2].l.upper;
++
+     set_round_mode(m3);
+     env->regs[r1] = float32_to_int64(v2, &env->fpu_status);
+     return set_cc_nz_f32(v2);
+@@ -1473,6 +1510,7 @@ uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ {
+     float64 v2 = env->fregs[f2].d;
++
+     set_round_mode(m3);
+     env->regs[r1] = float64_to_int64(v2, &env->fpu_status);
+     return set_cc_nz_f64(v2);
+@@ -1482,6 +1520,7 @@ uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ {
+     CPU_QuadU v2;
++
+     v2.ll.upper = env->fregs[f2].ll;
+     v2.ll.lower = env->fregs[f2 + 2].ll;
+     set_round_mode(m3);
+@@ -1501,9 +1540,10 @@ uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ {
+     float32 v2 = env->fregs[f2].l.upper;
++
+     set_round_mode(m3);
+     env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+-                     float32_to_int32(v2, &env->fpu_status);
++        float32_to_int32(v2, &env->fpu_status);
+     return set_cc_nz_f32(v2);
+ }
+ 
+@@ -1511,9 +1551,10 @@ uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ {
+     float64 v2 = env->fregs[f2].d;
++
+     set_round_mode(m3);
+     env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+-                     float64_to_int32(v2, &env->fpu_status);
++        float64_to_int32(v2, &env->fpu_status);
+     return set_cc_nz_f64(v2);
+ }
+ 
+@@ -1521,10 +1562,11 @@ uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ {
+     CPU_QuadU v2;
++
+     v2.ll.upper = env->fregs[f2].ll;
+     v2.ll.lower = env->fregs[f2 + 2].ll;
+     env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+-                     float128_to_int32(v2.q, &env->fpu_status);
++        float128_to_int32(v2.q, &env->fpu_status);
+     return set_cc_nz_f128(v2.q);
+ }
+ 
+@@ -1544,6 +1586,7 @@ void HELPER(lzdr)(uint32_t f1)
+ void HELPER(lzxr)(uint32_t f1)
+ {
+     CPU_QuadU x;
++
+     x.q = float64_to_float128(float64_zero, &env->fpu_status);
+     env->fregs[f1].ll = x.ll.upper;
+     env->fregs[f1 + 1].ll = x.ll.lower;
+@@ -1553,12 +1596,13 @@ void HELPER(lzxr)(uint32_t f1)
+ uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
++    CPU_QuadU v2;
++    CPU_QuadU res;
++
+     v1.ll.upper = env->fregs[f1].ll;
+     v1.ll.lower = env->fregs[f1 + 2].ll;
+-    CPU_QuadU v2;
+     v2.ll.upper = env->fregs[f2].ll;
+     v2.ll.lower = env->fregs[f2 + 2].ll;
+-    CPU_QuadU res;
+     res.q = float128_sub(v1.q, v2.q, &env->fpu_status);
+     env->fregs[f1].ll = res.ll.upper;
+     env->fregs[f1 + 2].ll = res.ll.lower;
+@@ -1569,12 +1613,13 @@ uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
+ uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
++    CPU_QuadU v2;
++    CPU_QuadU res;
++
+     v1.ll.upper = env->fregs[f1].ll;
+     v1.ll.lower = env->fregs[f1 + 2].ll;
+-    CPU_QuadU v2;
+     v2.ll.upper = env->fregs[f2].ll;
+     v2.ll.lower = env->fregs[f2 + 2].ll;
+-    CPU_QuadU res;
+     res.q = float128_add(v1.q, v2.q, &env->fpu_status);
+     env->fregs[f1].ll = res.ll.upper;
+     env->fregs[f1 + 2].ll = res.ll.lower;
+@@ -1599,8 +1644,9 @@ void HELPER(ddbr)(uint32_t f1, uint32_t f2)
+ /* 64-bit FP multiply and add RM */
+ void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
+ {
+-    HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __FUNCTION__, f1, a2, f3);
+     CPU_DoubleU v2;
++
++    HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __func__, f1, a2, f3);
+     v2.ll = ldq(a2);
+     env->fregs[f1].d = float64_add(env->fregs[f1].d,
+                                    float64_mul(v2.d, env->fregs[f3].d,
+@@ -1611,7 +1657,7 @@ void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
+ /* 64-bit FP multiply and add RR */
+ void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+ {
+-    HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __FUNCTION__, f1, f2, f3);
++    HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
+     env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d,
+                                                env->fregs[f3].d,
+                                                &env->fpu_status),
+@@ -1621,7 +1667,7 @@ void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+ /* 64-bit FP multiply and subtract RR */
+ void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+ {
+-    HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __FUNCTION__, f1, f2, f3);
++    HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
+     env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d,
+                                                env->fregs[f3].d,
+                                                &env->fpu_status),
+@@ -1642,6 +1688,7 @@ void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
+ void HELPER(ldeb)(uint32_t f1, uint64_t a2)
+ {
+     uint32_t v2;
++
+     v2 = ldl(a2);
+     env->fregs[f1].d = float32_to_float64(v2,
+                                           &env->fpu_status);
+@@ -1651,8 +1698,9 @@ void HELPER(ldeb)(uint32_t f1, uint64_t a2)
+ void HELPER(lxdb)(uint32_t f1, uint64_t a2)
+ {
+     CPU_DoubleU v2;
+-    v2.ll = ldq(a2);
+     CPU_QuadU v1;
++
++    v2.ll = ldq(a2);
+     v1.q = float64_to_float128(v2.d, &env->fpu_status);
+     env->fregs[f1].ll = v1.ll.upper;
+     env->fregs[f1 + 2].ll = v1.ll.lower;
+@@ -1665,7 +1713,7 @@ uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
+     int neg = float32_is_neg(v1);
+     uint32_t cc = 0;
+ 
+-    HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, (long)v1, m2, neg);
++    HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, (long)v1, m2, neg);
+     if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
+         (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
+         (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
+@@ -1687,7 +1735,7 @@ uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
+     int neg = float64_is_neg(v1);
+     uint32_t cc = 0;
+ 
+-    HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __FUNCTION__, v1, m2, neg);
++    HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, v1, m2, neg);
+     if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
+         (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
+         (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
+@@ -1706,10 +1754,12 @@ uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
+ {
+     CPU_QuadU v1;
+     uint32_t cc = 0;
++    int neg;
++
+     v1.ll.upper = env->fregs[f1].ll;
+     v1.ll.lower = env->fregs[f1 + 2].ll;
+ 
+-    int neg = float128_is_neg(v1.q);
++    neg = float128_is_neg(v1.q);
+     if ((float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) ||
+         (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) ||
+         (float128_is_any_nan(v1.q) && (m2 & (1 << (3-neg)))) ||
+@@ -1787,7 +1837,7 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
+ 
+     /* store result */
+     env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+-                    ((uint32_t)cksm + (cksm >> 32));
++        ((uint32_t)cksm + (cksm >> 32));
+ }
+ 
+ static inline uint32_t cc_calc_ltgt_32(CPUS390XState *env, int32_t src,
+@@ -1848,10 +1898,12 @@ static inline uint32_t cc_calc_ltugtu_64(CPUS390XState *env, uint64_t src,
+     }
+ }
+ 
+-static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val, uint32_t mask)
++static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val,
++                                     uint32_t mask)
+ {
+-    HELPER_LOG("%s: val 0x%x mask 0x%x\n", __FUNCTION__, val, mask);
+     uint16_t r = val & mask;
++
++    HELPER_LOG("%s: val 0x%x mask 0x%x\n", __func__, val, mask);
+     if (r == 0 || mask == 0) {
+         return 0;
+     } else if (r == mask) {
+@@ -1862,10 +1914,12 @@ static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val, uint32_t
+ }
+ 
+ /* set condition code for test under mask */
+-static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val, uint32_t mask)
++static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val,
++                                     uint32_t mask)
+ {
+     uint16_t r = val & mask;
+-    HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __FUNCTION__, val, mask, r);
++
++    HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __func__, val, mask, r);
+     if (r == 0 || mask == 0) {
+         return 0;
+     } else if (r == mask) {
+@@ -1888,8 +1942,8 @@ static inline uint32_t cc_calc_nz(CPUS390XState *env, uint64_t dst)
+     return !!dst;
+ }
+ 
+-static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1, int64_t a2,
+-                                      int64_t ar)
++static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1,
++                                      int64_t a2, int64_t ar)
+ {
+     if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
+         return 3; /* overflow */
+@@ -1904,8 +1958,8 @@ static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1, int64_t a2
+     }
+ }
+ 
+-static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1, uint64_t a2,
+-                                       uint64_t ar)
++static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1,
++                                       uint64_t a2, uint64_t ar)
+ {
+     if (ar == 0) {
+         if (a1) {
+@@ -1915,15 +1969,15 @@ static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1, uint64_t
+         }
+     } else {
+         if (ar < a1 || ar < a2) {
+-          return 3;
++            return 3;
+         } else {
+-          return 1;
++            return 1;
+         }
+     }
+ }
+ 
+-static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1, int64_t a2,
+-                                      int64_t ar)
++static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1,
++                                      int64_t a2, int64_t ar)
+ {
+     if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
+         return 3; /* overflow */
+@@ -1938,8 +1992,8 @@ static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1, int64_t a2
+     }
+ }
+ 
+-static inline uint32_t cc_calc_subu_64(CPUS390XState *env, uint64_t a1, uint64_t a2,
+-                                       uint64_t ar)
++static inline uint32_t cc_calc_subu_64(CPUS390XState *env, uint64_t a1,
++                                       uint64_t a2, uint64_t ar)
+ {
+     if (ar == 0) {
+         return 2;
+@@ -1982,8 +2036,8 @@ static inline uint32_t cc_calc_comp_64(CPUS390XState *env, int64_t dst)
+ }
+ 
+ 
+-static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1, int32_t a2,
+-                                      int32_t ar)
++static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1,
++                                      int32_t a2, int32_t ar)
+ {
+     if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
+         return 3; /* overflow */
+@@ -1998,26 +2052,26 @@ static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1, int32_t a2
+     }
+ }
+ 
+-static inline uint32_t cc_calc_addu_32(CPUS390XState *env, uint32_t a1, uint32_t a2,
+-                                       uint32_t ar)
++static inline uint32_t cc_calc_addu_32(CPUS390XState *env, uint32_t a1,
++                                       uint32_t a2, uint32_t ar)
+ {
+     if (ar == 0) {
+         if (a1) {
+-          return 2;
++            return 2;
+         } else {
+-          return 0;
++            return 0;
+         }
+     } else {
+         if (ar < a1 || ar < a2) {
+-          return 3;
++            return 3;
+         } else {
+-          return 1;
++            return 1;
+         }
+     }
+ }
+ 
+-static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1, int32_t a2,
+-                                      int32_t ar)
++static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1,
++                                      int32_t a2, int32_t ar)
+ {
+     if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
+         return 3; /* overflow */
+@@ -2032,8 +2086,8 @@ static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1, int32_t a2
+     }
+ }
+ 
+-static inline uint32_t cc_calc_subu_32(CPUS390XState *env, uint32_t a1, uint32_t a2,
+-                                       uint32_t ar)
++static inline uint32_t cc_calc_subu_32(CPUS390XState *env, uint32_t a1,
++                                       uint32_t a2, uint32_t ar)
+ {
+     if (ar == 0) {
+         return 2;
+@@ -2076,11 +2130,12 @@ static inline uint32_t cc_calc_comp_32(CPUS390XState *env, int32_t dst)
+ }
+ 
+ /* calculate condition code for insert character under mask insn */
+-static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask, uint32_t val)
++static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask,
++                                      uint32_t val)
+ {
+-    HELPER_LOG("%s: mask 0x%x val %d\n", __FUNCTION__, mask, val);
+     uint32_t cc;
+ 
++    HELPER_LOG("%s: mask 0x%x val %d\n", __func__, mask, val);
+     if (mask == 0xf) {
+         if (!val) {
+             return 0;
+@@ -2107,7 +2162,8 @@ static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask, uint32_
+     return cc;
+ }
+ 
+-static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src, uint64_t shift)
++static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src,
++                                    uint64_t shift)
+ {
+     uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
+     uint64_t match, r;
+@@ -2136,8 +2192,8 @@ static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src, uint64_t s
+ }
+ 
+ 
+-static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src,
+-                                  uint64_t dst, uint64_t vr)
++static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
++                                  uint64_t src, uint64_t dst, uint64_t vr)
+ {
+     uint32_t r = 0;
+ 
+@@ -2244,7 +2300,7 @@ static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t s
+         cpu_abort(env, "Unknown CC operation: %s\n", cc_name(cc_op));
+     }
+ 
+-    HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __FUNCTION__,
++    HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __func__,
+                cc_name(cc_op), src, dst, vr, r);
+     return r;
+ }
+@@ -2334,6 +2390,7 @@ void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
+     for (i = 0; i <= len; i++) {
+         uint8_t byte = ldub(array + i);
+         uint8_t new_byte = ldub(trans + byte);
++
+         stb(array + i, new_byte);
+     }
+ }
+@@ -2363,7 +2420,7 @@ static void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
+ }
+ 
+ /*
+- * ret < 0 indicates program check, ret = 0,1,2,3 -> cc
++ * ret < 0 indicates program check, ret = 0, 1, 2, 3 -> cc
+  */
+ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
+ {
+@@ -2382,24 +2439,24 @@ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
+         return -PGM_SPECIFICATION;
+     }
+ 
+-    switch(code) {
+-        case SCLP_CMDW_READ_SCP_INFO:
+-        case SCLP_CMDW_READ_SCP_INFO_FORCED:
+-            while ((ram_size >> (20 + shift)) > 65535) {
+-                shift++;
+-            }
+-            stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
+-            stb_phys(sccb + SCP_INCREMENT, 1 << shift);
+-            stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
++    switch (code) {
++    case SCLP_CMDW_READ_SCP_INFO:
++    case SCLP_CMDW_READ_SCP_INFO_FORCED:
++        while ((ram_size >> (20 + shift)) > 65535) {
++            shift++;
++        }
++        stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
++        stb_phys(sccb + SCP_INCREMENT, 1 << shift);
++        stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
+ 
+-            s390_sclp_extint(sccb & ~3);
+-            break;
+-        default:
++        s390_sclp_extint(sccb & ~3);
++        break;
++    default:
+ #ifdef DEBUG_HELPER
+-            printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
++        printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
+ #endif
+-            r = 3;
+-            break;
++        r = 3;
++        break;
+     }
+ 
+     return r;
+@@ -2479,7 +2536,7 @@ static inline uint64_t clock_value(CPUS390XState *env)
+     uint64_t time;
+ 
+     time = env->tod_offset +
+-           time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
++        time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
+ 
+     return time;
+ }
+@@ -2503,7 +2560,6 @@ uint32_t HELPER(stcke)(uint64_t a1)
+     /* XXX programmable fields */
+     stw(a1 + 17, 0);
+ 
+-
+     return 0;
+ }
+ 
+@@ -2584,7 +2640,7 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
+             ebcdic_put(sysib.model, "QEMU            ", 16);
+             ebcdic_put(sysib.sequence, "QEMU            ", 16);
+             ebcdic_put(sysib.plant, "QEMU", 4);
+-            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
++            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+         } else if ((sel1 == 2) && (sel2 == 1)) {
+             /* Basic Machine CPU */
+             struct sysib_121 sysib;
+@@ -2594,7 +2650,7 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
+             ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
+             ebcdic_put(sysib.plant, "QEMU", 4);
+             stw_p(&sysib.cpu_addr, env->cpu_num);
+-            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
++            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+         } else if ((sel1 == 2) && (sel2 == 2)) {
+             /* Basic Machine CPUs */
+             struct sysib_122 sysib;
+@@ -2606,68 +2662,68 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
+             stw_p(&sysib.active_cpus, 1);
+             stw_p(&sysib.standby_cpus, 0);
+             stw_p(&sysib.reserved_cpus, 0);
+-            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
++            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+         } else {
+             cc = 3;
+         }
+         break;
+     case STSI_LEVEL_2:
+-    {
+-        if ((sel1 == 2) && (sel2 == 1)) {
+-            /* LPAR CPU */
+-            struct sysib_221 sysib;
+-
+-            memset(&sysib, 0, sizeof(sysib));
+-            /* XXX make different for different CPUs? */
+-            ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
+-            ebcdic_put(sysib.plant, "QEMU", 4);
+-            stw_p(&sysib.cpu_addr, env->cpu_num);
+-            stw_p(&sysib.cpu_id, 0);
+-            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
+-        } else if ((sel1 == 2) && (sel2 == 2)) {
+-            /* LPAR CPUs */
+-            struct sysib_222 sysib;
+-
+-            memset(&sysib, 0, sizeof(sysib));
+-            stw_p(&sysib.lpar_num, 0);
+-            sysib.lcpuc = 0;
+-            /* XXX change when SMP comes */
+-            stw_p(&sysib.total_cpus, 1);
+-            stw_p(&sysib.conf_cpus, 1);
+-            stw_p(&sysib.standby_cpus, 0);
+-            stw_p(&sysib.reserved_cpus, 0);
+-            ebcdic_put(sysib.name, "QEMU    ", 8);
+-            stl_p(&sysib.caf, 1000);
+-            stw_p(&sysib.dedicated_cpus, 0);
+-            stw_p(&sysib.shared_cpus, 0);
+-            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
+-        } else {
+-            cc = 3;
++        {
++            if ((sel1 == 2) && (sel2 == 1)) {
++                /* LPAR CPU */
++                struct sysib_221 sysib;
++
++                memset(&sysib, 0, sizeof(sysib));
++                /* XXX make different for different CPUs? */
++                ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
++                ebcdic_put(sysib.plant, "QEMU", 4);
++                stw_p(&sysib.cpu_addr, env->cpu_num);
++                stw_p(&sysib.cpu_id, 0);
++                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
++            } else if ((sel1 == 2) && (sel2 == 2)) {
++                /* LPAR CPUs */
++                struct sysib_222 sysib;
++
++                memset(&sysib, 0, sizeof(sysib));
++                stw_p(&sysib.lpar_num, 0);
++                sysib.lcpuc = 0;
++                /* XXX change when SMP comes */
++                stw_p(&sysib.total_cpus, 1);
++                stw_p(&sysib.conf_cpus, 1);
++                stw_p(&sysib.standby_cpus, 0);
++                stw_p(&sysib.reserved_cpus, 0);
++                ebcdic_put(sysib.name, "QEMU    ", 8);
++                stl_p(&sysib.caf, 1000);
++                stw_p(&sysib.dedicated_cpus, 0);
++                stw_p(&sysib.shared_cpus, 0);
++                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
++            } else {
++                cc = 3;
++            }
++            break;
+         }
+-        break;
+-    }
+     case STSI_LEVEL_3:
+-    {
+-        if ((sel1 == 2) && (sel2 == 2)) {
+-            /* VM CPUs */
+-            struct sysib_322 sysib;
+-
+-            memset(&sysib, 0, sizeof(sysib));
+-            sysib.count = 1;
+-            /* XXX change when SMP comes */
+-            stw_p(&sysib.vm[0].total_cpus, 1);
+-            stw_p(&sysib.vm[0].conf_cpus, 1);
+-            stw_p(&sysib.vm[0].standby_cpus, 0);
+-            stw_p(&sysib.vm[0].reserved_cpus, 0);
+-            ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
+-            stl_p(&sysib.vm[0].caf, 1000);
+-            ebcdic_put(sysib.vm[0].cpi, "KVM/Linux       ", 16);
+-            cpu_physical_memory_rw(a0, (uint8_t*)&sysib, sizeof(sysib), 1);
+-        } else {
+-            cc = 3;
++        {
++            if ((sel1 == 2) && (sel2 == 2)) {
++                /* VM CPUs */
++                struct sysib_322 sysib;
++
++                memset(&sysib, 0, sizeof(sysib));
++                sysib.count = 1;
++                /* XXX change when SMP comes */
++                stw_p(&sysib.vm[0].total_cpus, 1);
++                stw_p(&sysib.vm[0].conf_cpus, 1);
++                stw_p(&sysib.vm[0].standby_cpus, 0);
++                stw_p(&sysib.vm[0].reserved_cpus, 0);
++                ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
++                stl_p(&sysib.vm[0].caf, 1000);
++                ebcdic_put(sysib.vm[0].cpi, "KVM/Linux       ", 16);
++                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
++            } else {
++                cc = 3;
++            }
++            break;
+         }
+-        break;
+-    }
+     case STSI_LEVEL_CURRENT:
+         env->regs[0] = STSI_LEVEL_3;
+         break;
+@@ -2781,6 +2837,7 @@ uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
+ {
+     uint8_t re;
+     uint8_t key;
++
+     if (r2 > ram_size) {
+         return 0;
+     }
+@@ -2865,7 +2922,7 @@ static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
+ uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
+ {
+     HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
+-               __FUNCTION__, l, a1, a2);
++               __func__, l, a1, a2);
+ 
+     return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
+ }
+@@ -2873,7 +2930,7 @@ uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
+ uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
+ {
+     HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
+-               __FUNCTION__, l, a1, a2);
++               __func__, l, a1, a2);
+ 
+     return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
+ }
+@@ -2883,9 +2940,9 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
+     int cc = 0;
+ 
+     HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
+-               __FUNCTION__, order_code, r1, cpu_addr);
++               __func__, order_code, r1, cpu_addr);
+ 
+-    /* Remember: Use "R1 or R1+1, whichever is the odd-numbered register"
++    /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register"
+        as parameter (input). Status (output) is always R1. */
+ 
+     switch (order_code) {
+@@ -2901,7 +2958,7 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
+         env->regs[r1] &= 0xffffffff00000000ULL;
+         cc = 1;
+         break;
+-#if !defined (CONFIG_USER_ONLY)
++#if !defined(CONFIG_USER_ONLY)
+     case SIGP_RESTART:
+         qemu_system_reset_request();
+         cpu_loop_exit(env);
+@@ -2922,7 +2979,7 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
+ 
+ void HELPER(sacf)(uint64_t a1)
+ {
+-    HELPER_LOG("%s: %16" PRIx64 "\n", __FUNCTION__, a1);
++    HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);
+ 
+     switch (a1 & 0xf00) {
+     case 0x000:
+@@ -2953,13 +3010,13 @@ void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
+     /* XXX broadcast to other CPUs */
+ 
+     /* XXX Linux is nice enough to give us the exact pte address.
+-           According to spec we'd have to find it out ourselves */
++       According to spec we'd have to find it out ourselves */
+     /* XXX Linux is fine with overwriting the pte, the spec requires
+-           us to only set the invalid bit */
++       us to only set the invalid bit */
+     stq_phys(pte_addr, pte | _PAGE_INVALID);
+ 
+     /* XXX we exploit the fact that Linux passes the exact virtual
+-           address here - it's not obliged to! */
++       address here - it's not obliged to! */
+     tlb_flush_page(env, page);
+ 
+     /* XXX 31-bit hack */
+@@ -3008,7 +3065,8 @@ uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
+     env->exception_index = old_exc;
+ 
+     if (!(env->psw.mask & PSW_MASK_64)) {
+-        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | (ret & 0xffffffffULL);
++        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
++            (ret & 0xffffffffULL);
+     } else {
+         env->regs[r1] = ret;
+     }
+-- 
+1.7.12.1
+
diff --git a/0006-target-s390x-split-FPU-ops.patch b/0006-target-s390x-split-FPU-ops.patch
new file mode 100644
index 0000000..5aabf6f
--- /dev/null
+++ b/0006-target-s390x-split-FPU-ops.patch
@@ -0,0 +1,1756 @@
+From 3eb9b25ae5d2bcc024646c5a04f28899661ab14c Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:31 +0000
+Subject: [PATCH] target-s390x: split FPU ops
+
+Move floating point instructions to fpu_helper.c.
+
+While exporting some condition code helpers,
+avoid duplicate identifier conflict with translate.c.
+
+Remove unused set_cc_nz_f64() in translate.c.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/Makefile.objs |   2 +
+ target-s390x/cpu.h         |   6 +
+ target-s390x/fpu_helper.c  | 836 +++++++++++++++++++++++++++++++++++++++++++++
+ target-s390x/op_helper.c   | 802 -------------------------------------------
+ target-s390x/translate.c   |  11 +-
+ 5 files changed, 847 insertions(+), 810 deletions(-)
+ create mode 100644 target-s390x/fpu_helper.c
+
+diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
+index 80be3bb..23b3bd9 100644
+--- a/target-s390x/Makefile.objs
++++ b/target-s390x/Makefile.objs
+@@ -1,5 +1,7 @@
+ obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
++obj-y += fpu_helper.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-$(CONFIG_KVM) += kvm.o
+ 
+ $(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
++$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
+index 18ac6e3..b4620c5 100644
+--- a/target-s390x/cpu.h
++++ b/target-s390x/cpu.h
+@@ -999,4 +999,10 @@ static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
+     env->psw.addr = tb->pc;
+ }
+ 
++/* fpu_helper.c */
++uint32_t set_cc_f32(float32 v1, float32 v2);
++uint32_t set_cc_f64(float64 v1, float64 v2);
++uint32_t set_cc_nz_f32(float32 v);
++uint32_t set_cc_nz_f64(float64 v);
++
+ #endif
+diff --git a/target-s390x/fpu_helper.c b/target-s390x/fpu_helper.c
+new file mode 100644
+index 0000000..1389052
+--- /dev/null
++++ b/target-s390x/fpu_helper.c
+@@ -0,0 +1,836 @@
++/*
++ *  S/390 FPU helper routines
++ *
++ *  Copyright (c) 2009 Ulrich Hecht
++ *  Copyright (c) 2009 Alexander Graf
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "cpu.h"
++#include "dyngen-exec.h"
++#include "helper.h"
++
++#if !defined(CONFIG_USER_ONLY)
++#include "softmmu_exec.h"
++#endif
++
++/* #define DEBUG_HELPER */
++#ifdef DEBUG_HELPER
++#define HELPER_LOG(x...) qemu_log(x)
++#else
++#define HELPER_LOG(x...)
++#endif
++
++static inline int float_comp_to_cc(int float_compare)
++{
++    switch (float_compare) {
++    case float_relation_equal:
++        return 0;
++    case float_relation_less:
++        return 1;
++    case float_relation_greater:
++        return 2;
++    case float_relation_unordered:
++        return 3;
++    default:
++        cpu_abort(env, "unknown return value for float compare\n");
++    }
++}
++
++/* condition codes for binary FP ops */
++uint32_t set_cc_f32(float32 v1, float32 v2)
++{
++    return float_comp_to_cc(float32_compare_quiet(v1, v2, &env->fpu_status));
++}
++
++uint32_t set_cc_f64(float64 v1, float64 v2)
++{
++    return float_comp_to_cc(float64_compare_quiet(v1, v2, &env->fpu_status));
++}
++
++/* condition codes for unary FP ops */
++uint32_t set_cc_nz_f32(float32 v)
++{
++    if (float32_is_any_nan(v)) {
++        return 3;
++    } else if (float32_is_zero(v)) {
++        return 0;
++    } else if (float32_is_neg(v)) {
++        return 1;
++    } else {
++        return 2;
++    }
++}
++
++uint32_t set_cc_nz_f64(float64 v)
++{
++    if (float64_is_any_nan(v)) {
++        return 3;
++    } else if (float64_is_zero(v)) {
++        return 0;
++    } else if (float64_is_neg(v)) {
++        return 1;
++    } else {
++        return 2;
++    }
++}
++
++static uint32_t set_cc_nz_f128(float128 v)
++{
++    if (float128_is_any_nan(v)) {
++        return 3;
++    } else if (float128_is_zero(v)) {
++        return 0;
++    } else if (float128_is_neg(v)) {
++        return 1;
++    } else {
++        return 2;
++    }
++}
++
++/* convert 32-bit int to 64-bit float */
++void HELPER(cdfbr)(uint32_t f1, int32_t v2)
++{
++    HELPER_LOG("%s: converting %d to f%d\n", __func__, v2, f1);
++    env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status);
++}
++
++/* convert 32-bit int to 128-bit float */
++void HELPER(cxfbr)(uint32_t f1, int32_t v2)
++{
++    CPU_QuadU v1;
++
++    v1.q = int32_to_float128(v2, &env->fpu_status);
++    env->fregs[f1].ll = v1.ll.upper;
++    env->fregs[f1 + 2].ll = v1.ll.lower;
++}
++
++/* convert 64-bit int to 32-bit float */
++void HELPER(cegbr)(uint32_t f1, int64_t v2)
++{
++    HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
++    env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status);
++}
++
++/* convert 64-bit int to 64-bit float */
++void HELPER(cdgbr)(uint32_t f1, int64_t v2)
++{
++    HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
++    env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status);
++}
++
++/* convert 64-bit int to 128-bit float */
++void HELPER(cxgbr)(uint32_t f1, int64_t v2)
++{
++    CPU_QuadU x1;
++
++    x1.q = int64_to_float128(v2, &env->fpu_status);
++    HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __func__, v2,
++               x1.ll.upper, x1.ll.lower);
++    env->fregs[f1].ll = x1.ll.upper;
++    env->fregs[f1 + 2].ll = x1.ll.lower;
++}
++
++/* convert 32-bit int to 32-bit float */
++void HELPER(cefbr)(uint32_t f1, int32_t v2)
++{
++    env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status);
++    HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __func__, v2,
++               env->fregs[f1].l.upper, f1);
++}
++
++/* 32-bit FP addition RR */
++uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
++                                         env->fregs[f2].l.upper,
++                                         &env->fpu_status);
++    HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
++               env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
++
++    return set_cc_nz_f32(env->fregs[f1].l.upper);
++}
++
++/* 64-bit FP addition RR */
++uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d,
++                                   &env->fpu_status);
++    HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __func__,
++               env->fregs[f2].d, env->fregs[f1].d, f1);
++
++    return set_cc_nz_f64(env->fregs[f1].d);
++}
++
++/* 32-bit FP subtraction RR */
++uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper,
++                                         env->fregs[f2].l.upper,
++                                         &env->fpu_status);
++    HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
++               env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
++
++    return set_cc_nz_f32(env->fregs[f1].l.upper);
++}
++
++/* 64-bit FP subtraction RR */
++uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d,
++                                   &env->fpu_status);
++    HELPER_LOG("%s: subtracting 0x%ld resulting in 0x%ld in f%d\n",
++               __func__, env->fregs[f2].d, env->fregs[f1].d, f1);
++
++    return set_cc_nz_f64(env->fregs[f1].d);
++}
++
++/* 32-bit FP division RR */
++void HELPER(debr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper,
++                                         env->fregs[f2].l.upper,
++                                         &env->fpu_status);
++}
++
++/* 128-bit FP division RR */
++void HELPER(dxbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU v1;
++    CPU_QuadU v2;
++    CPU_QuadU res;
++
++    v1.ll.upper = env->fregs[f1].ll;
++    v1.ll.lower = env->fregs[f1 + 2].ll;
++    v2.ll.upper = env->fregs[f2].ll;
++    v2.ll.lower = env->fregs[f2 + 2].ll;
++    res.q = float128_div(v1.q, v2.q, &env->fpu_status);
++    env->fregs[f1].ll = res.ll.upper;
++    env->fregs[f1 + 2].ll = res.ll.lower;
++}
++
++/* 64-bit FP multiplication RR */
++void HELPER(mdbr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d,
++                                   &env->fpu_status);
++}
++
++/* 128-bit FP multiplication RR */
++void HELPER(mxbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU v1;
++    CPU_QuadU v2;
++    CPU_QuadU res;
++
++    v1.ll.upper = env->fregs[f1].ll;
++    v1.ll.lower = env->fregs[f1 + 2].ll;
++    v2.ll.upper = env->fregs[f2].ll;
++    v2.ll.lower = env->fregs[f2 + 2].ll;
++    res.q = float128_mul(v1.q, v2.q, &env->fpu_status);
++    env->fregs[f1].ll = res.ll.upper;
++    env->fregs[f1 + 2].ll = res.ll.lower;
++}
++
++/* convert 32-bit float to 64-bit float */
++void HELPER(ldebr)(uint32_t r1, uint32_t r2)
++{
++    env->fregs[r1].d = float32_to_float64(env->fregs[r2].l.upper,
++                                          &env->fpu_status);
++}
++
++/* convert 128-bit float to 64-bit float */
++void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU x2;
++
++    x2.ll.upper = env->fregs[f2].ll;
++    x2.ll.lower = env->fregs[f2 + 2].ll;
++    env->fregs[f1].d = float128_to_float64(x2.q, &env->fpu_status);
++    HELPER_LOG("%s: to 0x%ld\n", __func__, env->fregs[f1].d);
++}
++
++/* convert 64-bit float to 128-bit float */
++void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU res;
++
++    res.q = float64_to_float128(env->fregs[f2].d, &env->fpu_status);
++    env->fregs[f1].ll = res.ll.upper;
++    env->fregs[f1 + 2].ll = res.ll.lower;
++}
++
++/* convert 64-bit float to 32-bit float */
++void HELPER(ledbr)(uint32_t f1, uint32_t f2)
++{
++    float64 d2 = env->fregs[f2].d;
++
++    env->fregs[f1].l.upper = float64_to_float32(d2, &env->fpu_status);
++}
++
++/* convert 128-bit float to 32-bit float */
++void HELPER(lexbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU x2;
++
++    x2.ll.upper = env->fregs[f2].ll;
++    x2.ll.lower = env->fregs[f2 + 2].ll;
++    env->fregs[f1].l.upper = float128_to_float32(x2.q, &env->fpu_status);
++    HELPER_LOG("%s: to 0x%d\n", __func__, env->fregs[f1].l.upper);
++}
++
++/* absolute value of 32-bit float */
++uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
++{
++    float32 v1;
++    float32 v2 = env->fregs[f2].d;
++
++    v1 = float32_abs(v2);
++    env->fregs[f1].d = v1;
++    return set_cc_nz_f32(v1);
++}
++
++/* absolute value of 64-bit float */
++uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
++{
++    float64 v1;
++    float64 v2 = env->fregs[f2].d;
++
++    v1 = float64_abs(v2);
++    env->fregs[f1].d = v1;
++    return set_cc_nz_f64(v1);
++}
++
++/* absolute value of 128-bit float */
++uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU v1;
++    CPU_QuadU v2;
++
++    v2.ll.upper = env->fregs[f2].ll;
++    v2.ll.lower = env->fregs[f2 + 2].ll;
++    v1.q = float128_abs(v2.q);
++    env->fregs[f1].ll = v1.ll.upper;
++    env->fregs[f1 + 2].ll = v1.ll.lower;
++    return set_cc_nz_f128(v1.q);
++}
++
++/* load and test 64-bit float */
++uint32_t HELPER(ltdbr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].d = env->fregs[f2].d;
++    return set_cc_nz_f64(env->fregs[f1].d);
++}
++
++/* load and test 32-bit float */
++uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].l.upper = env->fregs[f2].l.upper;
++    return set_cc_nz_f32(env->fregs[f1].l.upper);
++}
++
++/* load and test 128-bit float */
++uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU x;
++
++    x.ll.upper = env->fregs[f2].ll;
++    x.ll.lower = env->fregs[f2 + 2].ll;
++    env->fregs[f1].ll = x.ll.upper;
++    env->fregs[f1 + 2].ll = x.ll.lower;
++    return set_cc_nz_f128(x.q);
++}
++
++/* load complement of 32-bit float */
++uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].l.upper = float32_chs(env->fregs[f2].l.upper);
++
++    return set_cc_nz_f32(env->fregs[f1].l.upper);
++}
++
++/* load complement of 64-bit float */
++uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].d = float64_chs(env->fregs[f2].d);
++
++    return set_cc_nz_f64(env->fregs[f1].d);
++}
++
++/* load complement of 128-bit float */
++uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU x1, x2;
++
++    x2.ll.upper = env->fregs[f2].ll;
++    x2.ll.lower = env->fregs[f2 + 2].ll;
++    x1.q = float128_chs(x2.q);
++    env->fregs[f1].ll = x1.ll.upper;
++    env->fregs[f1 + 2].ll = x1.ll.lower;
++    return set_cc_nz_f128(x1.q);
++}
++
++/* 32-bit FP addition RM */
++void HELPER(aeb)(uint32_t f1, uint32_t val)
++{
++    float32 v1 = env->fregs[f1].l.upper;
++    CPU_FloatU v2;
++
++    v2.l = val;
++    HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __func__,
++               v1, f1, v2.f);
++    env->fregs[f1].l.upper = float32_add(v1, v2.f, &env->fpu_status);
++}
++
++/* 32-bit FP division RM */
++void HELPER(deb)(uint32_t f1, uint32_t val)
++{
++    float32 v1 = env->fregs[f1].l.upper;
++    CPU_FloatU v2;
++
++    v2.l = val;
++    HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __func__,
++               v1, f1, v2.f);
++    env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status);
++}
++
++/* 32-bit FP multiplication RM */
++void HELPER(meeb)(uint32_t f1, uint32_t val)
++{
++    float32 v1 = env->fregs[f1].l.upper;
++    CPU_FloatU v2;
++
++    v2.l = val;
++    HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __func__,
++               v1, f1, v2.f);
++    env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status);
++}
++
++/* 32-bit FP compare RR */
++uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2)
++{
++    float32 v1 = env->fregs[f1].l.upper;
++    float32 v2 = env->fregs[f2].l.upper;
++
++    HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __func__,
++               v1, f1, v2);
++    return set_cc_f32(v1, v2);
++}
++
++/* 64-bit FP compare RR */
++uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
++{
++    float64 v1 = env->fregs[f1].d;
++    float64 v2 = env->fregs[f2].d;
++
++    HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __func__,
++               v1, f1, v2);
++    return set_cc_f64(v1, v2);
++}
++
++/* 128-bit FP compare RR */
++uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU v1;
++    CPU_QuadU v2;
++
++    v1.ll.upper = env->fregs[f1].ll;
++    v1.ll.lower = env->fregs[f1 + 2].ll;
++    v2.ll.upper = env->fregs[f2].ll;
++    v2.ll.lower = env->fregs[f2 + 2].ll;
++
++    return float_comp_to_cc(float128_compare_quiet(v1.q, v2.q,
++                                                   &env->fpu_status));
++}
++
++/* 64-bit FP compare RM */
++uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2)
++{
++    float64 v1 = env->fregs[f1].d;
++    CPU_DoubleU v2;
++
++    v2.ll = ldq(a2);
++    HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __func__, v1,
++               f1, v2.d);
++    return set_cc_f64(v1, v2.d);
++}
++
++/* 64-bit FP addition RM */
++uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
++{
++    float64 v1 = env->fregs[f1].d;
++    CPU_DoubleU v2;
++
++    v2.ll = ldq(a2);
++    HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __func__,
++               v1, f1, v2.d);
++    env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status);
++    return set_cc_nz_f64(v1);
++}
++
++/* 32-bit FP subtraction RM */
++void HELPER(seb)(uint32_t f1, uint32_t val)
++{
++    float32 v1 = env->fregs[f1].l.upper;
++    CPU_FloatU v2;
++
++    v2.l = val;
++    env->fregs[f1].l.upper = float32_sub(v1, v2.f, &env->fpu_status);
++}
++
++/* 64-bit FP subtraction RM */
++uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2)
++{
++    float64 v1 = env->fregs[f1].d;
++    CPU_DoubleU v2;
++
++    v2.ll = ldq(a2);
++    env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status);
++    return set_cc_nz_f64(v1);
++}
++
++/* 64-bit FP multiplication RM */
++void HELPER(mdb)(uint32_t f1, uint64_t a2)
++{
++    float64 v1 = env->fregs[f1].d;
++    CPU_DoubleU v2;
++
++    v2.ll = ldq(a2);
++    HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __func__,
++               v1, f1, v2.d);
++    env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status);
++}
++
++/* 64-bit FP division RM */
++void HELPER(ddb)(uint32_t f1, uint64_t a2)
++{
++    float64 v1 = env->fregs[f1].d;
++    CPU_DoubleU v2;
++
++    v2.ll = ldq(a2);
++    HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __func__,
++               v1, f1, v2.d);
++    env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status);
++}
++
++static void set_round_mode(int m3)
++{
++    switch (m3) {
++    case 0:
++        /* current mode */
++        break;
++    case 1:
++        /* biased round no nearest */
++    case 4:
++        /* round to nearest */
++        set_float_rounding_mode(float_round_nearest_even, &env->fpu_status);
++        break;
++    case 5:
++        /* round to zero */
++        set_float_rounding_mode(float_round_to_zero, &env->fpu_status);
++        break;
++    case 6:
++        /* round to +inf */
++        set_float_rounding_mode(float_round_up, &env->fpu_status);
++        break;
++    case 7:
++        /* round to -inf */
++        set_float_rounding_mode(float_round_down, &env->fpu_status);
++        break;
++    }
++}
++
++/* convert 32-bit float to 64-bit int */
++uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
++{
++    float32 v2 = env->fregs[f2].l.upper;
++
++    set_round_mode(m3);
++    env->regs[r1] = float32_to_int64(v2, &env->fpu_status);
++    return set_cc_nz_f32(v2);
++}
++
++/* convert 64-bit float to 64-bit int */
++uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
++{
++    float64 v2 = env->fregs[f2].d;
++
++    set_round_mode(m3);
++    env->regs[r1] = float64_to_int64(v2, &env->fpu_status);
++    return set_cc_nz_f64(v2);
++}
++
++/* convert 128-bit float to 64-bit int */
++uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
++{
++    CPU_QuadU v2;
++
++    v2.ll.upper = env->fregs[f2].ll;
++    v2.ll.lower = env->fregs[f2 + 2].ll;
++    set_round_mode(m3);
++    env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status);
++    if (float128_is_any_nan(v2.q)) {
++        return 3;
++    } else if (float128_is_zero(v2.q)) {
++        return 0;
++    } else if (float128_is_neg(v2.q)) {
++        return 1;
++    } else {
++        return 2;
++    }
++}
++
++/* convert 32-bit float to 32-bit int */
++uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
++{
++    float32 v2 = env->fregs[f2].l.upper;
++
++    set_round_mode(m3);
++    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
++        float32_to_int32(v2, &env->fpu_status);
++    return set_cc_nz_f32(v2);
++}
++
++/* convert 64-bit float to 32-bit int */
++uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
++{
++    float64 v2 = env->fregs[f2].d;
++
++    set_round_mode(m3);
++    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
++        float64_to_int32(v2, &env->fpu_status);
++    return set_cc_nz_f64(v2);
++}
++
++/* convert 128-bit float to 32-bit int */
++uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
++{
++    CPU_QuadU v2;
++
++    v2.ll.upper = env->fregs[f2].ll;
++    v2.ll.lower = env->fregs[f2 + 2].ll;
++    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
++        float128_to_int32(v2.q, &env->fpu_status);
++    return set_cc_nz_f128(v2.q);
++}
++
++/* load 32-bit FP zero */
++void HELPER(lzer)(uint32_t f1)
++{
++    env->fregs[f1].l.upper = float32_zero;
++}
++
++/* load 64-bit FP zero */
++void HELPER(lzdr)(uint32_t f1)
++{
++    env->fregs[f1].d = float64_zero;
++}
++
++/* load 128-bit FP zero */
++void HELPER(lzxr)(uint32_t f1)
++{
++    CPU_QuadU x;
++
++    x.q = float64_to_float128(float64_zero, &env->fpu_status);
++    env->fregs[f1].ll = x.ll.upper;
++    env->fregs[f1 + 1].ll = x.ll.lower;
++}
++
++/* 128-bit FP subtraction RR */
++uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU v1;
++    CPU_QuadU v2;
++    CPU_QuadU res;
++
++    v1.ll.upper = env->fregs[f1].ll;
++    v1.ll.lower = env->fregs[f1 + 2].ll;
++    v2.ll.upper = env->fregs[f2].ll;
++    v2.ll.lower = env->fregs[f2 + 2].ll;
++    res.q = float128_sub(v1.q, v2.q, &env->fpu_status);
++    env->fregs[f1].ll = res.ll.upper;
++    env->fregs[f1 + 2].ll = res.ll.lower;
++    return set_cc_nz_f128(res.q);
++}
++
++/* 128-bit FP addition RR */
++uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
++{
++    CPU_QuadU v1;
++    CPU_QuadU v2;
++    CPU_QuadU res;
++
++    v1.ll.upper = env->fregs[f1].ll;
++    v1.ll.lower = env->fregs[f1 + 2].ll;
++    v2.ll.upper = env->fregs[f2].ll;
++    v2.ll.lower = env->fregs[f2 + 2].ll;
++    res.q = float128_add(v1.q, v2.q, &env->fpu_status);
++    env->fregs[f1].ll = res.ll.upper;
++    env->fregs[f1 + 2].ll = res.ll.lower;
++    return set_cc_nz_f128(res.q);
++}
++
++/* 32-bit FP multiplication RR */
++void HELPER(meebr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper,
++                                         env->fregs[f2].l.upper,
++                                         &env->fpu_status);
++}
++
++/* 64-bit FP division RR */
++void HELPER(ddbr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].d = float64_div(env->fregs[f1].d, env->fregs[f2].d,
++                                   &env->fpu_status);
++}
++
++/* 64-bit FP multiply and add RM */
++void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
++{
++    CPU_DoubleU v2;
++
++    HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __func__, f1, a2, f3);
++    v2.ll = ldq(a2);
++    env->fregs[f1].d = float64_add(env->fregs[f1].d,
++                                   float64_mul(v2.d, env->fregs[f3].d,
++                                               &env->fpu_status),
++                                   &env->fpu_status);
++}
++
++/* 64-bit FP multiply and add RR */
++void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
++{
++    HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
++    env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d,
++                                               env->fregs[f3].d,
++                                               &env->fpu_status),
++                                   env->fregs[f1].d, &env->fpu_status);
++}
++
++/* 64-bit FP multiply and subtract RR */
++void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
++{
++    HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
++    env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d,
++                                               env->fregs[f3].d,
++                                               &env->fpu_status),
++                                   env->fregs[f1].d, &env->fpu_status);
++}
++
++/* 32-bit FP multiply and add RR */
++void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
++{
++    env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
++                                         float32_mul(env->fregs[f2].l.upper,
++                                                     env->fregs[f3].l.upper,
++                                                     &env->fpu_status),
++                                         &env->fpu_status);
++}
++
++/* convert 32-bit float to 64-bit float */
++void HELPER(ldeb)(uint32_t f1, uint64_t a2)
++{
++    uint32_t v2;
++
++    v2 = ldl(a2);
++    env->fregs[f1].d = float32_to_float64(v2,
++                                          &env->fpu_status);
++}
++
++/* convert 64-bit float to 128-bit float */
++void HELPER(lxdb)(uint32_t f1, uint64_t a2)
++{
++    CPU_DoubleU v2;
++    CPU_QuadU v1;
++
++    v2.ll = ldq(a2);
++    v1.q = float64_to_float128(v2.d, &env->fpu_status);
++    env->fregs[f1].ll = v1.ll.upper;
++    env->fregs[f1 + 2].ll = v1.ll.lower;
++}
++
++/* test data class 32-bit */
++uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
++{
++    float32 v1 = env->fregs[f1].l.upper;
++    int neg = float32_is_neg(v1);
++    uint32_t cc = 0;
++
++    HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, (long)v1, m2, neg);
++    if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
++        (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
++        (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
++        (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
++        cc = 1;
++    } else if (m2 & (1 << (9-neg))) {
++        /* assume normalized number */
++        cc = 1;
++    }
++
++    /* FIXME: denormalized? */
++    return cc;
++}
++
++/* test data class 64-bit */
++uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
++{
++    float64 v1 = env->fregs[f1].d;
++    int neg = float64_is_neg(v1);
++    uint32_t cc = 0;
++
++    HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, v1, m2, neg);
++    if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
++        (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
++        (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
++        (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
++        cc = 1;
++    } else if (m2 & (1 << (9-neg))) {
++        /* assume normalized number */
++        cc = 1;
++    }
++    /* FIXME: denormalized? */
++    return cc;
++}
++
++/* test data class 128-bit */
++uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
++{
++    CPU_QuadU v1;
++    uint32_t cc = 0;
++    int neg;
++
++    v1.ll.upper = env->fregs[f1].ll;
++    v1.ll.lower = env->fregs[f1 + 2].ll;
++
++    neg = float128_is_neg(v1.q);
++    if ((float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) ||
++        (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) ||
++        (float128_is_any_nan(v1.q) && (m2 & (1 << (3-neg)))) ||
++        (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg))))) {
++        cc = 1;
++    } else if (m2 & (1 << (9-neg))) {
++        /* assume normalized number */
++        cc = 1;
++    }
++    /* FIXME: denormalized? */
++    return cc;
++}
++
++/* square root 64-bit RR */
++void HELPER(sqdbr)(uint32_t f1, uint32_t f2)
++{
++    env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status);
++}
+diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
+index 195e93e..270bf14 100644
+--- a/target-s390x/op_helper.c
++++ b/target-s390x/op_helper.c
+@@ -977,802 +977,6 @@ uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
+     }
+ }
+ 
+-static inline int float_comp_to_cc(int float_compare)
+-{
+-    switch (float_compare) {
+-    case float_relation_equal:
+-        return 0;
+-    case float_relation_less:
+-        return 1;
+-    case float_relation_greater:
+-        return 2;
+-    case float_relation_unordered:
+-        return 3;
+-    default:
+-        cpu_abort(env, "unknown return value for float compare\n");
+-    }
+-}
+-
+-/* condition codes for binary FP ops */
+-static uint32_t set_cc_f32(float32 v1, float32 v2)
+-{
+-    return float_comp_to_cc(float32_compare_quiet(v1, v2, &env->fpu_status));
+-}
+-
+-static uint32_t set_cc_f64(float64 v1, float64 v2)
+-{
+-    return float_comp_to_cc(float64_compare_quiet(v1, v2, &env->fpu_status));
+-}
+-
+-/* condition codes for unary FP ops */
+-static uint32_t set_cc_nz_f32(float32 v)
+-{
+-    if (float32_is_any_nan(v)) {
+-        return 3;
+-    } else if (float32_is_zero(v)) {
+-        return 0;
+-    } else if (float32_is_neg(v)) {
+-        return 1;
+-    } else {
+-        return 2;
+-    }
+-}
+-
+-static uint32_t set_cc_nz_f64(float64 v)
+-{
+-    if (float64_is_any_nan(v)) {
+-        return 3;
+-    } else if (float64_is_zero(v)) {
+-        return 0;
+-    } else if (float64_is_neg(v)) {
+-        return 1;
+-    } else {
+-        return 2;
+-    }
+-}
+-
+-static uint32_t set_cc_nz_f128(float128 v)
+-{
+-    if (float128_is_any_nan(v)) {
+-        return 3;
+-    } else if (float128_is_zero(v)) {
+-        return 0;
+-    } else if (float128_is_neg(v)) {
+-        return 1;
+-    } else {
+-        return 2;
+-    }
+-}
+-
+-/* convert 32-bit int to 64-bit float */
+-void HELPER(cdfbr)(uint32_t f1, int32_t v2)
+-{
+-    HELPER_LOG("%s: converting %d to f%d\n", __func__, v2, f1);
+-    env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status);
+-}
+-
+-/* convert 32-bit int to 128-bit float */
+-void HELPER(cxfbr)(uint32_t f1, int32_t v2)
+-{
+-    CPU_QuadU v1;
+-
+-    v1.q = int32_to_float128(v2, &env->fpu_status);
+-    env->fregs[f1].ll = v1.ll.upper;
+-    env->fregs[f1 + 2].ll = v1.ll.lower;
+-}
+-
+-/* convert 64-bit int to 32-bit float */
+-void HELPER(cegbr)(uint32_t f1, int64_t v2)
+-{
+-    HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
+-    env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status);
+-}
+-
+-/* convert 64-bit int to 64-bit float */
+-void HELPER(cdgbr)(uint32_t f1, int64_t v2)
+-{
+-    HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
+-    env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status);
+-}
+-
+-/* convert 64-bit int to 128-bit float */
+-void HELPER(cxgbr)(uint32_t f1, int64_t v2)
+-{
+-    CPU_QuadU x1;
+-
+-    x1.q = int64_to_float128(v2, &env->fpu_status);
+-    HELPER_LOG("%s: converted %ld to 0x%lx and 0x%lx\n", __func__, v2,
+-               x1.ll.upper, x1.ll.lower);
+-    env->fregs[f1].ll = x1.ll.upper;
+-    env->fregs[f1 + 2].ll = x1.ll.lower;
+-}
+-
+-/* convert 32-bit int to 32-bit float */
+-void HELPER(cefbr)(uint32_t f1, int32_t v2)
+-{
+-    env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status);
+-    HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __func__, v2,
+-               env->fregs[f1].l.upper, f1);
+-}
+-
+-/* 32-bit FP addition RR */
+-uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
+-                                         env->fregs[f2].l.upper,
+-                                         &env->fpu_status);
+-    HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
+-               env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
+-
+-    return set_cc_nz_f32(env->fregs[f1].l.upper);
+-}
+-
+-/* 64-bit FP addition RR */
+-uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d,
+-                                   &env->fpu_status);
+-    HELPER_LOG("%s: adding 0x%ld resulting in 0x%ld in f%d\n", __func__,
+-               env->fregs[f2].d, env->fregs[f1].d, f1);
+-
+-    return set_cc_nz_f64(env->fregs[f1].d);
+-}
+-
+-/* 32-bit FP subtraction RR */
+-uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper,
+-                                         env->fregs[f2].l.upper,
+-                                         &env->fpu_status);
+-    HELPER_LOG("%s: adding 0x%d resulting in 0x%d in f%d\n", __func__,
+-               env->fregs[f2].l.upper, env->fregs[f1].l.upper, f1);
+-
+-    return set_cc_nz_f32(env->fregs[f1].l.upper);
+-}
+-
+-/* 64-bit FP subtraction RR */
+-uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d,
+-                                   &env->fpu_status);
+-    HELPER_LOG("%s: subtracting 0x%ld resulting in 0x%ld in f%d\n",
+-               __func__, env->fregs[f2].d, env->fregs[f1].d, f1);
+-
+-    return set_cc_nz_f64(env->fregs[f1].d);
+-}
+-
+-/* 32-bit FP division RR */
+-void HELPER(debr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper,
+-                                         env->fregs[f2].l.upper,
+-                                         &env->fpu_status);
+-}
+-
+-/* 128-bit FP division RR */
+-void HELPER(dxbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU v1;
+-    CPU_QuadU v2;
+-    CPU_QuadU res;
+-
+-    v1.ll.upper = env->fregs[f1].ll;
+-    v1.ll.lower = env->fregs[f1 + 2].ll;
+-    v2.ll.upper = env->fregs[f2].ll;
+-    v2.ll.lower = env->fregs[f2 + 2].ll;
+-    res.q = float128_div(v1.q, v2.q, &env->fpu_status);
+-    env->fregs[f1].ll = res.ll.upper;
+-    env->fregs[f1 + 2].ll = res.ll.lower;
+-}
+-
+-/* 64-bit FP multiplication RR */
+-void HELPER(mdbr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d,
+-                                   &env->fpu_status);
+-}
+-
+-/* 128-bit FP multiplication RR */
+-void HELPER(mxbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU v1;
+-    CPU_QuadU v2;
+-    CPU_QuadU res;
+-
+-    v1.ll.upper = env->fregs[f1].ll;
+-    v1.ll.lower = env->fregs[f1 + 2].ll;
+-    v2.ll.upper = env->fregs[f2].ll;
+-    v2.ll.lower = env->fregs[f2 + 2].ll;
+-    res.q = float128_mul(v1.q, v2.q, &env->fpu_status);
+-    env->fregs[f1].ll = res.ll.upper;
+-    env->fregs[f1 + 2].ll = res.ll.lower;
+-}
+-
+-/* convert 32-bit float to 64-bit float */
+-void HELPER(ldebr)(uint32_t r1, uint32_t r2)
+-{
+-    env->fregs[r1].d = float32_to_float64(env->fregs[r2].l.upper,
+-                                          &env->fpu_status);
+-}
+-
+-/* convert 128-bit float to 64-bit float */
+-void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU x2;
+-
+-    x2.ll.upper = env->fregs[f2].ll;
+-    x2.ll.lower = env->fregs[f2 + 2].ll;
+-    env->fregs[f1].d = float128_to_float64(x2.q, &env->fpu_status);
+-    HELPER_LOG("%s: to 0x%ld\n", __func__, env->fregs[f1].d);
+-}
+-
+-/* convert 64-bit float to 128-bit float */
+-void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU res;
+-
+-    res.q = float64_to_float128(env->fregs[f2].d, &env->fpu_status);
+-    env->fregs[f1].ll = res.ll.upper;
+-    env->fregs[f1 + 2].ll = res.ll.lower;
+-}
+-
+-/* convert 64-bit float to 32-bit float */
+-void HELPER(ledbr)(uint32_t f1, uint32_t f2)
+-{
+-    float64 d2 = env->fregs[f2].d;
+-
+-    env->fregs[f1].l.upper = float64_to_float32(d2, &env->fpu_status);
+-}
+-
+-/* convert 128-bit float to 32-bit float */
+-void HELPER(lexbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU x2;
+-
+-    x2.ll.upper = env->fregs[f2].ll;
+-    x2.ll.lower = env->fregs[f2 + 2].ll;
+-    env->fregs[f1].l.upper = float128_to_float32(x2.q, &env->fpu_status);
+-    HELPER_LOG("%s: to 0x%d\n", __func__, env->fregs[f1].l.upper);
+-}
+-
+-/* absolute value of 32-bit float */
+-uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
+-{
+-    float32 v1;
+-    float32 v2 = env->fregs[f2].d;
+-
+-    v1 = float32_abs(v2);
+-    env->fregs[f1].d = v1;
+-    return set_cc_nz_f32(v1);
+-}
+-
+-/* absolute value of 64-bit float */
+-uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
+-{
+-    float64 v1;
+-    float64 v2 = env->fregs[f2].d;
+-
+-    v1 = float64_abs(v2);
+-    env->fregs[f1].d = v1;
+-    return set_cc_nz_f64(v1);
+-}
+-
+-/* absolute value of 128-bit float */
+-uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU v1;
+-    CPU_QuadU v2;
+-
+-    v2.ll.upper = env->fregs[f2].ll;
+-    v2.ll.lower = env->fregs[f2 + 2].ll;
+-    v1.q = float128_abs(v2.q);
+-    env->fregs[f1].ll = v1.ll.upper;
+-    env->fregs[f1 + 2].ll = v1.ll.lower;
+-    return set_cc_nz_f128(v1.q);
+-}
+-
+-/* load and test 64-bit float */
+-uint32_t HELPER(ltdbr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].d = env->fregs[f2].d;
+-    return set_cc_nz_f64(env->fregs[f1].d);
+-}
+-
+-/* load and test 32-bit float */
+-uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].l.upper = env->fregs[f2].l.upper;
+-    return set_cc_nz_f32(env->fregs[f1].l.upper);
+-}
+-
+-/* load and test 128-bit float */
+-uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU x;
+-
+-    x.ll.upper = env->fregs[f2].ll;
+-    x.ll.lower = env->fregs[f2 + 2].ll;
+-    env->fregs[f1].ll = x.ll.upper;
+-    env->fregs[f1 + 2].ll = x.ll.lower;
+-    return set_cc_nz_f128(x.q);
+-}
+-
+-/* load complement of 32-bit float */
+-uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].l.upper = float32_chs(env->fregs[f2].l.upper);
+-
+-    return set_cc_nz_f32(env->fregs[f1].l.upper);
+-}
+-
+-/* load complement of 64-bit float */
+-uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].d = float64_chs(env->fregs[f2].d);
+-
+-    return set_cc_nz_f64(env->fregs[f1].d);
+-}
+-
+-/* load complement of 128-bit float */
+-uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU x1, x2;
+-
+-    x2.ll.upper = env->fregs[f2].ll;
+-    x2.ll.lower = env->fregs[f2 + 2].ll;
+-    x1.q = float128_chs(x2.q);
+-    env->fregs[f1].ll = x1.ll.upper;
+-    env->fregs[f1 + 2].ll = x1.ll.lower;
+-    return set_cc_nz_f128(x1.q);
+-}
+-
+-/* 32-bit FP addition RM */
+-void HELPER(aeb)(uint32_t f1, uint32_t val)
+-{
+-    float32 v1 = env->fregs[f1].l.upper;
+-    CPU_FloatU v2;
+-
+-    v2.l = val;
+-    HELPER_LOG("%s: adding 0x%d from f%d and 0x%d\n", __func__,
+-               v1, f1, v2.f);
+-    env->fregs[f1].l.upper = float32_add(v1, v2.f, &env->fpu_status);
+-}
+-
+-/* 32-bit FP division RM */
+-void HELPER(deb)(uint32_t f1, uint32_t val)
+-{
+-    float32 v1 = env->fregs[f1].l.upper;
+-    CPU_FloatU v2;
+-
+-    v2.l = val;
+-    HELPER_LOG("%s: dividing 0x%d from f%d by 0x%d\n", __func__,
+-               v1, f1, v2.f);
+-    env->fregs[f1].l.upper = float32_div(v1, v2.f, &env->fpu_status);
+-}
+-
+-/* 32-bit FP multiplication RM */
+-void HELPER(meeb)(uint32_t f1, uint32_t val)
+-{
+-    float32 v1 = env->fregs[f1].l.upper;
+-    CPU_FloatU v2;
+-
+-    v2.l = val;
+-    HELPER_LOG("%s: multiplying 0x%d from f%d and 0x%d\n", __func__,
+-               v1, f1, v2.f);
+-    env->fregs[f1].l.upper = float32_mul(v1, v2.f, &env->fpu_status);
+-}
+-
+-/* 32-bit FP compare RR */
+-uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2)
+-{
+-    float32 v1 = env->fregs[f1].l.upper;
+-    float32 v2 = env->fregs[f2].l.upper;
+-
+-    HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __func__,
+-               v1, f1, v2);
+-    return set_cc_f32(v1, v2);
+-}
+-
+-/* 64-bit FP compare RR */
+-uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
+-{
+-    float64 v1 = env->fregs[f1].d;
+-    float64 v2 = env->fregs[f2].d;
+-
+-    HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __func__,
+-               v1, f1, v2);
+-    return set_cc_f64(v1, v2);
+-}
+-
+-/* 128-bit FP compare RR */
+-uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU v1;
+-    CPU_QuadU v2;
+-
+-    v1.ll.upper = env->fregs[f1].ll;
+-    v1.ll.lower = env->fregs[f1 + 2].ll;
+-    v2.ll.upper = env->fregs[f2].ll;
+-    v2.ll.lower = env->fregs[f2 + 2].ll;
+-
+-    return float_comp_to_cc(float128_compare_quiet(v1.q, v2.q,
+-                                                   &env->fpu_status));
+-}
+-
+-/* 64-bit FP compare RM */
+-uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2)
+-{
+-    float64 v1 = env->fregs[f1].d;
+-    CPU_DoubleU v2;
+-
+-    v2.ll = ldq(a2);
+-    HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __func__, v1,
+-               f1, v2.d);
+-    return set_cc_f64(v1, v2.d);
+-}
+-
+-/* 64-bit FP addition RM */
+-uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
+-{
+-    float64 v1 = env->fregs[f1].d;
+-    CPU_DoubleU v2;
+-
+-    v2.ll = ldq(a2);
+-    HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __func__,
+-               v1, f1, v2.d);
+-    env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status);
+-    return set_cc_nz_f64(v1);
+-}
+-
+-/* 32-bit FP subtraction RM */
+-void HELPER(seb)(uint32_t f1, uint32_t val)
+-{
+-    float32 v1 = env->fregs[f1].l.upper;
+-    CPU_FloatU v2;
+-
+-    v2.l = val;
+-    env->fregs[f1].l.upper = float32_sub(v1, v2.f, &env->fpu_status);
+-}
+-
+-/* 64-bit FP subtraction RM */
+-uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2)
+-{
+-    float64 v1 = env->fregs[f1].d;
+-    CPU_DoubleU v2;
+-
+-    v2.ll = ldq(a2);
+-    env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status);
+-    return set_cc_nz_f64(v1);
+-}
+-
+-/* 64-bit FP multiplication RM */
+-void HELPER(mdb)(uint32_t f1, uint64_t a2)
+-{
+-    float64 v1 = env->fregs[f1].d;
+-    CPU_DoubleU v2;
+-
+-    v2.ll = ldq(a2);
+-    HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __func__,
+-               v1, f1, v2.d);
+-    env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status);
+-}
+-
+-/* 64-bit FP division RM */
+-void HELPER(ddb)(uint32_t f1, uint64_t a2)
+-{
+-    float64 v1 = env->fregs[f1].d;
+-    CPU_DoubleU v2;
+-
+-    v2.ll = ldq(a2);
+-    HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __func__,
+-               v1, f1, v2.d);
+-    env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status);
+-}
+-
+-static void set_round_mode(int m3)
+-{
+-    switch (m3) {
+-    case 0:
+-        /* current mode */
+-        break;
+-    case 1:
+-        /* biased round no nearest */
+-    case 4:
+-        /* round to nearest */
+-        set_float_rounding_mode(float_round_nearest_even, &env->fpu_status);
+-        break;
+-    case 5:
+-        /* round to zero */
+-        set_float_rounding_mode(float_round_to_zero, &env->fpu_status);
+-        break;
+-    case 6:
+-        /* round to +inf */
+-        set_float_rounding_mode(float_round_up, &env->fpu_status);
+-        break;
+-    case 7:
+-        /* round to -inf */
+-        set_float_rounding_mode(float_round_down, &env->fpu_status);
+-        break;
+-    }
+-}
+-
+-/* convert 32-bit float to 64-bit int */
+-uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
+-{
+-    float32 v2 = env->fregs[f2].l.upper;
+-
+-    set_round_mode(m3);
+-    env->regs[r1] = float32_to_int64(v2, &env->fpu_status);
+-    return set_cc_nz_f32(v2);
+-}
+-
+-/* convert 64-bit float to 64-bit int */
+-uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+-{
+-    float64 v2 = env->fregs[f2].d;
+-
+-    set_round_mode(m3);
+-    env->regs[r1] = float64_to_int64(v2, &env->fpu_status);
+-    return set_cc_nz_f64(v2);
+-}
+-
+-/* convert 128-bit float to 64-bit int */
+-uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+-{
+-    CPU_QuadU v2;
+-
+-    v2.ll.upper = env->fregs[f2].ll;
+-    v2.ll.lower = env->fregs[f2 + 2].ll;
+-    set_round_mode(m3);
+-    env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status);
+-    if (float128_is_any_nan(v2.q)) {
+-        return 3;
+-    } else if (float128_is_zero(v2.q)) {
+-        return 0;
+-    } else if (float128_is_neg(v2.q)) {
+-        return 1;
+-    } else {
+-        return 2;
+-    }
+-}
+-
+-/* convert 32-bit float to 32-bit int */
+-uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
+-{
+-    float32 v2 = env->fregs[f2].l.upper;
+-
+-    set_round_mode(m3);
+-    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+-        float32_to_int32(v2, &env->fpu_status);
+-    return set_cc_nz_f32(v2);
+-}
+-
+-/* convert 64-bit float to 32-bit int */
+-uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+-{
+-    float64 v2 = env->fregs[f2].d;
+-
+-    set_round_mode(m3);
+-    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+-        float64_to_int32(v2, &env->fpu_status);
+-    return set_cc_nz_f64(v2);
+-}
+-
+-/* convert 128-bit float to 32-bit int */
+-uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+-{
+-    CPU_QuadU v2;
+-
+-    v2.ll.upper = env->fregs[f2].ll;
+-    v2.ll.lower = env->fregs[f2 + 2].ll;
+-    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+-        float128_to_int32(v2.q, &env->fpu_status);
+-    return set_cc_nz_f128(v2.q);
+-}
+-
+-/* load 32-bit FP zero */
+-void HELPER(lzer)(uint32_t f1)
+-{
+-    env->fregs[f1].l.upper = float32_zero;
+-}
+-
+-/* load 64-bit FP zero */
+-void HELPER(lzdr)(uint32_t f1)
+-{
+-    env->fregs[f1].d = float64_zero;
+-}
+-
+-/* load 128-bit FP zero */
+-void HELPER(lzxr)(uint32_t f1)
+-{
+-    CPU_QuadU x;
+-
+-    x.q = float64_to_float128(float64_zero, &env->fpu_status);
+-    env->fregs[f1].ll = x.ll.upper;
+-    env->fregs[f1 + 1].ll = x.ll.lower;
+-}
+-
+-/* 128-bit FP subtraction RR */
+-uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU v1;
+-    CPU_QuadU v2;
+-    CPU_QuadU res;
+-
+-    v1.ll.upper = env->fregs[f1].ll;
+-    v1.ll.lower = env->fregs[f1 + 2].ll;
+-    v2.ll.upper = env->fregs[f2].ll;
+-    v2.ll.lower = env->fregs[f2 + 2].ll;
+-    res.q = float128_sub(v1.q, v2.q, &env->fpu_status);
+-    env->fregs[f1].ll = res.ll.upper;
+-    env->fregs[f1 + 2].ll = res.ll.lower;
+-    return set_cc_nz_f128(res.q);
+-}
+-
+-/* 128-bit FP addition RR */
+-uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
+-{
+-    CPU_QuadU v1;
+-    CPU_QuadU v2;
+-    CPU_QuadU res;
+-
+-    v1.ll.upper = env->fregs[f1].ll;
+-    v1.ll.lower = env->fregs[f1 + 2].ll;
+-    v2.ll.upper = env->fregs[f2].ll;
+-    v2.ll.lower = env->fregs[f2 + 2].ll;
+-    res.q = float128_add(v1.q, v2.q, &env->fpu_status);
+-    env->fregs[f1].ll = res.ll.upper;
+-    env->fregs[f1 + 2].ll = res.ll.lower;
+-    return set_cc_nz_f128(res.q);
+-}
+-
+-/* 32-bit FP multiplication RR */
+-void HELPER(meebr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper,
+-                                         env->fregs[f2].l.upper,
+-                                         &env->fpu_status);
+-}
+-
+-/* 64-bit FP division RR */
+-void HELPER(ddbr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].d = float64_div(env->fregs[f1].d, env->fregs[f2].d,
+-                                   &env->fpu_status);
+-}
+-
+-/* 64-bit FP multiply and add RM */
+-void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
+-{
+-    CPU_DoubleU v2;
+-
+-    HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __func__, f1, a2, f3);
+-    v2.ll = ldq(a2);
+-    env->fregs[f1].d = float64_add(env->fregs[f1].d,
+-                                   float64_mul(v2.d, env->fregs[f3].d,
+-                                               &env->fpu_status),
+-                                   &env->fpu_status);
+-}
+-
+-/* 64-bit FP multiply and add RR */
+-void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+-{
+-    HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
+-    env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d,
+-                                               env->fregs[f3].d,
+-                                               &env->fpu_status),
+-                                   env->fregs[f1].d, &env->fpu_status);
+-}
+-
+-/* 64-bit FP multiply and subtract RR */
+-void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+-{
+-    HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
+-    env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d,
+-                                               env->fregs[f3].d,
+-                                               &env->fpu_status),
+-                                   env->fregs[f1].d, &env->fpu_status);
+-}
+-
+-/* 32-bit FP multiply and add RR */
+-void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
+-{
+-    env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
+-                                         float32_mul(env->fregs[f2].l.upper,
+-                                                     env->fregs[f3].l.upper,
+-                                                     &env->fpu_status),
+-                                         &env->fpu_status);
+-}
+-
+-/* convert 32-bit float to 64-bit float */
+-void HELPER(ldeb)(uint32_t f1, uint64_t a2)
+-{
+-    uint32_t v2;
+-
+-    v2 = ldl(a2);
+-    env->fregs[f1].d = float32_to_float64(v2,
+-                                          &env->fpu_status);
+-}
+-
+-/* convert 64-bit float to 128-bit float */
+-void HELPER(lxdb)(uint32_t f1, uint64_t a2)
+-{
+-    CPU_DoubleU v2;
+-    CPU_QuadU v1;
+-
+-    v2.ll = ldq(a2);
+-    v1.q = float64_to_float128(v2.d, &env->fpu_status);
+-    env->fregs[f1].ll = v1.ll.upper;
+-    env->fregs[f1 + 2].ll = v1.ll.lower;
+-}
+-
+-/* test data class 32-bit */
+-uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
+-{
+-    float32 v1 = env->fregs[f1].l.upper;
+-    int neg = float32_is_neg(v1);
+-    uint32_t cc = 0;
+-
+-    HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, (long)v1, m2, neg);
+-    if ((float32_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
+-        (float32_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
+-        (float32_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
+-        (float32_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
+-        cc = 1;
+-    } else if (m2 & (1 << (9-neg))) {
+-        /* assume normalized number */
+-        cc = 1;
+-    }
+-
+-    /* FIXME: denormalized? */
+-    return cc;
+-}
+-
+-/* test data class 64-bit */
+-uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
+-{
+-    float64 v1 = env->fregs[f1].d;
+-    int neg = float64_is_neg(v1);
+-    uint32_t cc = 0;
+-
+-    HELPER_LOG("%s: v1 0x%lx m2 0x%lx neg %d\n", __func__, v1, m2, neg);
+-    if ((float64_is_zero(v1) && (m2 & (1 << (11-neg)))) ||
+-        (float64_is_infinity(v1) && (m2 & (1 << (5-neg)))) ||
+-        (float64_is_any_nan(v1) && (m2 & (1 << (3-neg)))) ||
+-        (float64_is_signaling_nan(v1) && (m2 & (1 << (1-neg))))) {
+-        cc = 1;
+-    } else if (m2 & (1 << (9-neg))) {
+-        /* assume normalized number */
+-        cc = 1;
+-    }
+-    /* FIXME: denormalized? */
+-    return cc;
+-}
+-
+-/* test data class 128-bit */
+-uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
+-{
+-    CPU_QuadU v1;
+-    uint32_t cc = 0;
+-    int neg;
+-
+-    v1.ll.upper = env->fregs[f1].ll;
+-    v1.ll.lower = env->fregs[f1 + 2].ll;
+-
+-    neg = float128_is_neg(v1.q);
+-    if ((float128_is_zero(v1.q) && (m2 & (1 << (11-neg)))) ||
+-        (float128_is_infinity(v1.q) && (m2 & (1 << (5-neg)))) ||
+-        (float128_is_any_nan(v1.q) && (m2 & (1 << (3-neg)))) ||
+-        (float128_is_signaling_nan(v1.q) && (m2 & (1 << (1-neg))))) {
+-        cc = 1;
+-    } else if (m2 & (1 << (9-neg))) {
+-        /* assume normalized number */
+-        cc = 1;
+-    }
+-    /* FIXME: denormalized? */
+-    return cc;
+-}
+-
+ /* find leftmost one */
+ uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
+ {
+@@ -1795,12 +999,6 @@ uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
+     }
+ }
+ 
+-/* square root 64-bit RR */
+-void HELPER(sqdbr)(uint32_t f1, uint32_t f2)
+-{
+-    env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status);
+-}
+-
+ /* checksum */
+ void HELPER(cksm)(uint32_t r1, uint32_t r2)
+ {
+diff --git a/target-s390x/translate.c b/target-s390x/translate.c
+index 1c1baf5..c370df3 100644
+--- a/target-s390x/translate.c
++++ b/target-s390x/translate.c
+@@ -667,16 +667,11 @@ static void set_cc_cmp_f32_i64(DisasContext *s, TCGv_i32 v1, TCGv_i64 v2)
+     s->cc_op = CC_OP_LTGT_F32;
+ }
+ 
+-static void set_cc_nz_f32(DisasContext *s, TCGv_i32 v1)
++static void gen_set_cc_nz_f32(DisasContext *s, TCGv_i32 v1)
+ {
+     gen_op_update1_cc_i32(s, CC_OP_NZ_F32, v1);
+ }
+ 
+-static inline void set_cc_nz_f64(DisasContext *s, TCGv_i64 v1)
+-{
+-    gen_op_update1_cc_i64(s, CC_OP_NZ_F64, v1);
+-}
+-
+ /* CC value is in env->cc_op */
+ static inline void set_cc_static(DisasContext *s)
+ {
+@@ -2235,7 +2230,7 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
+         tcg_temp_free_i32(tmp32);
+ 
+         tmp32 = load_freg32(r1);
+-        set_cc_nz_f32(s, tmp32);
++        gen_set_cc_nz_f32(s, tmp32);
+         tcg_temp_free_i32(tmp32);
+         break;
+     case 0xb: /* SEB    R1,D2(X2,B2)       [RXE] */
+@@ -2248,7 +2243,7 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
+         tcg_temp_free_i32(tmp32);
+ 
+         tmp32 = load_freg32(r1);
+-        set_cc_nz_f32(s, tmp32);
++        gen_set_cc_nz_f32(s, tmp32);
+         tcg_temp_free_i32(tmp32);
+         break;
+     case 0xd: /* DEB    R1,D2(X2,B2)       [RXE] */
+-- 
+1.7.12.1
+
diff --git a/0007-target-s390x-split-condition-code-helpers.patch b/0007-target-s390x-split-condition-code-helpers.patch
new file mode 100644
index 0000000..33ddc67
--- /dev/null
+++ b/0007-target-s390x-split-condition-code-helpers.patch
@@ -0,0 +1,1158 @@
+From f642126aece222f6ff87d26c29f00e1b6c47e10a Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:32 +0000
+Subject: [PATCH] target-s390x: split condition code helpers
+
+Move condition code helpers to cc_helper.c.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/Makefile.objs |   3 +-
+ target-s390x/cc_helper.c   | 551 +++++++++++++++++++++++++++++++++++++++++++++
+ target-s390x/cpu.h         |   3 +
+ target-s390x/op_helper.c   | 522 +-----------------------------------------
+ 4 files changed, 557 insertions(+), 522 deletions(-)
+ create mode 100644 target-s390x/cc_helper.c
+
+diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
+index 23b3bd9..f9437d6 100644
+--- a/target-s390x/Makefile.objs
++++ b/target-s390x/Makefile.objs
+@@ -1,7 +1,8 @@
+ obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
+-obj-y += fpu_helper.o
++obj-y += fpu_helper.o cc_helper.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-$(CONFIG_KVM) += kvm.o
+ 
+ $(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
++$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
+new file mode 100644
+index 0000000..2ac1659
+--- /dev/null
++++ b/target-s390x/cc_helper.c
+@@ -0,0 +1,551 @@
++/*
++ *  S/390 condition code helper routines
++ *
++ *  Copyright (c) 2009 Ulrich Hecht
++ *  Copyright (c) 2009 Alexander Graf
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "cpu.h"
++#include "dyngen-exec.h"
++#include "helper.h"
++
++/* #define DEBUG_HELPER */
++#ifdef DEBUG_HELPER
++#define HELPER_LOG(x...) qemu_log(x)
++#else
++#define HELPER_LOG(x...)
++#endif
++
++static inline uint32_t cc_calc_ltgt_32(CPUS390XState *env, int32_t src,
++                                       int32_t dst)
++{
++    if (src == dst) {
++        return 0;
++    } else if (src < dst) {
++        return 1;
++    } else {
++        return 2;
++    }
++}
++
++static inline uint32_t cc_calc_ltgt0_32(CPUS390XState *env, int32_t dst)
++{
++    return cc_calc_ltgt_32(env, dst, 0);
++}
++
++static inline uint32_t cc_calc_ltgt_64(CPUS390XState *env, int64_t src,
++                                       int64_t dst)
++{
++    if (src == dst) {
++        return 0;
++    } else if (src < dst) {
++        return 1;
++    } else {
++        return 2;
++    }
++}
++
++static inline uint32_t cc_calc_ltgt0_64(CPUS390XState *env, int64_t dst)
++{
++    return cc_calc_ltgt_64(env, dst, 0);
++}
++
++static inline uint32_t cc_calc_ltugtu_32(CPUS390XState *env, uint32_t src,
++                                         uint32_t dst)
++{
++    if (src == dst) {
++        return 0;
++    } else if (src < dst) {
++        return 1;
++    } else {
++        return 2;
++    }
++}
++
++static inline uint32_t cc_calc_ltugtu_64(CPUS390XState *env, uint64_t src,
++                                         uint64_t dst)
++{
++    if (src == dst) {
++        return 0;
++    } else if (src < dst) {
++        return 1;
++    } else {
++        return 2;
++    }
++}
++
++static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val,
++                                     uint32_t mask)
++{
++    uint16_t r = val & mask;
++
++    HELPER_LOG("%s: val 0x%x mask 0x%x\n", __func__, val, mask);
++    if (r == 0 || mask == 0) {
++        return 0;
++    } else if (r == mask) {
++        return 3;
++    } else {
++        return 1;
++    }
++}
++
++/* set condition code for test under mask */
++static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val,
++                                     uint32_t mask)
++{
++    uint16_t r = val & mask;
++
++    HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __func__, val, mask, r);
++    if (r == 0 || mask == 0) {
++        return 0;
++    } else if (r == mask) {
++        return 3;
++    } else {
++        while (!(mask & 0x8000)) {
++            mask <<= 1;
++            val <<= 1;
++        }
++        if (val & 0x8000) {
++            return 2;
++        } else {
++            return 1;
++        }
++    }
++}
++
++static inline uint32_t cc_calc_nz(CPUS390XState *env, uint64_t dst)
++{
++    return !!dst;
++}
++
++static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1,
++                                      int64_t a2, int64_t ar)
++{
++    if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
++        return 3; /* overflow */
++    } else {
++        if (ar < 0) {
++            return 1;
++        } else if (ar > 0) {
++            return 2;
++        } else {
++            return 0;
++        }
++    }
++}
++
++static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1,
++                                       uint64_t a2, uint64_t ar)
++{
++    if (ar == 0) {
++        if (a1) {
++            return 2;
++        } else {
++            return 0;
++        }
++    } else {
++        if (ar < a1 || ar < a2) {
++            return 3;
++        } else {
++            return 1;
++        }
++    }
++}
++
++static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1,
++                                      int64_t a2, int64_t ar)
++{
++    if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
++        return 3; /* overflow */
++    } else {
++        if (ar < 0) {
++            return 1;
++        } else if (ar > 0) {
++            return 2;
++        } else {
++            return 0;
++        }
++    }
++}
++
++static inline uint32_t cc_calc_subu_64(CPUS390XState *env, uint64_t a1,
++                                       uint64_t a2, uint64_t ar)
++{
++    if (ar == 0) {
++        return 2;
++    } else {
++        if (a2 > a1) {
++            return 1;
++        } else {
++            return 3;
++        }
++    }
++}
++
++static inline uint32_t cc_calc_abs_64(CPUS390XState *env, int64_t dst)
++{
++    if ((uint64_t)dst == 0x8000000000000000ULL) {
++        return 3;
++    } else if (dst) {
++        return 1;
++    } else {
++        return 0;
++    }
++}
++
++static inline uint32_t cc_calc_nabs_64(CPUS390XState *env, int64_t dst)
++{
++    return !!dst;
++}
++
++static inline uint32_t cc_calc_comp_64(CPUS390XState *env, int64_t dst)
++{
++    if ((uint64_t)dst == 0x8000000000000000ULL) {
++        return 3;
++    } else if (dst < 0) {
++        return 1;
++    } else if (dst > 0) {
++        return 2;
++    } else {
++        return 0;
++    }
++}
++
++
++static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1,
++                                      int32_t a2, int32_t ar)
++{
++    if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
++        return 3; /* overflow */
++    } else {
++        if (ar < 0) {
++            return 1;
++        } else if (ar > 0) {
++            return 2;
++        } else {
++            return 0;
++        }
++    }
++}
++
++static inline uint32_t cc_calc_addu_32(CPUS390XState *env, uint32_t a1,
++                                       uint32_t a2, uint32_t ar)
++{
++    if (ar == 0) {
++        if (a1) {
++            return 2;
++        } else {
++            return 0;
++        }
++    } else {
++        if (ar < a1 || ar < a2) {
++            return 3;
++        } else {
++            return 1;
++        }
++    }
++}
++
++static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1,
++                                      int32_t a2, int32_t ar)
++{
++    if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
++        return 3; /* overflow */
++    } else {
++        if (ar < 0) {
++            return 1;
++        } else if (ar > 0) {
++            return 2;
++        } else {
++            return 0;
++        }
++    }
++}
++
++static inline uint32_t cc_calc_subu_32(CPUS390XState *env, uint32_t a1,
++                                       uint32_t a2, uint32_t ar)
++{
++    if (ar == 0) {
++        return 2;
++    } else {
++        if (a2 > a1) {
++            return 1;
++        } else {
++            return 3;
++        }
++    }
++}
++
++static inline uint32_t cc_calc_abs_32(CPUS390XState *env, int32_t dst)
++{
++    if ((uint32_t)dst == 0x80000000UL) {
++        return 3;
++    } else if (dst) {
++        return 1;
++    } else {
++        return 0;
++    }
++}
++
++static inline uint32_t cc_calc_nabs_32(CPUS390XState *env, int32_t dst)
++{
++    return !!dst;
++}
++
++static inline uint32_t cc_calc_comp_32(CPUS390XState *env, int32_t dst)
++{
++    if ((uint32_t)dst == 0x80000000UL) {
++        return 3;
++    } else if (dst < 0) {
++        return 1;
++    } else if (dst > 0) {
++        return 2;
++    } else {
++        return 0;
++    }
++}
++
++/* calculate condition code for insert character under mask insn */
++static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask,
++                                      uint32_t val)
++{
++    uint32_t cc;
++
++    HELPER_LOG("%s: mask 0x%x val %d\n", __func__, mask, val);
++    if (mask == 0xf) {
++        if (!val) {
++            return 0;
++        } else if (val & 0x80000000) {
++            return 1;
++        } else {
++            return 2;
++        }
++    }
++
++    if (!val || !mask) {
++        cc = 0;
++    } else {
++        while (mask != 1) {
++            mask >>= 1;
++            val >>= 8;
++        }
++        if (val & 0x80) {
++            cc = 1;
++        } else {
++            cc = 2;
++        }
++    }
++    return cc;
++}
++
++static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src,
++                                    uint64_t shift)
++{
++    uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
++    uint64_t match, r;
++
++    /* check if the sign bit stays the same */
++    if (src & (1ULL << 63)) {
++        match = mask;
++    } else {
++        match = 0;
++    }
++
++    if ((src & mask) != match) {
++        /* overflow */
++        return 3;
++    }
++
++    r = ((src << shift) & ((1ULL << 63) - 1)) | (src & (1ULL << 63));
++
++    if ((int64_t)r == 0) {
++        return 0;
++    } else if ((int64_t)r < 0) {
++        return 1;
++    }
++
++    return 2;
++}
++
++
++static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
++                                  uint64_t src, uint64_t dst, uint64_t vr)
++{
++    uint32_t r = 0;
++
++    switch (cc_op) {
++    case CC_OP_CONST0:
++    case CC_OP_CONST1:
++    case CC_OP_CONST2:
++    case CC_OP_CONST3:
++        /* cc_op value _is_ cc */
++        r = cc_op;
++        break;
++    case CC_OP_LTGT0_32:
++        r = cc_calc_ltgt0_32(env, dst);
++        break;
++    case CC_OP_LTGT0_64:
++        r =  cc_calc_ltgt0_64(env, dst);
++        break;
++    case CC_OP_LTGT_32:
++        r =  cc_calc_ltgt_32(env, src, dst);
++        break;
++    case CC_OP_LTGT_64:
++        r =  cc_calc_ltgt_64(env, src, dst);
++        break;
++    case CC_OP_LTUGTU_32:
++        r =  cc_calc_ltugtu_32(env, src, dst);
++        break;
++    case CC_OP_LTUGTU_64:
++        r =  cc_calc_ltugtu_64(env, src, dst);
++        break;
++    case CC_OP_TM_32:
++        r =  cc_calc_tm_32(env, src, dst);
++        break;
++    case CC_OP_TM_64:
++        r =  cc_calc_tm_64(env, src, dst);
++        break;
++    case CC_OP_NZ:
++        r =  cc_calc_nz(env, dst);
++        break;
++    case CC_OP_ADD_64:
++        r =  cc_calc_add_64(env, src, dst, vr);
++        break;
++    case CC_OP_ADDU_64:
++        r =  cc_calc_addu_64(env, src, dst, vr);
++        break;
++    case CC_OP_SUB_64:
++        r =  cc_calc_sub_64(env, src, dst, vr);
++        break;
++    case CC_OP_SUBU_64:
++        r =  cc_calc_subu_64(env, src, dst, vr);
++        break;
++    case CC_OP_ABS_64:
++        r =  cc_calc_abs_64(env, dst);
++        break;
++    case CC_OP_NABS_64:
++        r =  cc_calc_nabs_64(env, dst);
++        break;
++    case CC_OP_COMP_64:
++        r =  cc_calc_comp_64(env, dst);
++        break;
++
++    case CC_OP_ADD_32:
++        r =  cc_calc_add_32(env, src, dst, vr);
++        break;
++    case CC_OP_ADDU_32:
++        r =  cc_calc_addu_32(env, src, dst, vr);
++        break;
++    case CC_OP_SUB_32:
++        r =  cc_calc_sub_32(env, src, dst, vr);
++        break;
++    case CC_OP_SUBU_32:
++        r =  cc_calc_subu_32(env, src, dst, vr);
++        break;
++    case CC_OP_ABS_32:
++        r =  cc_calc_abs_64(env, dst);
++        break;
++    case CC_OP_NABS_32:
++        r =  cc_calc_nabs_64(env, dst);
++        break;
++    case CC_OP_COMP_32:
++        r =  cc_calc_comp_32(env, dst);
++        break;
++
++    case CC_OP_ICM:
++        r =  cc_calc_icm_32(env, src, dst);
++        break;
++    case CC_OP_SLAG:
++        r =  cc_calc_slag(env, src, dst);
++        break;
++
++    case CC_OP_LTGT_F32:
++        r = set_cc_f32(src, dst);
++        break;
++    case CC_OP_LTGT_F64:
++        r = set_cc_f64(src, dst);
++        break;
++    case CC_OP_NZ_F32:
++        r = set_cc_nz_f32(dst);
++        break;
++    case CC_OP_NZ_F64:
++        r = set_cc_nz_f64(dst);
++        break;
++
++    default:
++        cpu_abort(env, "Unknown CC operation: %s\n", cc_name(cc_op));
++    }
++
++    HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __func__,
++               cc_name(cc_op), src, dst, vr, r);
++    return r;
++}
++
++uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
++                 uint64_t vr)
++{
++    return do_calc_cc(env, cc_op, src, dst, vr);
++}
++
++uint32_t HELPER(calc_cc)(uint32_t cc_op, uint64_t src, uint64_t dst,
++                         uint64_t vr)
++{
++    return do_calc_cc(env, cc_op, src, dst, vr);
++}
++
++/* insert psw mask and condition code into r1 */
++void HELPER(ipm)(uint32_t cc, uint32_t r1)
++{
++    uint64_t r = env->regs[r1];
++
++    r &= 0xffffffff00ffffffULL;
++    r |= (cc << 28) | ((env->psw.mask >> 40) & 0xf);
++    env->regs[r1] = r;
++    HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __func__,
++               cc, env->psw.mask, r);
++}
++
++#ifndef CONFIG_USER_ONLY
++void HELPER(load_psw)(uint64_t mask, uint64_t addr)
++{
++    load_psw(env, mask, addr);
++    cpu_loop_exit(env);
++}
++
++void HELPER(sacf)(uint64_t a1)
++{
++    HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);
++
++    switch (a1 & 0xf00) {
++    case 0x000:
++        env->psw.mask &= ~PSW_MASK_ASC;
++        env->psw.mask |= PSW_ASC_PRIMARY;
++        break;
++    case 0x100:
++        env->psw.mask &= ~PSW_MASK_ASC;
++        env->psw.mask |= PSW_ASC_SECONDARY;
++        break;
++    case 0x300:
++        env->psw.mask &= ~PSW_MASK_ASC;
++        env->psw.mask |= PSW_ASC_HOME;
++        break;
++    default:
++        qemu_log("unknown sacf mode: %" PRIx64 "\n", a1);
++        program_interrupt(env, PGM_SPECIFICATION, 2);
++        break;
++    }
++}
++#endif
+diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
+index b4620c5..97fde5e 100644
+--- a/target-s390x/cpu.h
++++ b/target-s390x/cpu.h
+@@ -1005,4 +1005,7 @@ uint32_t set_cc_f64(float64 v1, float64 v2);
+ uint32_t set_cc_nz_f32(float32 v);
+ uint32_t set_cc_nz_f64(float64 v);
+ 
++/* op_helper.c */
++void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
++
+ #endif
+diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
+index 270bf14..eced890 100644
+--- a/target-s390x/op_helper.c
++++ b/target-s390x/op_helper.c
+@@ -779,18 +779,6 @@ uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
+     return cc;
+ }
+ 
+-/* insert psw mask and condition code into r1 */
+-void HELPER(ipm)(uint32_t cc, uint32_t r1)
+-{
+-    uint64_t r = env->regs[r1];
+-
+-    r &= 0xffffffff00ffffffULL;
+-    r |= (cc << 28) | ((env->psw.mask >> 40) & 0xf);
+-    env->regs[r1] = r;
+-    HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __func__,
+-               cc, env->psw.mask, r);
+-}
+-
+ /* load access registers r1 to r3 from memory at a2 */
+ void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+@@ -1038,483 +1026,6 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
+         ((uint32_t)cksm + (cksm >> 32));
+ }
+ 
+-static inline uint32_t cc_calc_ltgt_32(CPUS390XState *env, int32_t src,
+-                                       int32_t dst)
+-{
+-    if (src == dst) {
+-        return 0;
+-    } else if (src < dst) {
+-        return 1;
+-    } else {
+-        return 2;
+-    }
+-}
+-
+-static inline uint32_t cc_calc_ltgt0_32(CPUS390XState *env, int32_t dst)
+-{
+-    return cc_calc_ltgt_32(env, dst, 0);
+-}
+-
+-static inline uint32_t cc_calc_ltgt_64(CPUS390XState *env, int64_t src,
+-                                       int64_t dst)
+-{
+-    if (src == dst) {
+-        return 0;
+-    } else if (src < dst) {
+-        return 1;
+-    } else {
+-        return 2;
+-    }
+-}
+-
+-static inline uint32_t cc_calc_ltgt0_64(CPUS390XState *env, int64_t dst)
+-{
+-    return cc_calc_ltgt_64(env, dst, 0);
+-}
+-
+-static inline uint32_t cc_calc_ltugtu_32(CPUS390XState *env, uint32_t src,
+-                                         uint32_t dst)
+-{
+-    if (src == dst) {
+-        return 0;
+-    } else if (src < dst) {
+-        return 1;
+-    } else {
+-        return 2;
+-    }
+-}
+-
+-static inline uint32_t cc_calc_ltugtu_64(CPUS390XState *env, uint64_t src,
+-                                         uint64_t dst)
+-{
+-    if (src == dst) {
+-        return 0;
+-    } else if (src < dst) {
+-        return 1;
+-    } else {
+-        return 2;
+-    }
+-}
+-
+-static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val,
+-                                     uint32_t mask)
+-{
+-    uint16_t r = val & mask;
+-
+-    HELPER_LOG("%s: val 0x%x mask 0x%x\n", __func__, val, mask);
+-    if (r == 0 || mask == 0) {
+-        return 0;
+-    } else if (r == mask) {
+-        return 3;
+-    } else {
+-        return 1;
+-    }
+-}
+-
+-/* set condition code for test under mask */
+-static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val,
+-                                     uint32_t mask)
+-{
+-    uint16_t r = val & mask;
+-
+-    HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __func__, val, mask, r);
+-    if (r == 0 || mask == 0) {
+-        return 0;
+-    } else if (r == mask) {
+-        return 3;
+-    } else {
+-        while (!(mask & 0x8000)) {
+-            mask <<= 1;
+-            val <<= 1;
+-        }
+-        if (val & 0x8000) {
+-            return 2;
+-        } else {
+-            return 1;
+-        }
+-    }
+-}
+-
+-static inline uint32_t cc_calc_nz(CPUS390XState *env, uint64_t dst)
+-{
+-    return !!dst;
+-}
+-
+-static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1,
+-                                      int64_t a2, int64_t ar)
+-{
+-    if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
+-        return 3; /* overflow */
+-    } else {
+-        if (ar < 0) {
+-            return 1;
+-        } else if (ar > 0) {
+-            return 2;
+-        } else {
+-            return 0;
+-        }
+-    }
+-}
+-
+-static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1,
+-                                       uint64_t a2, uint64_t ar)
+-{
+-    if (ar == 0) {
+-        if (a1) {
+-            return 2;
+-        } else {
+-            return 0;
+-        }
+-    } else {
+-        if (ar < a1 || ar < a2) {
+-            return 3;
+-        } else {
+-            return 1;
+-        }
+-    }
+-}
+-
+-static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1,
+-                                      int64_t a2, int64_t ar)
+-{
+-    if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
+-        return 3; /* overflow */
+-    } else {
+-        if (ar < 0) {
+-            return 1;
+-        } else if (ar > 0) {
+-            return 2;
+-        } else {
+-            return 0;
+-        }
+-    }
+-}
+-
+-static inline uint32_t cc_calc_subu_64(CPUS390XState *env, uint64_t a1,
+-                                       uint64_t a2, uint64_t ar)
+-{
+-    if (ar == 0) {
+-        return 2;
+-    } else {
+-        if (a2 > a1) {
+-            return 1;
+-        } else {
+-            return 3;
+-        }
+-    }
+-}
+-
+-static inline uint32_t cc_calc_abs_64(CPUS390XState *env, int64_t dst)
+-{
+-    if ((uint64_t)dst == 0x8000000000000000ULL) {
+-        return 3;
+-    } else if (dst) {
+-        return 1;
+-    } else {
+-        return 0;
+-    }
+-}
+-
+-static inline uint32_t cc_calc_nabs_64(CPUS390XState *env, int64_t dst)
+-{
+-    return !!dst;
+-}
+-
+-static inline uint32_t cc_calc_comp_64(CPUS390XState *env, int64_t dst)
+-{
+-    if ((uint64_t)dst == 0x8000000000000000ULL) {
+-        return 3;
+-    } else if (dst < 0) {
+-        return 1;
+-    } else if (dst > 0) {
+-        return 2;
+-    } else {
+-        return 0;
+-    }
+-}
+-
+-
+-static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1,
+-                                      int32_t a2, int32_t ar)
+-{
+-    if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
+-        return 3; /* overflow */
+-    } else {
+-        if (ar < 0) {
+-            return 1;
+-        } else if (ar > 0) {
+-            return 2;
+-        } else {
+-            return 0;
+-        }
+-    }
+-}
+-
+-static inline uint32_t cc_calc_addu_32(CPUS390XState *env, uint32_t a1,
+-                                       uint32_t a2, uint32_t ar)
+-{
+-    if (ar == 0) {
+-        if (a1) {
+-            return 2;
+-        } else {
+-            return 0;
+-        }
+-    } else {
+-        if (ar < a1 || ar < a2) {
+-            return 3;
+-        } else {
+-            return 1;
+-        }
+-    }
+-}
+-
+-static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1,
+-                                      int32_t a2, int32_t ar)
+-{
+-    if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
+-        return 3; /* overflow */
+-    } else {
+-        if (ar < 0) {
+-            return 1;
+-        } else if (ar > 0) {
+-            return 2;
+-        } else {
+-            return 0;
+-        }
+-    }
+-}
+-
+-static inline uint32_t cc_calc_subu_32(CPUS390XState *env, uint32_t a1,
+-                                       uint32_t a2, uint32_t ar)
+-{
+-    if (ar == 0) {
+-        return 2;
+-    } else {
+-        if (a2 > a1) {
+-            return 1;
+-        } else {
+-            return 3;
+-        }
+-    }
+-}
+-
+-static inline uint32_t cc_calc_abs_32(CPUS390XState *env, int32_t dst)
+-{
+-    if ((uint32_t)dst == 0x80000000UL) {
+-        return 3;
+-    } else if (dst) {
+-        return 1;
+-    } else {
+-        return 0;
+-    }
+-}
+-
+-static inline uint32_t cc_calc_nabs_32(CPUS390XState *env, int32_t dst)
+-{
+-    return !!dst;
+-}
+-
+-static inline uint32_t cc_calc_comp_32(CPUS390XState *env, int32_t dst)
+-{
+-    if ((uint32_t)dst == 0x80000000UL) {
+-        return 3;
+-    } else if (dst < 0) {
+-        return 1;
+-    } else if (dst > 0) {
+-        return 2;
+-    } else {
+-        return 0;
+-    }
+-}
+-
+-/* calculate condition code for insert character under mask insn */
+-static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask,
+-                                      uint32_t val)
+-{
+-    uint32_t cc;
+-
+-    HELPER_LOG("%s: mask 0x%x val %d\n", __func__, mask, val);
+-    if (mask == 0xf) {
+-        if (!val) {
+-            return 0;
+-        } else if (val & 0x80000000) {
+-            return 1;
+-        } else {
+-            return 2;
+-        }
+-    }
+-
+-    if (!val || !mask) {
+-        cc = 0;
+-    } else {
+-        while (mask != 1) {
+-            mask >>= 1;
+-            val >>= 8;
+-        }
+-        if (val & 0x80) {
+-            cc = 1;
+-        } else {
+-            cc = 2;
+-        }
+-    }
+-    return cc;
+-}
+-
+-static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src,
+-                                    uint64_t shift)
+-{
+-    uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
+-    uint64_t match, r;
+-
+-    /* check if the sign bit stays the same */
+-    if (src & (1ULL << 63)) {
+-        match = mask;
+-    } else {
+-        match = 0;
+-    }
+-
+-    if ((src & mask) != match) {
+-        /* overflow */
+-        return 3;
+-    }
+-
+-    r = ((src << shift) & ((1ULL << 63) - 1)) | (src & (1ULL << 63));
+-
+-    if ((int64_t)r == 0) {
+-        return 0;
+-    } else if ((int64_t)r < 0) {
+-        return 1;
+-    }
+-
+-    return 2;
+-}
+-
+-
+-static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
+-                                  uint64_t src, uint64_t dst, uint64_t vr)
+-{
+-    uint32_t r = 0;
+-
+-    switch (cc_op) {
+-    case CC_OP_CONST0:
+-    case CC_OP_CONST1:
+-    case CC_OP_CONST2:
+-    case CC_OP_CONST3:
+-        /* cc_op value _is_ cc */
+-        r = cc_op;
+-        break;
+-    case CC_OP_LTGT0_32:
+-        r = cc_calc_ltgt0_32(env, dst);
+-        break;
+-    case CC_OP_LTGT0_64:
+-        r =  cc_calc_ltgt0_64(env, dst);
+-        break;
+-    case CC_OP_LTGT_32:
+-        r =  cc_calc_ltgt_32(env, src, dst);
+-        break;
+-    case CC_OP_LTGT_64:
+-        r =  cc_calc_ltgt_64(env, src, dst);
+-        break;
+-    case CC_OP_LTUGTU_32:
+-        r =  cc_calc_ltugtu_32(env, src, dst);
+-        break;
+-    case CC_OP_LTUGTU_64:
+-        r =  cc_calc_ltugtu_64(env, src, dst);
+-        break;
+-    case CC_OP_TM_32:
+-        r =  cc_calc_tm_32(env, src, dst);
+-        break;
+-    case CC_OP_TM_64:
+-        r =  cc_calc_tm_64(env, src, dst);
+-        break;
+-    case CC_OP_NZ:
+-        r =  cc_calc_nz(env, dst);
+-        break;
+-    case CC_OP_ADD_64:
+-        r =  cc_calc_add_64(env, src, dst, vr);
+-        break;
+-    case CC_OP_ADDU_64:
+-        r =  cc_calc_addu_64(env, src, dst, vr);
+-        break;
+-    case CC_OP_SUB_64:
+-        r =  cc_calc_sub_64(env, src, dst, vr);
+-        break;
+-    case CC_OP_SUBU_64:
+-        r =  cc_calc_subu_64(env, src, dst, vr);
+-        break;
+-    case CC_OP_ABS_64:
+-        r =  cc_calc_abs_64(env, dst);
+-        break;
+-    case CC_OP_NABS_64:
+-        r =  cc_calc_nabs_64(env, dst);
+-        break;
+-    case CC_OP_COMP_64:
+-        r =  cc_calc_comp_64(env, dst);
+-        break;
+-
+-    case CC_OP_ADD_32:
+-        r =  cc_calc_add_32(env, src, dst, vr);
+-        break;
+-    case CC_OP_ADDU_32:
+-        r =  cc_calc_addu_32(env, src, dst, vr);
+-        break;
+-    case CC_OP_SUB_32:
+-        r =  cc_calc_sub_32(env, src, dst, vr);
+-        break;
+-    case CC_OP_SUBU_32:
+-        r =  cc_calc_subu_32(env, src, dst, vr);
+-        break;
+-    case CC_OP_ABS_32:
+-        r =  cc_calc_abs_64(env, dst);
+-        break;
+-    case CC_OP_NABS_32:
+-        r =  cc_calc_nabs_64(env, dst);
+-        break;
+-    case CC_OP_COMP_32:
+-        r =  cc_calc_comp_32(env, dst);
+-        break;
+-
+-    case CC_OP_ICM:
+-        r =  cc_calc_icm_32(env, src, dst);
+-        break;
+-    case CC_OP_SLAG:
+-        r =  cc_calc_slag(env, src, dst);
+-        break;
+-
+-    case CC_OP_LTGT_F32:
+-        r = set_cc_f32(src, dst);
+-        break;
+-    case CC_OP_LTGT_F64:
+-        r = set_cc_f64(src, dst);
+-        break;
+-    case CC_OP_NZ_F32:
+-        r = set_cc_nz_f32(dst);
+-        break;
+-    case CC_OP_NZ_F64:
+-        r = set_cc_nz_f64(dst);
+-        break;
+-
+-    default:
+-        cpu_abort(env, "Unknown CC operation: %s\n", cc_name(cc_op));
+-    }
+-
+-    HELPER_LOG("%s: %15s 0x%016lx 0x%016lx 0x%016lx = %d\n", __func__,
+-               cc_name(cc_op), src, dst, vr, r);
+-    return r;
+-}
+-
+-uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
+-                 uint64_t vr)
+-{
+-    return do_calc_cc(env, cc_op, src, dst, vr);
+-}
+-
+-uint32_t HELPER(calc_cc)(uint32_t cc_op, uint64_t src, uint64_t dst,
+-                         uint64_t vr)
+-{
+-    return do_calc_cc(env, cc_op, src, dst, vr);
+-}
+-
+ uint64_t HELPER(cvd)(int32_t bin)
+ {
+     /* positive 0 */
+@@ -1594,14 +1105,7 @@ void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
+ }
+ 
+ #ifndef CONFIG_USER_ONLY
+-
+-void HELPER(load_psw)(uint64_t mask, uint64_t addr)
+-{
+-    load_psw(env, mask, addr);
+-    cpu_loop_exit(env);
+-}
+-
+-static void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
++void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
+ {
+     qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
+ 
+@@ -2175,30 +1679,6 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
+     return cc;
+ }
+ 
+-void HELPER(sacf)(uint64_t a1)
+-{
+-    HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);
+-
+-    switch (a1 & 0xf00) {
+-    case 0x000:
+-        env->psw.mask &= ~PSW_MASK_ASC;
+-        env->psw.mask |= PSW_ASC_PRIMARY;
+-        break;
+-    case 0x100:
+-        env->psw.mask &= ~PSW_MASK_ASC;
+-        env->psw.mask |= PSW_ASC_SECONDARY;
+-        break;
+-    case 0x300:
+-        env->psw.mask &= ~PSW_MASK_ASC;
+-        env->psw.mask |= PSW_ASC_HOME;
+-        break;
+-    default:
+-        qemu_log("unknown sacf mode: %" PRIx64 "\n", a1);
+-        program_interrupt(env, PGM_SPECIFICATION, 2);
+-        break;
+-    }
+-}
+-
+ /* invalidate pte */
+ void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
+ {
+-- 
+1.7.12.1
+
diff --git a/0008-target-s390x-split-integer-helpers.patch b/0008-target-s390x-split-integer-helpers.patch
new file mode 100644
index 0000000..5610e6d
--- /dev/null
+++ b/0008-target-s390x-split-integer-helpers.patch
@@ -0,0 +1,444 @@
+From e9f67c1f326a995ff0000a08a223435386867d8f Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:33 +0000
+Subject: [PATCH] target-s390x: split integer helpers
+
+Move integer helpers to int_helper.c.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/Makefile.objs |   3 +-
+ target-s390x/int_helper.c  | 201 +++++++++++++++++++++++++++++++++++++++++++++
+ target-s390x/op_helper.c   | 170 --------------------------------------
+ 3 files changed, 203 insertions(+), 171 deletions(-)
+ create mode 100644 target-s390x/int_helper.c
+
+diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
+index f9437d6..e8f66e9 100644
+--- a/target-s390x/Makefile.objs
++++ b/target-s390x/Makefile.objs
+@@ -1,8 +1,9 @@
+ obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
+-obj-y += fpu_helper.o cc_helper.o
++obj-y += int_helper.o fpu_helper.o cc_helper.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-$(CONFIG_KVM) += kvm.o
+ 
+ $(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
++$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
+new file mode 100644
+index 0000000..e2eeb07
+--- /dev/null
++++ b/target-s390x/int_helper.c
+@@ -0,0 +1,201 @@
++/*
++ *  S/390 integer helper routines
++ *
++ *  Copyright (c) 2009 Ulrich Hecht
++ *  Copyright (c) 2009 Alexander Graf
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "cpu.h"
++#include "dyngen-exec.h"
++#include "host-utils.h"
++#include "helper.h"
++
++/* #define DEBUG_HELPER */
++#ifdef DEBUG_HELPER
++#define HELPER_LOG(x...) qemu_log(x)
++#else
++#define HELPER_LOG(x...)
++#endif
++
++/* 64/64 -> 128 unsigned multiplication */
++void HELPER(mlg)(uint32_t r1, uint64_t v2)
++{
++#if HOST_LONG_BITS == 64 && defined(__GNUC__)
++    /* assuming 64-bit hosts have __uint128_t */
++    __uint128_t res = (__uint128_t)env->regs[r1 + 1];
++
++    res *= (__uint128_t)v2;
++    env->regs[r1] = (uint64_t)(res >> 64);
++    env->regs[r1 + 1] = (uint64_t)res;
++#else
++    mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2);
++#endif
++}
++
++/* 128 -> 64/64 unsigned division */
++void HELPER(dlg)(uint32_t r1, uint64_t v2)
++{
++    uint64_t divisor = v2;
++
++    if (!env->regs[r1]) {
++        /* 64 -> 64/64 case */
++        env->regs[r1] = env->regs[r1 + 1] % divisor;
++        env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
++        return;
++    } else {
++#if HOST_LONG_BITS == 64 && defined(__GNUC__)
++        /* assuming 64-bit hosts have __uint128_t */
++        __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
++            (env->regs[r1 + 1]);
++        __uint128_t quotient = dividend / divisor;
++        __uint128_t remainder = dividend % divisor;
++
++        env->regs[r1 + 1] = quotient;
++        env->regs[r1] = remainder;
++#else
++        /* 32-bit hosts would need special wrapper functionality - just abort if
++           we encounter such a case; it's very unlikely anyways. */
++        cpu_abort(env, "128 -> 64/64 division not implemented\n");
++#endif
++    }
++}
++
++/* absolute value 32-bit */
++uint32_t HELPER(abs_i32)(int32_t val)
++{
++    if (val < 0) {
++        return -val;
++    } else {
++        return val;
++    }
++}
++
++/* negative absolute value 32-bit */
++int32_t HELPER(nabs_i32)(int32_t val)
++{
++    if (val < 0) {
++        return val;
++    } else {
++        return -val;
++    }
++}
++
++/* absolute value 64-bit */
++uint64_t HELPER(abs_i64)(int64_t val)
++{
++    HELPER_LOG("%s: val 0x%" PRIx64 "\n", __func__, val);
++
++    if (val < 0) {
++        return -val;
++    } else {
++        return val;
++    }
++}
++
++/* negative absolute value 64-bit */
++int64_t HELPER(nabs_i64)(int64_t val)
++{
++    if (val < 0) {
++        return val;
++    } else {
++        return -val;
++    }
++}
++
++/* add with carry 32-bit unsigned */
++uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
++{
++    uint32_t res;
++
++    res = v1 + v2;
++    if (cc & 2) {
++        res++;
++    }
++
++    return res;
++}
++
++/* subtract unsigned v2 from v1 with borrow */
++uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
++{
++    uint32_t v1 = env->regs[r1];
++    uint32_t res = v1 + (~v2) + (cc >> 1);
++
++    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res;
++    if (cc & 2) {
++        /* borrow */
++        return v1 ? 1 : 0;
++    } else {
++        return v1 ? 3 : 2;
++    }
++}
++
++/* subtract unsigned v2 from v1 with borrow */
++uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
++{
++    uint64_t res = v1 + (~v2) + (cc >> 1);
++
++    env->regs[r1] = res;
++    if (cc & 2) {
++        /* borrow */
++        return v1 ? 1 : 0;
++    } else {
++        return v1 ? 3 : 2;
++    }
++}
++
++/* find leftmost one */
++uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
++{
++    uint64_t res = 0;
++    uint64_t ov2 = v2;
++
++    while (!(v2 & 0x8000000000000000ULL) && v2) {
++        v2 <<= 1;
++        res++;
++    }
++
++    if (!v2) {
++        env->regs[r1] = 64;
++        env->regs[r1 + 1] = 0;
++        return 0;
++    } else {
++        env->regs[r1] = res;
++        env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
++        return 2;
++    }
++}
++
++uint64_t HELPER(cvd)(int32_t bin)
++{
++    /* positive 0 */
++    uint64_t dec = 0x0c;
++    int shift = 4;
++
++    if (bin < 0) {
++        bin = -bin;
++        dec = 0x0d;
++    }
++
++    for (shift = 4; (shift < 64) && bin; shift += 4) {
++        int current_number = bin % 10;
++
++        dec |= (current_number) << shift;
++        bin /= 10;
++    }
++
++    return dec;
++}
+diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
+index eced890..3b8b997 100644
+--- a/target-s390x/op_helper.c
++++ b/target-s390x/op_helper.c
+@@ -352,49 +352,6 @@ void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
+     HELPER_LOG("\n");
+ }
+ 
+-/* 64/64 -> 128 unsigned multiplication */
+-void HELPER(mlg)(uint32_t r1, uint64_t v2)
+-{
+-#if HOST_LONG_BITS == 64 && defined(__GNUC__)
+-    /* assuming 64-bit hosts have __uint128_t */
+-    __uint128_t res = (__uint128_t)env->regs[r1 + 1];
+-
+-    res *= (__uint128_t)v2;
+-    env->regs[r1] = (uint64_t)(res >> 64);
+-    env->regs[r1 + 1] = (uint64_t)res;
+-#else
+-    mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2);
+-#endif
+-}
+-
+-/* 128 -> 64/64 unsigned division */
+-void HELPER(dlg)(uint32_t r1, uint64_t v2)
+-{
+-    uint64_t divisor = v2;
+-
+-    if (!env->regs[r1]) {
+-        /* 64 -> 64/64 case */
+-        env->regs[r1] = env->regs[r1 + 1] % divisor;
+-        env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
+-        return;
+-    } else {
+-#if HOST_LONG_BITS == 64 && defined(__GNUC__)
+-        /* assuming 64-bit hosts have __uint128_t */
+-        __uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
+-            (env->regs[r1 + 1]);
+-        __uint128_t quotient = dividend / divisor;
+-        __uint128_t remainder = dividend % divisor;
+-
+-        env->regs[r1 + 1] = quotient;
+-        env->regs[r1] = remainder;
+-#else
+-        /* 32-bit hosts would need special wrapper functionality - just abort if
+-           we encounter such a case; it's very unlikely anyways. */
+-        cpu_abort(env, "128 -> 64/64 division not implemented\n");
+-#endif
+-    }
+-}
+-
+ static inline uint64_t get_address(int x2, int b2, int d2)
+ {
+     uint64_t r = d2;
+@@ -677,61 +634,6 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+     return cc;
+ }
+ 
+-/* absolute value 32-bit */
+-uint32_t HELPER(abs_i32)(int32_t val)
+-{
+-    if (val < 0) {
+-        return -val;
+-    } else {
+-        return val;
+-    }
+-}
+-
+-/* negative absolute value 32-bit */
+-int32_t HELPER(nabs_i32)(int32_t val)
+-{
+-    if (val < 0) {
+-        return val;
+-    } else {
+-        return -val;
+-    }
+-}
+-
+-/* absolute value 64-bit */
+-uint64_t HELPER(abs_i64)(int64_t val)
+-{
+-    HELPER_LOG("%s: val 0x%" PRIx64 "\n", __func__, val);
+-
+-    if (val < 0) {
+-        return -val;
+-    } else {
+-        return val;
+-    }
+-}
+-
+-/* negative absolute value 64-bit */
+-int64_t HELPER(nabs_i64)(int64_t val)
+-{
+-    if (val < 0) {
+-        return val;
+-    } else {
+-        return -val;
+-    }
+-}
+-
+-/* add with carry 32-bit unsigned */
+-uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
+-{
+-    uint32_t res;
+-
+-    res = v1 + v2;
+-    if (cc & 2) {
+-        res++;
+-    }
+-
+-    return res;
+-}
+-
+ /* store character under mask high operates on the upper half of r1 */
+ void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
+ {
+@@ -936,57 +838,6 @@ uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+     return cc;
+ }
+ 
+-/* subtract unsigned v2 from v1 with borrow */
+-uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
+-{
+-    uint32_t v1 = env->regs[r1];
+-    uint32_t res = v1 + (~v2) + (cc >> 1);
+-
+-    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res;
+-    if (cc & 2) {
+-        /* borrow */
+-        return v1 ? 1 : 0;
+-    } else {
+-        return v1 ? 3 : 2;
+-    }
+-}
+-
+-/* subtract unsigned v2 from v1 with borrow */
+-uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
+-{
+-    uint64_t res = v1 + (~v2) + (cc >> 1);
+-
+-    env->regs[r1] = res;
+-    if (cc & 2) {
+-        /* borrow */
+-        return v1 ? 1 : 0;
+-    } else {
+-        return v1 ? 3 : 2;
+-    }
+-}
+-
+-/* find leftmost one */
+-uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
+-{
+-    uint64_t res = 0;
+-    uint64_t ov2 = v2;
+-
+-    while (!(v2 & 0x8000000000000000ULL) && v2) {
+-        v2 <<= 1;
+-        res++;
+-    }
+-
+-    if (!v2) {
+-        env->regs[r1] = 64;
+-        env->regs[r1 + 1] = 0;
+-        return 0;
+-    } else {
+-        env->regs[r1] = res;
+-        env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
+-        return 2;
+-    }
+-}
+-
+ /* checksum */
+ void HELPER(cksm)(uint32_t r1, uint32_t r2)
+ {
+@@ -1026,27 +877,6 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
+         ((uint32_t)cksm + (cksm >> 32));
+ }
+ 
+-uint64_t HELPER(cvd)(int32_t bin)
+-{
+-    /* positive 0 */
+-    uint64_t dec = 0x0c;
+-    int shift = 4;
+-
+-    if (bin < 0) {
+-        bin = -bin;
+-        dec = 0x0d;
+-    }
+-
+-    for (shift = 4; (shift < 64) && bin; shift += 4) {
+-        int current_number = bin % 10;
+-
+-        dec |= (current_number) << shift;
+-        bin /= 10;
+-    }
+-
+-    return dec;
+-}
+-
+ void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
+ {
+     int len_dest = len >> 4;
+-- 
+1.7.12.1
+
diff --git a/0009-target-s390x-split-memory-access-helpers.patch b/0009-target-s390x-split-memory-access-helpers.patch
new file mode 100644
index 0000000..0e87180
--- /dev/null
+++ b/0009-target-s390x-split-memory-access-helpers.patch
@@ -0,0 +1,2424 @@
+From a44aee2570031bfcf99098d278c53ab39a582ba6 Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:34 +0000
+Subject: [PATCH] target-s390x: split memory access helpers
+
+Move memory access helpers to mem_helper.c.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+[agraf: fold softmmu include ifdefs together]
+Signed-off-by: Alexander Graf <agraf at suse.de>
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/Makefile.objs |    3 +-
+ target-s390x/mem_helper.c  | 1190 ++++++++++++++++++++++++++++++++++++++++++++
+ target-s390x/op_helper.c   | 1159 +-----------------------------------------
+ 3 files changed, 1193 insertions(+), 1159 deletions(-)
+ create mode 100644 target-s390x/mem_helper.c
+
+diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
+index e8f66e9..b9b3061 100644
+--- a/target-s390x/Makefile.objs
++++ b/target-s390x/Makefile.objs
+@@ -1,5 +1,5 @@
+ obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
+-obj-y += int_helper.o fpu_helper.o cc_helper.o
++obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-$(CONFIG_KVM) += kvm.o
+ 
+@@ -7,3 +7,4 @@ $(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
++$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
+new file mode 100644
+index 0000000..ba05e65
+--- /dev/null
++++ b/target-s390x/mem_helper.c
+@@ -0,0 +1,1190 @@
++/*
++ *  S/390 memory access helper routines
++ *
++ *  Copyright (c) 2009 Ulrich Hecht
++ *  Copyright (c) 2009 Alexander Graf
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "cpu.h"
++#include "dyngen-exec.h"
++#include "helper.h"
++
++/*****************************************************************************/
++/* Softmmu support */
++#if !defined(CONFIG_USER_ONLY)
++#include "softmmu_exec.h"
++
++#define MMUSUFFIX _mmu
++
++#define SHIFT 0
++#include "softmmu_template.h"
++
++#define SHIFT 1
++#include "softmmu_template.h"
++
++#define SHIFT 2
++#include "softmmu_template.h"
++
++#define SHIFT 3
++#include "softmmu_template.h"
++
++/* try to fill the TLB and return an exception if error. If retaddr is
++   NULL, it means that the function was called in C code (i.e. not
++   from generated code or from helper.c) */
++/* XXX: fix it to restore all registers */
++void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
++              uintptr_t retaddr)
++{
++    TranslationBlock *tb;
++    CPUS390XState *saved_env;
++    int ret;
++
++    saved_env = env;
++    env = env1;
++    ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
++    if (unlikely(ret != 0)) {
++        if (likely(retaddr)) {
++            /* now we have a real cpu fault */
++            tb = tb_find_pc(retaddr);
++            if (likely(tb)) {
++                /* the PC is inside the translated code. It means that we have
++                   a virtual CPU fault */
++                cpu_restore_state(tb, env, retaddr);
++            }
++        }
++        cpu_loop_exit(env);
++    }
++    env = saved_env;
++}
++
++#endif
++
++/* #define DEBUG_HELPER */
++#ifdef DEBUG_HELPER
++#define HELPER_LOG(x...) qemu_log(x)
++#else
++#define HELPER_LOG(x...)
++#endif
++
++#ifndef CONFIG_USER_ONLY
++static void mvc_fast_memset(CPUS390XState *env, uint32_t l, uint64_t dest,
++                            uint8_t byte)
++{
++    target_phys_addr_t dest_phys;
++    target_phys_addr_t len = l;
++    void *dest_p;
++    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
++    int flags;
++
++    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
++        stb(dest, byte);
++        cpu_abort(env, "should never reach here");
++    }
++    dest_phys |= dest & ~TARGET_PAGE_MASK;
++
++    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
++
++    memset(dest_p, byte, len);
++
++    cpu_physical_memory_unmap(dest_p, 1, len, len);
++}
++
++static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
++                             uint64_t src)
++{
++    target_phys_addr_t dest_phys;
++    target_phys_addr_t src_phys;
++    target_phys_addr_t len = l;
++    void *dest_p;
++    void *src_p;
++    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
++    int flags;
++
++    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
++        stb(dest, 0);
++        cpu_abort(env, "should never reach here");
++    }
++    dest_phys |= dest & ~TARGET_PAGE_MASK;
++
++    if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) {
++        ldub(src);
++        cpu_abort(env, "should never reach here");
++    }
++    src_phys |= src & ~TARGET_PAGE_MASK;
++
++    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
++    src_p = cpu_physical_memory_map(src_phys, &len, 0);
++
++    memmove(dest_p, src_p, len);
++
++    cpu_physical_memory_unmap(dest_p, 1, len, len);
++    cpu_physical_memory_unmap(src_p, 0, len, len);
++}
++#endif
++
++/* and on array */
++uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
++{
++    int i;
++    unsigned char x;
++    uint32_t cc = 0;
++
++    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
++               __func__, l, dest, src);
++    for (i = 0; i <= l; i++) {
++        x = ldub(dest + i) & ldub(src + i);
++        if (x) {
++            cc = 1;
++        }
++        stb(dest + i, x);
++    }
++    return cc;
++}
++
++/* xor on array */
++uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
++{
++    int i;
++    unsigned char x;
++    uint32_t cc = 0;
++
++    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
++               __func__, l, dest, src);
++
++#ifndef CONFIG_USER_ONLY
++    /* xor with itself is the same as memset(0) */
++    if ((l > 32) && (src == dest) &&
++        (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK)) {
++        mvc_fast_memset(env, l + 1, dest, 0);
++        return 0;
++    }
++#else
++    if (src == dest) {
++        memset(g2h(dest), 0, l + 1);
++        return 0;
++    }
++#endif
++
++    for (i = 0; i <= l; i++) {
++        x = ldub(dest + i) ^ ldub(src + i);
++        if (x) {
++            cc = 1;
++        }
++        stb(dest + i, x);
++    }
++    return cc;
++}
++
++/* or on array */
++uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
++{
++    int i;
++    unsigned char x;
++    uint32_t cc = 0;
++
++    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
++               __func__, l, dest, src);
++    for (i = 0; i <= l; i++) {
++        x = ldub(dest + i) | ldub(src + i);
++        if (x) {
++            cc = 1;
++        }
++        stb(dest + i, x);
++    }
++    return cc;
++}
++
++/* memmove */
++void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
++{
++    int i = 0;
++    int x = 0;
++    uint32_t l_64 = (l + 1) / 8;
++
++    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
++               __func__, l, dest, src);
++
++#ifndef CONFIG_USER_ONLY
++    if ((l > 32) &&
++        (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) &&
++        (dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) {
++        if (dest == (src + 1)) {
++            mvc_fast_memset(env, l + 1, dest, ldub(src));
++            return;
++        } else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
++            mvc_fast_memmove(env, l + 1, dest, src);
++            return;
++        }
++    }
++#else
++    if (dest == (src + 1)) {
++        memset(g2h(dest), ldub(src), l + 1);
++        return;
++    } else {
++        memmove(g2h(dest), g2h(src), l + 1);
++        return;
++    }
++#endif
++
++    /* handle the parts that fit into 8-byte loads/stores */
++    if (dest != (src + 1)) {
++        for (i = 0; i < l_64; i++) {
++            stq(dest + x, ldq(src + x));
++            x += 8;
++        }
++    }
++
++    /* slow version crossing pages with byte accesses */
++    for (i = x; i <= l; i++) {
++        stb(dest + i, ldub(src + i));
++    }
++}
++
++/* compare unsigned byte arrays */
++uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
++{
++    int i;
++    unsigned char x, y;
++    uint32_t cc;
++
++    HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
++               __func__, l, s1, s2);
++    for (i = 0; i <= l; i++) {
++        x = ldub(s1 + i);
++        y = ldub(s2 + i);
++        HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y);
++        if (x < y) {
++            cc = 1;
++            goto done;
++        } else if (x > y) {
++            cc = 2;
++            goto done;
++        }
++    }
++    cc = 0;
++ done:
++    HELPER_LOG("\n");
++    return cc;
++}
++
++/* compare logical under mask */
++uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
++{
++    uint8_t r, d;
++    uint32_t cc;
++
++    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1,
++               mask, addr);
++    cc = 0;
++    while (mask) {
++        if (mask & 8) {
++            d = ldub(addr);
++            r = (r1 & 0xff000000UL) >> 24;
++            HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
++                       addr);
++            if (r < d) {
++                cc = 1;
++                break;
++            } else if (r > d) {
++                cc = 2;
++                break;
++            }
++            addr++;
++        }
++        mask = (mask << 1) & 0xf;
++        r1 <<= 8;
++    }
++    HELPER_LOG("\n");
++    return cc;
++}
++
++/* store character under mask */
++void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
++{
++    uint8_t r;
++
++    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __func__, r1, mask,
++               addr);
++    while (mask) {
++        if (mask & 8) {
++            r = (r1 & 0xff000000UL) >> 24;
++            stb(addr, r);
++            HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
++            addr++;
++        }
++        mask = (mask << 1) & 0xf;
++        r1 <<= 8;
++    }
++    HELPER_LOG("\n");
++}
++
++static inline uint64_t get_address(int x2, int b2, int d2)
++{
++    uint64_t r = d2;
++
++    if (x2) {
++        r += env->regs[x2];
++    }
++
++    if (b2) {
++        r += env->regs[b2];
++    }
++
++    /* 31-Bit mode */
++    if (!(env->psw.mask & PSW_MASK_64)) {
++        r &= 0x7fffffff;
++    }
++
++    return r;
++}
++
++static inline uint64_t get_address_31fix(int reg)
++{
++    uint64_t r = env->regs[reg];
++
++    /* 31-Bit mode */
++    if (!(env->psw.mask & PSW_MASK_64)) {
++        r &= 0x7fffffff;
++    }
++
++    return r;
++}
++
++/* search string (c is byte to search, r2 is string, r1 end of string) */
++uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
++{
++    uint64_t i;
++    uint32_t cc = 2;
++    uint64_t str = get_address_31fix(r2);
++    uint64_t end = get_address_31fix(r1);
++
++    HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
++               c, env->regs[r1], env->regs[r2]);
++
++    for (i = str; i != end; i++) {
++        if (ldub(i) == c) {
++            env->regs[r1] = i;
++            cc = 1;
++            break;
++        }
++    }
++
++    return cc;
++}
++
++/* unsigned string compare (c is string terminator) */
++uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
++{
++    uint64_t s1 = get_address_31fix(r1);
++    uint64_t s2 = get_address_31fix(r2);
++    uint8_t v1, v2;
++    uint32_t cc;
++
++    c = c & 0xff;
++#ifdef CONFIG_USER_ONLY
++    if (!c) {
++        HELPER_LOG("%s: comparing '%s' and '%s'\n",
++                   __func__, (char *)g2h(s1), (char *)g2h(s2));
++    }
++#endif
++    for (;;) {
++        v1 = ldub(s1);
++        v2 = ldub(s2);
++        if ((v1 == c || v2 == c) || (v1 != v2)) {
++            break;
++        }
++        s1++;
++        s2++;
++    }
++
++    if (v1 == v2) {
++        cc = 0;
++    } else {
++        cc = (v1 < v2) ? 1 : 2;
++        /* FIXME: 31-bit mode! */
++        env->regs[r1] = s1;
++        env->regs[r2] = s2;
++    }
++    return cc;
++}
++
++/* move page */
++void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
++{
++    /* XXX missing r0 handling */
++#ifdef CONFIG_USER_ONLY
++    int i;
++
++    for (i = 0; i < TARGET_PAGE_SIZE; i++) {
++        stb(r1 + i, ldub(r2 + i));
++    }
++#else
++    mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2);
++#endif
++}
++
++/* string copy (c is string terminator) */
++void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
++{
++    uint64_t dest = get_address_31fix(r1);
++    uint64_t src = get_address_31fix(r2);
++    uint8_t v;
++
++    c = c & 0xff;
++#ifdef CONFIG_USER_ONLY
++    if (!c) {
++        HELPER_LOG("%s: copy '%s' to 0x%lx\n", __func__, (char *)g2h(src),
++                   dest);
++    }
++#endif
++    for (;;) {
++        v = ldub(src);
++        stb(dest, v);
++        if (v == c) {
++            break;
++        }
++        src++;
++        dest++;
++    }
++    env->regs[r1] = dest; /* FIXME: 31-bit mode! */
++}
++
++/* compare and swap 64-bit */
++uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    /* FIXME: locking? */
++    uint32_t cc;
++    uint64_t v2 = ldq(a2);
++
++    if (env->regs[r1] == v2) {
++        cc = 0;
++        stq(a2, env->regs[r3]);
++    } else {
++        cc = 1;
++        env->regs[r1] = v2;
++    }
++    return cc;
++}
++
++/* compare double and swap 64-bit */
++uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    /* FIXME: locking? */
++    uint32_t cc;
++    uint64_t v2_hi = ldq(a2);
++    uint64_t v2_lo = ldq(a2 + 8);
++    uint64_t v1_hi = env->regs[r1];
++    uint64_t v1_lo = env->regs[r1 + 1];
++
++    if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) {
++        cc = 0;
++        stq(a2, env->regs[r3]);
++        stq(a2 + 8, env->regs[r3 + 1]);
++    } else {
++        cc = 1;
++        env->regs[r1] = v2_hi;
++        env->regs[r1 + 1] = v2_lo;
++    }
++
++    return cc;
++}
++
++/* compare and swap 32-bit */
++uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    /* FIXME: locking? */
++    uint32_t cc;
++    uint32_t v2 = ldl(a2);
++
++    HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
++    if (((uint32_t)env->regs[r1]) == v2) {
++        cc = 0;
++        stl(a2, (uint32_t)env->regs[r3]);
++    } else {
++        cc = 1;
++        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2;
++    }
++    return cc;
++}
++
++static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
++{
++    int pos = 24; /* top of the lower half of r1 */
++    uint64_t rmask = 0xff000000ULL;
++    uint8_t val = 0;
++    int ccd = 0;
++    uint32_t cc = 0;
++
++    while (mask) {
++        if (mask & 8) {
++            env->regs[r1] &= ~rmask;
++            val = ldub(address);
++            if ((val & 0x80) && !ccd) {
++                cc = 1;
++            }
++            ccd = 1;
++            if (val && cc == 0) {
++                cc = 2;
++            }
++            env->regs[r1] |= (uint64_t)val << pos;
++            address++;
++        }
++        mask = (mask << 1) & 0xf;
++        pos -= 8;
++        rmask >>= 8;
++    }
++
++    return cc;
++}
++
++/* execute instruction
++   this instruction executes an insn modified with the contents of r1
++   it does not change the executed instruction in memory
++   it does not change the program counter
++   in other words: tricky...
++   currently implemented by interpreting the cases it is most commonly used in
++*/
++uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
++{
++    uint16_t insn = lduw_code(addr);
++
++    HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
++               insn);
++    if ((insn & 0xf0ff) == 0xd000) {
++        uint32_t l, insn2, b1, b2, d1, d2;
++
++        l = v1 & 0xff;
++        insn2 = ldl_code(addr + 2);
++        b1 = (insn2 >> 28) & 0xf;
++        b2 = (insn2 >> 12) & 0xf;
++        d1 = (insn2 >> 16) & 0xfff;
++        d2 = insn2 & 0xfff;
++        switch (insn & 0xf00) {
++        case 0x200:
++            helper_mvc(l, get_address(0, b1, d1), get_address(0, b2, d2));
++            break;
++        case 0x500:
++            cc = helper_clc(l, get_address(0, b1, d1), get_address(0, b2, d2));
++            break;
++        case 0x700:
++            cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
++            break;
++        case 0xc00:
++            helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2));
++            break;
++        default:
++            goto abort;
++            break;
++        }
++    } else if ((insn & 0xff00) == 0x0a00) {
++        /* supervisor call */
++        HELPER_LOG("%s: svc %ld via execute\n", __func__, (insn | v1) & 0xff);
++        env->psw.addr = ret - 4;
++        env->int_svc_code = (insn | v1) & 0xff;
++        env->int_svc_ilc = 4;
++        helper_exception(EXCP_SVC);
++    } else if ((insn & 0xff00) == 0xbf00) {
++        uint32_t insn2, r1, r3, b2, d2;
++
++        insn2 = ldl_code(addr + 2);
++        r1 = (insn2 >> 20) & 0xf;
++        r3 = (insn2 >> 16) & 0xf;
++        b2 = (insn2 >> 12) & 0xf;
++        d2 = insn2 & 0xfff;
++        cc = helper_icm(r1, get_address(0, b2, d2), r3);
++    } else {
++    abort:
++        cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
++                  insn);
++    }
++    return cc;
++}
++
++/* store character under mask high operates on the upper half of r1 */
++void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
++{
++    int pos = 56; /* top of the upper half of r1 */
++
++    while (mask) {
++        if (mask & 8) {
++            stb(address, (env->regs[r1] >> pos) & 0xff);
++            address++;
++        }
++        mask = (mask << 1) & 0xf;
++        pos -= 8;
++    }
++}
++
++/* insert character under mask high; same as icm, but operates on the
++   upper half of r1 */
++uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
++{
++    int pos = 56; /* top of the upper half of r1 */
++    uint64_t rmask = 0xff00000000000000ULL;
++    uint8_t val = 0;
++    int ccd = 0;
++    uint32_t cc = 0;
++
++    while (mask) {
++        if (mask & 8) {
++            env->regs[r1] &= ~rmask;
++            val = ldub(address);
++            if ((val & 0x80) && !ccd) {
++                cc = 1;
++            }
++            ccd = 1;
++            if (val && cc == 0) {
++                cc = 2;
++            }
++            env->regs[r1] |= (uint64_t)val << pos;
++            address++;
++        }
++        mask = (mask << 1) & 0xf;
++        pos -= 8;
++        rmask >>= 8;
++    }
++
++    return cc;
++}
++
++/* load access registers r1 to r3 from memory at a2 */
++void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    int i;
++
++    for (i = r1;; i = (i + 1) % 16) {
++        env->aregs[i] = ldl(a2);
++        a2 += 4;
++
++        if (i == r3) {
++            break;
++        }
++    }
++}
++
++/* store access registers r1 to r3 in memory at a2 */
++void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    int i;
++
++    for (i = r1;; i = (i + 1) % 16) {
++        stl(a2, env->aregs[i]);
++        a2 += 4;
++
++        if (i == r3) {
++            break;
++        }
++    }
++}
++
++/* move long */
++uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
++{
++    uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
++    uint64_t dest = get_address_31fix(r1);
++    uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
++    uint64_t src = get_address_31fix(r2);
++    uint8_t pad = src >> 24;
++    uint8_t v;
++    uint32_t cc;
++
++    if (destlen == srclen) {
++        cc = 0;
++    } else if (destlen < srclen) {
++        cc = 1;
++    } else {
++        cc = 2;
++    }
++
++    if (srclen > destlen) {
++        srclen = destlen;
++    }
++
++    for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
++        v = ldub(src);
++        stb(dest, v);
++    }
++
++    for (; destlen; dest++, destlen--) {
++        stb(dest, pad);
++    }
++
++    env->regs[r1 + 1] = destlen;
++    /* can't use srclen here, we trunc'ed it */
++    env->regs[r2 + 1] -= src - env->regs[r2];
++    env->regs[r1] = dest;
++    env->regs[r2] = src;
++
++    return cc;
++}
++
++/* move long extended another memcopy insn with more bells and whistles */
++uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    uint64_t destlen = env->regs[r1 + 1];
++    uint64_t dest = env->regs[r1];
++    uint64_t srclen = env->regs[r3 + 1];
++    uint64_t src = env->regs[r3];
++    uint8_t pad = a2 & 0xff;
++    uint8_t v;
++    uint32_t cc;
++
++    if (!(env->psw.mask & PSW_MASK_64)) {
++        destlen = (uint32_t)destlen;
++        srclen = (uint32_t)srclen;
++        dest &= 0x7fffffff;
++        src &= 0x7fffffff;
++    }
++
++    if (destlen == srclen) {
++        cc = 0;
++    } else if (destlen < srclen) {
++        cc = 1;
++    } else {
++        cc = 2;
++    }
++
++    if (srclen > destlen) {
++        srclen = destlen;
++    }
++
++    for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
++        v = ldub(src);
++        stb(dest, v);
++    }
++
++    for (; destlen; dest++, destlen--) {
++        stb(dest, pad);
++    }
++
++    env->regs[r1 + 1] = destlen;
++    /* can't use srclen here, we trunc'ed it */
++    /* FIXME: 31-bit mode! */
++    env->regs[r3 + 1] -= src - env->regs[r3];
++    env->regs[r1] = dest;
++    env->regs[r3] = src;
++
++    return cc;
++}
++
++/* compare logical long extended memcompare insn with padding */
++uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    uint64_t destlen = env->regs[r1 + 1];
++    uint64_t dest = get_address_31fix(r1);
++    uint64_t srclen = env->regs[r3 + 1];
++    uint64_t src = get_address_31fix(r3);
++    uint8_t pad = a2 & 0xff;
++    uint8_t v1 = 0, v2 = 0;
++    uint32_t cc = 0;
++
++    if (!(destlen || srclen)) {
++        return cc;
++    }
++
++    if (srclen > destlen) {
++        srclen = destlen;
++    }
++
++    for (; destlen || srclen; src++, dest++, destlen--, srclen--) {
++        v1 = srclen ? ldub(src) : pad;
++        v2 = destlen ? ldub(dest) : pad;
++        if (v1 != v2) {
++            cc = (v1 < v2) ? 1 : 2;
++            break;
++        }
++    }
++
++    env->regs[r1 + 1] = destlen;
++    /* can't use srclen here, we trunc'ed it */
++    env->regs[r3 + 1] -= src - env->regs[r3];
++    env->regs[r1] = dest;
++    env->regs[r3] = src;
++
++    return cc;
++}
++
++/* checksum */
++void HELPER(cksm)(uint32_t r1, uint32_t r2)
++{
++    uint64_t src = get_address_31fix(r2);
++    uint64_t src_len = env->regs[(r2 + 1) & 15];
++    uint64_t cksm = (uint32_t)env->regs[r1];
++
++    while (src_len >= 4) {
++        cksm += ldl(src);
++
++        /* move to next word */
++        src_len -= 4;
++        src += 4;
++    }
++
++    switch (src_len) {
++    case 0:
++        break;
++    case 1:
++        cksm += ldub(src) << 24;
++        break;
++    case 2:
++        cksm += lduw(src) << 16;
++        break;
++    case 3:
++        cksm += lduw(src) << 16;
++        cksm += ldub(src + 2) << 8;
++        break;
++    }
++
++    /* indicate we've processed everything */
++    env->regs[r2] = src + src_len;
++    env->regs[(r2 + 1) & 15] = 0;
++
++    /* store result */
++    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
++        ((uint32_t)cksm + (cksm >> 32));
++}
++
++void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
++{
++    int len_dest = len >> 4;
++    int len_src = len & 0xf;
++    uint8_t b;
++    int second_nibble = 0;
++
++    dest += len_dest;
++    src += len_src;
++
++    /* last byte is special, it only flips the nibbles */
++    b = ldub(src);
++    stb(dest, (b << 4) | (b >> 4));
++    src--;
++    len_src--;
++
++    /* now pad every nibble with 0xf0 */
++
++    while (len_dest > 0) {
++        uint8_t cur_byte = 0;
++
++        if (len_src > 0) {
++            cur_byte = ldub(src);
++        }
++
++        len_dest--;
++        dest--;
++
++        /* only advance one nibble at a time */
++        if (second_nibble) {
++            cur_byte >>= 4;
++            len_src--;
++            src--;
++        }
++        second_nibble = !second_nibble;
++
++        /* digit */
++        cur_byte = (cur_byte & 0xf);
++        /* zone bits */
++        cur_byte |= 0xf0;
++
++        stb(dest, cur_byte);
++    }
++}
++
++void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
++{
++    int i;
++
++    for (i = 0; i <= len; i++) {
++        uint8_t byte = ldub(array + i);
++        uint8_t new_byte = ldub(trans + byte);
++
++        stb(array + i, new_byte);
++    }
++}
++
++#if !defined(CONFIG_USER_ONLY)
++void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    int i;
++    uint64_t src = a2;
++
++    for (i = r1;; i = (i + 1) % 16) {
++        env->cregs[i] = ldq(src);
++        HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
++                   i, src, env->cregs[i]);
++        src += sizeof(uint64_t);
++
++        if (i == r3) {
++            break;
++        }
++    }
++
++    tlb_flush(env, 1);
++}
++
++void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    int i;
++    uint64_t src = a2;
++
++    for (i = r1;; i = (i + 1) % 16) {
++        env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) | ldl(src);
++        src += sizeof(uint32_t);
++
++        if (i == r3) {
++            break;
++        }
++    }
++
++    tlb_flush(env, 1);
++}
++
++void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    int i;
++    uint64_t dest = a2;
++
++    for (i = r1;; i = (i + 1) % 16) {
++        stq(dest, env->cregs[i]);
++        dest += sizeof(uint64_t);
++
++        if (i == r3) {
++            break;
++        }
++    }
++}
++
++void HELPER(stctl)(uint32_t r1, uint64_t a2, uint32_t r3)
++{
++    int i;
++    uint64_t dest = a2;
++
++    for (i = r1;; i = (i + 1) % 16) {
++        stl(dest, env->cregs[i]);
++        dest += sizeof(uint32_t);
++
++        if (i == r3) {
++            break;
++        }
++    }
++}
++
++uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2)
++{
++    /* XXX implement */
++
++    return 0;
++}
++
++/* insert storage key extended */
++uint64_t HELPER(iske)(uint64_t r2)
++{
++    uint64_t addr = get_address(0, 0, r2);
++
++    if (addr > ram_size) {
++        return 0;
++    }
++
++    return env->storage_keys[addr / TARGET_PAGE_SIZE];
++}
++
++/* set storage key extended */
++void HELPER(sske)(uint32_t r1, uint64_t r2)
++{
++    uint64_t addr = get_address(0, 0, r2);
++
++    if (addr > ram_size) {
++        return;
++    }
++
++    env->storage_keys[addr / TARGET_PAGE_SIZE] = r1;
++}
++
++/* reset reference bit extended */
++uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
++{
++    uint8_t re;
++    uint8_t key;
++
++    if (r2 > ram_size) {
++        return 0;
++    }
++
++    key = env->storage_keys[r2 / TARGET_PAGE_SIZE];
++    re = key & (SK_R | SK_C);
++    env->storage_keys[r2 / TARGET_PAGE_SIZE] = (key & ~SK_R);
++
++    /*
++     * cc
++     *
++     * 0  Reference bit zero; change bit zero
++     * 1  Reference bit zero; change bit one
++     * 2  Reference bit one; change bit zero
++     * 3  Reference bit one; change bit one
++     */
++
++    return re >> 1;
++}
++
++/* compare and swap and purge */
++uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
++{
++    uint32_t cc;
++    uint32_t o1 = env->regs[r1];
++    uint64_t a2 = get_address_31fix(r2) & ~3ULL;
++    uint32_t o2 = ldl(a2);
++
++    if (o1 == o2) {
++        stl(a2, env->regs[(r1 + 1) & 15]);
++        if (env->regs[r2] & 0x3) {
++            /* flush TLB / ALB */
++            tlb_flush(env, 1);
++        }
++        cc = 0;
++    } else {
++        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | o2;
++        cc = 1;
++    }
++
++    return cc;
++}
++
++static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
++                        uint64_t mode2)
++{
++    target_ulong src, dest;
++    int flags, cc = 0, i;
++
++    if (!l) {
++        return 0;
++    } else if (l > 256) {
++        /* max 256 */
++        l = 256;
++        cc = 3;
++    }
++
++    if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) {
++        cpu_loop_exit(env);
++    }
++    dest |= a1 & ~TARGET_PAGE_MASK;
++
++    if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) {
++        cpu_loop_exit(env);
++    }
++    src |= a2 & ~TARGET_PAGE_MASK;
++
++    /* XXX replace w/ memcpy */
++    for (i = 0; i < l; i++) {
++        /* XXX be more clever */
++        if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) ||
++            (((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) {
++            mvc_asc(l - i, a1 + i, mode1, a2 + i, mode2);
++            break;
++        }
++        stb_phys(dest + i, ldub_phys(src + i));
++    }
++
++    return cc;
++}
++
++uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
++{
++    HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
++               __func__, l, a1, a2);
++
++    return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
++}
++
++uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
++{
++    HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
++               __func__, l, a1, a2);
++
++    return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
++}
++
++/* invalidate pte */
++void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
++{
++    uint64_t page = vaddr & TARGET_PAGE_MASK;
++    uint64_t pte = 0;
++
++    /* XXX broadcast to other CPUs */
++
++    /* XXX Linux is nice enough to give us the exact pte address.
++       According to spec we'd have to find it out ourselves */
++    /* XXX Linux is fine with overwriting the pte, the spec requires
++       us to only set the invalid bit */
++    stq_phys(pte_addr, pte | _PAGE_INVALID);
++
++    /* XXX we exploit the fact that Linux passes the exact virtual
++       address here - it's not obliged to! */
++    tlb_flush_page(env, page);
++
++    /* XXX 31-bit hack */
++    if (page & 0x80000000) {
++        tlb_flush_page(env, page & ~0x80000000);
++    } else {
++        tlb_flush_page(env, page | 0x80000000);
++    }
++}
++
++/* flush local tlb */
++void HELPER(ptlb)(void)
++{
++    tlb_flush(env, 1);
++}
++
++/* store using real address */
++void HELPER(stura)(uint64_t addr, uint32_t v1)
++{
++    stw_phys(get_address(0, 0, addr), v1);
++}
++
++/* load real address */
++uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
++{
++    uint32_t cc = 0;
++    int old_exc = env->exception_index;
++    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
++    uint64_t ret;
++    int flags;
++
++    /* XXX incomplete - has more corner cases */
++    if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
++        program_interrupt(env, PGM_SPECIAL_OP, 2);
++    }
++
++    env->exception_index = old_exc;
++    if (mmu_translate(env, addr, 0, asc, &ret, &flags)) {
++        cc = 3;
++    }
++    if (env->exception_index == EXCP_PGM) {
++        ret = env->int_pgm_code | 0x80000000;
++    } else {
++        ret |= addr & ~TARGET_PAGE_MASK;
++    }
++    env->exception_index = old_exc;
++
++    if (!(env->psw.mask & PSW_MASK_64)) {
++        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
++            (ret & 0xffffffffULL);
++    } else {
++        env->regs[r1] = ret;
++    }
++
++    return cc;
++}
++
++#endif
+diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
+index 3b8b997..bb8dbf5 100644
+--- a/target-s390x/op_helper.c
++++ b/target-s390x/op_helper.c
+@@ -32,57 +32,8 @@
+ #endif
+ 
+ #if !defined(CONFIG_USER_ONLY)
+-#include "sysemu.h"
+-#endif
+-
+-/*****************************************************************************/
+-/* Softmmu support */
+-#if !defined(CONFIG_USER_ONLY)
+ #include "softmmu_exec.h"
+-
+-#define MMUSUFFIX _mmu
+-
+-#define SHIFT 0
+-#include "softmmu_template.h"
+-
+-#define SHIFT 1
+-#include "softmmu_template.h"
+-
+-#define SHIFT 2
+-#include "softmmu_template.h"
+-
+-#define SHIFT 3
+-#include "softmmu_template.h"
+-
+-/* try to fill the TLB and return an exception if error. If retaddr is
+-   NULL, it means that the function was called in C code (i.e. not
+-   from generated code or from helper.c) */
+-/* XXX: fix it to restore all registers */
+-void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
+-              uintptr_t retaddr)
+-{
+-    TranslationBlock *tb;
+-    CPUS390XState *saved_env;
+-    int ret;
+-
+-    saved_env = env;
+-    env = env1;
+-    ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
+-    if (unlikely(ret != 0)) {
+-        if (likely(retaddr)) {
+-            /* now we have a real cpu fault */
+-            tb = tb_find_pc(retaddr);
+-            if (likely(tb)) {
+-                /* the PC is inside the translated code. It means that we have
+-                   a virtual CPU fault */
+-                cpu_restore_state(tb, env, retaddr);
+-            }
+-        }
+-        cpu_loop_exit(env);
+-    }
+-    env = saved_env;
+-}
+-
++#include "sysemu.h"
+ #endif
+ 
+ /* #define DEBUG_HELPER */
+@@ -101,840 +52,6 @@ void HELPER(exception)(uint32_t excp)
+ }
+ 
+ #ifndef CONFIG_USER_ONLY
+-static void mvc_fast_memset(CPUS390XState *env, uint32_t l, uint64_t dest,
+-                            uint8_t byte)
+-{
+-    target_phys_addr_t dest_phys;
+-    target_phys_addr_t len = l;
+-    void *dest_p;
+-    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
+-    int flags;
+-
+-    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
+-        stb(dest, byte);
+-        cpu_abort(env, "should never reach here");
+-    }
+-    dest_phys |= dest & ~TARGET_PAGE_MASK;
+-
+-    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
+-
+-    memset(dest_p, byte, len);
+-
+-    cpu_physical_memory_unmap(dest_p, 1, len, len);
+-}
+-
+-static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
+-                             uint64_t src)
+-{
+-    target_phys_addr_t dest_phys;
+-    target_phys_addr_t src_phys;
+-    target_phys_addr_t len = l;
+-    void *dest_p;
+-    void *src_p;
+-    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
+-    int flags;
+-
+-    if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
+-        stb(dest, 0);
+-        cpu_abort(env, "should never reach here");
+-    }
+-    dest_phys |= dest & ~TARGET_PAGE_MASK;
+-
+-    if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) {
+-        ldub(src);
+-        cpu_abort(env, "should never reach here");
+-    }
+-    src_phys |= src & ~TARGET_PAGE_MASK;
+-
+-    dest_p = cpu_physical_memory_map(dest_phys, &len, 1);
+-    src_p = cpu_physical_memory_map(src_phys, &len, 0);
+-
+-    memmove(dest_p, src_p, len);
+-
+-    cpu_physical_memory_unmap(dest_p, 1, len, len);
+-    cpu_physical_memory_unmap(src_p, 0, len, len);
+-}
+-#endif
+-
+-/* and on array */
+-uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
+-{
+-    int i;
+-    unsigned char x;
+-    uint32_t cc = 0;
+-
+-    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+-               __func__, l, dest, src);
+-    for (i = 0; i <= l; i++) {
+-        x = ldub(dest + i) & ldub(src + i);
+-        if (x) {
+-            cc = 1;
+-        }
+-        stb(dest + i, x);
+-    }
+-    return cc;
+-}
+-
+-/* xor on array */
+-uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
+-{
+-    int i;
+-    unsigned char x;
+-    uint32_t cc = 0;
+-
+-    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+-               __func__, l, dest, src);
+-
+-#ifndef CONFIG_USER_ONLY
+-    /* xor with itself is the same as memset(0) */
+-    if ((l > 32) && (src == dest) &&
+-        (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK)) {
+-        mvc_fast_memset(env, l + 1, dest, 0);
+-        return 0;
+-    }
+-#else
+-    if (src == dest) {
+-        memset(g2h(dest), 0, l + 1);
+-        return 0;
+-    }
+-#endif
+-
+-    for (i = 0; i <= l; i++) {
+-        x = ldub(dest + i) ^ ldub(src + i);
+-        if (x) {
+-            cc = 1;
+-        }
+-        stb(dest + i, x);
+-    }
+-    return cc;
+-}
+-
+-/* or on array */
+-uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
+-{
+-    int i;
+-    unsigned char x;
+-    uint32_t cc = 0;
+-
+-    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+-               __func__, l, dest, src);
+-    for (i = 0; i <= l; i++) {
+-        x = ldub(dest + i) | ldub(src + i);
+-        if (x) {
+-            cc = 1;
+-        }
+-        stb(dest + i, x);
+-    }
+-    return cc;
+-}
+-
+-/* memmove */
+-void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
+-{
+-    int i = 0;
+-    int x = 0;
+-    uint32_t l_64 = (l + 1) / 8;
+-
+-    HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+-               __func__, l, dest, src);
+-
+-#ifndef CONFIG_USER_ONLY
+-    if ((l > 32) &&
+-        (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) &&
+-        (dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) {
+-        if (dest == (src + 1)) {
+-            mvc_fast_memset(env, l + 1, dest, ldub(src));
+-            return;
+-        } else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
+-            mvc_fast_memmove(env, l + 1, dest, src);
+-            return;
+-        }
+-    }
+-#else
+-    if (dest == (src + 1)) {
+-        memset(g2h(dest), ldub(src), l + 1);
+-        return;
+-    } else {
+-        memmove(g2h(dest), g2h(src), l + 1);
+-        return;
+-    }
+-#endif
+-
+-    /* handle the parts that fit into 8-byte loads/stores */
+-    if (dest != (src + 1)) {
+-        for (i = 0; i < l_64; i++) {
+-            stq(dest + x, ldq(src + x));
+-            x += 8;
+-        }
+-    }
+-
+-    /* slow version crossing pages with byte accesses */
+-    for (i = x; i <= l; i++) {
+-        stb(dest + i, ldub(src + i));
+-    }
+-}
+-
+-/* compare unsigned byte arrays */
+-uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
+-{
+-    int i;
+-    unsigned char x, y;
+-    uint32_t cc;
+-
+-    HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
+-               __func__, l, s1, s2);
+-    for (i = 0; i <= l; i++) {
+-        x = ldub(s1 + i);
+-        y = ldub(s2 + i);
+-        HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y);
+-        if (x < y) {
+-            cc = 1;
+-            goto done;
+-        } else if (x > y) {
+-            cc = 2;
+-            goto done;
+-        }
+-    }
+-    cc = 0;
+- done:
+-    HELPER_LOG("\n");
+-    return cc;
+-}
+-
+-/* compare logical under mask */
+-uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
+-{
+-    uint8_t r, d;
+-    uint32_t cc;
+-
+-    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%" PRIx64 "\n", __func__, r1,
+-               mask, addr);
+-    cc = 0;
+-    while (mask) {
+-        if (mask & 8) {
+-            d = ldub(addr);
+-            r = (r1 & 0xff000000UL) >> 24;
+-            HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
+-                       addr);
+-            if (r < d) {
+-                cc = 1;
+-                break;
+-            } else if (r > d) {
+-                cc = 2;
+-                break;
+-            }
+-            addr++;
+-        }
+-        mask = (mask << 1) & 0xf;
+-        r1 <<= 8;
+-    }
+-    HELPER_LOG("\n");
+-    return cc;
+-}
+-
+-/* store character under mask */
+-void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
+-{
+-    uint8_t r;
+-
+-    HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __func__, r1, mask,
+-               addr);
+-    while (mask) {
+-        if (mask & 8) {
+-            r = (r1 & 0xff000000UL) >> 24;
+-            stb(addr, r);
+-            HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
+-            addr++;
+-        }
+-        mask = (mask << 1) & 0xf;
+-        r1 <<= 8;
+-    }
+-    HELPER_LOG("\n");
+-}
+-
+-static inline uint64_t get_address(int x2, int b2, int d2)
+-{
+-    uint64_t r = d2;
+-
+-    if (x2) {
+-        r += env->regs[x2];
+-    }
+-
+-    if (b2) {
+-        r += env->regs[b2];
+-    }
+-
+-    /* 31-Bit mode */
+-    if (!(env->psw.mask & PSW_MASK_64)) {
+-        r &= 0x7fffffff;
+-    }
+-
+-    return r;
+-}
+-
+-static inline uint64_t get_address_31fix(int reg)
+-{
+-    uint64_t r = env->regs[reg];
+-
+-    /* 31-Bit mode */
+-    if (!(env->psw.mask & PSW_MASK_64)) {
+-        r &= 0x7fffffff;
+-    }
+-
+-    return r;
+-}
+-
+-/* search string (c is byte to search, r2 is string, r1 end of string) */
+-uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
+-{
+-    uint64_t i;
+-    uint32_t cc = 2;
+-    uint64_t str = get_address_31fix(r2);
+-    uint64_t end = get_address_31fix(r1);
+-
+-    HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
+-               c, env->regs[r1], env->regs[r2]);
+-
+-    for (i = str; i != end; i++) {
+-        if (ldub(i) == c) {
+-            env->regs[r1] = i;
+-            cc = 1;
+-            break;
+-        }
+-    }
+-
+-    return cc;
+-}
+-
+-/* unsigned string compare (c is string terminator) */
+-uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
+-{
+-    uint64_t s1 = get_address_31fix(r1);
+-    uint64_t s2 = get_address_31fix(r2);
+-    uint8_t v1, v2;
+-    uint32_t cc;
+-
+-    c = c & 0xff;
+-#ifdef CONFIG_USER_ONLY
+-    if (!c) {
+-        HELPER_LOG("%s: comparing '%s' and '%s'\n",
+-                   __func__, (char *)g2h(s1), (char *)g2h(s2));
+-    }
+-#endif
+-    for (;;) {
+-        v1 = ldub(s1);
+-        v2 = ldub(s2);
+-        if ((v1 == c || v2 == c) || (v1 != v2)) {
+-            break;
+-        }
+-        s1++;
+-        s2++;
+-    }
+-
+-    if (v1 == v2) {
+-        cc = 0;
+-    } else {
+-        cc = (v1 < v2) ? 1 : 2;
+-        /* FIXME: 31-bit mode! */
+-        env->regs[r1] = s1;
+-        env->regs[r2] = s2;
+-    }
+-    return cc;
+-}
+-
+-/* move page */
+-void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
+-{
+-    /* XXX missing r0 handling */
+-#ifdef CONFIG_USER_ONLY
+-    int i;
+-
+-    for (i = 0; i < TARGET_PAGE_SIZE; i++) {
+-        stb(r1 + i, ldub(r2 + i));
+-    }
+-#else
+-    mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2);
+-#endif
+-}
+-
+-/* string copy (c is string terminator) */
+-void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
+-{
+-    uint64_t dest = get_address_31fix(r1);
+-    uint64_t src = get_address_31fix(r2);
+-    uint8_t v;
+-
+-    c = c & 0xff;
+-#ifdef CONFIG_USER_ONLY
+-    if (!c) {
+-        HELPER_LOG("%s: copy '%s' to 0x%lx\n", __func__, (char *)g2h(src),
+-                   dest);
+-    }
+-#endif
+-    for (;;) {
+-        v = ldub(src);
+-        stb(dest, v);
+-        if (v == c) {
+-            break;
+-        }
+-        src++;
+-        dest++;
+-    }
+-    env->regs[r1] = dest; /* FIXME: 31-bit mode! */
+-}
+-
+-/* compare and swap 64-bit */
+-uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    /* FIXME: locking? */
+-    uint32_t cc;
+-    uint64_t v2 = ldq(a2);
+-
+-    if (env->regs[r1] == v2) {
+-        cc = 0;
+-        stq(a2, env->regs[r3]);
+-    } else {
+-        cc = 1;
+-        env->regs[r1] = v2;
+-    }
+-    return cc;
+-}
+-
+-/* compare double and swap 64-bit */
+-uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    /* FIXME: locking? */
+-    uint32_t cc;
+-    uint64_t v2_hi = ldq(a2);
+-    uint64_t v2_lo = ldq(a2 + 8);
+-    uint64_t v1_hi = env->regs[r1];
+-    uint64_t v1_lo = env->regs[r1 + 1];
+-
+-    if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) {
+-        cc = 0;
+-        stq(a2, env->regs[r3]);
+-        stq(a2 + 8, env->regs[r3 + 1]);
+-    } else {
+-        cc = 1;
+-        env->regs[r1] = v2_hi;
+-        env->regs[r1 + 1] = v2_lo;
+-    }
+-
+-    return cc;
+-}
+-
+-/* compare and swap 32-bit */
+-uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    /* FIXME: locking? */
+-    uint32_t cc;
+-    uint32_t v2 = ldl(a2);
+-
+-    HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
+-    if (((uint32_t)env->regs[r1]) == v2) {
+-        cc = 0;
+-        stl(a2, (uint32_t)env->regs[r3]);
+-    } else {
+-        cc = 1;
+-        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2;
+-    }
+-    return cc;
+-}
+-
+-static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
+-{
+-    int pos = 24; /* top of the lower half of r1 */
+-    uint64_t rmask = 0xff000000ULL;
+-    uint8_t val = 0;
+-    int ccd = 0;
+-    uint32_t cc = 0;
+-
+-    while (mask) {
+-        if (mask & 8) {
+-            env->regs[r1] &= ~rmask;
+-            val = ldub(address);
+-            if ((val & 0x80) && !ccd) {
+-                cc = 1;
+-            }
+-            ccd = 1;
+-            if (val && cc == 0) {
+-                cc = 2;
+-            }
+-            env->regs[r1] |= (uint64_t)val << pos;
+-            address++;
+-        }
+-        mask = (mask << 1) & 0xf;
+-        pos -= 8;
+-        rmask >>= 8;
+-    }
+-
+-    return cc;
+-}
+-
+-/* execute instruction
+-   this instruction executes an insn modified with the contents of r1
+-   it does not change the executed instruction in memory
+-   it does not change the program counter
+-   in other words: tricky...
+-   currently implemented by interpreting the cases it is most commonly used in
+-*/
+-uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+-{
+-    uint16_t insn = lduw_code(addr);
+-
+-    HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
+-               insn);
+-    if ((insn & 0xf0ff) == 0xd000) {
+-        uint32_t l, insn2, b1, b2, d1, d2;
+-
+-        l = v1 & 0xff;
+-        insn2 = ldl_code(addr + 2);
+-        b1 = (insn2 >> 28) & 0xf;
+-        b2 = (insn2 >> 12) & 0xf;
+-        d1 = (insn2 >> 16) & 0xfff;
+-        d2 = insn2 & 0xfff;
+-        switch (insn & 0xf00) {
+-        case 0x200:
+-            helper_mvc(l, get_address(0, b1, d1), get_address(0, b2, d2));
+-            break;
+-        case 0x500:
+-            cc = helper_clc(l, get_address(0, b1, d1), get_address(0, b2, d2));
+-            break;
+-        case 0x700:
+-            cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
+-            break;
+-        case 0xc00:
+-            helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2));
+-            break;
+-        default:
+-            goto abort;
+-            break;
+-        }
+-    } else if ((insn & 0xff00) == 0x0a00) {
+-        /* supervisor call */
+-        HELPER_LOG("%s: svc %ld via execute\n", __func__, (insn | v1) & 0xff);
+-        env->psw.addr = ret - 4;
+-        env->int_svc_code = (insn | v1) & 0xff;
+-        env->int_svc_ilc = 4;
+-        helper_exception(EXCP_SVC);
+-    } else if ((insn & 0xff00) == 0xbf00) {
+-        uint32_t insn2, r1, r3, b2, d2;
+-
+-        insn2 = ldl_code(addr + 2);
+-        r1 = (insn2 >> 20) & 0xf;
+-        r3 = (insn2 >> 16) & 0xf;
+-        b2 = (insn2 >> 12) & 0xf;
+-        d2 = insn2 & 0xfff;
+-        cc = helper_icm(r1, get_address(0, b2, d2), r3);
+-    } else {
+-    abort:
+-        cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
+-                  insn);
+-    }
+-    return cc;
+-}
+-
+-/* store character under mask high operates on the upper half of r1 */
+-void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
+-{
+-    int pos = 56; /* top of the upper half of r1 */
+-
+-    while (mask) {
+-        if (mask & 8) {
+-            stb(address, (env->regs[r1] >> pos) & 0xff);
+-            address++;
+-        }
+-        mask = (mask << 1) & 0xf;
+-        pos -= 8;
+-    }
+-}
+-
+-/* insert character under mask high; same as icm, but operates on the
+-   upper half of r1 */
+-uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
+-{
+-    int pos = 56; /* top of the upper half of r1 */
+-    uint64_t rmask = 0xff00000000000000ULL;
+-    uint8_t val = 0;
+-    int ccd = 0;
+-    uint32_t cc = 0;
+-
+-    while (mask) {
+-        if (mask & 8) {
+-            env->regs[r1] &= ~rmask;
+-            val = ldub(address);
+-            if ((val & 0x80) && !ccd) {
+-                cc = 1;
+-            }
+-            ccd = 1;
+-            if (val && cc == 0) {
+-                cc = 2;
+-            }
+-            env->regs[r1] |= (uint64_t)val << pos;
+-            address++;
+-        }
+-        mask = (mask << 1) & 0xf;
+-        pos -= 8;
+-        rmask >>= 8;
+-    }
+-
+-    return cc;
+-}
+-
+-/* load access registers r1 to r3 from memory at a2 */
+-void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    int i;
+-
+-    for (i = r1;; i = (i + 1) % 16) {
+-        env->aregs[i] = ldl(a2);
+-        a2 += 4;
+-
+-        if (i == r3) {
+-            break;
+-        }
+-    }
+-}
+-
+-/* store access registers r1 to r3 in memory at a2 */
+-void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    int i;
+-
+-    for (i = r1;; i = (i + 1) % 16) {
+-        stl(a2, env->aregs[i]);
+-        a2 += 4;
+-
+-        if (i == r3) {
+-            break;
+-        }
+-    }
+-}
+-
+-/* move long */
+-uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
+-{
+-    uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
+-    uint64_t dest = get_address_31fix(r1);
+-    uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
+-    uint64_t src = get_address_31fix(r2);
+-    uint8_t pad = src >> 24;
+-    uint8_t v;
+-    uint32_t cc;
+-
+-    if (destlen == srclen) {
+-        cc = 0;
+-    } else if (destlen < srclen) {
+-        cc = 1;
+-    } else {
+-        cc = 2;
+-    }
+-
+-    if (srclen > destlen) {
+-        srclen = destlen;
+-    }
+-
+-    for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
+-        v = ldub(src);
+-        stb(dest, v);
+-    }
+-
+-    for (; destlen; dest++, destlen--) {
+-        stb(dest, pad);
+-    }
+-
+-    env->regs[r1 + 1] = destlen;
+-    /* can't use srclen here, we trunc'ed it */
+-    env->regs[r2 + 1] -= src - env->regs[r2];
+-    env->regs[r1] = dest;
+-    env->regs[r2] = src;
+-
+-    return cc;
+-}
+-
+-/* move long extended another memcopy insn with more bells and whistles */
+-uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    uint64_t destlen = env->regs[r1 + 1];
+-    uint64_t dest = env->regs[r1];
+-    uint64_t srclen = env->regs[r3 + 1];
+-    uint64_t src = env->regs[r3];
+-    uint8_t pad = a2 & 0xff;
+-    uint8_t v;
+-    uint32_t cc;
+-
+-    if (!(env->psw.mask & PSW_MASK_64)) {
+-        destlen = (uint32_t)destlen;
+-        srclen = (uint32_t)srclen;
+-        dest &= 0x7fffffff;
+-        src &= 0x7fffffff;
+-    }
+-
+-    if (destlen == srclen) {
+-        cc = 0;
+-    } else if (destlen < srclen) {
+-        cc = 1;
+-    } else {
+-        cc = 2;
+-    }
+-
+-    if (srclen > destlen) {
+-        srclen = destlen;
+-    }
+-
+-    for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
+-        v = ldub(src);
+-        stb(dest, v);
+-    }
+-
+-    for (; destlen; dest++, destlen--) {
+-        stb(dest, pad);
+-    }
+-
+-    env->regs[r1 + 1] = destlen;
+-    /* can't use srclen here, we trunc'ed it */
+-    /* FIXME: 31-bit mode! */
+-    env->regs[r3 + 1] -= src - env->regs[r3];
+-    env->regs[r1] = dest;
+-    env->regs[r3] = src;
+-
+-    return cc;
+-}
+-
+-/* compare logical long extended memcompare insn with padding */
+-uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    uint64_t destlen = env->regs[r1 + 1];
+-    uint64_t dest = get_address_31fix(r1);
+-    uint64_t srclen = env->regs[r3 + 1];
+-    uint64_t src = get_address_31fix(r3);
+-    uint8_t pad = a2 & 0xff;
+-    uint8_t v1 = 0, v2 = 0;
+-    uint32_t cc = 0;
+-
+-    if (!(destlen || srclen)) {
+-        return cc;
+-    }
+-
+-    if (srclen > destlen) {
+-        srclen = destlen;
+-    }
+-
+-    for (; destlen || srclen; src++, dest++, destlen--, srclen--) {
+-        v1 = srclen ? ldub(src) : pad;
+-        v2 = destlen ? ldub(dest) : pad;
+-        if (v1 != v2) {
+-            cc = (v1 < v2) ? 1 : 2;
+-            break;
+-        }
+-    }
+-
+-    env->regs[r1 + 1] = destlen;
+-    /* can't use srclen here, we trunc'ed it */
+-    env->regs[r3 + 1] -= src - env->regs[r3];
+-    env->regs[r1] = dest;
+-    env->regs[r3] = src;
+-
+-    return cc;
+-}
+-
+-/* checksum */
+-void HELPER(cksm)(uint32_t r1, uint32_t r2)
+-{
+-    uint64_t src = get_address_31fix(r2);
+-    uint64_t src_len = env->regs[(r2 + 1) & 15];
+-    uint64_t cksm = (uint32_t)env->regs[r1];
+-
+-    while (src_len >= 4) {
+-        cksm += ldl(src);
+-
+-        /* move to next word */
+-        src_len -= 4;
+-        src += 4;
+-    }
+-
+-    switch (src_len) {
+-    case 0:
+-        break;
+-    case 1:
+-        cksm += ldub(src) << 24;
+-        break;
+-    case 2:
+-        cksm += lduw(src) << 16;
+-        break;
+-    case 3:
+-        cksm += lduw(src) << 16;
+-        cksm += ldub(src + 2) << 8;
+-        break;
+-    }
+-
+-    /* indicate we've processed everything */
+-    env->regs[r2] = src + src_len;
+-    env->regs[(r2 + 1) & 15] = 0;
+-
+-    /* store result */
+-    env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+-        ((uint32_t)cksm + (cksm >> 32));
+-}
+-
+-void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
+-{
+-    int len_dest = len >> 4;
+-    int len_src = len & 0xf;
+-    uint8_t b;
+-    int second_nibble = 0;
+-
+-    dest += len_dest;
+-    src += len_src;
+-
+-    /* last byte is special, it only flips the nibbles */
+-    b = ldub(src);
+-    stb(dest, (b << 4) | (b >> 4));
+-    src--;
+-    len_src--;
+-
+-    /* now pad every nibble with 0xf0 */
+-
+-    while (len_dest > 0) {
+-        uint8_t cur_byte = 0;
+-
+-        if (len_src > 0) {
+-            cur_byte = ldub(src);
+-        }
+-
+-        len_dest--;
+-        dest--;
+-
+-        /* only advance one nibble at a time */
+-        if (second_nibble) {
+-            cur_byte >>= 4;
+-            len_src--;
+-            src--;
+-        }
+-        second_nibble = !second_nibble;
+-
+-        /* digit */
+-        cur_byte = (cur_byte & 0xf);
+-        /* zone bits */
+-        cur_byte |= 0xf0;
+-
+-        stb(dest, cur_byte);
+-    }
+-}
+-
+-void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
+-{
+-    int i;
+-
+-    for (i = 0; i <= len; i++) {
+-        uint8_t byte = ldub(array + i);
+-        uint8_t new_byte = ldub(trans + byte);
+-
+-        stb(array + i, new_byte);
+-    }
+-}
+-
+-#ifndef CONFIG_USER_ONLY
+ void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
+ {
+     qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
+@@ -1267,206 +384,6 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
+     return cc;
+ }
+ 
+-void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    int i;
+-    uint64_t src = a2;
+-
+-    for (i = r1;; i = (i + 1) % 16) {
+-        env->cregs[i] = ldq(src);
+-        HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
+-                   i, src, env->cregs[i]);
+-        src += sizeof(uint64_t);
+-
+-        if (i == r3) {
+-            break;
+-        }
+-    }
+-
+-    tlb_flush(env, 1);
+-}
+-
+-void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    int i;
+-    uint64_t src = a2;
+-
+-    for (i = r1;; i = (i + 1) % 16) {
+-        env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) | ldl(src);
+-        src += sizeof(uint32_t);
+-
+-        if (i == r3) {
+-            break;
+-        }
+-    }
+-
+-    tlb_flush(env, 1);
+-}
+-
+-void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    int i;
+-    uint64_t dest = a2;
+-
+-    for (i = r1;; i = (i + 1) % 16) {
+-        stq(dest, env->cregs[i]);
+-        dest += sizeof(uint64_t);
+-
+-        if (i == r3) {
+-            break;
+-        }
+-    }
+-}
+-
+-void HELPER(stctl)(uint32_t r1, uint64_t a2, uint32_t r3)
+-{
+-    int i;
+-    uint64_t dest = a2;
+-
+-    for (i = r1;; i = (i + 1) % 16) {
+-        stl(dest, env->cregs[i]);
+-        dest += sizeof(uint32_t);
+-
+-        if (i == r3) {
+-            break;
+-        }
+-    }
+-}
+-
+-uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2)
+-{
+-    /* XXX implement */
+-
+-    return 0;
+-}
+-
+-/* insert storage key extended */
+-uint64_t HELPER(iske)(uint64_t r2)
+-{
+-    uint64_t addr = get_address(0, 0, r2);
+-
+-    if (addr > ram_size) {
+-        return 0;
+-    }
+-
+-    return env->storage_keys[addr / TARGET_PAGE_SIZE];
+-}
+-
+-/* set storage key extended */
+-void HELPER(sske)(uint32_t r1, uint64_t r2)
+-{
+-    uint64_t addr = get_address(0, 0, r2);
+-
+-    if (addr > ram_size) {
+-        return;
+-    }
+-
+-    env->storage_keys[addr / TARGET_PAGE_SIZE] = r1;
+-}
+-
+-/* reset reference bit extended */
+-uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
+-{
+-    uint8_t re;
+-    uint8_t key;
+-
+-    if (r2 > ram_size) {
+-        return 0;
+-    }
+-
+-    key = env->storage_keys[r2 / TARGET_PAGE_SIZE];
+-    re = key & (SK_R | SK_C);
+-    env->storage_keys[r2 / TARGET_PAGE_SIZE] = (key & ~SK_R);
+-
+-    /*
+-     * cc
+-     *
+-     * 0  Reference bit zero; change bit zero
+-     * 1  Reference bit zero; change bit one
+-     * 2  Reference bit one; change bit zero
+-     * 3  Reference bit one; change bit one
+-     */
+-
+-    return re >> 1;
+-}
+-
+-/* compare and swap and purge */
+-uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
+-{
+-    uint32_t cc;
+-    uint32_t o1 = env->regs[r1];
+-    uint64_t a2 = get_address_31fix(r2) & ~3ULL;
+-    uint32_t o2 = ldl(a2);
+-
+-    if (o1 == o2) {
+-        stl(a2, env->regs[(r1 + 1) & 15]);
+-        if (env->regs[r2] & 0x3) {
+-            /* flush TLB / ALB */
+-            tlb_flush(env, 1);
+-        }
+-        cc = 0;
+-    } else {
+-        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | o2;
+-        cc = 1;
+-    }
+-
+-    return cc;
+-}
+-
+-static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
+-                        uint64_t mode2)
+-{
+-    target_ulong src, dest;
+-    int flags, cc = 0, i;
+-
+-    if (!l) {
+-        return 0;
+-    } else if (l > 256) {
+-        /* max 256 */
+-        l = 256;
+-        cc = 3;
+-    }
+-
+-    if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) {
+-        cpu_loop_exit(env);
+-    }
+-    dest |= a1 & ~TARGET_PAGE_MASK;
+-
+-    if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) {
+-        cpu_loop_exit(env);
+-    }
+-    src |= a2 & ~TARGET_PAGE_MASK;
+-
+-    /* XXX replace w/ memcpy */
+-    for (i = 0; i < l; i++) {
+-        /* XXX be more clever */
+-        if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) ||
+-            (((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) {
+-            mvc_asc(l - i, a1 + i, mode1, a2 + i, mode2);
+-            break;
+-        }
+-        stb_phys(dest + i, ldub_phys(src + i));
+-    }
+-
+-    return cc;
+-}
+-
+-uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
+-{
+-    HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
+-               __func__, l, a1, a2);
+-
+-    return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
+-}
+-
+-uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
+-{
+-    HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
+-               __func__, l, a1, a2);
+-
+-    return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
+-}
+-
+ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
+ {
+     int cc = 0;
+@@ -1508,78 +425,4 @@ uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
+ 
+     return cc;
+ }
+-
+-/* invalidate pte */
+-void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
+-{
+-    uint64_t page = vaddr & TARGET_PAGE_MASK;
+-    uint64_t pte = 0;
+-
+-    /* XXX broadcast to other CPUs */
+-
+-    /* XXX Linux is nice enough to give us the exact pte address.
+-       According to spec we'd have to find it out ourselves */
+-    /* XXX Linux is fine with overwriting the pte, the spec requires
+-       us to only set the invalid bit */
+-    stq_phys(pte_addr, pte | _PAGE_INVALID);
+-
+-    /* XXX we exploit the fact that Linux passes the exact virtual
+-       address here - it's not obliged to! */
+-    tlb_flush_page(env, page);
+-
+-    /* XXX 31-bit hack */
+-    if (page & 0x80000000) {
+-        tlb_flush_page(env, page & ~0x80000000);
+-    } else {
+-        tlb_flush_page(env, page | 0x80000000);
+-    }
+-}
+-
+-/* flush local tlb */
+-void HELPER(ptlb)(void)
+-{
+-    tlb_flush(env, 1);
+-}
+-
+-/* store using real address */
+-void HELPER(stura)(uint64_t addr, uint32_t v1)
+-{
+-    stw_phys(get_address(0, 0, addr), v1);
+-}
+-
+-/* load real address */
+-uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
+-{
+-    uint32_t cc = 0;
+-    int old_exc = env->exception_index;
+-    uint64_t asc = env->psw.mask & PSW_MASK_ASC;
+-    uint64_t ret;
+-    int flags;
+-
+-    /* XXX incomplete - has more corner cases */
+-    if (!(env->psw.mask & PSW_MASK_64) && (addr >> 32)) {
+-        program_interrupt(env, PGM_SPECIAL_OP, 2);
+-    }
+-
+-    env->exception_index = old_exc;
+-    if (mmu_translate(env, addr, 0, asc, &ret, &flags)) {
+-        cc = 3;
+-    }
+-    if (env->exception_index == EXCP_PGM) {
+-        ret = env->int_pgm_code | 0x80000000;
+-    } else {
+-        ret |= addr & ~TARGET_PAGE_MASK;
+-    }
+-    env->exception_index = old_exc;
+-
+-    if (!(env->psw.mask & PSW_MASK_64)) {
+-        env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+-            (ret & 0xffffffffULL);
+-    } else {
+-        env->regs[r1] = ret;
+-    }
+-
+-    return cc;
+-}
+-
+ #endif
+-- 
+1.7.12.1
+
diff --git a/0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch b/0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch
new file mode 100644
index 0000000..e96aa52
--- /dev/null
+++ b/0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch
@@ -0,0 +1,924 @@
+From 56018228deac6e704a7ec8befd9e9dc69f2fe73f Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:35 +0000
+Subject: [PATCH] target-s390x: rename op_helper.c to misc_helper.c
+
+Now op_helper.c contains miscellaneous helpers, rename
+it to misc_helper.c.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+[agraf: fix conflict]
+Signed-off-by: Alexander Graf <agraf at suse.de>
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/Makefile.objs |   6 +-
+ target-s390x/cpu.h         |   2 +-
+ target-s390x/misc_helper.c | 428 +++++++++++++++++++++++++++++++++++++++++++++
+ target-s390x/op_helper.c   | 428 ---------------------------------------------
+ 4 files changed, 432 insertions(+), 432 deletions(-)
+ create mode 100644 target-s390x/misc_helper.c
+ delete mode 100644 target-s390x/op_helper.c
+
+diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
+index b9b3061..a87d26f 100644
+--- a/target-s390x/Makefile.objs
++++ b/target-s390x/Makefile.objs
+@@ -1,10 +1,10 @@
+-obj-y += translate.o op_helper.o helper.o cpu.o interrupt.o
+-obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o
++obj-y += translate.o helper.o cpu.o interrupt.o
++obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-$(CONFIG_KVM) += kvm.o
+ 
+-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
++$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
+index 97fde5e..0ccb551 100644
+--- a/target-s390x/cpu.h
++++ b/target-s390x/cpu.h
+@@ -1005,7 +1005,7 @@ uint32_t set_cc_f64(float64 v1, float64 v2);
+ uint32_t set_cc_nz_f32(float32 v);
+ uint32_t set_cc_nz_f64(float64 v);
+ 
+-/* op_helper.c */
++/* misc_helper.c */
+ void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
+ 
+ #endif
+diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
+new file mode 100644
+index 0000000..1d5137f
+--- /dev/null
++++ b/target-s390x/misc_helper.c
+@@ -0,0 +1,428 @@
++/*
++ *  S/390 misc helper routines
++ *
++ *  Copyright (c) 2009 Ulrich Hecht
++ *  Copyright (c) 2009 Alexander Graf
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include "cpu.h"
++#include "memory.h"
++#include "cputlb.h"
++#include "dyngen-exec.h"
++#include "host-utils.h"
++#include "helper.h"
++#include <string.h>
++#include "kvm.h"
++#include "qemu-timer.h"
++#ifdef CONFIG_KVM
++#include <linux/kvm.h>
++#endif
++
++#if !defined(CONFIG_USER_ONLY)
++#include "softmmu_exec.h"
++#include "sysemu.h"
++#endif
++
++/* #define DEBUG_HELPER */
++#ifdef DEBUG_HELPER
++#define HELPER_LOG(x...) qemu_log(x)
++#else
++#define HELPER_LOG(x...)
++#endif
++
++/* raise an exception */
++void HELPER(exception)(uint32_t excp)
++{
++    HELPER_LOG("%s: exception %d\n", __func__, excp);
++    env->exception_index = excp;
++    cpu_loop_exit(env);
++}
++
++#ifndef CONFIG_USER_ONLY
++void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
++{
++    qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
++
++    if (kvm_enabled()) {
++#ifdef CONFIG_KVM
++        kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
++#endif
++    } else {
++        env->int_pgm_code = code;
++        env->int_pgm_ilc = ilc;
++        env->exception_index = EXCP_PGM;
++        cpu_loop_exit(env);
++    }
++}
++
++/*
++ * ret < 0 indicates program check, ret = 0, 1, 2, 3 -> cc
++ */
++int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
++{
++    int r = 0;
++    int shift = 0;
++
++#ifdef DEBUG_HELPER
++    printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code);
++#endif
++
++    /* basic checks */
++    if (!memory_region_is_ram(phys_page_find(sccb >> TARGET_PAGE_BITS)->mr)) {
++        return -PGM_ADDRESSING;
++    }
++    if (sccb & ~0x7ffffff8ul) {
++        return -PGM_SPECIFICATION;
++    }
++
++    switch (code) {
++    case SCLP_CMDW_READ_SCP_INFO:
++    case SCLP_CMDW_READ_SCP_INFO_FORCED:
++        while ((ram_size >> (20 + shift)) > 65535) {
++            shift++;
++        }
++        stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
++        stb_phys(sccb + SCP_INCREMENT, 1 << shift);
++        stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
++
++        s390_sclp_extint(sccb & ~3);
++        break;
++    default:
++#ifdef DEBUG_HELPER
++        printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
++#endif
++        r = 3;
++        break;
++    }
++
++    return r;
++}
++
++/* SCLP service call */
++uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
++{
++    int r;
++
++    r = sclp_service_call(env, r1, r2);
++    if (r < 0) {
++        program_interrupt(env, -r, 4);
++        return 0;
++    }
++    return r;
++}
++
++/* DIAG */
++uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
++{
++    uint64_t r;
++
++    switch (num) {
++    case 0x500:
++        /* KVM hypercall */
++        r = s390_virtio_hypercall(env, mem, code);
++        break;
++    case 0x44:
++        /* yield */
++        r = 0;
++        break;
++    case 0x308:
++        /* ipl */
++        r = 0;
++        break;
++    default:
++        r = -1;
++        break;
++    }
++
++    if (r) {
++        program_interrupt(env, PGM_OPERATION, ILC_LATER_INC);
++    }
++
++    return r;
++}
++
++/* Store CPU ID */
++void HELPER(stidp)(uint64_t a1)
++{
++    stq(a1, env->cpu_num);
++}
++
++/* Set Prefix */
++void HELPER(spx)(uint64_t a1)
++{
++    uint32_t prefix;
++
++    prefix = ldl(a1);
++    env->psa = prefix & 0xfffff000;
++    qemu_log("prefix: %#x\n", prefix);
++    tlb_flush_page(env, 0);
++    tlb_flush_page(env, TARGET_PAGE_SIZE);
++}
++
++/* Set Clock */
++uint32_t HELPER(sck)(uint64_t a1)
++{
++    /* XXX not implemented - is it necessary? */
++
++    return 0;
++}
++
++static inline uint64_t clock_value(CPUS390XState *env)
++{
++    uint64_t time;
++
++    time = env->tod_offset +
++        time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
++
++    return time;
++}
++
++/* Store Clock */
++uint32_t HELPER(stck)(uint64_t a1)
++{
++    stq(a1, clock_value(env));
++
++    return 0;
++}
++
++/* Store Clock Extended */
++uint32_t HELPER(stcke)(uint64_t a1)
++{
++    stb(a1, 0);
++    /* basically the same value as stck */
++    stq(a1 + 1, clock_value(env) | env->cpu_num);
++    /* more fine grained than stck */
++    stq(a1 + 9, 0);
++    /* XXX programmable fields */
++    stw(a1 + 17, 0);
++
++    return 0;
++}
++
++/* Set Clock Comparator */
++void HELPER(sckc)(uint64_t a1)
++{
++    uint64_t time = ldq(a1);
++
++    if (time == -1ULL) {
++        return;
++    }
++
++    /* difference between now and then */
++    time -= clock_value(env);
++    /* nanoseconds */
++    time = (time * 125) >> 9;
++
++    qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time);
++}
++
++/* Store Clock Comparator */
++void HELPER(stckc)(uint64_t a1)
++{
++    /* XXX implement */
++    stq(a1, 0);
++}
++
++/* Set CPU Timer */
++void HELPER(spt)(uint64_t a1)
++{
++    uint64_t time = ldq(a1);
++
++    if (time == -1ULL) {
++        return;
++    }
++
++    /* nanoseconds */
++    time = (time * 125) >> 9;
++
++    qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time);
++}
++
++/* Store CPU Timer */
++void HELPER(stpt)(uint64_t a1)
++{
++    /* XXX implement */
++    stq(a1, 0);
++}
++
++/* Store System Information */
++uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
++{
++    int cc = 0;
++    int sel1, sel2;
++
++    if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 &&
++        ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) {
++        /* valid function code, invalid reserved bits */
++        program_interrupt(env, PGM_SPECIFICATION, 2);
++    }
++
++    sel1 = r0 & STSI_R0_SEL1_MASK;
++    sel2 = r1 & STSI_R1_SEL2_MASK;
++
++    /* XXX: spec exception if sysib is not 4k-aligned */
++
++    switch (r0 & STSI_LEVEL_MASK) {
++    case STSI_LEVEL_1:
++        if ((sel1 == 1) && (sel2 == 1)) {
++            /* Basic Machine Configuration */
++            struct sysib_111 sysib;
++
++            memset(&sysib, 0, sizeof(sysib));
++            ebcdic_put(sysib.manuf, "QEMU            ", 16);
++            /* same as machine type number in STORE CPU ID */
++            ebcdic_put(sysib.type, "QEMU", 4);
++            /* same as model number in STORE CPU ID */
++            ebcdic_put(sysib.model, "QEMU            ", 16);
++            ebcdic_put(sysib.sequence, "QEMU            ", 16);
++            ebcdic_put(sysib.plant, "QEMU", 4);
++            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
++        } else if ((sel1 == 2) && (sel2 == 1)) {
++            /* Basic Machine CPU */
++            struct sysib_121 sysib;
++
++            memset(&sysib, 0, sizeof(sysib));
++            /* XXX make different for different CPUs? */
++            ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
++            ebcdic_put(sysib.plant, "QEMU", 4);
++            stw_p(&sysib.cpu_addr, env->cpu_num);
++            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
++        } else if ((sel1 == 2) && (sel2 == 2)) {
++            /* Basic Machine CPUs */
++            struct sysib_122 sysib;
++
++            memset(&sysib, 0, sizeof(sysib));
++            stl_p(&sysib.capability, 0x443afc29);
++            /* XXX change when SMP comes */
++            stw_p(&sysib.total_cpus, 1);
++            stw_p(&sysib.active_cpus, 1);
++            stw_p(&sysib.standby_cpus, 0);
++            stw_p(&sysib.reserved_cpus, 0);
++            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
++        } else {
++            cc = 3;
++        }
++        break;
++    case STSI_LEVEL_2:
++        {
++            if ((sel1 == 2) && (sel2 == 1)) {
++                /* LPAR CPU */
++                struct sysib_221 sysib;
++
++                memset(&sysib, 0, sizeof(sysib));
++                /* XXX make different for different CPUs? */
++                ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
++                ebcdic_put(sysib.plant, "QEMU", 4);
++                stw_p(&sysib.cpu_addr, env->cpu_num);
++                stw_p(&sysib.cpu_id, 0);
++                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
++            } else if ((sel1 == 2) && (sel2 == 2)) {
++                /* LPAR CPUs */
++                struct sysib_222 sysib;
++
++                memset(&sysib, 0, sizeof(sysib));
++                stw_p(&sysib.lpar_num, 0);
++                sysib.lcpuc = 0;
++                /* XXX change when SMP comes */
++                stw_p(&sysib.total_cpus, 1);
++                stw_p(&sysib.conf_cpus, 1);
++                stw_p(&sysib.standby_cpus, 0);
++                stw_p(&sysib.reserved_cpus, 0);
++                ebcdic_put(sysib.name, "QEMU    ", 8);
++                stl_p(&sysib.caf, 1000);
++                stw_p(&sysib.dedicated_cpus, 0);
++                stw_p(&sysib.shared_cpus, 0);
++                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
++            } else {
++                cc = 3;
++            }
++            break;
++        }
++    case STSI_LEVEL_3:
++        {
++            if ((sel1 == 2) && (sel2 == 2)) {
++                /* VM CPUs */
++                struct sysib_322 sysib;
++
++                memset(&sysib, 0, sizeof(sysib));
++                sysib.count = 1;
++                /* XXX change when SMP comes */
++                stw_p(&sysib.vm[0].total_cpus, 1);
++                stw_p(&sysib.vm[0].conf_cpus, 1);
++                stw_p(&sysib.vm[0].standby_cpus, 0);
++                stw_p(&sysib.vm[0].reserved_cpus, 0);
++                ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
++                stl_p(&sysib.vm[0].caf, 1000);
++                ebcdic_put(sysib.vm[0].cpi, "KVM/Linux       ", 16);
++                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
++            } else {
++                cc = 3;
++            }
++            break;
++        }
++    case STSI_LEVEL_CURRENT:
++        env->regs[0] = STSI_LEVEL_3;
++        break;
++    default:
++        cc = 3;
++        break;
++    }
++
++    return cc;
++}
++
++uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
++{
++    int cc = 0;
++
++    HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
++               __func__, order_code, r1, cpu_addr);
++
++    /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register"
++       as parameter (input). Status (output) is always R1. */
++
++    switch (order_code) {
++    case SIGP_SET_ARCH:
++        /* switch arch */
++        break;
++    case SIGP_SENSE:
++        /* enumerate CPU status */
++        if (cpu_addr) {
++            /* XXX implement when SMP comes */
++            return 3;
++        }
++        env->regs[r1] &= 0xffffffff00000000ULL;
++        cc = 1;
++        break;
++#if !defined(CONFIG_USER_ONLY)
++    case SIGP_RESTART:
++        qemu_system_reset_request();
++        cpu_loop_exit(env);
++        break;
++    case SIGP_STOP:
++        qemu_system_shutdown_request();
++        cpu_loop_exit(env);
++        break;
++#endif
++    default:
++        /* unknown sigp */
++        fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code);
++        cc = 3;
++    }
++
++    return cc;
++}
++#endif
+diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
+deleted file mode 100644
+index bb8dbf5..0000000
+--- a/target-s390x/op_helper.c
++++ /dev/null
+@@ -1,428 +0,0 @@
+-/*
+- *  S/390 helper routines
+- *
+- *  Copyright (c) 2009 Ulrich Hecht
+- *  Copyright (c) 2009 Alexander Graf
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Lesser General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Lesser General Public License for more details.
+- *
+- * You should have received a copy of the GNU Lesser General Public
+- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+- */
+-
+-#include "cpu.h"
+-#include "memory.h"
+-#include "cputlb.h"
+-#include "dyngen-exec.h"
+-#include "host-utils.h"
+-#include "helper.h"
+-#include <string.h>
+-#include "kvm.h"
+-#include "qemu-timer.h"
+-#ifdef CONFIG_KVM
+-#include <linux/kvm.h>
+-#endif
+-
+-#if !defined(CONFIG_USER_ONLY)
+-#include "softmmu_exec.h"
+-#include "sysemu.h"
+-#endif
+-
+-/* #define DEBUG_HELPER */
+-#ifdef DEBUG_HELPER
+-#define HELPER_LOG(x...) qemu_log(x)
+-#else
+-#define HELPER_LOG(x...)
+-#endif
+-
+-/* raise an exception */
+-void HELPER(exception)(uint32_t excp)
+-{
+-    HELPER_LOG("%s: exception %d\n", __func__, excp);
+-    env->exception_index = excp;
+-    cpu_loop_exit(env);
+-}
+-
+-#ifndef CONFIG_USER_ONLY
+-void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
+-{
+-    qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
+-
+-    if (kvm_enabled()) {
+-#ifdef CONFIG_KVM
+-        kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
+-#endif
+-    } else {
+-        env->int_pgm_code = code;
+-        env->int_pgm_ilc = ilc;
+-        env->exception_index = EXCP_PGM;
+-        cpu_loop_exit(env);
+-    }
+-}
+-
+-/*
+- * ret < 0 indicates program check, ret = 0, 1, 2, 3 -> cc
+- */
+-int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
+-{
+-    int r = 0;
+-    int shift = 0;
+-
+-#ifdef DEBUG_HELPER
+-    printf("sclp(0x%x, 0x%" PRIx64 ")\n", sccb, code);
+-#endif
+-
+-    /* basic checks */
+-    if (!memory_region_is_ram(phys_page_find(sccb >> TARGET_PAGE_BITS)->mr)) {
+-        return -PGM_ADDRESSING;
+-    }
+-    if (sccb & ~0x7ffffff8ul) {
+-        return -PGM_SPECIFICATION;
+-    }
+-
+-    switch (code) {
+-    case SCLP_CMDW_READ_SCP_INFO:
+-    case SCLP_CMDW_READ_SCP_INFO_FORCED:
+-        while ((ram_size >> (20 + shift)) > 65535) {
+-            shift++;
+-        }
+-        stw_phys(sccb + SCP_MEM_CODE, ram_size >> (20 + shift));
+-        stb_phys(sccb + SCP_INCREMENT, 1 << shift);
+-        stw_phys(sccb + SCP_RESPONSE_CODE, 0x10);
+-
+-        s390_sclp_extint(sccb & ~3);
+-        break;
+-    default:
+-#ifdef DEBUG_HELPER
+-        printf("KVM: invalid sclp call 0x%x / 0x%" PRIx64 "x\n", sccb, code);
+-#endif
+-        r = 3;
+-        break;
+-    }
+-
+-    return r;
+-}
+-
+-/* SCLP service call */
+-uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
+-{
+-    int r;
+-
+-    r = sclp_service_call(env, r1, r2);
+-    if (r < 0) {
+-        program_interrupt(env, -r, 4);
+-        return 0;
+-    }
+-    return r;
+-}
+-
+-/* DIAG */
+-uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
+-{
+-    uint64_t r;
+-
+-    switch (num) {
+-    case 0x500:
+-        /* KVM hypercall */
+-        r = s390_virtio_hypercall(env, mem, code);
+-        break;
+-    case 0x44:
+-        /* yield */
+-        r = 0;
+-        break;
+-    case 0x308:
+-        /* ipl */
+-        r = 0;
+-        break;
+-    default:
+-        r = -1;
+-        break;
+-    }
+-
+-    if (r) {
+-        program_interrupt(env, PGM_OPERATION, ILC_LATER_INC);
+-    }
+-
+-    return r;
+-}
+-
+-/* Store CPU ID */
+-void HELPER(stidp)(uint64_t a1)
+-{
+-    stq(a1, env->cpu_num);
+-}
+-
+-/* Set Prefix */
+-void HELPER(spx)(uint64_t a1)
+-{
+-    uint32_t prefix;
+-
+-    prefix = ldl(a1);
+-    env->psa = prefix & 0xfffff000;
+-    qemu_log("prefix: %#x\n", prefix);
+-    tlb_flush_page(env, 0);
+-    tlb_flush_page(env, TARGET_PAGE_SIZE);
+-}
+-
+-/* Set Clock */
+-uint32_t HELPER(sck)(uint64_t a1)
+-{
+-    /* XXX not implemented - is it necessary? */
+-
+-    return 0;
+-}
+-
+-static inline uint64_t clock_value(CPUS390XState *env)
+-{
+-    uint64_t time;
+-
+-    time = env->tod_offset +
+-        time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
+-
+-    return time;
+-}
+-
+-/* Store Clock */
+-uint32_t HELPER(stck)(uint64_t a1)
+-{
+-    stq(a1, clock_value(env));
+-
+-    return 0;
+-}
+-
+-/* Store Clock Extended */
+-uint32_t HELPER(stcke)(uint64_t a1)
+-{
+-    stb(a1, 0);
+-    /* basically the same value as stck */
+-    stq(a1 + 1, clock_value(env) | env->cpu_num);
+-    /* more fine grained than stck */
+-    stq(a1 + 9, 0);
+-    /* XXX programmable fields */
+-    stw(a1 + 17, 0);
+-
+-    return 0;
+-}
+-
+-/* Set Clock Comparator */
+-void HELPER(sckc)(uint64_t a1)
+-{
+-    uint64_t time = ldq(a1);
+-
+-    if (time == -1ULL) {
+-        return;
+-    }
+-
+-    /* difference between now and then */
+-    time -= clock_value(env);
+-    /* nanoseconds */
+-    time = (time * 125) >> 9;
+-
+-    qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time);
+-}
+-
+-/* Store Clock Comparator */
+-void HELPER(stckc)(uint64_t a1)
+-{
+-    /* XXX implement */
+-    stq(a1, 0);
+-}
+-
+-/* Set CPU Timer */
+-void HELPER(spt)(uint64_t a1)
+-{
+-    uint64_t time = ldq(a1);
+-
+-    if (time == -1ULL) {
+-        return;
+-    }
+-
+-    /* nanoseconds */
+-    time = (time * 125) >> 9;
+-
+-    qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time);
+-}
+-
+-/* Store CPU Timer */
+-void HELPER(stpt)(uint64_t a1)
+-{
+-    /* XXX implement */
+-    stq(a1, 0);
+-}
+-
+-/* Store System Information */
+-uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
+-{
+-    int cc = 0;
+-    int sel1, sel2;
+-
+-    if ((r0 & STSI_LEVEL_MASK) <= STSI_LEVEL_3 &&
+-        ((r0 & STSI_R0_RESERVED_MASK) || (r1 & STSI_R1_RESERVED_MASK))) {
+-        /* valid function code, invalid reserved bits */
+-        program_interrupt(env, PGM_SPECIFICATION, 2);
+-    }
+-
+-    sel1 = r0 & STSI_R0_SEL1_MASK;
+-    sel2 = r1 & STSI_R1_SEL2_MASK;
+-
+-    /* XXX: spec exception if sysib is not 4k-aligned */
+-
+-    switch (r0 & STSI_LEVEL_MASK) {
+-    case STSI_LEVEL_1:
+-        if ((sel1 == 1) && (sel2 == 1)) {
+-            /* Basic Machine Configuration */
+-            struct sysib_111 sysib;
+-
+-            memset(&sysib, 0, sizeof(sysib));
+-            ebcdic_put(sysib.manuf, "QEMU            ", 16);
+-            /* same as machine type number in STORE CPU ID */
+-            ebcdic_put(sysib.type, "QEMU", 4);
+-            /* same as model number in STORE CPU ID */
+-            ebcdic_put(sysib.model, "QEMU            ", 16);
+-            ebcdic_put(sysib.sequence, "QEMU            ", 16);
+-            ebcdic_put(sysib.plant, "QEMU", 4);
+-            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+-        } else if ((sel1 == 2) && (sel2 == 1)) {
+-            /* Basic Machine CPU */
+-            struct sysib_121 sysib;
+-
+-            memset(&sysib, 0, sizeof(sysib));
+-            /* XXX make different for different CPUs? */
+-            ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
+-            ebcdic_put(sysib.plant, "QEMU", 4);
+-            stw_p(&sysib.cpu_addr, env->cpu_num);
+-            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+-        } else if ((sel1 == 2) && (sel2 == 2)) {
+-            /* Basic Machine CPUs */
+-            struct sysib_122 sysib;
+-
+-            memset(&sysib, 0, sizeof(sysib));
+-            stl_p(&sysib.capability, 0x443afc29);
+-            /* XXX change when SMP comes */
+-            stw_p(&sysib.total_cpus, 1);
+-            stw_p(&sysib.active_cpus, 1);
+-            stw_p(&sysib.standby_cpus, 0);
+-            stw_p(&sysib.reserved_cpus, 0);
+-            cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+-        } else {
+-            cc = 3;
+-        }
+-        break;
+-    case STSI_LEVEL_2:
+-        {
+-            if ((sel1 == 2) && (sel2 == 1)) {
+-                /* LPAR CPU */
+-                struct sysib_221 sysib;
+-
+-                memset(&sysib, 0, sizeof(sysib));
+-                /* XXX make different for different CPUs? */
+-                ebcdic_put(sysib.sequence, "QEMUQEMUQEMUQEMU", 16);
+-                ebcdic_put(sysib.plant, "QEMU", 4);
+-                stw_p(&sysib.cpu_addr, env->cpu_num);
+-                stw_p(&sysib.cpu_id, 0);
+-                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+-            } else if ((sel1 == 2) && (sel2 == 2)) {
+-                /* LPAR CPUs */
+-                struct sysib_222 sysib;
+-
+-                memset(&sysib, 0, sizeof(sysib));
+-                stw_p(&sysib.lpar_num, 0);
+-                sysib.lcpuc = 0;
+-                /* XXX change when SMP comes */
+-                stw_p(&sysib.total_cpus, 1);
+-                stw_p(&sysib.conf_cpus, 1);
+-                stw_p(&sysib.standby_cpus, 0);
+-                stw_p(&sysib.reserved_cpus, 0);
+-                ebcdic_put(sysib.name, "QEMU    ", 8);
+-                stl_p(&sysib.caf, 1000);
+-                stw_p(&sysib.dedicated_cpus, 0);
+-                stw_p(&sysib.shared_cpus, 0);
+-                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+-            } else {
+-                cc = 3;
+-            }
+-            break;
+-        }
+-    case STSI_LEVEL_3:
+-        {
+-            if ((sel1 == 2) && (sel2 == 2)) {
+-                /* VM CPUs */
+-                struct sysib_322 sysib;
+-
+-                memset(&sysib, 0, sizeof(sysib));
+-                sysib.count = 1;
+-                /* XXX change when SMP comes */
+-                stw_p(&sysib.vm[0].total_cpus, 1);
+-                stw_p(&sysib.vm[0].conf_cpus, 1);
+-                stw_p(&sysib.vm[0].standby_cpus, 0);
+-                stw_p(&sysib.vm[0].reserved_cpus, 0);
+-                ebcdic_put(sysib.vm[0].name, "KVMguest", 8);
+-                stl_p(&sysib.vm[0].caf, 1000);
+-                ebcdic_put(sysib.vm[0].cpi, "KVM/Linux       ", 16);
+-                cpu_physical_memory_rw(a0, (uint8_t *)&sysib, sizeof(sysib), 1);
+-            } else {
+-                cc = 3;
+-            }
+-            break;
+-        }
+-    case STSI_LEVEL_CURRENT:
+-        env->regs[0] = STSI_LEVEL_3;
+-        break;
+-    default:
+-        cc = 3;
+-        break;
+-    }
+-
+-    return cc;
+-}
+-
+-uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
+-{
+-    int cc = 0;
+-
+-    HELPER_LOG("%s: %016" PRIx64 " %08x %016" PRIx64 "\n",
+-               __func__, order_code, r1, cpu_addr);
+-
+-    /* Remember: Use "R1 or R1 + 1, whichever is the odd-numbered register"
+-       as parameter (input). Status (output) is always R1. */
+-
+-    switch (order_code) {
+-    case SIGP_SET_ARCH:
+-        /* switch arch */
+-        break;
+-    case SIGP_SENSE:
+-        /* enumerate CPU status */
+-        if (cpu_addr) {
+-            /* XXX implement when SMP comes */
+-            return 3;
+-        }
+-        env->regs[r1] &= 0xffffffff00000000ULL;
+-        cc = 1;
+-        break;
+-#if !defined(CONFIG_USER_ONLY)
+-    case SIGP_RESTART:
+-        qemu_system_reset_request();
+-        cpu_loop_exit(env);
+-        break;
+-    case SIGP_STOP:
+-        qemu_system_shutdown_request();
+-        cpu_loop_exit(env);
+-        break;
+-#endif
+-    default:
+-        /* unknown sigp */
+-        fprintf(stderr, "XXX unknown sigp: 0x%" PRIx64 "\n", order_code);
+-        cc = 3;
+-    }
+-
+-    return cc;
+-}
+-#endif
+-- 
+1.7.12.1
+
diff --git a/0011-target-s390x-avoid-AREG0-for-FPU-helpers.patch b/0011-target-s390x-avoid-AREG0-for-FPU-helpers.patch
new file mode 100644
index 0000000..597face
--- /dev/null
+++ b/0011-target-s390x-avoid-AREG0-for-FPU-helpers.patch
@@ -0,0 +1,1218 @@
+From 5d38110b1e23c963302f13f5917001a9298445a7 Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:36 +0000
+Subject: [PATCH] target-s390x: avoid AREG0 for FPU helpers
+
+Make FPU helpers take a parameter for CPUState instead
+of relying on global env.
+
+Introduce temporary wrappers for FPU load and store ops.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/Makefile.objs |   1 -
+ target-s390x/cc_helper.c   |   4 +-
+ target-s390x/cpu.h         |  14 +++-
+ target-s390x/fpu_helper.c  | 184 +++++++++++++++++++++++----------------------
+ target-s390x/helper.h      | 126 +++++++++++++++----------------
+ target-s390x/mem_helper.c  |  49 ++++++++++++
+ target-s390x/translate.c   |  70 ++++++++---------
+ 7 files changed, 257 insertions(+), 191 deletions(-)
+
+diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
+index a87d26f..7d965e9 100644
+--- a/target-s390x/Makefile.objs
++++ b/target-s390x/Makefile.objs
+@@ -4,7 +4,6 @@ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-$(CONFIG_KVM) += kvm.o
+ 
+ $(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+-$(obj)/fpu_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
+index 2ac1659..9c3a2c4 100644
+--- a/target-s390x/cc_helper.c
++++ b/target-s390x/cc_helper.c
+@@ -473,10 +473,10 @@ static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
+         break;
+ 
+     case CC_OP_LTGT_F32:
+-        r = set_cc_f32(src, dst);
++        r = set_cc_f32(env, src, dst);
+         break;
+     case CC_OP_LTGT_F64:
+-        r = set_cc_f64(src, dst);
++        r = set_cc_f64(env, src, dst);
+         break;
+     case CC_OP_NZ_F32:
+         r = set_cc_nz_f32(dst);
+diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
+index 0ccb551..9b7a2e3 100644
+--- a/target-s390x/cpu.h
++++ b/target-s390x/cpu.h
+@@ -1000,12 +1000,22 @@ static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
+ }
+ 
+ /* fpu_helper.c */
+-uint32_t set_cc_f32(float32 v1, float32 v2);
+-uint32_t set_cc_f64(float64 v1, float64 v2);
++uint32_t set_cc_f32(CPUS390XState *env, float32 v1, float32 v2);
++uint32_t set_cc_f64(CPUS390XState *env, float64 v1, float64 v2);
+ uint32_t set_cc_nz_f32(float32 v);
+ uint32_t set_cc_nz_f64(float64 v);
+ 
+ /* misc_helper.c */
+ void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
+ 
++/* temporary wrappers */
++uint32_t cpu_ldub_data(CPUS390XState *env, target_ulong ptr);
++uint32_t cpu_lduw_data(CPUS390XState *env, target_ulong ptr);
++uint32_t cpu_ldl_data(CPUS390XState *env, target_ulong ptr);
++uint64_t cpu_ldq_data(CPUS390XState *env, target_ulong ptr);
++
++void cpu_stb_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
++void cpu_stw_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
++void cpu_stl_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
++void cpu_stq_data(CPUS390XState *env, target_ulong ptr, uint64_t data);
+ #endif
+diff --git a/target-s390x/fpu_helper.c b/target-s390x/fpu_helper.c
+index 1389052..e235419 100644
+--- a/target-s390x/fpu_helper.c
++++ b/target-s390x/fpu_helper.c
+@@ -19,10 +19,10 @@
+  */
+ 
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "helper.h"
+ 
+-#if !defined(CONFIG_USER_ONLY)
++/* temporarily disabled due to wrapper use */
++#if 0 && !defined(CONFIG_USER_ONLY)
+ #include "softmmu_exec.h"
+ #endif
+ 
+@@ -33,7 +33,7 @@
+ #define HELPER_LOG(x...)
+ #endif
+ 
+-static inline int float_comp_to_cc(int float_compare)
++static inline int float_comp_to_cc(CPUS390XState *env, int float_compare)
+ {
+     switch (float_compare) {
+     case float_relation_equal:
+@@ -50,14 +50,16 @@ static inline int float_comp_to_cc(int float_compare)
+ }
+ 
+ /* condition codes for binary FP ops */
+-uint32_t set_cc_f32(float32 v1, float32 v2)
++uint32_t set_cc_f32(CPUS390XState *env, float32 v1, float32 v2)
+ {
+-    return float_comp_to_cc(float32_compare_quiet(v1, v2, &env->fpu_status));
++    return float_comp_to_cc(env, float32_compare_quiet(v1, v2,
++                                                       &env->fpu_status));
+ }
+ 
+-uint32_t set_cc_f64(float64 v1, float64 v2)
++uint32_t set_cc_f64(CPUS390XState *env, float64 v1, float64 v2)
+ {
+-    return float_comp_to_cc(float64_compare_quiet(v1, v2, &env->fpu_status));
++    return float_comp_to_cc(env, float64_compare_quiet(v1, v2,
++                                                       &env->fpu_status));
+ }
+ 
+ /* condition codes for unary FP ops */
+@@ -101,14 +103,14 @@ static uint32_t set_cc_nz_f128(float128 v)
+ }
+ 
+ /* convert 32-bit int to 64-bit float */
+-void HELPER(cdfbr)(uint32_t f1, int32_t v2)
++void HELPER(cdfbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
+ {
+     HELPER_LOG("%s: converting %d to f%d\n", __func__, v2, f1);
+     env->fregs[f1].d = int32_to_float64(v2, &env->fpu_status);
+ }
+ 
+ /* convert 32-bit int to 128-bit float */
+-void HELPER(cxfbr)(uint32_t f1, int32_t v2)
++void HELPER(cxfbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
+ {
+     CPU_QuadU v1;
+ 
+@@ -118,21 +120,21 @@ void HELPER(cxfbr)(uint32_t f1, int32_t v2)
+ }
+ 
+ /* convert 64-bit int to 32-bit float */
+-void HELPER(cegbr)(uint32_t f1, int64_t v2)
++void HELPER(cegbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
+ {
+     HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
+     env->fregs[f1].l.upper = int64_to_float32(v2, &env->fpu_status);
+ }
+ 
+ /* convert 64-bit int to 64-bit float */
+-void HELPER(cdgbr)(uint32_t f1, int64_t v2)
++void HELPER(cdgbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
+ {
+     HELPER_LOG("%s: converting %ld to f%d\n", __func__, v2, f1);
+     env->fregs[f1].d = int64_to_float64(v2, &env->fpu_status);
+ }
+ 
+ /* convert 64-bit int to 128-bit float */
+-void HELPER(cxgbr)(uint32_t f1, int64_t v2)
++void HELPER(cxgbr)(CPUS390XState *env, uint32_t f1, int64_t v2)
+ {
+     CPU_QuadU x1;
+ 
+@@ -144,7 +146,7 @@ void HELPER(cxgbr)(uint32_t f1, int64_t v2)
+ }
+ 
+ /* convert 32-bit int to 32-bit float */
+-void HELPER(cefbr)(uint32_t f1, int32_t v2)
++void HELPER(cefbr)(CPUS390XState *env, uint32_t f1, int32_t v2)
+ {
+     env->fregs[f1].l.upper = int32_to_float32(v2, &env->fpu_status);
+     HELPER_LOG("%s: converting %d to 0x%d in f%d\n", __func__, v2,
+@@ -152,7 +154,7 @@ void HELPER(cefbr)(uint32_t f1, int32_t v2)
+ }
+ 
+ /* 32-bit FP addition RR */
+-uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(aebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
+                                          env->fregs[f2].l.upper,
+@@ -164,7 +166,7 @@ uint32_t HELPER(aebr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* 64-bit FP addition RR */
+-uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(adbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].d = float64_add(env->fregs[f1].d, env->fregs[f2].d,
+                                    &env->fpu_status);
+@@ -175,7 +177,7 @@ uint32_t HELPER(adbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* 32-bit FP subtraction RR */
+-uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(sebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].l.upper = float32_sub(env->fregs[f1].l.upper,
+                                          env->fregs[f2].l.upper,
+@@ -187,7 +189,7 @@ uint32_t HELPER(sebr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* 64-bit FP subtraction RR */
+-uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(sdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].d = float64_sub(env->fregs[f1].d, env->fregs[f2].d,
+                                    &env->fpu_status);
+@@ -198,7 +200,7 @@ uint32_t HELPER(sdbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* 32-bit FP division RR */
+-void HELPER(debr)(uint32_t f1, uint32_t f2)
++void HELPER(debr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].l.upper = float32_div(env->fregs[f1].l.upper,
+                                          env->fregs[f2].l.upper,
+@@ -206,7 +208,7 @@ void HELPER(debr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* 128-bit FP division RR */
+-void HELPER(dxbr)(uint32_t f1, uint32_t f2)
++void HELPER(dxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
+     CPU_QuadU v2;
+@@ -222,14 +224,14 @@ void HELPER(dxbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* 64-bit FP multiplication RR */
+-void HELPER(mdbr)(uint32_t f1, uint32_t f2)
++void HELPER(mdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].d = float64_mul(env->fregs[f1].d, env->fregs[f2].d,
+                                    &env->fpu_status);
+ }
+ 
+ /* 128-bit FP multiplication RR */
+-void HELPER(mxbr)(uint32_t f1, uint32_t f2)
++void HELPER(mxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
+     CPU_QuadU v2;
+@@ -245,14 +247,14 @@ void HELPER(mxbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* convert 32-bit float to 64-bit float */
+-void HELPER(ldebr)(uint32_t r1, uint32_t r2)
++void HELPER(ldebr)(CPUS390XState *env, uint32_t r1, uint32_t r2)
+ {
+     env->fregs[r1].d = float32_to_float64(env->fregs[r2].l.upper,
+                                           &env->fpu_status);
+ }
+ 
+ /* convert 128-bit float to 64-bit float */
+-void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
++void HELPER(ldxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU x2;
+ 
+@@ -263,7 +265,7 @@ void HELPER(ldxbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* convert 64-bit float to 128-bit float */
+-void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
++void HELPER(lxdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU res;
+ 
+@@ -273,7 +275,7 @@ void HELPER(lxdbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* convert 64-bit float to 32-bit float */
+-void HELPER(ledbr)(uint32_t f1, uint32_t f2)
++void HELPER(ledbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     float64 d2 = env->fregs[f2].d;
+ 
+@@ -281,7 +283,7 @@ void HELPER(ledbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* convert 128-bit float to 32-bit float */
+-void HELPER(lexbr)(uint32_t f1, uint32_t f2)
++void HELPER(lexbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU x2;
+ 
+@@ -292,7 +294,7 @@ void HELPER(lexbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* absolute value of 32-bit float */
+-uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(lpebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     float32 v1;
+     float32 v2 = env->fregs[f2].d;
+@@ -303,7 +305,7 @@ uint32_t HELPER(lpebr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* absolute value of 64-bit float */
+-uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(lpdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     float64 v1;
+     float64 v2 = env->fregs[f2].d;
+@@ -314,7 +316,7 @@ uint32_t HELPER(lpdbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* absolute value of 128-bit float */
+-uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(lpxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
+     CPU_QuadU v2;
+@@ -328,21 +330,21 @@ uint32_t HELPER(lpxbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* load and test 64-bit float */
+-uint32_t HELPER(ltdbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(ltdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].d = env->fregs[f2].d;
+     return set_cc_nz_f64(env->fregs[f1].d);
+ }
+ 
+ /* load and test 32-bit float */
+-uint32_t HELPER(ltebr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(ltebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].l.upper = env->fregs[f2].l.upper;
+     return set_cc_nz_f32(env->fregs[f1].l.upper);
+ }
+ 
+ /* load and test 128-bit float */
+-uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(ltxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU x;
+ 
+@@ -354,7 +356,7 @@ uint32_t HELPER(ltxbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* load complement of 32-bit float */
+-uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(lcebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].l.upper = float32_chs(env->fregs[f2].l.upper);
+ 
+@@ -362,7 +364,7 @@ uint32_t HELPER(lcebr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* load complement of 64-bit float */
+-uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(lcdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].d = float64_chs(env->fregs[f2].d);
+ 
+@@ -370,7 +372,7 @@ uint32_t HELPER(lcdbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* load complement of 128-bit float */
+-uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(lcxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU x1, x2;
+ 
+@@ -383,7 +385,7 @@ uint32_t HELPER(lcxbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* 32-bit FP addition RM */
+-void HELPER(aeb)(uint32_t f1, uint32_t val)
++void HELPER(aeb)(CPUS390XState *env, uint32_t f1, uint32_t val)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     CPU_FloatU v2;
+@@ -395,7 +397,7 @@ void HELPER(aeb)(uint32_t f1, uint32_t val)
+ }
+ 
+ /* 32-bit FP division RM */
+-void HELPER(deb)(uint32_t f1, uint32_t val)
++void HELPER(deb)(CPUS390XState *env, uint32_t f1, uint32_t val)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     CPU_FloatU v2;
+@@ -407,7 +409,7 @@ void HELPER(deb)(uint32_t f1, uint32_t val)
+ }
+ 
+ /* 32-bit FP multiplication RM */
+-void HELPER(meeb)(uint32_t f1, uint32_t val)
++void HELPER(meeb)(CPUS390XState *env, uint32_t f1, uint32_t val)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     CPU_FloatU v2;
+@@ -419,29 +421,29 @@ void HELPER(meeb)(uint32_t f1, uint32_t val)
+ }
+ 
+ /* 32-bit FP compare RR */
+-uint32_t HELPER(cebr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(cebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     float32 v2 = env->fregs[f2].l.upper;
+ 
+     HELPER_LOG("%s: comparing 0x%d from f%d and 0x%d\n", __func__,
+                v1, f1, v2);
+-    return set_cc_f32(v1, v2);
++    return set_cc_f32(env, v1, v2);
+ }
+ 
+ /* 64-bit FP compare RR */
+-uint32_t HELPER(cdbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(cdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     float64 v2 = env->fregs[f2].d;
+ 
+     HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%ld\n", __func__,
+                v1, f1, v2);
+-    return set_cc_f64(v1, v2);
++    return set_cc_f64(env, v1, v2);
+ }
+ 
+ /* 128-bit FP compare RR */
+-uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(cxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
+     CPU_QuadU v2;
+@@ -451,29 +453,29 @@ uint32_t HELPER(cxbr)(uint32_t f1, uint32_t f2)
+     v2.ll.upper = env->fregs[f2].ll;
+     v2.ll.lower = env->fregs[f2 + 2].ll;
+ 
+-    return float_comp_to_cc(float128_compare_quiet(v1.q, v2.q,
++    return float_comp_to_cc(env, float128_compare_quiet(v1.q, v2.q,
+                                                    &env->fpu_status));
+ }
+ 
+ /* 64-bit FP compare RM */
+-uint32_t HELPER(cdb)(uint32_t f1, uint64_t a2)
++uint32_t HELPER(cdb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     CPU_DoubleU v2;
+ 
+-    v2.ll = ldq(a2);
++    v2.ll = cpu_ldq_data(env, a2);
+     HELPER_LOG("%s: comparing 0x%ld from f%d and 0x%lx\n", __func__, v1,
+                f1, v2.d);
+-    return set_cc_f64(v1, v2.d);
++    return set_cc_f64(env, v1, v2.d);
+ }
+ 
+ /* 64-bit FP addition RM */
+-uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
++uint32_t HELPER(adb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     CPU_DoubleU v2;
+ 
+-    v2.ll = ldq(a2);
++    v2.ll = cpu_ldq_data(env, a2);
+     HELPER_LOG("%s: adding 0x%lx from f%d and 0x%lx\n", __func__,
+                v1, f1, v2.d);
+     env->fregs[f1].d = v1 = float64_add(v1, v2.d, &env->fpu_status);
+@@ -481,7 +483,7 @@ uint32_t HELPER(adb)(uint32_t f1, uint64_t a2)
+ }
+ 
+ /* 32-bit FP subtraction RM */
+-void HELPER(seb)(uint32_t f1, uint32_t val)
++void HELPER(seb)(CPUS390XState *env, uint32_t f1, uint32_t val)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     CPU_FloatU v2;
+@@ -491,41 +493,41 @@ void HELPER(seb)(uint32_t f1, uint32_t val)
+ }
+ 
+ /* 64-bit FP subtraction RM */
+-uint32_t HELPER(sdb)(uint32_t f1, uint64_t a2)
++uint32_t HELPER(sdb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     CPU_DoubleU v2;
+ 
+-    v2.ll = ldq(a2);
++    v2.ll = cpu_ldq_data(env, a2);
+     env->fregs[f1].d = v1 = float64_sub(v1, v2.d, &env->fpu_status);
+     return set_cc_nz_f64(v1);
+ }
+ 
+ /* 64-bit FP multiplication RM */
+-void HELPER(mdb)(uint32_t f1, uint64_t a2)
++void HELPER(mdb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     CPU_DoubleU v2;
+ 
+-    v2.ll = ldq(a2);
++    v2.ll = cpu_ldq_data(env, a2);
+     HELPER_LOG("%s: multiplying 0x%lx from f%d and 0x%ld\n", __func__,
+                v1, f1, v2.d);
+     env->fregs[f1].d = float64_mul(v1, v2.d, &env->fpu_status);
+ }
+ 
+ /* 64-bit FP division RM */
+-void HELPER(ddb)(uint32_t f1, uint64_t a2)
++void HELPER(ddb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     CPU_DoubleU v2;
+ 
+-    v2.ll = ldq(a2);
++    v2.ll = cpu_ldq_data(env, a2);
+     HELPER_LOG("%s: dividing 0x%lx from f%d by 0x%ld\n", __func__,
+                v1, f1, v2.d);
+     env->fregs[f1].d = float64_div(v1, v2.d, &env->fpu_status);
+ }
+ 
+-static void set_round_mode(int m3)
++static void set_round_mode(CPUS390XState *env, int m3)
+ {
+     switch (m3) {
+     case 0:
+@@ -553,33 +555,36 @@ static void set_round_mode(int m3)
+ }
+ 
+ /* convert 32-bit float to 64-bit int */
+-uint32_t HELPER(cgebr)(uint32_t r1, uint32_t f2, uint32_t m3)
++uint32_t HELPER(cgebr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
++                       uint32_t m3)
+ {
+     float32 v2 = env->fregs[f2].l.upper;
+ 
+-    set_round_mode(m3);
++    set_round_mode(env, m3);
+     env->regs[r1] = float32_to_int64(v2, &env->fpu_status);
+     return set_cc_nz_f32(v2);
+ }
+ 
+ /* convert 64-bit float to 64-bit int */
+-uint32_t HELPER(cgdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
++uint32_t HELPER(cgdbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
++                       uint32_t m3)
+ {
+     float64 v2 = env->fregs[f2].d;
+ 
+-    set_round_mode(m3);
++    set_round_mode(env, m3);
+     env->regs[r1] = float64_to_int64(v2, &env->fpu_status);
+     return set_cc_nz_f64(v2);
+ }
+ 
+ /* convert 128-bit float to 64-bit int */
+-uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
++uint32_t HELPER(cgxbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
++                       uint32_t m3)
+ {
+     CPU_QuadU v2;
+ 
+     v2.ll.upper = env->fregs[f2].ll;
+     v2.ll.lower = env->fregs[f2 + 2].ll;
+-    set_round_mode(m3);
++    set_round_mode(env, m3);
+     env->regs[r1] = float128_to_int64(v2.q, &env->fpu_status);
+     if (float128_is_any_nan(v2.q)) {
+         return 3;
+@@ -593,29 +598,32 @@ uint32_t HELPER(cgxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ }
+ 
+ /* convert 32-bit float to 32-bit int */
+-uint32_t HELPER(cfebr)(uint32_t r1, uint32_t f2, uint32_t m3)
++uint32_t HELPER(cfebr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
++                       uint32_t m3)
+ {
+     float32 v2 = env->fregs[f2].l.upper;
+ 
+-    set_round_mode(m3);
++    set_round_mode(env, m3);
+     env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+         float32_to_int32(v2, &env->fpu_status);
+     return set_cc_nz_f32(v2);
+ }
+ 
+ /* convert 64-bit float to 32-bit int */
+-uint32_t HELPER(cfdbr)(uint32_t r1, uint32_t f2, uint32_t m3)
++uint32_t HELPER(cfdbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
++                       uint32_t m3)
+ {
+     float64 v2 = env->fregs[f2].d;
+ 
+-    set_round_mode(m3);
++    set_round_mode(env, m3);
+     env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
+         float64_to_int32(v2, &env->fpu_status);
+     return set_cc_nz_f64(v2);
+ }
+ 
+ /* convert 128-bit float to 32-bit int */
+-uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
++uint32_t HELPER(cfxbr)(CPUS390XState *env, uint32_t r1, uint32_t f2,
++                       uint32_t m3)
+ {
+     CPU_QuadU v2;
+ 
+@@ -627,19 +635,19 @@ uint32_t HELPER(cfxbr)(uint32_t r1, uint32_t f2, uint32_t m3)
+ }
+ 
+ /* load 32-bit FP zero */
+-void HELPER(lzer)(uint32_t f1)
++void HELPER(lzer)(CPUS390XState *env, uint32_t f1)
+ {
+     env->fregs[f1].l.upper = float32_zero;
+ }
+ 
+ /* load 64-bit FP zero */
+-void HELPER(lzdr)(uint32_t f1)
++void HELPER(lzdr)(CPUS390XState *env, uint32_t f1)
+ {
+     env->fregs[f1].d = float64_zero;
+ }
+ 
+ /* load 128-bit FP zero */
+-void HELPER(lzxr)(uint32_t f1)
++void HELPER(lzxr)(CPUS390XState *env, uint32_t f1)
+ {
+     CPU_QuadU x;
+ 
+@@ -649,7 +657,7 @@ void HELPER(lzxr)(uint32_t f1)
+ }
+ 
+ /* 128-bit FP subtraction RR */
+-uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(sxbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
+     CPU_QuadU v2;
+@@ -666,7 +674,7 @@ uint32_t HELPER(sxbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* 128-bit FP addition RR */
+-uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
++uint32_t HELPER(axbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     CPU_QuadU v1;
+     CPU_QuadU v2;
+@@ -683,7 +691,7 @@ uint32_t HELPER(axbr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* 32-bit FP multiplication RR */
+-void HELPER(meebr)(uint32_t f1, uint32_t f2)
++void HELPER(meebr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].l.upper = float32_mul(env->fregs[f1].l.upper,
+                                          env->fregs[f2].l.upper,
+@@ -691,19 +699,19 @@ void HELPER(meebr)(uint32_t f1, uint32_t f2)
+ }
+ 
+ /* 64-bit FP division RR */
+-void HELPER(ddbr)(uint32_t f1, uint32_t f2)
++void HELPER(ddbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].d = float64_div(env->fregs[f1].d, env->fregs[f2].d,
+                                    &env->fpu_status);
+ }
+ 
+ /* 64-bit FP multiply and add RM */
+-void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
++void HELPER(madb)(CPUS390XState *env, uint32_t f1, uint64_t a2, uint32_t f3)
+ {
+     CPU_DoubleU v2;
+ 
+     HELPER_LOG("%s: f1 %d a2 0x%lx f3 %d\n", __func__, f1, a2, f3);
+-    v2.ll = ldq(a2);
++    v2.ll = cpu_ldq_data(env, a2);
+     env->fregs[f1].d = float64_add(env->fregs[f1].d,
+                                    float64_mul(v2.d, env->fregs[f3].d,
+                                                &env->fpu_status),
+@@ -711,7 +719,7 @@ void HELPER(madb)(uint32_t f1, uint64_t a2, uint32_t f3)
+ }
+ 
+ /* 64-bit FP multiply and add RR */
+-void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
++void HELPER(madbr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
+ {
+     HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
+     env->fregs[f1].d = float64_add(float64_mul(env->fregs[f2].d,
+@@ -721,7 +729,7 @@ void HELPER(madbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+ }
+ 
+ /* 64-bit FP multiply and subtract RR */
+-void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
++void HELPER(msdbr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
+ {
+     HELPER_LOG("%s: f1 %d f2 %d f3 %d\n", __func__, f1, f2, f3);
+     env->fregs[f1].d = float64_sub(float64_mul(env->fregs[f2].d,
+@@ -731,7 +739,7 @@ void HELPER(msdbr)(uint32_t f1, uint32_t f3, uint32_t f2)
+ }
+ 
+ /* 32-bit FP multiply and add RR */
+-void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
++void HELPER(maebr)(CPUS390XState *env, uint32_t f1, uint32_t f3, uint32_t f2)
+ {
+     env->fregs[f1].l.upper = float32_add(env->fregs[f1].l.upper,
+                                          float32_mul(env->fregs[f2].l.upper,
+@@ -741,29 +749,29 @@ void HELPER(maebr)(uint32_t f1, uint32_t f3, uint32_t f2)
+ }
+ 
+ /* convert 32-bit float to 64-bit float */
+-void HELPER(ldeb)(uint32_t f1, uint64_t a2)
++void HELPER(ldeb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
+ {
+     uint32_t v2;
+ 
+-    v2 = ldl(a2);
++    v2 = cpu_ldl_data(env, a2);
+     env->fregs[f1].d = float32_to_float64(v2,
+                                           &env->fpu_status);
+ }
+ 
+ /* convert 64-bit float to 128-bit float */
+-void HELPER(lxdb)(uint32_t f1, uint64_t a2)
++void HELPER(lxdb)(CPUS390XState *env, uint32_t f1, uint64_t a2)
+ {
+     CPU_DoubleU v2;
+     CPU_QuadU v1;
+ 
+-    v2.ll = ldq(a2);
++    v2.ll = cpu_ldq_data(env, a2);
+     v1.q = float64_to_float128(v2.d, &env->fpu_status);
+     env->fregs[f1].ll = v1.ll.upper;
+     env->fregs[f1 + 2].ll = v1.ll.lower;
+ }
+ 
+ /* test data class 32-bit */
+-uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
++uint32_t HELPER(tceb)(CPUS390XState *env, uint32_t f1, uint64_t m2)
+ {
+     float32 v1 = env->fregs[f1].l.upper;
+     int neg = float32_is_neg(v1);
+@@ -785,7 +793,7 @@ uint32_t HELPER(tceb)(uint32_t f1, uint64_t m2)
+ }
+ 
+ /* test data class 64-bit */
+-uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
++uint32_t HELPER(tcdb)(CPUS390XState *env, uint32_t f1, uint64_t m2)
+ {
+     float64 v1 = env->fregs[f1].d;
+     int neg = float64_is_neg(v1);
+@@ -806,7 +814,7 @@ uint32_t HELPER(tcdb)(uint32_t f1, uint64_t m2)
+ }
+ 
+ /* test data class 128-bit */
+-uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
++uint32_t HELPER(tcxb)(CPUS390XState *env, uint32_t f1, uint64_t m2)
+ {
+     CPU_QuadU v1;
+     uint32_t cc = 0;
+@@ -830,7 +838,7 @@ uint32_t HELPER(tcxb)(uint32_t f1, uint64_t m2)
+ }
+ 
+ /* square root 64-bit RR */
+-void HELPER(sqdbr)(uint32_t f1, uint32_t f2)
++void HELPER(sqdbr)(CPUS390XState *env, uint32_t f1, uint32_t f2)
+ {
+     env->fregs[f1].d = float64_sqrt(env->fregs[f2].d, &env->fpu_status);
+ }
+diff --git a/target-s390x/helper.h b/target-s390x/helper.h
+index 01c8d0e..af98773 100644
+--- a/target-s390x/helper.h
++++ b/target-s390x/helper.h
+@@ -45,70 +45,70 @@ DEF_HELPER_3(mvcle, i32, i32, i64, i32)
+ DEF_HELPER_3(clcle, i32, i32, i64, i32)
+ DEF_HELPER_3(slb, i32, i32, i32, i32)
+ DEF_HELPER_4(slbg, i32, i32, i32, i64, i64)
+-DEF_HELPER_2(cefbr, void, i32, s32)
+-DEF_HELPER_2(cdfbr, void, i32, s32)
+-DEF_HELPER_2(cxfbr, void, i32, s32)
+-DEF_HELPER_2(cegbr, void, i32, s64)
+-DEF_HELPER_2(cdgbr, void, i32, s64)
+-DEF_HELPER_2(cxgbr, void, i32, s64)
+-DEF_HELPER_2(adbr, i32, i32, i32)
+-DEF_HELPER_2(aebr, i32, i32, i32)
+-DEF_HELPER_2(sebr, i32, i32, i32)
+-DEF_HELPER_2(sdbr, i32, i32, i32)
+-DEF_HELPER_2(debr, void, i32, i32)
+-DEF_HELPER_2(dxbr, void, i32, i32)
+-DEF_HELPER_2(mdbr, void, i32, i32)
+-DEF_HELPER_2(mxbr, void, i32, i32)
+-DEF_HELPER_2(ldebr, void, i32, i32)
+-DEF_HELPER_2(ldxbr, void, i32, i32)
+-DEF_HELPER_2(lxdbr, void, i32, i32)
+-DEF_HELPER_2(ledbr, void, i32, i32)
+-DEF_HELPER_2(lexbr, void, i32, i32)
+-DEF_HELPER_2(lpebr, i32, i32, i32)
+-DEF_HELPER_2(lpdbr, i32, i32, i32)
+-DEF_HELPER_2(lpxbr, i32, i32, i32)
+-DEF_HELPER_2(ltebr, i32, i32, i32)
+-DEF_HELPER_2(ltdbr, i32, i32, i32)
+-DEF_HELPER_2(ltxbr, i32, i32, i32)
+-DEF_HELPER_2(lcebr, i32, i32, i32)
+-DEF_HELPER_2(lcdbr, i32, i32, i32)
+-DEF_HELPER_2(lcxbr, i32, i32, i32)
+-DEF_HELPER_2(aeb, void, i32, i32)
+-DEF_HELPER_2(deb, void, i32, i32)
+-DEF_HELPER_2(meeb, void, i32, i32)
+-DEF_HELPER_2(cdb, i32, i32, i64)
+-DEF_HELPER_2(adb, i32, i32, i64)
+-DEF_HELPER_2(seb, void, i32, i32)
+-DEF_HELPER_2(sdb, i32, i32, i64)
+-DEF_HELPER_2(mdb, void, i32, i64)
+-DEF_HELPER_2(ddb, void, i32, i64)
+-DEF_HELPER_FLAGS_2(cebr, TCG_CALL_PURE, i32, i32, i32)
+-DEF_HELPER_FLAGS_2(cdbr, TCG_CALL_PURE, i32, i32, i32)
+-DEF_HELPER_FLAGS_2(cxbr, TCG_CALL_PURE, i32, i32, i32)
+-DEF_HELPER_3(cgebr, i32, i32, i32, i32)
+-DEF_HELPER_3(cgdbr, i32, i32, i32, i32)
+-DEF_HELPER_3(cgxbr, i32, i32, i32, i32)
+-DEF_HELPER_1(lzer, void, i32)
+-DEF_HELPER_1(lzdr, void, i32)
+-DEF_HELPER_1(lzxr, void, i32)
+-DEF_HELPER_3(cfebr, i32, i32, i32, i32)
+-DEF_HELPER_3(cfdbr, i32, i32, i32, i32)
+-DEF_HELPER_3(cfxbr, i32, i32, i32, i32)
+-DEF_HELPER_2(axbr, i32, i32, i32)
+-DEF_HELPER_2(sxbr, i32, i32, i32)
+-DEF_HELPER_2(meebr, void, i32, i32)
+-DEF_HELPER_2(ddbr, void, i32, i32)
+-DEF_HELPER_3(madb, void, i32, i64, i32)
+-DEF_HELPER_3(maebr, void, i32, i32, i32)
+-DEF_HELPER_3(madbr, void, i32, i32, i32)
+-DEF_HELPER_3(msdbr, void, i32, i32, i32)
+-DEF_HELPER_2(ldeb, void, i32, i64)
+-DEF_HELPER_2(lxdb, void, i32, i64)
+-DEF_HELPER_FLAGS_2(tceb, TCG_CALL_PURE, i32, i32, i64)
+-DEF_HELPER_FLAGS_2(tcdb, TCG_CALL_PURE, i32, i32, i64)
+-DEF_HELPER_FLAGS_2(tcxb, TCG_CALL_PURE, i32, i32, i64)
++DEF_HELPER_3(cefbr, void, env, i32, s32)
++DEF_HELPER_3(cdfbr, void, env, i32, s32)
++DEF_HELPER_3(cxfbr, void, env, i32, s32)
++DEF_HELPER_3(cegbr, void, env, i32, s64)
++DEF_HELPER_3(cdgbr, void, env, i32, s64)
++DEF_HELPER_3(cxgbr, void, env, i32, s64)
++DEF_HELPER_3(adbr, i32, env, i32, i32)
++DEF_HELPER_3(aebr, i32, env, i32, i32)
++DEF_HELPER_3(sebr, i32, env, i32, i32)
++DEF_HELPER_3(sdbr, i32, env, i32, i32)
++DEF_HELPER_3(debr, void, env, i32, i32)
++DEF_HELPER_3(dxbr, void, env, i32, i32)
++DEF_HELPER_3(mdbr, void, env, i32, i32)
++DEF_HELPER_3(mxbr, void, env, i32, i32)
++DEF_HELPER_3(ldebr, void, env, i32, i32)
++DEF_HELPER_3(ldxbr, void, env, i32, i32)
++DEF_HELPER_3(lxdbr, void, env, i32, i32)
++DEF_HELPER_3(ledbr, void, env, i32, i32)
++DEF_HELPER_3(lexbr, void, env, i32, i32)
++DEF_HELPER_3(lpebr, i32, env, i32, i32)
++DEF_HELPER_3(lpdbr, i32, env, i32, i32)
++DEF_HELPER_3(lpxbr, i32, env, i32, i32)
++DEF_HELPER_3(ltebr, i32, env, i32, i32)
++DEF_HELPER_3(ltdbr, i32, env, i32, i32)
++DEF_HELPER_3(ltxbr, i32, env, i32, i32)
++DEF_HELPER_3(lcebr, i32, env, i32, i32)
++DEF_HELPER_3(lcdbr, i32, env, i32, i32)
++DEF_HELPER_3(lcxbr, i32, env, i32, i32)
++DEF_HELPER_3(aeb, void, env, i32, i32)
++DEF_HELPER_3(deb, void, env, i32, i32)
++DEF_HELPER_3(meeb, void, env, i32, i32)
++DEF_HELPER_3(cdb, i32, env, i32, i64)
++DEF_HELPER_3(adb, i32, env, i32, i64)
++DEF_HELPER_3(seb, void, env, i32, i32)
++DEF_HELPER_3(sdb, i32, env, i32, i64)
++DEF_HELPER_3(mdb, void, env, i32, i64)
++DEF_HELPER_3(ddb, void, env, i32, i64)
++DEF_HELPER_FLAGS_3(cebr, TCG_CALL_PURE, i32, env, i32, i32)
++DEF_HELPER_FLAGS_3(cdbr, TCG_CALL_PURE, i32, env, i32, i32)
++DEF_HELPER_FLAGS_3(cxbr, TCG_CALL_PURE, i32, env, i32, i32)
++DEF_HELPER_4(cgebr, i32, env, i32, i32, i32)
++DEF_HELPER_4(cgdbr, i32, env, i32, i32, i32)
++DEF_HELPER_4(cgxbr, i32, env, i32, i32, i32)
++DEF_HELPER_2(lzer, void, env, i32)
++DEF_HELPER_2(lzdr, void, env, i32)
++DEF_HELPER_2(lzxr, void, env, i32)
++DEF_HELPER_4(cfebr, i32, env, i32, i32, i32)
++DEF_HELPER_4(cfdbr, i32, env, i32, i32, i32)
++DEF_HELPER_4(cfxbr, i32, env, i32, i32, i32)
++DEF_HELPER_3(axbr, i32, env, i32, i32)
++DEF_HELPER_3(sxbr, i32, env, i32, i32)
++DEF_HELPER_3(meebr, void, env, i32, i32)
++DEF_HELPER_3(ddbr, void, env, i32, i32)
++DEF_HELPER_4(madb, void, env, i32, i64, i32)
++DEF_HELPER_4(maebr, void, env, i32, i32, i32)
++DEF_HELPER_4(madbr, void, env, i32, i32, i32)
++DEF_HELPER_4(msdbr, void, env, i32, i32, i32)
++DEF_HELPER_3(ldeb, void, env, i32, i64)
++DEF_HELPER_3(lxdb, void, env, i32, i64)
++DEF_HELPER_FLAGS_3(tceb, TCG_CALL_PURE, i32, env, i32, i64)
++DEF_HELPER_FLAGS_3(tcdb, TCG_CALL_PURE, i32, env, i32, i64)
++DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_PURE, i32, env, i32, i64)
+ DEF_HELPER_2(flogr, i32, i32, i64)
+-DEF_HELPER_2(sqdbr, void, i32, i32)
++DEF_HELPER_3(sqdbr, void, env, i32, i32)
+ DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32)
+ DEF_HELPER_3(unpk, void, i32, i64, i64)
+ DEF_HELPER_3(tr, void, i32, i64, i64)
+diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
+index ba05e65..3f8b3ba 100644
+--- a/target-s390x/mem_helper.c
++++ b/target-s390x/mem_helper.c
+@@ -1188,3 +1188,52 @@ uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
+ }
+ 
+ #endif
++
++/* temporary wrappers */
++#if defined(CONFIG_USER_ONLY)
++#define ldub_data(addr) ldub_raw(addr)
++#define lduw_data(addr) lduw_raw(addr)
++#define ldl_data(addr) ldl_raw(addr)
++#define ldq_data(addr) ldq_raw(addr)
++
++#define stb_data(addr, data) stb_raw(addr, data)
++#define stw_data(addr, data) stw_raw(addr, data)
++#define stl_data(addr, data) stl_raw(addr, data)
++#define stq_data(addr, data) stq_raw(addr, data)
++#endif
++
++#define WRAP_LD(rettype, fn)                                    \
++    rettype cpu_ ## fn(CPUS390XState *env1, target_ulong addr)  \
++    {                                                           \
++        CPUS390XState *saved_env;                               \
++        rettype ret;                                            \
++                                                                \
++        saved_env = env;                                        \
++        env = env1;                                             \
++        ret = fn(addr);                                         \
++        env = saved_env;                                        \
++        return ret;                                             \
++    }
++
++WRAP_LD(uint32_t, ldub_data)
++WRAP_LD(uint32_t, lduw_data)
++WRAP_LD(uint32_t, ldl_data)
++WRAP_LD(uint64_t, ldq_data)
++#undef WRAP_LD
++
++#define WRAP_ST(datatype, fn)                                           \
++    void cpu_ ## fn(CPUS390XState *env1, target_ulong addr, datatype val) \
++    {                                                                   \
++        CPUS390XState *saved_env;                                       \
++                                                                        \
++        saved_env = env;                                                \
++        env = env1;                                                     \
++        fn(addr, val);                                                  \
++        env = saved_env;                                                \
++    }
++
++WRAP_ST(uint32_t, stb_data)
++WRAP_ST(uint32_t, stw_data)
++WRAP_ST(uint32_t, stl_data)
++WRAP_ST(uint64_t, stq_data)
++#undef WRAP_ST
+diff --git a/target-s390x/translate.c b/target-s390x/translate.c
+index c370df3..b1f2071 100644
+--- a/target-s390x/translate.c
++++ b/target-s390x/translate.c
+@@ -2206,11 +2206,11 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
+     switch (op) {
+     case 0x4: /* LDEB R1,D2(X2,B2) [RXE] */
+         potential_page_fault(s);
+-        gen_helper_ldeb(tmp_r1, addr);
++        gen_helper_ldeb(cpu_env, tmp_r1, addr);
+         break;
+     case 0x5: /* LXDB R1,D2(X2,B2) [RXE] */
+         potential_page_fault(s);
+-        gen_helper_lxdb(tmp_r1, addr);
++        gen_helper_lxdb(cpu_env, tmp_r1, addr);
+         break;
+     case 0x9: /* CEB    R1,D2(X2,B2)       [RXE] */
+         tmp = tcg_temp_new_i64();
+@@ -2225,7 +2225,7 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
+         tmp32 = tcg_temp_new_i32();
+         tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
+         tcg_gen_trunc_i64_i32(tmp32, tmp);
+-        gen_helper_aeb(tmp_r1, tmp32);
++        gen_helper_aeb(cpu_env, tmp_r1, tmp32);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32);
+ 
+@@ -2238,7 +2238,7 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
+         tmp32 = tcg_temp_new_i32();
+         tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
+         tcg_gen_trunc_i64_i32(tmp32, tmp);
+-        gen_helper_seb(tmp_r1, tmp32);
++        gen_helper_seb(cpu_env, tmp_r1, tmp32);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32);
+ 
+@@ -2251,23 +2251,23 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
+         tmp32 = tcg_temp_new_i32();
+         tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
+         tcg_gen_trunc_i64_i32(tmp32, tmp);
+-        gen_helper_deb(tmp_r1, tmp32);
++        gen_helper_deb(cpu_env, tmp_r1, tmp32);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32);
+         break;
+     case 0x10: /* TCEB   R1,D2(X2,B2)       [RXE] */
+         potential_page_fault(s);
+-        gen_helper_tceb(cc_op, tmp_r1, addr);
++        gen_helper_tceb(cc_op, cpu_env, tmp_r1, addr);
+         set_cc_static(s);
+         break;
+     case 0x11: /* TCDB   R1,D2(X2,B2)       [RXE] */
+         potential_page_fault(s);
+-        gen_helper_tcdb(cc_op, tmp_r1, addr);
++        gen_helper_tcdb(cc_op, cpu_env, tmp_r1, addr);
+         set_cc_static(s);
+         break;
+     case 0x12: /* TCXB   R1,D2(X2,B2)       [RXE] */
+         potential_page_fault(s);
+-        gen_helper_tcxb(cc_op, tmp_r1, addr);
++        gen_helper_tcxb(cc_op, cpu_env, tmp_r1, addr);
+         set_cc_static(s);
+         break;
+     case 0x17: /* MEEB   R1,D2(X2,B2)       [RXE] */
+@@ -2275,38 +2275,38 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
+         tmp32 = tcg_temp_new_i32();
+         tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
+         tcg_gen_trunc_i64_i32(tmp32, tmp);
+-        gen_helper_meeb(tmp_r1, tmp32);
++        gen_helper_meeb(cpu_env, tmp_r1, tmp32);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32);
+         break;
+     case 0x19: /* CDB    R1,D2(X2,B2)       [RXE] */
+         potential_page_fault(s);
+-        gen_helper_cdb(cc_op, tmp_r1, addr);
++        gen_helper_cdb(cc_op, cpu_env, tmp_r1, addr);
+         set_cc_static(s);
+         break;
+     case 0x1a: /* ADB    R1,D2(X2,B2)       [RXE] */
+         potential_page_fault(s);
+-        gen_helper_adb(cc_op, tmp_r1, addr);
++        gen_helper_adb(cc_op, cpu_env, tmp_r1, addr);
+         set_cc_static(s);
+         break;
+     case 0x1b: /* SDB    R1,D2(X2,B2)       [RXE] */
+         potential_page_fault(s);
+-        gen_helper_sdb(cc_op, tmp_r1, addr);
++        gen_helper_sdb(cc_op, cpu_env, tmp_r1, addr);
+         set_cc_static(s);
+         break;
+     case 0x1c: /* MDB    R1,D2(X2,B2)       [RXE] */
+         potential_page_fault(s);
+-        gen_helper_mdb(tmp_r1, addr);
++        gen_helper_mdb(cpu_env, tmp_r1, addr);
+         break;
+     case 0x1d: /* DDB    R1,D2(X2,B2)       [RXE] */
+         potential_page_fault(s);
+-        gen_helper_ddb(tmp_r1, addr);
++        gen_helper_ddb(cpu_env, tmp_r1, addr);
+         break;
+     case 0x1e: /* MADB  R1,R3,D2(X2,B2) [RXF] */
+         /* for RXF insns, r1 is R3 and r1b is R1 */
+         tmp32 = tcg_const_i32(r1b);
+         potential_page_fault(s);
+-        gen_helper_madb(tmp32, addr, tmp_r1);
++        gen_helper_madb(cpu_env, tmp32, addr, tmp_r1);
+         tcg_temp_free_i32(tmp32);
+         break;
+     default:
+@@ -3001,14 +3001,14 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+ #define FP_HELPER(i) \
+     tmp32_1 = tcg_const_i32(r1); \
+     tmp32_2 = tcg_const_i32(r2); \
+-    gen_helper_ ## i (tmp32_1, tmp32_2); \
++    gen_helper_ ## i(cpu_env, tmp32_1, tmp32_2); \
+     tcg_temp_free_i32(tmp32_1); \
+     tcg_temp_free_i32(tmp32_2);
+ 
+ #define FP_HELPER_CC(i) \
+     tmp32_1 = tcg_const_i32(r1); \
+     tmp32_2 = tcg_const_i32(r2); \
+-    gen_helper_ ## i (cc_op, tmp32_1, tmp32_2); \
++    gen_helper_ ## i(cc_op, cpu_env, tmp32_1, tmp32_2); \
+     set_cc_static(s); \
+     tcg_temp_free_i32(tmp32_1); \
+     tcg_temp_free_i32(tmp32_2);
+@@ -3080,13 +3080,13 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+         tmp32_3 = tcg_const_i32(r1);
+         switch (op) {
+         case 0xe:
+-            gen_helper_maebr(tmp32_1, tmp32_3, tmp32_2);
++            gen_helper_maebr(cpu_env, tmp32_1, tmp32_3, tmp32_2);
+             break;
+         case 0x1e:
+-            gen_helper_madbr(tmp32_1, tmp32_3, tmp32_2);
++            gen_helper_madbr(cpu_env, tmp32_1, tmp32_3, tmp32_2);
+             break;
+         case 0x1f:
+-            gen_helper_msdbr(tmp32_1, tmp32_3, tmp32_2);
++            gen_helper_msdbr(cpu_env, tmp32_1, tmp32_3, tmp32_2);
+             break;
+         default:
+             tcg_abort();
+@@ -3138,17 +3138,17 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+         break;
+     case 0x74: /* LZER        R1                [RRE] */
+         tmp32_1 = tcg_const_i32(r1);
+-        gen_helper_lzer(tmp32_1);
++        gen_helper_lzer(cpu_env, tmp32_1);
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x75: /* LZDR        R1                [RRE] */
+         tmp32_1 = tcg_const_i32(r1);
+-        gen_helper_lzdr(tmp32_1);
++        gen_helper_lzdr(cpu_env, tmp32_1);
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x76: /* LZXR        R1                [RRE] */
+         tmp32_1 = tcg_const_i32(r1);
+-        gen_helper_lzxr(tmp32_1);
++        gen_helper_lzxr(cpu_env, tmp32_1);
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x84: /* SFPC        R1                [RRE] */
+@@ -3169,13 +3169,13 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+         tmp32_2 = load_reg32(r2);
+         switch (op) {
+         case 0x94:
+-            gen_helper_cefbr(tmp32_1, tmp32_2);
++            gen_helper_cefbr(cpu_env, tmp32_1, tmp32_2);
+             break;
+         case 0x95:
+-            gen_helper_cdfbr(tmp32_1, tmp32_2);
++            gen_helper_cdfbr(cpu_env, tmp32_1, tmp32_2);
+             break;
+         case 0x96:
+-            gen_helper_cxfbr(tmp32_1, tmp32_2);
++            gen_helper_cxfbr(cpu_env, tmp32_1, tmp32_2);
+             break;
+         default:
+             tcg_abort();
+@@ -3191,13 +3191,13 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+         tmp32_3 = tcg_const_i32(m3);
+         switch (op) {
+         case 0x98:
+-            gen_helper_cfebr(cc_op, tmp32_1, tmp32_2, tmp32_3);
++            gen_helper_cfebr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
+             break;
+         case 0x99:
+-            gen_helper_cfdbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
++            gen_helper_cfdbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
+             break;
+         case 0x9a:
+-            gen_helper_cfxbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
++            gen_helper_cfxbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
+             break;
+         default:
+             tcg_abort();
+@@ -3213,10 +3213,10 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+         tmp = load_reg(r2);
+         switch (op) {
+         case 0xa4:
+-            gen_helper_cegbr(tmp32_1, tmp);
++            gen_helper_cegbr(cpu_env, tmp32_1, tmp);
+             break;
+         case 0xa5:
+-            gen_helper_cdgbr(tmp32_1, tmp);
++            gen_helper_cdgbr(cpu_env, tmp32_1, tmp);
+             break;
+         default:
+             tcg_abort();
+@@ -3227,7 +3227,7 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+     case 0xa6: /* CXGBR       R1,R2             [RRE] */
+         tmp32_1 = tcg_const_i32(r1);
+         tmp = load_reg(r2);
+-        gen_helper_cxgbr(tmp32_1, tmp);
++        gen_helper_cxgbr(cpu_env, tmp32_1, tmp);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i64(tmp);
+         break;
+@@ -3235,7 +3235,7 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r2);
+         tmp32_3 = tcg_const_i32(m3);
+-        gen_helper_cgebr(cc_op, tmp32_1, tmp32_2, tmp32_3);
++        gen_helper_cgebr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
+         set_cc_static(s);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -3245,7 +3245,7 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r2);
+         tmp32_3 = tcg_const_i32(m3);
+-        gen_helper_cgdbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
++        gen_helper_cgdbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
+         set_cc_static(s);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -3255,7 +3255,7 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r2);
+         tmp32_3 = tcg_const_i32(m3);
+-        gen_helper_cgxbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
++        gen_helper_cgxbr(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
+         set_cc_static(s);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+-- 
+1.7.12.1
+
diff --git a/0012-target-s390x-avoid-AREG0-for-integer-helpers.patch b/0012-target-s390x-avoid-AREG0-for-integer-helpers.patch
new file mode 100644
index 0000000..379d0f7
--- /dev/null
+++ b/0012-target-s390x-avoid-AREG0-for-integer-helpers.patch
@@ -0,0 +1,202 @@
+From d44b8c2cacaa50e7420f0dfaf42c344bcf134431 Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:37 +0000
+Subject: [PATCH] target-s390x: avoid AREG0 for integer helpers
+
+Make integer helpers take a parameter for CPUState instead
+of relying on global env.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/Makefile.objs |  1 -
+ target-s390x/helper.h      | 10 +++++-----
+ target-s390x/int_helper.c  | 12 ++++++------
+ target-s390x/translate.c   | 16 ++++++++--------
+ 4 files changed, 19 insertions(+), 20 deletions(-)
+
+diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
+index 7d965e9..7b2c5c1 100644
+--- a/target-s390x/Makefile.objs
++++ b/target-s390x/Makefile.objs
+@@ -3,7 +3,6 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-$(CONFIG_KVM) += kvm.o
+ 
+-$(obj)/int_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-s390x/helper.h b/target-s390x/helper.h
+index af98773..c03cd59 100644
+--- a/target-s390x/helper.h
++++ b/target-s390x/helper.h
+@@ -12,8 +12,8 @@ DEF_HELPER_FLAGS_1(set_cc_comp_s64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64)
+ DEF_HELPER_FLAGS_2(set_cc_icm, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32)
+ DEF_HELPER_3(clm, i32, i32, i32, i64)
+ DEF_HELPER_3(stcm, void, i32, i32, i64)
+-DEF_HELPER_2(mlg, void, i32, i64)
+-DEF_HELPER_2(dlg, void, i32, i64)
++DEF_HELPER_3(mlg, void, env, i32, i64)
++DEF_HELPER_3(dlg, void, env, i32, i64)
+ DEF_HELPER_FLAGS_3(set_cc_add64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64, s64, s64)
+ DEF_HELPER_FLAGS_3(set_cc_addu64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64)
+ DEF_HELPER_FLAGS_3(set_cc_add32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32, s32, s32)
+@@ -43,8 +43,8 @@ DEF_HELPER_3(stam, void, i32, i64, i32)
+ DEF_HELPER_3(lam, void, i32, i64, i32)
+ DEF_HELPER_3(mvcle, i32, i32, i64, i32)
+ DEF_HELPER_3(clcle, i32, i32, i64, i32)
+-DEF_HELPER_3(slb, i32, i32, i32, i32)
+-DEF_HELPER_4(slbg, i32, i32, i32, i64, i64)
++DEF_HELPER_4(slb, i32, env, i32, i32, i32)
++DEF_HELPER_5(slbg, i32, env, i32, i32, i64, i64)
+ DEF_HELPER_3(cefbr, void, env, i32, s32)
+ DEF_HELPER_3(cdfbr, void, env, i32, s32)
+ DEF_HELPER_3(cxfbr, void, env, i32, s32)
+@@ -107,7 +107,7 @@ DEF_HELPER_3(lxdb, void, env, i32, i64)
+ DEF_HELPER_FLAGS_3(tceb, TCG_CALL_PURE, i32, env, i32, i64)
+ DEF_HELPER_FLAGS_3(tcdb, TCG_CALL_PURE, i32, env, i32, i64)
+ DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_PURE, i32, env, i32, i64)
+-DEF_HELPER_2(flogr, i32, i32, i64)
++DEF_HELPER_3(flogr, i32, env, i32, i64)
+ DEF_HELPER_3(sqdbr, void, env, i32, i32)
+ DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32)
+ DEF_HELPER_3(unpk, void, i32, i64, i64)
+diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
+index e2eeb07..f202a7e 100644
+--- a/target-s390x/int_helper.c
++++ b/target-s390x/int_helper.c
+@@ -19,7 +19,6 @@
+  */
+ 
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "host-utils.h"
+ #include "helper.h"
+ 
+@@ -31,7 +30,7 @@
+ #endif
+ 
+ /* 64/64 -> 128 unsigned multiplication */
+-void HELPER(mlg)(uint32_t r1, uint64_t v2)
++void HELPER(mlg)(CPUS390XState *env, uint32_t r1, uint64_t v2)
+ {
+ #if HOST_LONG_BITS == 64 && defined(__GNUC__)
+     /* assuming 64-bit hosts have __uint128_t */
+@@ -46,7 +45,7 @@ void HELPER(mlg)(uint32_t r1, uint64_t v2)
+ }
+ 
+ /* 128 -> 64/64 unsigned division */
+-void HELPER(dlg)(uint32_t r1, uint64_t v2)
++void HELPER(dlg)(CPUS390XState *env, uint32_t r1, uint64_t v2)
+ {
+     uint64_t divisor = v2;
+ 
+@@ -129,7 +128,7 @@ uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
+ }
+ 
+ /* subtract unsigned v2 from v1 with borrow */
+-uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
++uint32_t HELPER(slb)(CPUS390XState *env, uint32_t cc, uint32_t r1, uint32_t v2)
+ {
+     uint32_t v1 = env->regs[r1];
+     uint32_t res = v1 + (~v2) + (cc >> 1);
+@@ -144,7 +143,8 @@ uint32_t HELPER(slb)(uint32_t cc, uint32_t r1, uint32_t v2)
+ }
+ 
+ /* subtract unsigned v2 from v1 with borrow */
+-uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
++uint32_t HELPER(slbg)(CPUS390XState *env, uint32_t cc, uint32_t r1,
++                      uint64_t v1, uint64_t v2)
+ {
+     uint64_t res = v1 + (~v2) + (cc >> 1);
+ 
+@@ -158,7 +158,7 @@ uint32_t HELPER(slbg)(uint32_t cc, uint32_t r1, uint64_t v1, uint64_t v2)
+ }
+ 
+ /* find leftmost one */
+-uint32_t HELPER(flogr)(uint32_t r1, uint64_t v2)
++uint32_t HELPER(flogr)(CPUS390XState *env, uint32_t r1, uint64_t v2)
+ {
+     uint64_t res = 0;
+     uint64_t ov2 = v2;
+diff --git a/target-s390x/translate.c b/target-s390x/translate.c
+index b1f2071..2a61e92 100644
+--- a/target-s390x/translate.c
++++ b/target-s390x/translate.c
+@@ -1803,7 +1803,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = tcg_const_i32(r1);
+         tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
+-        gen_helper_mlg(tmp32_1, tmp2);
++        gen_helper_mlg(cpu_env, tmp32_1, tmp2);
+         tcg_temp_free_i64(tmp2);
+         tcg_temp_free_i32(tmp32_1);
+         break;
+@@ -1811,7 +1811,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = tcg_const_i32(r1);
+         tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
+-        gen_helper_dlg(tmp32_1, tmp2);
++        gen_helper_dlg(cpu_env, tmp32_1, tmp2);
+         tcg_temp_free_i64(tmp2);
+         tcg_temp_free_i32(tmp32_1);
+         break;
+@@ -1837,7 +1837,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
+         tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
+         /* XXX possible optimization point */
+         gen_op_calc_cc(s);
+-        gen_helper_slbg(cc_op, cc_op, tmp32_1, regs[r1], tmp2);
++        gen_helper_slbg(cc_op, cpu_env, cc_op, tmp32_1, regs[r1], tmp2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp2);
+         tcg_temp_free_i32(tmp32_1);
+@@ -1917,7 +1917,7 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
+         tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
+         /* XXX possible optimization point */
+         gen_op_calc_cc(s);
+-        gen_helper_slb(cc_op, cc_op, tmp32_1, tmp32_2);
++        gen_helper_slb(cc_op, cpu_env, cc_op, tmp32_1, tmp32_2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp2);
+         tcg_temp_free_i32(tmp32_1);
+@@ -3535,7 +3535,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
+     case 0x83: /* FLOGR R1,R2 [RRE] */
+         tmp = load_reg(r2);
+         tmp32_1 = tcg_const_i32(r1);
+-        gen_helper_flogr(cc_op, tmp32_1, tmp);
++        gen_helper_flogr(cc_op, cpu_env, tmp32_1, tmp);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+@@ -3555,7 +3555,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
+     case 0x87: /* DLGR      R1,R2     [RRE] */
+         tmp32_1 = tcg_const_i32(r1);
+         tmp = load_reg(r2);
+-        gen_helper_dlg(tmp32_1, tmp);
++        gen_helper_dlg(cpu_env, tmp32_1, tmp);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+         break;
+@@ -3580,7 +3580,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
+         tmp2 = load_reg(r2);
+         tmp32_1 = tcg_const_i32(r1);
+         gen_op_calc_cc(s);
+-        gen_helper_slbg(cc_op, cc_op, tmp32_1, tmp, tmp2);
++        gen_helper_slbg(cc_op, cpu_env, cc_op, tmp32_1, tmp, tmp2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i64(tmp2);
+@@ -3647,7 +3647,7 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
+         tmp32_1 = load_reg32(r2);
+         tmp32_2 = tcg_const_i32(r1);
+         gen_op_calc_cc(s);
+-        gen_helper_slb(cc_op, cc_op, tmp32_2, tmp32_1);
++        gen_helper_slb(cc_op, cpu_env, cc_op, tmp32_2, tmp32_1);
+         set_cc_static(s);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+-- 
+1.7.12.1
+
diff --git a/0013-target-s390x-avoid-AREG0-for-condition-code-helpers.patch b/0013-target-s390x-avoid-AREG0-for-condition-code-helpers.patch
new file mode 100644
index 0000000..eddecbb
--- /dev/null
+++ b/0013-target-s390x-avoid-AREG0-for-condition-code-helpers.patch
@@ -0,0 +1,190 @@
+From ead7a100e907eddd0ba9f3cebb5f84c1afb120b8 Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:38 +0000
+Subject: [PATCH] target-s390x: avoid AREG0 for condition code helpers
+
+Make condition code helpers take a parameter for CPUState instead
+of relying on global env.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/Makefile.objs |  1 -
+ target-s390x/cc_helper.c   | 11 +++++------
+ target-s390x/helper.h      | 10 +++++-----
+ target-s390x/translate.c   | 16 ++++++++--------
+ 4 files changed, 18 insertions(+), 20 deletions(-)
+
+diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
+index 7b2c5c1..736cf33 100644
+--- a/target-s390x/Makefile.objs
++++ b/target-s390x/Makefile.objs
+@@ -3,6 +3,5 @@ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-$(CONFIG_KVM) += kvm.o
+ 
+-$(obj)/cc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+ $(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
+index 9c3a2c4..19ef145 100644
+--- a/target-s390x/cc_helper.c
++++ b/target-s390x/cc_helper.c
+@@ -19,7 +19,6 @@
+  */
+ 
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "helper.h"
+ 
+ /* #define DEBUG_HELPER */
+@@ -500,14 +499,14 @@ uint32_t calc_cc(CPUS390XState *env, uint32_t cc_op, uint64_t src, uint64_t dst,
+     return do_calc_cc(env, cc_op, src, dst, vr);
+ }
+ 
+-uint32_t HELPER(calc_cc)(uint32_t cc_op, uint64_t src, uint64_t dst,
+-                         uint64_t vr)
++uint32_t HELPER(calc_cc)(CPUS390XState *env, uint32_t cc_op, uint64_t src,
++                         uint64_t dst, uint64_t vr)
+ {
+     return do_calc_cc(env, cc_op, src, dst, vr);
+ }
+ 
+ /* insert psw mask and condition code into r1 */
+-void HELPER(ipm)(uint32_t cc, uint32_t r1)
++void HELPER(ipm)(CPUS390XState *env, uint32_t cc, uint32_t r1)
+ {
+     uint64_t r = env->regs[r1];
+ 
+@@ -519,13 +518,13 @@ void HELPER(ipm)(uint32_t cc, uint32_t r1)
+ }
+ 
+ #ifndef CONFIG_USER_ONLY
+-void HELPER(load_psw)(uint64_t mask, uint64_t addr)
++void HELPER(load_psw)(CPUS390XState *env, uint64_t mask, uint64_t addr)
+ {
+     load_psw(env, mask, addr);
+     cpu_loop_exit(env);
+ }
+ 
+-void HELPER(sacf)(uint64_t a1)
++void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
+ {
+     HELPER_LOG("%s: %16" PRIx64 "\n", __func__, a1);
+ 
+diff --git a/target-s390x/helper.h b/target-s390x/helper.h
+index c03cd59..876b88e 100644
+--- a/target-s390x/helper.h
++++ b/target-s390x/helper.h
+@@ -36,7 +36,7 @@ DEF_HELPER_FLAGS_1(abs_i64, TCG_CALL_PURE|TCG_CALL_CONST, i64, s64)
+ DEF_HELPER_FLAGS_1(nabs_i64, TCG_CALL_PURE|TCG_CALL_CONST, s64, s64)
+ DEF_HELPER_3(stcmh, void, i32, i64, i32)
+ DEF_HELPER_3(icmh, i32, i32, i64, i32)
+-DEF_HELPER_2(ipm, void, i32, i32)
++DEF_HELPER_3(ipm, void, env, i32, i32)
+ DEF_HELPER_FLAGS_3(addc_u32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32, i32)
+ DEF_HELPER_FLAGS_3(set_cc_addc_u64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64)
+ DEF_HELPER_3(stam, void, i32, i64, i32)
+@@ -115,7 +115,7 @@ DEF_HELPER_3(tr, void, i32, i64, i64)
+ 
+ DEF_HELPER_2(servc, i32, i32, i64)
+ DEF_HELPER_3(diag, i64, i32, i64, i64)
+-DEF_HELPER_2(load_psw, void, i64, i64)
++DEF_HELPER_3(load_psw, void, env, i64, i64)
+ DEF_HELPER_1(program_interrupt, void, i32)
+ DEF_HELPER_FLAGS_1(stidp, TCG_CALL_CONST, void, i64)
+ DEF_HELPER_FLAGS_1(spx, TCG_CALL_CONST, void, i64)
+@@ -139,14 +139,14 @@ DEF_HELPER_2(csp, i32, i32, i32)
+ DEF_HELPER_3(mvcs, i32, i64, i64, i64)
+ DEF_HELPER_3(mvcp, i32, i64, i64, i64)
+ DEF_HELPER_3(sigp, i32, i64, i32, i64)
+-DEF_HELPER_1(sacf, void, i64)
++DEF_HELPER_2(sacf, void, env, i64)
+ DEF_HELPER_FLAGS_2(ipte, TCG_CALL_CONST, void, i64, i64)
+ DEF_HELPER_FLAGS_0(ptlb, TCG_CALL_CONST, void)
+ DEF_HELPER_2(lra, i32, i64, i32)
+ DEF_HELPER_2(stura, void, i64, i32)
+ DEF_HELPER_2(cksm, void, i32, i32)
+ 
+-DEF_HELPER_FLAGS_4(calc_cc, TCG_CALL_PURE|TCG_CALL_CONST,
+-                   i32, i32, i64, i64, i64)
++DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_PURE|TCG_CALL_CONST,
++                   i32, env, i32, i64, i64, i64)
+ 
+ #include "def-helper.h"
+diff --git a/target-s390x/translate.c b/target-s390x/translate.c
+index 2a61e92..1d87272 100644
+--- a/target-s390x/translate.c
++++ b/target-s390x/translate.c
+@@ -722,7 +722,7 @@ static void gen_op_calc_cc(DisasContext *s)
+     case CC_OP_NZ_F32:
+     case CC_OP_NZ_F64:
+         /* 1 argument */
+-        gen_helper_calc_cc(cc_op, local_cc_op, dummy, cc_dst, dummy);
++        gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, dummy, cc_dst, dummy);
+         break;
+     case CC_OP_ICM:
+     case CC_OP_LTGT_32:
+@@ -735,7 +735,7 @@ static void gen_op_calc_cc(DisasContext *s)
+     case CC_OP_LTGT_F64:
+     case CC_OP_SLAG:
+         /* 2 arguments */
+-        gen_helper_calc_cc(cc_op, local_cc_op, cc_src, cc_dst, dummy);
++        gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, dummy);
+         break;
+     case CC_OP_ADD_64:
+     case CC_OP_ADDU_64:
+@@ -746,11 +746,11 @@ static void gen_op_calc_cc(DisasContext *s)
+     case CC_OP_SUB_32:
+     case CC_OP_SUBU_32:
+         /* 3 arguments */
+-        gen_helper_calc_cc(cc_op, local_cc_op, cc_src, cc_dst, cc_vr);
++        gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, cc_vr);
+         break;
+     case CC_OP_DYNAMIC:
+         /* unknown operation - assume 3 arguments and cc_op in env */
+-        gen_helper_calc_cc(cc_op, cc_op, cc_src, cc_dst, cc_vr);
++        gen_helper_calc_cc(cc_op, cpu_env, cc_op, cc_src, cc_dst, cc_vr);
+         break;
+     default:
+         tcg_abort();
+@@ -2628,7 +2628,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+     case 0x22: /* IPM    R1               [RRE] */
+         tmp32_1 = tcg_const_i32(r1);
+         gen_op_calc_cc(s);
+-        gen_helper_ipm(cc_op, tmp32_1);
++        gen_helper_ipm(cpu_env, cc_op, tmp32_1);
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x41: /* CKSM    R1,R2     [RRE] */
+@@ -2916,7 +2916,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+-        gen_helper_sacf(tmp);
++        gen_helper_sacf(cpu_env, tmp);
+         tcg_temp_free_i64(tmp);
+         /* addressing mode has changed, so end the block */
+         s->pc += ilc * 2;
+@@ -2967,7 +2967,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         tcg_gen_qemu_ld64(tmp2, tmp, get_mem_index(s));
+         tcg_gen_addi_i64(tmp, tmp, 8);
+         tcg_gen_qemu_ld64(tmp3, tmp, get_mem_index(s));
+-        gen_helper_load_psw(tmp2, tmp3);
++        gen_helper_load_psw(cpu_env, tmp2, tmp3);
+         /* we need to keep cc_op intact */
+         s->is_jmp = DISAS_JUMP;
+         tcg_temp_free_i64(tmp);
+@@ -4527,7 +4527,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
+         tcg_gen_addi_i64(tmp, tmp, 4);
+         tcg_gen_qemu_ld32u(tmp3, tmp, get_mem_index(s));
+-        gen_helper_load_psw(tmp2, tmp3);
++        gen_helper_load_psw(cpu_env, tmp2, tmp3);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i64(tmp2);
+         tcg_temp_free_i64(tmp3);
+-- 
+1.7.12.1
+
diff --git a/0014-target-s390x-avoid-AREG0-for-misc-helpers.patch b/0014-target-s390x-avoid-AREG0-for-misc-helpers.patch
new file mode 100644
index 0000000..11ff8fb
--- /dev/null
+++ b/0014-target-s390x-avoid-AREG0-for-misc-helpers.patch
@@ -0,0 +1,411 @@
+From 208547c7afbe6ee8a9a1f81095e67a6cbe4a37ec Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:39 +0000
+Subject: [PATCH] target-s390x: avoid AREG0 for misc helpers
+
+Make misc helpers take a parameter for CPUState instead
+of relying on global env.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+[agraf: fix conflict]
+Signed-off-by: Alexander Graf <agraf at suse.de>
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/Makefile.objs |  1 -
+ target-s390x/helper.h      | 26 +++++++++++-----------
+ target-s390x/mem_helper.c  |  2 +-
+ target-s390x/misc_helper.c | 55 +++++++++++++++++++++++++---------------------
+ target-s390x/translate.c   | 32 +++++++++++++--------------
+ 5 files changed, 60 insertions(+), 56 deletions(-)
+
+diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
+index 736cf33..156d946 100644
+--- a/target-s390x/Makefile.objs
++++ b/target-s390x/Makefile.objs
+@@ -4,4 +4,3 @@ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-$(CONFIG_KVM) += kvm.o
+ 
+ $(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+-$(obj)/misc_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-s390x/helper.h b/target-s390x/helper.h
+index 876b88e..f4e0b37 100644
+--- a/target-s390x/helper.h
++++ b/target-s390x/helper.h
+@@ -1,6 +1,6 @@
+ #include "def-helper.h"
+ 
+-DEF_HELPER_1(exception, void, i32)
++DEF_HELPER_2(exception, void, env, i32)
+ DEF_HELPER_3(nc, i32, i32, i64, i64)
+ DEF_HELPER_3(oc, i32, i32, i64, i64)
+ DEF_HELPER_3(xc, i32, i32, i64, i64)
+@@ -113,20 +113,20 @@ DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32)
+ DEF_HELPER_3(unpk, void, i32, i64, i64)
+ DEF_HELPER_3(tr, void, i32, i64, i64)
+ 
+-DEF_HELPER_2(servc, i32, i32, i64)
+-DEF_HELPER_3(diag, i64, i32, i64, i64)
++DEF_HELPER_3(servc, i32, env, i32, i64)
++DEF_HELPER_4(diag, i64, env, i32, i64, i64)
+ DEF_HELPER_3(load_psw, void, env, i64, i64)
+ DEF_HELPER_1(program_interrupt, void, i32)
+-DEF_HELPER_FLAGS_1(stidp, TCG_CALL_CONST, void, i64)
+-DEF_HELPER_FLAGS_1(spx, TCG_CALL_CONST, void, i64)
++DEF_HELPER_FLAGS_2(stidp, TCG_CALL_CONST, void, env, i64)
++DEF_HELPER_FLAGS_2(spx, TCG_CALL_CONST, void, env, i64)
+ DEF_HELPER_FLAGS_1(sck, TCG_CALL_CONST, i32, i64)
+-DEF_HELPER_1(stck, i32, i64)
+-DEF_HELPER_1(stcke, i32, i64)
+-DEF_HELPER_FLAGS_1(sckc, TCG_CALL_CONST, void, i64)
+-DEF_HELPER_FLAGS_1(stckc, TCG_CALL_CONST, void, i64)
+-DEF_HELPER_FLAGS_1(spt, TCG_CALL_CONST, void, i64)
+-DEF_HELPER_FLAGS_1(stpt, TCG_CALL_CONST, void, i64)
+-DEF_HELPER_3(stsi, i32, i64, i32, i32)
++DEF_HELPER_2(stck, i32, env, i64)
++DEF_HELPER_2(stcke, i32, env, i64)
++DEF_HELPER_FLAGS_2(sckc, TCG_CALL_CONST, void, env, i64)
++DEF_HELPER_FLAGS_2(stckc, TCG_CALL_CONST, void, env, i64)
++DEF_HELPER_FLAGS_2(spt, TCG_CALL_CONST, void, env, i64)
++DEF_HELPER_FLAGS_2(stpt, TCG_CALL_CONST, void, env, i64)
++DEF_HELPER_4(stsi, i32, env, i64, i32, i32)
+ DEF_HELPER_3(lctl, void, i32, i64, i32)
+ DEF_HELPER_3(lctlg, void, i32, i64, i32)
+ DEF_HELPER_3(stctl, void, i32, i64, i32)
+@@ -138,7 +138,7 @@ DEF_HELPER_FLAGS_2(rrbe, TCG_CALL_CONST, i32, i32, i64)
+ DEF_HELPER_2(csp, i32, i32, i32)
+ DEF_HELPER_3(mvcs, i32, i64, i64, i64)
+ DEF_HELPER_3(mvcp, i32, i64, i64, i64)
+-DEF_HELPER_3(sigp, i32, i64, i32, i64)
++DEF_HELPER_4(sigp, i32, env, i64, i32, i64)
+ DEF_HELPER_2(sacf, void, env, i64)
+ DEF_HELPER_FLAGS_2(ipte, TCG_CALL_CONST, void, i64, i64)
+ DEF_HELPER_FLAGS_0(ptlb, TCG_CALL_CONST, void)
+diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
+index 3f8b3ba..52f2602 100644
+--- a/target-s390x/mem_helper.c
++++ b/target-s390x/mem_helper.c
+@@ -595,7 +595,7 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+         env->psw.addr = ret - 4;
+         env->int_svc_code = (insn | v1) & 0xff;
+         env->int_svc_ilc = 4;
+-        helper_exception(EXCP_SVC);
++        helper_exception(env, EXCP_SVC);
+     } else if ((insn & 0xff00) == 0xbf00) {
+         uint32_t insn2, r1, r3, b2, d2;
+ 
+diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
+index 1d5137f..ced26c6 100644
+--- a/target-s390x/misc_helper.c
++++ b/target-s390x/misc_helper.c
+@@ -21,7 +21,6 @@
+ #include "cpu.h"
+ #include "memory.h"
+ #include "cputlb.h"
+-#include "dyngen-exec.h"
+ #include "host-utils.h"
+ #include "helper.h"
+ #include <string.h>
+@@ -32,7 +31,10 @@
+ #endif
+ 
+ #if !defined(CONFIG_USER_ONLY)
++/* temporarily disabled due to wrapper use */
++#if 0
+ #include "softmmu_exec.h"
++#endif
+ #include "sysemu.h"
+ #endif
+ 
+@@ -44,7 +46,7 @@
+ #endif
+ 
+ /* raise an exception */
+-void HELPER(exception)(uint32_t excp)
++void HELPER(exception)(CPUS390XState *env, uint32_t excp)
+ {
+     HELPER_LOG("%s: exception %d\n", __func__, excp);
+     env->exception_index = excp;
+@@ -112,7 +114,7 @@ int sclp_service_call(CPUS390XState *env, uint32_t sccb, uint64_t code)
+ }
+ 
+ /* SCLP service call */
+-uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
++uint32_t HELPER(servc)(CPUS390XState *env, uint32_t r1, uint64_t r2)
+ {
+     int r;
+ 
+@@ -125,7 +127,8 @@ uint32_t HELPER(servc)(uint32_t r1, uint64_t r2)
+ }
+ 
+ /* DIAG */
+-uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
++uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
++                      uint64_t code)
+ {
+     uint64_t r;
+ 
+@@ -155,17 +158,17 @@ uint64_t HELPER(diag)(uint32_t num, uint64_t mem, uint64_t code)
+ }
+ 
+ /* Store CPU ID */
+-void HELPER(stidp)(uint64_t a1)
++void HELPER(stidp)(CPUS390XState *env, uint64_t a1)
+ {
+-    stq(a1, env->cpu_num);
++    cpu_stq_data(env, a1, env->cpu_num);
+ }
+ 
+ /* Set Prefix */
+-void HELPER(spx)(uint64_t a1)
++void HELPER(spx)(CPUS390XState *env, uint64_t a1)
+ {
+     uint32_t prefix;
+ 
+-    prefix = ldl(a1);
++    prefix = cpu_ldl_data(env, a1);
+     env->psa = prefix & 0xfffff000;
+     qemu_log("prefix: %#x\n", prefix);
+     tlb_flush_page(env, 0);
+@@ -191,31 +194,31 @@ static inline uint64_t clock_value(CPUS390XState *env)
+ }
+ 
+ /* Store Clock */
+-uint32_t HELPER(stck)(uint64_t a1)
++uint32_t HELPER(stck)(CPUS390XState *env, uint64_t a1)
+ {
+-    stq(a1, clock_value(env));
++    cpu_stq_data(env, a1, clock_value(env));
+ 
+     return 0;
+ }
+ 
+ /* Store Clock Extended */
+-uint32_t HELPER(stcke)(uint64_t a1)
++uint32_t HELPER(stcke)(CPUS390XState *env, uint64_t a1)
+ {
+-    stb(a1, 0);
++    cpu_stb_data(env, a1, 0);
+     /* basically the same value as stck */
+-    stq(a1 + 1, clock_value(env) | env->cpu_num);
++    cpu_stq_data(env, a1 + 1, clock_value(env) | env->cpu_num);
+     /* more fine grained than stck */
+-    stq(a1 + 9, 0);
++    cpu_stq_data(env, a1 + 9, 0);
+     /* XXX programmable fields */
+-    stw(a1 + 17, 0);
++    cpu_stw_data(env, a1 + 17, 0);
+ 
+     return 0;
+ }
+ 
+ /* Set Clock Comparator */
+-void HELPER(sckc)(uint64_t a1)
++void HELPER(sckc)(CPUS390XState *env, uint64_t a1)
+ {
+-    uint64_t time = ldq(a1);
++    uint64_t time = cpu_ldq_data(env, a1);
+ 
+     if (time == -1ULL) {
+         return;
+@@ -230,16 +233,16 @@ void HELPER(sckc)(uint64_t a1)
+ }
+ 
+ /* Store Clock Comparator */
+-void HELPER(stckc)(uint64_t a1)
++void HELPER(stckc)(CPUS390XState *env, uint64_t a1)
+ {
+     /* XXX implement */
+-    stq(a1, 0);
++    cpu_stq_data(env, a1, 0);
+ }
+ 
+ /* Set CPU Timer */
+-void HELPER(spt)(uint64_t a1)
++void HELPER(spt)(CPUS390XState *env, uint64_t a1)
+ {
+-    uint64_t time = ldq(a1);
++    uint64_t time = cpu_ldq_data(env, a1);
+ 
+     if (time == -1ULL) {
+         return;
+@@ -252,14 +255,15 @@ void HELPER(spt)(uint64_t a1)
+ }
+ 
+ /* Store CPU Timer */
+-void HELPER(stpt)(uint64_t a1)
++void HELPER(stpt)(CPUS390XState *env, uint64_t a1)
+ {
+     /* XXX implement */
+-    stq(a1, 0);
++    cpu_stq_data(env, a1, 0);
+ }
+ 
+ /* Store System Information */
+-uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
++uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint32_t r0,
++                      uint32_t r1)
+ {
+     int cc = 0;
+     int sel1, sel2;
+@@ -384,7 +388,8 @@ uint32_t HELPER(stsi)(uint64_t a0, uint32_t r0, uint32_t r1)
+     return cc;
+ }
+ 
+-uint32_t HELPER(sigp)(uint64_t order_code, uint32_t r1, uint64_t cpu_addr)
++uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1,
++                      uint64_t cpu_addr)
+ {
+     int cc = 0;
+ 
+diff --git a/target-s390x/translate.c b/target-s390x/translate.c
+index 1d87272..0c61e63 100644
+--- a/target-s390x/translate.c
++++ b/target-s390x/translate.c
+@@ -312,7 +312,7 @@ static inline void gen_debug(DisasContext *s)
+     TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
+     update_psw_addr(s);
+     gen_op_calc_cc(s);
+-    gen_helper_exception(tmp);
++    gen_helper_exception(cpu_env, tmp);
+     tcg_temp_free_i32(tmp);
+     s->is_jmp = DISAS_EXCP;
+ }
+@@ -324,7 +324,7 @@ static void gen_illegal_opcode(DisasContext *s, int ilc)
+     TCGv_i32 tmp = tcg_const_i32(EXCP_SPEC);
+     update_psw_addr(s);
+     gen_op_calc_cc(s);
+-    gen_helper_exception(tmp);
++    gen_helper_exception(cpu_env, tmp);
+     tcg_temp_free_i32(tmp);
+     s->is_jmp = DISAS_EXCP;
+ }
+@@ -377,7 +377,7 @@ static void gen_program_exception(DisasContext *s, int ilc, int code)
+ 
+     /* trigger exception */
+     tmp = tcg_const_i32(EXCP_PGM);
+-    gen_helper_exception(tmp);
++    gen_helper_exception(cpu_env, tmp);
+     tcg_temp_free_i32(tmp);
+ 
+     /* end TB here */
+@@ -2712,7 +2712,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+-        gen_helper_stidp(tmp);
++        gen_helper_stidp(cpu_env, tmp);
+         tcg_temp_free_i64(tmp);
+         break;
+     case 0x04: /* SCK       D2(B2)     [S] */
+@@ -2730,7 +2730,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+-        gen_helper_stck(cc_op, tmp);
++        gen_helper_stck(cc_op, cpu_env, tmp);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         break;
+@@ -2740,7 +2740,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+-        gen_helper_sckc(tmp);
++        gen_helper_sckc(cpu_env, tmp);
+         tcg_temp_free_i64(tmp);
+         break;
+     case 0x07: /* STCKC    D2(B2)     [S] */
+@@ -2749,7 +2749,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+-        gen_helper_stckc(tmp);
++        gen_helper_stckc(cpu_env, tmp);
+         tcg_temp_free_i64(tmp);
+         break;
+     case 0x08: /* SPT      D2(B2)     [S] */
+@@ -2758,7 +2758,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+-        gen_helper_spt(tmp);
++        gen_helper_spt(cpu_env, tmp);
+         tcg_temp_free_i64(tmp);
+         break;
+     case 0x09: /* STPT     D2(B2)     [S] */
+@@ -2767,7 +2767,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+-        gen_helper_stpt(tmp);
++        gen_helper_stpt(cpu_env, tmp);
+         tcg_temp_free_i64(tmp);
+         break;
+     case 0x0a: /* SPKA     D2(B2)     [S] */
+@@ -2793,7 +2793,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+-        gen_helper_spx(tmp);
++        gen_helper_spx(cpu_env, tmp);
+         tcg_temp_free_i64(tmp);
+         break;
+     case 0x11: /* STPX     D2(B2)     [S] */
+@@ -2906,7 +2906,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+-        gen_helper_stcke(cc_op, tmp);
++        gen_helper_stcke(cc_op, cpu_env, tmp);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         break;
+@@ -2930,7 +2930,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         tmp32_1 = load_reg32(0);
+         tmp32_2 = load_reg32(1);
+         potential_page_fault(s);
+-        gen_helper_stsi(cc_op, tmp, tmp32_1, tmp32_2);
++        gen_helper_stsi(cc_op, cpu_env, tmp, tmp32_1, tmp32_2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+@@ -2980,7 +2980,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         potential_page_fault(s);
+         tmp32_1 = load_reg32(r2);
+         tmp = load_reg(r1);
+-        gen_helper_servc(cc_op, tmp32_1, tmp);
++        gen_helper_servc(cc_op, cpu_env, tmp32_1, tmp);
+         set_cc_static(s);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i64(tmp);
+@@ -3926,7 +3926,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_3 = tcg_const_i32(EXCP_SVC);
+         tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUS390XState, int_svc_code));
+         tcg_gen_st_i32(tmp32_2, cpu_env, offsetof(CPUS390XState, int_svc_ilc));
+-        gen_helper_exception(tmp32_3);
++        gen_helper_exception(cpu_env, tmp32_3);
+         s->is_jmp = DISAS_EXCP;
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -4543,7 +4543,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = tcg_const_i32(insn & 0xfff);
+         tmp2 = load_reg(2);
+         tmp3 = load_reg(1);
+-        gen_helper_diag(tmp2, tmp32_1, tmp2, tmp3);
++        gen_helper_diag(tmp2, cpu_env, tmp32_1, tmp2, tmp3);
+         store_reg(2, tmp2);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i64(tmp2);
+@@ -4777,7 +4777,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp2 = load_reg(r3);
+         tmp32_1 = tcg_const_i32(r1);
+         potential_page_fault(s);
+-        gen_helper_sigp(cc_op, tmp, tmp32_1, tmp2);
++        gen_helper_sigp(cc_op, cpu_env, tmp, tmp32_1, tmp2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i64(tmp2);
+-- 
+1.7.12.1
+
diff --git a/0015-target-s390x-switch-to-AREG0-free-mode.patch b/0015-target-s390x-switch-to-AREG0-free-mode.patch
new file mode 100644
index 0000000..2329cb2
--- /dev/null
+++ b/0015-target-s390x-switch-to-AREG0-free-mode.patch
@@ -0,0 +1,1584 @@
+From 77fb132a1dc3780a57d8a1e889b366f0492963a5 Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:33:40 +0000
+Subject: [PATCH] target-s390x: switch to AREG0 free mode
+
+Add an explicit CPUState parameter instead of relying on AREG0.
+
+Remove temporary wrappers and switch to AREG0 free mode.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+[agraf: fix conflicts]
+Signed-off-by: Alexander Graf <agraf at suse.de>
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure                  |   2 +-
+ target-s390x/Makefile.objs |   2 -
+ target-s390x/cpu.h         |  10 --
+ target-s390x/fpu_helper.c  |   3 +-
+ target-s390x/helper.c      |   6 +-
+ target-s390x/helper.h      |  78 +++++------
+ target-s390x/mem_helper.c  | 338 ++++++++++++++++++++-------------------------
+ target-s390x/misc_helper.c |   3 -
+ target-s390x/translate.c   |  88 ++++++------
+ 9 files changed, 239 insertions(+), 291 deletions(-)
+
+diff --git a/configure b/configure
+index bf3acc8..3ad6f74 100755
+--- a/configure
++++ b/configure
+@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+ 
+ 
+ case "$target_arch2" in
+-  alpha | i386 | or32 | sparc* | x86_64 | xtensa* | ppc*)
++  alpha | i386 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
+     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
+   ;;
+ esac
+diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
+index 156d946..e728abf 100644
+--- a/target-s390x/Makefile.objs
++++ b/target-s390x/Makefile.objs
+@@ -2,5 +2,3 @@ obj-y += translate.o helper.o cpu.o interrupt.o
+ obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-$(CONFIG_KVM) += kvm.o
+-
+-$(obj)/mem_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
+index 9b7a2e3..ed81af3 100644
+--- a/target-s390x/cpu.h
++++ b/target-s390x/cpu.h
+@@ -1008,14 +1008,4 @@ uint32_t set_cc_nz_f64(float64 v);
+ /* misc_helper.c */
+ void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
+ 
+-/* temporary wrappers */
+-uint32_t cpu_ldub_data(CPUS390XState *env, target_ulong ptr);
+-uint32_t cpu_lduw_data(CPUS390XState *env, target_ulong ptr);
+-uint32_t cpu_ldl_data(CPUS390XState *env, target_ulong ptr);
+-uint64_t cpu_ldq_data(CPUS390XState *env, target_ulong ptr);
+-
+-void cpu_stb_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
+-void cpu_stw_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
+-void cpu_stl_data(CPUS390XState *env, target_ulong ptr, uint32_t data);
+-void cpu_stq_data(CPUS390XState *env, target_ulong ptr, uint64_t data);
+ #endif
+diff --git a/target-s390x/fpu_helper.c b/target-s390x/fpu_helper.c
+index e235419..ee9420d 100644
+--- a/target-s390x/fpu_helper.c
++++ b/target-s390x/fpu_helper.c
+@@ -21,8 +21,7 @@
+ #include "cpu.h"
+ #include "helper.h"
+ 
+-/* temporarily disabled due to wrapper use */
+-#if 0 && !defined(CONFIG_USER_ONLY)
++#if !defined(CONFIG_USER_ONLY)
+ #include "softmmu_exec.h"
+ #endif
+ 
+diff --git a/target-s390x/helper.c b/target-s390x/helper.c
+index d98e6d9..a5741ec 100644
+--- a/target-s390x/helper.c
++++ b/target-s390x/helper.c
+@@ -499,14 +499,14 @@ static void do_program_interrupt(CPUS390XState *env)
+ 
+     switch (ilc) {
+     case ILC_LATER:
+-        ilc = get_ilc(ldub_code(env->psw.addr));
++        ilc = get_ilc(cpu_ldub_code(env, env->psw.addr));
+         break;
+     case ILC_LATER_INC:
+-        ilc = get_ilc(ldub_code(env->psw.addr));
++        ilc = get_ilc(cpu_ldub_code(env, env->psw.addr));
+         env->psw.addr += ilc * 2;
+         break;
+     case ILC_LATER_INC_2:
+-        ilc = get_ilc(ldub_code(env->psw.addr)) * 2;
++        ilc = get_ilc(cpu_ldub_code(env, env->psw.addr)) * 2;
+         env->psw.addr += ilc;
+         break;
+     }
+diff --git a/target-s390x/helper.h b/target-s390x/helper.h
+index f4e0b37..5419f37 100644
+--- a/target-s390x/helper.h
++++ b/target-s390x/helper.h
+@@ -1,17 +1,17 @@
+ #include "def-helper.h"
+ 
+ DEF_HELPER_2(exception, void, env, i32)
+-DEF_HELPER_3(nc, i32, i32, i64, i64)
+-DEF_HELPER_3(oc, i32, i32, i64, i64)
+-DEF_HELPER_3(xc, i32, i32, i64, i64)
+-DEF_HELPER_3(mvc, void, i32, i64, i64)
+-DEF_HELPER_3(clc, i32, i32, i64, i64)
+-DEF_HELPER_2(mvcl, i32, i32, i32)
++DEF_HELPER_4(nc, i32, env, i32, i64, i64)
++DEF_HELPER_4(oc, i32, env, i32, i64, i64)
++DEF_HELPER_4(xc, i32, env, i32, i64, i64)
++DEF_HELPER_4(mvc, void, env, i32, i64, i64)
++DEF_HELPER_4(clc, i32, env, i32, i64, i64)
++DEF_HELPER_3(mvcl, i32, env, i32, i32)
+ DEF_HELPER_FLAGS_1(set_cc_comp_s32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32)
+ DEF_HELPER_FLAGS_1(set_cc_comp_s64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64)
+ DEF_HELPER_FLAGS_2(set_cc_icm, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32)
+-DEF_HELPER_3(clm, i32, i32, i32, i64)
+-DEF_HELPER_3(stcm, void, i32, i32, i64)
++DEF_HELPER_4(clm, i32, env, i32, i32, i64)
++DEF_HELPER_4(stcm, void, env, i32, i32, i64)
+ DEF_HELPER_3(mlg, void, env, i32, i64)
+ DEF_HELPER_3(dlg, void, env, i32, i64)
+ DEF_HELPER_FLAGS_3(set_cc_add64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64, s64, s64)
+@@ -22,27 +22,27 @@ DEF_HELPER_FLAGS_3(set_cc_sub64, TCG_CALL_PURE|TCG_CALL_CONST, i32, s64, s64, s6
+ DEF_HELPER_FLAGS_3(set_cc_subu64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64)
+ DEF_HELPER_FLAGS_3(set_cc_sub32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32, s32, s32)
+ DEF_HELPER_FLAGS_3(set_cc_subu32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32, i32)
+-DEF_HELPER_3(srst, i32, i32, i32, i32)
+-DEF_HELPER_3(clst, i32, i32, i32, i32)
+-DEF_HELPER_3(mvpg, void, i64, i64, i64)
+-DEF_HELPER_3(mvst, void, i32, i32, i32)
+-DEF_HELPER_3(csg, i32, i32, i64, i32)
+-DEF_HELPER_3(cdsg, i32, i32, i64, i32)
+-DEF_HELPER_3(cs, i32, i32, i64, i32)
+-DEF_HELPER_4(ex, i32, i32, i64, i64, i64)
++DEF_HELPER_4(srst, i32, env, i32, i32, i32)
++DEF_HELPER_4(clst, i32, env, i32, i32, i32)
++DEF_HELPER_4(mvpg, void, env, i64, i64, i64)
++DEF_HELPER_4(mvst, void, env, i32, i32, i32)
++DEF_HELPER_4(csg, i32, env, i32, i64, i32)
++DEF_HELPER_4(cdsg, i32, env, i32, i64, i32)
++DEF_HELPER_4(cs, i32, env, i32, i64, i32)
++DEF_HELPER_5(ex, i32, env, i32, i64, i64, i64)
+ DEF_HELPER_FLAGS_1(abs_i32, TCG_CALL_PURE|TCG_CALL_CONST, i32, s32)
+ DEF_HELPER_FLAGS_1(nabs_i32, TCG_CALL_PURE|TCG_CALL_CONST, s32, s32)
+ DEF_HELPER_FLAGS_1(abs_i64, TCG_CALL_PURE|TCG_CALL_CONST, i64, s64)
+ DEF_HELPER_FLAGS_1(nabs_i64, TCG_CALL_PURE|TCG_CALL_CONST, s64, s64)
+-DEF_HELPER_3(stcmh, void, i32, i64, i32)
+-DEF_HELPER_3(icmh, i32, i32, i64, i32)
++DEF_HELPER_4(stcmh, void, env, i32, i64, i32)
++DEF_HELPER_4(icmh, i32, env, i32, i64, i32)
+ DEF_HELPER_3(ipm, void, env, i32, i32)
+ DEF_HELPER_FLAGS_3(addc_u32, TCG_CALL_PURE|TCG_CALL_CONST, i32, i32, i32, i32)
+ DEF_HELPER_FLAGS_3(set_cc_addc_u64, TCG_CALL_PURE|TCG_CALL_CONST, i32, i64, i64, i64)
+-DEF_HELPER_3(stam, void, i32, i64, i32)
+-DEF_HELPER_3(lam, void, i32, i64, i32)
+-DEF_HELPER_3(mvcle, i32, i32, i64, i32)
+-DEF_HELPER_3(clcle, i32, i32, i64, i32)
++DEF_HELPER_4(stam, void, env, i32, i64, i32)
++DEF_HELPER_4(lam, void, env, i32, i64, i32)
++DEF_HELPER_4(mvcle, i32, env, i32, i64, i32)
++DEF_HELPER_4(clcle, i32, env, i32, i64, i32)
+ DEF_HELPER_4(slb, i32, env, i32, i32, i32)
+ DEF_HELPER_5(slbg, i32, env, i32, i32, i64, i64)
+ DEF_HELPER_3(cefbr, void, env, i32, s32)
+@@ -110,8 +110,8 @@ DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_PURE, i32, env, i32, i64)
+ DEF_HELPER_3(flogr, i32, env, i32, i64)
+ DEF_HELPER_3(sqdbr, void, env, i32, i32)
+ DEF_HELPER_FLAGS_1(cvd, TCG_CALL_PURE|TCG_CALL_CONST, i64, s32)
+-DEF_HELPER_3(unpk, void, i32, i64, i64)
+-DEF_HELPER_3(tr, void, i32, i64, i64)
++DEF_HELPER_4(unpk, void, env, i32, i64, i64)
++DEF_HELPER_4(tr, void, env, i32, i64, i64)
+ 
+ DEF_HELPER_3(servc, i32, env, i32, i64)
+ DEF_HELPER_4(diag, i64, env, i32, i64, i64)
+@@ -127,24 +127,24 @@ DEF_HELPER_FLAGS_2(stckc, TCG_CALL_CONST, void, env, i64)
+ DEF_HELPER_FLAGS_2(spt, TCG_CALL_CONST, void, env, i64)
+ DEF_HELPER_FLAGS_2(stpt, TCG_CALL_CONST, void, env, i64)
+ DEF_HELPER_4(stsi, i32, env, i64, i32, i32)
+-DEF_HELPER_3(lctl, void, i32, i64, i32)
+-DEF_HELPER_3(lctlg, void, i32, i64, i32)
+-DEF_HELPER_3(stctl, void, i32, i64, i32)
+-DEF_HELPER_3(stctg, void, i32, i64, i32)
++DEF_HELPER_4(lctl, void, env, i32, i64, i32)
++DEF_HELPER_4(lctlg, void, env, i32, i64, i32)
++DEF_HELPER_4(stctl, void, env, i32, i64, i32)
++DEF_HELPER_4(stctg, void, env, i32, i64, i32)
+ DEF_HELPER_FLAGS_2(tprot, TCG_CALL_CONST, i32, i64, i64)
+-DEF_HELPER_FLAGS_1(iske, TCG_CALL_PURE|TCG_CALL_CONST, i64, i64)
+-DEF_HELPER_FLAGS_2(sske, TCG_CALL_CONST, void, i32, i64)
+-DEF_HELPER_FLAGS_2(rrbe, TCG_CALL_CONST, i32, i32, i64)
+-DEF_HELPER_2(csp, i32, i32, i32)
+-DEF_HELPER_3(mvcs, i32, i64, i64, i64)
+-DEF_HELPER_3(mvcp, i32, i64, i64, i64)
++DEF_HELPER_FLAGS_2(iske, TCG_CALL_PURE|TCG_CALL_CONST, i64, env, i64)
++DEF_HELPER_FLAGS_3(sske, TCG_CALL_CONST, void, env, i32, i64)
++DEF_HELPER_FLAGS_3(rrbe, TCG_CALL_CONST, i32, env, i32, i64)
++DEF_HELPER_3(csp, i32, env, i32, i32)
++DEF_HELPER_4(mvcs, i32, env, i64, i64, i64)
++DEF_HELPER_4(mvcp, i32, env, i64, i64, i64)
+ DEF_HELPER_4(sigp, i32, env, i64, i32, i64)
+ DEF_HELPER_2(sacf, void, env, i64)
+-DEF_HELPER_FLAGS_2(ipte, TCG_CALL_CONST, void, i64, i64)
+-DEF_HELPER_FLAGS_0(ptlb, TCG_CALL_CONST, void)
+-DEF_HELPER_2(lra, i32, i64, i32)
+-DEF_HELPER_2(stura, void, i64, i32)
+-DEF_HELPER_2(cksm, void, i32, i32)
++DEF_HELPER_FLAGS_3(ipte, TCG_CALL_CONST, void, env, i64, i64)
++DEF_HELPER_FLAGS_1(ptlb, TCG_CALL_CONST, void, env)
++DEF_HELPER_3(lra, i32, env, i64, i32)
++DEF_HELPER_3(stura, void, env, i64, i32)
++DEF_HELPER_3(cksm, void, env, i32, i32)
+ 
+ DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_PURE|TCG_CALL_CONST,
+                    i32, env, i32, i64, i64, i64)
+diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
+index 52f2602..b21b37c 100644
+--- a/target-s390x/mem_helper.c
++++ b/target-s390x/mem_helper.c
+@@ -19,7 +19,6 @@
+  */
+ 
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "helper.h"
+ 
+ /*****************************************************************************/
+@@ -45,15 +44,12 @@
+    NULL, it means that the function was called in C code (i.e. not
+    from generated code or from helper.c) */
+ /* XXX: fix it to restore all registers */
+-void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
++void tlb_fill(CPUS390XState *env, target_ulong addr, int is_write, int mmu_idx,
+               uintptr_t retaddr)
+ {
+     TranslationBlock *tb;
+-    CPUS390XState *saved_env;
+     int ret;
+ 
+-    saved_env = env;
+-    env = env1;
+     ret = cpu_s390x_handle_mmu_fault(env, addr, is_write, mmu_idx);
+     if (unlikely(ret != 0)) {
+         if (likely(retaddr)) {
+@@ -67,7 +63,6 @@ void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
+         }
+         cpu_loop_exit(env);
+     }
+-    env = saved_env;
+ }
+ 
+ #endif
+@@ -90,7 +85,7 @@ static void mvc_fast_memset(CPUS390XState *env, uint32_t l, uint64_t dest,
+     int flags;
+ 
+     if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
+-        stb(dest, byte);
++        cpu_stb_data(env, dest, byte);
+         cpu_abort(env, "should never reach here");
+     }
+     dest_phys |= dest & ~TARGET_PAGE_MASK;
+@@ -114,13 +109,13 @@ static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
+     int flags;
+ 
+     if (mmu_translate(env, dest, 1, asc, &dest_phys, &flags)) {
+-        stb(dest, 0);
++        cpu_stb_data(env, dest, 0);
+         cpu_abort(env, "should never reach here");
+     }
+     dest_phys |= dest & ~TARGET_PAGE_MASK;
+ 
+     if (mmu_translate(env, src, 0, asc, &src_phys, &flags)) {
+-        ldub(src);
++        cpu_ldub_data(env, src);
+         cpu_abort(env, "should never reach here");
+     }
+     src_phys |= src & ~TARGET_PAGE_MASK;
+@@ -136,7 +131,8 @@ static void mvc_fast_memmove(CPUS390XState *env, uint32_t l, uint64_t dest,
+ #endif
+ 
+ /* and on array */
+-uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
++uint32_t HELPER(nc)(CPUS390XState *env, uint32_t l, uint64_t dest,
++                    uint64_t src)
+ {
+     int i;
+     unsigned char x;
+@@ -145,17 +141,18 @@ uint32_t HELPER(nc)(uint32_t l, uint64_t dest, uint64_t src)
+     HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+                __func__, l, dest, src);
+     for (i = 0; i <= l; i++) {
+-        x = ldub(dest + i) & ldub(src + i);
++        x = cpu_ldub_data(env, dest + i) & cpu_ldub_data(env, src + i);
+         if (x) {
+             cc = 1;
+         }
+-        stb(dest + i, x);
++        cpu_stb_data(env, dest + i, x);
+     }
+     return cc;
+ }
+ 
+ /* xor on array */
+-uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
++uint32_t HELPER(xc)(CPUS390XState *env, uint32_t l, uint64_t dest,
++                    uint64_t src)
+ {
+     int i;
+     unsigned char x;
+@@ -179,17 +176,18 @@ uint32_t HELPER(xc)(uint32_t l, uint64_t dest, uint64_t src)
+ #endif
+ 
+     for (i = 0; i <= l; i++) {
+-        x = ldub(dest + i) ^ ldub(src + i);
++        x = cpu_ldub_data(env, dest + i) ^ cpu_ldub_data(env, src + i);
+         if (x) {
+             cc = 1;
+         }
+-        stb(dest + i, x);
++        cpu_stb_data(env, dest + i, x);
+     }
+     return cc;
+ }
+ 
+ /* or on array */
+-uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
++uint32_t HELPER(oc)(CPUS390XState *env, uint32_t l, uint64_t dest,
++                    uint64_t src)
+ {
+     int i;
+     unsigned char x;
+@@ -198,17 +196,17 @@ uint32_t HELPER(oc)(uint32_t l, uint64_t dest, uint64_t src)
+     HELPER_LOG("%s l %d dest %" PRIx64 " src %" PRIx64 "\n",
+                __func__, l, dest, src);
+     for (i = 0; i <= l; i++) {
+-        x = ldub(dest + i) | ldub(src + i);
++        x = cpu_ldub_data(env, dest + i) | cpu_ldub_data(env, src + i);
+         if (x) {
+             cc = 1;
+         }
+-        stb(dest + i, x);
++        cpu_stb_data(env, dest + i, x);
+     }
+     return cc;
+ }
+ 
+ /* memmove */
+-void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
++void HELPER(mvc)(CPUS390XState *env, uint32_t l, uint64_t dest, uint64_t src)
+ {
+     int i = 0;
+     int x = 0;
+@@ -222,7 +220,7 @@ void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
+         (src & TARGET_PAGE_MASK) == ((src + l) & TARGET_PAGE_MASK) &&
+         (dest & TARGET_PAGE_MASK) == ((dest + l) & TARGET_PAGE_MASK)) {
+         if (dest == (src + 1)) {
+-            mvc_fast_memset(env, l + 1, dest, ldub(src));
++            mvc_fast_memset(env, l + 1, dest, cpu_ldub_data(env, src));
+             return;
+         } else if ((src & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) {
+             mvc_fast_memmove(env, l + 1, dest, src);
+@@ -231,7 +229,7 @@ void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
+     }
+ #else
+     if (dest == (src + 1)) {
+-        memset(g2h(dest), ldub(src), l + 1);
++        memset(g2h(dest), cpu_ldub_data(env, src), l + 1);
+         return;
+     } else {
+         memmove(g2h(dest), g2h(src), l + 1);
+@@ -242,19 +240,19 @@ void HELPER(mvc)(uint32_t l, uint64_t dest, uint64_t src)
+     /* handle the parts that fit into 8-byte loads/stores */
+     if (dest != (src + 1)) {
+         for (i = 0; i < l_64; i++) {
+-            stq(dest + x, ldq(src + x));
++            cpu_stq_data(env, dest + x, cpu_ldq_data(env, src + x));
+             x += 8;
+         }
+     }
+ 
+     /* slow version crossing pages with byte accesses */
+     for (i = x; i <= l; i++) {
+-        stb(dest + i, ldub(src + i));
++        cpu_stb_data(env, dest + i, cpu_ldub_data(env, src + i));
+     }
+ }
+ 
+ /* compare unsigned byte arrays */
+-uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
++uint32_t HELPER(clc)(CPUS390XState *env, uint32_t l, uint64_t s1, uint64_t s2)
+ {
+     int i;
+     unsigned char x, y;
+@@ -263,8 +261,8 @@ uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
+     HELPER_LOG("%s l %d s1 %" PRIx64 " s2 %" PRIx64 "\n",
+                __func__, l, s1, s2);
+     for (i = 0; i <= l; i++) {
+-        x = ldub(s1 + i);
+-        y = ldub(s2 + i);
++        x = cpu_ldub_data(env, s1 + i);
++        y = cpu_ldub_data(env, s2 + i);
+         HELPER_LOG("%02x (%c)/%02x (%c) ", x, x, y, y);
+         if (x < y) {
+             cc = 1;
+@@ -281,7 +279,8 @@ uint32_t HELPER(clc)(uint32_t l, uint64_t s1, uint64_t s2)
+ }
+ 
+ /* compare logical under mask */
+-uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
++uint32_t HELPER(clm)(CPUS390XState *env, uint32_t r1, uint32_t mask,
++                     uint64_t addr)
+ {
+     uint8_t r, d;
+     uint32_t cc;
+@@ -291,7 +290,7 @@ uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
+     cc = 0;
+     while (mask) {
+         if (mask & 8) {
+-            d = ldub(addr);
++            d = cpu_ldub_data(env, addr);
+             r = (r1 & 0xff000000UL) >> 24;
+             HELPER_LOG("mask 0x%x %02x/%02x (0x%" PRIx64 ") ", mask, r, d,
+                        addr);
+@@ -312,7 +311,8 @@ uint32_t HELPER(clm)(uint32_t r1, uint32_t mask, uint64_t addr)
+ }
+ 
+ /* store character under mask */
+-void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
++void HELPER(stcm)(CPUS390XState *env, uint32_t r1, uint32_t mask,
++                  uint64_t addr)
+ {
+     uint8_t r;
+ 
+@@ -321,7 +321,7 @@ void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
+     while (mask) {
+         if (mask & 8) {
+             r = (r1 & 0xff000000UL) >> 24;
+-            stb(addr, r);
++            cpu_stb_data(env, addr, r);
+             HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
+             addr++;
+         }
+@@ -331,7 +331,7 @@ void HELPER(stcm)(uint32_t r1, uint32_t mask, uint64_t addr)
+     HELPER_LOG("\n");
+ }
+ 
+-static inline uint64_t get_address(int x2, int b2, int d2)
++static inline uint64_t get_address(CPUS390XState *env, int x2, int b2, int d2)
+ {
+     uint64_t r = d2;
+ 
+@@ -351,7 +351,7 @@ static inline uint64_t get_address(int x2, int b2, int d2)
+     return r;
+ }
+ 
+-static inline uint64_t get_address_31fix(int reg)
++static inline uint64_t get_address_31fix(CPUS390XState *env, int reg)
+ {
+     uint64_t r = env->regs[reg];
+ 
+@@ -364,18 +364,18 @@ static inline uint64_t get_address_31fix(int reg)
+ }
+ 
+ /* search string (c is byte to search, r2 is string, r1 end of string) */
+-uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
++uint32_t HELPER(srst)(CPUS390XState *env, uint32_t c, uint32_t r1, uint32_t r2)
+ {
+     uint64_t i;
+     uint32_t cc = 2;
+-    uint64_t str = get_address_31fix(r2);
+-    uint64_t end = get_address_31fix(r1);
++    uint64_t str = get_address_31fix(env, r2);
++    uint64_t end = get_address_31fix(env, r1);
+ 
+     HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
+                c, env->regs[r1], env->regs[r2]);
+ 
+     for (i = str; i != end; i++) {
+-        if (ldub(i) == c) {
++        if (cpu_ldub_data(env, i) == c) {
+             env->regs[r1] = i;
+             cc = 1;
+             break;
+@@ -386,10 +386,10 @@ uint32_t HELPER(srst)(uint32_t c, uint32_t r1, uint32_t r2)
+ }
+ 
+ /* unsigned string compare (c is string terminator) */
+-uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
++uint32_t HELPER(clst)(CPUS390XState *env, uint32_t c, uint32_t r1, uint32_t r2)
+ {
+-    uint64_t s1 = get_address_31fix(r1);
+-    uint64_t s2 = get_address_31fix(r2);
++    uint64_t s1 = get_address_31fix(env, r1);
++    uint64_t s2 = get_address_31fix(env, r2);
+     uint8_t v1, v2;
+     uint32_t cc;
+ 
+@@ -401,8 +401,8 @@ uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
+     }
+ #endif
+     for (;;) {
+-        v1 = ldub(s1);
+-        v2 = ldub(s2);
++        v1 = cpu_ldub_data(env, s1);
++        v2 = cpu_ldub_data(env, s2);
+         if ((v1 == c || v2 == c) || (v1 != v2)) {
+             break;
+         }
+@@ -422,14 +422,14 @@ uint32_t HELPER(clst)(uint32_t c, uint32_t r1, uint32_t r2)
+ }
+ 
+ /* move page */
+-void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
++void HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2)
+ {
+     /* XXX missing r0 handling */
+ #ifdef CONFIG_USER_ONLY
+     int i;
+ 
+     for (i = 0; i < TARGET_PAGE_SIZE; i++) {
+-        stb(r1 + i, ldub(r2 + i));
++        cpu_stb_data(env, r1 + i, cpu_ldub_data(env, r2 + i));
+     }
+ #else
+     mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2);
+@@ -437,10 +437,10 @@ void HELPER(mvpg)(uint64_t r0, uint64_t r1, uint64_t r2)
+ }
+ 
+ /* string copy (c is string terminator) */
+-void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
++void HELPER(mvst)(CPUS390XState *env, uint32_t c, uint32_t r1, uint32_t r2)
+ {
+-    uint64_t dest = get_address_31fix(r1);
+-    uint64_t src = get_address_31fix(r2);
++    uint64_t dest = get_address_31fix(env, r1);
++    uint64_t src = get_address_31fix(env, r2);
+     uint8_t v;
+ 
+     c = c & 0xff;
+@@ -451,8 +451,8 @@ void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
+     }
+ #endif
+     for (;;) {
+-        v = ldub(src);
+-        stb(dest, v);
++        v = cpu_ldub_data(env, src);
++        cpu_stb_data(env, dest, v);
+         if (v == c) {
+             break;
+         }
+@@ -463,15 +463,15 @@ void HELPER(mvst)(uint32_t c, uint32_t r1, uint32_t r2)
+ }
+ 
+ /* compare and swap 64-bit */
+-uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
++uint32_t HELPER(csg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+     /* FIXME: locking? */
+     uint32_t cc;
+-    uint64_t v2 = ldq(a2);
++    uint64_t v2 = cpu_ldq_data(env, a2);
+ 
+     if (env->regs[r1] == v2) {
+         cc = 0;
+-        stq(a2, env->regs[r3]);
++        cpu_stq_data(env, a2, env->regs[r3]);
+     } else {
+         cc = 1;
+         env->regs[r1] = v2;
+@@ -480,19 +480,19 @@ uint32_t HELPER(csg)(uint32_t r1, uint64_t a2, uint32_t r3)
+ }
+ 
+ /* compare double and swap 64-bit */
+-uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
++uint32_t HELPER(cdsg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+     /* FIXME: locking? */
+     uint32_t cc;
+-    uint64_t v2_hi = ldq(a2);
+-    uint64_t v2_lo = ldq(a2 + 8);
++    uint64_t v2_hi = cpu_ldq_data(env, a2);
++    uint64_t v2_lo = cpu_ldq_data(env, a2 + 8);
+     uint64_t v1_hi = env->regs[r1];
+     uint64_t v1_lo = env->regs[r1 + 1];
+ 
+     if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) {
+         cc = 0;
+-        stq(a2, env->regs[r3]);
+-        stq(a2 + 8, env->regs[r3 + 1]);
++        cpu_stq_data(env, a2, env->regs[r3]);
++        cpu_stq_data(env, a2 + 8, env->regs[r3 + 1]);
+     } else {
+         cc = 1;
+         env->regs[r1] = v2_hi;
+@@ -503,16 +503,16 @@ uint32_t HELPER(cdsg)(uint32_t r1, uint64_t a2, uint32_t r3)
+ }
+ 
+ /* compare and swap 32-bit */
+-uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
++uint32_t HELPER(cs)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+     /* FIXME: locking? */
+     uint32_t cc;
+-    uint32_t v2 = ldl(a2);
++    uint32_t v2 = cpu_ldl_data(env, a2);
+ 
+     HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
+     if (((uint32_t)env->regs[r1]) == v2) {
+         cc = 0;
+-        stl(a2, (uint32_t)env->regs[r3]);
++        cpu_stl_data(env, a2, (uint32_t)env->regs[r3]);
+     } else {
+         cc = 1;
+         env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2;
+@@ -520,7 +520,8 @@ uint32_t HELPER(cs)(uint32_t r1, uint64_t a2, uint32_t r3)
+     return cc;
+ }
+ 
+-static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
++static uint32_t helper_icm(CPUS390XState *env, uint32_t r1, uint64_t address,
++                           uint32_t mask)
+ {
+     int pos = 24; /* top of the lower half of r1 */
+     uint64_t rmask = 0xff000000ULL;
+@@ -531,7 +532,7 @@ static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
+     while (mask) {
+         if (mask & 8) {
+             env->regs[r1] &= ~rmask;
+-            val = ldub(address);
++            val = cpu_ldub_data(env, address);
+             if ((val & 0x80) && !ccd) {
+                 cc = 1;
+             }
+@@ -557,9 +558,10 @@ static uint32_t helper_icm(uint32_t r1, uint64_t address, uint32_t mask)
+    in other words: tricky...
+    currently implemented by interpreting the cases it is most commonly used in
+ */
+-uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
++uint32_t HELPER(ex)(CPUS390XState *env, uint32_t cc, uint64_t v1,
++                    uint64_t addr, uint64_t ret)
+ {
+-    uint16_t insn = lduw_code(addr);
++    uint16_t insn = cpu_lduw_code(env, addr);
+ 
+     HELPER_LOG("%s: v1 0x%lx addr 0x%lx insn 0x%x\n", __func__, v1, addr,
+                insn);
+@@ -567,23 +569,27 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+         uint32_t l, insn2, b1, b2, d1, d2;
+ 
+         l = v1 & 0xff;
+-        insn2 = ldl_code(addr + 2);
++        insn2 = cpu_ldl_code(env, addr + 2);
+         b1 = (insn2 >> 28) & 0xf;
+         b2 = (insn2 >> 12) & 0xf;
+         d1 = (insn2 >> 16) & 0xfff;
+         d2 = insn2 & 0xfff;
+         switch (insn & 0xf00) {
+         case 0x200:
+-            helper_mvc(l, get_address(0, b1, d1), get_address(0, b2, d2));
++            helper_mvc(env, l, get_address(env, 0, b1, d1),
++                       get_address(env, 0, b2, d2));
+             break;
+         case 0x500:
+-            cc = helper_clc(l, get_address(0, b1, d1), get_address(0, b2, d2));
++            cc = helper_clc(env, l, get_address(env, 0, b1, d1),
++                            get_address(env, 0, b2, d2));
+             break;
+         case 0x700:
+-            cc = helper_xc(l, get_address(0, b1, d1), get_address(0, b2, d2));
++            cc = helper_xc(env, l, get_address(env, 0, b1, d1),
++                           get_address(env, 0, b2, d2));
+             break;
+         case 0xc00:
+-            helper_tr(l, get_address(0, b1, d1), get_address(0, b2, d2));
++            helper_tr(env, l, get_address(env, 0, b1, d1),
++                      get_address(env, 0, b2, d2));
+             break;
+         default:
+             goto abort;
+@@ -599,12 +605,12 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+     } else if ((insn & 0xff00) == 0xbf00) {
+         uint32_t insn2, r1, r3, b2, d2;
+ 
+-        insn2 = ldl_code(addr + 2);
++        insn2 = cpu_ldl_code(env, addr + 2);
+         r1 = (insn2 >> 20) & 0xf;
+         r3 = (insn2 >> 16) & 0xf;
+         b2 = (insn2 >> 12) & 0xf;
+         d2 = insn2 & 0xfff;
+-        cc = helper_icm(r1, get_address(0, b2, d2), r3);
++        cc = helper_icm(env, r1, get_address(env, 0, b2, d2), r3);
+     } else {
+     abort:
+         cpu_abort(env, "EXECUTE on instruction prefix 0x%x not implemented\n",
+@@ -614,13 +620,14 @@ uint32_t HELPER(ex)(uint32_t cc, uint64_t v1, uint64_t addr, uint64_t ret)
+ }
+ 
+ /* store character under mask high operates on the upper half of r1 */
+-void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
++void HELPER(stcmh)(CPUS390XState *env, uint32_t r1, uint64_t address,
++                   uint32_t mask)
+ {
+     int pos = 56; /* top of the upper half of r1 */
+ 
+     while (mask) {
+         if (mask & 8) {
+-            stb(address, (env->regs[r1] >> pos) & 0xff);
++            cpu_stb_data(env, address, (env->regs[r1] >> pos) & 0xff);
+             address++;
+         }
+         mask = (mask << 1) & 0xf;
+@@ -630,7 +637,8 @@ void HELPER(stcmh)(uint32_t r1, uint64_t address, uint32_t mask)
+ 
+ /* insert character under mask high; same as icm, but operates on the
+    upper half of r1 */
+-uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
++uint32_t HELPER(icmh)(CPUS390XState *env, uint32_t r1, uint64_t address,
++                      uint32_t mask)
+ {
+     int pos = 56; /* top of the upper half of r1 */
+     uint64_t rmask = 0xff00000000000000ULL;
+@@ -641,7 +649,7 @@ uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
+     while (mask) {
+         if (mask & 8) {
+             env->regs[r1] &= ~rmask;
+-            val = ldub(address);
++            val = cpu_ldub_data(env, address);
+             if ((val & 0x80) && !ccd) {
+                 cc = 1;
+             }
+@@ -661,12 +669,12 @@ uint32_t HELPER(icmh)(uint32_t r1, uint64_t address, uint32_t mask)
+ }
+ 
+ /* load access registers r1 to r3 from memory at a2 */
+-void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
++void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+     int i;
+ 
+     for (i = r1;; i = (i + 1) % 16) {
+-        env->aregs[i] = ldl(a2);
++        env->aregs[i] = cpu_ldl_data(env, a2);
+         a2 += 4;
+ 
+         if (i == r3) {
+@@ -676,12 +684,12 @@ void HELPER(lam)(uint32_t r1, uint64_t a2, uint32_t r3)
+ }
+ 
+ /* store access registers r1 to r3 in memory at a2 */
+-void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
++void HELPER(stam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+     int i;
+ 
+     for (i = r1;; i = (i + 1) % 16) {
+-        stl(a2, env->aregs[i]);
++        cpu_stl_data(env, a2, env->aregs[i]);
+         a2 += 4;
+ 
+         if (i == r3) {
+@@ -691,12 +699,12 @@ void HELPER(stam)(uint32_t r1, uint64_t a2, uint32_t r3)
+ }
+ 
+ /* move long */
+-uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
++uint32_t HELPER(mvcl)(CPUS390XState *env, uint32_t r1, uint32_t r2)
+ {
+     uint64_t destlen = env->regs[r1 + 1] & 0xffffff;
+-    uint64_t dest = get_address_31fix(r1);
++    uint64_t dest = get_address_31fix(env, r1);
+     uint64_t srclen = env->regs[r2 + 1] & 0xffffff;
+-    uint64_t src = get_address_31fix(r2);
++    uint64_t src = get_address_31fix(env, r2);
+     uint8_t pad = src >> 24;
+     uint8_t v;
+     uint32_t cc;
+@@ -714,12 +722,12 @@ uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
+     }
+ 
+     for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
+-        v = ldub(src);
+-        stb(dest, v);
++        v = cpu_ldub_data(env, src);
++        cpu_stb_data(env, dest, v);
+     }
+ 
+     for (; destlen; dest++, destlen--) {
+-        stb(dest, pad);
++        cpu_stb_data(env, dest, pad);
+     }
+ 
+     env->regs[r1 + 1] = destlen;
+@@ -732,7 +740,8 @@ uint32_t HELPER(mvcl)(uint32_t r1, uint32_t r2)
+ }
+ 
+ /* move long extended another memcopy insn with more bells and whistles */
+-uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
++uint32_t HELPER(mvcle)(CPUS390XState *env, uint32_t r1, uint64_t a2,
++                       uint32_t r3)
+ {
+     uint64_t destlen = env->regs[r1 + 1];
+     uint64_t dest = env->regs[r1];
+@@ -762,12 +771,12 @@ uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+     }
+ 
+     for (; destlen && srclen; src++, dest++, destlen--, srclen--) {
+-        v = ldub(src);
+-        stb(dest, v);
++        v = cpu_ldub_data(env, src);
++        cpu_stb_data(env, dest, v);
+     }
+ 
+     for (; destlen; dest++, destlen--) {
+-        stb(dest, pad);
++        cpu_stb_data(env, dest, pad);
+     }
+ 
+     env->regs[r1 + 1] = destlen;
+@@ -781,12 +790,13 @@ uint32_t HELPER(mvcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+ }
+ 
+ /* compare logical long extended memcompare insn with padding */
+-uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
++uint32_t HELPER(clcle)(CPUS390XState *env, uint32_t r1, uint64_t a2,
++                       uint32_t r3)
+ {
+     uint64_t destlen = env->regs[r1 + 1];
+-    uint64_t dest = get_address_31fix(r1);
++    uint64_t dest = get_address_31fix(env, r1);
+     uint64_t srclen = env->regs[r3 + 1];
+-    uint64_t src = get_address_31fix(r3);
++    uint64_t src = get_address_31fix(env, r3);
+     uint8_t pad = a2 & 0xff;
+     uint8_t v1 = 0, v2 = 0;
+     uint32_t cc = 0;
+@@ -800,8 +810,8 @@ uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+     }
+ 
+     for (; destlen || srclen; src++, dest++, destlen--, srclen--) {
+-        v1 = srclen ? ldub(src) : pad;
+-        v2 = destlen ? ldub(dest) : pad;
++        v1 = srclen ? cpu_ldub_data(env, src) : pad;
++        v2 = destlen ? cpu_ldub_data(env, dest) : pad;
+         if (v1 != v2) {
+             cc = (v1 < v2) ? 1 : 2;
+             break;
+@@ -818,14 +828,14 @@ uint32_t HELPER(clcle)(uint32_t r1, uint64_t a2, uint32_t r3)
+ }
+ 
+ /* checksum */
+-void HELPER(cksm)(uint32_t r1, uint32_t r2)
++void HELPER(cksm)(CPUS390XState *env, uint32_t r1, uint32_t r2)
+ {
+-    uint64_t src = get_address_31fix(r2);
++    uint64_t src = get_address_31fix(env, r2);
+     uint64_t src_len = env->regs[(r2 + 1) & 15];
+     uint64_t cksm = (uint32_t)env->regs[r1];
+ 
+     while (src_len >= 4) {
+-        cksm += ldl(src);
++        cksm += cpu_ldl_data(env, src);
+ 
+         /* move to next word */
+         src_len -= 4;
+@@ -836,14 +846,14 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
+     case 0:
+         break;
+     case 1:
+-        cksm += ldub(src) << 24;
++        cksm += cpu_ldub_data(env, src) << 24;
+         break;
+     case 2:
+-        cksm += lduw(src) << 16;
++        cksm += cpu_lduw_data(env, src) << 16;
+         break;
+     case 3:
+-        cksm += lduw(src) << 16;
+-        cksm += ldub(src + 2) << 8;
++        cksm += cpu_lduw_data(env, src) << 16;
++        cksm += cpu_ldub_data(env, src + 2) << 8;
+         break;
+     }
+ 
+@@ -856,7 +866,8 @@ void HELPER(cksm)(uint32_t r1, uint32_t r2)
+         ((uint32_t)cksm + (cksm >> 32));
+ }
+ 
+-void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
++void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest,
++                  uint64_t src)
+ {
+     int len_dest = len >> 4;
+     int len_src = len & 0xf;
+@@ -867,8 +878,8 @@ void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
+     src += len_src;
+ 
+     /* last byte is special, it only flips the nibbles */
+-    b = ldub(src);
+-    stb(dest, (b << 4) | (b >> 4));
++    b = cpu_ldub_data(env, src);
++    cpu_stb_data(env, dest, (b << 4) | (b >> 4));
+     src--;
+     len_src--;
+ 
+@@ -878,7 +889,7 @@ void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
+         uint8_t cur_byte = 0;
+ 
+         if (len_src > 0) {
+-            cur_byte = ldub(src);
++            cur_byte = cpu_ldub_data(env, src);
+         }
+ 
+         len_dest--;
+@@ -897,30 +908,31 @@ void HELPER(unpk)(uint32_t len, uint64_t dest, uint64_t src)
+         /* zone bits */
+         cur_byte |= 0xf0;
+ 
+-        stb(dest, cur_byte);
++        cpu_stb_data(env, dest, cur_byte);
+     }
+ }
+ 
+-void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
++void HELPER(tr)(CPUS390XState *env, uint32_t len, uint64_t array,
++                uint64_t trans)
+ {
+     int i;
+ 
+     for (i = 0; i <= len; i++) {
+-        uint8_t byte = ldub(array + i);
+-        uint8_t new_byte = ldub(trans + byte);
++        uint8_t byte = cpu_ldub_data(env, array + i);
++        uint8_t new_byte = cpu_ldub_data(env, trans + byte);
+ 
+-        stb(array + i, new_byte);
++        cpu_stb_data(env, array + i, new_byte);
+     }
+ }
+ 
+ #if !defined(CONFIG_USER_ONLY)
+-void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
++void HELPER(lctlg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+     int i;
+     uint64_t src = a2;
+ 
+     for (i = r1;; i = (i + 1) % 16) {
+-        env->cregs[i] = ldq(src);
++        env->cregs[i] = cpu_ldq_data(env, src);
+         HELPER_LOG("load ctl %d from 0x%" PRIx64 " == 0x%" PRIx64 "\n",
+                    i, src, env->cregs[i]);
+         src += sizeof(uint64_t);
+@@ -933,13 +945,14 @@ void HELPER(lctlg)(uint32_t r1, uint64_t a2, uint32_t r3)
+     tlb_flush(env, 1);
+ }
+ 
+-void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
++void HELPER(lctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+     int i;
+     uint64_t src = a2;
+ 
+     for (i = r1;; i = (i + 1) % 16) {
+-        env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) | ldl(src);
++        env->cregs[i] = (env->cregs[i] & 0xFFFFFFFF00000000ULL) |
++            cpu_ldl_data(env, src);
+         src += sizeof(uint32_t);
+ 
+         if (i == r3) {
+@@ -950,13 +963,13 @@ void HELPER(lctl)(uint32_t r1, uint64_t a2, uint32_t r3)
+     tlb_flush(env, 1);
+ }
+ 
+-void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
++void HELPER(stctg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+     int i;
+     uint64_t dest = a2;
+ 
+     for (i = r1;; i = (i + 1) % 16) {
+-        stq(dest, env->cregs[i]);
++        cpu_stq_data(env, dest, env->cregs[i]);
+         dest += sizeof(uint64_t);
+ 
+         if (i == r3) {
+@@ -965,13 +978,13 @@ void HELPER(stctg)(uint32_t r1, uint64_t a2, uint32_t r3)
+     }
+ }
+ 
+-void HELPER(stctl)(uint32_t r1, uint64_t a2, uint32_t r3)
++void HELPER(stctl)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
+ {
+     int i;
+     uint64_t dest = a2;
+ 
+     for (i = r1;; i = (i + 1) % 16) {
+-        stl(dest, env->cregs[i]);
++        cpu_stl_data(env, dest, env->cregs[i]);
+         dest += sizeof(uint32_t);
+ 
+         if (i == r3) {
+@@ -988,9 +1001,9 @@ uint32_t HELPER(tprot)(uint64_t a1, uint64_t a2)
+ }
+ 
+ /* insert storage key extended */
+-uint64_t HELPER(iske)(uint64_t r2)
++uint64_t HELPER(iske)(CPUS390XState *env, uint64_t r2)
+ {
+-    uint64_t addr = get_address(0, 0, r2);
++    uint64_t addr = get_address(env, 0, 0, r2);
+ 
+     if (addr > ram_size) {
+         return 0;
+@@ -1000,9 +1013,9 @@ uint64_t HELPER(iske)(uint64_t r2)
+ }
+ 
+ /* set storage key extended */
+-void HELPER(sske)(uint32_t r1, uint64_t r2)
++void HELPER(sske)(CPUS390XState *env, uint32_t r1, uint64_t r2)
+ {
+-    uint64_t addr = get_address(0, 0, r2);
++    uint64_t addr = get_address(env, 0, 0, r2);
+ 
+     if (addr > ram_size) {
+         return;
+@@ -1012,7 +1025,7 @@ void HELPER(sske)(uint32_t r1, uint64_t r2)
+ }
+ 
+ /* reset reference bit extended */
+-uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
++uint32_t HELPER(rrbe)(CPUS390XState *env, uint32_t r1, uint64_t r2)
+ {
+     uint8_t re;
+     uint8_t key;
+@@ -1038,15 +1051,15 @@ uint32_t HELPER(rrbe)(uint32_t r1, uint64_t r2)
+ }
+ 
+ /* compare and swap and purge */
+-uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
++uint32_t HELPER(csp)(CPUS390XState *env, uint32_t r1, uint32_t r2)
+ {
+     uint32_t cc;
+     uint32_t o1 = env->regs[r1];
+-    uint64_t a2 = get_address_31fix(r2) & ~3ULL;
+-    uint32_t o2 = ldl(a2);
++    uint64_t a2 = get_address_31fix(env, r2) & ~3ULL;
++    uint32_t o2 = cpu_ldl_data(env, a2);
+ 
+     if (o1 == o2) {
+-        stl(a2, env->regs[(r1 + 1) & 15]);
++        cpu_stl_data(env, a2, env->regs[(r1 + 1) & 15]);
+         if (env->regs[r2] & 0x3) {
+             /* flush TLB / ALB */
+             tlb_flush(env, 1);
+@@ -1060,8 +1073,8 @@ uint32_t HELPER(csp)(uint32_t r1, uint32_t r2)
+     return cc;
+ }
+ 
+-static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
+-                        uint64_t mode2)
++static uint32_t mvc_asc(CPUS390XState *env, int64_t l, uint64_t a1,
++                        uint64_t mode1, uint64_t a2, uint64_t mode2)
+ {
+     target_ulong src, dest;
+     int flags, cc = 0, i;
+@@ -1089,7 +1102,7 @@ static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
+         /* XXX be more clever */
+         if ((((dest + i) & TARGET_PAGE_MASK) != (dest & TARGET_PAGE_MASK)) ||
+             (((src + i) & TARGET_PAGE_MASK) != (src & TARGET_PAGE_MASK))) {
+-            mvc_asc(l - i, a1 + i, mode1, a2 + i, mode2);
++            mvc_asc(env, l - i, a1 + i, mode1, a2 + i, mode2);
+             break;
+         }
+         stb_phys(dest + i, ldub_phys(src + i));
+@@ -1098,24 +1111,24 @@ static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
+     return cc;
+ }
+ 
+-uint32_t HELPER(mvcs)(uint64_t l, uint64_t a1, uint64_t a2)
++uint32_t HELPER(mvcs)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
+ {
+     HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
+                __func__, l, a1, a2);
+ 
+-    return mvc_asc(l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
++    return mvc_asc(env, l, a1, PSW_ASC_SECONDARY, a2, PSW_ASC_PRIMARY);
+ }
+ 
+-uint32_t HELPER(mvcp)(uint64_t l, uint64_t a1, uint64_t a2)
++uint32_t HELPER(mvcp)(CPUS390XState *env, uint64_t l, uint64_t a1, uint64_t a2)
+ {
+     HELPER_LOG("%s: %16" PRIx64 " %16" PRIx64 " %16" PRIx64 "\n",
+                __func__, l, a1, a2);
+ 
+-    return mvc_asc(l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
++    return mvc_asc(env, l, a1, PSW_ASC_PRIMARY, a2, PSW_ASC_SECONDARY);
+ }
+ 
+ /* invalidate pte */
+-void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
++void HELPER(ipte)(CPUS390XState *env, uint64_t pte_addr, uint64_t vaddr)
+ {
+     uint64_t page = vaddr & TARGET_PAGE_MASK;
+     uint64_t pte = 0;
+@@ -1141,19 +1154,19 @@ void HELPER(ipte)(uint64_t pte_addr, uint64_t vaddr)
+ }
+ 
+ /* flush local tlb */
+-void HELPER(ptlb)(void)
++void HELPER(ptlb)(CPUS390XState *env)
+ {
+     tlb_flush(env, 1);
+ }
+ 
+ /* store using real address */
+-void HELPER(stura)(uint64_t addr, uint32_t v1)
++void HELPER(stura)(CPUS390XState *env, uint64_t addr, uint32_t v1)
+ {
+-    stw_phys(get_address(0, 0, addr), v1);
++    stw_phys(get_address(env, 0, 0, addr), v1);
+ }
+ 
+ /* load real address */
+-uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
++uint32_t HELPER(lra)(CPUS390XState *env, uint64_t addr, uint32_t r1)
+ {
+     uint32_t cc = 0;
+     int old_exc = env->exception_index;
+@@ -1188,52 +1201,3 @@ uint32_t HELPER(lra)(uint64_t addr, uint32_t r1)
+ }
+ 
+ #endif
+-
+-/* temporary wrappers */
+-#if defined(CONFIG_USER_ONLY)
+-#define ldub_data(addr) ldub_raw(addr)
+-#define lduw_data(addr) lduw_raw(addr)
+-#define ldl_data(addr) ldl_raw(addr)
+-#define ldq_data(addr) ldq_raw(addr)
+-
+-#define stb_data(addr, data) stb_raw(addr, data)
+-#define stw_data(addr, data) stw_raw(addr, data)
+-#define stl_data(addr, data) stl_raw(addr, data)
+-#define stq_data(addr, data) stq_raw(addr, data)
+-#endif
+-
+-#define WRAP_LD(rettype, fn)                                    \
+-    rettype cpu_ ## fn(CPUS390XState *env1, target_ulong addr)  \
+-    {                                                           \
+-        CPUS390XState *saved_env;                               \
+-        rettype ret;                                            \
+-                                                                \
+-        saved_env = env;                                        \
+-        env = env1;                                             \
+-        ret = fn(addr);                                         \
+-        env = saved_env;                                        \
+-        return ret;                                             \
+-    }
+-
+-WRAP_LD(uint32_t, ldub_data)
+-WRAP_LD(uint32_t, lduw_data)
+-WRAP_LD(uint32_t, ldl_data)
+-WRAP_LD(uint64_t, ldq_data)
+-#undef WRAP_LD
+-
+-#define WRAP_ST(datatype, fn)                                           \
+-    void cpu_ ## fn(CPUS390XState *env1, target_ulong addr, datatype val) \
+-    {                                                                   \
+-        CPUS390XState *saved_env;                                       \
+-                                                                        \
+-        saved_env = env;                                                \
+-        env = env1;                                                     \
+-        fn(addr, val);                                                  \
+-        env = saved_env;                                                \
+-    }
+-
+-WRAP_ST(uint32_t, stb_data)
+-WRAP_ST(uint32_t, stw_data)
+-WRAP_ST(uint32_t, stl_data)
+-WRAP_ST(uint64_t, stq_data)
+-#undef WRAP_ST
+diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
+index ced26c6..2938ac9 100644
+--- a/target-s390x/misc_helper.c
++++ b/target-s390x/misc_helper.c
+@@ -31,10 +31,7 @@
+ #endif
+ 
+ #if !defined(CONFIG_USER_ONLY)
+-/* temporarily disabled due to wrapper use */
+-#if 0
+ #include "softmmu_exec.h"
+-#endif
+ #include "sysemu.h"
+ #endif
+ 
+diff --git a/target-s390x/translate.c b/target-s390x/translate.c
+index 0c61e63..66119cd 100644
+--- a/target-s390x/translate.c
++++ b/target-s390x/translate.c
+@@ -276,19 +276,19 @@ static inline void potential_page_fault(DisasContext *s)
+ 
+ static inline uint64_t ld_code2(uint64_t pc)
+ {
+-    return (uint64_t)lduw_code(pc);
++    return (uint64_t)cpu_lduw_code(cpu_single_env, pc);
+ }
+ 
+ static inline uint64_t ld_code4(uint64_t pc)
+ {
+-    return (uint64_t)ldl_code(pc);
++    return (uint64_t)cpu_ldl_code(cpu_single_env, pc);
+ }
+ 
+ static inline uint64_t ld_code6(uint64_t pc)
+ {
+     uint64_t opc;
+-    opc = (uint64_t)lduw_code(pc) << 32;
+-    opc |= (uint64_t)(uint32_t)ldl_code(pc+2);
++    opc = (uint64_t)cpu_lduw_code(cpu_single_env, pc) << 32;
++    opc |= (uint64_t)(uint32_t)cpu_ldl_code(cpu_single_env, pc + 2);
+     return opc;
+ }
+ 
+@@ -1263,7 +1263,7 @@ static void gen_op_mvc(DisasContext *s, int l, TCGv_i64 s1, TCGv_i64 s2)
+         /* Fall back to helper */
+         vl = tcg_const_i32(l);
+         potential_page_fault(s);
+-        gen_helper_mvc(vl, s1, s2);
++        gen_helper_mvc(cpu_env, vl, s1, s2);
+         tcg_temp_free_i32(vl);
+         return;
+     }
+@@ -1455,7 +1455,7 @@ static void gen_op_clc(DisasContext *s, int l, TCGv_i64 s1, TCGv_i64 s2)
+ 
+     potential_page_fault(s);
+     vl = tcg_const_i32(l);
+-    gen_helper_clc(cc_op, vl, s1, s2);
++    gen_helper_clc(cc_op, cpu_env, vl, s1, s2);
+     tcg_temp_free_i32(vl);
+     set_cc_static(s);
+ }
+@@ -2094,7 +2094,7 @@ do_mh:
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_stcmh(tmp32_1, tmp, tmp32_2);
++        gen_helper_stcmh(cpu_env, tmp32_1, tmp, tmp32_2);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -2107,7 +2107,7 @@ do_mh:
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_lctlg(tmp32_1, tmp, tmp32_2);
++        gen_helper_lctlg(cpu_env, tmp32_1, tmp, tmp32_2);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -2119,7 +2119,7 @@ do_mh:
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_stctg(tmp32_1, tmp, tmp32_2);
++        gen_helper_stctg(cpu_env, tmp32_1, tmp, tmp32_2);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -2131,7 +2131,7 @@ do_mh:
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+         /* XXX rewrite in tcg */
+-        gen_helper_csg(cc_op, tmp32_1, tmp, tmp32_2);
++        gen_helper_csg(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+@@ -2143,7 +2143,7 @@ do_mh:
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+         /* XXX rewrite in tcg */
+-        gen_helper_cdsg(cc_op, tmp32_1, tmp, tmp32_2);
++        gen_helper_cdsg(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+@@ -2183,7 +2183,7 @@ do_mh:
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+         /* XXX split CC calculation out */
+-        gen_helper_icmh(cc_op, tmp32_1, tmp, tmp32_2);
++        gen_helper_icmh(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+@@ -2635,7 +2635,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r2);
+         potential_page_fault(s);
+-        gen_helper_cksm(tmp32_1, tmp32_2);
++        gen_helper_cksm(cpu_env, tmp32_1, tmp32_2);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+         gen_op_movi_cc(s, 0);
+@@ -2664,7 +2664,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         tmp2 = load_reg(r1);
+         tmp3 = load_reg(r2);
+         potential_page_fault(s);
+-        gen_helper_mvpg(tmp, tmp2, tmp3);
++        gen_helper_mvpg(cpu_env, tmp, tmp2, tmp3);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i64(tmp2);
+         tcg_temp_free_i64(tmp3);
+@@ -2676,7 +2676,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         tmp32_2 = tcg_const_i32(r1);
+         tmp32_3 = tcg_const_i32(r2);
+         potential_page_fault(s);
+-        gen_helper_mvst(tmp32_1, tmp32_2, tmp32_3);
++        gen_helper_mvst(cpu_env, tmp32_1, tmp32_2, tmp32_3);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+         tcg_temp_free_i32(tmp32_3);
+@@ -2687,7 +2687,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         tmp32_2 = tcg_const_i32(r1);
+         tmp32_3 = tcg_const_i32(r2);
+         potential_page_fault(s);
+-        gen_helper_clst(cc_op, tmp32_1, tmp32_2, tmp32_3);
++        gen_helper_clst(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
+         set_cc_static(s);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -2698,7 +2698,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         tmp32_2 = tcg_const_i32(r1);
+         tmp32_3 = tcg_const_i32(r2);
+         potential_page_fault(s);
+-        gen_helper_srst(cc_op, tmp32_1, tmp32_2, tmp32_3);
++        gen_helper_srst(cc_op, cpu_env, tmp32_1, tmp32_2, tmp32_3);
+         set_cc_static(s);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -2785,7 +2785,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+     case 0x0d: /* PTLB                [S] */
+         /* Purge TLB */
+         check_privileged(s, ilc);
+-        gen_helper_ptlb();
++        gen_helper_ptlb(cpu_env);
+         break;
+     case 0x10: /* SPX      D2(B2)     [S] */
+         /* Set Prefix Register */
+@@ -2828,7 +2828,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         r2 = insn & 0xf;
+         tmp = load_reg(r1);
+         tmp2 = load_reg(r2);
+-        gen_helper_ipte(tmp, tmp2);
++        gen_helper_ipte(cpu_env, tmp, tmp2);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i64(tmp2);
+         break;
+@@ -2839,7 +2839,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         r2 = insn & 0xf;
+         tmp = load_reg(r2);
+         tmp2 = tcg_temp_new_i64();
+-        gen_helper_iske(tmp2, tmp);
++        gen_helper_iske(tmp2, cpu_env, tmp);
+         store_reg(r1, tmp2);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i64(tmp2);
+@@ -2851,7 +2851,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         r2 = insn & 0xf;
+         tmp32_1 = load_reg32(r1);
+         tmp = load_reg(r2);
+-        gen_helper_rrbe(cc_op, tmp32_1, tmp);
++        gen_helper_rrbe(cc_op, cpu_env, tmp32_1, tmp);
+         set_cc_static(s);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i64(tmp);
+@@ -2863,7 +2863,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         r2 = insn & 0xf;
+         tmp32_1 = load_reg32(r1);
+         tmp = load_reg(r2);
+-        gen_helper_sske(tmp32_1, tmp);
++        gen_helper_sske(cpu_env, tmp32_1, tmp);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i64(tmp);
+         break;
+@@ -2880,7 +2880,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         tmp32_1 = load_reg32(r1);
+         tmp = load_reg(r2);
+         potential_page_fault(s);
+-        gen_helper_stura(tmp, tmp32_1);
++        gen_helper_stura(cpu_env, tmp, tmp32_1);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i64(tmp);
+         break;
+@@ -2891,7 +2891,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         r2 = insn & 0xf;
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r2);
+-        gen_helper_csp(cc_op, tmp32_1, tmp32_2);
++        gen_helper_csp(cc_op, cpu_env, tmp32_1, tmp32_2);
+         set_cc_static(s);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -3865,7 +3865,7 @@ static void disas_s390_insn(DisasContext *s)
+     int ilc;
+     int l1;
+ 
+-    opc = ldub_code(s->pc);
++    opc = cpu_ldub_code(cpu_single_env, s->pc);
+     LOG_DISAS("opc 0x%x\n", opc);
+ 
+     ilc = get_ilc(opc);
+@@ -3951,7 +3951,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r2);
+         potential_page_fault(s);
+-        gen_helper_mvcl(cc_op, tmp32_1, tmp32_2);
++        gen_helper_mvcl(cc_op, cpu_env, tmp32_1, tmp32_2);
+         set_cc_static(s);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -4165,7 +4165,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp3 = tcg_const_i64(s->pc + 4);
+         update_psw_addr(s);
+         gen_op_calc_cc(s);
+-        gen_helper_ex(cc_op, cc_op, tmp2, tmp, tmp3);
++        gen_helper_ex(cc_op, cpu_env, cc_op, tmp2, tmp, tmp3);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i64(tmp2);
+@@ -4694,7 +4694,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_lam(tmp32_1, tmp, tmp32_2);
++        gen_helper_lam(cpu_env, tmp32_1, tmp, tmp32_2);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -4706,7 +4706,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_stam(tmp32_1, tmp, tmp32_2);
++        gen_helper_stam(cpu_env, tmp32_1, tmp, tmp32_2);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -4732,7 +4732,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_mvcle(cc_op, tmp32_1, tmp, tmp32_2);
++        gen_helper_mvcle(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+@@ -4745,7 +4745,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_clcle(cc_op, tmp32_1, tmp, tmp32_2);
++        gen_helper_clcle(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+@@ -4789,7 +4789,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp32_1 = tcg_const_i32(r1);
+         potential_page_fault(s);
+-        gen_helper_lra(cc_op, tmp, tmp32_1);
++        gen_helper_lra(cc_op, cpu_env, tmp, tmp32_1);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+@@ -4835,7 +4835,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_stctl(tmp32_1, tmp, tmp32_2);
++        gen_helper_stctl(cpu_env, tmp32_1, tmp, tmp32_2);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -4849,7 +4849,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_lctl(tmp32_1, tmp, tmp32_2);
++        gen_helper_lctl(cpu_env, tmp32_1, tmp, tmp32_2);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -4869,7 +4869,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_cs(cc_op, tmp32_1, tmp, tmp32_2);
++        gen_helper_cs(cc_op, cpu_env, tmp32_1, tmp, tmp32_2);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+@@ -4882,7 +4882,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = load_reg32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_clm(cc_op, tmp32_1, tmp32_2, tmp);
++        gen_helper_clm(cc_op, cpu_env, tmp32_1, tmp32_2, tmp);
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+@@ -4895,7 +4895,7 @@ static void disas_s390_insn(DisasContext *s)
+         tmp32_1 = load_reg32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+         potential_page_fault(s);
+-        gen_helper_stcm(tmp32_1, tmp32_2, tmp);
++        gen_helper_stcm(cpu_env, tmp32_1, tmp32_2, tmp);
+         tcg_temp_free_i64(tmp);
+         tcg_temp_free_i32(tmp32_1);
+         tcg_temp_free_i32(tmp32_2);
+@@ -4992,7 +4992,7 @@ static void disas_s390_insn(DisasContext *s)
+             break;
+         case 0xd4:
+             potential_page_fault(s);
+-            gen_helper_nc(cc_op, vl, tmp, tmp2);
++            gen_helper_nc(cc_op, cpu_env, vl, tmp, tmp2);
+             set_cc_static(s);
+             break;
+         case 0xd5:
+@@ -5000,22 +5000,22 @@ static void disas_s390_insn(DisasContext *s)
+             break;
+         case 0xd6:
+             potential_page_fault(s);
+-            gen_helper_oc(cc_op, vl, tmp, tmp2);
++            gen_helper_oc(cc_op, cpu_env, vl, tmp, tmp2);
+             set_cc_static(s);
+             break;
+         case 0xd7:
+             potential_page_fault(s);
+-            gen_helper_xc(cc_op, vl, tmp, tmp2);
++            gen_helper_xc(cc_op, cpu_env, vl, tmp, tmp2);
+             set_cc_static(s);
+             break;
+         case 0xdc:
+             potential_page_fault(s);
+-            gen_helper_tr(vl, tmp, tmp2);
++            gen_helper_tr(cpu_env, vl, tmp, tmp2);
+             set_cc_static(s);
+             break;
+         case 0xf3:
+             potential_page_fault(s);
+-            gen_helper_unpk(vl, tmp, tmp2);
++            gen_helper_unpk(cpu_env, vl, tmp, tmp2);
+             break;
+         default:
+             tcg_abort();
+@@ -5040,9 +5040,9 @@ static void disas_s390_insn(DisasContext *s)
+         tmp2 = get_address(s, 0, b1, d1);
+         tmp3 = get_address(s, 0, b2, d2);
+         if (opc == 0xda) {
+-            gen_helper_mvcp(cc_op, tmp, tmp2, tmp3);
++            gen_helper_mvcp(cc_op, cpu_env, tmp, tmp2, tmp3);
+         } else {
+-            gen_helper_mvcs(cc_op, tmp, tmp2, tmp3);
++            gen_helper_mvcs(cc_op, cpu_env, tmp, tmp2, tmp3);
+         }
+         set_cc_static(s);
+         tcg_temp_free_i64(tmp);
+-- 
+1.7.12.1
+
diff --git a/0016-tcg-s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch b/0016-tcg-s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch
new file mode 100644
index 0000000..96c305e
--- /dev/null
+++ b/0016-tcg-s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch
@@ -0,0 +1,64 @@
+From 0b95df52ecad351c916108e9f3a9d1bc3327b495 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Sat, 8 Sep 2012 03:45:43 +0000
+Subject: [PATCH] tcg/s390: fix ld/st with CONFIG_TCG_PASS_AREG0
+
+The load/store slow path has been broken in e141ab52d:
+- We need to move 4 registers for store functions and 3 registers for
+  load functions and not the reverse.
+- According to the s390x calling convention the arguments of a function
+  should be zero extended. This means that the register shift should be
+  done with TCG_TYPE_I64 to ensure the higher word is correctly zero
+  extended when needed.
+
+I am aware that CONFIG_TCG_PASS_AREG0 is being removed and thus that
+this patch can be improved, but doing so means it can also be applied to
+the 1.1 and 1.2 stable branches.
+
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/s390/tcg-target.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
+index 04662c1..99b5339 100644
+--- a/tcg/s390/tcg-target.c
++++ b/tcg/s390/tcg-target.c
+@@ -1509,11 +1509,13 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
+         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, mem_index);
+ #ifdef CONFIG_TCG_PASS_AREG0
+         /* XXX/FIXME: suboptimal */
+-        tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
++        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
++                    tcg_target_call_iarg_regs[2]);
++        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
+                     tcg_target_call_iarg_regs[1]);
+-        tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
++        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
+                     tcg_target_call_iarg_regs[0]);
+-        tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
++        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
+                     TCG_AREG0);
+ #endif
+         tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
+@@ -1521,13 +1523,11 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
+         tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
+ #ifdef CONFIG_TCG_PASS_AREG0
+         /* XXX/FIXME: suboptimal */
+-        tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
+-                    tcg_target_call_iarg_regs[2]);
+         tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
+                     tcg_target_call_iarg_regs[1]);
+-        tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
++        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[1],
+                     tcg_target_call_iarg_regs[0]);
+-        tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
++        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
+                     TCG_AREG0);
+ #endif
+         tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
+-- 
+1.7.12.1
+
diff --git a/0017-target-arm-Fix-potential-buffer-overflow.patch b/0017-target-arm-Fix-potential-buffer-overflow.patch
new file mode 100644
index 0000000..6b9726e
--- /dev/null
+++ b/0017-target-arm-Fix-potential-buffer-overflow.patch
@@ -0,0 +1,47 @@
+From e7c3f6b4365f3162f8e25d58f76410aca28719a2 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Tue, 4 Sep 2012 07:35:57 +0200
+Subject: [PATCH] target-arm: Fix potential buffer overflow
+
+Report from smatch:
+
+target-arm/helper.c:651 arm946_prbs_read(6) error:
+ buffer overflow 'env->cp15.c6_region' 8 <= 8
+target-arm/helper.c:661 arm946_prbs_write(6) error:
+ buffer overflow 'env->cp15.c6_region' 8 <= 8
+
+c7_region is an array with 8 elements, so the index must be less than 8.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-arm/helper.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/target-arm/helper.c b/target-arm/helper.c
+index dceaa95..e27df96 100644
+--- a/target-arm/helper.c
++++ b/target-arm/helper.c
+@@ -645,7 +645,7 @@ static int pmsav5_insn_ap_read(CPUARMState *env, const ARMCPRegInfo *ri,
+ static int arm946_prbs_read(CPUARMState *env, const ARMCPRegInfo *ri,
+                             uint64_t *value)
+ {
+-    if (ri->crm > 8) {
++    if (ri->crm >= 8) {
+         return EXCP_UDEF;
+     }
+     *value = env->cp15.c6_region[ri->crm];
+@@ -655,7 +655,7 @@ static int arm946_prbs_read(CPUARMState *env, const ARMCPRegInfo *ri,
+ static int arm946_prbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                              uint64_t value)
+ {
+-    if (ri->crm > 8) {
++    if (ri->crm >= 8) {
+         return EXCP_UDEF;
+     }
+     env->cp15.c6_region[ri->crm] = value;
+-- 
+1.7.12.1
+
diff --git a/0018-tcg-optimize-split-expression-simplification.patch b/0018-tcg-optimize-split-expression-simplification.patch
new file mode 100644
index 0000000..0dcd9b0
--- /dev/null
+++ b/0018-tcg-optimize-split-expression-simplification.patch
@@ -0,0 +1,57 @@
+From 16f29b266435c7eaffc5081c6bba4651d56a8ce8 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Thu, 6 Sep 2012 16:47:13 +0200
+Subject: [PATCH] tcg/optimize: split expression simplification
+
+Split expression simplification in multiple parts so that a given op
+can appear multiple times. This patch should not change anything.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 9c65474..63f970d 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -322,7 +322,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             break;
+         }
+ 
+-        /* Simplify expression if possible. */
++        /* Simplify expression for "op r, a, 0 => mov r, a" cases */
+         switch (op) {
+         CASE_OP_32_64(add):
+         CASE_OP_32_64(sub):
+@@ -352,6 +352,12 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 continue;
+             }
+             break;
++        default:
++            break;
++        }
++
++        /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
++        switch (op) {
+         CASE_OP_32_64(mul):
+             if ((temps[args[2]].state == TCG_TEMP_CONST
+                 && temps[args[2]].val == 0)) {
+@@ -362,6 +368,12 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 continue;
+             }
+             break;
++        default:
++            break;
++        }
++
++        /* Simplify expression for "op r, a, a => mov r, a" cases */
++        switch (op) {
+         CASE_OP_32_64(or):
+         CASE_OP_32_64(and):
+             if (args[1] == args[2]) {
+-- 
+1.7.12.1
+
diff --git a/0019-tcg-optimize-simplify-or-xor-r-a-0-cases.patch b/0019-tcg-optimize-simplify-or-xor-r-a-0-cases.patch
new file mode 100644
index 0000000..4f9dd62
--- /dev/null
+++ b/0019-tcg-optimize-simplify-or-xor-r-a-0-cases.patch
@@ -0,0 +1,30 @@
+From f69f9bd1a7a095ee153eea5422651780aef178b0 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Thu, 6 Sep 2012 16:47:14 +0200
+Subject: [PATCH] tcg/optimize: simplify or/xor r, a, 0 cases
+
+or/xor r, a, 0 is equivalent to a mov r, a.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 63f970d..0db849e 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -331,6 +331,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+         CASE_OP_32_64(sar):
+         CASE_OP_32_64(rotl):
+         CASE_OP_32_64(rotr):
++        CASE_OP_32_64(or):
++        CASE_OP_32_64(xor):
+             if (temps[args[1]].state == TCG_TEMP_CONST) {
+                 /* Proceed with possible constant folding. */
+                 break;
+-- 
+1.7.12.1
+
diff --git a/0020-tcg-optimize-simplify-and-r-a-0-cases.patch b/0020-tcg-optimize-simplify-and-r-a-0-cases.patch
new file mode 100644
index 0000000..e609e66
--- /dev/null
+++ b/0020-tcg-optimize-simplify-and-r-a-0-cases.patch
@@ -0,0 +1,29 @@
+From f08c59ce7dee67a95cf06d9588b4312e7d071788 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Thu, 6 Sep 2012 16:47:14 +0200
+Subject: [PATCH] tcg/optimize: simplify and r, a, 0 cases
+
+and r, a, 0 is equivalent to a movi r, 0.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 0db849e..c12cb2b 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -360,6 +360,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+ 
+         /* Simplify expression for "op r, a, 0 => movi r, 0" cases */
+         switch (op) {
++        CASE_OP_32_64(and):
+         CASE_OP_32_64(mul):
+             if ((temps[args[2]].state == TCG_TEMP_CONST
+                 && temps[args[2]].val == 0)) {
+-- 
+1.7.12.1
+
diff --git a/0021-tcg-optimize-simplify-shift-rot-r-0-a-movi-r-0-cases.patch b/0021-tcg-optimize-simplify-shift-rot-r-0-a-movi-r-0-cases.patch
new file mode 100644
index 0000000..d77bf30
--- /dev/null
+++ b/0021-tcg-optimize-simplify-shift-rot-r-0-a-movi-r-0-cases.patch
@@ -0,0 +1,48 @@
+From bbed332c7ad12e9885d3f457f366fa0b29445dcd Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Thu, 6 Sep 2012 16:47:14 +0200
+Subject: [PATCH] tcg/optimize: simplify shift/rot r, 0, a => movi r, 0 cases
+
+shift/rot r, 0, a is equivalent to movi r, 0.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index c12cb2b..1698ba3 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -322,6 +322,26 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             break;
+         }
+ 
++        /* Simplify expressions for "shift/rot r, 0, a => movi r, 0" */
++        switch (op) {
++        CASE_OP_32_64(shl):
++        CASE_OP_32_64(shr):
++        CASE_OP_32_64(sar):
++        CASE_OP_32_64(rotl):
++        CASE_OP_32_64(rotr):
++            if (temps[args[1]].state == TCG_TEMP_CONST
++                && temps[args[1]].val == 0) {
++                gen_opc_buf[op_index] = op_to_movi(op);
++                tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
++                args += 3;
++                gen_args += 2;
++                continue;
++            }
++            break;
++        default:
++            break;
++        }
++
+         /* Simplify expression for "op r, a, 0 => mov r, a" cases */
+         switch (op) {
+         CASE_OP_32_64(add):
+-- 
+1.7.12.1
+
diff --git a/0022-tcg-optimize-swap-brcond-setcond-arguments-when-poss.patch b/0022-tcg-optimize-swap-brcond-setcond-arguments-when-poss.patch
new file mode 100644
index 0000000..19135ee
--- /dev/null
+++ b/0022-tcg-optimize-swap-brcond-setcond-arguments-when-poss.patch
@@ -0,0 +1,49 @@
+From 1127ad0d084f0cef11b5658b3dbbf8505d8d3af0 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Thu, 6 Sep 2012 16:47:14 +0200
+Subject: [PATCH] tcg/optimize: swap brcond/setcond arguments when possible
+
+brcond and setcond ops are not commutative, but it's easy to compute the
+new condition after swapping the arguments. Try to always put the constant
+argument in second position like for commutative ops, to help backends to
+generate better code.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 1698ba3..7debc8a 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -318,6 +318,24 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 args[2] = tmp;
+             }
+             break;
++        CASE_OP_32_64(brcond):
++            if (temps[args[0]].state == TCG_TEMP_CONST
++                && temps[args[1]].state != TCG_TEMP_CONST) {
++                tmp = args[0];
++                args[0] = args[1];
++                args[1] = tmp;
++                args[2] = tcg_swap_cond(args[2]);
++            }
++            break;
++        CASE_OP_32_64(setcond):
++            if (temps[args[1]].state == TCG_TEMP_CONST
++                && temps[args[2]].state != TCG_TEMP_CONST) {
++                tmp = args[1];
++                args[1] = args[2];
++                args[2] = tmp;
++                args[3] = tcg_swap_cond(args[3]);
++            }
++            break;
+         default:
+             break;
+         }
+-- 
+1.7.12.1
+
diff --git a/0023-tcg-optimize-add-constant-folding-for-setcond.patch b/0023-tcg-optimize-add-constant-folding-for-setcond.patch
new file mode 100644
index 0000000..0968e1e
--- /dev/null
+++ b/0023-tcg-optimize-add-constant-folding-for-setcond.patch
@@ -0,0 +1,114 @@
+From 1bbb9ac3e775b55d0d5c57c209f47e742a9be810 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Thu, 6 Sep 2012 16:47:14 +0200
+Subject: [PATCH] tcg/optimize: add constant folding for setcond
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 81 insertions(+)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 7debc8a..1cb1f36 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -267,6 +267,67 @@ static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
+     return res;
+ }
+ 
++static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
++                                       TCGArg y, TCGCond c)
++{
++    switch (op_bits(op)) {
++    case 32:
++        switch (c) {
++        case TCG_COND_EQ:
++            return (uint32_t)x == (uint32_t)y;
++        case TCG_COND_NE:
++            return (uint32_t)x != (uint32_t)y;
++        case TCG_COND_LT:
++            return (int32_t)x < (int32_t)y;
++        case TCG_COND_GE:
++            return (int32_t)x >= (int32_t)y;
++        case TCG_COND_LE:
++            return (int32_t)x <= (int32_t)y;
++        case TCG_COND_GT:
++            return (int32_t)x > (int32_t)y;
++        case TCG_COND_LTU:
++            return (uint32_t)x < (uint32_t)y;
++        case TCG_COND_GEU:
++            return (uint32_t)x >= (uint32_t)y;
++        case TCG_COND_LEU:
++            return (uint32_t)x <= (uint32_t)y;
++        case TCG_COND_GTU:
++            return (uint32_t)x > (uint32_t)y;
++        }
++        break;
++    case 64:
++        switch (c) {
++        case TCG_COND_EQ:
++            return (uint64_t)x == (uint64_t)y;
++        case TCG_COND_NE:
++            return (uint64_t)x != (uint64_t)y;
++        case TCG_COND_LT:
++            return (int64_t)x < (int64_t)y;
++        case TCG_COND_GE:
++            return (int64_t)x >= (int64_t)y;
++        case TCG_COND_LE:
++            return (int64_t)x <= (int64_t)y;
++        case TCG_COND_GT:
++            return (int64_t)x > (int64_t)y;
++        case TCG_COND_LTU:
++            return (uint64_t)x < (uint64_t)y;
++        case TCG_COND_GEU:
++            return (uint64_t)x >= (uint64_t)y;
++        case TCG_COND_LEU:
++            return (uint64_t)x <= (uint64_t)y;
++        case TCG_COND_GTU:
++            return (uint64_t)x > (uint64_t)y;
++        }
++        break;
++    }
++
++    fprintf(stderr,
++            "Unrecognized bitness %d or condition %d in "
++            "do_constant_folding_cond.\n", op_bits(op), c);
++    tcg_abort();
++}
++
++
+ /* Propagate constants and copies, fold constant expressions. */
+ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                                     TCGArg *args, TCGOpDef *tcg_op_defs)
+@@ -522,6 +583,26 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 args += 3;
+                 break;
+             }
++        CASE_OP_32_64(setcond):
++            if (temps[args[1]].state == TCG_TEMP_CONST
++                && temps[args[2]].state == TCG_TEMP_CONST) {
++                gen_opc_buf[op_index] = op_to_movi(op);
++                tmp = do_constant_folding_cond(op, temps[args[1]].val,
++                                               temps[args[2]].val, args[3]);
++                tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
++                gen_args += 2;
++                args += 4;
++                break;
++            } else {
++                reset_temp(args[0], nb_temps, nb_globals);
++                gen_args[0] = args[0];
++                gen_args[1] = args[1];
++                gen_args[2] = args[2];
++                gen_args[3] = args[3];
++                gen_args += 4;
++                args += 4;
++                break;
++            }
+         case INDEX_op_call:
+             nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
+             if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
+-- 
+1.7.12.1
+
diff --git a/0024-tcg-optimize-add-constant-folding-for-brcond.patch b/0024-tcg-optimize-add-constant-folding-for-brcond.patch
new file mode 100644
index 0000000..0b4c73b
--- /dev/null
+++ b/0024-tcg-optimize-add-constant-folding-for-brcond.patch
@@ -0,0 +1,60 @@
+From 98dc31743b94d5719c02c589e7cd652e95570b25 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Thu, 6 Sep 2012 16:47:14 +0200
+Subject: [PATCH] tcg/optimize: add constant folding for brcond
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 27 ++++++++++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 1cb1f36..156e8d9 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -603,6 +603,32 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 args += 4;
+                 break;
+             }
++        CASE_OP_32_64(brcond):
++            if (temps[args[0]].state == TCG_TEMP_CONST
++                && temps[args[1]].state == TCG_TEMP_CONST) {
++                if (do_constant_folding_cond(op, temps[args[0]].val,
++                                             temps[args[1]].val, args[2])) {
++                    memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
++                    gen_opc_buf[op_index] = INDEX_op_br;
++                    gen_args[0] = args[3];
++                    gen_args += 1;
++                    args += 4;
++                } else {
++                    gen_opc_buf[op_index] = INDEX_op_nop;
++                    args += 4;
++                }
++                break;
++            } else {
++                memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
++                reset_temp(args[0], nb_temps, nb_globals);
++                gen_args[0] = args[0];
++                gen_args[1] = args[1];
++                gen_args[2] = args[2];
++                gen_args[3] = args[3];
++                gen_args += 4;
++                args += 4;
++                break;
++            }
+         case INDEX_op_call:
+             nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
+             if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
+@@ -624,7 +650,6 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+         case INDEX_op_set_label:
+         case INDEX_op_jmp:
+         case INDEX_op_br:
+-        CASE_OP_32_64(brcond):
+             memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+             for (i = 0; i < def->nb_args; i++) {
+                 *gen_args = *args;
+-- 
+1.7.12.1
+
diff --git a/0025-tcg-optimize-fix-if-else-break-coding-style.patch b/0025-tcg-optimize-fix-if-else-break-coding-style.patch
new file mode 100644
index 0000000..ef77b6e
--- /dev/null
+++ b/0025-tcg-optimize-fix-if-else-break-coding-style.patch
@@ -0,0 +1,144 @@
+From b7dc881b44c3698a0a81d226d6012d3c5833fd29 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 7 Sep 2012 12:24:32 +0200
+Subject: [PATCH] tcg/optimize: fix if/else/break coding style
+
+optimizer.c contains some cases were the break is appearing in both the
+if and the else parts. Fix that by moving it to the outer part. Also
+move some common code there.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 34 +++++++++++-----------------------
+ 1 file changed, 11 insertions(+), 23 deletions(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 156e8d9..fba0ed9 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -441,15 +441,14 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 if ((temps[args[0]].state == TCG_TEMP_COPY
+                     && temps[args[0]].val == args[1])
+                     || args[0] == args[1]) {
+-                    args += 3;
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else {
+                     gen_opc_buf[op_index] = op_to_mov(op);
+                     tcg_opt_gen_mov(s, gen_args, args[0], args[1],
+                                     nb_temps, nb_globals);
+                     gen_args += 2;
+-                    args += 3;
+                 }
++                args += 3;
+                 continue;
+             }
+             break;
+@@ -480,15 +479,14 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+         CASE_OP_32_64(and):
+             if (args[1] == args[2]) {
+                 if (args[1] == args[0]) {
+-                    args += 3;
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else {
+                     gen_opc_buf[op_index] = op_to_mov(op);
+                     tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps,
+                                     nb_globals);
+                     gen_args += 2;
+-                    args += 3;
+                 }
++                args += 3;
+                 continue;
+             }
+             break;
+@@ -538,17 +536,14 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 gen_opc_buf[op_index] = op_to_movi(op);
+                 tmp = do_constant_folding(op, temps[args[1]].val, 0);
+                 tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
+-                gen_args += 2;
+-                args += 2;
+-                break;
+             } else {
+                 reset_temp(args[0], nb_temps, nb_globals);
+                 gen_args[0] = args[0];
+                 gen_args[1] = args[1];
+-                gen_args += 2;
+-                args += 2;
+-                break;
+             }
++            gen_args += 2;
++            args += 2;
++            break;
+         CASE_OP_32_64(add):
+         CASE_OP_32_64(sub):
+         CASE_OP_32_64(mul):
+@@ -572,17 +567,15 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                                           temps[args[2]].val);
+                 tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
+                 gen_args += 2;
+-                args += 3;
+-                break;
+             } else {
+                 reset_temp(args[0], nb_temps, nb_globals);
+                 gen_args[0] = args[0];
+                 gen_args[1] = args[1];
+                 gen_args[2] = args[2];
+                 gen_args += 3;
+-                args += 3;
+-                break;
+             }
++            args += 3;
++            break;
+         CASE_OP_32_64(setcond):
+             if (temps[args[1]].state == TCG_TEMP_CONST
+                 && temps[args[2]].state == TCG_TEMP_CONST) {
+@@ -591,8 +584,6 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                                                temps[args[2]].val, args[3]);
+                 tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
+                 gen_args += 2;
+-                args += 4;
+-                break;
+             } else {
+                 reset_temp(args[0], nb_temps, nb_globals);
+                 gen_args[0] = args[0];
+@@ -600,9 +591,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 gen_args[2] = args[2];
+                 gen_args[3] = args[3];
+                 gen_args += 4;
+-                args += 4;
+-                break;
+             }
++            args += 4;
++            break;
+         CASE_OP_32_64(brcond):
+             if (temps[args[0]].state == TCG_TEMP_CONST
+                 && temps[args[1]].state == TCG_TEMP_CONST) {
+@@ -612,12 +603,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                     gen_opc_buf[op_index] = INDEX_op_br;
+                     gen_args[0] = args[3];
+                     gen_args += 1;
+-                    args += 4;
+                 } else {
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+-                    args += 4;
+                 }
+-                break;
+             } else {
+                 memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+                 reset_temp(args[0], nb_temps, nb_globals);
+@@ -626,9 +614,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 gen_args[2] = args[2];
+                 gen_args[3] = args[3];
+                 gen_args += 4;
+-                args += 4;
+-                break;
+             }
++            args += 4;
++            break;
+         case INDEX_op_call:
+             nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
+             if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
+-- 
+1.7.12.1
+
diff --git a/0026-target-s390x-avoid-cpu_single_env.patch b/0026-target-s390x-avoid-cpu_single_env.patch
new file mode 100644
index 0000000..2b3e6a4
--- /dev/null
+++ b/0026-target-s390x-avoid-cpu_single_env.patch
@@ -0,0 +1,1337 @@
+From d8503917ec9ba86829387f05db7da2eb6fa8123f Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sat, 8 Sep 2012 11:15:37 +0000
+Subject: [PATCH] target-s390x: avoid cpu_single_env
+
+Pass around CPUState instead of using global cpu_single_env.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-s390x/translate.c | 356 ++++++++++++++++++++++++-----------------------
+ 1 file changed, 183 insertions(+), 173 deletions(-)
+
+diff --git a/target-s390x/translate.c b/target-s390x/translate.c
+index 66119cd..3214783 100644
+--- a/target-s390x/translate.c
++++ b/target-s390x/translate.c
+@@ -274,21 +274,21 @@ static inline void potential_page_fault(DisasContext *s)
+ #endif
+ }
+ 
+-static inline uint64_t ld_code2(uint64_t pc)
++static inline uint64_t ld_code2(CPUS390XState *env, uint64_t pc)
+ {
+-    return (uint64_t)cpu_lduw_code(cpu_single_env, pc);
++    return (uint64_t)cpu_lduw_code(env, pc);
+ }
+ 
+-static inline uint64_t ld_code4(uint64_t pc)
++static inline uint64_t ld_code4(CPUS390XState *env, uint64_t pc)
+ {
+-    return (uint64_t)cpu_ldl_code(cpu_single_env, pc);
++    return (uint64_t)cpu_ldl_code(env, pc);
+ }
+ 
+-static inline uint64_t ld_code6(uint64_t pc)
++static inline uint64_t ld_code6(CPUS390XState *env, uint64_t pc)
+ {
+     uint64_t opc;
+-    opc = (uint64_t)cpu_lduw_code(cpu_single_env, pc) << 32;
+-    opc |= (uint64_t)(uint32_t)cpu_ldl_code(cpu_single_env, pc + 2);
++    opc = (uint64_t)cpu_lduw_code(env, pc) << 32;
++    opc |= (uint64_t)(uint32_t)cpu_ldl_code(env, pc + 2);
+     return opc;
+ }
+ 
+@@ -319,7 +319,7 @@ static inline void gen_debug(DisasContext *s)
+ 
+ #ifdef CONFIG_USER_ONLY
+ 
+-static void gen_illegal_opcode(DisasContext *s, int ilc)
++static void gen_illegal_opcode(CPUS390XState *env, DisasContext *s, int ilc)
+ {
+     TCGv_i32 tmp = tcg_const_i32(EXCP_SPEC);
+     update_psw_addr(s);
+@@ -331,20 +331,20 @@ static void gen_illegal_opcode(DisasContext *s, int ilc)
+ 
+ #else /* CONFIG_USER_ONLY */
+ 
+-static void debug_print_inst(DisasContext *s, int ilc)
++static void debug_print_inst(CPUS390XState *env, DisasContext *s, int ilc)
+ {
+ #ifdef DEBUG_ILLEGAL_INSTRUCTIONS
+     uint64_t inst = 0;
+ 
+     switch (ilc & 3) {
+     case 1:
+-        inst = ld_code2(s->pc);
++        inst = ld_code2(env, s->pc);
+         break;
+     case 2:
+-        inst = ld_code4(s->pc);
++        inst = ld_code4(env, s->pc);
+         break;
+     case 3:
+-        inst = ld_code6(s->pc);
++        inst = ld_code6(env, s->pc);
+         break;
+     }
+ 
+@@ -353,11 +353,12 @@ static void debug_print_inst(DisasContext *s, int ilc)
+ #endif
+ }
+ 
+-static void gen_program_exception(DisasContext *s, int ilc, int code)
++static void gen_program_exception(CPUS390XState *env, DisasContext *s, int ilc,
++                                  int code)
+ {
+     TCGv_i32 tmp;
+ 
+-    debug_print_inst(s, ilc);
++    debug_print_inst(env, s, ilc);
+ 
+     /* remember what pgm exeption this was */
+     tmp = tcg_const_i32(code);
+@@ -385,20 +386,21 @@ static void gen_program_exception(DisasContext *s, int ilc, int code)
+ }
+ 
+ 
+-static void gen_illegal_opcode(DisasContext *s, int ilc)
++static void gen_illegal_opcode(CPUS390XState *env, DisasContext *s, int ilc)
+ {
+-    gen_program_exception(s, ilc, PGM_SPECIFICATION);
++    gen_program_exception(env, s, ilc, PGM_SPECIFICATION);
+ }
+ 
+-static void gen_privileged_exception(DisasContext *s, int ilc)
++static void gen_privileged_exception(CPUS390XState *env, DisasContext *s,
++                                     int ilc)
+ {
+-    gen_program_exception(s, ilc, PGM_PRIVILEGED);
++    gen_program_exception(env, s, ilc, PGM_PRIVILEGED);
+ }
+ 
+-static void check_privileged(DisasContext *s, int ilc)
++static void check_privileged(CPUS390XState *env, DisasContext *s, int ilc)
+ {
+     if (s->tb->flags & (PSW_MASK_PSTATE >> 32)) {
+-        gen_privileged_exception(s, ilc);
++        gen_privileged_exception(env, s, ilc);
+     }
+ }
+ 
+@@ -1460,7 +1462,8 @@ static void gen_op_clc(DisasContext *s, int l, TCGv_i64 s1, TCGv_i64 s2)
+     set_cc_static(s);
+ }
+ 
+-static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
++static void disas_e3(CPUS390XState *env, DisasContext* s, int op, int r1,
++                     int x2, int b2, int d2)
+ {
+     TCGv_i64 addr, tmp, tmp2, tmp3, tmp4;
+     TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
+@@ -1925,14 +1928,14 @@ static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
+         break;
+     default:
+         LOG_DISAS("illegal e3 operation 0x%x\n", op);
+-        gen_illegal_opcode(s, 3);
++        gen_illegal_opcode(env, s, 3);
+         break;
+     }
+     tcg_temp_free_i64(addr);
+ }
+ 
+ #ifndef CONFIG_USER_ONLY
+-static void disas_e5(DisasContext* s, uint64_t insn)
++static void disas_e5(CPUS390XState *env, DisasContext* s, uint64_t insn)
+ {
+     TCGv_i64 tmp, tmp2;
+     int op = (insn >> 32) & 0xff;
+@@ -1950,7 +1953,7 @@ static void disas_e5(DisasContext* s, uint64_t insn)
+         break;
+     default:
+         LOG_DISAS("illegal e5 operation 0x%x\n", op);
+-        gen_illegal_opcode(s, 3);
++        gen_illegal_opcode(env, s, 3);
+         break;
+     }
+ 
+@@ -1959,7 +1962,8 @@ static void disas_e5(DisasContext* s, uint64_t insn)
+ }
+ #endif
+ 
+-static void disas_eb(DisasContext *s, int op, int r1, int r3, int b2, int d2)
++static void disas_eb(CPUS390XState *env, DisasContext *s, int op, int r1,
++                     int r3, int b2, int d2)
+ {
+     TCGv_i64 tmp, tmp2, tmp3, tmp4;
+     TCGv_i32 tmp32_1, tmp32_2;
+@@ -2102,7 +2106,7 @@ do_mh:
+ #ifndef CONFIG_USER_ONLY
+     case 0x2f: /* LCTLG     R1,R3,D2(B2)     [RSE] */
+         /* Load Control */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+@@ -2114,7 +2118,7 @@ do_mh:
+         break;
+     case 0x25: /* STCTG     R1,R3,D2(B2)     [RSE] */
+         /* Store Control */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r3);
+@@ -2191,13 +2195,13 @@ do_mh:
+         break;
+     default:
+         LOG_DISAS("illegal eb operation 0x%x\n", op);
+-        gen_illegal_opcode(s, ilc);
++        gen_illegal_opcode(env, s, ilc);
+         break;
+     }
+ }
+ 
+-static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
+-                     int r1b)
++static void disas_ed(CPUS390XState *env, DisasContext *s, int op, int r1,
++                     int x2, int b2, int d2, int r1b)
+ {
+     TCGv_i32 tmp_r1, tmp32;
+     TCGv_i64 addr, tmp;
+@@ -2311,14 +2315,15 @@ static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
+         break;
+     default:
+         LOG_DISAS("illegal ed operation 0x%x\n", op);
+-        gen_illegal_opcode(s, 3);
++        gen_illegal_opcode(env, s, 3);
+         return;
+     }
+     tcg_temp_free_i32(tmp_r1);
+     tcg_temp_free_i64(addr);
+ }
+ 
+-static void disas_a5(DisasContext *s, int op, int r1, int i2)
++static void disas_a5(CPUS390XState *env, DisasContext *s, int op, int r1,
++                     int i2)
+ {
+     TCGv_i64 tmp, tmp2;
+     TCGv_i32 tmp32;
+@@ -2467,12 +2472,13 @@ static void disas_a5(DisasContext *s, int op, int r1, int i2)
+         break;
+     default:
+         LOG_DISAS("illegal a5 operation 0x%x\n", op);
+-        gen_illegal_opcode(s, 2);
++        gen_illegal_opcode(env, s, 2);
+         return;
+     }
+ }
+ 
+-static void disas_a7(DisasContext *s, int op, int r1, int i2)
++static void disas_a7(CPUS390XState *env, DisasContext *s, int op, int r1,
++                     int i2)
+ {
+     TCGv_i64 tmp, tmp2;
+     TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
+@@ -2604,12 +2610,13 @@ static void disas_a7(DisasContext *s, int op, int r1, int i2)
+         break;
+     default:
+         LOG_DISAS("illegal a7 operation 0x%x\n", op);
+-        gen_illegal_opcode(s, 2);
++        gen_illegal_opcode(env, s, 2);
+         return;
+     }
+ }
+ 
+-static void disas_b2(DisasContext *s, int op, uint32_t insn)
++static void disas_b2(CPUS390XState *env, DisasContext *s, int op,
++                     uint32_t insn)
+ {
+     TCGv_i64 tmp, tmp2, tmp3;
+     TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
+@@ -2708,7 +2715,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+ #ifndef CONFIG_USER_ONLY
+     case 0x02: /* STIDP     D2(B2)     [S] */
+         /* Store CPU ID */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+@@ -2717,7 +2724,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x04: /* SCK       D2(B2)     [S] */
+         /* Set Clock */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+@@ -2736,7 +2743,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x06: /* SCKC     D2(B2)     [S] */
+         /* Set Clock Comparator */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+@@ -2745,7 +2752,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x07: /* STCKC    D2(B2)     [S] */
+         /* Store Clock Comparator */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+@@ -2754,7 +2761,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x08: /* SPT      D2(B2)     [S] */
+         /* Set CPU Timer */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+@@ -2763,7 +2770,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x09: /* STPT     D2(B2)     [S] */
+         /* Store CPU Timer */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+@@ -2772,7 +2779,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x0a: /* SPKA     D2(B2)     [S] */
+         /* Set PSW Key from Address */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp2 = tcg_temp_new_i64();
+@@ -2784,12 +2791,12 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x0d: /* PTLB                [S] */
+         /* Purge TLB */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         gen_helper_ptlb(cpu_env);
+         break;
+     case 0x10: /* SPX      D2(B2)     [S] */
+         /* Set Prefix Register */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+@@ -2798,7 +2805,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x11: /* STPX     D2(B2)     [S] */
+         /* Store Prefix */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp2 = tcg_temp_new_i64();
+@@ -2809,7 +2816,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x12: /* STAP     D2(B2)     [S] */
+         /* Store CPU Address */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp2 = tcg_temp_new_i64();
+@@ -2823,7 +2830,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x21: /* IPTE     R1,R2      [RRE] */
+         /* Invalidate PTE */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         r1 = (insn >> 4) & 0xf;
+         r2 = insn & 0xf;
+         tmp = load_reg(r1);
+@@ -2834,7 +2841,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x29: /* ISKE     R1,R2      [RRE] */
+         /* Insert Storage Key Extended */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         r1 = (insn >> 4) & 0xf;
+         r2 = insn & 0xf;
+         tmp = load_reg(r2);
+@@ -2846,7 +2853,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x2a: /* RRBE     R1,R2      [RRE] */
+         /* Set Storage Key Extended */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         r1 = (insn >> 4) & 0xf;
+         r2 = insn & 0xf;
+         tmp32_1 = load_reg32(r1);
+@@ -2858,7 +2865,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x2b: /* SSKE     R1,R2      [RRE] */
+         /* Set Storage Key Extended */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         r1 = (insn >> 4) & 0xf;
+         r2 = insn & 0xf;
+         tmp32_1 = load_reg32(r1);
+@@ -2869,12 +2876,12 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x34: /* STCH ? */
+         /* Store Subchannel */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         gen_op_movi_cc(s, 3);
+         break;
+     case 0x46: /* STURA    R1,R2      [RRE] */
+         /* Store Using Real Address */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         r1 = (insn >> 4) & 0xf;
+         r2 = insn & 0xf;
+         tmp32_1 = load_reg32(r1);
+@@ -2886,7 +2893,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x50: /* CSP      R1,R2      [RRE] */
+         /* Compare And Swap And Purge */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         r1 = (insn >> 4) & 0xf;
+         r2 = insn & 0xf;
+         tmp32_1 = tcg_const_i32(r1);
+@@ -2898,7 +2905,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x5f: /* CHSC ? */
+         /* Channel Subsystem Call */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         gen_op_movi_cc(s, 3);
+         break;
+     case 0x78: /* STCKE    D2(B2)     [S] */
+@@ -2912,7 +2919,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x79: /* SACF    D2(B2)     [S] */
+         /* Store Clock Extended */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         potential_page_fault(s);
+@@ -2924,7 +2931,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         s->is_jmp = DISAS_EXCP;
+         break;
+     case 0x7d: /* STSI     D2,(B2)     [S] */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = load_reg32(0);
+@@ -2950,7 +2957,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0xb1: /* STFL     D2(B2)     [S] */
+         /* Store Facility List (CPU features) at 200 */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         tmp2 = tcg_const_i64(0xc0000000);
+         tmp = tcg_const_i64(200);
+         tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
+@@ -2959,7 +2966,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0xb2: /* LPSWE    D2(B2)     [S] */
+         /* Load PSW Extended */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp2 = tcg_temp_new_i64();
+@@ -2976,7 +2983,7 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+         break;
+     case 0x20: /* SERVC     R1,R2     [RRE] */
+         /* SCLP Service call (PV hypercall) */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         potential_page_fault(s);
+         tmp32_1 = load_reg32(r2);
+         tmp = load_reg(r1);
+@@ -2988,12 +2995,13 @@ static void disas_b2(DisasContext *s, int op, uint32_t insn)
+ #endif
+     default:
+         LOG_DISAS("illegal b2 operation 0x%x\n", op);
+-        gen_illegal_opcode(s, ilc);
++        gen_illegal_opcode(env, s, ilc);
+         break;
+     }
+ }
+ 
+-static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
++static void disas_b3(CPUS390XState *env, DisasContext *s, int op, int m3,
++                     int r1, int r2)
+ {
+     TCGv_i64 tmp;
+     TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
+@@ -3263,7 +3271,7 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+         break;
+     default:
+         LOG_DISAS("illegal b3 operation 0x%x\n", op);
+-        gen_illegal_opcode(s, 2);
++        gen_illegal_opcode(env, s, 2);
+         break;
+     }
+ 
+@@ -3271,7 +3279,8 @@ static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
+ #undef FP_HELPER
+ }
+ 
+-static void disas_b9(DisasContext *s, int op, int r1, int r2)
++static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
++                     int r2)
+ {
+     TCGv_i64 tmp, tmp2, tmp3;
+     TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
+@@ -3654,12 +3663,12 @@ static void disas_b9(DisasContext *s, int op, int r1, int r2)
+         break;
+     default:
+         LOG_DISAS("illegal b9 operation 0x%x\n", op);
+-        gen_illegal_opcode(s, 2);
++        gen_illegal_opcode(env, s, 2);
+         break;
+     }
+ }
+ 
+-static void disas_c0(DisasContext *s, int op, int r1, int i2)
++static void disas_c0(CPUS390XState *env, DisasContext *s, int op, int r1, int i2)
+ {
+     TCGv_i64 tmp;
+     TCGv_i32 tmp32_1, tmp32_2;
+@@ -3755,12 +3764,13 @@ static void disas_c0(DisasContext *s, int op, int r1, int i2)
+         break;
+     default:
+         LOG_DISAS("illegal c0 operation 0x%x\n", op);
+-        gen_illegal_opcode(s, 3);
++        gen_illegal_opcode(env, s, 3);
+         break;
+     }
+ }
+ 
+-static void disas_c2(DisasContext *s, int op, int r1, int i2)
++static void disas_c2(CPUS390XState *env, DisasContext *s, int op, int r1,
++                     int i2)
+ {
+     TCGv_i64 tmp, tmp2, tmp3;
+     TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
+@@ -3832,7 +3842,7 @@ static void disas_c2(DisasContext *s, int op, int r1, int i2)
+         break;
+     default:
+         LOG_DISAS("illegal c2 operation 0x%x\n", op);
+-        gen_illegal_opcode(s, 3);
++        gen_illegal_opcode(env, s, 3);
+         break;
+     }
+ }
+@@ -3854,7 +3864,7 @@ static void gen_and_or_xor_i32(int opc, TCGv_i32 tmp, TCGv_i32 tmp2)
+     }
+ }
+ 
+-static void disas_s390_insn(DisasContext *s)
++static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
+ {
+     TCGv_i64 tmp, tmp2, tmp3, tmp4;
+     TCGv_i32 tmp32_1, tmp32_2, tmp32_3, tmp32_4;
+@@ -3865,7 +3875,7 @@ static void disas_s390_insn(DisasContext *s)
+     int ilc;
+     int l1;
+ 
+-    opc = cpu_ldub_code(cpu_single_env, s->pc);
++    opc = cpu_ldub_code(env, s->pc);
+     LOG_DISAS("opc 0x%x\n", opc);
+ 
+     ilc = get_ilc(opc);
+@@ -3873,12 +3883,12 @@ static void disas_s390_insn(DisasContext *s)
+     switch (opc) {
+ #ifndef CONFIG_USER_ONLY
+     case 0x01: /* SAM */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         /* set addressing mode, but we only do 64bit anyways */
+         break;
+ #endif
+     case 0x6: /* BCTR     R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_reg32(r1);
+         tcg_gen_subi_i32(tmp32_1, tmp32_1, 1);
+@@ -3904,7 +3914,7 @@ static void disas_s390_insn(DisasContext *s)
+         }
+         break;
+     case 0x7: /* BCR    M1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         if (r2) {
+             tmp = load_reg(r2);
+@@ -3916,7 +3926,7 @@ static void disas_s390_insn(DisasContext *s)
+         }
+         break;
+     case 0xa: /* SVC    I         [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         debug_insn(insn);
+         i = insn & 0xff;
+         update_psw_addr(s);
+@@ -3933,7 +3943,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_3);
+         break;
+     case 0xd: /* BASR   R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp = tcg_const_i64(pc_to_link_info(s, s->pc + 2));
+         store_reg(r1, tmp);
+@@ -3946,7 +3956,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp);
+         break;
+     case 0xe: /* MVCL   R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = tcg_const_i32(r1);
+         tmp32_2 = tcg_const_i32(r2);
+@@ -3957,7 +3967,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_2);
+         break;
+     case 0x10: /* LPR    R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_reg32(r2);
+         set_cc_abs32(s, tmp32_1);
+@@ -3966,7 +3976,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x11: /* LNR    R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_reg32(r2);
+         set_cc_nabs32(s, tmp32_1);
+@@ -3975,7 +3985,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x12: /* LTR    R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_reg32(r2);
+         if (r1 != r2) {
+@@ -3985,7 +3995,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x13: /* LCR    R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_reg32(r2);
+         tcg_gen_neg_i32(tmp32_1, tmp32_1);
+@@ -3996,7 +4006,7 @@ static void disas_s390_insn(DisasContext *s)
+     case 0x14: /* NR     R1,R2     [RR] */
+     case 0x16: /* OR     R1,R2     [RR] */
+     case 0x17: /* XR     R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_2 = load_reg32(r2);
+         tmp32_1 = load_reg32(r1);
+@@ -4007,7 +4017,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_2);
+         break;
+     case 0x18: /* LR     R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_reg32(r2);
+         store_reg32(r1, tmp32_1);
+@@ -4015,7 +4025,7 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+     case 0x15: /* CLR    R1,R2     [RR] */
+     case 0x19: /* CR     R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_reg32(r1);
+         tmp32_2 = load_reg32(r2);
+@@ -4029,7 +4039,7 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+     case 0x1a: /* AR     R1,R2     [RR] */
+     case 0x1e: /* ALR    R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_reg32(r1);
+         tmp32_2 = load_reg32(r2);
+@@ -4047,7 +4057,7 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+     case 0x1b: /* SR     R1,R2     [RR] */
+     case 0x1f: /* SLR    R1,R2     [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_reg32(r1);
+         tmp32_2 = load_reg32(r2);
+@@ -4065,7 +4075,7 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+     case 0x1c: /* MR     R1,R2     [RR] */
+         /* reg(r1, r1+1) = reg(r1+1) * reg(r2) */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp2 = load_reg(r2);
+         tmp3 = load_reg((r1 + 1) & 15);
+@@ -4079,7 +4089,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp3);
+         break;
+     case 0x1d: /* DR     R1,R2               [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_reg32(r1);
+         tmp32_2 = load_reg32(r1 + 1);
+@@ -4114,21 +4124,21 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp3);
+         break;
+     case 0x28: /* LDR    R1,R2               [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp = load_freg(r2);
+         store_freg(r1, tmp);
+         tcg_temp_free_i64(tmp);
+         break;
+     case 0x38: /* LER    R1,R2               [RR] */
+-        insn = ld_code2(s->pc);
++        insn = ld_code2(env, s->pc);
+         decode_rr(s, insn, &r1, &r2);
+         tmp32_1 = load_freg32(r2);
+         store_freg32(r1, tmp32_1);
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x40: /* STH    R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = load_reg(r1);
+         tcg_gen_qemu_st16(tmp2, tmp, get_mem_index(s));
+@@ -4136,13 +4146,13 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x41:        /* la */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         store_reg(r1, tmp); /* FIXME: 31/24-bit addressing */
+         tcg_temp_free_i64(tmp);
+         break;
+     case 0x42: /* STC    R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = load_reg(r1);
+         tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s));
+@@ -4150,7 +4160,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x43: /* IC     R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s));
+@@ -4159,7 +4169,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x44: /* EX     R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = load_reg(r1);
+         tmp3 = tcg_const_i64(s->pc + 4);
+@@ -4172,7 +4182,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp3);
+         break;
+     case 0x46: /* BCT    R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tcg_temp_free_i64(tmp);
+ 
+@@ -4196,14 +4206,14 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp);
+         break;
+     case 0x47: /* BC     M1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         gen_bcr(s, r1, tmp, s->pc + 4);
+         tcg_temp_free_i64(tmp);
+         s->is_jmp = DISAS_TB_JUMP;
+         break;
+     case 0x48: /* LH     R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tcg_gen_qemu_ld16s(tmp2, tmp, get_mem_index(s));
+@@ -4212,7 +4222,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x49: /* CH     R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp32_1 = load_reg32(r1);
+         tmp32_2 = tcg_temp_new_i32();
+@@ -4228,7 +4238,7 @@ static void disas_s390_insn(DisasContext *s)
+     case 0x4a: /* AH     R1,D2(X2,B2)     [RX] */
+     case 0x4b: /* SH     R1,D2(X2,B2)     [RX] */
+     case 0x4c: /* MH     R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = load_reg32(r1);
+@@ -4261,7 +4271,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x4d: /* BAS    R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_const_i64(pc_to_link_info(s, s->pc + 4));
+         store_reg(r1, tmp2);
+@@ -4271,7 +4281,7 @@ static void disas_s390_insn(DisasContext *s)
+         s->is_jmp = DISAS_JUMP;
+         break;
+     case 0x4e: /* CVD    R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = tcg_temp_new_i32();
+@@ -4283,7 +4293,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x50: /* st r1, d2(x2, b2) */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = load_reg(r1);
+         tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
+@@ -4291,7 +4301,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x55: /* CL     R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = tcg_temp_new_i32();
+@@ -4307,7 +4317,7 @@ static void disas_s390_insn(DisasContext *s)
+     case 0x54: /* N      R1,D2(X2,B2)     [RX] */
+     case 0x56: /* O      R1,D2(X2,B2)     [RX] */
+     case 0x57: /* X      R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = load_reg32(r1);
+@@ -4323,7 +4333,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_2);
+         break;
+     case 0x58: /* l r1, d2(x2, b2) */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = tcg_temp_new_i32();
+@@ -4335,7 +4345,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x59: /* C      R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = tcg_temp_new_i32();
+@@ -4352,7 +4362,7 @@ static void disas_s390_insn(DisasContext *s)
+     case 0x5b: /* S      R1,D2(X2,B2)     [RX] */
+     case 0x5e: /* AL     R1,D2(X2,B2)     [RX] */
+     case 0x5f: /* SL     R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp32_1 = load_reg32(r1);
+         tmp32_2 = tcg_temp_new_i32();
+@@ -4395,7 +4405,7 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+     case 0x5c: /* M      R1,D2(X2,B2)        [RX] */
+         /* reg(r1, r1+1) = reg(r1+1) * *(s32*)addr */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tcg_gen_qemu_ld32s(tmp2, tmp, get_mem_index(s));
+@@ -4411,7 +4421,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp3);
+         break;
+     case 0x5d: /* D      R1,D2(X2,B2)        [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp3 = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp32_1 = load_reg32(r1);
+         tmp32_2 = load_reg32(r1 + 1);
+@@ -4445,7 +4455,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp3);
+         break;
+     case 0x60: /* STD    R1,D2(X2,B2)        [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = load_freg(r1);
+         tcg_gen_qemu_st64(tmp2, tmp, get_mem_index(s));
+@@ -4453,7 +4463,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x68: /* LD    R1,D2(X2,B2)        [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tcg_gen_qemu_ld64(tmp2, tmp, get_mem_index(s));
+@@ -4462,7 +4472,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x70: /* STE R1,D2(X2,B2) [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = load_freg32(r1);
+@@ -4473,7 +4483,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0x71: /* MS      R1,D2(X2,B2)     [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = load_reg32(r1);
+@@ -4488,7 +4498,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_2);
+         break;
+     case 0x78: /* LE     R1,D2(X2,B2)        [RX] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp2 = tcg_temp_new_i64();
+         tmp32_1 = tcg_temp_new_i32();
+@@ -4502,8 +4512,8 @@ static void disas_s390_insn(DisasContext *s)
+ #ifndef CONFIG_USER_ONLY
+     case 0x80: /* SSM      D2(B2)       [S] */
+         /* Set System Mask */
+-        check_privileged(s, ilc);
+-        insn = ld_code4(s->pc);
++        check_privileged(env, s, ilc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp2 = tcg_temp_new_i64();
+@@ -4518,8 +4528,8 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+     case 0x82: /* LPSW     D2(B2)       [S] */
+         /* Load PSW */
+-        check_privileged(s, ilc);
+-        insn = ld_code4(s->pc);
++        check_privileged(env, s, ilc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp2 = tcg_temp_new_i64();
+@@ -4536,9 +4546,9 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+     case 0x83: /* DIAG     R1,R3,D2     [RS] */
+         /* Diagnose call (KVM hypercall) */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         potential_page_fault(s);
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp32_1 = tcg_const_i32(insn & 0xfff);
+         tmp2 = load_reg(2);
+@@ -4553,7 +4563,7 @@ static void disas_s390_insn(DisasContext *s)
+     case 0x88: /* SRL    R1,D2(B2)        [RS] */
+     case 0x89: /* SLL    R1,D2(B2)        [RS] */
+     case 0x8a: /* SRA    R1,D2(B2)        [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = load_reg32(r1);
+@@ -4582,7 +4592,7 @@ static void disas_s390_insn(DisasContext *s)
+     case 0x8c: /* SRDL   R1,D2(B2)        [RS] */
+     case 0x8d: /* SLDL   R1,D2(B2)        [RS] */
+     case 0x8e: /* SRDA   R1,D2(B2)        [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2); /* shift */
+         tmp2 = tcg_temp_new_i64();
+@@ -4611,7 +4621,7 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+     case 0x98: /* LM     R1,R3,D2(B2)     [RS] */
+     case 0x90: /* STM    R1,R3,D2(B2)     [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+ 
+         tmp = get_address(s, 0, b2, d2);
+@@ -4637,7 +4647,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp4);
+         break;
+     case 0x91: /* TM     D1(B1),I2        [SI] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_si(s, insn, &i2, &b1, &d1);
+         tmp2 = tcg_const_i64(i2);
+         tcg_gen_qemu_ld8u(tmp, tmp, get_mem_index(s));
+@@ -4646,7 +4656,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x92: /* MVI    D1(B1),I2        [SI] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_si(s, insn, &i2, &b1, &d1);
+         tmp2 = tcg_const_i64(i2);
+         tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s));
+@@ -4656,7 +4666,7 @@ static void disas_s390_insn(DisasContext *s)
+     case 0x94: /* NI     D1(B1),I2        [SI] */
+     case 0x96: /* OI     D1(B1),I2        [SI] */
+     case 0x97: /* XI     D1(B1),I2        [SI] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_si(s, insn, &i2, &b1, &d1);
+         tmp2 = tcg_temp_new_i64();
+         tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s));
+@@ -4679,7 +4689,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x95: /* CLI    D1(B1),I2        [SI] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_si(s, insn, &i2, &b1, &d1);
+         tmp2 = tcg_temp_new_i64();
+         tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s));
+@@ -4688,7 +4698,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0x9a: /* LAM      R1,R3,D2(B2)     [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = tcg_const_i32(r1);
+@@ -4700,7 +4710,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_2);
+         break;
+     case 0x9b: /* STAM     R1,R3,D2(B2)     [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = tcg_const_i32(r1);
+@@ -4712,21 +4722,21 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_2);
+         break;
+     case 0xa5:
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         r1 = (insn >> 20) & 0xf;
+         op = (insn >> 16) & 0xf;
+         i2 = insn & 0xffff;
+-        disas_a5(s, op, r1, i2);
++        disas_a5(env, s, op, r1, i2);
+         break;
+     case 0xa7:
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         r1 = (insn >> 20) & 0xf;
+         op = (insn >> 16) & 0xf;
+         i2 = (short)insn;
+-        disas_a7(s, op, r1, i2);
++        disas_a7(env, s, op, r1, i2);
+         break;
+     case 0xa8: /* MVCLE   R1,R3,D2(B2)     [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = tcg_const_i32(r1);
+@@ -4739,7 +4749,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_2);
+         break;
+     case 0xa9: /* CLCLE   R1,R3,D2(B2)     [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = tcg_const_i32(r1);
+@@ -4754,8 +4764,8 @@ static void disas_s390_insn(DisasContext *s)
+ #ifndef CONFIG_USER_ONLY
+     case 0xac: /* STNSM   D1(B1),I2     [SI] */
+     case 0xad: /* STOSM   D1(B1),I2     [SI] */
+-        check_privileged(s, ilc);
+-        insn = ld_code4(s->pc);
++        check_privileged(env, s, ilc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_si(s, insn, &i2, &b1, &d1);
+         tmp2 = tcg_temp_new_i64();
+         tcg_gen_shri_i64(tmp2, psw_mask, 56);
+@@ -4770,8 +4780,8 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i64(tmp2);
+         break;
+     case 0xae: /* SIGP   R1,R3,D2(B2)     [RS] */
+-        check_privileged(s, ilc);
+-        insn = ld_code4(s->pc);
++        check_privileged(env, s, ilc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp2 = load_reg(r3);
+@@ -4784,8 +4794,8 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_1);
+         break;
+     case 0xb1: /* LRA    R1,D2(X2, B2)     [RX] */
+-        check_privileged(s, ilc);
+-        insn = ld_code4(s->pc);
++        check_privileged(env, s, ilc);
++        insn = ld_code4(env, s->pc);
+         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
+         tmp32_1 = tcg_const_i32(r1);
+         potential_page_fault(s);
+@@ -4796,7 +4806,7 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+ #endif
+     case 0xb2:
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         op = (insn >> 16) & 0xff;
+         switch (op) {
+         case 0x9c: /* STFPC    D2(B2) [S] */
+@@ -4813,23 +4823,23 @@ static void disas_s390_insn(DisasContext *s)
+             tcg_temp_free_i64(tmp2);
+             break;
+         default:
+-            disas_b2(s, op, insn);
++            disas_b2(env, s, op, insn);
+             break;
+         }
+         break;
+     case 0xb3:
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         op = (insn >> 16) & 0xff;
+         r3 = (insn >> 12) & 0xf; /* aka m3 */
+         r1 = (insn >> 4) & 0xf;
+         r2 = insn & 0xf;
+-        disas_b3(s, op, r3, r1, r2);
++        disas_b3(env, s, op, r3, r1, r2);
+         break;
+ #ifndef CONFIG_USER_ONLY
+     case 0xb6: /* STCTL     R1,R3,D2(B2)     [RS] */
+         /* Store Control */
+-        check_privileged(s, ilc);
+-        insn = ld_code4(s->pc);
++        check_privileged(env, s, ilc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = tcg_const_i32(r1);
+@@ -4842,8 +4852,8 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+     case 0xb7: /* LCTL      R1,R3,D2(B2)     [RS] */
+         /* Load Control */
+-        check_privileged(s, ilc);
+-        insn = ld_code4(s->pc);
++        check_privileged(env, s, ilc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = tcg_const_i32(r1);
+@@ -4856,14 +4866,14 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+ #endif
+     case 0xb9:
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         r1 = (insn >> 4) & 0xf;
+         r2 = insn & 0xf;
+         op = (insn >> 16) & 0xff;
+-        disas_b9(s, op, r1, r2);
++        disas_b9(env, s, op, r1, r2);
+         break;
+     case 0xba: /* CS     R1,R3,D2(B2)     [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = tcg_const_i32(r1);
+@@ -4876,7 +4886,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_2);
+         break;
+     case 0xbd: /* CLM    R1,M3,D2(B2)     [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = load_reg32(r1);
+@@ -4889,7 +4899,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_2);
+         break;
+     case 0xbe: /* STCM R1,M3,D2(B2) [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         tmp = get_address(s, 0, b2, d2);
+         tmp32_1 = load_reg32(r1);
+@@ -4901,7 +4911,7 @@ static void disas_s390_insn(DisasContext *s)
+         tcg_temp_free_i32(tmp32_2);
+         break;
+     case 0xbf: /* ICM    R1,M3,D2(B2)     [RS] */
+-        insn = ld_code4(s->pc);
++        insn = ld_code4(env, s->pc);
+         decode_rs(s, insn, &r1, &r3, &b2, &d2);
+         if (r3 == 15) {
+             /* effectively a 32-bit load */
+@@ -4956,16 +4966,16 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+     case 0xc0:
+     case 0xc2:
+-        insn = ld_code6(s->pc);
++        insn = ld_code6(env, s->pc);
+         r1 = (insn >> 36) & 0xf;
+         op = (insn >> 32) & 0xf;
+         i2 = (int)insn;
+         switch (opc) {
+         case 0xc0:
+-            disas_c0(s, op, r1, i2);
++            disas_c0(env, s, op, r1, i2);
+             break;
+         case 0xc2:
+-            disas_c2(s, op, r1, i2);
++            disas_c2(env, s, op, r1, i2);
+             break;
+         default:
+             tcg_abort();
+@@ -4978,7 +4988,7 @@ static void disas_s390_insn(DisasContext *s)
+     case 0xd7: /* XC     D1(L,B1),D2(B2)         [SS] */
+     case 0xdc: /* TR     D1(L,B1),D2(B2)         [SS] */
+     case 0xf3: /* UNPK   D1(L1,B1),D2(L2,B2)     [SS] */
+-        insn = ld_code6(s->pc);
++        insn = ld_code6(env, s->pc);
+         vl = tcg_const_i32((insn >> 32) & 0xff);
+         b1 = (insn >> 28) & 0xf;
+         b2 = (insn >> 12) & 0xf;
+@@ -5026,9 +5036,9 @@ static void disas_s390_insn(DisasContext *s)
+ #ifndef CONFIG_USER_ONLY
+     case 0xda: /* MVCP     D1(R1,B1),D2(B2),R3   [SS] */
+     case 0xdb: /* MVCS     D1(R1,B1),D2(B2),R3   [SS] */
+-        check_privileged(s, ilc);
++        check_privileged(env, s, ilc);
+         potential_page_fault(s);
+-        insn = ld_code6(s->pc);
++        insn = ld_code6(env, s->pc);
+         r1 = (insn >> 36) & 0xf;
+         r3 = (insn >> 32) & 0xf;
+         b1 = (insn >> 28) & 0xf;
+@@ -5051,7 +5061,7 @@ static void disas_s390_insn(DisasContext *s)
+         break;
+ #endif
+     case 0xe3:
+-        insn = ld_code6(s->pc);
++        insn = ld_code6(env, s->pc);
+         debug_insn(insn);
+         op = insn & 0xff;
+         r1 = (insn >> 36) & 0xf;
+@@ -5059,19 +5069,19 @@ static void disas_s390_insn(DisasContext *s)
+         b2 = (insn >> 28) & 0xf;
+         d2 = ((int)((((insn >> 16) & 0xfff)
+            | ((insn << 4) & 0xff000)) << 12)) >> 12;
+-        disas_e3(s, op,  r1, x2, b2, d2 );
++        disas_e3(env, s, op,  r1, x2, b2, d2 );
+         break;
+ #ifndef CONFIG_USER_ONLY
+     case 0xe5:
+         /* Test Protection */
+-        check_privileged(s, ilc);
+-        insn = ld_code6(s->pc);
++        check_privileged(env, s, ilc);
++        insn = ld_code6(env, s->pc);
+         debug_insn(insn);
+-        disas_e5(s, insn);
++        disas_e5(env, s, insn);
+         break;
+ #endif
+     case 0xeb:
+-        insn = ld_code6(s->pc);
++        insn = ld_code6(env, s->pc);
+         debug_insn(insn);
+         op = insn & 0xff;
+         r1 = (insn >> 36) & 0xf;
+@@ -5079,10 +5089,10 @@ static void disas_s390_insn(DisasContext *s)
+         b2 = (insn >> 28) & 0xf;
+         d2 = ((int)((((insn >> 16) & 0xfff)
+            | ((insn << 4) & 0xff000)) << 12)) >> 12;
+-        disas_eb(s, op, r1, r3, b2, d2);
++        disas_eb(env, s, op, r1, r3, b2, d2);
+         break;
+     case 0xed:
+-        insn = ld_code6(s->pc);
++        insn = ld_code6(env, s->pc);
+         debug_insn(insn);
+         op = insn & 0xff;
+         r1 = (insn >> 36) & 0xf;
+@@ -5090,11 +5100,11 @@ static void disas_s390_insn(DisasContext *s)
+         b2 = (insn >> 28) & 0xf;
+         d2 = (short)((insn >> 16) & 0xfff);
+         r1b = (insn >> 12) & 0xf;
+-        disas_ed(s, op, r1, x2, b2, d2, r1b);
++        disas_ed(env, s, op, r1, x2, b2, d2, r1b);
+         break;
+     default:
+         qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%x\n", opc);
+-        gen_illegal_opcode(s, ilc);
++        gen_illegal_opcode(env, s, ilc);
+         break;
+     }
+ 
+@@ -5167,7 +5177,7 @@ static inline void gen_intermediate_code_internal(CPUS390XState *env,
+         LOG_DISAS("pc " TARGET_FMT_lx "\n",
+                   dc.pc);
+ #endif
+-        disas_s390_insn(&dc);
++        disas_s390_insn(env, &dc);
+ 
+         num_insns++;
+         if (env->singlestep_enabled) {
+-- 
+1.7.12.1
+
diff --git a/0027-target-lm32-switch-to-AREG0-free-mode.patch b/0027-target-lm32-switch-to-AREG0-free-mode.patch
new file mode 100644
index 0000000..9a92a12
--- /dev/null
+++ b/0027-target-lm32-switch-to-AREG0-free-mode.patch
@@ -0,0 +1,282 @@
+From 25e9a95d0571c40738daa479467d757eb477739e Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 06:57:17 +0000
+Subject: [PATCH] target-lm32: switch to AREG0 free mode
+
+Add an explicit CPUState parameter instead of relying on AREG0
+and switch to AREG0 free mode.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure                 |  2 +-
+ target-lm32/Makefile.objs |  2 --
+ target-lm32/helper.h      | 20 ++++++++++----------
+ target-lm32/op_helper.c   | 29 +++++++++++------------------
+ target-lm32/translate.c   | 28 +++++++++++++---------------
+ 5 files changed, 35 insertions(+), 46 deletions(-)
+
+diff --git a/configure b/configure
+index 3ad6f74..1e3ea7f 100755
+--- a/configure
++++ b/configure
+@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+ 
+ 
+ case "$target_arch2" in
+-  alpha | i386 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
++  alpha | i386 | lm32 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
+     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
+   ;;
+ esac
+diff --git a/target-lm32/Makefile.objs b/target-lm32/Makefile.objs
+index 2e0e093..ca20f21 100644
+--- a/target-lm32/Makefile.objs
++++ b/target-lm32/Makefile.objs
+@@ -1,4 +1,2 @@
+ obj-y += translate.o op_helper.o helper.o cpu.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+-
+-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-lm32/helper.h b/target-lm32/helper.h
+index 9d335ef..07f5670 100644
+--- a/target-lm32/helper.h
++++ b/target-lm32/helper.h
+@@ -1,14 +1,14 @@
+ #include "def-helper.h"
+ 
+-DEF_HELPER_1(raise_exception, void, i32)
+-DEF_HELPER_0(hlt, void)
+-DEF_HELPER_1(wcsr_im, void, i32)
+-DEF_HELPER_1(wcsr_ip, void, i32)
+-DEF_HELPER_1(wcsr_jtx, void, i32)
+-DEF_HELPER_1(wcsr_jrx, void, i32)
+-DEF_HELPER_0(rcsr_im, i32)
+-DEF_HELPER_0(rcsr_ip, i32)
+-DEF_HELPER_0(rcsr_jtx, i32)
+-DEF_HELPER_0(rcsr_jrx, i32)
++DEF_HELPER_2(raise_exception, void, env, i32)
++DEF_HELPER_1(hlt, void, env)
++DEF_HELPER_2(wcsr_im, void, env, i32)
++DEF_HELPER_2(wcsr_ip, void, env, i32)
++DEF_HELPER_2(wcsr_jtx, void, env, i32)
++DEF_HELPER_2(wcsr_jrx, void, env, i32)
++DEF_HELPER_1(rcsr_im, i32, env)
++DEF_HELPER_1(rcsr_ip, i32, env)
++DEF_HELPER_1(rcsr_jtx, i32, env)
++DEF_HELPER_1(rcsr_jrx, i32, env)
+ 
+ #include "def-helper.h"
+diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
+index 51edc1a..7b91d8c 100644
+--- a/target-lm32/op_helper.c
++++ b/target-lm32/op_helper.c
+@@ -1,6 +1,5 @@
+ #include <assert.h>
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "helper.h"
+ #include "host-utils.h"
+ 
+@@ -18,55 +17,55 @@
+ #define SHIFT 3
+ #include "softmmu_template.h"
+ 
+-void helper_raise_exception(uint32_t index)
++void helper_raise_exception(CPULM32State *env, uint32_t index)
+ {
+     env->exception_index = index;
+     cpu_loop_exit(env);
+ }
+ 
+-void helper_hlt(void)
++void helper_hlt(CPULM32State *env)
+ {
+     env->halted = 1;
+     env->exception_index = EXCP_HLT;
+     cpu_loop_exit(env);
+ }
+ 
+-void helper_wcsr_im(uint32_t im)
++void helper_wcsr_im(CPULM32State *env, uint32_t im)
+ {
+     lm32_pic_set_im(env->pic_state, im);
+ }
+ 
+-void helper_wcsr_ip(uint32_t im)
++void helper_wcsr_ip(CPULM32State *env, uint32_t im)
+ {
+     lm32_pic_set_ip(env->pic_state, im);
+ }
+ 
+-void helper_wcsr_jtx(uint32_t jtx)
++void helper_wcsr_jtx(CPULM32State *env, uint32_t jtx)
+ {
+     lm32_juart_set_jtx(env->juart_state, jtx);
+ }
+ 
+-void helper_wcsr_jrx(uint32_t jrx)
++void helper_wcsr_jrx(CPULM32State *env, uint32_t jrx)
+ {
+     lm32_juart_set_jrx(env->juart_state, jrx);
+ }
+ 
+-uint32_t helper_rcsr_im(void)
++uint32_t helper_rcsr_im(CPULM32State *env)
+ {
+     return lm32_pic_get_im(env->pic_state);
+ }
+ 
+-uint32_t helper_rcsr_ip(void)
++uint32_t helper_rcsr_ip(CPULM32State *env)
+ {
+     return lm32_pic_get_ip(env->pic_state);
+ }
+ 
+-uint32_t helper_rcsr_jtx(void)
++uint32_t helper_rcsr_jtx(CPULM32State *env)
+ {
+     return lm32_juart_get_jtx(env->juart_state);
+ }
+ 
+-uint32_t helper_rcsr_jrx(void)
++uint32_t helper_rcsr_jrx(CPULM32State *env)
+ {
+     return lm32_juart_get_jrx(env->juart_state);
+ }
+@@ -74,17 +73,12 @@ uint32_t helper_rcsr_jrx(void)
+ /* Try to fill the TLB and return an exception if error. If retaddr is
+    NULL, it means that the function was called in C code (i.e. not
+    from generated code or from helper.c) */
+-/* XXX: fix it to restore all registers */
+-void tlb_fill(CPULM32State *env1, target_ulong addr, int is_write, int mmu_idx,
++void tlb_fill(CPULM32State *env, target_ulong addr, int is_write, int mmu_idx,
+               uintptr_t retaddr)
+ {
+     TranslationBlock *tb;
+-    CPULM32State *saved_env;
+     int ret;
+ 
+-    saved_env = env;
+-    env = env1;
+-
+     ret = cpu_lm32_handle_mmu_fault(env, addr, is_write, mmu_idx);
+     if (unlikely(ret)) {
+         if (retaddr) {
+@@ -98,7 +92,6 @@ void tlb_fill(CPULM32State *env1, target_ulong addr, int is_write, int mmu_idx,
+         }
+         cpu_loop_exit(env);
+     }
+-    env = saved_env;
+ }
+ #endif
+ 
+diff --git a/target-lm32/translate.c b/target-lm32/translate.c
+index 872a2ba..5f6dcba 100644
+--- a/target-lm32/translate.c
++++ b/target-lm32/translate.c
+@@ -116,7 +116,7 @@ static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
+ {
+     TCGv_i32 tmp = tcg_const_i32(index);
+ 
+-    gen_helper_raise_exception(tmp);
++    gen_helper_raise_exception(cpu_env, tmp);
+     tcg_temp_free_i32(tmp);
+ }
+ 
+@@ -179,7 +179,7 @@ static void dec_and(DisasContext *dc)
+     } else  {
+         if (dc->r0 == 0 && dc->r1 == 0 && dc->r2 == 0) {
+             tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
+-            gen_helper_hlt();
++            gen_helper_hlt(cpu_env);
+         } else {
+             tcg_gen_and_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);
+         }
+@@ -601,10 +601,10 @@ static void dec_rcsr(DisasContext *dc)
+         tcg_gen_mov_tl(cpu_R[dc->r2], cpu_ie);
+         break;
+     case CSR_IM:
+-        gen_helper_rcsr_im(cpu_R[dc->r2]);
++        gen_helper_rcsr_im(cpu_R[dc->r2], cpu_env);
+         break;
+     case CSR_IP:
+-        gen_helper_rcsr_ip(cpu_R[dc->r2]);
++        gen_helper_rcsr_ip(cpu_R[dc->r2], cpu_env);
+         break;
+     case CSR_CC:
+         tcg_gen_mov_tl(cpu_R[dc->r2], cpu_cc);
+@@ -622,10 +622,10 @@ static void dec_rcsr(DisasContext *dc)
+         tcg_gen_mov_tl(cpu_R[dc->r2], cpu_deba);
+         break;
+     case CSR_JTX:
+-        gen_helper_rcsr_jtx(cpu_R[dc->r2]);
++        gen_helper_rcsr_jtx(cpu_R[dc->r2], cpu_env);
+         break;
+     case CSR_JRX:
+-        gen_helper_rcsr_jrx(cpu_R[dc->r2]);
++        gen_helper_rcsr_jrx(cpu_R[dc->r2], cpu_env);
+         break;
+     case CSR_ICC:
+     case CSR_DCC:
+@@ -812,7 +812,7 @@ static void dec_wcsr(DisasContext *dc)
+         if (use_icount) {
+             gen_io_start();
+         }
+-        gen_helper_wcsr_im(cpu_R[dc->r1]);
++        gen_helper_wcsr_im(cpu_env, cpu_R[dc->r1]);
+         tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
+         if (use_icount) {
+             gen_io_end();
+@@ -824,7 +824,7 @@ static void dec_wcsr(DisasContext *dc)
+         if (use_icount) {
+             gen_io_start();
+         }
+-        gen_helper_wcsr_ip(cpu_R[dc->r1]);
++        gen_helper_wcsr_ip(cpu_env, cpu_R[dc->r1]);
+         tcg_gen_movi_tl(cpu_pc, dc->pc + 4);
+         if (use_icount) {
+             gen_io_end();
+@@ -844,10 +844,10 @@ static void dec_wcsr(DisasContext *dc)
+         tcg_gen_mov_tl(cpu_deba, cpu_R[dc->r1]);
+         break;
+     case CSR_JTX:
+-        gen_helper_wcsr_jtx(cpu_R[dc->r1]);
++        gen_helper_wcsr_jtx(cpu_env, cpu_R[dc->r1]);
+         break;
+     case CSR_JRX:
+-        gen_helper_wcsr_jrx(cpu_R[dc->r1]);
++        gen_helper_wcsr_jrx(cpu_env, cpu_R[dc->r1]);
+         break;
+     case CSR_DC:
+         tcg_gen_mov_tl(cpu_dc, cpu_R[dc->r1]);
+@@ -940,15 +940,13 @@ static const DecoderInfo decinfo[] = {
+     dec_cmpne
+ };
+ 
+-static inline void decode(DisasContext *dc)
++static inline void decode(DisasContext *dc, uint32_t ir)
+ {
+-    uint32_t ir;
+-
+     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
+         tcg_gen_debug_insn_start(dc->pc);
+     }
+ 
+-    dc->ir = ir = ldl_code(dc->pc);
++    dc->ir = ir;
+     LOG_DIS("%8.8x\t", dc->ir);
+ 
+     /* try guessing 'empty' instruction memory, although it may be a valid
+@@ -1068,7 +1066,7 @@ static void gen_intermediate_code_internal(CPULM32State *env,
+             gen_io_start();
+         }
+ 
+-        decode(dc);
++        decode(dc, cpu_ldl_code(env, dc->pc));
+         dc->pc += 4;
+         num_insns++;
+ 
+-- 
+1.7.12.1
+
diff --git a/0028-target-m68k-switch-to-AREG0-free-mode.patch b/0028-target-m68k-switch-to-AREG0-free-mode.patch
new file mode 100644
index 0000000..220b78d
--- /dev/null
+++ b/0028-target-m68k-switch-to-AREG0-free-mode.patch
@@ -0,0 +1,502 @@
+From 2ace9fd11db103aecebf451aff3bc23838248667 Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:27:38 +0000
+Subject: [PATCH] target-m68k: switch to AREG0 free mode
+
+Add an explicit CPUState parameter instead of relying on AREG0
+and switch to AREG0 free mode.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure                 |  2 +-
+ target-m68k/Makefile.objs |  2 --
+ target-m68k/helpers.h     |  2 +-
+ target-m68k/op_helper.c   | 68 +++++++++++++++++-------------------------
+ target-m68k/translate.c   | 76 ++++++++++++++++++++++++-----------------------
+ 5 files changed, 68 insertions(+), 82 deletions(-)
+
+diff --git a/configure b/configure
+index 1e3ea7f..af03942 100755
+--- a/configure
++++ b/configure
+@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+ 
+ 
+ case "$target_arch2" in
+-  alpha | i386 | lm32 | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
++  alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
+     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
+   ;;
+ esac
+diff --git a/target-m68k/Makefile.objs b/target-m68k/Makefile.objs
+index cda6015..7eccfab 100644
+--- a/target-m68k/Makefile.objs
++++ b/target-m68k/Makefile.objs
+@@ -1,5 +1,3 @@
+ obj-y += m68k-semi.o
+ obj-y += translate.o op_helper.o helper.o cpu.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+-
+-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-m68k/helpers.h b/target-m68k/helpers.h
+index cb8a0c7..8112b44 100644
+--- a/target-m68k/helpers.h
++++ b/target-m68k/helpers.h
+@@ -49,6 +49,6 @@ DEF_HELPER_3(set_mac_exts, void, env, i32, i32)
+ DEF_HELPER_3(set_mac_extu, void, env, i32, i32)
+ 
+ DEF_HELPER_2(flush_flags, void, env, i32)
+-DEF_HELPER_1(raise_exception, void, i32)
++DEF_HELPER_2(raise_exception, void, env, i32)
+ 
+ #include "def-helper.h"
+diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
+index 1971a57..3116287 100644
+--- a/target-m68k/op_helper.c
++++ b/target-m68k/op_helper.c
+@@ -17,17 +17,16 @@
+  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+  */
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "helpers.h"
+ 
+ #if defined(CONFIG_USER_ONLY)
+ 
+-void do_interrupt(CPUM68KState *env1)
++void do_interrupt(CPUM68KState *env)
+ {
+-    env1->exception_index = -1;
++    env->exception_index = -1;
+ }
+ 
+-void do_interrupt_m68k_hardirq(CPUM68KState *env1)
++void do_interrupt_m68k_hardirq(CPUM68KState *env)
+ {
+ }
+ 
+@@ -54,16 +53,12 @@ extern int semihosting_enabled;
+ /* Try to fill the TLB and return an exception if error. If retaddr is
+    NULL, it means that the function was called in C code (i.e. not
+    from generated code or from helper.c) */
+-/* XXX: fix it to restore all registers */
+-void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx,
++void tlb_fill(CPUM68KState *env, target_ulong addr, int is_write, int mmu_idx,
+               uintptr_t retaddr)
+ {
+     TranslationBlock *tb;
+-    CPUM68KState *saved_env;
+     int ret;
+ 
+-    saved_env = env;
+-    env = env1;
+     ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx);
+     if (unlikely(ret)) {
+         if (retaddr) {
+@@ -77,24 +72,23 @@ void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx,
+         }
+         cpu_loop_exit(env);
+     }
+-    env = saved_env;
+ }
+ 
+-static void do_rte(void)
++static void do_rte(CPUM68KState *env)
+ {
+     uint32_t sp;
+     uint32_t fmt;
+ 
+     sp = env->aregs[7];
+-    fmt = ldl_kernel(sp);
+-    env->pc = ldl_kernel(sp + 4);
++    fmt = cpu_ldl_kernel(env, sp);
++    env->pc = cpu_ldl_kernel(env, sp + 4);
+     sp |= (fmt >> 28) & 3;
+     env->sr = fmt & 0xffff;
+     m68k_switch_sp(env);
+     env->aregs[7] = sp + 8;
+ }
+ 
+-static void do_interrupt_all(int is_hw)
++static void do_interrupt_all(CPUM68KState *env, int is_hw)
+ {
+     uint32_t sp;
+     uint32_t fmt;
+@@ -108,14 +102,14 @@ static void do_interrupt_all(int is_hw)
+         switch (env->exception_index) {
+         case EXCP_RTE:
+             /* Return from an exception.  */
+-            do_rte();
++            do_rte(env);
+             return;
+         case EXCP_HALT_INSN:
+             if (semihosting_enabled
+                     && (env->sr & SR_S) != 0
+                     && (env->pc & 3) == 0
+-                    && lduw_code(env->pc - 4) == 0x4e71
+-                    && ldl_code(env->pc) == 0x4e7bf000) {
++                    && cpu_lduw_code(env, env->pc - 4) == 0x4e71
++                    && cpu_ldl_code(env, env->pc) == 0x4e7bf000) {
+                 env->pc += 4;
+                 do_m68k_semihosting(env, env->dregs[0]);
+                 return;
+@@ -151,44 +145,34 @@ static void do_interrupt_all(int is_hw)
+     /* ??? This could cause MMU faults.  */
+     sp &= ~3;
+     sp -= 4;
+-    stl_kernel(sp, retaddr);
++    cpu_stl_kernel(env, sp, retaddr);
+     sp -= 4;
+-    stl_kernel(sp, fmt);
++    cpu_stl_kernel(env, sp, fmt);
+     env->aregs[7] = sp;
+     /* Jump to vector.  */
+-    env->pc = ldl_kernel(env->vbr + vector);
++    env->pc = cpu_ldl_kernel(env, env->vbr + vector);
+ }
+ 
+-void do_interrupt(CPUM68KState *env1)
++void do_interrupt(CPUM68KState *env)
+ {
+-    CPUM68KState *saved_env;
+-
+-    saved_env = env;
+-    env = env1;
+-    do_interrupt_all(0);
+-    env = saved_env;
++    do_interrupt_all(env, 0);
+ }
+ 
+-void do_interrupt_m68k_hardirq(CPUM68KState *env1)
++void do_interrupt_m68k_hardirq(CPUM68KState *env)
+ {
+-    CPUM68KState *saved_env;
+-
+-    saved_env = env;
+-    env = env1;
+-    do_interrupt_all(1);
+-    env = saved_env;
++    do_interrupt_all(env, 1);
+ }
+ #endif
+ 
+-static void raise_exception(int tt)
++static void raise_exception(CPUM68KState *env, int tt)
+ {
+     env->exception_index = tt;
+     cpu_loop_exit(env);
+ }
+ 
+-void HELPER(raise_exception)(uint32_t tt)
++void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt)
+ {
+-    raise_exception(tt);
++    raise_exception(env, tt);
+ }
+ 
+ void HELPER(divu)(CPUM68KState *env, uint32_t word)
+@@ -202,8 +186,9 @@ void HELPER(divu)(CPUM68KState *env, uint32_t word)
+     num = env->div1;
+     den = env->div2;
+     /* ??? This needs to make sure the throwing location is accurate.  */
+-    if (den == 0)
+-        raise_exception(EXCP_DIV0);
++    if (den == 0) {
++        raise_exception(env, EXCP_DIV0);
++    }
+     quot = num / den;
+     rem = num % den;
+     flags = 0;
+@@ -231,8 +216,9 @@ void HELPER(divs)(CPUM68KState *env, uint32_t word)
+ 
+     num = env->div1;
+     den = env->div2;
+-    if (den == 0)
+-        raise_exception(EXCP_DIV0);
++    if (den == 0) {
++        raise_exception(env, EXCP_DIV0);
++    }
+     quot = num / den;
+     rem = num % den;
+     flags = 0;
+diff --git a/target-m68k/translate.c b/target-m68k/translate.c
+index 9fc1e31..10bb303 100644
+--- a/target-m68k/translate.c
++++ b/target-m68k/translate.c
+@@ -260,9 +260,9 @@ static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
+ static inline uint32_t read_im32(DisasContext *s)
+ {
+     uint32_t im;
+-    im = ((uint32_t)lduw_code(s->pc)) << 16;
++    im = ((uint32_t)cpu_lduw_code(cpu_single_env, s->pc)) << 16;
+     s->pc += 2;
+-    im |= lduw_code(s->pc);
++    im |= cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+     return im;
+ }
+@@ -297,7 +297,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
+     uint32_t bd, od;
+ 
+     offset = s->pc;
+-    ext = lduw_code(s->pc);
++    ext = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+ 
+     if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
+@@ -311,7 +311,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
+         if ((ext & 0x30) > 0x10) {
+             /* base displacement */
+             if ((ext & 0x30) == 0x20) {
+-                bd = (int16_t)lduw_code(s->pc);
++                bd = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
+                 s->pc += 2;
+             } else {
+                 bd = read_im32(s);
+@@ -360,7 +360,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
+             if ((ext & 3) > 1) {
+                 /* outer displacement */
+                 if ((ext & 3) == 2) {
+-                    od = (int16_t)lduw_code(s->pc);
++                    od = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
+                     s->pc += 2;
+                 } else {
+                     od = read_im32(s);
+@@ -514,7 +514,7 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
+     case 5: /* Indirect displacement.  */
+         reg = AREG(insn, 0);
+         tmp = tcg_temp_new();
+-        ext = lduw_code(s->pc);
++        ext = cpu_lduw_code(cpu_single_env, s->pc);
+         s->pc += 2;
+         tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
+         return tmp;
+@@ -524,7 +524,7 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
+     case 7: /* Other */
+         switch (insn & 7) {
+         case 0: /* Absolute short.  */
+-            offset = ldsw_code(s->pc);
++            offset = cpu_ldsw_code(cpu_single_env, s->pc);
+             s->pc += 2;
+             return tcg_const_i32(offset);
+         case 1: /* Absolute long.  */
+@@ -532,7 +532,7 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
+             return tcg_const_i32(offset);
+         case 2: /* pc displacement  */
+             offset = s->pc;
+-            offset += ldsw_code(s->pc);
++            offset += cpu_ldsw_code(cpu_single_env, s->pc);
+             s->pc += 2;
+             return tcg_const_i32(offset);
+         case 3: /* pc index+displacement.  */
+@@ -638,17 +638,19 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
+             /* Sign extend values for consistency.  */
+             switch (opsize) {
+             case OS_BYTE:
+-                if (what == EA_LOADS)
+-                    offset = ldsb_code(s->pc + 1);
+-                else
+-                    offset = ldub_code(s->pc + 1);
++                if (what == EA_LOADS) {
++                    offset = cpu_ldsb_code(cpu_single_env, s->pc + 1);
++                } else {
++                    offset = cpu_ldub_code(cpu_single_env, s->pc + 1);
++                }
+                 s->pc += 2;
+                 break;
+             case OS_WORD:
+-                if (what == EA_LOADS)
+-                    offset = ldsw_code(s->pc);
+-                else
+-                    offset = lduw_code(s->pc);
++                if (what == EA_LOADS) {
++                    offset = cpu_ldsw_code(cpu_single_env, s->pc);
++                } else {
++                    offset = cpu_lduw_code(cpu_single_env, s->pc);
++                }
+                 s->pc += 2;
+                 break;
+             case OS_LONG:
+@@ -815,7 +817,7 @@ static void gen_exception(DisasContext *s, uint32_t where, int nr)
+ {
+     gen_flush_cc_op(s);
+     gen_jmp_im(s, where);
+-    gen_helper_raise_exception(tcg_const_i32(nr));
++    gen_helper_raise_exception(cpu_env, tcg_const_i32(nr));
+ }
+ 
+ static inline void gen_addr_fault(DisasContext *s)
+@@ -934,7 +936,7 @@ DISAS_INSN(divl)
+     TCGv reg;
+     uint16_t ext;
+ 
+-    ext = lduw_code(s->pc);
++    ext = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+     if (ext & 0x87f8) {
+         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
+@@ -1086,7 +1088,7 @@ DISAS_INSN(movem)
+     TCGv tmp;
+     int is_load;
+ 
+-    mask = lduw_code(s->pc);
++    mask = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+     tmp = gen_lea(s, insn, OS_LONG);
+     if (IS_NULL_QREG(tmp)) {
+@@ -1130,7 +1132,7 @@ DISAS_INSN(bitop_im)
+         opsize = OS_LONG;
+     op = (insn >> 6) & 3;
+ 
+-    bitnum = lduw_code(s->pc);
++    bitnum = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+     if (bitnum & 0xff00) {
+         disas_undef(s, insn);
+@@ -1383,7 +1385,7 @@ static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
+     else if ((insn & 0x3f) == 0x3c)
+       {
+         uint16_t val;
+-        val = lduw_code(s->pc);
++        val = cpu_lduw_code(cpu_single_env, s->pc);
+         s->pc += 2;
+         gen_set_sr_im(s, val, ccr_only);
+       }
+@@ -1507,7 +1509,7 @@ DISAS_INSN(mull)
+ 
+     /* The upper 32 bits of the product are discarded, so
+        muls.l and mulu.l are functionally equivalent.  */
+-    ext = lduw_code(s->pc);
++    ext = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+     if (ext & 0x87ff) {
+         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
+@@ -1528,7 +1530,7 @@ DISAS_INSN(link)
+     TCGv reg;
+     TCGv tmp;
+ 
+-    offset = ldsw_code(s->pc);
++    offset = cpu_ldsw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+     reg = AREG(insn, 0);
+     tmp = tcg_temp_new();
+@@ -1649,7 +1651,7 @@ DISAS_INSN(branch)
+     op = (insn >> 8) & 0xf;
+     offset = (int8_t)insn;
+     if (offset == 0) {
+-        offset = ldsw_code(s->pc);
++        offset = cpu_ldsw_code(cpu_single_env, s->pc);
+         s->pc += 2;
+     } else if (offset == -1) {
+         offset = read_im32(s);
+@@ -1934,13 +1936,13 @@ DISAS_INSN(strldsr)
+     uint32_t addr;
+ 
+     addr = s->pc - 2;
+-    ext = lduw_code(s->pc);
++    ext = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+     if (ext != 0x46FC) {
+         gen_exception(s, addr, EXCP_UNSUPPORTED);
+         return;
+     }
+-    ext = lduw_code(s->pc);
++    ext = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+     if (IS_USER(s) || (ext & SR_S) == 0) {
+         gen_exception(s, addr, EXCP_PRIVILEGE);
+@@ -2008,7 +2010,7 @@ DISAS_INSN(stop)
+         return;
+     }
+ 
+-    ext = lduw_code(s->pc);
++    ext = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+ 
+     gen_set_sr_im(s, ext, 0);
+@@ -2035,7 +2037,7 @@ DISAS_INSN(movec)
+         return;
+     }
+ 
+-    ext = lduw_code(s->pc);
++    ext = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+ 
+     if (ext & 0x8000) {
+@@ -2100,7 +2102,7 @@ DISAS_INSN(fpu)
+     int set_dest;
+     int opsize;
+ 
+-    ext = lduw_code(s->pc);
++    ext = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+     opmode = ext & 0x7f;
+     switch ((ext >> 13) & 7) {
+@@ -2136,7 +2138,7 @@ DISAS_INSN(fpu)
+                 tcg_gen_addi_i32(tmp32, tmp32, -8);
+                 break;
+             case 5:
+-                offset = ldsw_code(s->pc);
++                offset = cpu_ldsw_code(cpu_single_env, s->pc);
+                 s->pc += 2;
+                 tcg_gen_addi_i32(tmp32, tmp32, offset);
+                 break;
+@@ -2250,12 +2252,12 @@ DISAS_INSN(fpu)
+                 tcg_gen_addi_i32(tmp32, tmp32, -8);
+                 break;
+             case 5:
+-                offset = ldsw_code(s->pc);
++                offset = cpu_ldsw_code(cpu_single_env, s->pc);
+                 s->pc += 2;
+                 tcg_gen_addi_i32(tmp32, tmp32, offset);
+                 break;
+             case 7:
+-                offset = ldsw_code(s->pc);
++                offset = cpu_ldsw_code(cpu_single_env, s->pc);
+                 offset += s->pc - 2;
+                 s->pc += 2;
+                 tcg_gen_addi_i32(tmp32, tmp32, offset);
+@@ -2381,10 +2383,10 @@ DISAS_INSN(fbcc)
+     int l1;
+ 
+     addr = s->pc;
+-    offset = ldsw_code(s->pc);
++    offset = cpu_ldsw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+     if (insn & (1 << 6)) {
+-        offset = (offset << 16) | lduw_code(s->pc);
++        offset = (offset << 16) | cpu_lduw_code(cpu_single_env, s->pc);
+         s->pc += 2;
+     }
+ 
+@@ -2506,7 +2508,7 @@ DISAS_INSN(mac)
+         s->done_mac = 1;
+     }
+ 
+-    ext = lduw_code(s->pc);
++    ext = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+ 
+     acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
+@@ -2941,7 +2943,7 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
+ {
+     uint16_t insn;
+ 
+-    insn = lduw_code(s->pc);
++    insn = cpu_lduw_code(cpu_single_env, s->pc);
+     s->pc += 2;
+ 
+     opcode_table[insn](s, insn);
+@@ -3028,7 +3030,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
+             gen_flush_cc_op(dc);
+             tcg_gen_movi_i32(QREG_PC, dc->pc);
+         }
+-        gen_helper_raise_exception(tcg_const_i32(EXCP_DEBUG));
++        gen_helper_raise_exception(cpu_env, tcg_const_i32(EXCP_DEBUG));
+     } else {
+         switch(dc->is_jmp) {
+         case DISAS_NEXT:
+-- 
+1.7.12.1
+
diff --git a/0029-target-m68k-avoid-using-cpu_single_env.patch b/0029-target-m68k-avoid-using-cpu_single_env.patch
new file mode 100644
index 0000000..871bbe8
--- /dev/null
+++ b/0029-target-m68k-avoid-using-cpu_single_env.patch
@@ -0,0 +1,901 @@
+From 5560cd783146734a60c446f43227044cbb580edd Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sat, 8 Sep 2012 10:48:20 +0000
+Subject: [PATCH] target-m68k: avoid using cpu_single_env
+
+Pass around CPUState instead of using global cpu_single_env.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-m68k/translate.c | 270 +++++++++++++++++++++++++-----------------------
+ 1 file changed, 140 insertions(+), 130 deletions(-)
+
+diff --git a/target-m68k/translate.c b/target-m68k/translate.c
+index 10bb303..fb707f2 100644
+--- a/target-m68k/translate.c
++++ b/target-m68k/translate.c
+@@ -150,18 +150,24 @@ static void *gen_throws_exception;
+ #define OS_SINGLE 4
+ #define OS_DOUBLE 5
+ 
+-typedef void (*disas_proc)(DisasContext *, uint16_t);
++typedef void (*disas_proc)(CPUM68KState *env, DisasContext *s, uint16_t insn);
+ 
+ #ifdef DEBUG_DISPATCH
+-#define DISAS_INSN(name) \
+-  static void real_disas_##name (DisasContext *s, uint16_t insn); \
+-  static void disas_##name (DisasContext *s, uint16_t insn) { \
+-    qemu_log("Dispatch " #name "\n"); \
+-    real_disas_##name(s, insn); } \
+-  static void real_disas_##name (DisasContext *s, uint16_t insn)
++#define DISAS_INSN(name)                                                \
++    static void real_disas_##name(CPUM68KState *env, DisasContext *s,   \
++                                  uint16_t insn);                       \
++    static void disas_##name(CPUM68KState *env, DisasContext *s,        \
++                             uint16_t insn)                             \
++    {                                                                   \
++        qemu_log("Dispatch " #name "\n");                               \
++        real_disas_##name(s, env, insn);                                \
++    }                                                                   \
++    static void real_disas_##name(CPUM68KState *env, DisasContext *s,   \
++                                  uint16_t insn)
+ #else
+-#define DISAS_INSN(name) \
+-  static void disas_##name (DisasContext *s, uint16_t insn)
++#define DISAS_INSN(name)                                                \
++    static void disas_##name(CPUM68KState *env, DisasContext *s,        \
++                             uint16_t insn)
+ #endif
+ 
+ /* Generate a load from the specified address.  Narrow values are
+@@ -257,12 +263,12 @@ static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
+ }
+ 
+ /* Read a 32-bit immediate constant.  */
+-static inline uint32_t read_im32(DisasContext *s)
++static inline uint32_t read_im32(CPUM68KState *env, DisasContext *s)
+ {
+     uint32_t im;
+-    im = ((uint32_t)cpu_lduw_code(cpu_single_env, s->pc)) << 16;
++    im = ((uint32_t)cpu_lduw_code(env, s->pc)) << 16;
+     s->pc += 2;
+-    im |= cpu_lduw_code(cpu_single_env, s->pc);
++    im |= cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+     return im;
+ }
+@@ -288,7 +294,8 @@ static TCGv gen_addr_index(uint16_t ext, TCGv tmp)
+ 
+ /* Handle a base + index + displacement effective addresss.
+    A NULL_QREG base means pc-relative.  */
+-static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
++static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, int opsize,
++                            TCGv base)
+ {
+     uint32_t offset;
+     uint16_t ext;
+@@ -297,7 +304,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
+     uint32_t bd, od;
+ 
+     offset = s->pc;
+-    ext = cpu_lduw_code(cpu_single_env, s->pc);
++    ext = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+ 
+     if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
+@@ -311,10 +318,10 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
+         if ((ext & 0x30) > 0x10) {
+             /* base displacement */
+             if ((ext & 0x30) == 0x20) {
+-                bd = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
++                bd = (int16_t)cpu_lduw_code(env, s->pc);
+                 s->pc += 2;
+             } else {
+-                bd = read_im32(s);
++                bd = read_im32(env, s);
+             }
+         } else {
+             bd = 0;
+@@ -360,10 +367,10 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
+             if ((ext & 3) > 1) {
+                 /* outer displacement */
+                 if ((ext & 3) == 2) {
+-                    od = (int16_t)cpu_lduw_code(cpu_single_env, s->pc);
++                    od = (int16_t)cpu_lduw_code(env, s->pc);
+                     s->pc += 2;
+                 } else {
+-                    od = read_im32(s);
++                    od = read_im32(env, s);
+                 }
+             } else {
+                 od = 0;
+@@ -492,7 +499,8 @@ static inline TCGv gen_extend(TCGv val, int opsize, int sign)
+ 
+ /* Generate code for an "effective address".  Does not adjust the base
+    register for autoincrement addressing modes.  */
+-static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
++static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn,
++                    int opsize)
+ {
+     TCGv reg;
+     TCGv tmp;
+@@ -514,29 +522,29 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
+     case 5: /* Indirect displacement.  */
+         reg = AREG(insn, 0);
+         tmp = tcg_temp_new();
+-        ext = cpu_lduw_code(cpu_single_env, s->pc);
++        ext = cpu_lduw_code(env, s->pc);
+         s->pc += 2;
+         tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
+         return tmp;
+     case 6: /* Indirect index + displacement.  */
+         reg = AREG(insn, 0);
+-        return gen_lea_indexed(s, opsize, reg);
++        return gen_lea_indexed(env, s, opsize, reg);
+     case 7: /* Other */
+         switch (insn & 7) {
+         case 0: /* Absolute short.  */
+-            offset = cpu_ldsw_code(cpu_single_env, s->pc);
++            offset = cpu_ldsw_code(env, s->pc);
+             s->pc += 2;
+             return tcg_const_i32(offset);
+         case 1: /* Absolute long.  */
+-            offset = read_im32(s);
++            offset = read_im32(env, s);
+             return tcg_const_i32(offset);
+         case 2: /* pc displacement  */
+             offset = s->pc;
+-            offset += cpu_ldsw_code(cpu_single_env, s->pc);
++            offset += cpu_ldsw_code(env, s->pc);
+             s->pc += 2;
+             return tcg_const_i32(offset);
+         case 3: /* pc index+displacement.  */
+-            return gen_lea_indexed(s, opsize, NULL_QREG);
++            return gen_lea_indexed(env, s, opsize, NULL_QREG);
+         case 4: /* Immediate.  */
+         default:
+             return NULL_QREG;
+@@ -548,15 +556,16 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
+ 
+ /* Helper function for gen_ea. Reuse the computed address between the
+    for read/write operands.  */
+-static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
+-                              TCGv val, TCGv *addrp, ea_what what)
++static inline TCGv gen_ea_once(CPUM68KState *env, DisasContext *s,
++                               uint16_t insn, int opsize, TCGv val,
++                               TCGv *addrp, ea_what what)
+ {
+     TCGv tmp;
+ 
+     if (addrp && what == EA_STORE) {
+         tmp = *addrp;
+     } else {
+-        tmp = gen_lea(s, insn, opsize);
++        tmp = gen_lea(env, s, insn, opsize);
+         if (IS_NULL_QREG(tmp))
+             return tmp;
+         if (addrp)
+@@ -568,8 +577,8 @@ static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
+ /* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
+    a write otherwise it is a read (0 == sign extend, -1 == zero extend).
+    ADDRP is non-null for readwrite operands.  */
+-static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
+-                   TCGv *addrp, ea_what what)
++static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn,
++                   int opsize, TCGv val, TCGv *addrp, ea_what what)
+ {
+     TCGv reg;
+     TCGv result;
+@@ -609,7 +618,7 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
+             if (addrp && what == EA_STORE) {
+                 tmp = *addrp;
+             } else {
+-                tmp = gen_lea(s, insn, opsize);
++                tmp = gen_lea(env, s, insn, opsize);
+                 if (IS_NULL_QREG(tmp))
+                     return tmp;
+                 if (addrp)
+@@ -626,35 +635,35 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
+         return result;
+     case 5: /* Indirect displacement.  */
+     case 6: /* Indirect index + displacement.  */
+-        return gen_ea_once(s, insn, opsize, val, addrp, what);
++        return gen_ea_once(env, s, insn, opsize, val, addrp, what);
+     case 7: /* Other */
+         switch (insn & 7) {
+         case 0: /* Absolute short.  */
+         case 1: /* Absolute long.  */
+         case 2: /* pc displacement  */
+         case 3: /* pc index+displacement.  */
+-            return gen_ea_once(s, insn, opsize, val, addrp, what);
++            return gen_ea_once(env, s, insn, opsize, val, addrp, what);
+         case 4: /* Immediate.  */
+             /* Sign extend values for consistency.  */
+             switch (opsize) {
+             case OS_BYTE:
+                 if (what == EA_LOADS) {
+-                    offset = cpu_ldsb_code(cpu_single_env, s->pc + 1);
++                    offset = cpu_ldsb_code(env, s->pc + 1);
+                 } else {
+-                    offset = cpu_ldub_code(cpu_single_env, s->pc + 1);
++                    offset = cpu_ldub_code(env, s->pc + 1);
+                 }
+                 s->pc += 2;
+                 break;
+             case OS_WORD:
+                 if (what == EA_LOADS) {
+-                    offset = cpu_ldsw_code(cpu_single_env, s->pc);
++                    offset = cpu_ldsw_code(env, s->pc);
+                 } else {
+-                    offset = cpu_lduw_code(cpu_single_env, s->pc);
++                    offset = cpu_lduw_code(env, s->pc);
+                 }
+                 s->pc += 2;
+                 break;
+             case OS_LONG:
+-                offset = read_im32(s);
++                offset = read_im32(env, s);
+                 break;
+             default:
+                 qemu_assert(0, "Bad immediate operand");
+@@ -825,20 +834,21 @@ static inline void gen_addr_fault(DisasContext *s)
+     gen_exception(s, s->insn_pc, EXCP_ADDRESS);
+ }
+ 
+-#define SRC_EA(result, opsize, op_sign, addrp) do { \
+-    result = gen_ea(s, insn, opsize, NULL_QREG, addrp, op_sign ? EA_LOADS : EA_LOADU); \
+-    if (IS_NULL_QREG(result)) { \
+-        gen_addr_fault(s); \
+-        return; \
+-    } \
++#define SRC_EA(env, result, opsize, op_sign, addrp) do {                \
++        result = gen_ea(env, s, insn, opsize, NULL_QREG, addrp,         \
++                        op_sign ? EA_LOADS : EA_LOADU);                 \
++        if (IS_NULL_QREG(result)) {                                     \
++            gen_addr_fault(s);                                          \
++            return;                                                     \
++        }                                                               \
+     } while (0)
+ 
+-#define DEST_EA(insn, opsize, val, addrp) do { \
+-    TCGv ea_result = gen_ea(s, insn, opsize, val, addrp, EA_STORE); \
+-    if (IS_NULL_QREG(ea_result)) { \
+-        gen_addr_fault(s); \
+-        return; \
+-    } \
++#define DEST_EA(env, insn, opsize, val, addrp) do {                     \
++        TCGv ea_result = gen_ea(env, s, insn, opsize, val, addrp, EA_STORE); \
++        if (IS_NULL_QREG(ea_result)) {                                  \
++            gen_addr_fault(s);                                          \
++            return;                                                     \
++        }                                                               \
+     } while (0)
+ 
+ /* Generate a jump to an immediate address.  */
+@@ -874,8 +884,7 @@ DISAS_INSN(undef_fpu)
+ DISAS_INSN(undef)
+ {
+     gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
+-    cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
+-              insn, s->pc - 2);
++    cpu_abort(env, "Illegal instruction: %04x @ %08x", insn, s->pc - 2);
+ }
+ 
+ DISAS_INSN(mulw)
+@@ -892,7 +901,7 @@ DISAS_INSN(mulw)
+         tcg_gen_ext16s_i32(tmp, reg);
+     else
+         tcg_gen_ext16u_i32(tmp, reg);
+-    SRC_EA(src, OS_WORD, sign, NULL);
++    SRC_EA(env, src, OS_WORD, sign, NULL);
+     tcg_gen_mul_i32(tmp, tmp, src);
+     tcg_gen_mov_i32(reg, tmp);
+     /* Unlike m68k, coldfire always clears the overflow bit.  */
+@@ -913,7 +922,7 @@ DISAS_INSN(divw)
+     } else {
+         tcg_gen_ext16u_i32(QREG_DIV1, reg);
+     }
+-    SRC_EA(src, OS_WORD, sign, NULL);
++    SRC_EA(env, src, OS_WORD, sign, NULL);
+     tcg_gen_mov_i32(QREG_DIV2, src);
+     if (sign) {
+         gen_helper_divs(cpu_env, tcg_const_i32(1));
+@@ -936,7 +945,7 @@ DISAS_INSN(divl)
+     TCGv reg;
+     uint16_t ext;
+ 
+-    ext = cpu_lduw_code(cpu_single_env, s->pc);
++    ext = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+     if (ext & 0x87f8) {
+         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
+@@ -945,7 +954,7 @@ DISAS_INSN(divl)
+     num = DREG(ext, 12);
+     reg = DREG(ext, 0);
+     tcg_gen_mov_i32(QREG_DIV1, num);
+-    SRC_EA(den, OS_LONG, 0, NULL);
++    SRC_EA(env, den, OS_LONG, 0, NULL);
+     tcg_gen_mov_i32(QREG_DIV2, den);
+     if (ext & 0x0800) {
+         gen_helper_divs(cpu_env, tcg_const_i32(0));
+@@ -975,11 +984,11 @@ DISAS_INSN(addsub)
+     reg = DREG(insn, 9);
+     dest = tcg_temp_new();
+     if (insn & 0x100) {
+-        SRC_EA(tmp, OS_LONG, 0, &addr);
++        SRC_EA(env, tmp, OS_LONG, 0, &addr);
+         src = reg;
+     } else {
+         tmp = reg;
+-        SRC_EA(src, OS_LONG, 0, NULL);
++        SRC_EA(env, src, OS_LONG, 0, NULL);
+     }
+     if (add) {
+         tcg_gen_add_i32(dest, tmp, src);
+@@ -992,7 +1001,7 @@ DISAS_INSN(addsub)
+     }
+     gen_update_cc_add(dest, src);
+     if (insn & 0x100) {
+-        DEST_EA(insn, OS_LONG, dest, &addr);
++        DEST_EA(env, insn, OS_LONG, dest, &addr);
+     } else {
+         tcg_gen_mov_i32(reg, dest);
+     }
+@@ -1022,7 +1031,7 @@ DISAS_INSN(bitop_reg)
+     else
+         opsize = OS_LONG;
+     op = (insn >> 6) & 3;
+-    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
++    SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
+     src2 = DREG(insn, 9);
+     dest = tcg_temp_new();
+ 
+@@ -1057,7 +1066,7 @@ DISAS_INSN(bitop_reg)
+         break;
+     }
+     if (op)
+-        DEST_EA(insn, opsize, dest, &addr);
++        DEST_EA(env, insn, opsize, dest, &addr);
+ }
+ 
+ DISAS_INSN(sats)
+@@ -1088,9 +1097,9 @@ DISAS_INSN(movem)
+     TCGv tmp;
+     int is_load;
+ 
+-    mask = cpu_lduw_code(cpu_single_env, s->pc);
++    mask = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+-    tmp = gen_lea(s, insn, OS_LONG);
++    tmp = gen_lea(env, s, insn, OS_LONG);
+     if (IS_NULL_QREG(tmp)) {
+         gen_addr_fault(s);
+         return;
+@@ -1132,14 +1141,14 @@ DISAS_INSN(bitop_im)
+         opsize = OS_LONG;
+     op = (insn >> 6) & 3;
+ 
+-    bitnum = cpu_lduw_code(cpu_single_env, s->pc);
++    bitnum = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+     if (bitnum & 0xff00) {
+-        disas_undef(s, insn);
++        disas_undef(env, s, insn);
+         return;
+     }
+ 
+-    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
++    SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
+ 
+     gen_flush_flags(s);
+     if (opsize == OS_BYTE)
+@@ -1174,7 +1183,7 @@ DISAS_INSN(bitop_im)
+         default: /* btst */
+             break;
+         }
+-        DEST_EA(insn, opsize, tmp, &addr);
++        DEST_EA(env, insn, opsize, tmp, &addr);
+     }
+ }
+ 
+@@ -1187,8 +1196,8 @@ DISAS_INSN(arith_im)
+     TCGv addr;
+ 
+     op = (insn >> 9) & 7;
+-    SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
+-    im = read_im32(s);
++    SRC_EA(env, src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
++    im = read_im32(env, s);
+     dest = tcg_temp_new();
+     switch (op) {
+     case 0: /* ori */
+@@ -1227,7 +1236,7 @@ DISAS_INSN(arith_im)
+         abort();
+     }
+     if (op != 6) {
+-        DEST_EA(insn, OS_LONG, dest, &addr);
++        DEST_EA(env, insn, OS_LONG, dest, &addr);
+     }
+ }
+ 
+@@ -1259,7 +1268,7 @@ DISAS_INSN(move)
+     default:
+         abort();
+     }
+-    SRC_EA(src, opsize, 1, NULL);
++    SRC_EA(env, src, opsize, 1, NULL);
+     op = (insn >> 6) & 7;
+     if (op == 1) {
+         /* movea */
+@@ -1270,7 +1279,7 @@ DISAS_INSN(move)
+         /* normal move */
+         uint16_t dest_ea;
+         dest_ea = ((insn >> 9) & 7) | (op << 3);
+-        DEST_EA(dest_ea, opsize, src, NULL);
++        DEST_EA(env, dest_ea, opsize, src, NULL);
+         /* This will be correct because loads sign extend.  */
+         gen_logic_cc(s, src);
+     }
+@@ -1291,7 +1300,7 @@ DISAS_INSN(lea)
+     TCGv tmp;
+ 
+     reg = AREG(insn, 9);
+-    tmp = gen_lea(s, insn, OS_LONG);
++    tmp = gen_lea(env, s, insn, OS_LONG);
+     if (IS_NULL_QREG(tmp)) {
+         gen_addr_fault(s);
+         return;
+@@ -1316,7 +1325,7 @@ DISAS_INSN(clr)
+     default:
+         abort();
+     }
+-    DEST_EA(insn, opsize, tcg_const_i32(0), NULL);
++    DEST_EA(env, insn, opsize, tcg_const_i32(0), NULL);
+     gen_logic_cc(s, tcg_const_i32(0));
+ }
+ 
+@@ -1365,7 +1374,8 @@ static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
+     }
+ }
+ 
+-static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
++static void gen_set_sr(CPUM68KState *env, DisasContext *s, uint16_t insn,
++                       int ccr_only)
+ {
+     TCGv tmp;
+     TCGv reg;
+@@ -1385,17 +1395,17 @@ static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
+     else if ((insn & 0x3f) == 0x3c)
+       {
+         uint16_t val;
+-        val = cpu_lduw_code(cpu_single_env, s->pc);
++        val = cpu_lduw_code(env, s->pc);
+         s->pc += 2;
+         gen_set_sr_im(s, val, ccr_only);
+       }
+     else
+-        disas_undef(s, insn);
++        disas_undef(env, s, insn);
+ }
+ 
+ DISAS_INSN(move_to_ccr)
+ {
+-    gen_set_sr(s, insn, 1);
++    gen_set_sr(env, s, insn, 1);
+ }
+ 
+ DISAS_INSN(not)
+@@ -1426,7 +1436,7 @@ DISAS_INSN(pea)
+ {
+     TCGv tmp;
+ 
+-    tmp = gen_lea(s, insn, OS_LONG);
++    tmp = gen_lea(env, s, insn, OS_LONG);
+     if (IS_NULL_QREG(tmp)) {
+         gen_addr_fault(s);
+         return;
+@@ -1472,7 +1482,7 @@ DISAS_INSN(tst)
+     default:
+         abort();
+     }
+-    SRC_EA(tmp, opsize, 1, NULL);
++    SRC_EA(env, tmp, opsize, 1, NULL);
+     gen_logic_cc(s, tmp);
+ }
+ 
+@@ -1494,10 +1504,10 @@ DISAS_INSN(tas)
+     TCGv addr;
+ 
+     dest = tcg_temp_new();
+-    SRC_EA(src1, OS_BYTE, 1, &addr);
++    SRC_EA(env, src1, OS_BYTE, 1, &addr);
+     gen_logic_cc(s, src1);
+     tcg_gen_ori_i32(dest, src1, 0x80);
+-    DEST_EA(insn, OS_BYTE, dest, &addr);
++    DEST_EA(env, insn, OS_BYTE, dest, &addr);
+ }
+ 
+ DISAS_INSN(mull)
+@@ -1509,14 +1519,14 @@ DISAS_INSN(mull)
+ 
+     /* The upper 32 bits of the product are discarded, so
+        muls.l and mulu.l are functionally equivalent.  */
+-    ext = cpu_lduw_code(cpu_single_env, s->pc);
++    ext = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+     if (ext & 0x87ff) {
+         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
+         return;
+     }
+     reg = DREG(ext, 12);
+-    SRC_EA(src1, OS_LONG, 0, NULL);
++    SRC_EA(env, src1, OS_LONG, 0, NULL);
+     dest = tcg_temp_new();
+     tcg_gen_mul_i32(dest, src1, reg);
+     tcg_gen_mov_i32(reg, dest);
+@@ -1530,7 +1540,7 @@ DISAS_INSN(link)
+     TCGv reg;
+     TCGv tmp;
+ 
+-    offset = cpu_ldsw_code(cpu_single_env, s->pc);
++    offset = cpu_ldsw_code(env, s->pc);
+     s->pc += 2;
+     reg = AREG(insn, 0);
+     tmp = tcg_temp_new();
+@@ -1574,7 +1584,7 @@ DISAS_INSN(jump)
+ 
+     /* Load the target address first to ensure correct exception
+        behavior.  */
+-    tmp = gen_lea(s, insn, OS_LONG);
++    tmp = gen_lea(env, s, insn, OS_LONG);
+     if (IS_NULL_QREG(tmp)) {
+         gen_addr_fault(s);
+         return;
+@@ -1594,7 +1604,7 @@ DISAS_INSN(addsubq)
+     int val;
+     TCGv addr;
+ 
+-    SRC_EA(src1, OS_LONG, 0, &addr);
++    SRC_EA(env, src1, OS_LONG, 0, &addr);
+     val = (insn >> 9) & 7;
+     if (val == 0)
+         val = 8;
+@@ -1621,7 +1631,7 @@ DISAS_INSN(addsubq)
+         }
+         gen_update_cc_add(dest, src2);
+     }
+-    DEST_EA(insn, OS_LONG, dest, &addr);
++    DEST_EA(env, insn, OS_LONG, dest, &addr);
+ }
+ 
+ DISAS_INSN(tpf)
+@@ -1636,7 +1646,7 @@ DISAS_INSN(tpf)
+     case 4: /* No extension words.  */
+         break;
+     default:
+-        disas_undef(s, insn);
++        disas_undef(env, s, insn);
+     }
+ }
+ 
+@@ -1651,10 +1661,10 @@ DISAS_INSN(branch)
+     op = (insn >> 8) & 0xf;
+     offset = (int8_t)insn;
+     if (offset == 0) {
+-        offset = cpu_ldsw_code(cpu_single_env, s->pc);
++        offset = cpu_ldsw_code(env, s->pc);
+         s->pc += 2;
+     } else if (offset == -1) {
+-        offset = read_im32(s);
++        offset = read_im32(env, s);
+     }
+     if (op == 1) {
+         /* bsr */
+@@ -1693,7 +1703,7 @@ DISAS_INSN(mvzs)
+         opsize = OS_WORD;
+     else
+         opsize = OS_BYTE;
+-    SRC_EA(src, opsize, (insn & 0x80) == 0, NULL);
++    SRC_EA(env, src, opsize, (insn & 0x80) == 0, NULL);
+     reg = DREG(insn, 9);
+     tcg_gen_mov_i32(reg, src);
+     gen_logic_cc(s, src);
+@@ -1709,11 +1719,11 @@ DISAS_INSN(or)
+     reg = DREG(insn, 9);
+     dest = tcg_temp_new();
+     if (insn & 0x100) {
+-        SRC_EA(src, OS_LONG, 0, &addr);
++        SRC_EA(env, src, OS_LONG, 0, &addr);
+         tcg_gen_or_i32(dest, src, reg);
+-        DEST_EA(insn, OS_LONG, dest, &addr);
++        DEST_EA(env, insn, OS_LONG, dest, &addr);
+     } else {
+-        SRC_EA(src, OS_LONG, 0, NULL);
++        SRC_EA(env, src, OS_LONG, 0, NULL);
+         tcg_gen_or_i32(dest, src, reg);
+         tcg_gen_mov_i32(reg, dest);
+     }
+@@ -1725,7 +1735,7 @@ DISAS_INSN(suba)
+     TCGv src;
+     TCGv reg;
+ 
+-    SRC_EA(src, OS_LONG, 0, NULL);
++    SRC_EA(env, src, OS_LONG, 0, NULL);
+     reg = AREG(insn, 9);
+     tcg_gen_sub_i32(reg, reg, src);
+ }
+@@ -1751,7 +1761,7 @@ DISAS_INSN(mov3q)
+         val = -1;
+     src = tcg_const_i32(val);
+     gen_logic_cc(s, src);
+-    DEST_EA(insn, OS_LONG, src, NULL);
++    DEST_EA(env, insn, OS_LONG, src, NULL);
+ }
+ 
+ DISAS_INSN(cmp)
+@@ -1779,7 +1789,7 @@ DISAS_INSN(cmp)
+     default:
+         abort();
+     }
+-    SRC_EA(src, opsize, 1, NULL);
++    SRC_EA(env, src, opsize, 1, NULL);
+     reg = DREG(insn, 9);
+     dest = tcg_temp_new();
+     tcg_gen_sub_i32(dest, reg, src);
+@@ -1798,7 +1808,7 @@ DISAS_INSN(cmpa)
+     } else {
+         opsize = OS_WORD;
+     }
+-    SRC_EA(src, opsize, 1, NULL);
++    SRC_EA(env, src, opsize, 1, NULL);
+     reg = AREG(insn, 9);
+     dest = tcg_temp_new();
+     tcg_gen_sub_i32(dest, reg, src);
+@@ -1813,12 +1823,12 @@ DISAS_INSN(eor)
+     TCGv dest;
+     TCGv addr;
+ 
+-    SRC_EA(src, OS_LONG, 0, &addr);
++    SRC_EA(env, src, OS_LONG, 0, &addr);
+     reg = DREG(insn, 9);
+     dest = tcg_temp_new();
+     tcg_gen_xor_i32(dest, src, reg);
+     gen_logic_cc(s, dest);
+-    DEST_EA(insn, OS_LONG, dest, &addr);
++    DEST_EA(env, insn, OS_LONG, dest, &addr);
+ }
+ 
+ DISAS_INSN(and)
+@@ -1831,11 +1841,11 @@ DISAS_INSN(and)
+     reg = DREG(insn, 9);
+     dest = tcg_temp_new();
+     if (insn & 0x100) {
+-        SRC_EA(src, OS_LONG, 0, &addr);
++        SRC_EA(env, src, OS_LONG, 0, &addr);
+         tcg_gen_and_i32(dest, src, reg);
+-        DEST_EA(insn, OS_LONG, dest, &addr);
++        DEST_EA(env, insn, OS_LONG, dest, &addr);
+     } else {
+-        SRC_EA(src, OS_LONG, 0, NULL);
++        SRC_EA(env, src, OS_LONG, 0, NULL);
+         tcg_gen_and_i32(dest, src, reg);
+         tcg_gen_mov_i32(reg, dest);
+     }
+@@ -1847,7 +1857,7 @@ DISAS_INSN(adda)
+     TCGv src;
+     TCGv reg;
+ 
+-    SRC_EA(src, OS_LONG, 0, NULL);
++    SRC_EA(env, src, OS_LONG, 0, NULL);
+     reg = AREG(insn, 9);
+     tcg_gen_add_i32(reg, reg, src);
+ }
+@@ -1936,13 +1946,13 @@ DISAS_INSN(strldsr)
+     uint32_t addr;
+ 
+     addr = s->pc - 2;
+-    ext = cpu_lduw_code(cpu_single_env, s->pc);
++    ext = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+     if (ext != 0x46FC) {
+         gen_exception(s, addr, EXCP_UNSUPPORTED);
+         return;
+     }
+-    ext = cpu_lduw_code(cpu_single_env, s->pc);
++    ext = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+     if (IS_USER(s) || (ext & SR_S) == 0) {
+         gen_exception(s, addr, EXCP_PRIVILEGE);
+@@ -1972,7 +1982,7 @@ DISAS_INSN(move_to_sr)
+         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
+         return;
+     }
+-    gen_set_sr(s, insn, 0);
++    gen_set_sr(env, s, insn, 0);
+     gen_lookup_tb(s);
+ }
+ 
+@@ -2010,7 +2020,7 @@ DISAS_INSN(stop)
+         return;
+     }
+ 
+-    ext = cpu_lduw_code(cpu_single_env, s->pc);
++    ext = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+ 
+     gen_set_sr_im(s, ext, 0);
+@@ -2037,7 +2047,7 @@ DISAS_INSN(movec)
+         return;
+     }
+ 
+-    ext = cpu_lduw_code(cpu_single_env, s->pc);
++    ext = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+ 
+     if (ext & 0x8000) {
+@@ -2102,7 +2112,7 @@ DISAS_INSN(fpu)
+     int set_dest;
+     int opsize;
+ 
+-    ext = cpu_lduw_code(cpu_single_env, s->pc);
++    ext = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+     opmode = ext & 0x7f;
+     switch ((ext >> 13) & 7) {
+@@ -2138,7 +2148,7 @@ DISAS_INSN(fpu)
+                 tcg_gen_addi_i32(tmp32, tmp32, -8);
+                 break;
+             case 5:
+-                offset = cpu_ldsw_code(cpu_single_env, s->pc);
++                offset = cpu_ldsw_code(env, s->pc);
+                 s->pc += 2;
+                 tcg_gen_addi_i32(tmp32, tmp32, offset);
+                 break;
+@@ -2164,7 +2174,7 @@ DISAS_INSN(fpu)
+         default:
+             goto undef;
+         }
+-        DEST_EA(insn, opsize, tmp32, NULL);
++        DEST_EA(env, insn, opsize, tmp32, NULL);
+         tcg_temp_free_i32(tmp32);
+         return;
+     case 4: /* fmove to control register.  */
+@@ -2192,7 +2202,7 @@ DISAS_INSN(fpu)
+                       (ext >> 10) & 7);
+             goto undef;
+         }
+-        DEST_EA(insn, OS_LONG, tmp32, NULL);
++        DEST_EA(env, insn, OS_LONG, tmp32, NULL);
+         break;
+     case 6: /* fmovem */
+     case 7:
+@@ -2202,7 +2212,7 @@ DISAS_INSN(fpu)
+             int i;
+             if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
+                 goto undef;
+-            tmp32 = gen_lea(s, insn, OS_LONG);
++            tmp32 = gen_lea(env, s, insn, OS_LONG);
+             if (IS_NULL_QREG(tmp32)) {
+                 gen_addr_fault(s);
+                 return;
+@@ -2252,12 +2262,12 @@ DISAS_INSN(fpu)
+                 tcg_gen_addi_i32(tmp32, tmp32, -8);
+                 break;
+             case 5:
+-                offset = cpu_ldsw_code(cpu_single_env, s->pc);
++                offset = cpu_ldsw_code(env, s->pc);
+                 s->pc += 2;
+                 tcg_gen_addi_i32(tmp32, tmp32, offset);
+                 break;
+             case 7:
+-                offset = cpu_ldsw_code(cpu_single_env, s->pc);
++                offset = cpu_ldsw_code(env, s->pc);
+                 offset += s->pc - 2;
+                 s->pc += 2;
+                 tcg_gen_addi_i32(tmp32, tmp32, offset);
+@@ -2277,7 +2287,7 @@ DISAS_INSN(fpu)
+             }
+             tcg_temp_free_i32(tmp32);
+         } else {
+-            SRC_EA(tmp32, opsize, 1, NULL);
++            SRC_EA(env, tmp32, opsize, 1, NULL);
+             src = tcg_temp_new_i64();
+             switch (opsize) {
+             case OS_LONG:
+@@ -2372,7 +2382,7 @@ DISAS_INSN(fpu)
+ undef:
+     /* FIXME: Is this right for offset addressing modes?  */
+     s->pc -= 2;
+-    disas_undef_fpu(s, insn);
++    disas_undef_fpu(env, s, insn);
+ }
+ 
+ DISAS_INSN(fbcc)
+@@ -2383,10 +2393,10 @@ DISAS_INSN(fbcc)
+     int l1;
+ 
+     addr = s->pc;
+-    offset = cpu_ldsw_code(cpu_single_env, s->pc);
++    offset = cpu_ldsw_code(env, s->pc);
+     s->pc += 2;
+     if (insn & (1 << 6)) {
+-        offset = (offset << 16) | cpu_lduw_code(cpu_single_env, s->pc);
++        offset = (offset << 16) | cpu_lduw_code(env, s->pc);
+         s->pc += 2;
+     }
+ 
+@@ -2508,18 +2518,18 @@ DISAS_INSN(mac)
+         s->done_mac = 1;
+     }
+ 
+-    ext = cpu_lduw_code(cpu_single_env, s->pc);
++    ext = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+ 
+     acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
+     dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
+     if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
+-        disas_undef(s, insn);
++        disas_undef(env, s, insn);
+         return;
+     }
+     if (insn & 0x30) {
+         /* MAC with load.  */
+-        tmp = gen_lea(s, insn, OS_LONG);
++        tmp = gen_lea(env, s, insn, OS_LONG);
+         addr = tcg_temp_new();
+         tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK);
+         /* Load the value now to ensure correct exception behavior.
+@@ -2733,7 +2743,7 @@ DISAS_INSN(to_mac)
+     int accnum;
+     accnum = (insn >> 9) & 3;
+     acc = MACREG(accnum);
+-    SRC_EA(val, OS_LONG, 0, NULL);
++    SRC_EA(env, val, OS_LONG, 0, NULL);
+     if (s->env->macsr & MACSR_FI) {
+         tcg_gen_ext_i32_i64(acc, val);
+         tcg_gen_shli_i64(acc, acc, 8);
+@@ -2750,7 +2760,7 @@ DISAS_INSN(to_mac)
+ DISAS_INSN(to_macsr)
+ {
+     TCGv val;
+-    SRC_EA(val, OS_LONG, 0, NULL);
++    SRC_EA(env, val, OS_LONG, 0, NULL);
+     gen_helper_set_macsr(cpu_env, val);
+     gen_lookup_tb(s);
+ }
+@@ -2758,7 +2768,7 @@ DISAS_INSN(to_macsr)
+ DISAS_INSN(to_mask)
+ {
+     TCGv val;
+-    SRC_EA(val, OS_LONG, 0, NULL);
++    SRC_EA(env, val, OS_LONG, 0, NULL);
+     tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000);
+ }
+ 
+@@ -2766,7 +2776,7 @@ DISAS_INSN(to_mext)
+ {
+     TCGv val;
+     TCGv acc;
+-    SRC_EA(val, OS_LONG, 0, NULL);
++    SRC_EA(env, val, OS_LONG, 0, NULL);
+     acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
+     if (s->env->macsr & MACSR_FI)
+         gen_helper_set_mac_extf(cpu_env, val, acc);
+@@ -2943,10 +2953,10 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
+ {
+     uint16_t insn;
+ 
+-    insn = cpu_lduw_code(cpu_single_env, s->pc);
++    insn = cpu_lduw_code(env, s->pc);
+     s->pc += 2;
+ 
+-    opcode_table[insn](s, insn);
++    opcode_table[insn](env, s, insn);
+ }
+ 
+ /* generate intermediate code for basic block 'tb'.  */
+-- 
+1.7.12.1
+
diff --git a/0030-target-unicore32-switch-to-AREG0-free-mode.patch b/0030-target-unicore32-switch-to-AREG0-free-mode.patch
new file mode 100644
index 0000000..4880417
--- /dev/null
+++ b/0030-target-unicore32-switch-to-AREG0-free-mode.patch
@@ -0,0 +1,437 @@
+From 23ff6fa6a883d210aab33e09d0bb9470df5083fc Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 07:42:33 +0000
+Subject: [PATCH] target-unicore32: switch to AREG0 free mode
+
+Add an explicit CPUState parameter instead of relying on AREG0
+and switch to AREG0 free mode.
+
+Tested-by: Guan Xuetao <gxt at mprc.pku.edu.cn>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure                      |  2 +-
+ target-unicore32/Makefile.objs |  2 --
+ target-unicore32/helper.h      | 26 ++++++++---------
+ target-unicore32/op_helper.c   | 65 ++++++++++++++++--------------------------
+ target-unicore32/translate.c   | 38 ++++++++++++------------
+ 5 files changed, 58 insertions(+), 75 deletions(-)
+
+diff --git a/configure b/configure
+index af03942..a8827ba 100755
+--- a/configure
++++ b/configure
+@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+ 
+ 
+ case "$target_arch2" in
+-  alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | x86_64 | xtensa* | ppc*)
++  alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
+     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
+   ;;
+ esac
+diff --git a/target-unicore32/Makefile.objs b/target-unicore32/Makefile.objs
+index 777f01f..8e143da 100644
+--- a/target-unicore32/Makefile.objs
++++ b/target-unicore32/Makefile.objs
+@@ -2,5 +2,3 @@ obj-y += translate.o op_helper.o helper.o cpu.o
+ obj-y += ucf64_helper.o
+ 
+ obj-$(CONFIG_SOFTMMU) += machine.o softmmu.o
+-
+-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-unicore32/helper.h b/target-unicore32/helper.h
+index 305318a..a4b8149 100644
+--- a/target-unicore32/helper.h
++++ b/target-unicore32/helper.h
+@@ -17,26 +17,26 @@ DEF_HELPER_1(cp1_putc, void, i32)
+ DEF_HELPER_1(clz, i32, i32)
+ DEF_HELPER_1(clo, i32, i32)
+ 
+-DEF_HELPER_1(exception, void, i32)
++DEF_HELPER_2(exception, void, env, i32)
+ 
+-DEF_HELPER_2(asr_write, void, i32, i32)
+-DEF_HELPER_0(asr_read, i32)
++DEF_HELPER_3(asr_write, void, env, i32, i32)
++DEF_HELPER_1(asr_read, i32, env)
+ 
+-DEF_HELPER_1(get_user_reg, i32, i32)
+-DEF_HELPER_2(set_user_reg, void, i32, i32)
++DEF_HELPER_2(get_user_reg, i32, env, i32)
++DEF_HELPER_3(set_user_reg, void, env, i32, i32)
+ 
+-DEF_HELPER_2(add_cc, i32, i32, i32)
+-DEF_HELPER_2(adc_cc, i32, i32, i32)
+-DEF_HELPER_2(sub_cc, i32, i32, i32)
+-DEF_HELPER_2(sbc_cc, i32, i32, i32)
++DEF_HELPER_3(add_cc, i32, env, i32, i32)
++DEF_HELPER_3(adc_cc, i32, env, i32, i32)
++DEF_HELPER_3(sub_cc, i32, env, i32, i32)
++DEF_HELPER_3(sbc_cc, i32, env, i32, i32)
+ 
+ DEF_HELPER_2(shl, i32, i32, i32)
+ DEF_HELPER_2(shr, i32, i32, i32)
+ DEF_HELPER_2(sar, i32, i32, i32)
+-DEF_HELPER_2(shl_cc, i32, i32, i32)
+-DEF_HELPER_2(shr_cc, i32, i32, i32)
+-DEF_HELPER_2(sar_cc, i32, i32, i32)
+-DEF_HELPER_2(ror_cc, i32, i32, i32)
++DEF_HELPER_3(shl_cc, i32, env, i32, i32)
++DEF_HELPER_3(shr_cc, i32, env, i32, i32)
++DEF_HELPER_3(sar_cc, i32, env, i32, i32)
++DEF_HELPER_3(ror_cc, i32, env, i32, i32)
+ 
+ DEF_HELPER_1(ucf64_get_fpscr, i32, env)
+ DEF_HELPER_2(ucf64_set_fpscr, void, env, i32)
+diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
+index c63789d..f474d1b 100644
+--- a/target-unicore32/op_helper.c
++++ b/target-unicore32/op_helper.c
+@@ -9,19 +9,18 @@
+  * later version. See the COPYING file in the top-level directory.
+  */
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "helper.h"
+ 
+ #define SIGNBIT (uint32_t)0x80000000
+ #define SIGNBIT64 ((uint64_t)1 << 63)
+ 
+-void HELPER(exception)(uint32_t excp)
++void HELPER(exception)(CPUUniCore32State *env, uint32_t excp)
+ {
+     env->exception_index = excp;
+     cpu_loop_exit(env);
+ }
+ 
+-static target_ulong asr_read(void)
++static target_ulong asr_read(CPUUniCore32State *env)
+ {
+     int ZF;
+     ZF = (env->ZF == 0);
+@@ -29,24 +28,18 @@ static target_ulong asr_read(void)
+         (env->CF << 29) | ((env->VF & 0x80000000) >> 3);
+ }
+ 
+-target_ulong cpu_asr_read(CPUUniCore32State *env1)
++target_ulong cpu_asr_read(CPUUniCore32State *env)
+ {
+-    CPUUniCore32State *saved_env;
+-    target_ulong ret;
+-
+-    saved_env = env;
+-    env = env1;
+-    ret = asr_read();
+-    env = saved_env;
+-    return ret;
++    return asr_read(env);
+ }
+ 
+-target_ulong HELPER(asr_read)(void)
++target_ulong HELPER(asr_read)(CPUUniCore32State *env)
+ {
+-    return asr_read();
++    return asr_read(env);
+ }
+ 
+-static void asr_write(target_ulong val, target_ulong mask)
++static void asr_write(CPUUniCore32State *env, target_ulong val,
++                      target_ulong mask)
+ {
+     if (mask & ASR_NZCV) {
+         env->ZF = (~val) & ASR_Z;
+@@ -62,23 +55,19 @@ static void asr_write(target_ulong val, target_ulong mask)
+     env->uncached_asr = (env->uncached_asr & ~mask) | (val & mask);
+ }
+ 
+-void cpu_asr_write(CPUUniCore32State *env1, target_ulong val, target_ulong mask)
++void cpu_asr_write(CPUUniCore32State *env, target_ulong val, target_ulong mask)
+ {
+-    CPUUniCore32State *saved_env;
+-
+-    saved_env = env;
+-    env = env1;
+-    asr_write(val, mask);
+-    env = saved_env;
++    asr_write(env, val, mask);
+ }
+ 
+-void HELPER(asr_write)(target_ulong val, target_ulong mask)
++void HELPER(asr_write)(CPUUniCore32State *env, target_ulong val,
++                       target_ulong mask)
+ {
+-    asr_write(val, mask);
++    asr_write(env, val, mask);
+ }
+ 
+ /* Access to user mode registers from privileged modes.  */
+-uint32_t HELPER(get_user_reg)(uint32_t regno)
++uint32_t HELPER(get_user_reg)(CPUUniCore32State *env, uint32_t regno)
+ {
+     uint32_t val;
+ 
+@@ -92,7 +81,7 @@ uint32_t HELPER(get_user_reg)(uint32_t regno)
+     return val;
+ }
+ 
+-void HELPER(set_user_reg)(uint32_t regno, uint32_t val)
++void HELPER(set_user_reg)(CPUUniCore32State *env, uint32_t regno, uint32_t val)
+ {
+     if (regno == 29) {
+         env->banked_r29[0] = val;
+@@ -107,7 +96,7 @@ void HELPER(set_user_reg)(uint32_t regno, uint32_t val)
+    The only way to do that in TCG is a conditional branch, which clobbers
+    all our temporaries.  For now implement these as helper functions.  */
+ 
+-uint32_t HELPER(add_cc)(uint32_t a, uint32_t b)
++uint32_t HELPER(add_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
+ {
+     uint32_t result;
+     result = a + b;
+@@ -117,7 +106,7 @@ uint32_t HELPER(add_cc)(uint32_t a, uint32_t b)
+     return result;
+ }
+ 
+-uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
++uint32_t HELPER(adc_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
+ {
+     uint32_t result;
+     if (!env->CF) {
+@@ -132,7 +121,7 @@ uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
+     return result;
+ }
+ 
+-uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
++uint32_t HELPER(sub_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
+ {
+     uint32_t result;
+     result = a - b;
+@@ -142,7 +131,7 @@ uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
+     return result;
+ }
+ 
+-uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b)
++uint32_t HELPER(sbc_cc)(CPUUniCore32State *env, uint32_t a, uint32_t b)
+ {
+     uint32_t result;
+     if (!env->CF) {
+@@ -186,7 +175,7 @@ uint32_t HELPER(sar)(uint32_t x, uint32_t i)
+     return (int32_t)x >> shift;
+ }
+ 
+-uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
++uint32_t HELPER(shl_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
+ {
+     int shift = i & 0xff;
+     if (shift >= 32) {
+@@ -203,7 +192,7 @@ uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
+     return x;
+ }
+ 
+-uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i)
++uint32_t HELPER(shr_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
+ {
+     int shift = i & 0xff;
+     if (shift >= 32) {
+@@ -220,7 +209,7 @@ uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i)
+     return x;
+ }
+ 
+-uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i)
++uint32_t HELPER(sar_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
+ {
+     int shift = i & 0xff;
+     if (shift >= 32) {
+@@ -233,7 +222,7 @@ uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i)
+     return x;
+ }
+ 
+-uint32_t HELPER(ror_cc)(uint32_t x, uint32_t i)
++uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
+ {
+     int shift1, shift;
+     shift1 = i & 0xff;
+@@ -264,16 +253,13 @@ uint32_t HELPER(ror_cc)(uint32_t x, uint32_t i)
+ #define SHIFT 3
+ #include "softmmu_template.h"
+ 
+-void tlb_fill(CPUUniCore32State *env1, target_ulong addr, int is_write,
+-        int mmu_idx, uintptr_t retaddr)
++void tlb_fill(CPUUniCore32State *env, target_ulong addr, int is_write,
++              int mmu_idx, uintptr_t retaddr)
+ {
+     TranslationBlock *tb;
+-    CPUUniCore32State *saved_env;
+     unsigned long pc;
+     int ret;
+ 
+-    saved_env = env;
+-    env = env1;
+     ret = uc32_cpu_handle_mmu_fault(env, addr, is_write, mmu_idx);
+     if (unlikely(ret)) {
+         if (retaddr) {
+@@ -287,6 +273,5 @@ void tlb_fill(CPUUniCore32State *env1, target_ulong addr, int is_write,
+         }
+         cpu_loop_exit(env);
+     }
+-    env = saved_env;
+ }
+ #endif
+diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
+index 188bf8c..b786a6b 100644
+--- a/target-unicore32/translate.c
++++ b/target-unicore32/translate.c
+@@ -253,7 +253,7 @@ static void disas_ocd_insn(CPUUniCore32State *env, DisasContext *s,
+ static inline void gen_set_asr(TCGv var, uint32_t mask)
+ {
+     TCGv tmp_mask = tcg_const_i32(mask);
+-    gen_helper_asr_write(var, tmp_mask);
++    gen_helper_asr_write(cpu_env, var, tmp_mask);
+     tcg_temp_free_i32(tmp_mask);
+ }
+ /* Set NZCV flags from the high 4 bits of var.  */
+@@ -263,7 +263,7 @@ static void gen_exception(int excp)
+ {
+     TCGv tmp = new_tmp();
+     tcg_gen_movi_i32(tmp, excp);
+-    gen_helper_exception(tmp);
++    gen_helper_exception(cpu_env, tmp);
+     dead_tmp(tmp);
+ }
+ 
+@@ -416,16 +416,16 @@ static inline void gen_uc32_shift_reg(TCGv var, int shiftop,
+     if (flags) {
+         switch (shiftop) {
+         case 0:
+-            gen_helper_shl_cc(var, var, shift);
++            gen_helper_shl_cc(var, cpu_env, var, shift);
+             break;
+         case 1:
+-            gen_helper_shr_cc(var, var, shift);
++            gen_helper_shr_cc(var, cpu_env, var, shift);
+             break;
+         case 2:
+-            gen_helper_sar_cc(var, var, shift);
++            gen_helper_sar_cc(var, cpu_env, var, shift);
+             break;
+         case 3:
+-            gen_helper_ror_cc(var, var, shift);
++            gen_helper_ror_cc(var, cpu_env, var, shift);
+             break;
+         }
+     } else {
+@@ -1323,11 +1323,11 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
+             if (IS_USER(s)) {
+                 ILLEGAL;
+             }
+-            gen_helper_sub_cc(tmp, tmp, tmp2);
++            gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+             gen_exception_return(s, tmp);
+         } else {
+             if (UCOP_SET_S) {
+-                gen_helper_sub_cc(tmp, tmp, tmp2);
++                gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+             } else {
+                 tcg_gen_sub_i32(tmp, tmp, tmp2);
+             }
+@@ -1336,7 +1336,7 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
+         break;
+     case 0x03:
+         if (UCOP_SET_S) {
+-            gen_helper_sub_cc(tmp, tmp2, tmp);
++            gen_helper_sub_cc(tmp, cpu_env, tmp2, tmp);
+         } else {
+             tcg_gen_sub_i32(tmp, tmp2, tmp);
+         }
+@@ -1344,7 +1344,7 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
+         break;
+     case 0x04:
+         if (UCOP_SET_S) {
+-            gen_helper_add_cc(tmp, tmp, tmp2);
++            gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
+         } else {
+             tcg_gen_add_i32(tmp, tmp, tmp2);
+         }
+@@ -1352,7 +1352,7 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
+         break;
+     case 0x05:
+         if (UCOP_SET_S) {
+-            gen_helper_adc_cc(tmp, tmp, tmp2);
++            gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
+         } else {
+             gen_add_carry(tmp, tmp, tmp2);
+         }
+@@ -1360,7 +1360,7 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
+         break;
+     case 0x06:
+         if (UCOP_SET_S) {
+-            gen_helper_sbc_cc(tmp, tmp, tmp2);
++            gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
+         } else {
+             gen_sub_carry(tmp, tmp, tmp2);
+         }
+@@ -1368,7 +1368,7 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
+         break;
+     case 0x07:
+         if (UCOP_SET_S) {
+-            gen_helper_sbc_cc(tmp, tmp2, tmp);
++            gen_helper_sbc_cc(tmp, cpu_env, tmp2, tmp);
+         } else {
+             gen_sub_carry(tmp, tmp2, tmp);
+         }
+@@ -1390,13 +1390,13 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
+         break;
+     case 0x0a:
+         if (UCOP_SET_S) {
+-            gen_helper_sub_cc(tmp, tmp, tmp2);
++            gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+         }
+         dead_tmp(tmp);
+         break;
+     case 0x0b:
+         if (UCOP_SET_S) {
+-            gen_helper_add_cc(tmp, tmp, tmp2);
++            gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
+         }
+         dead_tmp(tmp);
+         break;
+@@ -1536,7 +1536,7 @@ static void do_misc(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
+             tmp = load_cpu_field(bsr);
+         } else {
+             tmp = new_tmp();
+-            gen_helper_asr_read(tmp);
++            gen_helper_asr_read(tmp, cpu_env);
+         }
+         store_reg(s, UCOP_REG_D, tmp);
+         return;
+@@ -1760,7 +1760,7 @@ static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
+                     gen_bx(s, tmp);
+                 } else if (user) {
+                     tmp2 = tcg_const_i32(reg);
+-                    gen_helper_set_user_reg(tmp2, tmp);
++                    gen_helper_set_user_reg(cpu_env, tmp2, tmp);
+                     tcg_temp_free_i32(tmp2);
+                     dead_tmp(tmp);
+                 } else if (reg == UCOP_REG_N) {
+@@ -1778,7 +1778,7 @@ static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
+                 } else if (user) {
+                     tmp = new_tmp();
+                     tmp2 = tcg_const_i32(reg);
+-                    gen_helper_get_user_reg(tmp, tmp2);
++                    gen_helper_get_user_reg(tmp, cpu_env, tmp2);
+                     tcg_temp_free_i32(tmp2);
+                 } else {
+                     tmp = load_reg(s, reg);
+@@ -1861,7 +1861,7 @@ static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
+ {
+     unsigned int insn;
+ 
+-    insn = ldl_code(s->pc);
++    insn = cpu_ldl_code(env, s->pc);
+     s->pc += 4;
+ 
+     /* UniCore instructions class:
+-- 
+1.7.12.1
+
diff --git a/0031-target-arm-convert-void-helpers.patch b/0031-target-arm-convert-void-helpers.patch
new file mode 100644
index 0000000..3ea4640
--- /dev/null
+++ b/0031-target-arm-convert-void-helpers.patch
@@ -0,0 +1,181 @@
+From 140048c58e4ceb4f3bac87d7154d2731bb2bcd5d Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Tue, 4 Sep 2012 20:08:34 +0000
+Subject: [PATCH] target-arm: convert void helpers
+
+Add an explicit CPUState parameter instead of relying on AREG0.
+
+For easier review, convert only op helpers which don't return any value.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-arm/helper.h    |  8 ++++----
+ target-arm/op_helper.c | 20 ++++++++++----------
+ target-arm/translate.c |  8 ++++----
+ 3 files changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/target-arm/helper.h b/target-arm/helper.h
+index 21e9cfe..106aacd 100644
+--- a/target-arm/helper.h
++++ b/target-arm/helper.h
+@@ -50,10 +50,10 @@ DEF_HELPER_2(usad8, i32, i32, i32)
+ DEF_HELPER_1(logicq_cc, i32, i64)
+ 
+ DEF_HELPER_3(sel_flags, i32, i32, i32, i32)
+-DEF_HELPER_1(exception, void, i32)
+-DEF_HELPER_0(wfi, void)
++DEF_HELPER_2(exception, void, env, i32)
++DEF_HELPER_1(wfi, void, env)
+ 
+-DEF_HELPER_2(cpsr_write, void, i32, i32)
++DEF_HELPER_3(cpsr_write, void, env, i32, i32)
+ DEF_HELPER_0(cpsr_read, i32)
+ 
+ DEF_HELPER_3(v7m_msr, void, env, i32, i32)
+@@ -68,7 +68,7 @@ DEF_HELPER_2(get_r13_banked, i32, env, i32)
+ DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
+ 
+ DEF_HELPER_1(get_user_reg, i32, i32)
+-DEF_HELPER_2(set_user_reg, void, i32, i32)
++DEF_HELPER_3(set_user_reg, void, env, i32, i32)
+ 
+ DEF_HELPER_1(vfp_get_fpscr, i32, env)
+ DEF_HELPER_2(vfp_set_fpscr, void, env, i32)
+diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
+index d77bfab..b1adce3 100644
+--- a/target-arm/op_helper.c
++++ b/target-arm/op_helper.c
+@@ -23,7 +23,7 @@
+ #define SIGNBIT (uint32_t)0x80000000
+ #define SIGNBIT64 ((uint64_t)1 << 63)
+ 
+-static void raise_exception(int tt)
++static void raise_exception(CPUARMState *env, int tt)
+ {
+     env->exception_index = tt;
+     cpu_loop_exit(env);
+@@ -93,7 +93,7 @@ void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx,
+                 cpu_restore_state(tb, env, retaddr);
+             }
+         }
+-        raise_exception(env->exception_index);
++        raise_exception(env, env->exception_index);
+     }
+     env = saved_env;
+ }
+@@ -230,14 +230,14 @@ uint32_t HELPER(usat16)(uint32_t x, uint32_t shift)
+     return res;
+ }
+ 
+-void HELPER(wfi)(void)
++void HELPER(wfi)(CPUARMState *env)
+ {
+     env->exception_index = EXCP_HLT;
+     env->halted = 1;
+     cpu_loop_exit(env);
+ }
+ 
+-void HELPER(exception)(uint32_t excp)
++void HELPER(exception)(CPUARMState *env, uint32_t excp)
+ {
+     env->exception_index = excp;
+     cpu_loop_exit(env);
+@@ -248,7 +248,7 @@ uint32_t HELPER(cpsr_read)(void)
+     return cpsr_read(env) & ~CPSR_EXEC;
+ }
+ 
+-void HELPER(cpsr_write)(uint32_t val, uint32_t mask)
++void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
+ {
+     cpsr_write(env, val, mask);
+ }
+@@ -271,7 +271,7 @@ uint32_t HELPER(get_user_reg)(uint32_t regno)
+     return val;
+ }
+ 
+-void HELPER(set_user_reg)(uint32_t regno, uint32_t val)
++void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
+ {
+     if (regno == 13) {
+         env->banked_r13[0] = val;
+@@ -290,7 +290,7 @@ void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
+     const ARMCPRegInfo *ri = rip;
+     int excp = ri->writefn(env, ri, value);
+     if (excp) {
+-        raise_exception(excp);
++        raise_exception(env, excp);
+     }
+ }
+ 
+@@ -300,7 +300,7 @@ uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
+     uint64_t value;
+     int excp = ri->readfn(env, ri, &value);
+     if (excp) {
+-        raise_exception(excp);
++        raise_exception(env, excp);
+     }
+     return value;
+ }
+@@ -310,7 +310,7 @@ void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value)
+     const ARMCPRegInfo *ri = rip;
+     int excp = ri->writefn(env, ri, value);
+     if (excp) {
+-        raise_exception(excp);
++        raise_exception(env, excp);
+     }
+ }
+ 
+@@ -320,7 +320,7 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
+     uint64_t value;
+     int excp = ri->readfn(env, ri, &value);
+     if (excp) {
+-        raise_exception(excp);
++        raise_exception(env, excp);
+     }
+     return value;
+ }
+diff --git a/target-arm/translate.c b/target-arm/translate.c
+index edef79a..6f651d9 100644
+--- a/target-arm/translate.c
++++ b/target-arm/translate.c
+@@ -199,7 +199,7 @@ static void store_reg(DisasContext *s, int reg, TCGv var)
+ static inline void gen_set_cpsr(TCGv var, uint32_t mask)
+ {
+     TCGv tmp_mask = tcg_const_i32(mask);
+-    gen_helper_cpsr_write(var, tmp_mask);
++    gen_helper_cpsr_write(cpu_env, var, tmp_mask);
+     tcg_temp_free_i32(tmp_mask);
+ }
+ /* Set NZCV flags from the high 4 bits of var.  */
+@@ -209,7 +209,7 @@ static void gen_exception(int excp)
+ {
+     TCGv tmp = tcg_temp_new_i32();
+     tcg_gen_movi_i32(tmp, excp);
+-    gen_helper_exception(tmp);
++    gen_helper_exception(cpu_env, tmp);
+     tcg_temp_free_i32(tmp);
+ }
+ 
+@@ -7719,7 +7719,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+                             tmp = gen_ld32(addr, IS_USER(s));
+                             if (user) {
+                                 tmp2 = tcg_const_i32(i);
+-                                gen_helper_set_user_reg(tmp2, tmp);
++                                gen_helper_set_user_reg(cpu_env, tmp2, tmp);
+                                 tcg_temp_free_i32(tmp2);
+                                 tcg_temp_free_i32(tmp);
+                             } else if (i == rn) {
+@@ -9913,7 +9913,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
+             /* nothing more to generate */
+             break;
+         case DISAS_WFI:
+-            gen_helper_wfi();
++            gen_helper_wfi(cpu_env);
+             break;
+         case DISAS_SWI:
+             gen_exception(EXCP_SWI);
+-- 
+1.7.12.1
+
diff --git a/0032-target-arm-convert-remaining-helpers.patch b/0032-target-arm-convert-remaining-helpers.patch
new file mode 100644
index 0000000..73dd928
--- /dev/null
+++ b/0032-target-arm-convert-remaining-helpers.patch
@@ -0,0 +1,821 @@
+From 18e713cf6b5ae2e7c48bb412c959c10322bef5e5 Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Tue, 4 Sep 2012 20:19:15 +0000
+Subject: [PATCH] target-arm: convert remaining helpers
+
+Convert remaining helpers to AREG0 free mode: add an explicit
+CPUState parameter instead of relying on AREG0.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-arm/helper.h    |  52 +++++++++----------
+ target-arm/op_helper.c |  64 +++++++++++------------
+ target-arm/translate.c | 134 ++++++++++++++++++++++++-------------------------
+ 3 files changed, 125 insertions(+), 125 deletions(-)
+
+diff --git a/target-arm/helper.h b/target-arm/helper.h
+index 106aacd..afdb2b5 100644
+--- a/target-arm/helper.h
++++ b/target-arm/helper.h
+@@ -4,12 +4,12 @@ DEF_HELPER_1(clz, i32, i32)
+ DEF_HELPER_1(sxtb16, i32, i32)
+ DEF_HELPER_1(uxtb16, i32, i32)
+ 
+-DEF_HELPER_2(add_setq, i32, i32, i32)
+-DEF_HELPER_2(add_saturate, i32, i32, i32)
+-DEF_HELPER_2(sub_saturate, i32, i32, i32)
+-DEF_HELPER_2(add_usaturate, i32, i32, i32)
+-DEF_HELPER_2(sub_usaturate, i32, i32, i32)
+-DEF_HELPER_1(double_saturate, i32, s32)
++DEF_HELPER_3(add_setq, i32, env, i32, i32)
++DEF_HELPER_3(add_saturate, i32, env, i32, i32)
++DEF_HELPER_3(sub_saturate, i32, env, i32, i32)
++DEF_HELPER_3(add_usaturate, i32, env, i32, i32)
++DEF_HELPER_3(sub_usaturate, i32, env, i32, i32)
++DEF_HELPER_2(double_saturate, i32, env, s32)
+ DEF_HELPER_2(sdiv, s32, s32, s32)
+ DEF_HELPER_2(udiv, i32, i32, i32)
+ DEF_HELPER_1(rbit, i32, i32)
+@@ -40,10 +40,10 @@ PAS_OP(uq)
+ PAS_OP(uh)
+ #undef PAS_OP
+ 
+-DEF_HELPER_2(ssat, i32, i32, i32)
+-DEF_HELPER_2(usat, i32, i32, i32)
+-DEF_HELPER_2(ssat16, i32, i32, i32)
+-DEF_HELPER_2(usat16, i32, i32, i32)
++DEF_HELPER_3(ssat, i32, env, i32, i32)
++DEF_HELPER_3(usat, i32, env, i32, i32)
++DEF_HELPER_3(ssat16, i32, env, i32, i32)
++DEF_HELPER_3(usat16, i32, env, i32, i32)
+ 
+ DEF_HELPER_2(usad8, i32, i32, i32)
+ 
+@@ -54,7 +54,7 @@ DEF_HELPER_2(exception, void, env, i32)
+ DEF_HELPER_1(wfi, void, env)
+ 
+ DEF_HELPER_3(cpsr_write, void, env, i32, i32)
+-DEF_HELPER_0(cpsr_read, i32)
++DEF_HELPER_1(cpsr_read, i32, env)
+ 
+ DEF_HELPER_3(v7m_msr, void, env, i32, i32)
+ DEF_HELPER_2(v7m_mrs, i32, env, i32)
+@@ -67,7 +67,7 @@ DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
+ DEF_HELPER_2(get_r13_banked, i32, env, i32)
+ DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
+ 
+-DEF_HELPER_1(get_user_reg, i32, i32)
++DEF_HELPER_2(get_user_reg, i32, env, i32)
+ DEF_HELPER_3(set_user_reg, void, env, i32, i32)
+ 
+ DEF_HELPER_1(vfp_get_fpscr, i32, env)
+@@ -140,20 +140,20 @@ DEF_HELPER_2(recpe_f32, f32, f32, env)
+ DEF_HELPER_2(rsqrte_f32, f32, f32, env)
+ DEF_HELPER_2(recpe_u32, i32, i32, env)
+ DEF_HELPER_2(rsqrte_u32, i32, i32, env)
+-DEF_HELPER_4(neon_tbl, i32, i32, i32, i32, i32)
+-
+-DEF_HELPER_2(add_cc, i32, i32, i32)
+-DEF_HELPER_2(adc_cc, i32, i32, i32)
+-DEF_HELPER_2(sub_cc, i32, i32, i32)
+-DEF_HELPER_2(sbc_cc, i32, i32, i32)
+-
+-DEF_HELPER_2(shl, i32, i32, i32)
+-DEF_HELPER_2(shr, i32, i32, i32)
+-DEF_HELPER_2(sar, i32, i32, i32)
+-DEF_HELPER_2(shl_cc, i32, i32, i32)
+-DEF_HELPER_2(shr_cc, i32, i32, i32)
+-DEF_HELPER_2(sar_cc, i32, i32, i32)
+-DEF_HELPER_2(ror_cc, i32, i32, i32)
++DEF_HELPER_5(neon_tbl, i32, env, i32, i32, i32, i32)
++
++DEF_HELPER_3(add_cc, i32, env, i32, i32)
++DEF_HELPER_3(adc_cc, i32, env, i32, i32)
++DEF_HELPER_3(sub_cc, i32, env, i32, i32)
++DEF_HELPER_3(sbc_cc, i32, env, i32, i32)
++
++DEF_HELPER_3(shl, i32, env, i32, i32)
++DEF_HELPER_3(shr, i32, env, i32, i32)
++DEF_HELPER_3(sar, i32, env, i32, i32)
++DEF_HELPER_3(shl_cc, i32, env, i32, i32)
++DEF_HELPER_3(shr_cc, i32, env, i32, i32)
++DEF_HELPER_3(sar_cc, i32, env, i32, i32)
++DEF_HELPER_3(ror_cc, i32, env, i32, i32)
+ 
+ /* neon_helper.c */
+ DEF_HELPER_3(neon_qadd_u8, i32, env, i32, i32)
+diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
+index b1adce3..5b868bf 100644
+--- a/target-arm/op_helper.c
++++ b/target-arm/op_helper.c
+@@ -29,7 +29,7 @@ static void raise_exception(CPUARMState *env, int tt)
+     cpu_loop_exit(env);
+ }
+ 
+-uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def,
++uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
+                           uint32_t rn, uint32_t maxindex)
+ {
+     uint32_t val;
+@@ -101,7 +101,7 @@ void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx,
+ 
+ /* FIXME: Pass an explicit pointer to QF to CPUARMState, and move saturating
+    instructions into helper.c  */
+-uint32_t HELPER(add_setq)(uint32_t a, uint32_t b)
++uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
+ {
+     uint32_t res = a + b;
+     if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT))
+@@ -109,7 +109,7 @@ uint32_t HELPER(add_setq)(uint32_t a, uint32_t b)
+     return res;
+ }
+ 
+-uint32_t HELPER(add_saturate)(uint32_t a, uint32_t b)
++uint32_t HELPER(add_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
+ {
+     uint32_t res = a + b;
+     if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
+@@ -119,7 +119,7 @@ uint32_t HELPER(add_saturate)(uint32_t a, uint32_t b)
+     return res;
+ }
+ 
+-uint32_t HELPER(sub_saturate)(uint32_t a, uint32_t b)
++uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
+ {
+     uint32_t res = a - b;
+     if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
+@@ -129,7 +129,7 @@ uint32_t HELPER(sub_saturate)(uint32_t a, uint32_t b)
+     return res;
+ }
+ 
+-uint32_t HELPER(double_saturate)(int32_t val)
++uint32_t HELPER(double_saturate)(CPUARMState *env, int32_t val)
+ {
+     uint32_t res;
+     if (val >= 0x40000000) {
+@@ -144,7 +144,7 @@ uint32_t HELPER(double_saturate)(int32_t val)
+     return res;
+ }
+ 
+-uint32_t HELPER(add_usaturate)(uint32_t a, uint32_t b)
++uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
+ {
+     uint32_t res = a + b;
+     if (res < a) {
+@@ -154,7 +154,7 @@ uint32_t HELPER(add_usaturate)(uint32_t a, uint32_t b)
+     return res;
+ }
+ 
+-uint32_t HELPER(sub_usaturate)(uint32_t a, uint32_t b)
++uint32_t HELPER(sub_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
+ {
+     uint32_t res = a - b;
+     if (res > a) {
+@@ -165,7 +165,7 @@ uint32_t HELPER(sub_usaturate)(uint32_t a, uint32_t b)
+ }
+ 
+ /* Signed saturation.  */
+-static inline uint32_t do_ssat(int32_t val, int shift)
++static inline uint32_t do_ssat(CPUARMState *env, int32_t val, int shift)
+ {
+     int32_t top;
+     uint32_t mask;
+@@ -183,7 +183,7 @@ static inline uint32_t do_ssat(int32_t val, int shift)
+ }
+ 
+ /* Unsigned saturation.  */
+-static inline uint32_t do_usat(int32_t val, int shift)
++static inline uint32_t do_usat(CPUARMState *env, int32_t val, int shift)
+ {
+     uint32_t max;
+ 
+@@ -199,34 +199,34 @@ static inline uint32_t do_usat(int32_t val, int shift)
+ }
+ 
+ /* Signed saturate.  */
+-uint32_t HELPER(ssat)(uint32_t x, uint32_t shift)
++uint32_t HELPER(ssat)(CPUARMState *env, uint32_t x, uint32_t shift)
+ {
+-    return do_ssat(x, shift);
++    return do_ssat(env, x, shift);
+ }
+ 
+ /* Dual halfword signed saturate.  */
+-uint32_t HELPER(ssat16)(uint32_t x, uint32_t shift)
++uint32_t HELPER(ssat16)(CPUARMState *env, uint32_t x, uint32_t shift)
+ {
+     uint32_t res;
+ 
+-    res = (uint16_t)do_ssat((int16_t)x, shift);
+-    res |= do_ssat(((int32_t)x) >> 16, shift) << 16;
++    res = (uint16_t)do_ssat(env, (int16_t)x, shift);
++    res |= do_ssat(env, ((int32_t)x) >> 16, shift) << 16;
+     return res;
+ }
+ 
+ /* Unsigned saturate.  */
+-uint32_t HELPER(usat)(uint32_t x, uint32_t shift)
++uint32_t HELPER(usat)(CPUARMState *env, uint32_t x, uint32_t shift)
+ {
+-    return do_usat(x, shift);
++    return do_usat(env, x, shift);
+ }
+ 
+ /* Dual halfword unsigned saturate.  */
+-uint32_t HELPER(usat16)(uint32_t x, uint32_t shift)
++uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift)
+ {
+     uint32_t res;
+ 
+-    res = (uint16_t)do_usat((int16_t)x, shift);
+-    res |= do_usat(((int32_t)x) >> 16, shift) << 16;
++    res = (uint16_t)do_usat(env, (int16_t)x, shift);
++    res |= do_usat(env, ((int32_t)x) >> 16, shift) << 16;
+     return res;
+ }
+ 
+@@ -243,7 +243,7 @@ void HELPER(exception)(CPUARMState *env, uint32_t excp)
+     cpu_loop_exit(env);
+ }
+ 
+-uint32_t HELPER(cpsr_read)(void)
++uint32_t HELPER(cpsr_read)(CPUARMState *env)
+ {
+     return cpsr_read(env) & ~CPSR_EXEC;
+ }
+@@ -254,7 +254,7 @@ void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
+ }
+ 
+ /* Access to user mode registers from privileged modes.  */
+-uint32_t HELPER(get_user_reg)(uint32_t regno)
++uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
+ {
+     uint32_t val;
+ 
+@@ -329,7 +329,7 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
+    The only way to do that in TCG is a conditional branch, which clobbers
+    all our temporaries.  For now implement these as helper functions.  */
+ 
+-uint32_t HELPER (add_cc)(uint32_t a, uint32_t b)
++uint32_t HELPER (add_cc)(CPUARMState *env, uint32_t a, uint32_t b)
+ {
+     uint32_t result;
+     result = a + b;
+@@ -339,7 +339,7 @@ uint32_t HELPER (add_cc)(uint32_t a, uint32_t b)
+     return result;
+ }
+ 
+-uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
++uint32_t HELPER(adc_cc)(CPUARMState *env, uint32_t a, uint32_t b)
+ {
+     uint32_t result;
+     if (!env->CF) {
+@@ -354,7 +354,7 @@ uint32_t HELPER(adc_cc)(uint32_t a, uint32_t b)
+     return result;
+ }
+ 
+-uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
++uint32_t HELPER(sub_cc)(CPUARMState *env, uint32_t a, uint32_t b)
+ {
+     uint32_t result;
+     result = a - b;
+@@ -364,7 +364,7 @@ uint32_t HELPER(sub_cc)(uint32_t a, uint32_t b)
+     return result;
+ }
+ 
+-uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b)
++uint32_t HELPER(sbc_cc)(CPUARMState *env, uint32_t a, uint32_t b)
+ {
+     uint32_t result;
+     if (!env->CF) {
+@@ -381,7 +381,7 @@ uint32_t HELPER(sbc_cc)(uint32_t a, uint32_t b)
+ 
+ /* Similarly for variable shift instructions.  */
+ 
+-uint32_t HELPER(shl)(uint32_t x, uint32_t i)
++uint32_t HELPER(shl)(CPUARMState *env, uint32_t x, uint32_t i)
+ {
+     int shift = i & 0xff;
+     if (shift >= 32)
+@@ -389,7 +389,7 @@ uint32_t HELPER(shl)(uint32_t x, uint32_t i)
+     return x << shift;
+ }
+ 
+-uint32_t HELPER(shr)(uint32_t x, uint32_t i)
++uint32_t HELPER(shr)(CPUARMState *env, uint32_t x, uint32_t i)
+ {
+     int shift = i & 0xff;
+     if (shift >= 32)
+@@ -397,7 +397,7 @@ uint32_t HELPER(shr)(uint32_t x, uint32_t i)
+     return (uint32_t)x >> shift;
+ }
+ 
+-uint32_t HELPER(sar)(uint32_t x, uint32_t i)
++uint32_t HELPER(sar)(CPUARMState *env, uint32_t x, uint32_t i)
+ {
+     int shift = i & 0xff;
+     if (shift >= 32)
+@@ -405,7 +405,7 @@ uint32_t HELPER(sar)(uint32_t x, uint32_t i)
+     return (int32_t)x >> shift;
+ }
+ 
+-uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
++uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i)
+ {
+     int shift = i & 0xff;
+     if (shift >= 32) {
+@@ -421,7 +421,7 @@ uint32_t HELPER(shl_cc)(uint32_t x, uint32_t i)
+     return x;
+ }
+ 
+-uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i)
++uint32_t HELPER(shr_cc)(CPUARMState *env, uint32_t x, uint32_t i)
+ {
+     int shift = i & 0xff;
+     if (shift >= 32) {
+@@ -437,7 +437,7 @@ uint32_t HELPER(shr_cc)(uint32_t x, uint32_t i)
+     return x;
+ }
+ 
+-uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i)
++uint32_t HELPER(sar_cc)(CPUARMState *env, uint32_t x, uint32_t i)
+ {
+     int shift = i & 0xff;
+     if (shift >= 32) {
+@@ -450,7 +450,7 @@ uint32_t HELPER(sar_cc)(uint32_t x, uint32_t i)
+     return x;
+ }
+ 
+-uint32_t HELPER(ror_cc)(uint32_t x, uint32_t i)
++uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i)
+ {
+     int shift1, shift;
+     shift1 = i & 0xff;
+diff --git a/target-arm/translate.c b/target-arm/translate.c
+index 6f651d9..9ae3b26 100644
+--- a/target-arm/translate.c
++++ b/target-arm/translate.c
+@@ -490,16 +490,16 @@ static inline void gen_arm_shift_reg(TCGv var, int shiftop,
+ {
+     if (flags) {
+         switch (shiftop) {
+-        case 0: gen_helper_shl_cc(var, var, shift); break;
+-        case 1: gen_helper_shr_cc(var, var, shift); break;
+-        case 2: gen_helper_sar_cc(var, var, shift); break;
+-        case 3: gen_helper_ror_cc(var, var, shift); break;
++        case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
++        case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
++        case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
++        case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
+         }
+     } else {
+         switch (shiftop) {
+-        case 0: gen_helper_shl(var, var, shift); break;
+-        case 1: gen_helper_shr(var, var, shift); break;
+-        case 2: gen_helper_sar(var, var, shift); break;
++        case 0: gen_helper_shl(var, cpu_env, var, shift); break;
++        case 1: gen_helper_shr(var, cpu_env, var, shift); break;
++        case 2: gen_helper_sar(var, cpu_env, var, shift); break;
+         case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
+                 tcg_gen_rotr_i32(var, var, shift); break;
+         }
+@@ -6121,7 +6121,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
+                 tmp2 = neon_load_reg(rm, 0);
+                 tmp4 = tcg_const_i32(rn);
+                 tmp5 = tcg_const_i32(n);
+-                gen_helper_neon_tbl(tmp2, tmp2, tmp, tmp4, tmp5);
++                gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
+                 tcg_temp_free_i32(tmp);
+                 if (insn & (1 << 6)) {
+                     tmp = neon_load_reg(rd, 1);
+@@ -6130,7 +6130,7 @@ static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t ins
+                     tcg_gen_movi_i32(tmp, 0);
+                 }
+                 tmp3 = neon_load_reg(rm, 1);
+-                gen_helper_neon_tbl(tmp3, tmp3, tmp, tmp4, tmp5);
++                gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
+                 tcg_temp_free_i32(tmp5);
+                 tcg_temp_free_i32(tmp4);
+                 neon_store_reg(rd, 0, tmp2);
+@@ -6818,7 +6818,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+                     tmp = load_cpu_field(spsr);
+                 } else {
+                     tmp = tcg_temp_new_i32();
+-                    gen_helper_cpsr_read(tmp);
++                    gen_helper_cpsr_read(tmp, cpu_env);
+                 }
+                 store_reg(s, rd, tmp);
+             }
+@@ -6869,11 +6869,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+             tmp = load_reg(s, rm);
+             tmp2 = load_reg(s, rn);
+             if (op1 & 2)
+-                gen_helper_double_saturate(tmp2, tmp2);
++                gen_helper_double_saturate(tmp2, cpu_env, tmp2);
+             if (op1 & 1)
+-                gen_helper_sub_saturate(tmp, tmp, tmp2);
++                gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
+             else
+-                gen_helper_add_saturate(tmp, tmp, tmp2);
++                gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
+             tcg_temp_free_i32(tmp2);
+             store_reg(s, rd, tmp);
+             break;
+@@ -6911,7 +6911,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+                 tcg_temp_free_i64(tmp64);
+                 if ((sh & 2) == 0) {
+                     tmp2 = load_reg(s, rn);
+-                    gen_helper_add_setq(tmp, tmp, tmp2);
++                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
+                     tcg_temp_free_i32(tmp2);
+                 }
+                 store_reg(s, rd, tmp);
+@@ -6931,7 +6931,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+                 } else {
+                     if (op1 == 0) {
+                         tmp2 = load_reg(s, rn);
+-                        gen_helper_add_setq(tmp, tmp, tmp2);
++                        gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
+                         tcg_temp_free_i32(tmp2);
+                     }
+                     store_reg(s, rd, tmp);
+@@ -7005,11 +7005,11 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+                 if (IS_USER(s)) {
+                     goto illegal_op;
+                 }
+-                gen_helper_sub_cc(tmp, tmp, tmp2);
++                gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+                 gen_exception_return(s, tmp);
+             } else {
+                 if (set_cc) {
+-                    gen_helper_sub_cc(tmp, tmp, tmp2);
++                    gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+                 } else {
+                     tcg_gen_sub_i32(tmp, tmp, tmp2);
+                 }
+@@ -7018,7 +7018,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+             break;
+         case 0x03:
+             if (set_cc) {
+-                gen_helper_sub_cc(tmp, tmp2, tmp);
++                gen_helper_sub_cc(tmp, cpu_env, tmp2, tmp);
+             } else {
+                 tcg_gen_sub_i32(tmp, tmp2, tmp);
+             }
+@@ -7026,7 +7026,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+             break;
+         case 0x04:
+             if (set_cc) {
+-                gen_helper_add_cc(tmp, tmp, tmp2);
++                gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
+             } else {
+                 tcg_gen_add_i32(tmp, tmp, tmp2);
+             }
+@@ -7034,7 +7034,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+             break;
+         case 0x05:
+             if (set_cc) {
+-                gen_helper_adc_cc(tmp, tmp, tmp2);
++                gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
+             } else {
+                 gen_add_carry(tmp, tmp, tmp2);
+             }
+@@ -7042,7 +7042,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+             break;
+         case 0x06:
+             if (set_cc) {
+-                gen_helper_sbc_cc(tmp, tmp, tmp2);
++                gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
+             } else {
+                 gen_sub_carry(tmp, tmp, tmp2);
+             }
+@@ -7050,7 +7050,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+             break;
+         case 0x07:
+             if (set_cc) {
+-                gen_helper_sbc_cc(tmp, tmp2, tmp);
++                gen_helper_sbc_cc(tmp, cpu_env, tmp2, tmp);
+             } else {
+                 gen_sub_carry(tmp, tmp2, tmp);
+             }
+@@ -7072,13 +7072,13 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+             break;
+         case 0x0a:
+             if (set_cc) {
+-                gen_helper_sub_cc(tmp, tmp, tmp2);
++                gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+             }
+             tcg_temp_free_i32(tmp);
+             break;
+         case 0x0b:
+             if (set_cc) {
+-                gen_helper_add_cc(tmp, tmp, tmp2);
++                gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
+             }
+             tcg_temp_free_i32(tmp);
+             break;
+@@ -7395,9 +7395,9 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+                         sh = (insn >> 16) & 0x1f;
+                         tmp2 = tcg_const_i32(sh);
+                         if (insn & (1 << 22))
+-                          gen_helper_usat(tmp, tmp, tmp2);
++                          gen_helper_usat(tmp, cpu_env, tmp, tmp2);
+                         else
+-                          gen_helper_ssat(tmp, tmp, tmp2);
++                          gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
+                         tcg_temp_free_i32(tmp2);
+                         store_reg(s, rd, tmp);
+                     } else if ((insn & 0x00300fe0) == 0x00200f20) {
+@@ -7406,9 +7406,9 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+                         sh = (insn >> 16) & 0x1f;
+                         tmp2 = tcg_const_i32(sh);
+                         if (insn & (1 << 22))
+-                          gen_helper_usat16(tmp, tmp, tmp2);
++                          gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
+                         else
+-                          gen_helper_ssat16(tmp, tmp, tmp2);
++                          gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
+                         tcg_temp_free_i32(tmp2);
+                         store_reg(s, rd, tmp);
+                     } else if ((insn & 0x00700fe0) == 0x00000fa0) {
+@@ -7518,7 +7518,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+                              * however it may overflow considered as a signed
+                              * operation, in which case we must set the Q flag.
+                              */
+-                            gen_helper_add_setq(tmp, tmp, tmp2);
++                            gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
+                         }
+                         tcg_temp_free_i32(tmp2);
+                         if (insn & (1 << 22)) {
+@@ -7534,7 +7534,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+                             if (rd != 15)
+                               {
+                                 tmp2 = load_reg(s, rd);
+-                                gen_helper_add_setq(tmp, tmp, tmp2);
++                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
+                                 tcg_temp_free_i32(tmp2);
+                               }
+                             store_reg(s, rn, tmp);
+@@ -7738,7 +7738,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+                             } else if (user) {
+                                 tmp = tcg_temp_new_i32();
+                                 tmp2 = tcg_const_i32(i);
+-                                gen_helper_get_user_reg(tmp, tmp2);
++                                gen_helper_get_user_reg(tmp, cpu_env, tmp2);
+                                 tcg_temp_free_i32(tmp2);
+                             } else {
+                                 tmp = load_reg(s, i);
+@@ -7865,31 +7865,31 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCG
+         break;
+     case 8: /* add */
+         if (conds)
+-            gen_helper_add_cc(t0, t0, t1);
++            gen_helper_add_cc(t0, cpu_env, t0, t1);
+         else
+             tcg_gen_add_i32(t0, t0, t1);
+         break;
+     case 10: /* adc */
+         if (conds)
+-            gen_helper_adc_cc(t0, t0, t1);
++            gen_helper_adc_cc(t0, cpu_env, t0, t1);
+         else
+             gen_adc(t0, t1);
+         break;
+     case 11: /* sbc */
+         if (conds)
+-            gen_helper_sbc_cc(t0, t0, t1);
++            gen_helper_sbc_cc(t0, cpu_env, t0, t1);
+         else
+             gen_sub_carry(t0, t0, t1);
+         break;
+     case 13: /* sub */
+         if (conds)
+-            gen_helper_sub_cc(t0, t0, t1);
++            gen_helper_sub_cc(t0, cpu_env, t0, t1);
+         else
+             tcg_gen_sub_i32(t0, t0, t1);
+         break;
+     case 14: /* rsb */
+         if (conds)
+-            gen_helper_sub_cc(t0, t1, t0);
++            gen_helper_sub_cc(t0, cpu_env, t1, t0);
+         else
+             tcg_gen_sub_i32(t0, t1, t0);
+         break;
+@@ -8111,7 +8111,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
+                     gen_st32(tmp, addr, 0);
+                     tcg_gen_addi_i32(addr, addr, 4);
+                     tmp = tcg_temp_new_i32();
+-                    gen_helper_cpsr_read(tmp);
++                    gen_helper_cpsr_read(tmp, cpu_env);
+                     gen_st32(tmp, addr, 0);
+                     if (insn & (1 << 21)) {
+                         if ((insn & (1 << 24)) == 0) {
+@@ -8293,11 +8293,11 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
+                 tmp = load_reg(s, rn);
+                 tmp2 = load_reg(s, rm);
+                 if (op & 1)
+-                    gen_helper_double_saturate(tmp, tmp);
++                    gen_helper_double_saturate(tmp, cpu_env, tmp);
+                 if (op & 2)
+-                    gen_helper_sub_saturate(tmp, tmp2, tmp);
++                    gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
+                 else
+-                    gen_helper_add_saturate(tmp, tmp, tmp2);
++                    gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
+                 tcg_temp_free_i32(tmp2);
+             } else {
+                 tmp = load_reg(s, rn);
+@@ -8353,7 +8353,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
+                 tcg_temp_free_i32(tmp2);
+                 if (rs != 15) {
+                     tmp2 = load_reg(s, rs);
+-                    gen_helper_add_setq(tmp, tmp, tmp2);
++                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
+                     tcg_temp_free_i32(tmp2);
+                 }
+                 break;
+@@ -8370,13 +8370,13 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
+                      * however it may overflow considered as a signed
+                      * operation, in which case we must set the Q flag.
+                      */
+-                    gen_helper_add_setq(tmp, tmp, tmp2);
++                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
+                 }
+                 tcg_temp_free_i32(tmp2);
+                 if (rs != 15)
+                   {
+                     tmp2 = load_reg(s, rs);
+-                    gen_helper_add_setq(tmp, tmp, tmp2);
++                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
+                     tcg_temp_free_i32(tmp2);
+                   }
+                 break;
+@@ -8393,7 +8393,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
+                 if (rs != 15)
+                   {
+                     tmp2 = load_reg(s, rs);
+-                    gen_helper_add_setq(tmp, tmp, tmp2);
++                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
+                     tcg_temp_free_i32(tmp2);
+                   }
+                 break;
+@@ -8632,7 +8632,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
+                             gen_helper_v7m_mrs(tmp, cpu_env, addr);
+                             tcg_temp_free_i32(addr);
+                         } else {
+-                            gen_helper_cpsr_read(tmp);
++                            gen_helper_cpsr_read(tmp, cpu_env);
+                         }
+                         store_reg(s, rd, tmp);
+                         break;
+@@ -8721,15 +8721,15 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
+                         if (op & 4) {
+                             /* Unsigned.  */
+                             if ((op & 1) && shift == 0)
+-                                gen_helper_usat16(tmp, tmp, tmp2);
++                                gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
+                             else
+-                                gen_helper_usat(tmp, tmp, tmp2);
++                                gen_helper_usat(tmp, cpu_env, tmp, tmp2);
+                         } else {
+                             /* Signed.  */
+                             if ((op & 1) && shift == 0)
+-                                gen_helper_ssat16(tmp, tmp, tmp2);
++                                gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
+                             else
+-                                gen_helper_ssat(tmp, tmp, tmp2);
++                                gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
+                         }
+                         tcg_temp_free_i32(tmp2);
+                         break;
+@@ -9017,12 +9017,12 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
+                 if (s->condexec_mask)
+                     tcg_gen_sub_i32(tmp, tmp, tmp2);
+                 else
+-                    gen_helper_sub_cc(tmp, tmp, tmp2);
++                    gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+             } else {
+                 if (s->condexec_mask)
+                     tcg_gen_add_i32(tmp, tmp, tmp2);
+                 else
+-                    gen_helper_add_cc(tmp, tmp, tmp2);
++                    gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
+             }
+             tcg_temp_free_i32(tmp2);
+             store_reg(s, rd, tmp);
+@@ -9053,7 +9053,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
+             tcg_gen_movi_i32(tmp2, insn & 0xff);
+             switch (op) {
+             case 1: /* cmp */
+-                gen_helper_sub_cc(tmp, tmp, tmp2);
++                gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+                 tcg_temp_free_i32(tmp);
+                 tcg_temp_free_i32(tmp2);
+                 break;
+@@ -9061,7 +9061,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
+                 if (s->condexec_mask)
+                     tcg_gen_add_i32(tmp, tmp, tmp2);
+                 else
+-                    gen_helper_add_cc(tmp, tmp, tmp2);
++                    gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
+                 tcg_temp_free_i32(tmp2);
+                 store_reg(s, rd, tmp);
+                 break;
+@@ -9069,7 +9069,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
+                 if (s->condexec_mask)
+                     tcg_gen_sub_i32(tmp, tmp, tmp2);
+                 else
+-                    gen_helper_sub_cc(tmp, tmp, tmp2);
++                    gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+                 tcg_temp_free_i32(tmp2);
+                 store_reg(s, rd, tmp);
+                 break;
+@@ -9105,7 +9105,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
+             case 1: /* cmp */
+                 tmp = load_reg(s, rd);
+                 tmp2 = load_reg(s, rm);
+-                gen_helper_sub_cc(tmp, tmp, tmp2);
++                gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+                 tcg_temp_free_i32(tmp2);
+                 tcg_temp_free_i32(tmp);
+                 break;
+@@ -9166,25 +9166,25 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
+             break;
+         case 0x2: /* lsl */
+             if (s->condexec_mask) {
+-                gen_helper_shl(tmp2, tmp2, tmp);
++                gen_helper_shl(tmp2, cpu_env, tmp2, tmp);
+             } else {
+-                gen_helper_shl_cc(tmp2, tmp2, tmp);
++                gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
+                 gen_logic_CC(tmp2);
+             }
+             break;
+         case 0x3: /* lsr */
+             if (s->condexec_mask) {
+-                gen_helper_shr(tmp2, tmp2, tmp);
++                gen_helper_shr(tmp2, cpu_env, tmp2, tmp);
+             } else {
+-                gen_helper_shr_cc(tmp2, tmp2, tmp);
++                gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
+                 gen_logic_CC(tmp2);
+             }
+             break;
+         case 0x4: /* asr */
+             if (s->condexec_mask) {
+-                gen_helper_sar(tmp2, tmp2, tmp);
++                gen_helper_sar(tmp2, cpu_env, tmp2, tmp);
+             } else {
+-                gen_helper_sar_cc(tmp2, tmp2, tmp);
++                gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
+                 gen_logic_CC(tmp2);
+             }
+             break;
+@@ -9192,20 +9192,20 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
+             if (s->condexec_mask)
+                 gen_adc(tmp, tmp2);
+             else
+-                gen_helper_adc_cc(tmp, tmp, tmp2);
++                gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
+             break;
+         case 0x6: /* sbc */
+             if (s->condexec_mask)
+                 gen_sub_carry(tmp, tmp, tmp2);
+             else
+-                gen_helper_sbc_cc(tmp, tmp, tmp2);
++                gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
+             break;
+         case 0x7: /* ror */
+             if (s->condexec_mask) {
+                 tcg_gen_andi_i32(tmp, tmp, 0x1f);
+                 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
+             } else {
+-                gen_helper_ror_cc(tmp2, tmp2, tmp);
++                gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
+                 gen_logic_CC(tmp2);
+             }
+             break;
+@@ -9218,14 +9218,14 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
+             if (s->condexec_mask)
+                 tcg_gen_neg_i32(tmp, tmp2);
+             else
+-                gen_helper_sub_cc(tmp, tmp, tmp2);
++                gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+             break;
+         case 0xa: /* cmp */
+-            gen_helper_sub_cc(tmp, tmp, tmp2);
++            gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
+             rd = 16;
+             break;
+         case 0xb: /* cmn */
+-            gen_helper_add_cc(tmp, tmp, tmp2);
++            gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
+             rd = 16;
+             break;
+         case 0xc: /* orr */
+-- 
+1.7.12.1
+
diff --git a/0033-target-arm-final-conversion-to-AREG0-free-mode.patch b/0033-target-arm-final-conversion-to-AREG0-free-mode.patch
new file mode 100644
index 0000000..8a83359
--- /dev/null
+++ b/0033-target-arm-final-conversion-to-AREG0-free-mode.patch
@@ -0,0 +1,179 @@
+From 28b8f097f9fb107882aa51bd25ba87619beb033e Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Tue, 4 Sep 2012 20:25:59 +0000
+Subject: [PATCH] target-arm: final conversion to AREG0 free mode
+
+Convert code load functions and switch to AREG0 free mode.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure                |  2 +-
+ target-arm/Makefile.objs |  2 --
+ target-arm/cpu.h         | 10 ++++++----
+ target-arm/helper.c      |  9 +++++----
+ target-arm/op_helper.c   |  8 +-------
+ target-arm/translate.c   |  6 +++---
+ 6 files changed, 16 insertions(+), 21 deletions(-)
+
+diff --git a/configure b/configure
+index a8827ba..e8806f0 100755
+--- a/configure
++++ b/configure
+@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+ 
+ 
+ case "$target_arch2" in
+-  alpha | i386 | lm32 | m68k | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
++  alpha | arm* | i386 | lm32 | m68k | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
+     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
+   ;;
+ esac
+diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
+index f447c4f..b6f1a9e 100644
+--- a/target-arm/Makefile.objs
++++ b/target-arm/Makefile.objs
+@@ -2,5 +2,3 @@ obj-y += arm-semi.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+ obj-y += translate.o op_helper.o helper.o cpu.o
+ obj-y += neon_helper.o iwmmxt_helper.o
+-
+-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-arm/cpu.h b/target-arm/cpu.h
+index d7f93d9..7fac94f 100644
+--- a/target-arm/cpu.h
++++ b/target-arm/cpu.h
+@@ -734,9 +734,10 @@ static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb)
+ }
+ 
+ /* Load an instruction and return it in the standard little-endian order */
+-static inline uint32_t arm_ldl_code(uint32_t addr, bool do_swap)
++static inline uint32_t arm_ldl_code(CPUARMState *env, uint32_t addr,
++                                    bool do_swap)
+ {
+-    uint32_t insn = ldl_code(addr);
++    uint32_t insn = cpu_ldl_code(env, addr);
+     if (do_swap) {
+         return bswap32(insn);
+     }
+@@ -744,9 +745,10 @@ static inline uint32_t arm_ldl_code(uint32_t addr, bool do_swap)
+ }
+ 
+ /* Ditto, for a halfword (Thumb) instruction */
+-static inline uint16_t arm_lduw_code(uint32_t addr, bool do_swap)
++static inline uint16_t arm_lduw_code(CPUARMState *env, uint32_t addr,
++                                     bool do_swap)
+ {
+-    uint16_t insn = lduw_code(addr);
++    uint16_t insn = cpu_lduw_code(env, addr);
+     if (do_swap) {
+         return bswap16(insn);
+     }
+diff --git a/target-arm/helper.c b/target-arm/helper.c
+index e27df96..58340bd 100644
+--- a/target-arm/helper.c
++++ b/target-arm/helper.c
+@@ -1756,7 +1756,7 @@ static void do_interrupt_v7m(CPUARMState *env)
+     case EXCP_BKPT:
+         if (semihosting_enabled) {
+             int nr;
+-            nr = arm_lduw_code(env->regs[15], env->bswap_code) & 0xff;
++            nr = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff;
+             if (nr == 0xab) {
+                 env->regs[15] += 2;
+                 env->regs[0] = do_arm_semihosting(env);
+@@ -1828,9 +1828,10 @@ void do_interrupt(CPUARMState *env)
+         if (semihosting_enabled) {
+             /* Check for semihosting interrupt.  */
+             if (env->thumb) {
+-                mask = arm_lduw_code(env->regs[15] - 2, env->bswap_code) & 0xff;
++                mask = arm_lduw_code(env, env->regs[15] - 2, env->bswap_code)
++                    & 0xff;
+             } else {
+-                mask = arm_ldl_code(env->regs[15] - 4, env->bswap_code)
++                mask = arm_ldl_code(env, env->regs[15] - 4, env->bswap_code)
+                     & 0xffffff;
+             }
+             /* Only intercept calls from privileged modes, to provide some
+@@ -1851,7 +1852,7 @@ void do_interrupt(CPUARMState *env)
+     case EXCP_BKPT:
+         /* See if this is a semihosting syscall.  */
+         if (env->thumb && semihosting_enabled) {
+-            mask = arm_lduw_code(env->regs[15], env->bswap_code) & 0xff;
++            mask = arm_lduw_code(env, env->regs[15], env->bswap_code) & 0xff;
+             if (mask == 0xab
+                   && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
+                 env->regs[15] += 2;
+diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
+index 5b868bf..f13fc3a 100644
+--- a/target-arm/op_helper.c
++++ b/target-arm/op_helper.c
+@@ -17,7 +17,6 @@
+  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+  */
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "helper.h"
+ 
+ #define SIGNBIT (uint32_t)0x80000000
+@@ -72,16 +71,12 @@ uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
+ /* try to fill the TLB and return an exception if error. If retaddr is
+    NULL, it means that the function was called in C code (i.e. not
+    from generated code or from helper.c) */
+-/* XXX: fix it to restore all registers */
+-void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx,
++void tlb_fill(CPUARMState *env, target_ulong addr, int is_write, int mmu_idx,
+               uintptr_t retaddr)
+ {
+     TranslationBlock *tb;
+-    CPUARMState *saved_env;
+     int ret;
+ 
+-    saved_env = env;
+-    env = env1;
+     ret = cpu_arm_handle_mmu_fault(env, addr, is_write, mmu_idx);
+     if (unlikely(ret)) {
+         if (retaddr) {
+@@ -95,7 +90,6 @@ void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx,
+         }
+         raise_exception(env, env->exception_index);
+     }
+-    env = saved_env;
+ }
+ #endif
+ 
+diff --git a/target-arm/translate.c b/target-arm/translate.c
+index 9ae3b26..f4b447a 100644
+--- a/target-arm/translate.c
++++ b/target-arm/translate.c
+@@ -6534,7 +6534,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
+     TCGv addr;
+     TCGv_i64 tmp64;
+ 
+-    insn = arm_ldl_code(s->pc, s->bswap_code);
++    insn = arm_ldl_code(env, s->pc, s->bswap_code);
+     s->pc += 4;
+ 
+     /* M variants do not implement ARM mode.  */
+@@ -7962,7 +7962,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
+         /* Fall through to 32-bit decode.  */
+     }
+ 
+-    insn = arm_lduw_code(s->pc, s->bswap_code);
++    insn = arm_lduw_code(env, s->pc, s->bswap_code);
+     s->pc += 2;
+     insn |= (uint32_t)insn_hw1 << 16;
+ 
+@@ -8992,7 +8992,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
+         }
+     }
+ 
+-    insn = arm_lduw_code(s->pc, s->bswap_code);
++    insn = arm_lduw_code(env, s->pc, s->bswap_code);
+     s->pc += 2;
+ 
+     switch (insn >> 12) {
+-- 
+1.7.12.1
+
diff --git a/0034-target-microblaze-switch-to-AREG0-free-mode.patch b/0034-target-microblaze-switch-to-AREG0-free-mode.patch
new file mode 100644
index 0000000..fea6bb8
--- /dev/null
+++ b/0034-target-microblaze-switch-to-AREG0-free-mode.patch
@@ -0,0 +1,715 @@
+From 449d4f2cfbdd2b5fd00e3e82c78bf580bd81551d Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 08:39:22 +0000
+Subject: [PATCH] target-microblaze: switch to AREG0 free mode
+
+Add an explicit CPUState parameter instead of relying on AREG0
+and switch to AREG0 free mode.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure                       |   2 +-
+ target-microblaze/Makefile.objs |   2 -
+ target-microblaze/helper.h      |  48 ++++++++---------
+ target-microblaze/op_helper.c   | 115 ++++++++++++++++++----------------------
+ target-microblaze/translate.c   |  61 +++++++++++----------
+ 5 files changed, 110 insertions(+), 118 deletions(-)
+
+diff --git a/configure b/configure
+index e8806f0..0b4ef4a 100755
+--- a/configure
++++ b/configure
+@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+ 
+ 
+ case "$target_arch2" in
+-  alpha | arm* | i386 | lm32 | m68k | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
++  alpha | arm* | i386 | lm32 | m68k | microblaze* | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
+     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
+   ;;
+ esac
+diff --git a/target-microblaze/Makefile.objs b/target-microblaze/Makefile.objs
+index 4b09e8c..afb87bc 100644
+--- a/target-microblaze/Makefile.objs
++++ b/target-microblaze/Makefile.objs
+@@ -1,4 +1,2 @@
+ obj-y += translate.o op_helper.o helper.o cpu.o
+ obj-$(CONFIG_SOFTMMU) += mmu.o machine.o
+-
+-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-microblaze/helper.h b/target-microblaze/helper.h
+index 9dcfb0f..a1a732c 100644
+--- a/target-microblaze/helper.h
++++ b/target-microblaze/helper.h
+@@ -1,39 +1,39 @@
+ #include "def-helper.h"
+ 
+-DEF_HELPER_1(raise_exception, void, i32)
+-DEF_HELPER_0(debug, void)
++DEF_HELPER_2(raise_exception, void, env, i32)
++DEF_HELPER_1(debug, void, env)
+ DEF_HELPER_FLAGS_3(carry, TCG_CALL_PURE | TCG_CALL_CONST, i32, i32, i32, i32)
+ DEF_HELPER_2(cmp, i32, i32, i32)
+ DEF_HELPER_2(cmpu, i32, i32, i32)
+ DEF_HELPER_FLAGS_1(clz, TCG_CALL_PURE | TCG_CALL_CONST, i32, i32)
+ 
+-DEF_HELPER_2(divs, i32, i32, i32)
+-DEF_HELPER_2(divu, i32, i32, i32)
+-
+-DEF_HELPER_2(fadd, i32, i32, i32)
+-DEF_HELPER_2(frsub, i32, i32, i32)
+-DEF_HELPER_2(fmul, i32, i32, i32)
+-DEF_HELPER_2(fdiv, i32, i32, i32)
+-DEF_HELPER_1(flt, i32, i32)
+-DEF_HELPER_1(fint, i32, i32)
+-DEF_HELPER_1(fsqrt, i32, i32)
+-
+-DEF_HELPER_2(fcmp_un, i32, i32, i32)
+-DEF_HELPER_2(fcmp_lt, i32, i32, i32)
+-DEF_HELPER_2(fcmp_eq, i32, i32, i32)
+-DEF_HELPER_2(fcmp_le, i32, i32, i32)
+-DEF_HELPER_2(fcmp_gt, i32, i32, i32)
+-DEF_HELPER_2(fcmp_ne, i32, i32, i32)
+-DEF_HELPER_2(fcmp_ge, i32, i32, i32)
++DEF_HELPER_3(divs, i32, env, i32, i32)
++DEF_HELPER_3(divu, i32, env, i32, i32)
++
++DEF_HELPER_3(fadd, i32, env, i32, i32)
++DEF_HELPER_3(frsub, i32, env, i32, i32)
++DEF_HELPER_3(fmul, i32, env, i32, i32)
++DEF_HELPER_3(fdiv, i32, env, i32, i32)
++DEF_HELPER_2(flt, i32, env, i32)
++DEF_HELPER_2(fint, i32, env, i32)
++DEF_HELPER_2(fsqrt, i32, env, i32)
++
++DEF_HELPER_3(fcmp_un, i32, env, i32, i32)
++DEF_HELPER_3(fcmp_lt, i32, env, i32, i32)
++DEF_HELPER_3(fcmp_eq, i32, env, i32, i32)
++DEF_HELPER_3(fcmp_le, i32, env, i32, i32)
++DEF_HELPER_3(fcmp_gt, i32, env, i32, i32)
++DEF_HELPER_3(fcmp_ne, i32, env, i32, i32)
++DEF_HELPER_3(fcmp_ge, i32, env, i32, i32)
+ 
+ DEF_HELPER_FLAGS_2(pcmpbf, TCG_CALL_PURE | TCG_CALL_CONST, i32, i32, i32)
+ #if !defined(CONFIG_USER_ONLY)
+-DEF_HELPER_1(mmu_read, i32, i32)
+-DEF_HELPER_2(mmu_write, void, i32, i32)
++DEF_HELPER_2(mmu_read, i32, env, i32)
++DEF_HELPER_3(mmu_write, void, env, i32, i32)
+ #endif
+ 
+-DEF_HELPER_4(memalign, void, i32, i32, i32, i32)
+-DEF_HELPER_1(stackprot, void, i32)
++DEF_HELPER_5(memalign, void, env, i32, i32, i32, i32)
++DEF_HELPER_2(stackprot, void, env, i32)
+ 
+ DEF_HELPER_2(get, i32, i32, i32)
+ DEF_HELPER_3(put, void, i32, i32, i32)
+diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
+index 3b1f072..c9789f4 100644
+--- a/target-microblaze/op_helper.c
++++ b/target-microblaze/op_helper.c
+@@ -20,7 +20,6 @@
+ 
+ #include <assert.h>
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "helper.h"
+ #include "host-utils.h"
+ 
+@@ -42,17 +41,12 @@
+ /* Try to fill the TLB and return an exception if error. If retaddr is
+    NULL, it means that the function was called in C code (i.e. not
+    from generated code or from helper.c) */
+-/* XXX: fix it to restore all registers */
+-void tlb_fill(CPUMBState *env1, target_ulong addr, int is_write, int mmu_idx,
++void tlb_fill(CPUMBState *env, target_ulong addr, int is_write, int mmu_idx,
+               uintptr_t retaddr)
+ {
+     TranslationBlock *tb;
+-    CPUMBState *saved_env;
+     int ret;
+ 
+-    saved_env = env;
+-    env = env1;
+-
+     ret = cpu_mb_handle_mmu_fault(env, addr, is_write, mmu_idx);
+     if (unlikely(ret)) {
+         if (retaddr) {
+@@ -66,7 +60,6 @@ void tlb_fill(CPUMBState *env1, target_ulong addr, int is_write, int mmu_idx,
+         }
+         cpu_loop_exit(env);
+     }
+-    env = saved_env;
+ }
+ #endif
+ 
+@@ -105,13 +98,13 @@ uint32_t helper_get(uint32_t id, uint32_t ctrl)
+     return 0xdead0000 | id;
+ }
+ 
+-void helper_raise_exception(uint32_t index)
++void helper_raise_exception(CPUMBState *env, uint32_t index)
+ {
+     env->exception_index = index;
+     cpu_loop_exit(env);
+ }
+ 
+-void helper_debug(void)
++void helper_debug(CPUMBState *env)
+ {
+     int i;
+ 
+@@ -176,7 +169,7 @@ uint32_t helper_carry(uint32_t a, uint32_t b, uint32_t cf)
+     return ncf;
+ }
+ 
+-static inline int div_prepare(uint32_t a, uint32_t b)
++static inline int div_prepare(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     if (b == 0) {
+         env->sregs[SR_MSR] |= MSR_DZ;
+@@ -184,7 +177,7 @@ static inline int div_prepare(uint32_t a, uint32_t b)
+         if ((env->sregs[SR_MSR] & MSR_EE)
+             && !(env->pvr.regs[2] & PVR2_DIV_ZERO_EXC_MASK)) {
+             env->sregs[SR_ESR] = ESR_EC_DIVZERO;
+-            helper_raise_exception(EXCP_HW_EXCP);
++            helper_raise_exception(env, EXCP_HW_EXCP);
+         }
+         return 0;
+     }
+@@ -192,28 +185,30 @@ static inline int div_prepare(uint32_t a, uint32_t b)
+     return 1;
+ }
+ 
+-uint32_t helper_divs(uint32_t a, uint32_t b)
++uint32_t helper_divs(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+-    if (!div_prepare(a, b))
++    if (!div_prepare(env, a, b)) {
+         return 0;
++    }
+     return (int32_t)a / (int32_t)b;
+ }
+ 
+-uint32_t helper_divu(uint32_t a, uint32_t b)
++uint32_t helper_divu(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+-    if (!div_prepare(a, b))
++    if (!div_prepare(env, a, b)) {
+         return 0;
++    }
+     return a / b;
+ }
+ 
+ /* raise FPU exception.  */
+-static void raise_fpu_exception(void)
++static void raise_fpu_exception(CPUMBState *env)
+ {
+     env->sregs[SR_ESR] = ESR_EC_FPU;
+-    helper_raise_exception(EXCP_HW_EXCP);
++    helper_raise_exception(env, EXCP_HW_EXCP);
+ }
+ 
+-static void update_fpu_flags(int flags)
++static void update_fpu_flags(CPUMBState *env, int flags)
+ {
+     int raise = 0;
+ 
+@@ -236,11 +231,11 @@ static void update_fpu_flags(int flags)
+     if (raise
+         && (env->pvr.regs[2] & PVR2_FPU_EXC_MASK)
+         && (env->sregs[SR_MSR] & MSR_EE)) {
+-        raise_fpu_exception();
++        raise_fpu_exception(env);
+     }
+ }
+ 
+-uint32_t helper_fadd(uint32_t a, uint32_t b)
++uint32_t helper_fadd(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fd, fa, fb;
+     int flags;
+@@ -251,11 +246,11 @@ uint32_t helper_fadd(uint32_t a, uint32_t b)
+     fd.f = float32_add(fa.f, fb.f, &env->fp_status);
+ 
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags);
++    update_fpu_flags(env, flags);
+     return fd.l;
+ }
+ 
+-uint32_t helper_frsub(uint32_t a, uint32_t b)
++uint32_t helper_frsub(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fd, fa, fb;
+     int flags;
+@@ -265,11 +260,11 @@ uint32_t helper_frsub(uint32_t a, uint32_t b)
+     fb.l = b;
+     fd.f = float32_sub(fb.f, fa.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags);
++    update_fpu_flags(env, flags);
+     return fd.l;
+ }
+ 
+-uint32_t helper_fmul(uint32_t a, uint32_t b)
++uint32_t helper_fmul(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fd, fa, fb;
+     int flags;
+@@ -279,12 +274,12 @@ uint32_t helper_fmul(uint32_t a, uint32_t b)
+     fb.l = b;
+     fd.f = float32_mul(fa.f, fb.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags);
++    update_fpu_flags(env, flags);
+ 
+     return fd.l;
+ }
+ 
+-uint32_t helper_fdiv(uint32_t a, uint32_t b)
++uint32_t helper_fdiv(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fd, fa, fb;
+     int flags;
+@@ -294,12 +289,12 @@ uint32_t helper_fdiv(uint32_t a, uint32_t b)
+     fb.l = b;
+     fd.f = float32_div(fb.f, fa.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags);
++    update_fpu_flags(env, flags);
+ 
+     return fd.l;
+ }
+ 
+-uint32_t helper_fcmp_un(uint32_t a, uint32_t b)
++uint32_t helper_fcmp_un(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fa, fb;
+     uint32_t r = 0;
+@@ -308,7 +303,7 @@ uint32_t helper_fcmp_un(uint32_t a, uint32_t b)
+     fb.l = b;
+ 
+     if (float32_is_signaling_nan(fa.f) || float32_is_signaling_nan(fb.f)) {
+-        update_fpu_flags(float_flag_invalid);
++        update_fpu_flags(env, float_flag_invalid);
+         r = 1;
+     }
+ 
+@@ -319,7 +314,7 @@ uint32_t helper_fcmp_un(uint32_t a, uint32_t b)
+     return r;
+ }
+ 
+-uint32_t helper_fcmp_lt(uint32_t a, uint32_t b)
++uint32_t helper_fcmp_lt(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fa, fb;
+     int r;
+@@ -330,12 +325,12 @@ uint32_t helper_fcmp_lt(uint32_t a, uint32_t b)
+     fb.l = b;
+     r = float32_lt(fb.f, fa.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags & float_flag_invalid);
++    update_fpu_flags(env, flags & float_flag_invalid);
+ 
+     return r;
+ }
+ 
+-uint32_t helper_fcmp_eq(uint32_t a, uint32_t b)
++uint32_t helper_fcmp_eq(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fa, fb;
+     int flags;
+@@ -346,12 +341,12 @@ uint32_t helper_fcmp_eq(uint32_t a, uint32_t b)
+     fb.l = b;
+     r = float32_eq_quiet(fa.f, fb.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags & float_flag_invalid);
++    update_fpu_flags(env, flags & float_flag_invalid);
+ 
+     return r;
+ }
+ 
+-uint32_t helper_fcmp_le(uint32_t a, uint32_t b)
++uint32_t helper_fcmp_le(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fa, fb;
+     int flags;
+@@ -362,13 +357,13 @@ uint32_t helper_fcmp_le(uint32_t a, uint32_t b)
+     set_float_exception_flags(0, &env->fp_status);
+     r = float32_le(fa.f, fb.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags & float_flag_invalid);
++    update_fpu_flags(env, flags & float_flag_invalid);
+ 
+ 
+     return r;
+ }
+ 
+-uint32_t helper_fcmp_gt(uint32_t a, uint32_t b)
++uint32_t helper_fcmp_gt(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fa, fb;
+     int flags, r;
+@@ -378,11 +373,11 @@ uint32_t helper_fcmp_gt(uint32_t a, uint32_t b)
+     set_float_exception_flags(0, &env->fp_status);
+     r = float32_lt(fa.f, fb.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags & float_flag_invalid);
++    update_fpu_flags(env, flags & float_flag_invalid);
+     return r;
+ }
+ 
+-uint32_t helper_fcmp_ne(uint32_t a, uint32_t b)
++uint32_t helper_fcmp_ne(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fa, fb;
+     int flags, r;
+@@ -392,12 +387,12 @@ uint32_t helper_fcmp_ne(uint32_t a, uint32_t b)
+     set_float_exception_flags(0, &env->fp_status);
+     r = !float32_eq_quiet(fa.f, fb.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags & float_flag_invalid);
++    update_fpu_flags(env, flags & float_flag_invalid);
+ 
+     return r;
+ }
+ 
+-uint32_t helper_fcmp_ge(uint32_t a, uint32_t b)
++uint32_t helper_fcmp_ge(CPUMBState *env, uint32_t a, uint32_t b)
+ {
+     CPU_FloatU fa, fb;
+     int flags, r;
+@@ -407,12 +402,12 @@ uint32_t helper_fcmp_ge(uint32_t a, uint32_t b)
+     set_float_exception_flags(0, &env->fp_status);
+     r = !float32_lt(fa.f, fb.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags & float_flag_invalid);
++    update_fpu_flags(env, flags & float_flag_invalid);
+ 
+     return r;
+ }
+ 
+-uint32_t helper_flt(uint32_t a)
++uint32_t helper_flt(CPUMBState *env, uint32_t a)
+ {
+     CPU_FloatU fd, fa;
+ 
+@@ -421,7 +416,7 @@ uint32_t helper_flt(uint32_t a)
+     return fd.l;
+ }
+ 
+-uint32_t helper_fint(uint32_t a)
++uint32_t helper_fint(CPUMBState *env, uint32_t a)
+ {
+     CPU_FloatU fa;
+     uint32_t r;
+@@ -431,12 +426,12 @@ uint32_t helper_fint(uint32_t a)
+     fa.l = a;
+     r = float32_to_int32(fa.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags);
++    update_fpu_flags(env, flags);
+ 
+     return r;
+ }
+ 
+-uint32_t helper_fsqrt(uint32_t a)
++uint32_t helper_fsqrt(CPUMBState *env, uint32_t a)
+ {
+     CPU_FloatU fd, fa;
+     int flags;
+@@ -445,7 +440,7 @@ uint32_t helper_fsqrt(uint32_t a)
+     fa.l = a;
+     fd.l = float32_sqrt(fa.f, &env->fp_status);
+     flags = get_float_exception_flags(&env->fp_status);
+-    update_fpu_flags(flags);
++    update_fpu_flags(env, flags);
+ 
+     return fd.l;
+ }
+@@ -463,7 +458,8 @@ uint32_t helper_pcmpbf(uint32_t a, uint32_t b)
+     return 0;
+ }
+ 
+-void helper_memalign(uint32_t addr, uint32_t dr, uint32_t wr, uint32_t mask)
++void helper_memalign(CPUMBState *env, uint32_t addr, uint32_t dr, uint32_t wr,
++                     uint32_t mask)
+ {
+     if (addr & mask) {
+             qemu_log_mask(CPU_LOG_INT,
+@@ -478,45 +474,39 @@ void helper_memalign(uint32_t addr, uint32_t dr, uint32_t wr, uint32_t mask)
+             if (!(env->sregs[SR_MSR] & MSR_EE)) {
+                 return;
+             }
+-            helper_raise_exception(EXCP_HW_EXCP);
++            helper_raise_exception(env, EXCP_HW_EXCP);
+     }
+ }
+ 
+-void helper_stackprot(uint32_t addr)
++void helper_stackprot(CPUMBState *env, uint32_t addr)
+ {
+     if (addr < env->slr || addr > env->shr) {
+             qemu_log("Stack protector violation at %x %x %x\n",
+                      addr, env->slr, env->shr);
+             env->sregs[SR_EAR] = addr;
+             env->sregs[SR_ESR] = ESR_EC_STACKPROT;
+-            helper_raise_exception(EXCP_HW_EXCP);
++            helper_raise_exception(env, EXCP_HW_EXCP);
+     }
+ }
+ 
+ #if !defined(CONFIG_USER_ONLY)
+ /* Writes/reads to the MMU's special regs end up here.  */
+-uint32_t helper_mmu_read(uint32_t rn)
++uint32_t helper_mmu_read(CPUMBState *env, uint32_t rn)
+ {
+     return mmu_read(env, rn);
+ }
+ 
+-void helper_mmu_write(uint32_t rn, uint32_t v)
++void helper_mmu_write(CPUMBState *env, uint32_t rn, uint32_t v)
+ {
+     mmu_write(env, rn, v);
+ }
+ 
+-void cpu_unassigned_access(CPUMBState *env1, target_phys_addr_t addr,
++void cpu_unassigned_access(CPUMBState *env, target_phys_addr_t addr,
+                            int is_write, int is_exec, int is_asi, int size)
+ {
+-    CPUMBState *saved_env;
+-
+-    saved_env = env;
+-    env = env1;
+-
+     qemu_log_mask(CPU_LOG_INT, "Unassigned " TARGET_FMT_plx " wr=%d exe=%d\n",
+              addr, is_write, is_exec);
+     if (!(env->sregs[SR_MSR] & MSR_EE)) {
+-        env = saved_env;
+         return;
+     }
+ 
+@@ -524,14 +514,13 @@ void cpu_unassigned_access(CPUMBState *env1, target_phys_addr_t addr,
+     if (is_exec) {
+         if ((env->pvr.regs[2] & PVR2_IOPB_BUS_EXC_MASK)) {
+             env->sregs[SR_ESR] = ESR_EC_INSN_BUS;
+-            helper_raise_exception(EXCP_HW_EXCP);
++            helper_raise_exception(env, EXCP_HW_EXCP);
+         }
+     } else {
+         if ((env->pvr.regs[2] & PVR2_DOPB_BUS_EXC_MASK)) {
+             env->sregs[SR_ESR] = ESR_EC_DATA_BUS;
+-            helper_raise_exception(EXCP_HW_EXCP);
++            helper_raise_exception(env, EXCP_HW_EXCP);
+         }
+     }
+-    env = saved_env;
+ }
+ #endif
+diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
+index 7470149..9c7d77f 100644
+--- a/target-microblaze/translate.c
++++ b/target-microblaze/translate.c
+@@ -126,7 +126,7 @@ static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
+ 
+     t_sync_flags(dc);
+     tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
+-    gen_helper_raise_exception(tmp);
++    gen_helper_raise_exception(cpu_env, tmp);
+     tcg_temp_free_i32(tmp);
+     dc->is_jmp = DISAS_UPDATE;
+ }
+@@ -503,9 +503,9 @@ static void dec_msr(DisasContext *dc)
+         sr &= 7;
+         LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
+         if (to)
+-            gen_helper_mmu_write(tcg_const_tl(sr), cpu_R[dc->ra]);
++            gen_helper_mmu_write(cpu_env, tcg_const_tl(sr), cpu_R[dc->ra]);
+         else
+-            gen_helper_mmu_read(cpu_R[dc->rd], tcg_const_tl(sr));
++            gen_helper_mmu_read(cpu_R[dc->rd], cpu_env, tcg_const_tl(sr));
+         return;
+     }
+ #endif
+@@ -704,9 +704,11 @@ static void dec_div(DisasContext *dc)
+     }
+ 
+     if (u)
+-        gen_helper_divu(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
++        gen_helper_divu(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
++                        cpu_R[dc->ra]);
+     else
+-        gen_helper_divs(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
++        gen_helper_divs(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
++                        cpu_R[dc->ra]);
+     if (!dc->rd)
+         tcg_gen_movi_tl(cpu_R[dc->rd], 0);
+ }
+@@ -912,7 +914,7 @@ static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
+         tcg_gen_add_tl(*t, cpu_R[dc->ra], cpu_R[dc->rb]);
+ 
+         if (stackprot) {
+-            gen_helper_stackprot(*t);
++            gen_helper_stackprot(cpu_env, *t);
+         }
+         return t;
+     }
+@@ -930,7 +932,7 @@ static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
+     }
+ 
+     if (stackprot) {
+-        gen_helper_stackprot(*t);
++        gen_helper_stackprot(cpu_env, *t);
+     }
+     return t;
+ }
+@@ -1056,7 +1058,7 @@ static void dec_load(DisasContext *dc)
+         gen_load(dc, v, *addr, size);
+ 
+         tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
+-        gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
++        gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
+                             tcg_const_tl(0), tcg_const_tl(size - 1));
+         if (dc->rd) {
+             if (rev) {
+@@ -1218,7 +1220,7 @@ static void dec_store(DisasContext *dc)
+          *        the alignment checks in between the probe and the mem
+          *        access.
+          */
+-        gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
++        gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
+                             tcg_const_tl(1), tcg_const_tl(size - 1));
+     }
+ 
+@@ -1493,49 +1495,53 @@ static void dec_fpu(DisasContext *dc)
+ 
+     switch (fpu_insn) {
+         case 0:
+-            gen_helper_fadd(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
++            gen_helper_fadd(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
++                            cpu_R[dc->rb]);
+             break;
+ 
+         case 1:
+-            gen_helper_frsub(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
++            gen_helper_frsub(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
++                             cpu_R[dc->rb]);
+             break;
+ 
+         case 2:
+-            gen_helper_fmul(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
++            gen_helper_fmul(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
++                            cpu_R[dc->rb]);
+             break;
+ 
+         case 3:
+-            gen_helper_fdiv(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
++            gen_helper_fdiv(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
++                            cpu_R[dc->rb]);
+             break;
+ 
+         case 4:
+             switch ((dc->ir >> 4) & 7) {
+                 case 0:
+-                    gen_helper_fcmp_un(cpu_R[dc->rd],
++                    gen_helper_fcmp_un(cpu_R[dc->rd], cpu_env,
+                                        cpu_R[dc->ra], cpu_R[dc->rb]);
+                     break;
+                 case 1:
+-                    gen_helper_fcmp_lt(cpu_R[dc->rd],
++                    gen_helper_fcmp_lt(cpu_R[dc->rd], cpu_env,
+                                        cpu_R[dc->ra], cpu_R[dc->rb]);
+                     break;
+                 case 2:
+-                    gen_helper_fcmp_eq(cpu_R[dc->rd],
++                    gen_helper_fcmp_eq(cpu_R[dc->rd], cpu_env,
+                                        cpu_R[dc->ra], cpu_R[dc->rb]);
+                     break;
+                 case 3:
+-                    gen_helper_fcmp_le(cpu_R[dc->rd],
++                    gen_helper_fcmp_le(cpu_R[dc->rd], cpu_env,
+                                        cpu_R[dc->ra], cpu_R[dc->rb]);
+                     break;
+                 case 4:
+-                    gen_helper_fcmp_gt(cpu_R[dc->rd],
++                    gen_helper_fcmp_gt(cpu_R[dc->rd], cpu_env,
+                                        cpu_R[dc->ra], cpu_R[dc->rb]);
+                     break;
+                 case 5:
+-                    gen_helper_fcmp_ne(cpu_R[dc->rd],
++                    gen_helper_fcmp_ne(cpu_R[dc->rd], cpu_env,
+                                        cpu_R[dc->ra], cpu_R[dc->rb]);
+                     break;
+                 case 6:
+-                    gen_helper_fcmp_ge(cpu_R[dc->rd],
++                    gen_helper_fcmp_ge(cpu_R[dc->rd], cpu_env,
+                                        cpu_R[dc->ra], cpu_R[dc->rb]);
+                     break;
+                 default:
+@@ -1552,21 +1558,21 @@ static void dec_fpu(DisasContext *dc)
+             if (!dec_check_fpuv2(dc)) {
+                 return;
+             }
+-            gen_helper_flt(cpu_R[dc->rd], cpu_R[dc->ra]);
++            gen_helper_flt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
+             break;
+ 
+         case 6:
+             if (!dec_check_fpuv2(dc)) {
+                 return;
+             }
+-            gen_helper_fint(cpu_R[dc->rd], cpu_R[dc->ra]);
++            gen_helper_fint(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
+             break;
+ 
+         case 7:
+             if (!dec_check_fpuv2(dc)) {
+                 return;
+             }
+-            gen_helper_fsqrt(cpu_R[dc->rd], cpu_R[dc->ra]);
++            gen_helper_fsqrt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
+             break;
+ 
+         default:
+@@ -1654,15 +1660,14 @@ static struct decoder_info {
+     {{0, 0}, dec_null}
+ };
+ 
+-static inline void decode(DisasContext *dc)
++static inline void decode(DisasContext *dc, uint32_t ir)
+ {
+-    uint32_t ir;
+     int i;
+ 
+     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
+         tcg_gen_debug_insn_start(dc->pc);
+ 
+-    dc->ir = ir = ldl_code(dc->pc);
++    dc->ir = ir;
+     LOG_DIS("%8.8x\t", dc->ir);
+ 
+     if (dc->ir)
+@@ -1796,7 +1801,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
+             gen_io_start();
+ 
+         dc->clear_imm = 1;
+-	decode(dc);
++        decode(dc, cpu_ldl_code(env, dc->pc));
+         if (dc->clear_imm)
+             dc->tb_flags &= ~IMM_FLAG;
+         dc->pc += 4;
+@@ -1871,7 +1876,7 @@ gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
+         if (dc->is_jmp != DISAS_JUMP) {
+             tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
+         }
+-        gen_helper_raise_exception(tmp);
++        gen_helper_raise_exception(cpu_env, tmp);
+         tcg_temp_free_i32(tmp);
+     } else {
+         switch(dc->is_jmp) {
+-- 
+1.7.12.1
+
diff --git a/0035-target-cris-Avoid-AREG0-for-helpers.patch b/0035-target-cris-Avoid-AREG0-for-helpers.patch
new file mode 100644
index 0000000..9314afb
--- /dev/null
+++ b/0035-target-cris-Avoid-AREG0-for-helpers.patch
@@ -0,0 +1,523 @@
+From 1e3916b0cbfd39cb3fc8996423d5574068583145 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Thu, 30 Aug 2012 16:56:39 +0200
+Subject: [PATCH] target-cris: Avoid AREG0 for helpers
+
+Add an explicit CPUCRISState parameter instead of relying on AREG0.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-cris/helper.h        | 37 +++++++++++----------
+ target-cris/op_helper.c     | 80 ++++++++++++++++++++++++---------------------
+ target-cris/translate.c     | 44 +++++++++++++------------
+ target-cris/translate_v10.c |  4 +--
+ 4 files changed, 88 insertions(+), 77 deletions(-)
+
+diff --git a/target-cris/helper.h b/target-cris/helper.h
+index 093063a..99fb326 100644
+--- a/target-cris/helper.h
++++ b/target-cris/helper.h
+@@ -1,26 +1,29 @@
+ #include "def-helper.h"
+ 
+-DEF_HELPER_1(raise_exception, void, i32)
+-DEF_HELPER_1(tlb_flush_pid, void, i32)
+-DEF_HELPER_1(spc_write, void, i32)
++DEF_HELPER_2(raise_exception, void, env, i32)
++DEF_HELPER_2(tlb_flush_pid, void, env, i32)
++DEF_HELPER_2(spc_write, void, env, i32)
+ DEF_HELPER_3(dump, void, i32, i32, i32)
+-DEF_HELPER_0(rfe, void);
+-DEF_HELPER_0(rfn, void);
++DEF_HELPER_1(rfe, void, env);
++DEF_HELPER_1(rfn, void, env);
+ 
+-DEF_HELPER_2(movl_sreg_reg, void, i32, i32)
+-DEF_HELPER_2(movl_reg_sreg, void, i32, i32)
++DEF_HELPER_3(movl_sreg_reg, void, env, i32, i32)
++DEF_HELPER_3(movl_reg_sreg, void, env, i32, i32)
+ 
+ DEF_HELPER_FLAGS_1(lz, TCG_CALL_PURE, i32, i32);
+-DEF_HELPER_FLAGS_3(btst, TCG_CALL_PURE, i32, i32, i32, i32);
++DEF_HELPER_FLAGS_4(btst, TCG_CALL_PURE, i32, env, i32, i32, i32);
+ 
+-DEF_HELPER_FLAGS_3(evaluate_flags_muls, TCG_CALL_PURE, i32, i32, i32, i32)
+-DEF_HELPER_FLAGS_3(evaluate_flags_mulu, TCG_CALL_PURE, i32, i32, i32, i32)
+-DEF_HELPER_FLAGS_4(evaluate_flags_mcp, TCG_CALL_PURE, i32, i32, i32, i32, i32)
+-DEF_HELPER_FLAGS_4(evaluate_flags_alu_4, TCG_CALL_PURE, i32, i32, i32, i32, i32)
+-DEF_HELPER_FLAGS_4(evaluate_flags_sub_4, TCG_CALL_PURE, i32, i32, i32, i32, i32)
+-DEF_HELPER_FLAGS_2(evaluate_flags_move_4, TCG_CALL_PURE, i32, i32, i32)
+-DEF_HELPER_FLAGS_2(evaluate_flags_move_2, TCG_CALL_PURE, i32, i32, i32)
+-DEF_HELPER_0(evaluate_flags, void)
+-DEF_HELPER_0(top_evaluate_flags, void)
++DEF_HELPER_FLAGS_4(evaluate_flags_muls, TCG_CALL_PURE, i32, env, i32, i32, i32)
++DEF_HELPER_FLAGS_4(evaluate_flags_mulu, TCG_CALL_PURE, i32, env, i32, i32, i32)
++DEF_HELPER_FLAGS_5(evaluate_flags_mcp, TCG_CALL_PURE, i32, env,
++                                                      i32, i32, i32, i32)
++DEF_HELPER_FLAGS_5(evaluate_flags_alu_4, TCG_CALL_PURE, i32, env,
++                                                        i32, i32, i32, i32)
++DEF_HELPER_FLAGS_5(evaluate_flags_sub_4, TCG_CALL_PURE, i32, env,
++                                                        i32, i32, i32, i32)
++DEF_HELPER_FLAGS_3(evaluate_flags_move_4, TCG_CALL_PURE, i32, env, i32, i32)
++DEF_HELPER_FLAGS_3(evaluate_flags_move_2, TCG_CALL_PURE, i32, env, i32, i32)
++DEF_HELPER_1(evaluate_flags, void, env)
++DEF_HELPER_1(top_evaluate_flags, void, env)
+ 
+ #include "def-helper.h"
+diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
+index ac7c98c..5ca85a0 100644
+--- a/target-cris/op_helper.c
++++ b/target-cris/op_helper.c
+@@ -79,7 +79,7 @@ void tlb_fill(CPUCRISState *env1, target_ulong addr, int is_write, int mmu_idx,
+                 cpu_restore_state(tb, env, retaddr);
+ 
+ 		/* Evaluate flags after retranslation.  */
+-                helper_top_evaluate_flags();
++                helper_top_evaluate_flags(env);
+             }
+         }
+         cpu_loop_exit(env);
+@@ -89,13 +89,13 @@ void tlb_fill(CPUCRISState *env1, target_ulong addr, int is_write, int mmu_idx,
+ 
+ #endif
+ 
+-void helper_raise_exception(uint32_t index)
++void helper_raise_exception(CPUCRISState *env, uint32_t index)
+ {
+ 	env->exception_index = index;
+         cpu_loop_exit(env);
+ }
+ 
+-void helper_tlb_flush_pid(uint32_t pid)
++void helper_tlb_flush_pid(CPUCRISState *env, uint32_t pid)
+ {
+ #if !defined(CONFIG_USER_ONLY)
+ 	pid &= 0xff;
+@@ -104,7 +104,7 @@ void helper_tlb_flush_pid(uint32_t pid)
+ #endif
+ }
+ 
+-void helper_spc_write(uint32_t new_spc)
++void helper_spc_write(CPUCRISState *env, uint32_t new_spc)
+ {
+ #if !defined(CONFIG_USER_ONLY)
+ 	tlb_flush_page(env, env->pregs[PR_SPC]);
+@@ -121,7 +121,7 @@ void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2)
+ #define EXTRACT_FIELD(src, start, end) \
+ 	    (((src) >> start) & ((1 << (end - start + 1)) - 1))
+ 
+-void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
++void helper_movl_sreg_reg(CPUCRISState *env, uint32_t sreg, uint32_t reg)
+ {
+ 	uint32_t srs;
+ 	srs = env->pregs[PR_SRS];
+@@ -171,7 +171,7 @@ void helper_movl_sreg_reg (uint32_t sreg, uint32_t reg)
+ #endif
+ }
+ 
+-void helper_movl_reg_sreg (uint32_t reg, uint32_t sreg)
++void helper_movl_reg_sreg(CPUCRISState *env, uint32_t reg, uint32_t sreg)
+ {
+ 	uint32_t srs;
+ 	env->pregs[PR_SRS] &= 3;
+@@ -216,7 +216,7 @@ static void cris_ccs_rshift(CPUCRISState *env)
+ 	env->pregs[PR_CCS] = ccs;
+ }
+ 
+-void helper_rfe(void)
++void helper_rfe(CPUCRISState *env)
+ {
+ 	int rflag = env->pregs[PR_CCS] & R_FLAG;
+ 
+@@ -232,7 +232,7 @@ void helper_rfe(void)
+ 		env->pregs[PR_CCS] |= P_FLAG;
+ }
+ 
+-void helper_rfn(void)
++void helper_rfn(CPUCRISState *env)
+ {
+ 	int rflag = env->pregs[PR_CCS] & R_FLAG;
+ 
+@@ -256,7 +256,7 @@ uint32_t helper_lz(uint32_t t0)
+ 	return clz32(t0);
+ }
+ 
+-uint32_t helper_btst(uint32_t t0, uint32_t t1, uint32_t ccs)
++uint32_t helper_btst(CPUCRISState *env, uint32_t t0, uint32_t t1, uint32_t ccs)
+ {
+ 	/* FIXME: clean this up.  */
+ 
+@@ -284,7 +284,8 @@ uint32_t helper_btst(uint32_t t0, uint32_t t1, uint32_t ccs)
+ 	return ccs;
+ }
+ 
+-static inline uint32_t evaluate_flags_writeback(uint32_t flags, uint32_t ccs)
++static inline uint32_t evaluate_flags_writeback(CPUCRISState *env,
++                                                uint32_t flags, uint32_t ccs)
+ {
+ 	unsigned int x, z, mask;
+ 
+@@ -303,7 +304,8 @@ static inline uint32_t evaluate_flags_writeback(uint32_t flags, uint32_t ccs)
+ 	return ccs;
+ }
+ 
+-uint32_t helper_evaluate_flags_muls(uint32_t ccs, uint32_t res, uint32_t mof)
++uint32_t helper_evaluate_flags_muls(CPUCRISState *env,
++                                    uint32_t ccs, uint32_t res, uint32_t mof)
+ {
+ 	uint32_t flags = 0;
+ 	int64_t tmp;
+@@ -321,10 +323,11 @@ uint32_t helper_evaluate_flags_muls(uint32_t ccs, uint32_t res, uint32_t mof)
+ 	if ((dneg && mof != -1)
+ 	    || (!dneg && mof != 0))
+ 		flags |= V_FLAG;
+-	return evaluate_flags_writeback(flags, ccs);
++        return evaluate_flags_writeback(env, flags, ccs);
+ }
+ 
+-uint32_t helper_evaluate_flags_mulu(uint32_t ccs, uint32_t res, uint32_t mof)
++uint32_t helper_evaluate_flags_mulu(CPUCRISState *env,
++                                    uint32_t ccs, uint32_t res, uint32_t mof)
+ {
+ 	uint32_t flags = 0;
+ 	uint64_t tmp;
+@@ -339,10 +342,10 @@ uint32_t helper_evaluate_flags_mulu(uint32_t ccs, uint32_t res, uint32_t mof)
+ 	if (mof)
+ 		flags |= V_FLAG;
+ 
+-	return evaluate_flags_writeback(flags, ccs);
++        return evaluate_flags_writeback(env, flags, ccs);
+ }
+ 
+-uint32_t helper_evaluate_flags_mcp(uint32_t ccs,
++uint32_t helper_evaluate_flags_mcp(CPUCRISState *env, uint32_t ccs,
+ 				   uint32_t src, uint32_t dst, uint32_t res)
+ {
+ 	uint32_t flags = 0;
+@@ -368,10 +371,10 @@ uint32_t helper_evaluate_flags_mcp(uint32_t ccs,
+ 			flags |= R_FLAG;
+ 	}
+ 
+-	return evaluate_flags_writeback(flags, ccs);
++        return evaluate_flags_writeback(env, flags, ccs);
+ }
+ 
+-uint32_t helper_evaluate_flags_alu_4(uint32_t ccs,
++uint32_t helper_evaluate_flags_alu_4(CPUCRISState *env, uint32_t ccs,
+ 				     uint32_t src, uint32_t dst, uint32_t res)
+ {
+ 	uint32_t flags = 0;
+@@ -397,10 +400,10 @@ uint32_t helper_evaluate_flags_alu_4(uint32_t ccs,
+ 			flags |= C_FLAG;
+ 	}
+ 
+-	return evaluate_flags_writeback(flags, ccs);
++        return evaluate_flags_writeback(env, flags, ccs);
+ }
+ 
+-uint32_t helper_evaluate_flags_sub_4(uint32_t ccs,
++uint32_t helper_evaluate_flags_sub_4(CPUCRISState *env, uint32_t ccs,
+ 				     uint32_t src, uint32_t dst, uint32_t res)
+ {
+ 	uint32_t flags = 0;
+@@ -427,10 +430,11 @@ uint32_t helper_evaluate_flags_sub_4(uint32_t ccs,
+ 	}
+ 
+ 	flags ^= C_FLAG;
+-	return evaluate_flags_writeback(flags, ccs);
++        return evaluate_flags_writeback(env, flags, ccs);
+ }
+ 
+-uint32_t helper_evaluate_flags_move_4(uint32_t ccs, uint32_t res)
++uint32_t helper_evaluate_flags_move_4(CPUCRISState *env,
++                                      uint32_t ccs, uint32_t res)
+ {
+ 	uint32_t flags = 0;
+ 
+@@ -439,9 +443,10 @@ uint32_t helper_evaluate_flags_move_4(uint32_t ccs, uint32_t res)
+ 	else if (res == 0L)
+ 		flags |= Z_FLAG;
+ 
+-	return evaluate_flags_writeback(flags, ccs);
++        return evaluate_flags_writeback(env, flags, ccs);
+ }
+-uint32_t helper_evaluate_flags_move_2(uint32_t ccs, uint32_t res)
++uint32_t helper_evaluate_flags_move_2(CPUCRISState *env,
++                                      uint32_t ccs, uint32_t res)
+ {
+ 	uint32_t flags = 0;
+ 
+@@ -450,12 +455,12 @@ uint32_t helper_evaluate_flags_move_2(uint32_t ccs, uint32_t res)
+ 	else if (res == 0)
+ 		flags |= Z_FLAG;
+ 
+-	return evaluate_flags_writeback(flags, ccs);
++        return evaluate_flags_writeback(env, flags, ccs);
+ }
+ 
+ /* TODO: This is expensive. We could split things up and only evaluate part of
+    CCR on a need to know basis. For now, we simply re-evaluate everything.  */
+-void  helper_evaluate_flags(void)
++void helper_evaluate_flags(CPUCRISState *env)
+ {
+ 	uint32_t src, dst, res;
+ 	uint32_t flags = 0;
+@@ -571,25 +576,26 @@ void  helper_evaluate_flags(void)
+ 	if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)
+ 		flags ^= C_FLAG;
+ 
+-	env->pregs[PR_CCS] = evaluate_flags_writeback(flags, env->pregs[PR_CCS]);
++        env->pregs[PR_CCS] = evaluate_flags_writeback(env, flags,
++                                                      env->pregs[PR_CCS]);
+ }
+ 
+-void helper_top_evaluate_flags(void)
++void helper_top_evaluate_flags(CPUCRISState *env)
+ {
+ 	switch (env->cc_op)
+ 	{
+ 		case CC_OP_MCP:
+-			env->pregs[PR_CCS] = helper_evaluate_flags_mcp(
++                        env->pregs[PR_CCS] = helper_evaluate_flags_mcp(env,
+ 					env->pregs[PR_CCS], env->cc_src,
+ 					env->cc_dest, env->cc_result);
+ 			break;
+ 		case CC_OP_MULS:
+-			env->pregs[PR_CCS] = helper_evaluate_flags_muls(
++                        env->pregs[PR_CCS] = helper_evaluate_flags_muls(env,
+ 					env->pregs[PR_CCS], env->cc_result,
+ 					env->pregs[PR_MOF]);
+ 			break;
+ 		case CC_OP_MULU:
+-			env->pregs[PR_CCS] = helper_evaluate_flags_mulu(
++                        env->pregs[PR_CCS] = helper_evaluate_flags_mulu(env,
+ 					env->pregs[PR_CCS], env->cc_result,
+ 					env->pregs[PR_MOF]);
+ 			break;
+@@ -604,18 +610,18 @@ void helper_top_evaluate_flags(void)
+ 		{
+ 			case 4:
+ 				env->pregs[PR_CCS] =
+-					helper_evaluate_flags_move_4(
++                                        helper_evaluate_flags_move_4(env,
+ 							env->pregs[PR_CCS],
+ 							env->cc_result);
+ 				break;
+ 			case 2:
+ 				env->pregs[PR_CCS] =
+-					helper_evaluate_flags_move_2(
++                                        helper_evaluate_flags_move_2(env,
+ 							env->pregs[PR_CCS],
+ 							env->cc_result);
+ 				break;
+ 			default:
+-				helper_evaluate_flags();
++                                helper_evaluate_flags(env);
+ 				break;
+ 		}
+ 		break;
+@@ -626,12 +632,12 @@ void helper_top_evaluate_flags(void)
+ 		case CC_OP_CMP:
+ 			if (env->cc_size == 4)
+ 				env->pregs[PR_CCS] =
+-					helper_evaluate_flags_sub_4(
++                                        helper_evaluate_flags_sub_4(env,
+ 						env->pregs[PR_CCS],
+ 						env->cc_src, env->cc_dest,
+ 						env->cc_result);
+ 			else
+-				helper_evaluate_flags();
++                                helper_evaluate_flags(env);
+ 			break;
+ 		default:
+ 		{
+@@ -639,13 +645,13 @@ void helper_top_evaluate_flags(void)
+ 			{
+ 			case 4:
+ 				env->pregs[PR_CCS] =
+-					helper_evaluate_flags_alu_4(
++                                        helper_evaluate_flags_alu_4(env,
+ 						env->pregs[PR_CCS],
+ 						env->cc_src, env->cc_dest,
+ 						env->cc_result);
+ 				break;
+ 			default:
+-				helper_evaluate_flags();
++                                helper_evaluate_flags(env);
+ 				break;
+ 			}
+ 		}
+diff --git a/target-cris/translate.c b/target-cris/translate.c
+index ad31877..283dd98 100644
+--- a/target-cris/translate.c
++++ b/target-cris/translate.c
+@@ -211,9 +211,9 @@ static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
+ 		tcg_gen_andi_tl(cpu_PR[r], tn, 3);
+ 	else {
+ 		if (r == PR_PID) 
+-			gen_helper_tlb_flush_pid(tn);
++                        gen_helper_tlb_flush_pid(cpu_env, tn);
+ 		if (dc->tb_flags & S_FLAG && r == PR_SPC) 
+-			gen_helper_spc_write(tn);
++                        gen_helper_spc_write(cpu_env, tn);
+ 		else if (r == PR_CCS)
+ 			dc->cpustate_changed = 1;
+ 		tcg_gen_mov_tl(cpu_PR[r], tn);
+@@ -278,7 +278,7 @@ static void cris_lock_irq(DisasContext *dc)
+ static inline void t_gen_raise_exception(uint32_t index)
+ {
+         TCGv_i32 tmp = tcg_const_i32(index);
+-	gen_helper_raise_exception(tmp);
++        gen_helper_raise_exception(cpu_env, tmp);
+         tcg_temp_free_i32(tmp);
+ }
+ 
+@@ -624,17 +624,17 @@ static void cris_evaluate_flags(DisasContext *dc)
+ 	switch (dc->cc_op)
+ 	{
+ 	case CC_OP_MCP:
+-		gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS],
++                gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], cpu_env,
+ 					cpu_PR[PR_CCS], cc_src,
+ 					cc_dest, cc_result);
+ 		break;
+ 	case CC_OP_MULS:
+-		gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS],
++                gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], cpu_env,
+ 					cpu_PR[PR_CCS], cc_result,
+ 					cpu_PR[PR_MOF]);
+ 		break;
+ 	case CC_OP_MULU:
+-		gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS],
++                gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], cpu_env,
+ 					cpu_PR[PR_CCS], cc_result,
+ 					cpu_PR[PR_MOF]);
+ 		break;
+@@ -648,15 +648,15 @@ static void cris_evaluate_flags(DisasContext *dc)
+ 		switch (dc->cc_size)
+ 		{
+ 		case 4:
+-			gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
+-						cpu_PR[PR_CCS], cc_result);
++                        gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
++                                           cpu_env, cpu_PR[PR_CCS], cc_result);
+ 			break;
+ 		case 2:
+-			gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
+-						cpu_PR[PR_CCS], cc_result);
++                        gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
++                                           cpu_env, cpu_PR[PR_CCS], cc_result);
+ 			break;
+ 		default:
+-			gen_helper_evaluate_flags();
++                        gen_helper_evaluate_flags(cpu_env);
+ 			break;
+ 		}
+ 		break;
+@@ -666,21 +666,21 @@ static void cris_evaluate_flags(DisasContext *dc)
+ 	case CC_OP_SUB:
+ 	case CC_OP_CMP:
+ 		if (dc->cc_size == 4)
+-			gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS],
++                        gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], cpu_env,
+ 				cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
+ 		else
+-			gen_helper_evaluate_flags();
++                        gen_helper_evaluate_flags(cpu_env);
+ 
+ 		break;
+ 	default:
+ 		switch (dc->cc_size)
+ 		{
+ 			case 4:
+-			gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS],
++                        gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], cpu_env,
+ 				cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
+ 				break;
+ 			default:
+-				gen_helper_evaluate_flags();
++                                gen_helper_evaluate_flags(cpu_env);
+ 				break;
+ 		}
+ 		break;
+@@ -1475,7 +1475,7 @@ static int dec_btstq(DisasContext *dc)
+ 
+ 	cris_cc_mask(dc, CC_MASK_NZ);
+ 	cris_evaluate_flags(dc);
+-	gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
++        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
+ 			tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
+ 	cris_alu(dc, CC_OP_MOVE,
+ 		 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
+@@ -1925,7 +1925,7 @@ static int dec_btst_r(DisasContext *dc)
+ 		    dc->op1, dc->op2);
+ 	cris_cc_mask(dc, CC_MASK_NZ);
+ 	cris_evaluate_flags(dc);
+-	gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
++        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->op2],
+ 			cpu_R[dc->op1], cpu_PR[PR_CCS]);
+ 	cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
+ 		 cpu_R[dc->op2], cpu_R[dc->op2], 4);
+@@ -2135,14 +2135,16 @@ static int dec_move_rs(DisasContext *dc)
+ {
+ 	LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
+ 	cris_cc_mask(dc, 0);
+-	gen_helper_movl_sreg_reg(tcg_const_tl(dc->op2), tcg_const_tl(dc->op1));
++        gen_helper_movl_sreg_reg(cpu_env, tcg_const_tl(dc->op2),
++                                 tcg_const_tl(dc->op1));
+ 	return 2;
+ }
+ static int dec_move_sr(DisasContext *dc)
+ {
+ 	LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
+ 	cris_cc_mask(dc, 0);
+-	gen_helper_movl_reg_sreg(tcg_const_tl(dc->op1), tcg_const_tl(dc->op2));
++        gen_helper_movl_reg_sreg(cpu_env, tcg_const_tl(dc->op1),
++                                 tcg_const_tl(dc->op2));
+ 	return 2;
+ }
+ 
+@@ -2906,14 +2908,14 @@ static int dec_rfe_etc(DisasContext *dc)
+ 			/* rfe.  */
+ 			LOG_DIS("rfe\n");
+ 			cris_evaluate_flags(dc);
+-			gen_helper_rfe();
++                        gen_helper_rfe(cpu_env);
+ 			dc->is_jmp = DISAS_UPDATE;
+ 			break;
+ 		case 5:
+ 			/* rfn.  */
+ 			LOG_DIS("rfn\n");
+ 			cris_evaluate_flags(dc);
+-			gen_helper_rfn();
++                        gen_helper_rfn(cpu_env);
+ 			dc->is_jmp = DISAS_UPDATE;
+ 			break;
+ 		case 6:
+diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
+index 3629629..9a39c6a 100644
+--- a/target-cris/translate_v10.c
++++ b/target-cris/translate_v10.c
+@@ -289,7 +289,7 @@ static unsigned int dec10_quick_imm(DisasContext *dc)
+             } else {
+                 /* BTST */
+                 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
+-                gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
++                gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->dst],
+                            tcg_const_tl(imm), cpu_PR[PR_CCS]);
+             }
+             break;
+@@ -723,7 +723,7 @@ static unsigned int dec10_reg(DisasContext *dc)
+                 LOG_DIS("btst $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
+                 cris_cc_mask(dc, CC_MASK_NZVC);
+                 cris_update_cc_op(dc, CC_OP_FLAGS, 4);
+-                gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
++                gen_helper_btst(cpu_PR[PR_CCS], cpu_env, cpu_R[dc->dst],
+                            cpu_R[dc->src], cpu_PR[PR_CCS]);
+                 break;
+             case CRISV10_REG_DSTEP:
+-- 
+1.7.12.1
+
diff --git a/0036-target-cris-Switch-to-AREG0-free-mode.patch b/0036-target-cris-Switch-to-AREG0-free-mode.patch
new file mode 100644
index 0000000..1464e22
--- /dev/null
+++ b/0036-target-cris-Switch-to-AREG0-free-mode.patch
@@ -0,0 +1,1538 @@
+From 327937b3765d53776e42ffd3990e0b551c98b0e6 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 7 Sep 2012 16:13:27 +0200
+Subject: [PATCH] target-cris: Switch to AREG0 free mode
+
+Add an explicit CPUCRISState parameter instead of relying on AREG0, and
+use cpu_ld* in translation and interrupt handling. Remove AREG0 swapping
+in tlb_fill(). Switch to AREG0 free mode
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure                   |   2 +-
+ target-cris/Makefile.objs   |   2 -
+ target-cris/helper.c        |   4 +-
+ target-cris/op_helper.c     |   9 +-
+ target-cris/translate.c     | 256 ++++++++++++++++++++++----------------------
+ target-cris/translate_v10.c |  95 ++++++++--------
+ 6 files changed, 181 insertions(+), 187 deletions(-)
+
+diff --git a/configure b/configure
+index 0b4ef4a..2a12022 100755
+--- a/configure
++++ b/configure
+@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+ 
+ 
+ case "$target_arch2" in
+-  alpha | arm* | i386 | lm32 | m68k | microblaze* | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
++  alpha | arm* | cris | i386 | lm32 | m68k | microblaze* | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
+     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
+   ;;
+ esac
+diff --git a/target-cris/Makefile.objs b/target-cris/Makefile.objs
+index 4b09e8c..afb87bc 100644
+--- a/target-cris/Makefile.objs
++++ b/target-cris/Makefile.objs
+@@ -1,4 +1,2 @@
+ obj-y += translate.o op_helper.o helper.o cpu.o
+ obj-$(CONFIG_SOFTMMU) += mmu.o machine.o
+-
+-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-cris/helper.c b/target-cris/helper.c
+index bfbc29e..1bdb7e2 100644
+--- a/target-cris/helper.c
++++ b/target-cris/helper.c
+@@ -151,7 +151,7 @@ static void do_interruptv10(CPUCRISState *env)
+ 	}
+ 
+ 	/* Now that we are in kernel mode, load the handlers address.  */
+-	env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
++        env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4);
+ 	env->locked_irq = 1;
+ 	env->pregs[PR_CCS] |= F_FLAG_V10; /* set F.  */
+ 
+@@ -233,7 +233,7 @@ void do_interrupt(CPUCRISState *env)
+ 	/* Now that we are in kernel mode, load the handlers address.
+ 	   This load may not fault, real hw leaves that behaviour as
+ 	   undefined.  */
+-	env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
++        env->pc = cpu_ldl_code(env, env->pregs[PR_EBP] + ex_vec * 4);
+ 
+ 	/* Clear the excption_index to avoid spurios hw_aborts for recursive
+ 	   bus faults.  */
+diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
+index 5ca85a0..a7468d4 100644
+--- a/target-cris/op_helper.c
++++ b/target-cris/op_helper.c
+@@ -19,7 +19,6 @@
+  */
+ 
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "mmu.h"
+ #include "helper.h"
+ #include "host-utils.h"
+@@ -55,17 +54,12 @@
+ /* Try to fill the TLB and return an exception if error. If retaddr is
+    NULL, it means that the function was called in C code (i.e. not
+    from generated code or from helper.c) */
+-/* XXX: fix it to restore all registers */
+-void tlb_fill(CPUCRISState *env1, target_ulong addr, int is_write, int mmu_idx,
++void tlb_fill(CPUCRISState *env, target_ulong addr, int is_write, int mmu_idx,
+               uintptr_t retaddr)
+ {
+     TranslationBlock *tb;
+-    CPUCRISState *saved_env;
+     int ret;
+ 
+-    saved_env = env;
+-    env = env1;
+-
+     D_LOG("%s pc=%x tpc=%x ra=%p\n", __func__,
+           env->pc, env->debug1, (void *)retaddr);
+     ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx);
+@@ -84,7 +78,6 @@ void tlb_fill(CPUCRISState *env1, target_ulong addr, int is_write, int mmu_idx,
+         }
+         cpu_loop_exit(env);
+     }
+-    env = saved_env;
+ }
+ 
+ #endif
+diff --git a/target-cris/translate.c b/target-cris/translate.c
+index 283dd98..19144b5 100644
+--- a/target-cris/translate.c
++++ b/target-cris/translate.c
+@@ -78,7 +78,7 @@ typedef struct DisasContext {
+ 	target_ulong pc, ppc;
+ 
+ 	/* Decoder.  */
+-	unsigned int (*decoder)(struct DisasContext *dc);
++        unsigned int (*decoder)(CPUCRISState *env, struct DisasContext *dc);
+ 	uint32_t ir;
+ 	uint32_t opcode;
+ 	unsigned int op1;
+@@ -233,7 +233,7 @@ static int sign_extend(unsigned int val, unsigned int width)
+ 	return sval;
+ }
+ 
+-static int cris_fetch(DisasContext *dc, uint32_t addr,
++static int cris_fetch(CPUCRISState *env, DisasContext *dc, uint32_t addr,
+ 		      unsigned int size, unsigned int sign)
+ {
+ 	int r;
+@@ -241,24 +241,24 @@ static int cris_fetch(DisasContext *dc, uint32_t addr,
+ 	switch (size) {
+ 		case 4:
+ 		{
+-			r = ldl_code(addr);
++                        r = cpu_ldl_code(env, addr);
+ 			break;
+ 		}
+ 		case 2:
+ 		{
+ 			if (sign) {
+-				r = ldsw_code(addr);
++                                r = cpu_ldsw_code(env, addr);
+ 			} else {
+-				r = lduw_code(addr);
++                                r = cpu_lduw_code(env, addr);
+ 			}
+ 			break;
+ 		}
+ 		case 1:
+ 		{
+ 			if (sign) {
+-				r = ldsb_code(addr);
++                                r = cpu_ldsb_code(env, addr);
+ 			} else {
+-				r = ldub_code(addr);
++                                r = cpu_ldub_code(env, addr);
+ 			}
+ 			break;
+ 		}
+@@ -1304,8 +1304,8 @@ static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
+ 		t_gen_zext(dst, cpu_R[rd], size);
+ }
+ 
+-static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
+-			   TCGv dst)
++static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
++                           int s_ext, int memsize, TCGv dst)
+ {
+ 	unsigned int rs;
+ 	uint32_t imm;
+@@ -1321,7 +1321,7 @@ static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
+ 		if (memsize == 1)
+ 			insn_len++;
+ 
+-		imm = cris_fetch(dc, dc->pc + 2, memsize, s_ext);
++                imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
+ 		tcg_gen_movi_tl(dst, imm);
+ 		dc->postinc = 0;
+ 	} else {
+@@ -1338,12 +1338,12 @@ static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
+ /* Prepare T0 and T1 for a memory + alu operation.
+    s_ext decides if the operand1 should be sign-extended or zero-extended when
+    needed.  */
+-static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize,
+-			  TCGv dst, TCGv src)
++static int dec_prep_alu_m(CPUCRISState *env, DisasContext *dc,
++                          int s_ext, int memsize, TCGv dst, TCGv src)
+ {
+ 	int insn_len;
+ 
+-	insn_len = dec_prep_move_m(dc, s_ext, memsize, src);
++        insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
+ 	tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
+ 	return insn_len;
+ }
+@@ -1362,7 +1362,7 @@ static const char *cc_name(int cc)
+ 
+ /* Start of insn decoders.  */
+ 
+-static int dec_bccq(DisasContext *dc)
++static int dec_bccq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	int32_t offset;
+ 	int sign;
+@@ -1382,7 +1382,7 @@ static int dec_bccq(DisasContext *dc)
+ 	cris_prepare_cc_branch (dc, offset, cond);
+ 	return 2;
+ }
+-static int dec_addoq(DisasContext *dc)
++static int dec_addoq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	int32_t imm;
+ 
+@@ -1396,7 +1396,7 @@ static int dec_addoq(DisasContext *dc)
+ 
+ 	return 2;
+ }
+-static int dec_addq(DisasContext *dc)
++static int dec_addq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
+ 
+@@ -1408,7 +1408,7 @@ static int dec_addq(DisasContext *dc)
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
+ 	return 2;
+ }
+-static int dec_moveq(DisasContext *dc)
++static int dec_moveq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	uint32_t imm;
+ 
+@@ -1419,7 +1419,7 @@ static int dec_moveq(DisasContext *dc)
+ 	tcg_gen_movi_tl(cpu_R[dc->op2], imm);
+ 	return 2;
+ }
+-static int dec_subq(DisasContext *dc)
++static int dec_subq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
+ 
+@@ -1430,7 +1430,7 @@ static int dec_subq(DisasContext *dc)
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
+ 	return 2;
+ }
+-static int dec_cmpq(DisasContext *dc)
++static int dec_cmpq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	uint32_t imm;
+ 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
+@@ -1443,7 +1443,7 @@ static int dec_cmpq(DisasContext *dc)
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
+ 	return 2;
+ }
+-static int dec_andq(DisasContext *dc)
++static int dec_andq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	uint32_t imm;
+ 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
+@@ -1456,7 +1456,7 @@ static int dec_andq(DisasContext *dc)
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
+ 	return 2;
+ }
+-static int dec_orq(DisasContext *dc)
++static int dec_orq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	uint32_t imm;
+ 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
+@@ -1468,7 +1468,7 @@ static int dec_orq(DisasContext *dc)
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
+ 	return 2;
+ }
+-static int dec_btstq(DisasContext *dc)
++static int dec_btstq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
+ 	LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);
+@@ -1483,7 +1483,7 @@ static int dec_btstq(DisasContext *dc)
+ 	dc->flags_uptodate = 1;
+ 	return 2;
+ }
+-static int dec_asrq(DisasContext *dc)
++static int dec_asrq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
+ 	LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
+@@ -1495,7 +1495,7 @@ static int dec_asrq(DisasContext *dc)
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], 4);
+ 	return 2;
+ }
+-static int dec_lslq(DisasContext *dc)
++static int dec_lslq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
+ 	LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
+@@ -1509,7 +1509,7 @@ static int dec_lslq(DisasContext *dc)
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], 4);
+ 	return 2;
+ }
+-static int dec_lsrq(DisasContext *dc)
++static int dec_lsrq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
+ 	LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
+@@ -1523,7 +1523,7 @@ static int dec_lsrq(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_move_r(DisasContext *dc)
++static int dec_move_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	int size = memsize_zz(dc);
+ 
+@@ -1551,7 +1551,7 @@ static int dec_move_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_scc_r(DisasContext *dc)
++static int dec_scc_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	int cond = dc->op2;
+ 
+@@ -1594,7 +1594,7 @@ static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
+ 	}
+ }
+ 
+-static int dec_and_r(DisasContext *dc)
++static int dec_and_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1611,7 +1611,7 @@ static int dec_and_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_lz_r(DisasContext *dc)
++static int dec_lz_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	LOG_DIS("lz $r%u, $r%u\n",
+@@ -1624,7 +1624,7 @@ static int dec_lz_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_lsl_r(DisasContext *dc)
++static int dec_lsl_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1641,7 +1641,7 @@ static int dec_lsl_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_lsr_r(DisasContext *dc)
++static int dec_lsr_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1658,7 +1658,7 @@ static int dec_lsr_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_asr_r(DisasContext *dc)
++static int dec_asr_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1675,7 +1675,7 @@ static int dec_asr_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_muls_r(DisasContext *dc)
++static int dec_muls_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1691,7 +1691,7 @@ static int dec_muls_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_mulu_r(DisasContext *dc)
++static int dec_mulu_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1708,7 +1708,7 @@ static int dec_mulu_r(DisasContext *dc)
+ }
+ 
+ 
+-static int dec_dstep_r(DisasContext *dc)
++static int dec_dstep_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
+ 	cris_cc_mask(dc, CC_MASK_NZ);
+@@ -1717,7 +1717,7 @@ static int dec_dstep_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_xor_r(DisasContext *dc)
++static int dec_xor_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1733,7 +1733,7 @@ static int dec_xor_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_bound_r(DisasContext *dc)
++static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv l0;
+ 	int size = memsize_zz(dc);
+@@ -1747,7 +1747,7 @@ static int dec_bound_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_cmp_r(DisasContext *dc)
++static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1762,7 +1762,7 @@ static int dec_cmp_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_abs_r(DisasContext *dc)
++static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 
+@@ -1781,7 +1781,7 @@ static int dec_abs_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_add_r(DisasContext *dc)
++static int dec_add_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1796,7 +1796,7 @@ static int dec_add_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_addc_r(DisasContext *dc)
++static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("addc $r%u, $r%u\n",
+ 		    dc->op1, dc->op2);
+@@ -1811,7 +1811,7 @@ static int dec_addc_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_mcp_r(DisasContext *dc)
++static int dec_mcp_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("mcp $p%u, $r%u\n",
+ 		     dc->op2, dc->op1);
+@@ -1838,7 +1838,7 @@ static char * swapmode_name(int mode, char *modename) {
+ }
+ #endif
+ 
+-static int dec_swap_r(DisasContext *dc)
++static int dec_swap_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ #if DISAS_CRIS
+@@ -1864,7 +1864,7 @@ static int dec_swap_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_or_r(DisasContext *dc)
++static int dec_or_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1878,7 +1878,7 @@ static int dec_or_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_addi_r(DisasContext *dc)
++static int dec_addi_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	LOG_DIS("addi.%c $r%u, $r%u\n",
+@@ -1891,7 +1891,7 @@ static int dec_addi_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_addi_acr(DisasContext *dc)
++static int dec_addi_acr(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
+@@ -1904,7 +1904,7 @@ static int dec_addi_acr(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_neg_r(DisasContext *dc)
++static int dec_neg_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1919,7 +1919,7 @@ static int dec_neg_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_btst_r(DisasContext *dc)
++static int dec_btst_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("btst $r%u, $r%u\n",
+ 		    dc->op1, dc->op2);
+@@ -1934,7 +1934,7 @@ static int dec_btst_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_sub_r(DisasContext *dc)
++static int dec_sub_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int size = memsize_zz(dc);
+@@ -1949,7 +1949,7 @@ static int dec_sub_r(DisasContext *dc)
+ }
+ 
+ /* Zero extension. From size to dword.  */
+-static int dec_movu_r(DisasContext *dc)
++static int dec_movu_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	int size = memsize_z(dc);
+@@ -1966,7 +1966,7 @@ static int dec_movu_r(DisasContext *dc)
+ }
+ 
+ /* Sign extension. From size to dword.  */
+-static int dec_movs_r(DisasContext *dc)
++static int dec_movs_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	int size = memsize_z(dc);
+@@ -1985,7 +1985,7 @@ static int dec_movs_r(DisasContext *dc)
+ }
+ 
+ /* zero extension. From size to dword.  */
+-static int dec_addu_r(DisasContext *dc)
++static int dec_addu_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	int size = memsize_z(dc);
+@@ -2004,7 +2004,7 @@ static int dec_addu_r(DisasContext *dc)
+ }
+ 
+ /* Sign extension. From size to dword.  */
+-static int dec_adds_r(DisasContext *dc)
++static int dec_adds_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	int size = memsize_z(dc);
+@@ -2023,7 +2023,7 @@ static int dec_adds_r(DisasContext *dc)
+ }
+ 
+ /* Zero extension. From size to dword.  */
+-static int dec_subu_r(DisasContext *dc)
++static int dec_subu_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	int size = memsize_z(dc);
+@@ -2042,7 +2042,7 @@ static int dec_subu_r(DisasContext *dc)
+ }
+ 
+ /* Sign extension. From size to dword.  */
+-static int dec_subs_r(DisasContext *dc)
++static int dec_subs_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	int size = memsize_z(dc);
+@@ -2060,7 +2060,7 @@ static int dec_subs_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_setclrf(DisasContext *dc)
++static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
+ {
+ 	uint32_t flags;
+ 	int set = (~dc->opcode >> 2) & 1;
+@@ -2131,7 +2131,7 @@ static int dec_setclrf(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_move_rs(DisasContext *dc)
++static int dec_move_rs(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
+ 	cris_cc_mask(dc, 0);
+@@ -2139,7 +2139,7 @@ static int dec_move_rs(DisasContext *dc)
+                                  tcg_const_tl(dc->op1));
+ 	return 2;
+ }
+-static int dec_move_sr(DisasContext *dc)
++static int dec_move_sr(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
+ 	cris_cc_mask(dc, 0);
+@@ -2148,7 +2148,7 @@ static int dec_move_sr(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_move_rp(DisasContext *dc)
++static int dec_move_rp(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
+@@ -2178,7 +2178,7 @@ static int dec_move_rp(DisasContext *dc)
+ 	tcg_temp_free(t[0]);
+ 	return 2;
+ }
+-static int dec_move_pr(DisasContext *dc)
++static int dec_move_pr(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
+@@ -2200,7 +2200,7 @@ static int dec_move_pr(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_move_mr(DisasContext *dc)
++static int dec_move_mr(CPUCRISState *env, DisasContext *dc)
+ {
+ 	int memsize = memsize_zz(dc);
+ 	int insn_len;
+@@ -2210,7 +2210,7 @@ static int dec_move_mr(DisasContext *dc)
+ 		    dc->op2);
+ 
+ 	if (memsize == 4) {
+-		insn_len = dec_prep_move_m(dc, 0, 4, cpu_R[dc->op2]);
++                insn_len = dec_prep_move_m(env, dc, 0, 4, cpu_R[dc->op2]);
+ 		cris_cc_mask(dc, CC_MASK_NZ);
+ 		cris_update_cc_op(dc, CC_OP_MOVE, 4);
+ 		cris_update_cc_x(dc);
+@@ -2220,7 +2220,7 @@ static int dec_move_mr(DisasContext *dc)
+ 		TCGv t0;
+ 
+ 		t0 = tcg_temp_new();
+-		insn_len = dec_prep_move_m(dc, 0, memsize, t0);
++                insn_len = dec_prep_move_m(env, dc, 0, memsize, t0);
+ 		cris_cc_mask(dc, CC_MASK_NZ);
+ 		cris_alu(dc, CC_OP_MOVE,
+ 			    cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
+@@ -2242,7 +2242,7 @@ static inline void cris_alu_m_free_temps(TCGv *t)
+ 	tcg_temp_free(t[1]);
+ }
+ 
+-static int dec_movs_m(DisasContext *dc)
++static int dec_movs_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_z(dc);
+@@ -2254,7 +2254,7 @@ static int dec_movs_m(DisasContext *dc)
+ 
+ 	cris_alu_m_alloc_temps(t);
+ 	/* sign extend.  */
+-	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZ);
+ 	cris_alu(dc, CC_OP_MOVE,
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+@@ -2263,7 +2263,7 @@ static int dec_movs_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_addu_m(DisasContext *dc)
++static int dec_addu_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_z(dc);
+@@ -2275,7 +2275,7 @@ static int dec_addu_m(DisasContext *dc)
+ 
+ 	cris_alu_m_alloc_temps(t);
+ 	/* sign extend.  */
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZVC);
+ 	cris_alu(dc, CC_OP_ADD,
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+@@ -2284,7 +2284,7 @@ static int dec_addu_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_adds_m(DisasContext *dc)
++static int dec_adds_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_z(dc);
+@@ -2296,7 +2296,7 @@ static int dec_adds_m(DisasContext *dc)
+ 
+ 	cris_alu_m_alloc_temps(t);
+ 	/* sign extend.  */
+-	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZVC);
+ 	cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ 	do_postinc(dc, memsize);
+@@ -2304,7 +2304,7 @@ static int dec_adds_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_subu_m(DisasContext *dc)
++static int dec_subu_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_z(dc);
+@@ -2316,7 +2316,7 @@ static int dec_subu_m(DisasContext *dc)
+ 
+ 	cris_alu_m_alloc_temps(t);
+ 	/* sign extend.  */
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZVC);
+ 	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ 	do_postinc(dc, memsize);
+@@ -2324,7 +2324,7 @@ static int dec_subu_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_subs_m(DisasContext *dc)
++static int dec_subs_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_z(dc);
+@@ -2336,7 +2336,7 @@ static int dec_subs_m(DisasContext *dc)
+ 
+ 	cris_alu_m_alloc_temps(t);
+ 	/* sign extend.  */
+-	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZVC);
+ 	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ 	do_postinc(dc, memsize);
+@@ -2344,7 +2344,7 @@ static int dec_subs_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_movu_m(DisasContext *dc)
++static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_z(dc);
+@@ -2356,7 +2356,7 @@ static int dec_movu_m(DisasContext *dc)
+ 		    dc->op2);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZ);
+ 	cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ 	do_postinc(dc, memsize);
+@@ -2364,7 +2364,7 @@ static int dec_movu_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_cmpu_m(DisasContext *dc)
++static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_z(dc);
+@@ -2375,7 +2375,7 @@ static int dec_cmpu_m(DisasContext *dc)
+ 		    dc->op2);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZVC);
+ 	cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
+ 	do_postinc(dc, memsize);
+@@ -2383,7 +2383,7 @@ static int dec_cmpu_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_cmps_m(DisasContext *dc)
++static int dec_cmps_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_z(dc);
+@@ -2394,7 +2394,7 @@ static int dec_cmps_m(DisasContext *dc)
+ 		    dc->op2);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZVC);
+ 	cris_alu(dc, CC_OP_CMP,
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
+@@ -2404,7 +2404,7 @@ static int dec_cmps_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_cmp_m(DisasContext *dc)
++static int dec_cmp_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_zz(dc);
+@@ -2415,7 +2415,7 @@ static int dec_cmp_m(DisasContext *dc)
+ 		    dc->op2);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZVC);
+ 	cris_alu(dc, CC_OP_CMP,
+ 		    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
+@@ -2425,7 +2425,7 @@ static int dec_cmp_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_test_m(DisasContext *dc)
++static int dec_test_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_zz(dc);
+@@ -2438,7 +2438,7 @@ static int dec_test_m(DisasContext *dc)
+ 	cris_evaluate_flags(dc);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZ);
+ 	tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
+ 
+@@ -2449,7 +2449,7 @@ static int dec_test_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_and_m(DisasContext *dc)
++static int dec_and_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_zz(dc);
+@@ -2460,7 +2460,7 @@ static int dec_and_m(DisasContext *dc)
+ 		    dc->op2);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZ);
+ 	cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
+ 	do_postinc(dc, memsize);
+@@ -2468,7 +2468,7 @@ static int dec_and_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_add_m(DisasContext *dc)
++static int dec_add_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_zz(dc);
+@@ -2479,7 +2479,7 @@ static int dec_add_m(DisasContext *dc)
+ 		    dc->op2);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZVC);
+ 	cris_alu(dc, CC_OP_ADD,
+ 		 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
+@@ -2488,7 +2488,7 @@ static int dec_add_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_addo_m(DisasContext *dc)
++static int dec_addo_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_zz(dc);
+@@ -2499,7 +2499,7 @@ static int dec_addo_m(DisasContext *dc)
+ 		    dc->op2);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 1, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, 0);
+ 	cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
+ 	do_postinc(dc, memsize);
+@@ -2507,7 +2507,7 @@ static int dec_addo_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_bound_m(DisasContext *dc)
++static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv l[2];
+ 	int memsize = memsize_zz(dc);
+@@ -2519,7 +2519,7 @@ static int dec_bound_m(DisasContext *dc)
+ 
+ 	l[0] = tcg_temp_local_new();
+ 	l[1] = tcg_temp_local_new();
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, l[0], l[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, l[0], l[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZ);
+ 	cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
+ 	do_postinc(dc, memsize);
+@@ -2528,7 +2528,7 @@ static int dec_bound_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_addc_mr(DisasContext *dc)
++static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int insn_len = 2;
+@@ -2543,7 +2543,7 @@ static int dec_addc_mr(DisasContext *dc)
+ 	dc->flags_x = X_FLAG;
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, 4, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZVC);
+ 	cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
+ 	do_postinc(dc, 4);
+@@ -2551,7 +2551,7 @@ static int dec_addc_mr(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_sub_m(DisasContext *dc)
++static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_zz(dc);
+@@ -2562,7 +2562,7 @@ static int dec_sub_m(DisasContext *dc)
+ 		    dc->op2, dc->ir, dc->zzsize);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZVC);
+ 	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
+ 	do_postinc(dc, memsize);
+@@ -2570,7 +2570,7 @@ static int dec_sub_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_or_m(DisasContext *dc)
++static int dec_or_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_zz(dc);
+@@ -2581,7 +2581,7 @@ static int dec_or_m(DisasContext *dc)
+ 		    dc->op2, dc->pc);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, CC_MASK_NZ);
+ 	cris_alu(dc, CC_OP_OR,
+ 		    cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
+@@ -2590,7 +2590,7 @@ static int dec_or_m(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_move_mp(DisasContext *dc)
++static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t[2];
+ 	int memsize = memsize_zz(dc);
+@@ -2603,7 +2603,7 @@ static int dec_move_mp(DisasContext *dc)
+ 		    dc->op2);
+ 
+ 	cris_alu_m_alloc_temps(t);
+-	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
++        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
+ 	cris_cc_mask(dc, 0);
+ 	if (dc->op2 == PR_CCS) {
+ 		cris_evaluate_flags(dc);
+@@ -2622,7 +2622,7 @@ static int dec_move_mp(DisasContext *dc)
+ 	return insn_len;
+ }
+ 
+-static int dec_move_pm(DisasContext *dc)
++static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv t0;
+ 	int memsize;
+@@ -2648,7 +2648,7 @@ static int dec_move_pm(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_movem_mr(DisasContext *dc)
++static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv_i64 tmp[16];
+         TCGv tmp32;
+@@ -2695,7 +2695,7 @@ static int dec_movem_mr(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_movem_rm(DisasContext *dc)
++static int dec_movem_rm(CPUCRISState *env, DisasContext *dc)
+ {
+ 	TCGv tmp;
+ 	TCGv addr;
+@@ -2724,7 +2724,7 @@ static int dec_movem_rm(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_move_rm(DisasContext *dc)
++static int dec_move_rm(CPUCRISState *env, DisasContext *dc)
+ {
+ 	int memsize;
+ 
+@@ -2743,7 +2743,7 @@ static int dec_move_rm(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_lapcq(DisasContext *dc)
++static int dec_lapcq(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("lapcq %x, $r%u\n",
+ 		    dc->pc + dc->op1*2, dc->op2);
+@@ -2752,7 +2752,7 @@ static int dec_lapcq(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_lapc_im(DisasContext *dc)
++static int dec_lapc_im(CPUCRISState *env, DisasContext *dc)
+ {
+ 	unsigned int rd;
+ 	int32_t imm;
+@@ -2761,7 +2761,7 @@ static int dec_lapc_im(DisasContext *dc)
+ 	rd = dc->op2;
+ 
+ 	cris_cc_mask(dc, 0);
+-	imm = cris_fetch(dc, dc->pc + 2, 4, 0);
++        imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
+ 	LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
+ 
+ 	pc = dc->pc;
+@@ -2771,7 +2771,7 @@ static int dec_lapc_im(DisasContext *dc)
+ }
+ 
+ /* Jump to special reg.  */
+-static int dec_jump_p(DisasContext *dc)
++static int dec_jump_p(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("jump $p%u\n", dc->op2);
+ 
+@@ -2786,7 +2786,7 @@ static int dec_jump_p(DisasContext *dc)
+ }
+ 
+ /* Jump and save.  */
+-static int dec_jas_r(DisasContext *dc)
++static int dec_jas_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
+ 	cris_cc_mask(dc, 0);
+@@ -2800,11 +2800,11 @@ static int dec_jas_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_jas_im(DisasContext *dc)
++static int dec_jas_im(CPUCRISState *env, DisasContext *dc)
+ {
+ 	uint32_t imm;
+ 
+-	imm = cris_fetch(dc, dc->pc + 2, 4, 0);
++        imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
+ 
+ 	LOG_DIS("jas 0x%x\n", imm);
+ 	cris_cc_mask(dc, 0);
+@@ -2816,11 +2816,11 @@ static int dec_jas_im(DisasContext *dc)
+ 	return 6;
+ }
+ 
+-static int dec_jasc_im(DisasContext *dc)
++static int dec_jasc_im(CPUCRISState *env, DisasContext *dc)
+ {
+ 	uint32_t imm;
+ 
+-	imm = cris_fetch(dc, dc->pc + 2, 4, 0);
++        imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
+ 
+ 	LOG_DIS("jasc 0x%x\n", imm);
+ 	cris_cc_mask(dc, 0);
+@@ -2832,7 +2832,7 @@ static int dec_jasc_im(DisasContext *dc)
+ 	return 6;
+ }
+ 
+-static int dec_jasc_r(DisasContext *dc)
++static int dec_jasc_r(CPUCRISState *env, DisasContext *dc)
+ {
+ 	LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
+ 	cris_cc_mask(dc, 0);
+@@ -2843,12 +2843,12 @@ static int dec_jasc_r(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_bcc_im(DisasContext *dc)
++static int dec_bcc_im(CPUCRISState *env, DisasContext *dc)
+ {
+ 	int32_t offset;
+ 	uint32_t cond = dc->op2;
+ 
+-	offset = cris_fetch(dc, dc->pc + 2, 2, 1);
++        offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
+ 
+ 	LOG_DIS("b%s %d pc=%x dst=%x\n",
+ 		    cc_name(cond), offset,
+@@ -2860,12 +2860,12 @@ static int dec_bcc_im(DisasContext *dc)
+ 	return 4;
+ }
+ 
+-static int dec_bas_im(DisasContext *dc)
++static int dec_bas_im(CPUCRISState *env, DisasContext *dc)
+ {
+ 	int32_t simm;
+ 
+ 
+-	simm = cris_fetch(dc, dc->pc + 2, 4, 0);
++        simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
+ 
+ 	LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
+ 	cris_cc_mask(dc, 0);
+@@ -2877,10 +2877,10 @@ static int dec_bas_im(DisasContext *dc)
+ 	return 6;
+ }
+ 
+-static int dec_basc_im(DisasContext *dc)
++static int dec_basc_im(CPUCRISState *env, DisasContext *dc)
+ {
+ 	int32_t simm;
+-	simm = cris_fetch(dc, dc->pc + 2, 4, 0);
++        simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
+ 
+ 	LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
+ 	cris_cc_mask(dc, 0);
+@@ -2892,7 +2892,7 @@ static int dec_basc_im(DisasContext *dc)
+ 	return 6;
+ }
+ 
+-static int dec_rfe_etc(DisasContext *dc)
++static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
+ {
+ 	cris_cc_mask(dc, 0);
+ 
+@@ -2939,17 +2939,17 @@ static int dec_rfe_etc(DisasContext *dc)
+ 	return 2;
+ }
+ 
+-static int dec_ftag_fidx_d_m(DisasContext *dc)
++static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	return 2;
+ }
+ 
+-static int dec_ftag_fidx_i_m(DisasContext *dc)
++static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc)
+ {
+ 	return 2;
+ }
+ 
+-static int dec_null(DisasContext *dc)
++static int dec_null(CPUCRISState *env, DisasContext *dc)
+ {
+ 	printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
+ 		dc->pc, dc->opcode, dc->op1, dc->op2);
+@@ -2963,7 +2963,7 @@ static struct decoder_info {
+ 		uint32_t bits;
+ 		uint32_t mask;
+ 	};
+-	int (*dec)(DisasContext *dc);
++        int (*dec)(CPUCRISState *env, DisasContext *dc);
+ } decinfo[] = {
+ 	/* Order matters here.  */
+ 	{DEC_MOVEQ, dec_moveq},
+@@ -3069,7 +3069,7 @@ static struct decoder_info {
+ 	{{0, 0}, dec_null}
+ };
+ 
+-static unsigned int crisv32_decoder(DisasContext *dc)
++static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
+ {
+ 	int insn_len = 2;
+ 	int i;
+@@ -3078,7 +3078,7 @@ static unsigned int crisv32_decoder(DisasContext *dc)
+ 		tcg_gen_debug_insn_start(dc->pc);
+ 
+ 	/* Load a halfword onto the instruction register.  */
+-	dc->ir = cris_fetch(dc, dc->pc, 2, 0);
++        dc->ir = cris_fetch(env, dc, dc->pc, 2, 0);
+ 
+ 	/* Now decode it.  */
+ 	dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
+@@ -3092,7 +3092,7 @@ static unsigned int crisv32_decoder(DisasContext *dc)
+ 	for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
+ 		if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
+ 		{
+-			insn_len = decinfo[i].dec(dc);
++                        insn_len = decinfo[i].dec(env, dc);
+ 			break;
+ 		}
+ 	}
+@@ -3286,7 +3286,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
+                     gen_io_start();
+ 		dc->clear_x = 1;
+ 
+-		insn_len = dc->decoder(dc);
++                insn_len = dc->decoder(env, dc);
+ 		dc->ppc = dc->pc;
+ 		dc->pc += insn_len;
+ 		if (dc->clear_x)
+diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
+index 9a39c6a..d2cca89 100644
+--- a/target-cris/translate_v10.c
++++ b/target-cris/translate_v10.c
+@@ -164,8 +164,8 @@ static unsigned int crisv10_post_memaddr(DisasContext *dc, unsigned int size)
+     return insn_len;
+ }
+ 
+-static int dec10_prep_move_m(DisasContext *dc, int s_ext, int memsize,
+-                           TCGv dst)
++static int dec10_prep_move_m(CPUCRISState *env, DisasContext *dc,
++                             int s_ext, int memsize, TCGv dst)
+ {
+     unsigned int rs;
+     uint32_t imm;
+@@ -182,17 +182,17 @@ static int dec10_prep_move_m(DisasContext *dc, int s_ext, int memsize,
+         if (memsize != 4) {
+             if (s_ext) {
+                 if (memsize == 1)
+-                    imm = ldsb_code(dc->pc + 2);
++                    imm = cpu_ldsb_code(env, dc->pc + 2);
+                 else
+-                    imm = ldsw_code(dc->pc + 2);
++                    imm = cpu_ldsw_code(env, dc->pc + 2);
+             } else {
+                 if (memsize == 1)
+-                    imm = ldub_code(dc->pc + 2);
++                    imm = cpu_ldub_code(env, dc->pc + 2);
+                 else
+-                    imm = lduw_code(dc->pc + 2);
++                    imm = cpu_lduw_code(env, dc->pc + 2);
+             }
+         } else
+-            imm = ldl_code(dc->pc + 2);
++            imm = cpu_ldl_code(env, dc->pc + 2);
+ 
+         tcg_gen_movi_tl(dst, imm);
+ 
+@@ -752,7 +752,8 @@ static unsigned int dec10_reg(DisasContext *dc)
+     return insn_len;
+ }
+ 
+-static unsigned int dec10_ind_move_m_r(DisasContext *dc, unsigned int size)
++static unsigned int dec10_ind_move_m_r(CPUCRISState *env, DisasContext *dc,
++                                       unsigned int size)
+ {
+     unsigned int insn_len = 2;
+     TCGv t;
+@@ -762,7 +763,7 @@ static unsigned int dec10_ind_move_m_r(DisasContext *dc, unsigned int size)
+ 
+     cris_cc_mask(dc, CC_MASK_NZVC);
+     t = tcg_temp_new();
+-    insn_len += dec10_prep_move_m(dc, 0, size, t);
++    insn_len += dec10_prep_move_m(env, dc, 0, size, t);
+     cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, size);
+     if (dc->dst == 15) {
+         tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
+@@ -789,7 +790,7 @@ static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size)
+     return insn_len;
+ }
+ 
+-static unsigned int dec10_ind_move_m_pr(DisasContext *dc)
++static unsigned int dec10_ind_move_m_pr(CPUCRISState *env, DisasContext *dc)
+ {
+     unsigned int insn_len = 2, rd = dc->dst;
+     TCGv t, addr;
+@@ -799,7 +800,7 @@ static unsigned int dec10_ind_move_m_pr(DisasContext *dc)
+ 
+     addr = tcg_temp_new();
+     t = tcg_temp_new();
+-    insn_len += dec10_prep_move_m(dc, 0, 4, t);
++    insn_len += dec10_prep_move_m(env, dc, 0, 4, t);
+     if (rd == 15) {
+         tcg_gen_mov_tl(env_btarget, t);
+         cris_prepare_jmp(dc, JMP_INDIRECT);
+@@ -899,14 +900,15 @@ static void dec10_movem_m_r(DisasContext *dc)
+     tcg_temp_free(t0);
+ }
+ 
+-static int dec10_ind_alu(DisasContext *dc, int op, unsigned int size)
++static int dec10_ind_alu(CPUCRISState *env, DisasContext *dc,
++                         int op, unsigned int size)
+ {
+     int insn_len = 0;
+     int rd = dc->dst;
+     TCGv t[2];
+ 
+     cris_alu_m_alloc_temps(t);
+-    insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
++    insn_len += dec10_prep_move_m(env, dc, 0, size, t[0]);
+     cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t[0], size);
+     if (dc->dst == 15) {
+         tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
+@@ -920,14 +922,15 @@ static int dec10_ind_alu(DisasContext *dc, int op, unsigned int size)
+     return insn_len;
+ }
+ 
+-static int dec10_ind_bound(DisasContext *dc, unsigned int size)
++static int dec10_ind_bound(CPUCRISState *env, DisasContext *dc,
++                           unsigned int size)
+ {
+     int insn_len = 0;
+     int rd = dc->dst;
+     TCGv t;
+ 
+     t = tcg_temp_local_new();
+-    insn_len += dec10_prep_move_m(dc, 0, size, t);
++    insn_len += dec10_prep_move_m(env, dc, 0, size, t);
+     cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4);
+     if (dc->dst == 15) {
+         tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
+@@ -940,7 +943,7 @@ static int dec10_ind_bound(DisasContext *dc, unsigned int size)
+     return insn_len;
+ }
+ 
+-static int dec10_alux_m(DisasContext *dc, int op)
++static int dec10_alux_m(CPUCRISState *env, DisasContext *dc, int op)
+ {
+     unsigned int size = (dc->size & 1) ? 2 : 1;
+     unsigned int sx = !!(dc->size & 2);
+@@ -953,7 +956,7 @@ static int dec10_alux_m(DisasContext *dc, int op)
+     t = tcg_temp_new();
+ 
+     cris_cc_mask(dc, CC_MASK_NZVC);
+-    insn_len += dec10_prep_move_m(dc, sx, size, t);
++    insn_len += dec10_prep_move_m(env, dc, sx, size, t);
+     cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t, 4);
+     if (dc->dst == 15) {
+         tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
+@@ -966,7 +969,7 @@ static int dec10_alux_m(DisasContext *dc, int op)
+     return insn_len;
+ }
+ 
+-static int dec10_dip(DisasContext *dc)
++static int dec10_dip(CPUCRISState *env, DisasContext *dc)
+ {
+     int insn_len = 2;
+     uint32_t imm;
+@@ -974,7 +977,7 @@ static int dec10_dip(DisasContext *dc)
+     LOG_DIS("dip pc=%x opcode=%d r%d r%d\n",
+               dc->pc, dc->opcode, dc->src, dc->dst);
+     if (dc->src == 15) {
+-        imm = ldl_code(dc->pc + 2);
++        imm = cpu_ldl_code(env, dc->pc + 2);
+         tcg_gen_movi_tl(cpu_PR[PR_PREFIX], imm);
+         if (dc->postinc)
+             insn_len += 4;
+@@ -989,7 +992,7 @@ static int dec10_dip(DisasContext *dc)
+     return insn_len;
+ }
+ 
+-static int dec10_bdap_m(DisasContext *dc, int size)
++static int dec10_bdap_m(CPUCRISState *env, DisasContext *dc, int size)
+ {
+     int insn_len = 2;
+     int rd = dc->dst;
+@@ -1014,13 +1017,13 @@ static int dec10_bdap_m(DisasContext *dc, int size)
+     }
+ #endif
+     /* Now the rest of the modes are truly indirect.  */
+-    insn_len += dec10_prep_move_m(dc, 1, size, cpu_PR[PR_PREFIX]);
++    insn_len += dec10_prep_move_m(env, dc, 1, size, cpu_PR[PR_PREFIX]);
+     tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_PR[PR_PREFIX], cpu_R[rd]);
+     cris_set_prefix(dc);
+     return insn_len;
+ }
+ 
+-static unsigned int dec10_ind(DisasContext *dc)
++static unsigned int dec10_ind(CPUCRISState *env, DisasContext *dc)
+ {
+     unsigned int insn_len = 2;
+     unsigned int size = dec10_size(dc->size);
+@@ -1031,7 +1034,7 @@ static unsigned int dec10_ind(DisasContext *dc)
+     if (dc->size != 3) {
+         switch (dc->opcode) {
+             case CRISV10_IND_MOVE_M_R:
+-                return dec10_ind_move_m_r(dc, size);
++                return dec10_ind_move_m_r(env, dc, size);
+                 break;
+             case CRISV10_IND_MOVE_R_M:
+                 return dec10_ind_move_r_m(dc, size);
+@@ -1039,7 +1042,7 @@ static unsigned int dec10_ind(DisasContext *dc)
+             case CRISV10_IND_CMP:
+                 LOG_DIS("cmp size=%d op=%d %d\n",  size, dc->src, dc->dst);
+                 cris_cc_mask(dc, CC_MASK_NZVC);
+-                insn_len += dec10_ind_alu(dc, CC_OP_CMP, size);
++                insn_len += dec10_ind_alu(env, dc, CC_OP_CMP, size);
+                 break;
+             case CRISV10_IND_TEST:
+                 LOG_DIS("test size=%d op=%d %d\n",  size, dc->src, dc->dst);
+@@ -1047,7 +1050,7 @@ static unsigned int dec10_ind(DisasContext *dc)
+                 cris_evaluate_flags(dc);
+                 cris_cc_mask(dc, CC_MASK_NZVC);
+                 cris_alu_m_alloc_temps(t);
+-                insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
++                insn_len += dec10_prep_move_m(env, dc, 0, size, t[0]);
+                 tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
+                 cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
+                          t[0], tcg_const_tl(0), size);
+@@ -1056,39 +1059,39 @@ static unsigned int dec10_ind(DisasContext *dc)
+             case CRISV10_IND_ADD:
+                 LOG_DIS("add size=%d op=%d %d\n",  size, dc->src, dc->dst);
+                 cris_cc_mask(dc, CC_MASK_NZVC);
+-                insn_len += dec10_ind_alu(dc, CC_OP_ADD, size);
++                insn_len += dec10_ind_alu(env, dc, CC_OP_ADD, size);
+                 break;
+             case CRISV10_IND_SUB:
+                 LOG_DIS("sub size=%d op=%d %d\n",  size, dc->src, dc->dst);
+                 cris_cc_mask(dc, CC_MASK_NZVC);
+-                insn_len += dec10_ind_alu(dc, CC_OP_SUB, size);
++                insn_len += dec10_ind_alu(env, dc, CC_OP_SUB, size);
+                 break;
+             case CRISV10_IND_BOUND:
+                 LOG_DIS("bound size=%d op=%d %d\n",  size, dc->src, dc->dst);
+                 cris_cc_mask(dc, CC_MASK_NZVC);
+-                insn_len += dec10_ind_bound(dc, size);
++                insn_len += dec10_ind_bound(env, dc, size);
+                 break;
+             case CRISV10_IND_AND:
+                 LOG_DIS("and size=%d op=%d %d\n",  size, dc->src, dc->dst);
+                 cris_cc_mask(dc, CC_MASK_NZVC);
+-                insn_len += dec10_ind_alu(dc, CC_OP_AND, size);
++                insn_len += dec10_ind_alu(env, dc, CC_OP_AND, size);
+                 break;
+             case CRISV10_IND_OR:
+                 LOG_DIS("or size=%d op=%d %d\n",  size, dc->src, dc->dst);
+                 cris_cc_mask(dc, CC_MASK_NZVC);
+-                insn_len += dec10_ind_alu(dc, CC_OP_OR, size);
++                insn_len += dec10_ind_alu(env, dc, CC_OP_OR, size);
+                 break;
+             case CRISV10_IND_MOVX:
+-                insn_len = dec10_alux_m(dc, CC_OP_MOVE);
++                insn_len = dec10_alux_m(env, dc, CC_OP_MOVE);
+                 break;
+             case CRISV10_IND_ADDX:
+-                insn_len = dec10_alux_m(dc, CC_OP_ADD);
++                insn_len = dec10_alux_m(env, dc, CC_OP_ADD);
+                 break;
+             case CRISV10_IND_SUBX:
+-                insn_len = dec10_alux_m(dc, CC_OP_SUB);
++                insn_len = dec10_alux_m(env, dc, CC_OP_SUB);
+                 break;
+             case CRISV10_IND_CMPX:
+-                insn_len = dec10_alux_m(dc, CC_OP_CMP);
++                insn_len = dec10_alux_m(env, dc, CC_OP_CMP);
+                 break;
+             case CRISV10_IND_MUL:
+                 /* This is a reg insn coded in the mem indir space.  */
+@@ -1097,7 +1100,7 @@ static unsigned int dec10_ind(DisasContext *dc)
+                 dec10_reg_mul(dc, size, dc->ir & (1 << 10));
+                 break;
+             case CRISV10_IND_BDAP_M:
+-                insn_len = dec10_bdap_m(dc, size);
++                insn_len = dec10_bdap_m(env, dc, size);
+                 break;
+             default:
+                 LOG_DIS("pc=%x var-ind.%d %d r%d r%d\n",
+@@ -1110,7 +1113,7 @@ static unsigned int dec10_ind(DisasContext *dc)
+ 
+     switch (dc->opcode) {
+         case CRISV10_IND_MOVE_M_SPR:
+-            insn_len = dec10_ind_move_m_pr(dc);
++            insn_len = dec10_ind_move_m_pr(env, dc);
+             break;
+         case CRISV10_IND_MOVE_SPR_M:
+             insn_len = dec10_ind_move_pr_m(dc);
+@@ -1119,7 +1122,7 @@ static unsigned int dec10_ind(DisasContext *dc)
+             if (dc->src == 15) {
+                 LOG_DIS("jump.%d %d r%d r%d direct\n", size,
+                          dc->opcode, dc->src, dc->dst);
+-                imm = ldl_code(dc->pc + 2);
++                imm = cpu_ldl_code(env, dc->pc + 2);
+                 if (dc->mode == CRISV10_MODE_AUTOINC)
+                     insn_len += size;
+ 
+@@ -1168,24 +1171,24 @@ static unsigned int dec10_ind(DisasContext *dc)
+             dc->delayed_branch--; /* v10 has no dslot here.  */
+             break;
+         case CRISV10_IND_MOVX:
+-            insn_len = dec10_alux_m(dc, CC_OP_MOVE);
++            insn_len = dec10_alux_m(env, dc, CC_OP_MOVE);
+             break;
+         case CRISV10_IND_ADDX:
+-            insn_len = dec10_alux_m(dc, CC_OP_ADD);
++            insn_len = dec10_alux_m(env, dc, CC_OP_ADD);
+             break;
+         case CRISV10_IND_SUBX:
+-            insn_len = dec10_alux_m(dc, CC_OP_SUB);
++            insn_len = dec10_alux_m(env, dc, CC_OP_SUB);
+             break;
+         case CRISV10_IND_CMPX:
+-            insn_len = dec10_alux_m(dc, CC_OP_CMP);
++            insn_len = dec10_alux_m(env, dc, CC_OP_CMP);
+             break;
+         case CRISV10_IND_DIP:
+-            insn_len = dec10_dip(dc);
++            insn_len = dec10_dip(env, dc);
+             break;
+         case CRISV10_IND_BCC_M:
+ 
+             cris_cc_mask(dc, 0);
+-            imm = ldsw_code(dc->pc + 2);
++            imm = cpu_ldsw_code(env, dc->pc + 2);
+             simm = (int16_t)imm;
+             simm += 4;
+ 
+@@ -1202,7 +1205,7 @@ static unsigned int dec10_ind(DisasContext *dc)
+     return insn_len;
+ }
+ 
+-static unsigned int crisv10_decoder(DisasContext *dc)
++static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc)
+ {
+     unsigned int insn_len = 2;
+ 
+@@ -1210,7 +1213,7 @@ static unsigned int crisv10_decoder(DisasContext *dc)
+         tcg_gen_debug_insn_start(dc->pc);
+ 
+     /* Load a halfword onto the instruction register.  */
+-    dc->ir = lduw_code(dc->pc);
++    dc->ir = cpu_lduw_code(env, dc->pc);
+ 
+     /* Now decode it.  */
+     dc->opcode   = EXTRACT_FIELD(dc->ir, 6, 9);
+@@ -1235,7 +1238,7 @@ static unsigned int crisv10_decoder(DisasContext *dc)
+             break;
+         case CRISV10_MODE_AUTOINC:
+         case CRISV10_MODE_INDIRECT:
+-            insn_len = dec10_ind(dc);
++            insn_len = dec10_ind(env, dc);
+             break;
+     }
+ 
+-- 
+1.7.12.1
+
diff --git a/0037-target-sh4-switch-to-AREG0-free-mode.patch b/0037-target-sh4-switch-to-AREG0-free-mode.patch
new file mode 100644
index 0000000..dbbffb0
--- /dev/null
+++ b/0037-target-sh4-switch-to-AREG0-free-mode.patch
@@ -0,0 +1,1060 @@
+From 22bb4c416286bbfc340f65e5c7f286d96a731cc7 Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 10:37:06 +0000
+Subject: [PATCH] target-sh4: switch to AREG0 free mode
+
+Add an explicit CPUState parameter instead of relying on AREG0
+and switch to AREG0 free mode.
+
+Acked-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure                |   2 +-
+ target-sh4/Makefile.objs |   2 -
+ target-sh4/helper.h      |  84 +++++++++++-----------
+ target-sh4/op_helper.c   | 182 +++++++++++++++++++++++------------------------
+ target-sh4/translate.c   | 114 ++++++++++++++++-------------
+ 5 files changed, 195 insertions(+), 189 deletions(-)
+
+diff --git a/configure b/configure
+index 2a12022..03ce76e 100755
+--- a/configure
++++ b/configure
+@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+ 
+ 
+ case "$target_arch2" in
+-  alpha | arm* | cris | i386 | lm32 | m68k | microblaze* | or32 | s390x | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
++  alpha | arm* | cris | i386 | lm32 | m68k | microblaze* | or32 | s390x | sh4* | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
+     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
+   ;;
+ esac
+diff --git a/target-sh4/Makefile.objs b/target-sh4/Makefile.objs
+index 2e0e093..ca20f21 100644
+--- a/target-sh4/Makefile.objs
++++ b/target-sh4/Makefile.objs
+@@ -1,4 +1,2 @@
+ obj-y += translate.o op_helper.o helper.o cpu.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+-
+-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-sh4/helper.h b/target-sh4/helper.h
+index 95e3c7c..6e4f108 100644
+--- a/target-sh4/helper.h
++++ b/target-sh4/helper.h
+@@ -1,54 +1,54 @@
+ #include "def-helper.h"
+ 
+-DEF_HELPER_0(ldtlb, void)
+-DEF_HELPER_0(raise_illegal_instruction, void)
+-DEF_HELPER_0(raise_slot_illegal_instruction, void)
+-DEF_HELPER_0(raise_fpu_disable, void)
+-DEF_HELPER_0(raise_slot_fpu_disable, void)
+-DEF_HELPER_0(debug, void)
+-DEF_HELPER_1(sleep, void, i32)
+-DEF_HELPER_1(trapa, void, i32)
++DEF_HELPER_1(ldtlb, void, env)
++DEF_HELPER_1(raise_illegal_instruction, void, env)
++DEF_HELPER_1(raise_slot_illegal_instruction, void, env)
++DEF_HELPER_1(raise_fpu_disable, void, env)
++DEF_HELPER_1(raise_slot_fpu_disable, void, env)
++DEF_HELPER_1(debug, void, env)
++DEF_HELPER_2(sleep, void, env, i32)
++DEF_HELPER_2(trapa, void, env, i32)
+ 
+-DEF_HELPER_2(movcal, void, i32, i32)
+-DEF_HELPER_0(discard_movcal_backup, void)
+-DEF_HELPER_1(ocbi, void, i32)
++DEF_HELPER_3(movcal, void, env, i32, i32)
++DEF_HELPER_1(discard_movcal_backup, void, env)
++DEF_HELPER_2(ocbi, void, env, i32)
+ 
+-DEF_HELPER_2(addv, i32, i32, i32)
+-DEF_HELPER_2(addc, i32, i32, i32)
+-DEF_HELPER_2(subv, i32, i32, i32)
+-DEF_HELPER_2(subc, i32, i32, i32)
+-DEF_HELPER_2(div1, i32, i32, i32)
+-DEF_HELPER_2(macl, void, i32, i32)
+-DEF_HELPER_2(macw, void, i32, i32)
++DEF_HELPER_3(addv, i32, env, i32, i32)
++DEF_HELPER_3(addc, i32, env, i32, i32)
++DEF_HELPER_3(subv, i32, env, i32, i32)
++DEF_HELPER_3(subc, i32, env, i32, i32)
++DEF_HELPER_3(div1, i32, env, i32, i32)
++DEF_HELPER_3(macl, void, env, i32, i32)
++DEF_HELPER_3(macw, void, env, i32, i32)
+ 
+-DEF_HELPER_1(ld_fpscr, void, i32)
++DEF_HELPER_2(ld_fpscr, void, env, i32)
+ 
+ DEF_HELPER_1(fabs_FT, f32, f32)
+ DEF_HELPER_1(fabs_DT, f64, f64)
+-DEF_HELPER_2(fadd_FT, f32, f32, f32)
+-DEF_HELPER_2(fadd_DT, f64, f64, f64)
+-DEF_HELPER_1(fcnvsd_FT_DT, f64, f32)
+-DEF_HELPER_1(fcnvds_DT_FT, f32, f64)
++DEF_HELPER_3(fadd_FT, f32, env, f32, f32)
++DEF_HELPER_3(fadd_DT, f64, env, f64, f64)
++DEF_HELPER_2(fcnvsd_FT_DT, f64, env, f32)
++DEF_HELPER_2(fcnvds_DT_FT, f32, env, f64)
+ 
+-DEF_HELPER_2(fcmp_eq_FT, void, f32, f32)
+-DEF_HELPER_2(fcmp_eq_DT, void, f64, f64)
+-DEF_HELPER_2(fcmp_gt_FT, void, f32, f32)
+-DEF_HELPER_2(fcmp_gt_DT, void, f64, f64)
+-DEF_HELPER_2(fdiv_FT, f32, f32, f32)
+-DEF_HELPER_2(fdiv_DT, f64, f64, f64)
+-DEF_HELPER_1(float_FT, f32, i32)
+-DEF_HELPER_1(float_DT, f64, i32)
+-DEF_HELPER_3(fmac_FT, f32, f32, f32, f32)
+-DEF_HELPER_2(fmul_FT, f32, f32, f32)
+-DEF_HELPER_2(fmul_DT, f64, f64, f64)
++DEF_HELPER_3(fcmp_eq_FT, void, env, f32, f32)
++DEF_HELPER_3(fcmp_eq_DT, void, env, f64, f64)
++DEF_HELPER_3(fcmp_gt_FT, void, env, f32, f32)
++DEF_HELPER_3(fcmp_gt_DT, void, env, f64, f64)
++DEF_HELPER_3(fdiv_FT, f32, env, f32, f32)
++DEF_HELPER_3(fdiv_DT, f64, env, f64, f64)
++DEF_HELPER_2(float_FT, f32, env, i32)
++DEF_HELPER_2(float_DT, f64, env, i32)
++DEF_HELPER_4(fmac_FT, f32, env, f32, f32, f32)
++DEF_HELPER_3(fmul_FT, f32, env, f32, f32)
++DEF_HELPER_3(fmul_DT, f64, env, f64, f64)
+ DEF_HELPER_1(fneg_T, f32, f32)
+-DEF_HELPER_2(fsub_FT, f32, f32, f32)
+-DEF_HELPER_2(fsub_DT, f64, f64, f64)
+-DEF_HELPER_1(fsqrt_FT, f32, f32)
+-DEF_HELPER_1(fsqrt_DT, f64, f64)
+-DEF_HELPER_1(ftrc_FT, i32, f32)
+-DEF_HELPER_1(ftrc_DT, i32, f64)
+-DEF_HELPER_2(fipr, void, i32, i32)
+-DEF_HELPER_1(ftrv, void, i32)
++DEF_HELPER_3(fsub_FT, f32, env, f32, f32)
++DEF_HELPER_3(fsub_DT, f64, env, f64, f64)
++DEF_HELPER_2(fsqrt_FT, f32, env, f32)
++DEF_HELPER_2(fsqrt_DT, f64, env, f64)
++DEF_HELPER_2(ftrc_FT, i32, env, f32)
++DEF_HELPER_2(ftrc_DT, i32, env, f64)
++DEF_HELPER_3(fipr, void, env, i32, i32)
++DEF_HELPER_2(ftrv, void, env, i32)
+ 
+ #include "def-helper.h"
+diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
+index 4054791..9b4328d 100644
+--- a/target-sh4/op_helper.c
++++ b/target-sh4/op_helper.c
+@@ -19,10 +19,9 @@
+ #include <assert.h>
+ #include <stdlib.h>
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "helper.h"
+ 
+-static void cpu_restore_state_from_retaddr(uintptr_t retaddr)
++static void cpu_restore_state_from_retaddr(CPUSH4State *env, uintptr_t retaddr)
+ {
+     TranslationBlock *tb;
+ 
+@@ -53,26 +52,22 @@ static void cpu_restore_state_from_retaddr(uintptr_t retaddr)
+ #define SHIFT 3
+ #include "softmmu_template.h"
+ 
+-void tlb_fill(CPUSH4State *env1, target_ulong addr, int is_write, int mmu_idx,
++void tlb_fill(CPUSH4State *env, target_ulong addr, int is_write, int mmu_idx,
+               uintptr_t retaddr)
+ {
+-    CPUSH4State *saved_env;
+     int ret;
+ 
+-    saved_env = env;
+-    env = env1;
+     ret = cpu_sh4_handle_mmu_fault(env, addr, is_write, mmu_idx);
+     if (ret) {
+         /* now we have a real cpu fault */
+-        cpu_restore_state_from_retaddr(retaddr);
++        cpu_restore_state_from_retaddr(env, retaddr);
+         cpu_loop_exit(env);
+     }
+-    env = saved_env;
+ }
+ 
+ #endif
+ 
+-void helper_ldtlb(void)
++void helper_ldtlb(CPUSH4State *env)
+ {
+ #ifdef CONFIG_USER_ONLY
+     /* XXXXX */
+@@ -82,40 +77,41 @@ void helper_ldtlb(void)
+ #endif
+ }
+ 
+-static inline void raise_exception(int index, uintptr_t retaddr)
++static inline void raise_exception(CPUSH4State *env, int index,
++                                   uintptr_t retaddr)
+ {
+     env->exception_index = index;
+-    cpu_restore_state_from_retaddr(retaddr);
++    cpu_restore_state_from_retaddr(env, retaddr);
+     cpu_loop_exit(env);
+ }
+ 
+-void helper_raise_illegal_instruction(void)
++void helper_raise_illegal_instruction(CPUSH4State *env)
+ {
+-    raise_exception(0x180, GETPC());
++    raise_exception(env, 0x180, GETPC());
+ }
+ 
+-void helper_raise_slot_illegal_instruction(void)
++void helper_raise_slot_illegal_instruction(CPUSH4State *env)
+ {
+-    raise_exception(0x1a0, GETPC());
++    raise_exception(env, 0x1a0, GETPC());
+ }
+ 
+-void helper_raise_fpu_disable(void)
++void helper_raise_fpu_disable(CPUSH4State *env)
+ {
+-    raise_exception(0x800, GETPC());
++    raise_exception(env, 0x800, GETPC());
+ }
+ 
+-void helper_raise_slot_fpu_disable(void)
++void helper_raise_slot_fpu_disable(CPUSH4State *env)
+ {
+-    raise_exception(0x820, GETPC());
++    raise_exception(env, 0x820, GETPC());
+ }
+ 
+-void helper_debug(void)
++void helper_debug(CPUSH4State *env)
+ {
+     env->exception_index = EXCP_DEBUG;
+     cpu_loop_exit(env);
+ }
+ 
+-void helper_sleep(uint32_t next_pc)
++void helper_sleep(CPUSH4State *env, uint32_t next_pc)
+ {
+     env->halted = 1;
+     env->in_sleep = 1;
+@@ -124,13 +120,13 @@ void helper_sleep(uint32_t next_pc)
+     cpu_loop_exit(env);
+ }
+ 
+-void helper_trapa(uint32_t tra)
++void helper_trapa(CPUSH4State *env, uint32_t tra)
+ {
+     env->tra = tra << 2;
+-    raise_exception(0x160, GETPC());
++    raise_exception(env, 0x160, GETPC());
+ }
+ 
+-void helper_movcal(uint32_t address, uint32_t value)
++void helper_movcal(CPUSH4State *env, uint32_t address, uint32_t value)
+ {
+     if (cpu_sh4_is_cached (env, address))
+     {
+@@ -144,7 +140,7 @@ void helper_movcal(uint32_t address, uint32_t value)
+     }
+ }
+ 
+-void helper_discard_movcal_backup(void)
++void helper_discard_movcal_backup(CPUSH4State *env)
+ {
+     memory_content *current = env->movcal_backup;
+ 
+@@ -158,7 +154,7 @@ void helper_discard_movcal_backup(void)
+     } 
+ }
+ 
+-void helper_ocbi(uint32_t address)
++void helper_ocbi(CPUSH4State *env, uint32_t address)
+ {
+     memory_content **current = &(env->movcal_backup);
+     while (*current)
+@@ -167,7 +163,7 @@ void helper_ocbi(uint32_t address)
+ 	if ((a & ~0x1F) == (address & ~0x1F))
+ 	{
+ 	    memory_content *next = (*current)->next;
+-	    stl(a, (*current)->value);
++            cpu_stl_data(env, a, (*current)->value);
+ 	    
+ 	    if (next == NULL)
+ 	    {
+@@ -181,7 +177,7 @@ void helper_ocbi(uint32_t address)
+     }
+ }
+ 
+-uint32_t helper_addc(uint32_t arg0, uint32_t arg1)
++uint32_t helper_addc(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
+ {
+     uint32_t tmp0, tmp1;
+ 
+@@ -197,7 +193,7 @@ uint32_t helper_addc(uint32_t arg0, uint32_t arg1)
+     return arg1;
+ }
+ 
+-uint32_t helper_addv(uint32_t arg0, uint32_t arg1)
++uint32_t helper_addv(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
+ {
+     uint32_t dest, src, ans;
+ 
+@@ -236,7 +232,7 @@ uint32_t helper_addv(uint32_t arg0, uint32_t arg1)
+ #define SETM env->sr |= SR_M
+ #define CLRM env->sr &= ~SR_M
+ 
+-uint32_t helper_div1(uint32_t arg0, uint32_t arg1)
++uint32_t helper_div1(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
+ {
+     uint32_t tmp0, tmp2;
+     uint8_t old_q, tmp1 = 0xff;
+@@ -344,7 +340,7 @@ uint32_t helper_div1(uint32_t arg0, uint32_t arg1)
+     return arg1;
+ }
+ 
+-void helper_macl(uint32_t arg0, uint32_t arg1)
++void helper_macl(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
+ {
+     int64_t res;
+ 
+@@ -360,7 +356,7 @@ void helper_macl(uint32_t arg0, uint32_t arg1)
+     }
+ }
+ 
+-void helper_macw(uint32_t arg0, uint32_t arg1)
++void helper_macw(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
+ {
+     int64_t res;
+ 
+@@ -379,7 +375,7 @@ void helper_macw(uint32_t arg0, uint32_t arg1)
+     }
+ }
+ 
+-uint32_t helper_subc(uint32_t arg0, uint32_t arg1)
++uint32_t helper_subc(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
+ {
+     uint32_t tmp0, tmp1;
+ 
+@@ -395,7 +391,7 @@ uint32_t helper_subc(uint32_t arg0, uint32_t arg1)
+     return arg1;
+ }
+ 
+-uint32_t helper_subv(uint32_t arg0, uint32_t arg1)
++uint32_t helper_subv(CPUSH4State *env, uint32_t arg0, uint32_t arg1)
+ {
+     int32_t dest, src, ans;
+ 
+@@ -424,17 +420,17 @@ uint32_t helper_subv(uint32_t arg0, uint32_t arg1)
+     return arg1;
+ }
+ 
+-static inline void set_t(void)
++static inline void set_t(CPUSH4State *env)
+ {
+     env->sr |= SR_T;
+ }
+ 
+-static inline void clr_t(void)
++static inline void clr_t(CPUSH4State *env)
+ {
+     env->sr &= ~SR_T;
+ }
+ 
+-void helper_ld_fpscr(uint32_t val)
++void helper_ld_fpscr(CPUSH4State *env, uint32_t val)
+ {
+     env->fpscr = val & FPSCR_MASK;
+     if ((val & FPSCR_RM_MASK) == FPSCR_RM_ZERO) {
+@@ -445,7 +441,7 @@ void helper_ld_fpscr(uint32_t val)
+     set_flush_to_zero((val & FPSCR_DN) != 0, &env->fp_status);
+ }
+ 
+-static void update_fpscr(uintptr_t retaddr)
++static void update_fpscr(CPUSH4State *env, uintptr_t retaddr)
+ {
+     int xcpt, cause, enable;
+ 
+@@ -479,7 +475,7 @@ static void update_fpscr(uintptr_t retaddr)
+         cause = (env->fpscr & FPSCR_CAUSE_MASK) >> FPSCR_CAUSE_SHIFT;
+         enable = (env->fpscr & FPSCR_ENABLE_MASK) >> FPSCR_ENABLE_SHIFT;
+         if (cause & enable) {
+-            cpu_restore_state_from_retaddr(retaddr);
++            cpu_restore_state_from_retaddr(env, retaddr);
+             env->exception_index = 0x120;
+             cpu_loop_exit(env);
+         }
+@@ -496,156 +492,156 @@ float64 helper_fabs_DT(float64 t0)
+     return float64_abs(t0);
+ }
+ 
+-float32 helper_fadd_FT(float32 t0, float32 t1)
++float32 helper_fadd_FT(CPUSH4State *env, float32 t0, float32 t1)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float32_add(t0, t1, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+-float64 helper_fadd_DT(float64 t0, float64 t1)
++float64 helper_fadd_DT(CPUSH4State *env, float64 t0, float64 t1)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float64_add(t0, t1, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+-void helper_fcmp_eq_FT(float32 t0, float32 t1)
++void helper_fcmp_eq_FT(CPUSH4State *env, float32 t0, float32 t1)
+ {
+     int relation;
+ 
+     set_float_exception_flags(0, &env->fp_status);
+     relation = float32_compare(t0, t1, &env->fp_status);
+     if (unlikely(relation == float_relation_unordered)) {
+-        update_fpscr(GETPC());
++        update_fpscr(env, GETPC());
+     } else if (relation == float_relation_equal) {
+-	set_t();
++        set_t(env);
+     } else {
+-	clr_t();
++        clr_t(env);
+     }
+ }
+ 
+-void helper_fcmp_eq_DT(float64 t0, float64 t1)
++void helper_fcmp_eq_DT(CPUSH4State *env, float64 t0, float64 t1)
+ {
+     int relation;
+ 
+     set_float_exception_flags(0, &env->fp_status);
+     relation = float64_compare(t0, t1, &env->fp_status);
+     if (unlikely(relation == float_relation_unordered)) {
+-        update_fpscr(GETPC());
++        update_fpscr(env, GETPC());
+     } else if (relation == float_relation_equal) {
+-	set_t();
++        set_t(env);
+     } else {
+-	clr_t();
++        clr_t(env);
+     }
+ }
+ 
+-void helper_fcmp_gt_FT(float32 t0, float32 t1)
++void helper_fcmp_gt_FT(CPUSH4State *env, float32 t0, float32 t1)
+ {
+     int relation;
+ 
+     set_float_exception_flags(0, &env->fp_status);
+     relation = float32_compare(t0, t1, &env->fp_status);
+     if (unlikely(relation == float_relation_unordered)) {
+-        update_fpscr(GETPC());
++        update_fpscr(env, GETPC());
+     } else if (relation == float_relation_greater) {
+-	set_t();
++        set_t(env);
+     } else {
+-	clr_t();
++        clr_t(env);
+     }
+ }
+ 
+-void helper_fcmp_gt_DT(float64 t0, float64 t1)
++void helper_fcmp_gt_DT(CPUSH4State *env, float64 t0, float64 t1)
+ {
+     int relation;
+ 
+     set_float_exception_flags(0, &env->fp_status);
+     relation = float64_compare(t0, t1, &env->fp_status);
+     if (unlikely(relation == float_relation_unordered)) {
+-        update_fpscr(GETPC());
++        update_fpscr(env, GETPC());
+     } else if (relation == float_relation_greater) {
+-	set_t();
++        set_t(env);
+     } else {
+-	clr_t();
++        clr_t(env);
+     }
+ }
+ 
+-float64 helper_fcnvsd_FT_DT(float32 t0)
++float64 helper_fcnvsd_FT_DT(CPUSH4State *env, float32 t0)
+ {
+     float64 ret;
+     set_float_exception_flags(0, &env->fp_status);
+     ret = float32_to_float64(t0, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return ret;
+ }
+ 
+-float32 helper_fcnvds_DT_FT(float64 t0)
++float32 helper_fcnvds_DT_FT(CPUSH4State *env, float64 t0)
+ {
+     float32 ret;
+     set_float_exception_flags(0, &env->fp_status);
+     ret = float64_to_float32(t0, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return ret;
+ }
+ 
+-float32 helper_fdiv_FT(float32 t0, float32 t1)
++float32 helper_fdiv_FT(CPUSH4State *env, float32 t0, float32 t1)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float32_div(t0, t1, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+-float64 helper_fdiv_DT(float64 t0, float64 t1)
++float64 helper_fdiv_DT(CPUSH4State *env, float64 t0, float64 t1)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float64_div(t0, t1, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+-float32 helper_float_FT(uint32_t t0)
++float32 helper_float_FT(CPUSH4State *env, uint32_t t0)
+ {
+     float32 ret;
+     set_float_exception_flags(0, &env->fp_status);
+     ret = int32_to_float32(t0, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return ret;
+ }
+ 
+-float64 helper_float_DT(uint32_t t0)
++float64 helper_float_DT(CPUSH4State *env, uint32_t t0)
+ {
+     float64 ret;
+     set_float_exception_flags(0, &env->fp_status);
+     ret = int32_to_float64(t0, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return ret;
+ }
+ 
+-float32 helper_fmac_FT(float32 t0, float32 t1, float32 t2)
++float32 helper_fmac_FT(CPUSH4State *env, float32 t0, float32 t1, float32 t2)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float32_mul(t0, t1, &env->fp_status);
+     t0 = float32_add(t0, t2, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+-float32 helper_fmul_FT(float32 t0, float32 t1)
++float32 helper_fmul_FT(CPUSH4State *env, float32 t0, float32 t1)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float32_mul(t0, t1, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+-float64 helper_fmul_DT(float64 t0, float64 t1)
++float64 helper_fmul_DT(CPUSH4State *env, float64 t0, float64 t1)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float64_mul(t0, t1, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+@@ -654,57 +650,57 @@ float32 helper_fneg_T(float32 t0)
+     return float32_chs(t0);
+ }
+ 
+-float32 helper_fsqrt_FT(float32 t0)
++float32 helper_fsqrt_FT(CPUSH4State *env, float32 t0)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float32_sqrt(t0, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+-float64 helper_fsqrt_DT(float64 t0)
++float64 helper_fsqrt_DT(CPUSH4State *env, float64 t0)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float64_sqrt(t0, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+-float32 helper_fsub_FT(float32 t0, float32 t1)
++float32 helper_fsub_FT(CPUSH4State *env, float32 t0, float32 t1)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float32_sub(t0, t1, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+-float64 helper_fsub_DT(float64 t0, float64 t1)
++float64 helper_fsub_DT(CPUSH4State *env, float64 t0, float64 t1)
+ {
+     set_float_exception_flags(0, &env->fp_status);
+     t0 = float64_sub(t0, t1, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return t0;
+ }
+ 
+-uint32_t helper_ftrc_FT(float32 t0)
++uint32_t helper_ftrc_FT(CPUSH4State *env, float32 t0)
+ {
+     uint32_t ret;
+     set_float_exception_flags(0, &env->fp_status);
+     ret = float32_to_int32_round_to_zero(t0, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return ret;
+ }
+ 
+-uint32_t helper_ftrc_DT(float64 t0)
++uint32_t helper_ftrc_DT(CPUSH4State *env, float64 t0)
+ {
+     uint32_t ret;
+     set_float_exception_flags(0, &env->fp_status);
+     ret = float64_to_int32_round_to_zero(t0, &env->fp_status);
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+     return ret;
+ }
+ 
+-void helper_fipr(uint32_t m, uint32_t n)
++void helper_fipr(CPUSH4State *env, uint32_t m, uint32_t n)
+ {
+     int bank, i;
+     float32 r, p;
+@@ -719,12 +715,12 @@ void helper_fipr(uint32_t m, uint32_t n)
+                         &env->fp_status);
+         r = float32_add(r, p, &env->fp_status);
+     }
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+ 
+     env->fregs[bank + n + 3] = r;
+ }
+ 
+-void helper_ftrv(uint32_t n)
++void helper_ftrv(CPUSH4State *env, uint32_t n)
+ {
+     int bank_matrix, bank_vector;
+     int i, j;
+@@ -743,7 +739,7 @@ void helper_ftrv(uint32_t n)
+             r[i] = float32_add(r[i], p, &env->fp_status);
+         }
+     }
+-    update_fpscr(GETPC());
++    update_fpscr(env, GETPC());
+ 
+     for (i = 0 ; i < 4 ; i++) {
+         env->fregs[bank_vector + i] = r[i];
+diff --git a/target-sh4/translate.c b/target-sh4/translate.c
+index 6532ad2..d05c74c 100644
+--- a/target-sh4/translate.c
++++ b/target-sh4/translate.c
+@@ -276,7 +276,7 @@ static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
+     } else {
+         tcg_gen_movi_i32(cpu_pc, dest);
+         if (ctx->singlestep_enabled)
+-            gen_helper_debug();
++            gen_helper_debug(cpu_env);
+         tcg_gen_exit_tb(0);
+     }
+ }
+@@ -288,7 +288,7 @@ static void gen_jump(DisasContext * ctx)
+ 	   delayed jump as immediate jump are conditinal jumps */
+ 	tcg_gen_mov_i32(cpu_pc, cpu_delayed_pc);
+ 	if (ctx->singlestep_enabled)
+-	    gen_helper_debug();
++            gen_helper_debug(cpu_env);
+ 	tcg_gen_exit_tb(0);
+     } else {
+ 	gen_goto_tb(ctx, 0, ctx->delayed_pc);
+@@ -437,7 +437,7 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
+ #define CHECK_NOT_DELAY_SLOT \
+   if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL))     \
+   {                                                           \
+-      gen_helper_raise_slot_illegal_instruction();            \
++      gen_helper_raise_slot_illegal_instruction(cpu_env);     \
+       ctx->bstate = BS_EXCP;                                  \
+       return;                                                 \
+   }
+@@ -445,9 +445,9 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
+ #define CHECK_PRIVILEGED                                        \
+   if (IS_USER(ctx)) {                                           \
+       if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
+-         gen_helper_raise_slot_illegal_instruction();           \
++          gen_helper_raise_slot_illegal_instruction(cpu_env);   \
+       } else {                                                  \
+-         gen_helper_raise_illegal_instruction();                \
++          gen_helper_raise_illegal_instruction(cpu_env);        \
+       }                                                         \
+       ctx->bstate = BS_EXCP;                                    \
+       return;                                                   \
+@@ -456,9 +456,9 @@ static inline void gen_store_fpr64 (TCGv_i64 t, int reg)
+ #define CHECK_FPU_ENABLED                                       \
+   if (ctx->flags & SR_FD) {                                     \
+       if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) { \
+-          gen_helper_raise_slot_fpu_disable();                  \
++          gen_helper_raise_slot_fpu_disable(cpu_env);           \
+       } else {                                                  \
+-          gen_helper_raise_fpu_disable();                       \
++          gen_helper_raise_fpu_disable(cpu_env);                \
+       }                                                         \
+       ctx->bstate = BS_EXCP;                                    \
+       return;                                                   \
+@@ -492,7 +492,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	  if (opcode != 0x0093 /* ocbi */
+ 	      && opcode != 0x00c3 /* movca.l */)
+ 	      {
+-		  gen_helper_discard_movcal_backup ();
++                  gen_helper_discard_movcal_backup(cpu_env);
+ 		  ctx->has_movcal = 0;
+ 	      }
+ 	}
+@@ -523,7 +523,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	return;
+     case 0x0038:		/* ldtlb */
+ 	CHECK_PRIVILEGED
+-	gen_helper_ldtlb();
++        gen_helper_ldtlb(cpu_env);
+ 	return;
+     case 0x002b:		/* rte */
+ 	CHECK_PRIVILEGED
+@@ -551,7 +551,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	return;
+     case 0x001b:		/* sleep */
+ 	CHECK_PRIVILEGED
+-	gen_helper_sleep(tcg_const_i32(ctx->pc + 2));
++        gen_helper_sleep(cpu_env, tcg_const_i32(ctx->pc + 2));
+ 	return;
+     }
+ 
+@@ -761,10 +761,10 @@ static void _decode_opc(DisasContext * ctx)
+ 	tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));
+ 	return;
+     case 0x300e:		/* addc Rm,Rn */
+-	gen_helper_addc(REG(B11_8), REG(B7_4), REG(B11_8));
++        gen_helper_addc(REG(B11_8), cpu_env, REG(B7_4), REG(B11_8));
+ 	return;
+     case 0x300f:		/* addv Rm,Rn */
+-	gen_helper_addv(REG(B11_8), REG(B7_4), REG(B11_8));
++        gen_helper_addv(REG(B11_8), cpu_env, REG(B7_4), REG(B11_8));
+ 	return;
+     case 0x2009:		/* and Rm,Rn */
+ 	tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));
+@@ -817,7 +817,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	}
+ 	return;
+     case 0x3004:		/* div1 Rm,Rn */
+-	gen_helper_div1(REG(B11_8), REG(B7_4), REG(B11_8));
++        gen_helper_div1(REG(B11_8), cpu_env, REG(B7_4), REG(B11_8));
+ 	return;
+     case 0x300d:		/* dmuls.l Rm,Rn */
+ 	{
+@@ -870,7 +870,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	    tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
+ 	    arg1 = tcg_temp_new();
+ 	    tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
+-	    gen_helper_macl(arg0, arg1);
++            gen_helper_macl(cpu_env, arg0, arg1);
+ 	    tcg_temp_free(arg1);
+ 	    tcg_temp_free(arg0);
+ 	    tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);
+@@ -884,7 +884,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	    tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);
+ 	    arg1 = tcg_temp_new();
+ 	    tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);
+-	    gen_helper_macw(arg0, arg1);
++            gen_helper_macw(cpu_env, arg0, arg1);
+ 	    tcg_temp_free(arg1);
+ 	    tcg_temp_free(arg0);
+ 	    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);
+@@ -1013,10 +1013,10 @@ static void _decode_opc(DisasContext * ctx)
+ 	tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));
+ 	return;
+     case 0x300a:		/* subc Rm,Rn */
+-	gen_helper_subc(REG(B11_8), REG(B7_4), REG(B11_8));
++        gen_helper_subc(REG(B11_8), cpu_env, REG(B7_4), REG(B11_8));
+ 	return;
+     case 0x300b:		/* subv Rm,Rn */
+-	gen_helper_subv(REG(B11_8), REG(B7_4), REG(B11_8));
++        gen_helper_subv(REG(B11_8), cpu_env, REG(B7_4), REG(B11_8));
+ 	return;
+     case 0x2008:		/* tst Rm,Rn */
+ 	{
+@@ -1152,22 +1152,22 @@ static void _decode_opc(DisasContext * ctx)
+ 		gen_load_fpr64(fp1, DREG(B7_4));
+                 switch (ctx->opcode & 0xf00f) {
+                 case 0xf000:		/* fadd Rm,Rn */
+-                    gen_helper_fadd_DT(fp0, fp0, fp1);
++                    gen_helper_fadd_DT(fp0, cpu_env, fp0, fp1);
+                     break;
+                 case 0xf001:		/* fsub Rm,Rn */
+-                    gen_helper_fsub_DT(fp0, fp0, fp1);
++                    gen_helper_fsub_DT(fp0, cpu_env, fp0, fp1);
+                     break;
+                 case 0xf002:		/* fmul Rm,Rn */
+-                    gen_helper_fmul_DT(fp0, fp0, fp1);
++                    gen_helper_fmul_DT(fp0, cpu_env, fp0, fp1);
+                     break;
+                 case 0xf003:		/* fdiv Rm,Rn */
+-                    gen_helper_fdiv_DT(fp0, fp0, fp1);
++                    gen_helper_fdiv_DT(fp0, cpu_env, fp0, fp1);
+                     break;
+                 case 0xf004:		/* fcmp/eq Rm,Rn */
+-                    gen_helper_fcmp_eq_DT(fp0, fp1);
++                    gen_helper_fcmp_eq_DT(cpu_env, fp0, fp1);
+                     return;
+                 case 0xf005:		/* fcmp/gt Rm,Rn */
+-                    gen_helper_fcmp_gt_DT(fp0, fp1);
++                    gen_helper_fcmp_gt_DT(cpu_env, fp0, fp1);
+                     return;
+                 }
+ 		gen_store_fpr64(fp0, DREG(B11_8));
+@@ -1176,22 +1176,32 @@ static void _decode_opc(DisasContext * ctx)
+ 	    } else {
+                 switch (ctx->opcode & 0xf00f) {
+                 case 0xf000:		/* fadd Rm,Rn */
+-                    gen_helper_fadd_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
++                    gen_helper_fadd_FT(cpu_fregs[FREG(B11_8)], cpu_env,
++                                       cpu_fregs[FREG(B11_8)],
++                                       cpu_fregs[FREG(B7_4)]);
+                     break;
+                 case 0xf001:		/* fsub Rm,Rn */
+-                    gen_helper_fsub_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
++                    gen_helper_fsub_FT(cpu_fregs[FREG(B11_8)], cpu_env,
++                                       cpu_fregs[FREG(B11_8)],
++                                       cpu_fregs[FREG(B7_4)]);
+                     break;
+                 case 0xf002:		/* fmul Rm,Rn */
+-                    gen_helper_fmul_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
++                    gen_helper_fmul_FT(cpu_fregs[FREG(B11_8)], cpu_env,
++                                       cpu_fregs[FREG(B11_8)],
++                                       cpu_fregs[FREG(B7_4)]);
+                     break;
+                 case 0xf003:		/* fdiv Rm,Rn */
+-                    gen_helper_fdiv_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
++                    gen_helper_fdiv_FT(cpu_fregs[FREG(B11_8)], cpu_env,
++                                       cpu_fregs[FREG(B11_8)],
++                                       cpu_fregs[FREG(B7_4)]);
+                     break;
+                 case 0xf004:		/* fcmp/eq Rm,Rn */
+-                    gen_helper_fcmp_eq_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
++                    gen_helper_fcmp_eq_FT(cpu_env, cpu_fregs[FREG(B11_8)],
++                                          cpu_fregs[FREG(B7_4)]);
+                     return;
+                 case 0xf005:		/* fcmp/gt Rm,Rn */
+-                    gen_helper_fcmp_gt_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B7_4)]);
++                    gen_helper_fcmp_gt_FT(cpu_env, cpu_fregs[FREG(B11_8)],
++                                          cpu_fregs[FREG(B7_4)]);
+                     return;
+                 }
+ 	    }
+@@ -1203,8 +1213,9 @@ static void _decode_opc(DisasContext * ctx)
+             if (ctx->fpscr & FPSCR_PR) {
+                 break; /* illegal instruction */
+             } else {
+-                gen_helper_fmac_FT(cpu_fregs[FREG(B11_8)],
+-                                   cpu_fregs[FREG(0)], cpu_fregs[FREG(B7_4)], cpu_fregs[FREG(B11_8)]);
++                gen_helper_fmac_FT(cpu_fregs[FREG(B11_8)], cpu_env,
++                                   cpu_fregs[FREG(0)], cpu_fregs[FREG(B7_4)],
++                                   cpu_fregs[FREG(B11_8)]);
+                 return;
+             }
+         }
+@@ -1356,7 +1367,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	    TCGv imm;
+ 	    CHECK_NOT_DELAY_SLOT
+ 	    imm = tcg_const_i32(B7_0);
+-	    gen_helper_trapa(imm);
++            gen_helper_trapa(cpu_env, imm);
+ 	    tcg_temp_free(imm);
+ 	    ctx->bstate = BS_BRANCH;
+ 	}
+@@ -1531,7 +1542,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052, {CHECK_FPU_ENABLED})
+     case 0x406a:		/* lds Rm,FPSCR */
+ 	CHECK_FPU_ENABLED
+-	gen_helper_ld_fpscr(REG(B11_8));
++        gen_helper_ld_fpscr(cpu_env, REG(B11_8));
+ 	ctx->bstate = BS_STOP;
+ 	return;
+     case 0x4066:		/* lds.l @Rm+,FPSCR */
+@@ -1540,7 +1551,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	    TCGv addr = tcg_temp_new();
+ 	    tcg_gen_qemu_ld32s(addr, REG(B11_8), ctx->memidx);
+ 	    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);
+-	    gen_helper_ld_fpscr(addr);
++            gen_helper_ld_fpscr(cpu_env, addr);
+ 	    tcg_temp_free(addr);
+ 	    ctx->bstate = BS_STOP;
+ 	}
+@@ -1567,7 +1578,7 @@ static void _decode_opc(DisasContext * ctx)
+         {
+             TCGv val = tcg_temp_new();
+             tcg_gen_qemu_ld32u(val, REG(B11_8), ctx->memidx);
+-            gen_helper_movcal (REG(B11_8), val);            
++            gen_helper_movcal(cpu_env, REG(B11_8), val);
+             tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx);
+         }
+         ctx->has_movcal = 1;
+@@ -1619,7 +1630,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	    break;
+     case 0x0093:		/* ocbi @Rn */
+ 	{
+-	    gen_helper_ocbi (REG(B11_8));
++            gen_helper_ocbi(cpu_env, REG(B11_8));
+ 	}
+ 	return;
+     case 0x00a3:		/* ocbp @Rn */
+@@ -1733,12 +1744,12 @@ static void _decode_opc(DisasContext * ctx)
+ 	    if (ctx->opcode & 0x0100)
+ 		break; /* illegal instruction */
+ 	    fp = tcg_temp_new_i64();
+-	    gen_helper_float_DT(fp, cpu_fpul);
++            gen_helper_float_DT(fp, cpu_env, cpu_fpul);
+ 	    gen_store_fpr64(fp, DREG(B11_8));
+ 	    tcg_temp_free_i64(fp);
+ 	}
+ 	else {
+-	    gen_helper_float_FT(cpu_fregs[FREG(B11_8)], cpu_fpul);
++            gen_helper_float_FT(cpu_fregs[FREG(B11_8)], cpu_env, cpu_fpul);
+ 	}
+ 	return;
+     case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */
+@@ -1749,11 +1760,11 @@ static void _decode_opc(DisasContext * ctx)
+ 		break; /* illegal instruction */
+ 	    fp = tcg_temp_new_i64();
+ 	    gen_load_fpr64(fp, DREG(B11_8));
+-	    gen_helper_ftrc_DT(cpu_fpul, fp);
++            gen_helper_ftrc_DT(cpu_fpul, cpu_env, fp);
+ 	    tcg_temp_free_i64(fp);
+ 	}
+ 	else {
+-	    gen_helper_ftrc_FT(cpu_fpul, cpu_fregs[FREG(B11_8)]);
++            gen_helper_ftrc_FT(cpu_fpul, cpu_env, cpu_fregs[FREG(B11_8)]);
+ 	}
+ 	return;
+     case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */
+@@ -1783,11 +1794,12 @@ static void _decode_opc(DisasContext * ctx)
+ 		break; /* illegal instruction */
+ 	    TCGv_i64 fp = tcg_temp_new_i64();
+ 	    gen_load_fpr64(fp, DREG(B11_8));
+-	    gen_helper_fsqrt_DT(fp, fp);
++            gen_helper_fsqrt_DT(fp, cpu_env, fp);
+ 	    gen_store_fpr64(fp, DREG(B11_8));
+ 	    tcg_temp_free_i64(fp);
+ 	} else {
+-	    gen_helper_fsqrt_FT(cpu_fregs[FREG(B11_8)], cpu_fregs[FREG(B11_8)]);
++            gen_helper_fsqrt_FT(cpu_fregs[FREG(B11_8)], cpu_env,
++                                cpu_fregs[FREG(B11_8)]);
+ 	}
+ 	return;
+     case 0xf07d: /* fsrra FRn */
+@@ -1809,7 +1821,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	CHECK_FPU_ENABLED
+ 	{
+ 	    TCGv_i64 fp = tcg_temp_new_i64();
+-	    gen_helper_fcnvsd_FT_DT(fp, cpu_fpul);
++            gen_helper_fcnvsd_FT_DT(fp, cpu_env, cpu_fpul);
+ 	    gen_store_fpr64(fp, DREG(B11_8));
+ 	    tcg_temp_free_i64(fp);
+ 	}
+@@ -1819,7 +1831,7 @@ static void _decode_opc(DisasContext * ctx)
+ 	{
+ 	    TCGv_i64 fp = tcg_temp_new_i64();
+ 	    gen_load_fpr64(fp, DREG(B11_8));
+-	    gen_helper_fcnvds_DT_FT(cpu_fpul, fp);
++            gen_helper_fcnvds_DT_FT(cpu_fpul, cpu_env, fp);
+ 	    tcg_temp_free_i64(fp);
+ 	}
+ 	return;
+@@ -1829,7 +1841,7 @@ static void _decode_opc(DisasContext * ctx)
+             TCGv m, n;
+             m = tcg_const_i32((ctx->opcode >> 8) & 3);
+             n = tcg_const_i32((ctx->opcode >> 10) & 3);
+-            gen_helper_fipr(m, n);
++            gen_helper_fipr(cpu_env, m, n);
+             tcg_temp_free(m);
+             tcg_temp_free(n);
+             return;
+@@ -1841,7 +1853,7 @@ static void _decode_opc(DisasContext * ctx)
+             (ctx->fpscr & FPSCR_PR) == 0) {
+             TCGv n;
+             n = tcg_const_i32((ctx->opcode >> 10) & 3);
+-            gen_helper_ftrv(n);
++            gen_helper_ftrv(cpu_env, n);
+             tcg_temp_free(n);
+             return;
+         }
+@@ -1853,9 +1865,9 @@ static void _decode_opc(DisasContext * ctx)
+     fflush(stderr);
+ #endif
+     if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) {
+-       gen_helper_raise_slot_illegal_instruction();
++        gen_helper_raise_slot_illegal_instruction(cpu_env);
+     } else {
+-       gen_helper_raise_illegal_instruction();
++        gen_helper_raise_illegal_instruction(cpu_env);
+     }
+     ctx->bstate = BS_EXCP;
+ }
+@@ -1934,7 +1946,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
+                 if (ctx.pc == bp->pc) {
+ 		    /* We have hit a breakpoint - make sure PC is up-to-date */
+ 		    tcg_gen_movi_i32(cpu_pc, ctx.pc);
+-		    gen_helper_debug();
++                    gen_helper_debug(cpu_env);
+ 		    ctx.bstate = BS_EXCP;
+ 		    break;
+ 		}
+@@ -1958,7 +1970,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
+ 	fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
+ 	fflush(stderr);
+ #endif
+-	ctx.opcode = lduw_code(ctx.pc);
++        ctx.opcode = cpu_lduw_code(env, ctx.pc);
+ 	decode_opc(&ctx);
+         num_insns++;
+ 	ctx.pc += 2;
+@@ -1975,7 +1987,7 @@ gen_intermediate_code_internal(CPUSH4State * env, TranslationBlock * tb,
+         gen_io_end();
+     if (env->singlestep_enabled) {
+         tcg_gen_movi_i32(cpu_pc, ctx.pc);
+-        gen_helper_debug();
++        gen_helper_debug(cpu_env);
+     } else {
+ 	switch (ctx.bstate) {
+         case BS_STOP:
+-- 
+1.7.12.1
+
diff --git a/0038-target-mips-switch-to-AREG0-free-mode.patch b/0038-target-mips-switch-to-AREG0-free-mode.patch
new file mode 100644
index 0000000..6c8ea5a
--- /dev/null
+++ b/0038-target-mips-switch-to-AREG0-free-mode.patch
@@ -0,0 +1,6336 @@
+From 8ad14b12fbe7555da2b2f0f1f28e07b8a34b686c Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 14:52:59 +0000
+Subject: [PATCH] target-mips: switch to AREG0 free mode
+
+Add an explicit CPUState parameter instead of relying on AREG0
+and switch to AREG0 free mode.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Acked-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure                 |    2 +-
+ target-mips/Makefile.objs |    2 -
+ target-mips/cpu.h         |   16 +-
+ target-mips/helper.h      |  410 ++++++++---------
+ target-mips/op_helper.c   | 1065 ++++++++++++++++++++++++---------------------
+ target-mips/translate.c   |  754 ++++++++++++++++----------------
+ 6 files changed, 1163 insertions(+), 1086 deletions(-)
+
+diff --git a/configure b/configure
+index 03ce76e..83b068d 100755
+--- a/configure
++++ b/configure
+@@ -3839,7 +3839,7 @@ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+ 
+ 
+ case "$target_arch2" in
+-  alpha | arm* | cris | i386 | lm32 | m68k | microblaze* | or32 | s390x | sh4* | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
++  alpha | arm* | cris | i386 | lm32 | m68k | microblaze* | mips* | or32 | s390x | sh4* | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
+     echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
+   ;;
+ esac
+diff --git a/target-mips/Makefile.objs b/target-mips/Makefile.objs
+index 2e0e093..ca20f21 100644
+--- a/target-mips/Makefile.objs
++++ b/target-mips/Makefile.objs
+@@ -1,4 +1,2 @@
+ obj-y += translate.o op_helper.o helper.o cpu.o
+ obj-$(CONFIG_SOFTMMU) += machine.o
+-
+-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/target-mips/cpu.h b/target-mips/cpu.h
+index ce3467f..be4f805 100644
+--- a/target-mips/cpu.h
++++ b/target-mips/cpu.h
+@@ -38,10 +38,10 @@ struct CPUMIPSTLBContext {
+     uint32_t nb_tlb;
+     uint32_t tlb_in_use;
+     int (*map_address) (struct CPUMIPSState *env, target_phys_addr_t *physical, int *prot, target_ulong address, int rw, int access_type);
+-    void (*helper_tlbwi) (void);
+-    void (*helper_tlbwr) (void);
+-    void (*helper_tlbp) (void);
+-    void (*helper_tlbr) (void);
++    void (*helper_tlbwi)(struct CPUMIPSState *env);
++    void (*helper_tlbwr)(struct CPUMIPSState *env);
++    void (*helper_tlbp)(struct CPUMIPSState *env);
++    void (*helper_tlbr)(struct CPUMIPSState *env);
+     union {
+         struct {
+             r4k_tlb_t tlb[MIPS_TLB_MAX];
+@@ -485,10 +485,10 @@ int fixed_mmu_map_address (CPUMIPSState *env, target_phys_addr_t *physical, int
+                            target_ulong address, int rw, int access_type);
+ int r4k_map_address (CPUMIPSState *env, target_phys_addr_t *physical, int *prot,
+                      target_ulong address, int rw, int access_type);
+-void r4k_helper_tlbwi (void);
+-void r4k_helper_tlbwr (void);
+-void r4k_helper_tlbp (void);
+-void r4k_helper_tlbr (void);
++void r4k_helper_tlbwi(CPUMIPSState *env);
++void r4k_helper_tlbwr(CPUMIPSState *env);
++void r4k_helper_tlbp(CPUMIPSState *env);
++void r4k_helper_tlbr(CPUMIPSState *env);
+ 
+ void cpu_unassigned_access(CPUMIPSState *env, target_phys_addr_t addr,
+                            int is_write, int is_exec, int unused, int size);
+diff --git a/target-mips/helper.h b/target-mips/helper.h
+index 76fb451..109ac37 100644
+--- a/target-mips/helper.h
++++ b/target-mips/helper.h
+@@ -1,25 +1,25 @@
+ #include "def-helper.h"
+ 
+-DEF_HELPER_2(raise_exception_err, noreturn, i32, int)
+-DEF_HELPER_1(raise_exception, noreturn, i32)
++DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int)
++DEF_HELPER_2(raise_exception, noreturn, env, i32)
+ 
+ #ifdef TARGET_MIPS64
+-DEF_HELPER_3(ldl, tl, tl, tl, int)
+-DEF_HELPER_3(ldr, tl, tl, tl, int)
+-DEF_HELPER_3(sdl, void, tl, tl, int)
+-DEF_HELPER_3(sdr, void, tl, tl, int)
++DEF_HELPER_4(ldl, tl, env, tl, tl, int)
++DEF_HELPER_4(ldr, tl, env, tl, tl, int)
++DEF_HELPER_4(sdl, void, env, tl, tl, int)
++DEF_HELPER_4(sdr, void, env, tl, tl, int)
+ #endif
+-DEF_HELPER_3(lwl, tl, tl, tl, int)
+-DEF_HELPER_3(lwr, tl, tl, tl, int)
+-DEF_HELPER_3(swl, void, tl, tl, int)
+-DEF_HELPER_3(swr, void, tl, tl, int)
++DEF_HELPER_4(lwl, tl, env, tl, tl, int)
++DEF_HELPER_4(lwr, tl, env, tl, tl, int)
++DEF_HELPER_4(swl, void, env, tl, tl, int)
++DEF_HELPER_4(swr, void, env, tl, tl, int)
+ 
+ #ifndef CONFIG_USER_ONLY
+-DEF_HELPER_2(ll, tl, tl, int)
+-DEF_HELPER_3(sc, tl, tl, tl, int)
++DEF_HELPER_3(ll, tl, env, tl, int)
++DEF_HELPER_4(sc, tl, env, tl, tl, int)
+ #ifdef TARGET_MIPS64
+-DEF_HELPER_2(lld, tl, tl, int)
+-DEF_HELPER_3(scd, tl, tl, tl, int)
++DEF_HELPER_3(lld, tl, env, tl, int)
++DEF_HELPER_4(scd, tl, env, tl, tl, int)
+ #endif
+ #endif
+ 
+@@ -28,195 +28,195 @@ DEF_HELPER_FLAGS_1(clz, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
+ #ifdef TARGET_MIPS64
+ DEF_HELPER_FLAGS_1(dclo, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
+ DEF_HELPER_FLAGS_1(dclz, TCG_CALL_CONST | TCG_CALL_PURE, tl, tl)
+-DEF_HELPER_2(dmult, void, tl, tl)
+-DEF_HELPER_2(dmultu, void, tl, tl)
++DEF_HELPER_3(dmult, void, env, tl, tl)
++DEF_HELPER_3(dmultu, void, env, tl, tl)
+ #endif
+ 
+-DEF_HELPER_2(muls, tl, tl, tl)
+-DEF_HELPER_2(mulsu, tl, tl, tl)
+-DEF_HELPER_2(macc, tl, tl, tl)
+-DEF_HELPER_2(maccu, tl, tl, tl)
+-DEF_HELPER_2(msac, tl, tl, tl)
+-DEF_HELPER_2(msacu, tl, tl, tl)
+-DEF_HELPER_2(mulhi, tl, tl, tl)
+-DEF_HELPER_2(mulhiu, tl, tl, tl)
+-DEF_HELPER_2(mulshi, tl, tl, tl)
+-DEF_HELPER_2(mulshiu, tl, tl, tl)
+-DEF_HELPER_2(macchi, tl, tl, tl)
+-DEF_HELPER_2(macchiu, tl, tl, tl)
+-DEF_HELPER_2(msachi, tl, tl, tl)
+-DEF_HELPER_2(msachiu, tl, tl, tl)
++DEF_HELPER_3(muls, tl, env, tl, tl)
++DEF_HELPER_3(mulsu, tl, env, tl, tl)
++DEF_HELPER_3(macc, tl, env, tl, tl)
++DEF_HELPER_3(maccu, tl, env, tl, tl)
++DEF_HELPER_3(msac, tl, env, tl, tl)
++DEF_HELPER_3(msacu, tl, env, tl, tl)
++DEF_HELPER_3(mulhi, tl, env, tl, tl)
++DEF_HELPER_3(mulhiu, tl, env, tl, tl)
++DEF_HELPER_3(mulshi, tl, env, tl, tl)
++DEF_HELPER_3(mulshiu, tl, env, tl, tl)
++DEF_HELPER_3(macchi, tl, env, tl, tl)
++DEF_HELPER_3(macchiu, tl, env, tl, tl)
++DEF_HELPER_3(msachi, tl, env, tl, tl)
++DEF_HELPER_3(msachiu, tl, env, tl, tl)
+ 
+ #ifndef CONFIG_USER_ONLY
+ /* CP0 helpers */
+-DEF_HELPER_0(mfc0_mvpcontrol, tl)
+-DEF_HELPER_0(mfc0_mvpconf0, tl)
+-DEF_HELPER_0(mfc0_mvpconf1, tl)
+-DEF_HELPER_0(mftc0_vpecontrol, tl)
+-DEF_HELPER_0(mftc0_vpeconf0, tl)
+-DEF_HELPER_0(mfc0_random, tl)
+-DEF_HELPER_0(mfc0_tcstatus, tl)
+-DEF_HELPER_0(mftc0_tcstatus, tl)
+-DEF_HELPER_0(mfc0_tcbind, tl)
+-DEF_HELPER_0(mftc0_tcbind, tl)
+-DEF_HELPER_0(mfc0_tcrestart, tl)
+-DEF_HELPER_0(mftc0_tcrestart, tl)
+-DEF_HELPER_0(mfc0_tchalt, tl)
+-DEF_HELPER_0(mftc0_tchalt, tl)
+-DEF_HELPER_0(mfc0_tccontext, tl)
+-DEF_HELPER_0(mftc0_tccontext, tl)
+-DEF_HELPER_0(mfc0_tcschedule, tl)
+-DEF_HELPER_0(mftc0_tcschedule, tl)
+-DEF_HELPER_0(mfc0_tcschefback, tl)
+-DEF_HELPER_0(mftc0_tcschefback, tl)
+-DEF_HELPER_0(mfc0_count, tl)
+-DEF_HELPER_0(mftc0_entryhi, tl)
+-DEF_HELPER_0(mftc0_status, tl)
+-DEF_HELPER_0(mftc0_cause, tl)
+-DEF_HELPER_0(mftc0_epc, tl)
+-DEF_HELPER_0(mftc0_ebase, tl)
+-DEF_HELPER_1(mftc0_configx, tl, tl)
+-DEF_HELPER_0(mfc0_lladdr, tl)
+-DEF_HELPER_1(mfc0_watchlo, tl, i32)
+-DEF_HELPER_1(mfc0_watchhi, tl, i32)
+-DEF_HELPER_0(mfc0_debug, tl)
+-DEF_HELPER_0(mftc0_debug, tl)
++DEF_HELPER_1(mfc0_mvpcontrol, tl, env)
++DEF_HELPER_1(mfc0_mvpconf0, tl, env)
++DEF_HELPER_1(mfc0_mvpconf1, tl, env)
++DEF_HELPER_1(mftc0_vpecontrol, tl, env)
++DEF_HELPER_1(mftc0_vpeconf0, tl, env)
++DEF_HELPER_1(mfc0_random, tl, env)
++DEF_HELPER_1(mfc0_tcstatus, tl, env)
++DEF_HELPER_1(mftc0_tcstatus, tl, env)
++DEF_HELPER_1(mfc0_tcbind, tl, env)
++DEF_HELPER_1(mftc0_tcbind, tl, env)
++DEF_HELPER_1(mfc0_tcrestart, tl, env)
++DEF_HELPER_1(mftc0_tcrestart, tl, env)
++DEF_HELPER_1(mfc0_tchalt, tl, env)
++DEF_HELPER_1(mftc0_tchalt, tl, env)
++DEF_HELPER_1(mfc0_tccontext, tl, env)
++DEF_HELPER_1(mftc0_tccontext, tl, env)
++DEF_HELPER_1(mfc0_tcschedule, tl, env)
++DEF_HELPER_1(mftc0_tcschedule, tl, env)
++DEF_HELPER_1(mfc0_tcschefback, tl, env)
++DEF_HELPER_1(mftc0_tcschefback, tl, env)
++DEF_HELPER_1(mfc0_count, tl, env)
++DEF_HELPER_1(mftc0_entryhi, tl, env)
++DEF_HELPER_1(mftc0_status, tl, env)
++DEF_HELPER_1(mftc0_cause, tl, env)
++DEF_HELPER_1(mftc0_epc, tl, env)
++DEF_HELPER_1(mftc0_ebase, tl, env)
++DEF_HELPER_2(mftc0_configx, tl, env, tl)
++DEF_HELPER_1(mfc0_lladdr, tl, env)
++DEF_HELPER_2(mfc0_watchlo, tl, env, i32)
++DEF_HELPER_2(mfc0_watchhi, tl, env, i32)
++DEF_HELPER_1(mfc0_debug, tl, env)
++DEF_HELPER_1(mftc0_debug, tl, env)
+ #ifdef TARGET_MIPS64
+-DEF_HELPER_0(dmfc0_tcrestart, tl)
+-DEF_HELPER_0(dmfc0_tchalt, tl)
+-DEF_HELPER_0(dmfc0_tccontext, tl)
+-DEF_HELPER_0(dmfc0_tcschedule, tl)
+-DEF_HELPER_0(dmfc0_tcschefback, tl)
+-DEF_HELPER_0(dmfc0_lladdr, tl)
+-DEF_HELPER_1(dmfc0_watchlo, tl, i32)
++DEF_HELPER_1(dmfc0_tcrestart, tl, env)
++DEF_HELPER_1(dmfc0_tchalt, tl, env)
++DEF_HELPER_1(dmfc0_tccontext, tl, env)
++DEF_HELPER_1(dmfc0_tcschedule, tl, env)
++DEF_HELPER_1(dmfc0_tcschefback, tl, env)
++DEF_HELPER_1(dmfc0_lladdr, tl, env)
++DEF_HELPER_2(dmfc0_watchlo, tl, env, i32)
+ #endif /* TARGET_MIPS64 */
+ 
+-DEF_HELPER_1(mtc0_index, void, tl)
+-DEF_HELPER_1(mtc0_mvpcontrol, void, tl)
+-DEF_HELPER_1(mtc0_vpecontrol, void, tl)
+-DEF_HELPER_1(mttc0_vpecontrol, void, tl)
+-DEF_HELPER_1(mtc0_vpeconf0, void, tl)
+-DEF_HELPER_1(mttc0_vpeconf0, void, tl)
+-DEF_HELPER_1(mtc0_vpeconf1, void, tl)
+-DEF_HELPER_1(mtc0_yqmask, void, tl)
+-DEF_HELPER_1(mtc0_vpeopt, void, tl)
+-DEF_HELPER_1(mtc0_entrylo0, void, tl)
+-DEF_HELPER_1(mtc0_tcstatus, void, tl)
+-DEF_HELPER_1(mttc0_tcstatus, void, tl)
+-DEF_HELPER_1(mtc0_tcbind, void, tl)
+-DEF_HELPER_1(mttc0_tcbind, void, tl)
+-DEF_HELPER_1(mtc0_tcrestart, void, tl)
+-DEF_HELPER_1(mttc0_tcrestart, void, tl)
+-DEF_HELPER_1(mtc0_tchalt, void, tl)
+-DEF_HELPER_1(mttc0_tchalt, void, tl)
+-DEF_HELPER_1(mtc0_tccontext, void, tl)
+-DEF_HELPER_1(mttc0_tccontext, void, tl)
+-DEF_HELPER_1(mtc0_tcschedule, void, tl)
+-DEF_HELPER_1(mttc0_tcschedule, void, tl)
+-DEF_HELPER_1(mtc0_tcschefback, void, tl)
+-DEF_HELPER_1(mttc0_tcschefback, void, tl)
+-DEF_HELPER_1(mtc0_entrylo1, void, tl)
+-DEF_HELPER_1(mtc0_context, void, tl)
+-DEF_HELPER_1(mtc0_pagemask, void, tl)
+-DEF_HELPER_1(mtc0_pagegrain, void, tl)
+-DEF_HELPER_1(mtc0_wired, void, tl)
+-DEF_HELPER_1(mtc0_srsconf0, void, tl)
+-DEF_HELPER_1(mtc0_srsconf1, void, tl)
+-DEF_HELPER_1(mtc0_srsconf2, void, tl)
+-DEF_HELPER_1(mtc0_srsconf3, void, tl)
+-DEF_HELPER_1(mtc0_srsconf4, void, tl)
+-DEF_HELPER_1(mtc0_hwrena, void, tl)
+-DEF_HELPER_1(mtc0_count, void, tl)
+-DEF_HELPER_1(mtc0_entryhi, void, tl)
+-DEF_HELPER_1(mttc0_entryhi, void, tl)
+-DEF_HELPER_1(mtc0_compare, void, tl)
+-DEF_HELPER_1(mtc0_status, void, tl)
+-DEF_HELPER_1(mttc0_status, void, tl)
+-DEF_HELPER_1(mtc0_intctl, void, tl)
+-DEF_HELPER_1(mtc0_srsctl, void, tl)
+-DEF_HELPER_1(mtc0_cause, void, tl)
+-DEF_HELPER_1(mttc0_cause, void, tl)
+-DEF_HELPER_1(mtc0_ebase, void, tl)
+-DEF_HELPER_1(mttc0_ebase, void, tl)
+-DEF_HELPER_1(mtc0_config0, void, tl)
+-DEF_HELPER_1(mtc0_config2, void, tl)
+-DEF_HELPER_1(mtc0_lladdr, void, tl)
+-DEF_HELPER_2(mtc0_watchlo, void, tl, i32)
+-DEF_HELPER_2(mtc0_watchhi, void, tl, i32)
+-DEF_HELPER_1(mtc0_xcontext, void, tl)
+-DEF_HELPER_1(mtc0_framemask, void, tl)
+-DEF_HELPER_1(mtc0_debug, void, tl)
+-DEF_HELPER_1(mttc0_debug, void, tl)
+-DEF_HELPER_1(mtc0_performance0, void, tl)
+-DEF_HELPER_1(mtc0_taglo, void, tl)
+-DEF_HELPER_1(mtc0_datalo, void, tl)
+-DEF_HELPER_1(mtc0_taghi, void, tl)
+-DEF_HELPER_1(mtc0_datahi, void, tl)
++DEF_HELPER_2(mtc0_index, void, env, tl)
++DEF_HELPER_2(mtc0_mvpcontrol, void, env, tl)
++DEF_HELPER_2(mtc0_vpecontrol, void, env, tl)
++DEF_HELPER_2(mttc0_vpecontrol, void, env, tl)
++DEF_HELPER_2(mtc0_vpeconf0, void, env, tl)
++DEF_HELPER_2(mttc0_vpeconf0, void, env, tl)
++DEF_HELPER_2(mtc0_vpeconf1, void, env, tl)
++DEF_HELPER_2(mtc0_yqmask, void, env, tl)
++DEF_HELPER_2(mtc0_vpeopt, void, env, tl)
++DEF_HELPER_2(mtc0_entrylo0, void, env, tl)
++DEF_HELPER_2(mtc0_tcstatus, void, env, tl)
++DEF_HELPER_2(mttc0_tcstatus, void, env, tl)
++DEF_HELPER_2(mtc0_tcbind, void, env, tl)
++DEF_HELPER_2(mttc0_tcbind, void, env, tl)
++DEF_HELPER_2(mtc0_tcrestart, void, env, tl)
++DEF_HELPER_2(mttc0_tcrestart, void, env, tl)
++DEF_HELPER_2(mtc0_tchalt, void, env, tl)
++DEF_HELPER_2(mttc0_tchalt, void, env, tl)
++DEF_HELPER_2(mtc0_tccontext, void, env, tl)
++DEF_HELPER_2(mttc0_tccontext, void, env, tl)
++DEF_HELPER_2(mtc0_tcschedule, void, env, tl)
++DEF_HELPER_2(mttc0_tcschedule, void, env, tl)
++DEF_HELPER_2(mtc0_tcschefback, void, env, tl)
++DEF_HELPER_2(mttc0_tcschefback, void, env, tl)
++DEF_HELPER_2(mtc0_entrylo1, void, env, tl)
++DEF_HELPER_2(mtc0_context, void, env, tl)
++DEF_HELPER_2(mtc0_pagemask, void, env, tl)
++DEF_HELPER_2(mtc0_pagegrain, void, env, tl)
++DEF_HELPER_2(mtc0_wired, void, env, tl)
++DEF_HELPER_2(mtc0_srsconf0, void, env, tl)
++DEF_HELPER_2(mtc0_srsconf1, void, env, tl)
++DEF_HELPER_2(mtc0_srsconf2, void, env, tl)
++DEF_HELPER_2(mtc0_srsconf3, void, env, tl)
++DEF_HELPER_2(mtc0_srsconf4, void, env, tl)
++DEF_HELPER_2(mtc0_hwrena, void, env, tl)
++DEF_HELPER_2(mtc0_count, void, env, tl)
++DEF_HELPER_2(mtc0_entryhi, void, env, tl)
++DEF_HELPER_2(mttc0_entryhi, void, env, tl)
++DEF_HELPER_2(mtc0_compare, void, env, tl)
++DEF_HELPER_2(mtc0_status, void, env, tl)
++DEF_HELPER_2(mttc0_status, void, env, tl)
++DEF_HELPER_2(mtc0_intctl, void, env, tl)
++DEF_HELPER_2(mtc0_srsctl, void, env, tl)
++DEF_HELPER_2(mtc0_cause, void, env, tl)
++DEF_HELPER_2(mttc0_cause, void, env, tl)
++DEF_HELPER_2(mtc0_ebase, void, env, tl)
++DEF_HELPER_2(mttc0_ebase, void, env, tl)
++DEF_HELPER_2(mtc0_config0, void, env, tl)
++DEF_HELPER_2(mtc0_config2, void, env, tl)
++DEF_HELPER_2(mtc0_lladdr, void, env, tl)
++DEF_HELPER_3(mtc0_watchlo, void, env, tl, i32)
++DEF_HELPER_3(mtc0_watchhi, void, env, tl, i32)
++DEF_HELPER_2(mtc0_xcontext, void, env, tl)
++DEF_HELPER_2(mtc0_framemask, void, env, tl)
++DEF_HELPER_2(mtc0_debug, void, env, tl)
++DEF_HELPER_2(mttc0_debug, void, env, tl)
++DEF_HELPER_2(mtc0_performance0, void, env, tl)
++DEF_HELPER_2(mtc0_taglo, void, env, tl)
++DEF_HELPER_2(mtc0_datalo, void, env, tl)
++DEF_HELPER_2(mtc0_taghi, void, env, tl)
++DEF_HELPER_2(mtc0_datahi, void, env, tl)
+ 
+ /* MIPS MT functions */
+-DEF_HELPER_1(mftgpr, tl, i32);
+-DEF_HELPER_1(mftlo, tl, i32)
+-DEF_HELPER_1(mfthi, tl, i32)
+-DEF_HELPER_1(mftacx, tl, i32)
+-DEF_HELPER_0(mftdsp, tl)
+-DEF_HELPER_2(mttgpr, void, tl, i32)
+-DEF_HELPER_2(mttlo, void, tl, i32)
+-DEF_HELPER_2(mtthi, void, tl, i32)
+-DEF_HELPER_2(mttacx, void, tl, i32)
+-DEF_HELPER_1(mttdsp, void, tl)
++DEF_HELPER_2(mftgpr, tl, env, i32);
++DEF_HELPER_2(mftlo, tl, env, i32)
++DEF_HELPER_2(mfthi, tl, env, i32)
++DEF_HELPER_2(mftacx, tl, env, i32)
++DEF_HELPER_1(mftdsp, tl, env)
++DEF_HELPER_3(mttgpr, void, env, tl, i32)
++DEF_HELPER_3(mttlo, void, env, tl, i32)
++DEF_HELPER_3(mtthi, void, env, tl, i32)
++DEF_HELPER_3(mttacx, void, env, tl, i32)
++DEF_HELPER_2(mttdsp, void, env, tl)
+ DEF_HELPER_0(dmt, tl)
+ DEF_HELPER_0(emt, tl)
+-DEF_HELPER_0(dvpe, tl)
+-DEF_HELPER_0(evpe, tl)
++DEF_HELPER_1(dvpe, tl, env)
++DEF_HELPER_1(evpe, tl, env)
+ #endif /* !CONFIG_USER_ONLY */
+ 
+ /* microMIPS functions */
+-DEF_HELPER_3(lwm, void, tl, tl, i32);
+-DEF_HELPER_3(swm, void, tl, tl, i32);
++DEF_HELPER_4(lwm, void, env, tl, tl, i32);
++DEF_HELPER_4(swm, void, env, tl, tl, i32);
+ #ifdef TARGET_MIPS64
+-DEF_HELPER_3(ldm, void, tl, tl, i32);
+-DEF_HELPER_3(sdm, void, tl, tl, i32);
++DEF_HELPER_4(ldm, void, env, tl, tl, i32);
++DEF_HELPER_4(sdm, void, env, tl, tl, i32);
+ #endif
+ 
+ DEF_HELPER_2(fork, void, tl, tl)
+-DEF_HELPER_1(yield, tl, tl)
++DEF_HELPER_2(yield, tl, env, tl)
+ 
+ /* CP1 functions */
+-DEF_HELPER_1(cfc1, tl, i32)
+-DEF_HELPER_2(ctc1, void, tl, i32)
++DEF_HELPER_2(cfc1, tl, env, i32)
++DEF_HELPER_3(ctc1, void, env, tl, i32)
+ 
+-DEF_HELPER_1(float_cvtd_s, i64, i32)
+-DEF_HELPER_1(float_cvtd_w, i64, i32)
+-DEF_HELPER_1(float_cvtd_l, i64, i64)
+-DEF_HELPER_1(float_cvtl_d, i64, i64)
+-DEF_HELPER_1(float_cvtl_s, i64, i32)
+-DEF_HELPER_1(float_cvtps_pw, i64, i64)
+-DEF_HELPER_1(float_cvtpw_ps, i64, i64)
+-DEF_HELPER_1(float_cvts_d, i32, i64)
+-DEF_HELPER_1(float_cvts_w, i32, i32)
+-DEF_HELPER_1(float_cvts_l, i32, i64)
+-DEF_HELPER_1(float_cvts_pl, i32, i32)
+-DEF_HELPER_1(float_cvts_pu, i32, i32)
+-DEF_HELPER_1(float_cvtw_s, i32, i32)
+-DEF_HELPER_1(float_cvtw_d, i32, i64)
++DEF_HELPER_2(float_cvtd_s, i64, env, i32)
++DEF_HELPER_2(float_cvtd_w, i64, env, i32)
++DEF_HELPER_2(float_cvtd_l, i64, env, i64)
++DEF_HELPER_2(float_cvtl_d, i64, env, i64)
++DEF_HELPER_2(float_cvtl_s, i64, env, i32)
++DEF_HELPER_2(float_cvtps_pw, i64, env, i64)
++DEF_HELPER_2(float_cvtpw_ps, i64, env, i64)
++DEF_HELPER_2(float_cvts_d, i32, env, i64)
++DEF_HELPER_2(float_cvts_w, i32, env, i32)
++DEF_HELPER_2(float_cvts_l, i32, env, i64)
++DEF_HELPER_2(float_cvts_pl, i32, env, i32)
++DEF_HELPER_2(float_cvts_pu, i32, env, i32)
++DEF_HELPER_2(float_cvtw_s, i32, env, i32)
++DEF_HELPER_2(float_cvtw_d, i32, env, i64)
+ 
+-DEF_HELPER_2(float_addr_ps, i64, i64, i64)
+-DEF_HELPER_2(float_mulr_ps, i64, i64, i64)
++DEF_HELPER_3(float_addr_ps, i64, env, i64, i64)
++DEF_HELPER_3(float_mulr_ps, i64, env, i64, i64)
+ 
+-#define FOP_PROTO(op)                       \
+-DEF_HELPER_1(float_ ## op ## l_s, i64, i32) \
+-DEF_HELPER_1(float_ ## op ## l_d, i64, i64) \
+-DEF_HELPER_1(float_ ## op ## w_s, i32, i32) \
+-DEF_HELPER_1(float_ ## op ## w_d, i32, i64)
++#define FOP_PROTO(op)                            \
++DEF_HELPER_2(float_ ## op ## l_s, i64, env, i32) \
++DEF_HELPER_2(float_ ## op ## l_d, i64, env, i64) \
++DEF_HELPER_2(float_ ## op ## w_s, i32, env, i32) \
++DEF_HELPER_2(float_ ## op ## w_d, i32, env, i64)
+ FOP_PROTO(round)
+ FOP_PROTO(trunc)
+ FOP_PROTO(ceil)
+ FOP_PROTO(floor)
+ #undef FOP_PROTO
+ 
+-#define FOP_PROTO(op)                       \
+-DEF_HELPER_1(float_ ## op ## _s, i32, i32)  \
+-DEF_HELPER_1(float_ ## op ## _d, i64, i64)
++#define FOP_PROTO(op)                            \
++DEF_HELPER_2(float_ ## op ## _s, i32, env, i32)  \
++DEF_HELPER_2(float_ ## op ## _d, i64, env, i64)
+ FOP_PROTO(sqrt)
+ FOP_PROTO(rsqrt)
+ FOP_PROTO(recip)
+@@ -228,14 +228,20 @@ DEF_HELPER_1(float_ ## op ## _d, i64, i64)  \
+ DEF_HELPER_1(float_ ## op ## _ps, i64, i64)
+ FOP_PROTO(abs)
+ FOP_PROTO(chs)
++#undef FOP_PROTO
++
++#define FOP_PROTO(op)                            \
++DEF_HELPER_2(float_ ## op ## _s, i32, env, i32)  \
++DEF_HELPER_2(float_ ## op ## _d, i64, env, i64)  \
++DEF_HELPER_2(float_ ## op ## _ps, i64, env, i64)
+ FOP_PROTO(recip1)
+ FOP_PROTO(rsqrt1)
+ #undef FOP_PROTO
+ 
+-#define FOP_PROTO(op)                             \
+-DEF_HELPER_2(float_ ## op ## _s, i32, i32, i32)   \
+-DEF_HELPER_2(float_ ## op ## _d, i64, i64, i64)   \
+-DEF_HELPER_2(float_ ## op ## _ps, i64, i64, i64)
++#define FOP_PROTO(op)                                  \
++DEF_HELPER_3(float_ ## op ## _s, i32, env, i32, i32)   \
++DEF_HELPER_3(float_ ## op ## _d, i64, env, i64, i64)   \
++DEF_HELPER_3(float_ ## op ## _ps, i64, env, i64, i64)
+ FOP_PROTO(add)
+ FOP_PROTO(sub)
+ FOP_PROTO(mul)
+@@ -244,23 +250,23 @@ FOP_PROTO(recip2)
+ FOP_PROTO(rsqrt2)
+ #undef FOP_PROTO
+ 
+-#define FOP_PROTO(op)                                 \
+-DEF_HELPER_3(float_ ## op ## _s, i32, i32, i32, i32)  \
+-DEF_HELPER_3(float_ ## op ## _d, i64, i64, i64, i64)  \
+-DEF_HELPER_3(float_ ## op ## _ps, i64, i64, i64, i64)
++#define FOP_PROTO(op)                                      \
++DEF_HELPER_4(float_ ## op ## _s, i32, env, i32, i32, i32)  \
++DEF_HELPER_4(float_ ## op ## _d, i64, env, i64, i64, i64)  \
++DEF_HELPER_4(float_ ## op ## _ps, i64, env, i64, i64, i64)
+ FOP_PROTO(muladd)
+ FOP_PROTO(mulsub)
+ FOP_PROTO(nmuladd)
+ FOP_PROTO(nmulsub)
+ #undef FOP_PROTO
+ 
+-#define FOP_PROTO(op)                               \
+-DEF_HELPER_3(cmp_d_ ## op, void, i64, i64, int)     \
+-DEF_HELPER_3(cmpabs_d_ ## op, void, i64, i64, int)  \
+-DEF_HELPER_3(cmp_s_ ## op, void, i32, i32, int)     \
+-DEF_HELPER_3(cmpabs_s_ ## op, void, i32, i32, int)  \
+-DEF_HELPER_3(cmp_ps_ ## op, void, i64, i64, int)    \
+-DEF_HELPER_3(cmpabs_ps_ ## op, void, i64, i64, int)
++#define FOP_PROTO(op)                                    \
++DEF_HELPER_4(cmp_d_ ## op, void, env, i64, i64, int)     \
++DEF_HELPER_4(cmpabs_d_ ## op, void, env, i64, i64, int)  \
++DEF_HELPER_4(cmp_s_ ## op, void, env, i32, i32, int)     \
++DEF_HELPER_4(cmpabs_s_ ## op, void, env, i32, i32, int)  \
++DEF_HELPER_4(cmp_ps_ ## op, void, env, i64, i64, int)    \
++DEF_HELPER_4(cmpabs_ps_ ## op, void, env, i64, i64, int)
+ FOP_PROTO(f)
+ FOP_PROTO(un)
+ FOP_PROTO(eq)
+@@ -281,20 +287,20 @@ FOP_PROTO(ngt)
+ 
+ /* Special functions */
+ #ifndef CONFIG_USER_ONLY
+-DEF_HELPER_0(tlbwi, void)
+-DEF_HELPER_0(tlbwr, void)
+-DEF_HELPER_0(tlbp, void)
+-DEF_HELPER_0(tlbr, void)
+-DEF_HELPER_0(di, tl)
+-DEF_HELPER_0(ei, tl)
+-DEF_HELPER_0(eret, void)
+-DEF_HELPER_0(deret, void)
++DEF_HELPER_1(tlbwi, void, env)
++DEF_HELPER_1(tlbwr, void, env)
++DEF_HELPER_1(tlbp, void, env)
++DEF_HELPER_1(tlbr, void, env)
++DEF_HELPER_1(di, tl, env)
++DEF_HELPER_1(ei, tl, env)
++DEF_HELPER_1(eret, void, env)
++DEF_HELPER_1(deret, void, env)
+ #endif /* !CONFIG_USER_ONLY */
+-DEF_HELPER_0(rdhwr_cpunum, tl)
+-DEF_HELPER_0(rdhwr_synci_step, tl)
+-DEF_HELPER_0(rdhwr_cc, tl)
+-DEF_HELPER_0(rdhwr_ccres, tl)
+-DEF_HELPER_1(pmon, void, int)
+-DEF_HELPER_0(wait, void)
++DEF_HELPER_1(rdhwr_cpunum, tl, env)
++DEF_HELPER_1(rdhwr_synci_step, tl, env)
++DEF_HELPER_1(rdhwr_cc, tl, env)
++DEF_HELPER_1(rdhwr_ccres, tl, env)
++DEF_HELPER_2(pmon, void, env, int)
++DEF_HELPER_1(wait, void, env)
+ 
+ #include "def-helper.h"
+diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
+index e5bc93e..d2a8a55 100644
+--- a/target-mips/op_helper.c
++++ b/target-mips/op_helper.c
+@@ -18,8 +18,6 @@
+  */
+ #include <stdlib.h>
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+-
+ #include "host-utils.h"
+ 
+ #include "helper.h"
+@@ -84,7 +82,8 @@ static inline void compute_hflags(CPUMIPSState *env)
+ /*****************************************************************************/
+ /* Exceptions processing helpers */
+ 
+-void helper_raise_exception_err (uint32_t exception, int error_code)
++void helper_raise_exception_err(CPUMIPSState *env, uint32_t exception,
++                                int error_code)
+ {
+ #if 1
+     if (exception < 0x100)
+@@ -95,13 +94,13 @@ void helper_raise_exception_err (uint32_t exception, int error_code)
+     cpu_loop_exit(env);
+ }
+ 
+-void helper_raise_exception (uint32_t exception)
++void helper_raise_exception(CPUMIPSState *env, uint32_t exception)
+ {
+-    helper_raise_exception_err(exception, 0);
++    helper_raise_exception_err(env, exception, 0);
+ }
+ 
+ #if !defined(CONFIG_USER_ONLY)
+-static void do_restore_state(uintptr_t pc)
++static void do_restore_state(CPUMIPSState *env, uintptr_t pc)
+ {
+     TranslationBlock *tb;
+ 
+@@ -114,20 +113,22 @@ static void do_restore_state(uintptr_t pc)
+ 
+ #if defined(CONFIG_USER_ONLY)
+ #define HELPER_LD(name, insn, type)                                     \
+-static inline type do_##name(target_ulong addr, int mem_idx)            \
++static inline type do_##name(CPUMIPSState *env, target_ulong addr,      \
++                             int mem_idx)                               \
+ {                                                                       \
+     return (type) insn##_raw(addr);                                     \
+ }
+ #else
+ #define HELPER_LD(name, insn, type)                                     \
+-static inline type do_##name(target_ulong addr, int mem_idx)            \
++static inline type do_##name(CPUMIPSState *env, target_ulong addr,      \
++                             int mem_idx)                               \
+ {                                                                       \
+     switch (mem_idx)                                                    \
+     {                                                                   \
+-    case 0: return (type) insn##_kernel(addr); break;                   \
+-    case 1: return (type) insn##_super(addr); break;                    \
++    case 0: return (type) cpu_##insn##_kernel(env, addr); break;        \
++    case 1: return (type) cpu_##insn##_super(env, addr); break;         \
+     default:                                                            \
+-    case 2: return (type) insn##_user(addr); break;                     \
++    case 2: return (type) cpu_##insn##_user(env, addr); break;          \
+     }                                                                   \
+ }
+ #endif
+@@ -140,20 +141,22 @@ HELPER_LD(ld, ldq, int64_t)
+ 
+ #if defined(CONFIG_USER_ONLY)
+ #define HELPER_ST(name, insn, type)                                     \
+-static inline void do_##name(target_ulong addr, type val, int mem_idx)  \
++static inline void do_##name(CPUMIPSState *env, target_ulong addr,      \
++                             type val, int mem_idx)                     \
+ {                                                                       \
+     insn##_raw(addr, val);                                              \
+ }
+ #else
+ #define HELPER_ST(name, insn, type)                                     \
+-static inline void do_##name(target_ulong addr, type val, int mem_idx)  \
++static inline void do_##name(CPUMIPSState *env, target_ulong addr,      \
++                             type val, int mem_idx)                     \
+ {                                                                       \
+     switch (mem_idx)                                                    \
+     {                                                                   \
+-    case 0: insn##_kernel(addr, val); break;                            \
+-    case 1: insn##_super(addr, val); break;                             \
++    case 0: cpu_##insn##_kernel(env, addr, val); break;                 \
++    case 1: cpu_##insn##_super(env, addr, val); break;                  \
+     default:                                                            \
+-    case 2: insn##_user(addr, val); break;                              \
++    case 2: cpu_##insn##_user(env, addr, val); break;                   \
+     }                                                                   \
+ }
+ #endif
+@@ -187,12 +190,12 @@ target_ulong helper_dclz (target_ulong arg1)
+ #endif /* TARGET_MIPS64 */
+ 
+ /* 64 bits arithmetic for 32 bits hosts */
+-static inline uint64_t get_HILO (void)
++static inline uint64_t get_HILO(CPUMIPSState *env)
+ {
+     return ((uint64_t)(env->active_tc.HI[0]) << 32) | (uint32_t)env->active_tc.LO[0];
+ }
+ 
+-static inline target_ulong set_HIT0_LO(uint64_t HILO)
++static inline target_ulong set_HIT0_LO(CPUMIPSState *env, uint64_t HILO)
+ {
+     target_ulong tmp;
+     env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
+@@ -200,7 +203,7 @@ static inline target_ulong set_HIT0_LO(uint64_t HILO)
+     return tmp;
+ }
+ 
+-static inline target_ulong set_HI_LOT0(uint64_t HILO)
++static inline target_ulong set_HI_LOT0(CPUMIPSState *env, uint64_t HILO)
+ {
+     target_ulong tmp = env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);
+     env->active_tc.HI[0] = (int32_t)(HILO >> 32);
+@@ -208,91 +211,110 @@ static inline target_ulong set_HI_LOT0(uint64_t HILO)
+ }
+ 
+ /* Multiplication variants of the vr54xx. */
+-target_ulong helper_muls (target_ulong arg1, target_ulong arg2)
++target_ulong helper_muls(CPUMIPSState *env, target_ulong arg1,
++                         target_ulong arg2)
+ {
+-    return set_HI_LOT0(0 - ((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2));
++    return set_HI_LOT0(env, 0 - ((int64_t)(int32_t)arg1 *
++                                 (int64_t)(int32_t)arg2));
+ }
+ 
+-target_ulong helper_mulsu (target_ulong arg1, target_ulong arg2)
++target_ulong helper_mulsu(CPUMIPSState *env, target_ulong arg1,
++                          target_ulong arg2)
+ {
+-    return set_HI_LOT0(0 - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
++    return set_HI_LOT0(env, 0 - (uint64_t)(uint32_t)arg1 *
++                       (uint64_t)(uint32_t)arg2);
+ }
+ 
+-target_ulong helper_macc (target_ulong arg1, target_ulong arg2)
++target_ulong helper_macc(CPUMIPSState *env, target_ulong arg1,
++                         target_ulong arg2)
+ {
+-    return set_HI_LOT0((int64_t)get_HILO() + (int64_t)(int32_t)arg1 *
+-                                             (int64_t)(int32_t)arg2);
++    return set_HI_LOT0(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 *
++                       (int64_t)(int32_t)arg2);
+ }
+ 
+-target_ulong helper_macchi (target_ulong arg1, target_ulong arg2)
++target_ulong helper_macchi(CPUMIPSState *env, target_ulong arg1,
++                           target_ulong arg2)
+ {
+-    return set_HIT0_LO((int64_t)get_HILO() + (int64_t)(int32_t)arg1 *
+-                                             (int64_t)(int32_t)arg2);
++    return set_HIT0_LO(env, (int64_t)get_HILO(env) + (int64_t)(int32_t)arg1 *
++                       (int64_t)(int32_t)arg2);
+ }
+ 
+-target_ulong helper_maccu (target_ulong arg1, target_ulong arg2)
++target_ulong helper_maccu(CPUMIPSState *env, target_ulong arg1,
++                          target_ulong arg2)
+ {
+-    return set_HI_LOT0((uint64_t)get_HILO() + (uint64_t)(uint32_t)arg1 *
+-                                              (uint64_t)(uint32_t)arg2);
++    return set_HI_LOT0(env, (uint64_t)get_HILO(env) +
++                       (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
+ }
+ 
+-target_ulong helper_macchiu (target_ulong arg1, target_ulong arg2)
++target_ulong helper_macchiu(CPUMIPSState *env, target_ulong arg1,
++                            target_ulong arg2)
+ {
+-    return set_HIT0_LO((uint64_t)get_HILO() + (uint64_t)(uint32_t)arg1 *
+-                                              (uint64_t)(uint32_t)arg2);
++    return set_HIT0_LO(env, (uint64_t)get_HILO(env) +
++                       (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
+ }
+ 
+-target_ulong helper_msac (target_ulong arg1, target_ulong arg2)
++target_ulong helper_msac(CPUMIPSState *env, target_ulong arg1,
++                         target_ulong arg2)
+ {
+-    return set_HI_LOT0((int64_t)get_HILO() - (int64_t)(int32_t)arg1 *
+-                                             (int64_t)(int32_t)arg2);
++    return set_HI_LOT0(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 *
++                       (int64_t)(int32_t)arg2);
+ }
+ 
+-target_ulong helper_msachi (target_ulong arg1, target_ulong arg2)
++target_ulong helper_msachi(CPUMIPSState *env, target_ulong arg1,
++                           target_ulong arg2)
+ {
+-    return set_HIT0_LO((int64_t)get_HILO() - (int64_t)(int32_t)arg1 *
+-                                             (int64_t)(int32_t)arg2);
++    return set_HIT0_LO(env, (int64_t)get_HILO(env) - (int64_t)(int32_t)arg1 *
++                       (int64_t)(int32_t)arg2);
+ }
+ 
+-target_ulong helper_msacu (target_ulong arg1, target_ulong arg2)
++target_ulong helper_msacu(CPUMIPSState *env, target_ulong arg1,
++                          target_ulong arg2)
+ {
+-    return set_HI_LOT0((uint64_t)get_HILO() - (uint64_t)(uint32_t)arg1 *
+-                                              (uint64_t)(uint32_t)arg2);
++    return set_HI_LOT0(env, (uint64_t)get_HILO(env) -
++                       (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
+ }
+ 
+-target_ulong helper_msachiu (target_ulong arg1, target_ulong arg2)
++target_ulong helper_msachiu(CPUMIPSState *env, target_ulong arg1,
++                            target_ulong arg2)
+ {
+-    return set_HIT0_LO((uint64_t)get_HILO() - (uint64_t)(uint32_t)arg1 *
+-                                              (uint64_t)(uint32_t)arg2);
++    return set_HIT0_LO(env, (uint64_t)get_HILO(env) -
++                       (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
+ }
+ 
+-target_ulong helper_mulhi (target_ulong arg1, target_ulong arg2)
++target_ulong helper_mulhi(CPUMIPSState *env, target_ulong arg1,
++                          target_ulong arg2)
+ {
+-    return set_HIT0_LO((int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2);
++    return set_HIT0_LO(env, (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2);
+ }
+ 
+-target_ulong helper_mulhiu (target_ulong arg1, target_ulong arg2)
++target_ulong helper_mulhiu(CPUMIPSState *env, target_ulong arg1,
++                           target_ulong arg2)
+ {
+-    return set_HIT0_LO((uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
++    return set_HIT0_LO(env, (uint64_t)(uint32_t)arg1 *
++                       (uint64_t)(uint32_t)arg2);
+ }
+ 
+-target_ulong helper_mulshi (target_ulong arg1, target_ulong arg2)
++target_ulong helper_mulshi(CPUMIPSState *env, target_ulong arg1,
++                           target_ulong arg2)
+ {
+-    return set_HIT0_LO(0 - (int64_t)(int32_t)arg1 * (int64_t)(int32_t)arg2);
++    return set_HIT0_LO(env, 0 - (int64_t)(int32_t)arg1 *
++                       (int64_t)(int32_t)arg2);
+ }
+ 
+-target_ulong helper_mulshiu (target_ulong arg1, target_ulong arg2)
++target_ulong helper_mulshiu(CPUMIPSState *env, target_ulong arg1,
++                            target_ulong arg2)
+ {
+-    return set_HIT0_LO(0 - (uint64_t)(uint32_t)arg1 * (uint64_t)(uint32_t)arg2);
++    return set_HIT0_LO(env, 0 - (uint64_t)(uint32_t)arg1 *
++                       (uint64_t)(uint32_t)arg2);
+ }
+ 
+ #ifdef TARGET_MIPS64
+-void helper_dmult (target_ulong arg1, target_ulong arg2)
++void helper_dmult(CPUMIPSState *env, target_ulong arg1, target_ulong arg2)
+ {
+     muls64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), arg1, arg2);
+ }
+ 
+-void helper_dmultu (target_ulong arg1, target_ulong arg2)
++void helper_dmultu(CPUMIPSState *env, target_ulong arg1, target_ulong arg2)
+ {
+     mulu64(&(env->active_tc.LO[0]), &(env->active_tc.HI[0]), arg1, arg2);
+ }
+@@ -300,7 +322,9 @@ void helper_dmultu (target_ulong arg1, target_ulong arg2)
+ 
+ #ifndef CONFIG_USER_ONLY
+ 
+-static inline target_phys_addr_t do_translate_address(target_ulong address, int rw)
++static inline target_phys_addr_t do_translate_address(CPUMIPSState *env,
++                                                      target_ulong address,
++                                                      int rw)
+ {
+     target_phys_addr_t lladdr;
+ 
+@@ -314,10 +338,10 @@ static inline target_phys_addr_t do_translate_address(target_ulong address, int
+ }
+ 
+ #define HELPER_LD_ATOMIC(name, insn)                                          \
+-target_ulong helper_##name(target_ulong arg, int mem_idx)                     \
++target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx)  \
+ {                                                                             \
+-    env->lladdr = do_translate_address(arg, 0);                               \
+-    env->llval = do_##insn(arg, mem_idx);                                     \
++    env->lladdr = do_translate_address(env, arg, 0);                          \
++    env->llval = do_##insn(env, arg, mem_idx);                                \
+     return env->llval;                                                        \
+ }
+ HELPER_LD_ATOMIC(ll, lw)
+@@ -327,18 +351,19 @@ HELPER_LD_ATOMIC(lld, ld)
+ #undef HELPER_LD_ATOMIC
+ 
+ #define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask)                      \
+-target_ulong helper_##name(target_ulong arg1, target_ulong arg2, int mem_idx) \
++target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1,              \
++                           target_ulong arg2, int mem_idx)                    \
+ {                                                                             \
+     target_long tmp;                                                          \
+                                                                               \
+     if (arg2 & almask) {                                                      \
+         env->CP0_BadVAddr = arg2;                                             \
+-        helper_raise_exception(EXCP_AdES);                                    \
++        helper_raise_exception(env, EXCP_AdES);                               \
+     }                                                                         \
+-    if (do_translate_address(arg2, 1) == env->lladdr) {                       \
+-        tmp = do_##ld_insn(arg2, mem_idx);                                    \
++    if (do_translate_address(env, arg2, 1) == env->lladdr) {                  \
++        tmp = do_##ld_insn(env, arg2, mem_idx);                               \
+         if (tmp == env->llval) {                                              \
+-            do_##st_insn(arg2, arg1, mem_idx);                                \
++            do_##st_insn(env, arg2, arg1, mem_idx);                           \
+             return 1;                                                         \
+         }                                                                     \
+     }                                                                         \
+@@ -359,80 +384,84 @@ HELPER_ST_ATOMIC(scd, ld, sd, 0x7)
+ #define GET_OFFSET(addr, offset) (addr - (offset))
+ #endif
+ 
+-target_ulong helper_lwl(target_ulong arg1, target_ulong arg2, int mem_idx)
++target_ulong helper_lwl(CPUMIPSState *env, target_ulong arg1,
++                        target_ulong arg2, int mem_idx)
+ {
+     target_ulong tmp;
+ 
+-    tmp = do_lbu(arg2, mem_idx);
++    tmp = do_lbu(env, arg2, mem_idx);
+     arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);
+ 
+     if (GET_LMASK(arg2) <= 2) {
+-        tmp = do_lbu(GET_OFFSET(arg2, 1), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);
+         arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);
+     }
+ 
+     if (GET_LMASK(arg2) <= 1) {
+-        tmp = do_lbu(GET_OFFSET(arg2, 2), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);
+         arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);
+     }
+ 
+     if (GET_LMASK(arg2) == 0) {
+-        tmp = do_lbu(GET_OFFSET(arg2, 3), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);
+         arg1 = (arg1 & 0xFFFFFF00) | tmp;
+     }
+     return (int32_t)arg1;
+ }
+ 
+-target_ulong helper_lwr(target_ulong arg1, target_ulong arg2, int mem_idx)
++target_ulong helper_lwr(CPUMIPSState *env, target_ulong arg1,
++                        target_ulong arg2, int mem_idx)
+ {
+     target_ulong tmp;
+ 
+-    tmp = do_lbu(arg2, mem_idx);
++    tmp = do_lbu(env, arg2, mem_idx);
+     arg1 = (arg1 & 0xFFFFFF00) | tmp;
+ 
+     if (GET_LMASK(arg2) >= 1) {
+-        tmp = do_lbu(GET_OFFSET(arg2, -1), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, -1), mem_idx);
+         arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);
+     }
+ 
+     if (GET_LMASK(arg2) >= 2) {
+-        tmp = do_lbu(GET_OFFSET(arg2, -2), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, -2), mem_idx);
+         arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);
+     }
+ 
+     if (GET_LMASK(arg2) == 3) {
+-        tmp = do_lbu(GET_OFFSET(arg2, -3), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, -3), mem_idx);
+         arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);
+     }
+     return (int32_t)arg1;
+ }
+ 
+-void helper_swl(target_ulong arg1, target_ulong arg2, int mem_idx)
++void helper_swl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
++                int mem_idx)
+ {
+-    do_sb(arg2, (uint8_t)(arg1 >> 24), mem_idx);
++    do_sb(env, arg2, (uint8_t)(arg1 >> 24), mem_idx);
+ 
+     if (GET_LMASK(arg2) <= 2)
+-        do_sb(GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16), mem_idx);
+ 
+     if (GET_LMASK(arg2) <= 1)
+-        do_sb(GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8), mem_idx);
+ 
+     if (GET_LMASK(arg2) == 0)
+-        do_sb(GET_OFFSET(arg2, 3), (uint8_t)arg1, mem_idx);
++        do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)arg1, mem_idx);
+ }
+ 
+-void helper_swr(target_ulong arg1, target_ulong arg2, int mem_idx)
++void helper_swr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
++                int mem_idx)
+ {
+-    do_sb(arg2, (uint8_t)arg1, mem_idx);
++    do_sb(env, arg2, (uint8_t)arg1, mem_idx);
+ 
+     if (GET_LMASK(arg2) >= 1)
+-        do_sb(GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
+ 
+     if (GET_LMASK(arg2) >= 2)
+-        do_sb(GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
+ 
+     if (GET_LMASK(arg2) == 3)
+-        do_sb(GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
+ }
+ 
+ #if defined(TARGET_MIPS64)
+@@ -445,167 +474,172 @@ void helper_swr(target_ulong arg1, target_ulong arg2, int mem_idx)
+ #define GET_LMASK64(v) (((v) & 7) ^ 7)
+ #endif
+ 
+-target_ulong helper_ldl(target_ulong arg1, target_ulong arg2, int mem_idx)
++target_ulong helper_ldl(CPUMIPSState *env, target_ulong arg1,
++                        target_ulong arg2, int mem_idx)
+ {
+     uint64_t tmp;
+ 
+-    tmp = do_lbu(arg2, mem_idx);
++    tmp = do_lbu(env, arg2, mem_idx);
+     arg1 = (arg1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
+ 
+     if (GET_LMASK64(arg2) <= 6) {
+-        tmp = do_lbu(GET_OFFSET(arg2, 1), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);
+         arg1 = (arg1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
+     }
+ 
+     if (GET_LMASK64(arg2) <= 5) {
+-        tmp = do_lbu(GET_OFFSET(arg2, 2), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);
+         arg1 = (arg1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
+     }
+ 
+     if (GET_LMASK64(arg2) <= 4) {
+-        tmp = do_lbu(GET_OFFSET(arg2, 3), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);
+         arg1 = (arg1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
+     }
+ 
+     if (GET_LMASK64(arg2) <= 3) {
+-        tmp = do_lbu(GET_OFFSET(arg2, 4), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, 4), mem_idx);
+         arg1 = (arg1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
+     }
+ 
+     if (GET_LMASK64(arg2) <= 2) {
+-        tmp = do_lbu(GET_OFFSET(arg2, 5), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, 5), mem_idx);
+         arg1 = (arg1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
+     }
+ 
+     if (GET_LMASK64(arg2) <= 1) {
+-        tmp = do_lbu(GET_OFFSET(arg2, 6), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, 6), mem_idx);
+         arg1 = (arg1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
+     }
+ 
+     if (GET_LMASK64(arg2) == 0) {
+-        tmp = do_lbu(GET_OFFSET(arg2, 7), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, 7), mem_idx);
+         arg1 = (arg1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
+     }
+ 
+     return arg1;
+ }
+ 
+-target_ulong helper_ldr(target_ulong arg1, target_ulong arg2, int mem_idx)
++target_ulong helper_ldr(CPUMIPSState *env, target_ulong arg1,
++                        target_ulong arg2, int mem_idx)
+ {
+     uint64_t tmp;
+ 
+-    tmp = do_lbu(arg2, mem_idx);
++    tmp = do_lbu(env, arg2, mem_idx);
+     arg1 = (arg1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
+ 
+     if (GET_LMASK64(arg2) >= 1) {
+-        tmp = do_lbu(GET_OFFSET(arg2, -1), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, -1), mem_idx);
+         arg1 = (arg1 & 0xFFFFFFFFFFFF00FFULL) | (tmp  << 8);
+     }
+ 
+     if (GET_LMASK64(arg2) >= 2) {
+-        tmp = do_lbu(GET_OFFSET(arg2, -2), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, -2), mem_idx);
+         arg1 = (arg1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
+     }
+ 
+     if (GET_LMASK64(arg2) >= 3) {
+-        tmp = do_lbu(GET_OFFSET(arg2, -3), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, -3), mem_idx);
+         arg1 = (arg1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
+     }
+ 
+     if (GET_LMASK64(arg2) >= 4) {
+-        tmp = do_lbu(GET_OFFSET(arg2, -4), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, -4), mem_idx);
+         arg1 = (arg1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
+     }
+ 
+     if (GET_LMASK64(arg2) >= 5) {
+-        tmp = do_lbu(GET_OFFSET(arg2, -5), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, -5), mem_idx);
+         arg1 = (arg1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
+     }
+ 
+     if (GET_LMASK64(arg2) >= 6) {
+-        tmp = do_lbu(GET_OFFSET(arg2, -6), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, -6), mem_idx);
+         arg1 = (arg1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
+     }
+ 
+     if (GET_LMASK64(arg2) == 7) {
+-        tmp = do_lbu(GET_OFFSET(arg2, -7), mem_idx);
++        tmp = do_lbu(env, GET_OFFSET(arg2, -7), mem_idx);
+         arg1 = (arg1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
+     }
+ 
+     return arg1;
+ }
+ 
+-void helper_sdl(target_ulong arg1, target_ulong arg2, int mem_idx)
++void helper_sdl(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
++                int mem_idx)
+ {
+-    do_sb(arg2, (uint8_t)(arg1 >> 56), mem_idx);
++    do_sb(env, arg2, (uint8_t)(arg1 >> 56), mem_idx);
+ 
+     if (GET_LMASK64(arg2) <= 6)
+-        do_sb(GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48), mem_idx);
+ 
+     if (GET_LMASK64(arg2) <= 5)
+-        do_sb(GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40), mem_idx);
+ 
+     if (GET_LMASK64(arg2) <= 4)
+-        do_sb(GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32), mem_idx);
+ 
+     if (GET_LMASK64(arg2) <= 3)
+-        do_sb(GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24), mem_idx);
+ 
+     if (GET_LMASK64(arg2) <= 2)
+-        do_sb(GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16), mem_idx);
+ 
+     if (GET_LMASK64(arg2) <= 1)
+-        do_sb(GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8), mem_idx);
+ 
+     if (GET_LMASK64(arg2) <= 0)
+-        do_sb(GET_OFFSET(arg2, 7), (uint8_t)arg1, mem_idx);
++        do_sb(env, GET_OFFSET(arg2, 7), (uint8_t)arg1, mem_idx);
+ }
+ 
+-void helper_sdr(target_ulong arg1, target_ulong arg2, int mem_idx)
++void helper_sdr(CPUMIPSState *env, target_ulong arg1, target_ulong arg2,
++                int mem_idx)
+ {
+-    do_sb(arg2, (uint8_t)arg1, mem_idx);
++    do_sb(env, arg2, (uint8_t)arg1, mem_idx);
+ 
+     if (GET_LMASK64(arg2) >= 1)
+-        do_sb(GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
+ 
+     if (GET_LMASK64(arg2) >= 2)
+-        do_sb(GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
+ 
+     if (GET_LMASK64(arg2) >= 3)
+-        do_sb(GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
+ 
+     if (GET_LMASK64(arg2) >= 4)
+-        do_sb(GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32), mem_idx);
+ 
+     if (GET_LMASK64(arg2) >= 5)
+-        do_sb(GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40), mem_idx);
+ 
+     if (GET_LMASK64(arg2) >= 6)
+-        do_sb(GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48), mem_idx);
+ 
+     if (GET_LMASK64(arg2) == 7)
+-        do_sb(GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56), mem_idx);
++        do_sb(env, GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56), mem_idx);
+ }
+ #endif /* TARGET_MIPS64 */
+ 
+ static const int multiple_regs[] = { 16, 17, 18, 19, 20, 21, 22, 23, 30 };
+ 
+-void helper_lwm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
++void helper_lwm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
++                uint32_t mem_idx)
+ {
+     target_ulong base_reglist = reglist & 0xf;
+     target_ulong do_r31 = reglist & 0x10;
+ #ifdef CONFIG_USER_ONLY
+ #undef ldfun
+-#define ldfun ldl_raw
++#define ldfun(env, addr) ldl_raw(addr)
+ #else
+-    uint32_t (*ldfun)(target_ulong);
++    uint32_t (*ldfun)(CPUMIPSState *env, target_ulong);
+ 
+     switch (mem_idx)
+     {
+-    case 0: ldfun = ldl_kernel; break;
+-    case 1: ldfun = ldl_super; break;
++    case 0: ldfun = cpu_ldl_kernel; break;
++    case 1: ldfun = cpu_ldl_super; break;
+     default:
+-    case 2: ldfun = ldl_user; break;
++    case 2: ldfun = cpu_ldl_user; break;
+     }
+ #endif
+ 
+@@ -613,32 +647,33 @@ void helper_lwm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
+         target_ulong i;
+ 
+         for (i = 0; i < base_reglist; i++) {
+-            env->active_tc.gpr[multiple_regs[i]] = (target_long) ldfun(addr);
++            env->active_tc.gpr[multiple_regs[i]] = (target_long)ldfun(env, addr);
+             addr += 4;
+         }
+     }
+ 
+     if (do_r31) {
+-        env->active_tc.gpr[31] = (target_long) ldfun(addr);
++        env->active_tc.gpr[31] = (target_long)ldfun(env, addr);
+     }
+ }
+ 
+-void helper_swm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
++void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
++                uint32_t mem_idx)
+ {
+     target_ulong base_reglist = reglist & 0xf;
+     target_ulong do_r31 = reglist & 0x10;
+ #ifdef CONFIG_USER_ONLY
+ #undef stfun
+-#define stfun stl_raw
++#define stfun(env, addr, val) stl_raw(addr, val)
+ #else
+-    void (*stfun)(target_ulong, uint32_t);
++    void (*stfun)(CPUMIPSState *env, target_ulong, uint32_t);
+ 
+     switch (mem_idx)
+     {
+-    case 0: stfun = stl_kernel; break;
+-    case 1: stfun = stl_super; break;
++    case 0: stfun = cpu_stl_kernel; break;
++    case 1: stfun = cpu_stl_super; break;
+      default:
+-    case 2: stfun = stl_user; break;
++    case 2: stfun = cpu_stl_user; break;
+     }
+ #endif
+ 
+@@ -646,33 +681,34 @@ void helper_swm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
+         target_ulong i;
+ 
+         for (i = 0; i < base_reglist; i++) {
+-            stfun(addr, env->active_tc.gpr[multiple_regs[i]]);
++            stfun(env, addr, env->active_tc.gpr[multiple_regs[i]]);
+             addr += 4;
+         }
+     }
+ 
+     if (do_r31) {
+-        stfun(addr, env->active_tc.gpr[31]);
++        stfun(env, addr, env->active_tc.gpr[31]);
+     }
+ }
+ 
+ #if defined(TARGET_MIPS64)
+-void helper_ldm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
++void helper_ldm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
++                uint32_t mem_idx)
+ {
+     target_ulong base_reglist = reglist & 0xf;
+     target_ulong do_r31 = reglist & 0x10;
+ #ifdef CONFIG_USER_ONLY
+ #undef ldfun
+-#define ldfun ldq_raw
++#define ldfun(env, addr) ldq_raw(addr)
+ #else
+-    uint64_t (*ldfun)(target_ulong);
++    uint64_t (*ldfun)(CPUMIPSState *env, target_ulong);
+ 
+     switch (mem_idx)
+     {
+-    case 0: ldfun = ldq_kernel; break;
+-    case 1: ldfun = ldq_super; break;
++    case 0: ldfun = cpu_ldq_kernel; break;
++    case 1: ldfun = cpu_ldq_super; break;
+     default:
+-    case 2: ldfun = ldq_user; break;
++    case 2: ldfun = cpu_ldq_user; break;
+     }
+ #endif
+ 
+@@ -680,32 +716,33 @@ void helper_ldm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
+         target_ulong i;
+ 
+         for (i = 0; i < base_reglist; i++) {
+-            env->active_tc.gpr[multiple_regs[i]] = ldfun(addr);
++            env->active_tc.gpr[multiple_regs[i]] = ldfun(env, addr);
+             addr += 8;
+         }
+     }
+ 
+     if (do_r31) {
+-        env->active_tc.gpr[31] = ldfun(addr);
++        env->active_tc.gpr[31] = ldfun(env, addr);
+     }
+ }
+ 
+-void helper_sdm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
++void helper_sdm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
++                uint32_t mem_idx)
+ {
+     target_ulong base_reglist = reglist & 0xf;
+     target_ulong do_r31 = reglist & 0x10;
+ #ifdef CONFIG_USER_ONLY
+ #undef stfun
+-#define stfun stq_raw
++#define stfun(env, addr, val) stq_raw(addr, val)
+ #else
+-    void (*stfun)(target_ulong, uint64_t);
++    void (*stfun)(CPUMIPSState *env, target_ulong, uint64_t);
+ 
+     switch (mem_idx)
+     {
+-    case 0: stfun = stq_kernel; break;
+-    case 1: stfun = stq_super; break;
++    case 0: stfun = cpu_stq_kernel; break;
++    case 1: stfun = cpu_stq_super; break;
+      default:
+-    case 2: stfun = stq_user; break;
++    case 2: stfun = cpu_stq_user; break;
+     }
+ #endif
+ 
+@@ -713,13 +750,13 @@ void helper_sdm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
+         target_ulong i;
+ 
+         for (i = 0; i < base_reglist; i++) {
+-            stfun(addr, env->active_tc.gpr[multiple_regs[i]]);
++            stfun(env, addr, env->active_tc.gpr[multiple_regs[i]]);
+             addr += 8;
+         }
+     }
+ 
+     if (do_r31) {
+-        stfun(addr, env->active_tc.gpr[31]);
++        stfun(env, addr, env->active_tc.gpr[31]);
+     }
+ }
+ #endif
+@@ -772,7 +809,7 @@ static inline void mips_tc_sleep(CPUMIPSState *c, int tc)
+    FIXME: This code assumes that all VPEs have the same number of TCs,
+           which depends on runtime setup. Can probably be fixed by
+           walking the list of CPUMIPSStates.  */
+-static CPUMIPSState *mips_cpu_map_tc(int *tc)
++static CPUMIPSState *mips_cpu_map_tc(CPUMIPSState *env, int *tc)
+ {
+     CPUMIPSState *other;
+     int vpe_idx, nr_threads = env->nr_threads;
+@@ -799,7 +836,7 @@ static CPUMIPSState *mips_cpu_map_tc(int *tc)
+    These helper call synchronizes the regs for a given cpu.  */
+ 
+ /* Called for updates to CP0_Status.  */
+-static void sync_c0_status(CPUMIPSState *cpu, int tc)
++static void sync_c0_status(CPUMIPSState *env, CPUMIPSState *cpu, int tc)
+ {
+     int32_t tcstatus, *tcst;
+     uint32_t v = cpu->CP0_Status;
+@@ -834,7 +871,8 @@ static void sync_c0_status(CPUMIPSState *cpu, int tc)
+ }
+ 
+ /* Called for updates to CP0_TCStatus.  */
+-static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc, target_ulong v)
++static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc,
++                             target_ulong v)
+ {
+     uint32_t status;
+     uint32_t tcu, tmx, tasid, tksu;
+@@ -883,35 +921,35 @@ static void sync_c0_entryhi(CPUMIPSState *cpu, int tc)
+ }
+ 
+ /* CP0 helpers */
+-target_ulong helper_mfc0_mvpcontrol (void)
++target_ulong helper_mfc0_mvpcontrol(CPUMIPSState *env)
+ {
+     return env->mvp->CP0_MVPControl;
+ }
+ 
+-target_ulong helper_mfc0_mvpconf0 (void)
++target_ulong helper_mfc0_mvpconf0(CPUMIPSState *env)
+ {
+     return env->mvp->CP0_MVPConf0;
+ }
+ 
+-target_ulong helper_mfc0_mvpconf1 (void)
++target_ulong helper_mfc0_mvpconf1(CPUMIPSState *env)
+ {
+     return env->mvp->CP0_MVPConf1;
+ }
+ 
+-target_ulong helper_mfc0_random (void)
++target_ulong helper_mfc0_random(CPUMIPSState *env)
+ {
+     return (int32_t)cpu_mips_get_random(env);
+ }
+ 
+-target_ulong helper_mfc0_tcstatus (void)
++target_ulong helper_mfc0_tcstatus(CPUMIPSState *env)
+ {
+     return env->active_tc.CP0_TCStatus;
+ }
+ 
+-target_ulong helper_mftc0_tcstatus(void)
++target_ulong helper_mftc0_tcstatus(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.CP0_TCStatus;
+@@ -919,15 +957,15 @@ target_ulong helper_mftc0_tcstatus(void)
+         return other->tcs[other_tc].CP0_TCStatus;
+ }
+ 
+-target_ulong helper_mfc0_tcbind (void)
++target_ulong helper_mfc0_tcbind(CPUMIPSState *env)
+ {
+     return env->active_tc.CP0_TCBind;
+ }
+ 
+-target_ulong helper_mftc0_tcbind(void)
++target_ulong helper_mftc0_tcbind(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.CP0_TCBind;
+@@ -935,15 +973,15 @@ target_ulong helper_mftc0_tcbind(void)
+         return other->tcs[other_tc].CP0_TCBind;
+ }
+ 
+-target_ulong helper_mfc0_tcrestart (void)
++target_ulong helper_mfc0_tcrestart(CPUMIPSState *env)
+ {
+     return env->active_tc.PC;
+ }
+ 
+-target_ulong helper_mftc0_tcrestart(void)
++target_ulong helper_mftc0_tcrestart(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.PC;
+@@ -951,15 +989,15 @@ target_ulong helper_mftc0_tcrestart(void)
+         return other->tcs[other_tc].PC;
+ }
+ 
+-target_ulong helper_mfc0_tchalt (void)
++target_ulong helper_mfc0_tchalt(CPUMIPSState *env)
+ {
+     return env->active_tc.CP0_TCHalt;
+ }
+ 
+-target_ulong helper_mftc0_tchalt(void)
++target_ulong helper_mftc0_tchalt(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.CP0_TCHalt;
+@@ -967,15 +1005,15 @@ target_ulong helper_mftc0_tchalt(void)
+         return other->tcs[other_tc].CP0_TCHalt;
+ }
+ 
+-target_ulong helper_mfc0_tccontext (void)
++target_ulong helper_mfc0_tccontext(CPUMIPSState *env)
+ {
+     return env->active_tc.CP0_TCContext;
+ }
+ 
+-target_ulong helper_mftc0_tccontext(void)
++target_ulong helper_mftc0_tccontext(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.CP0_TCContext;
+@@ -983,15 +1021,15 @@ target_ulong helper_mftc0_tccontext(void)
+         return other->tcs[other_tc].CP0_TCContext;
+ }
+ 
+-target_ulong helper_mfc0_tcschedule (void)
++target_ulong helper_mfc0_tcschedule(CPUMIPSState *env)
+ {
+     return env->active_tc.CP0_TCSchedule;
+ }
+ 
+-target_ulong helper_mftc0_tcschedule(void)
++target_ulong helper_mftc0_tcschedule(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.CP0_TCSchedule;
+@@ -999,15 +1037,15 @@ target_ulong helper_mftc0_tcschedule(void)
+         return other->tcs[other_tc].CP0_TCSchedule;
+ }
+ 
+-target_ulong helper_mfc0_tcschefback (void)
++target_ulong helper_mfc0_tcschefback(CPUMIPSState *env)
+ {
+     return env->active_tc.CP0_TCScheFBack;
+ }
+ 
+-target_ulong helper_mftc0_tcschefback(void)
++target_ulong helper_mftc0_tcschefback(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.CP0_TCScheFBack;
+@@ -1015,24 +1053,24 @@ target_ulong helper_mftc0_tcschefback(void)
+         return other->tcs[other_tc].CP0_TCScheFBack;
+ }
+ 
+-target_ulong helper_mfc0_count (void)
++target_ulong helper_mfc0_count(CPUMIPSState *env)
+ {
+     return (int32_t)cpu_mips_get_count(env);
+ }
+ 
+-target_ulong helper_mftc0_entryhi(void)
++target_ulong helper_mftc0_entryhi(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     return other->CP0_EntryHi;
+ }
+ 
+-target_ulong helper_mftc0_cause(void)
++target_ulong helper_mftc0_cause(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+     int32_t tccause;
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc) {
+         tccause = other->CP0_Cause;
+@@ -1043,30 +1081,30 @@ target_ulong helper_mftc0_cause(void)
+     return tccause;
+ }
+ 
+-target_ulong helper_mftc0_status(void)
++target_ulong helper_mftc0_status(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     return other->CP0_Status;
+ }
+ 
+-target_ulong helper_mfc0_lladdr (void)
++target_ulong helper_mfc0_lladdr(CPUMIPSState *env)
+ {
+     return (int32_t)(env->lladdr >> env->CP0_LLAddr_shift);
+ }
+ 
+-target_ulong helper_mfc0_watchlo (uint32_t sel)
++target_ulong helper_mfc0_watchlo(CPUMIPSState *env, uint32_t sel)
+ {
+     return (int32_t)env->CP0_WatchLo[sel];
+ }
+ 
+-target_ulong helper_mfc0_watchhi (uint32_t sel)
++target_ulong helper_mfc0_watchhi(CPUMIPSState *env, uint32_t sel)
+ {
+     return env->CP0_WatchHi[sel];
+ }
+ 
+-target_ulong helper_mfc0_debug (void)
++target_ulong helper_mfc0_debug(CPUMIPSState *env)
+ {
+     target_ulong t0 = env->CP0_Debug;
+     if (env->hflags & MIPS_HFLAG_DM)
+@@ -1075,11 +1113,11 @@ target_ulong helper_mfc0_debug (void)
+     return t0;
+ }
+ 
+-target_ulong helper_mftc0_debug(void)
++target_ulong helper_mftc0_debug(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+     int32_t tcstatus;
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         tcstatus = other->active_tc.CP0_Debug_tcstatus;
+@@ -1092,43 +1130,43 @@ target_ulong helper_mftc0_debug(void)
+ }
+ 
+ #if defined(TARGET_MIPS64)
+-target_ulong helper_dmfc0_tcrestart (void)
++target_ulong helper_dmfc0_tcrestart(CPUMIPSState *env)
+ {
+     return env->active_tc.PC;
+ }
+ 
+-target_ulong helper_dmfc0_tchalt (void)
++target_ulong helper_dmfc0_tchalt(CPUMIPSState *env)
+ {
+     return env->active_tc.CP0_TCHalt;
+ }
+ 
+-target_ulong helper_dmfc0_tccontext (void)
++target_ulong helper_dmfc0_tccontext(CPUMIPSState *env)
+ {
+     return env->active_tc.CP0_TCContext;
+ }
+ 
+-target_ulong helper_dmfc0_tcschedule (void)
++target_ulong helper_dmfc0_tcschedule(CPUMIPSState *env)
+ {
+     return env->active_tc.CP0_TCSchedule;
+ }
+ 
+-target_ulong helper_dmfc0_tcschefback (void)
++target_ulong helper_dmfc0_tcschefback(CPUMIPSState *env)
+ {
+     return env->active_tc.CP0_TCScheFBack;
+ }
+ 
+-target_ulong helper_dmfc0_lladdr (void)
++target_ulong helper_dmfc0_lladdr(CPUMIPSState *env)
+ {
+     return env->lladdr >> env->CP0_LLAddr_shift;
+ }
+ 
+-target_ulong helper_dmfc0_watchlo (uint32_t sel)
++target_ulong helper_dmfc0_watchlo(CPUMIPSState *env, uint32_t sel)
+ {
+     return env->CP0_WatchLo[sel];
+ }
+ #endif /* TARGET_MIPS64 */
+ 
+-void helper_mtc0_index (target_ulong arg1)
++void helper_mtc0_index(CPUMIPSState *env, target_ulong arg1)
+ {
+     int num = 1;
+     unsigned int tmp = env->tlb->nb_tlb;
+@@ -1140,7 +1178,7 @@ void helper_mtc0_index (target_ulong arg1)
+     env->CP0_Index = (env->CP0_Index & 0x80000000) | (arg1 & (num - 1));
+ }
+ 
+-void helper_mtc0_mvpcontrol (target_ulong arg1)
++void helper_mtc0_mvpcontrol(CPUMIPSState *env, target_ulong arg1)
+ {
+     uint32_t mask = 0;
+     uint32_t newval;
+@@ -1157,7 +1195,7 @@ void helper_mtc0_mvpcontrol (target_ulong arg1)
+     env->mvp->CP0_MVPControl = newval;
+ }
+ 
+-void helper_mtc0_vpecontrol (target_ulong arg1)
++void helper_mtc0_vpecontrol(CPUMIPSState *env, target_ulong arg1)
+ {
+     uint32_t mask;
+     uint32_t newval;
+@@ -1174,10 +1212,10 @@ void helper_mtc0_vpecontrol (target_ulong arg1)
+     env->CP0_VPEControl = newval;
+ }
+ 
+-void helper_mttc0_vpecontrol(target_ulong arg1)
++void helper_mttc0_vpecontrol(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+     uint32_t mask;
+     uint32_t newval;
+ 
+@@ -1190,23 +1228,23 @@ void helper_mttc0_vpecontrol(target_ulong arg1)
+     other->CP0_VPEControl = newval;
+ }
+ 
+-target_ulong helper_mftc0_vpecontrol(void)
++target_ulong helper_mftc0_vpecontrol(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+     /* FIXME: Mask away return zero on read bits.  */
+     return other->CP0_VPEControl;
+ }
+ 
+-target_ulong helper_mftc0_vpeconf0(void)
++target_ulong helper_mftc0_vpeconf0(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     return other->CP0_VPEConf0;
+ }
+ 
+-void helper_mtc0_vpeconf0 (target_ulong arg1)
++void helper_mtc0_vpeconf0(CPUMIPSState *env, target_ulong arg1)
+ {
+     uint32_t mask = 0;
+     uint32_t newval;
+@@ -1223,10 +1261,10 @@ void helper_mtc0_vpeconf0 (target_ulong arg1)
+     env->CP0_VPEConf0 = newval;
+ }
+ 
+-void helper_mttc0_vpeconf0(target_ulong arg1)
++void helper_mttc0_vpeconf0(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+     uint32_t mask = 0;
+     uint32_t newval;
+ 
+@@ -1237,7 +1275,7 @@ void helper_mttc0_vpeconf0(target_ulong arg1)
+     other->CP0_VPEConf0 = newval;
+ }
+ 
+-void helper_mtc0_vpeconf1 (target_ulong arg1)
++void helper_mtc0_vpeconf1(CPUMIPSState *env, target_ulong arg1)
+ {
+     uint32_t mask = 0;
+     uint32_t newval;
+@@ -1255,25 +1293,25 @@ void helper_mtc0_vpeconf1 (target_ulong arg1)
+     env->CP0_VPEConf1 = newval;
+ }
+ 
+-void helper_mtc0_yqmask (target_ulong arg1)
++void helper_mtc0_yqmask(CPUMIPSState *env, target_ulong arg1)
+ {
+     /* Yield qualifier inputs not implemented. */
+     env->CP0_YQMask = 0x00000000;
+ }
+ 
+-void helper_mtc0_vpeopt (target_ulong arg1)
++void helper_mtc0_vpeopt(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_VPEOpt = arg1 & 0x0000ffff;
+ }
+ 
+-void helper_mtc0_entrylo0 (target_ulong arg1)
++void helper_mtc0_entrylo0(CPUMIPSState *env, target_ulong arg1)
+ {
+     /* Large physaddr (PABITS) not implemented */
+     /* 1k pages not implemented */
+     env->CP0_EntryLo0 = arg1 & 0x3FFFFFFF;
+ }
+ 
+-void helper_mtc0_tcstatus (target_ulong arg1)
++void helper_mtc0_tcstatus(CPUMIPSState *env, target_ulong arg1)
+ {
+     uint32_t mask = env->CP0_TCStatus_rw_bitmask;
+     uint32_t newval;
+@@ -1284,10 +1322,10 @@ void helper_mtc0_tcstatus (target_ulong arg1)
+     sync_c0_tcstatus(env, env->current_tc, newval);
+ }
+ 
+-void helper_mttc0_tcstatus (target_ulong arg1)
++void helper_mttc0_tcstatus(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         other->active_tc.CP0_TCStatus = arg1;
+@@ -1296,7 +1334,7 @@ void helper_mttc0_tcstatus (target_ulong arg1)
+     sync_c0_tcstatus(other, other_tc, arg1);
+ }
+ 
+-void helper_mtc0_tcbind (target_ulong arg1)
++void helper_mtc0_tcbind(CPUMIPSState *env, target_ulong arg1)
+ {
+     uint32_t mask = (1 << CP0TCBd_TBE);
+     uint32_t newval;
+@@ -1307,12 +1345,12 @@ void helper_mtc0_tcbind (target_ulong arg1)
+     env->active_tc.CP0_TCBind = newval;
+ }
+ 
+-void helper_mttc0_tcbind (target_ulong arg1)
++void helper_mttc0_tcbind(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+     uint32_t mask = (1 << CP0TCBd_TBE);
+     uint32_t newval;
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
+         mask |= (1 << CP0TCBd_CurVPE);
+@@ -1325,7 +1363,7 @@ void helper_mttc0_tcbind (target_ulong arg1)
+     }
+ }
+ 
+-void helper_mtc0_tcrestart (target_ulong arg1)
++void helper_mtc0_tcrestart(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->active_tc.PC = arg1;
+     env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
+@@ -1333,10 +1371,10 @@ void helper_mtc0_tcrestart (target_ulong arg1)
+     /* MIPS16 not implemented. */
+ }
+ 
+-void helper_mttc0_tcrestart (target_ulong arg1)
++void helper_mttc0_tcrestart(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc) {
+         other->active_tc.PC = arg1;
+@@ -1351,7 +1389,7 @@ void helper_mttc0_tcrestart (target_ulong arg1)
+     }
+ }
+ 
+-void helper_mtc0_tchalt (target_ulong arg1)
++void helper_mtc0_tchalt(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->active_tc.CP0_TCHalt = arg1 & 0x1;
+ 
+@@ -1363,10 +1401,10 @@ void helper_mtc0_tchalt (target_ulong arg1)
+     }
+ }
+ 
+-void helper_mttc0_tchalt (target_ulong arg1)
++void helper_mttc0_tchalt(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     // TODO: Halt TC / Restart (if allocated+active) TC.
+ 
+@@ -1382,15 +1420,15 @@ void helper_mttc0_tchalt (target_ulong arg1)
+     }
+ }
+ 
+-void helper_mtc0_tccontext (target_ulong arg1)
++void helper_mtc0_tccontext(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->active_tc.CP0_TCContext = arg1;
+ }
+ 
+-void helper_mttc0_tccontext (target_ulong arg1)
++void helper_mttc0_tccontext(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         other->active_tc.CP0_TCContext = arg1;
+@@ -1398,15 +1436,15 @@ void helper_mttc0_tccontext (target_ulong arg1)
+         other->tcs[other_tc].CP0_TCContext = arg1;
+ }
+ 
+-void helper_mtc0_tcschedule (target_ulong arg1)
++void helper_mtc0_tcschedule(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->active_tc.CP0_TCSchedule = arg1;
+ }
+ 
+-void helper_mttc0_tcschedule (target_ulong arg1)
++void helper_mttc0_tcschedule(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         other->active_tc.CP0_TCSchedule = arg1;
+@@ -1414,15 +1452,15 @@ void helper_mttc0_tcschedule (target_ulong arg1)
+         other->tcs[other_tc].CP0_TCSchedule = arg1;
+ }
+ 
+-void helper_mtc0_tcschefback (target_ulong arg1)
++void helper_mtc0_tcschefback(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->active_tc.CP0_TCScheFBack = arg1;
+ }
+ 
+-void helper_mttc0_tcschefback (target_ulong arg1)
++void helper_mttc0_tcschefback(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         other->active_tc.CP0_TCScheFBack = arg1;
+@@ -1430,25 +1468,25 @@ void helper_mttc0_tcschefback (target_ulong arg1)
+         other->tcs[other_tc].CP0_TCScheFBack = arg1;
+ }
+ 
+-void helper_mtc0_entrylo1 (target_ulong arg1)
++void helper_mtc0_entrylo1(CPUMIPSState *env, target_ulong arg1)
+ {
+     /* Large physaddr (PABITS) not implemented */
+     /* 1k pages not implemented */
+     env->CP0_EntryLo1 = arg1 & 0x3FFFFFFF;
+ }
+ 
+-void helper_mtc0_context (target_ulong arg1)
++void helper_mtc0_context(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_Context = (env->CP0_Context & 0x007FFFFF) | (arg1 & ~0x007FFFFF);
+ }
+ 
+-void helper_mtc0_pagemask (target_ulong arg1)
++void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
+ {
+     /* 1k pages not implemented */
+     env->CP0_PageMask = arg1 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
+ }
+ 
+-void helper_mtc0_pagegrain (target_ulong arg1)
++void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
+ {
+     /* SmartMIPS not implemented */
+     /* Large physaddr (PABITS) not implemented */
+@@ -1456,47 +1494,47 @@ void helper_mtc0_pagegrain (target_ulong arg1)
+     env->CP0_PageGrain = 0;
+ }
+ 
+-void helper_mtc0_wired (target_ulong arg1)
++void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_Wired = arg1 % env->tlb->nb_tlb;
+ }
+ 
+-void helper_mtc0_srsconf0 (target_ulong arg1)
++void helper_mtc0_srsconf0(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_SRSConf0 |= arg1 & env->CP0_SRSConf0_rw_bitmask;
+ }
+ 
+-void helper_mtc0_srsconf1 (target_ulong arg1)
++void helper_mtc0_srsconf1(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_SRSConf1 |= arg1 & env->CP0_SRSConf1_rw_bitmask;
+ }
+ 
+-void helper_mtc0_srsconf2 (target_ulong arg1)
++void helper_mtc0_srsconf2(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_SRSConf2 |= arg1 & env->CP0_SRSConf2_rw_bitmask;
+ }
+ 
+-void helper_mtc0_srsconf3 (target_ulong arg1)
++void helper_mtc0_srsconf3(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_SRSConf3 |= arg1 & env->CP0_SRSConf3_rw_bitmask;
+ }
+ 
+-void helper_mtc0_srsconf4 (target_ulong arg1)
++void helper_mtc0_srsconf4(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_SRSConf4 |= arg1 & env->CP0_SRSConf4_rw_bitmask;
+ }
+ 
+-void helper_mtc0_hwrena (target_ulong arg1)
++void helper_mtc0_hwrena(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_HWREna = arg1 & 0x0000000F;
+ }
+ 
+-void helper_mtc0_count (target_ulong arg1)
++void helper_mtc0_count(CPUMIPSState *env, target_ulong arg1)
+ {
+     cpu_mips_store_count(env, arg1);
+ }
+ 
+-void helper_mtc0_entryhi (target_ulong arg1)
++void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
+ {
+     target_ulong old, val;
+ 
+@@ -1515,21 +1553,21 @@ void helper_mtc0_entryhi (target_ulong arg1)
+         cpu_mips_tlb_flush(env, 1);
+ }
+ 
+-void helper_mttc0_entryhi(target_ulong arg1)
++void helper_mttc0_entryhi(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     other->CP0_EntryHi = arg1;
+     sync_c0_entryhi(other, other_tc);
+ }
+ 
+-void helper_mtc0_compare (target_ulong arg1)
++void helper_mtc0_compare(CPUMIPSState *env, target_ulong arg1)
+ {
+     cpu_mips_store_compare(env, arg1);
+ }
+ 
+-void helper_mtc0_status (target_ulong arg1)
++void helper_mtc0_status(CPUMIPSState *env, target_ulong arg1)
+ {
+     uint32_t val, old;
+     uint32_t mask = env->CP0_Status_rw_bitmask;
+@@ -1538,7 +1576,7 @@ void helper_mtc0_status (target_ulong arg1)
+     old = env->CP0_Status;
+     env->CP0_Status = (env->CP0_Status & ~mask) | val;
+     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+-        sync_c0_status(env, env->current_tc);
++        sync_c0_status(env, env, env->current_tc);
+     } else {
+         compute_hflags(env);
+     }
+@@ -1557,22 +1595,22 @@ void helper_mtc0_status (target_ulong arg1)
+     }
+ }
+ 
+-void helper_mttc0_status(target_ulong arg1)
++void helper_mttc0_status(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     other->CP0_Status = arg1 & ~0xf1000018;
+-    sync_c0_status(other, other_tc);
++    sync_c0_status(env, other, other_tc);
+ }
+ 
+-void helper_mtc0_intctl (target_ulong arg1)
++void helper_mtc0_intctl(CPUMIPSState *env, target_ulong arg1)
+ {
+     /* vectored interrupts not implemented, no performance counters. */
+     env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000003e0) | (arg1 & 0x000003e0);
+ }
+ 
+-void helper_mtc0_srsctl (target_ulong arg1)
++void helper_mtc0_srsctl(CPUMIPSState *env, target_ulong arg1)
+ {
+     uint32_t mask = (0xf << CP0SRSCtl_ESS) | (0xf << CP0SRSCtl_PSS);
+     env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (arg1 & mask);
+@@ -1606,52 +1644,52 @@ static void mtc0_cause(CPUMIPSState *cpu, target_ulong arg1)
+     }
+ }
+ 
+-void helper_mtc0_cause(target_ulong arg1)
++void helper_mtc0_cause(CPUMIPSState *env, target_ulong arg1)
+ {
+     mtc0_cause(env, arg1);
+ }
+ 
+-void helper_mttc0_cause(target_ulong arg1)
++void helper_mttc0_cause(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     mtc0_cause(other, arg1);
+ }
+ 
+-target_ulong helper_mftc0_epc(void)
++target_ulong helper_mftc0_epc(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     return other->CP0_EPC;
+ }
+ 
+-target_ulong helper_mftc0_ebase(void)
++target_ulong helper_mftc0_ebase(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     return other->CP0_EBase;
+ }
+ 
+-void helper_mtc0_ebase (target_ulong arg1)
++void helper_mtc0_ebase(CPUMIPSState *env, target_ulong arg1)
+ {
+     /* vectored interrupts not implemented */
+     env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
+ }
+ 
+-void helper_mttc0_ebase(target_ulong arg1)
++void helper_mttc0_ebase(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+     other->CP0_EBase = (other->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
+ }
+ 
+-target_ulong helper_mftc0_configx(target_ulong idx)
++target_ulong helper_mftc0_configx(CPUMIPSState *env, target_ulong idx)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     switch (idx) {
+     case 0: return other->CP0_Config0;
+@@ -1667,49 +1705,49 @@ target_ulong helper_mftc0_configx(target_ulong idx)
+     return 0;
+ }
+ 
+-void helper_mtc0_config0 (target_ulong arg1)
++void helper_mtc0_config0(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (arg1 & 0x00000007);
+ }
+ 
+-void helper_mtc0_config2 (target_ulong arg1)
++void helper_mtc0_config2(CPUMIPSState *env, target_ulong arg1)
+ {
+     /* tertiary/secondary caches not implemented */
+     env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
+ }
+ 
+-void helper_mtc0_lladdr (target_ulong arg1)
++void helper_mtc0_lladdr(CPUMIPSState *env, target_ulong arg1)
+ {
+     target_long mask = env->CP0_LLAddr_rw_bitmask;
+     arg1 = arg1 << env->CP0_LLAddr_shift;
+     env->lladdr = (env->lladdr & ~mask) | (arg1 & mask);
+ }
+ 
+-void helper_mtc0_watchlo (target_ulong arg1, uint32_t sel)
++void helper_mtc0_watchlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+ {
+     /* Watch exceptions for instructions, data loads, data stores
+        not implemented. */
+     env->CP0_WatchLo[sel] = (arg1 & ~0x7);
+ }
+ 
+-void helper_mtc0_watchhi (target_ulong arg1, uint32_t sel)
++void helper_mtc0_watchhi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+ {
+     env->CP0_WatchHi[sel] = (arg1 & 0x40FF0FF8);
+     env->CP0_WatchHi[sel] &= ~(env->CP0_WatchHi[sel] & arg1 & 0x7);
+ }
+ 
+-void helper_mtc0_xcontext (target_ulong arg1)
++void helper_mtc0_xcontext(CPUMIPSState *env, target_ulong arg1)
+ {
+     target_ulong mask = (1ULL << (env->SEGBITS - 7)) - 1;
+     env->CP0_XContext = (env->CP0_XContext & mask) | (arg1 & ~mask);
+ }
+ 
+-void helper_mtc0_framemask (target_ulong arg1)
++void helper_mtc0_framemask(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_Framemask = arg1; /* XXX */
+ }
+ 
+-void helper_mtc0_debug (target_ulong arg1)
++void helper_mtc0_debug(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_Debug = (env->CP0_Debug & 0x8C03FC1F) | (arg1 & 0x13300120);
+     if (arg1 & (1 << CP0DB_DM))
+@@ -1718,11 +1756,11 @@ void helper_mtc0_debug (target_ulong arg1)
+         env->hflags &= ~MIPS_HFLAG_DM;
+ }
+ 
+-void helper_mttc0_debug(target_ulong arg1)
++void helper_mttc0_debug(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+     uint32_t val = arg1 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     /* XXX: Might be wrong, check with EJTAG spec. */
+     if (other_tc == other->current_tc)
+@@ -1734,36 +1772,36 @@ void helper_mttc0_debug(target_ulong arg1)
+                      (arg1 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
+ }
+ 
+-void helper_mtc0_performance0 (target_ulong arg1)
++void helper_mtc0_performance0(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_Performance0 = arg1 & 0x000007ff;
+ }
+ 
+-void helper_mtc0_taglo (target_ulong arg1)
++void helper_mtc0_taglo(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_TagLo = arg1 & 0xFFFFFCF6;
+ }
+ 
+-void helper_mtc0_datalo (target_ulong arg1)
++void helper_mtc0_datalo(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_DataLo = arg1; /* XXX */
+ }
+ 
+-void helper_mtc0_taghi (target_ulong arg1)
++void helper_mtc0_taghi(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_TagHi = arg1; /* XXX */
+ }
+ 
+-void helper_mtc0_datahi (target_ulong arg1)
++void helper_mtc0_datahi(CPUMIPSState *env, target_ulong arg1)
+ {
+     env->CP0_DataHi = arg1; /* XXX */
+ }
+ 
+ /* MIPS MT functions */
+-target_ulong helper_mftgpr(uint32_t sel)
++target_ulong helper_mftgpr(CPUMIPSState *env, uint32_t sel)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.gpr[sel];
+@@ -1771,10 +1809,10 @@ target_ulong helper_mftgpr(uint32_t sel)
+         return other->tcs[other_tc].gpr[sel];
+ }
+ 
+-target_ulong helper_mftlo(uint32_t sel)
++target_ulong helper_mftlo(CPUMIPSState *env, uint32_t sel)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.LO[sel];
+@@ -1782,10 +1820,10 @@ target_ulong helper_mftlo(uint32_t sel)
+         return other->tcs[other_tc].LO[sel];
+ }
+ 
+-target_ulong helper_mfthi(uint32_t sel)
++target_ulong helper_mfthi(CPUMIPSState *env, uint32_t sel)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.HI[sel];
+@@ -1793,10 +1831,10 @@ target_ulong helper_mfthi(uint32_t sel)
+         return other->tcs[other_tc].HI[sel];
+ }
+ 
+-target_ulong helper_mftacx(uint32_t sel)
++target_ulong helper_mftacx(CPUMIPSState *env, uint32_t sel)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.ACX[sel];
+@@ -1804,10 +1842,10 @@ target_ulong helper_mftacx(uint32_t sel)
+         return other->tcs[other_tc].ACX[sel];
+ }
+ 
+-target_ulong helper_mftdsp(void)
++target_ulong helper_mftdsp(CPUMIPSState *env)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         return other->active_tc.DSPControl;
+@@ -1815,10 +1853,10 @@ target_ulong helper_mftdsp(void)
+         return other->tcs[other_tc].DSPControl;
+ }
+ 
+-void helper_mttgpr(target_ulong arg1, uint32_t sel)
++void helper_mttgpr(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         other->active_tc.gpr[sel] = arg1;
+@@ -1826,10 +1864,10 @@ void helper_mttgpr(target_ulong arg1, uint32_t sel)
+         other->tcs[other_tc].gpr[sel] = arg1;
+ }
+ 
+-void helper_mttlo(target_ulong arg1, uint32_t sel)
++void helper_mttlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         other->active_tc.LO[sel] = arg1;
+@@ -1837,10 +1875,10 @@ void helper_mttlo(target_ulong arg1, uint32_t sel)
+         other->tcs[other_tc].LO[sel] = arg1;
+ }
+ 
+-void helper_mtthi(target_ulong arg1, uint32_t sel)
++void helper_mtthi(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         other->active_tc.HI[sel] = arg1;
+@@ -1848,10 +1886,10 @@ void helper_mtthi(target_ulong arg1, uint32_t sel)
+         other->tcs[other_tc].HI[sel] = arg1;
+ }
+ 
+-void helper_mttacx(target_ulong arg1, uint32_t sel)
++void helper_mttacx(CPUMIPSState *env, target_ulong arg1, uint32_t sel)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         other->active_tc.ACX[sel] = arg1;
+@@ -1859,10 +1897,10 @@ void helper_mttacx(target_ulong arg1, uint32_t sel)
+         other->tcs[other_tc].ACX[sel] = arg1;
+ }
+ 
+-void helper_mttdsp(target_ulong arg1)
++void helper_mttdsp(CPUMIPSState *env, target_ulong arg1)
+ {
+     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+-    CPUMIPSState *other = mips_cpu_map_tc(&other_tc);
++    CPUMIPSState *other = mips_cpu_map_tc(env, &other_tc);
+ 
+     if (other_tc == other->current_tc)
+         other->active_tc.DSPControl = arg1;
+@@ -1883,7 +1921,7 @@ target_ulong helper_emt(void)
+     return 0;
+ }
+ 
+-target_ulong helper_dvpe(void)
++target_ulong helper_dvpe(CPUMIPSState *env)
+ {
+     CPUMIPSState *other_cpu = first_cpu;
+     target_ulong prev = env->mvp->CP0_MVPControl;
+@@ -1899,7 +1937,7 @@ target_ulong helper_dvpe(void)
+     return prev;
+ }
+ 
+-target_ulong helper_evpe(void)
++target_ulong helper_evpe(CPUMIPSState *env)
+ {
+     CPUMIPSState *other_cpu = first_cpu;
+     target_ulong prev = env->mvp->CP0_MVPControl;
+@@ -1925,7 +1963,7 @@ void helper_fork(target_ulong arg1, target_ulong arg2)
+     // TODO: store to TC register
+ }
+ 
+-target_ulong helper_yield(target_ulong arg)
++target_ulong helper_yield(CPUMIPSState *env, target_ulong arg)
+ {
+     target_long arg1 = arg;
+ 
+@@ -1936,13 +1974,13 @@ target_ulong helper_yield(target_ulong arg)
+                 env->active_tc.CP0_TCStatus & (1 << CP0TCSt_DT)) {
+                 env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
+                 env->CP0_VPEControl |= 4 << CP0VPECo_EXCPT;
+-                helper_raise_exception(EXCP_THREAD);
++                helper_raise_exception(env, EXCP_THREAD);
+             }
+         }
+     } else if (arg1 == 0) {
+         if (0 /* TODO: TC underflow */) {
+             env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
+-            helper_raise_exception(EXCP_THREAD);
++            helper_raise_exception(env, EXCP_THREAD);
+         } else {
+             // TODO: Deallocate TC
+         }
+@@ -1950,7 +1988,7 @@ target_ulong helper_yield(target_ulong arg)
+         /* Yield qualifier inputs not implemented. */
+         env->CP0_VPEControl &= ~(0x7 << CP0VPECo_EXCPT);
+         env->CP0_VPEControl |= 2 << CP0VPECo_EXCPT;
+-        helper_raise_exception(EXCP_THREAD);
++        helper_raise_exception(env, EXCP_THREAD);
+     }
+     return env->CP0_YQMask;
+ }
+@@ -1972,7 +2010,7 @@ static void r4k_mips_tlb_flush_extra (CPUMIPSState *env, int first)
+     }
+ }
+ 
+-static void r4k_fill_tlb (int idx)
++static void r4k_fill_tlb(CPUMIPSState *env, int idx)
+ {
+     r4k_tlb_t *tlb;
+ 
+@@ -1995,7 +2033,7 @@ static void r4k_fill_tlb (int idx)
+     tlb->PFN[1] = (env->CP0_EntryLo1 >> 6) << 12;
+ }
+ 
+-void r4k_helper_tlbwi (void)
++void r4k_helper_tlbwi(CPUMIPSState *env)
+ {
+     int idx;
+ 
+@@ -2007,18 +2045,18 @@ void r4k_helper_tlbwi (void)
+     r4k_mips_tlb_flush_extra (env, env->tlb->nb_tlb);
+ 
+     r4k_invalidate_tlb(env, idx, 0);
+-    r4k_fill_tlb(idx);
++    r4k_fill_tlb(env, idx);
+ }
+ 
+-void r4k_helper_tlbwr (void)
++void r4k_helper_tlbwr(CPUMIPSState *env)
+ {
+     int r = cpu_mips_get_random(env);
+ 
+     r4k_invalidate_tlb(env, r, 1);
+-    r4k_fill_tlb(r);
++    r4k_fill_tlb(env, r);
+ }
+ 
+-void r4k_helper_tlbp (void)
++void r4k_helper_tlbp(CPUMIPSState *env)
+ {
+     r4k_tlb_t *tlb;
+     target_ulong mask;
+@@ -2060,7 +2098,7 @@ void r4k_helper_tlbp (void)
+     }
+ }
+ 
+-void r4k_helper_tlbr (void)
++void r4k_helper_tlbr(CPUMIPSState *env)
+ {
+     r4k_tlb_t *tlb;
+     uint8_t ASID;
+@@ -2084,28 +2122,28 @@ void r4k_helper_tlbr (void)
+                         (tlb->C1 << 3) | (tlb->PFN[1] >> 6);
+ }
+ 
+-void helper_tlbwi(void)
++void helper_tlbwi(CPUMIPSState *env)
+ {
+-    env->tlb->helper_tlbwi();
++    env->tlb->helper_tlbwi(env);
+ }
+ 
+-void helper_tlbwr(void)
++void helper_tlbwr(CPUMIPSState *env)
+ {
+-    env->tlb->helper_tlbwr();
++    env->tlb->helper_tlbwr(env);
+ }
+ 
+-void helper_tlbp(void)
++void helper_tlbp(CPUMIPSState *env)
+ {
+-    env->tlb->helper_tlbp();
++    env->tlb->helper_tlbp(env);
+ }
+ 
+-void helper_tlbr(void)
++void helper_tlbr(CPUMIPSState *env)
+ {
+-    env->tlb->helper_tlbr();
++    env->tlb->helper_tlbr(env);
+ }
+ 
+ /* Specials */
+-target_ulong helper_di (void)
++target_ulong helper_di(CPUMIPSState *env)
+ {
+     target_ulong t0 = env->CP0_Status;
+ 
+@@ -2113,7 +2151,7 @@ target_ulong helper_di (void)
+     return t0;
+ }
+ 
+-target_ulong helper_ei (void)
++target_ulong helper_ei(CPUMIPSState *env)
+ {
+     target_ulong t0 = env->CP0_Status;
+ 
+@@ -2121,7 +2159,7 @@ target_ulong helper_ei (void)
+     return t0;
+ }
+ 
+-static void debug_pre_eret (void)
++static void debug_pre_eret(CPUMIPSState *env)
+ {
+     if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
+         qemu_log("ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
+@@ -2134,7 +2172,7 @@ static void debug_pre_eret (void)
+     }
+ }
+ 
+-static void debug_post_eret (void)
++static void debug_post_eret(CPUMIPSState *env)
+ {
+     if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
+         qemu_log("  =>  PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
+@@ -2152,7 +2190,7 @@ static void debug_post_eret (void)
+     }
+ }
+ 
+-static void set_pc (target_ulong error_pc)
++static void set_pc(CPUMIPSState *env, target_ulong error_pc)
+ {
+     env->active_tc.PC = error_pc & ~(target_ulong)1;
+     if (error_pc & 1) {
+@@ -2162,78 +2200,78 @@ static void set_pc (target_ulong error_pc)
+     }
+ }
+ 
+-void helper_eret (void)
++void helper_eret(CPUMIPSState *env)
+ {
+-    debug_pre_eret();
++    debug_pre_eret(env);
+     if (env->CP0_Status & (1 << CP0St_ERL)) {
+-        set_pc(env->CP0_ErrorEPC);
++        set_pc(env, env->CP0_ErrorEPC);
+         env->CP0_Status &= ~(1 << CP0St_ERL);
+     } else {
+-        set_pc(env->CP0_EPC);
++        set_pc(env, env->CP0_EPC);
+         env->CP0_Status &= ~(1 << CP0St_EXL);
+     }
+     compute_hflags(env);
+-    debug_post_eret();
++    debug_post_eret(env);
+     env->lladdr = 1;
+ }
+ 
+-void helper_deret (void)
++void helper_deret(CPUMIPSState *env)
+ {
+-    debug_pre_eret();
+-    set_pc(env->CP0_DEPC);
++    debug_pre_eret(env);
++    set_pc(env, env->CP0_DEPC);
+ 
+     env->hflags &= MIPS_HFLAG_DM;
+     compute_hflags(env);
+-    debug_post_eret();
++    debug_post_eret(env);
+     env->lladdr = 1;
+ }
+ #endif /* !CONFIG_USER_ONLY */
+ 
+-target_ulong helper_rdhwr_cpunum(void)
++target_ulong helper_rdhwr_cpunum(CPUMIPSState *env)
+ {
+     if ((env->hflags & MIPS_HFLAG_CP0) ||
+         (env->CP0_HWREna & (1 << 0)))
+         return env->CP0_EBase & 0x3ff;
+     else
+-        helper_raise_exception(EXCP_RI);
++        helper_raise_exception(env, EXCP_RI);
+ 
+     return 0;
+ }
+ 
+-target_ulong helper_rdhwr_synci_step(void)
++target_ulong helper_rdhwr_synci_step(CPUMIPSState *env)
+ {
+     if ((env->hflags & MIPS_HFLAG_CP0) ||
+         (env->CP0_HWREna & (1 << 1)))
+         return env->SYNCI_Step;
+     else
+-        helper_raise_exception(EXCP_RI);
++        helper_raise_exception(env, EXCP_RI);
+ 
+     return 0;
+ }
+ 
+-target_ulong helper_rdhwr_cc(void)
++target_ulong helper_rdhwr_cc(CPUMIPSState *env)
+ {
+     if ((env->hflags & MIPS_HFLAG_CP0) ||
+         (env->CP0_HWREna & (1 << 2)))
+         return env->CP0_Count;
+     else
+-        helper_raise_exception(EXCP_RI);
++        helper_raise_exception(env, EXCP_RI);
+ 
+     return 0;
+ }
+ 
+-target_ulong helper_rdhwr_ccres(void)
++target_ulong helper_rdhwr_ccres(CPUMIPSState *env)
+ {
+     if ((env->hflags & MIPS_HFLAG_CP0) ||
+         (env->CP0_HWREna & (1 << 3)))
+         return env->CCRes;
+     else
+-        helper_raise_exception(EXCP_RI);
++        helper_raise_exception(env, EXCP_RI);
+ 
+     return 0;
+ }
+ 
+-void helper_pmon (int function)
++void helper_pmon(CPUMIPSState *env, int function)
+ {
+     function /= 2;
+     switch (function) {
+@@ -2259,16 +2297,17 @@ void helper_pmon (int function)
+     }
+ }
+ 
+-void helper_wait (void)
++void helper_wait(CPUMIPSState *env)
+ {
+     env->halted = 1;
+     cpu_reset_interrupt(env, CPU_INTERRUPT_WAKE);
+-    helper_raise_exception(EXCP_HLT);
++    helper_raise_exception(env, EXCP_HLT);
+ }
+ 
+ #if !defined(CONFIG_USER_ONLY)
+ 
+-static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write,
++static void QEMU_NORETURN do_unaligned_access(CPUMIPSState *env,
++                                              target_ulong addr, int is_write,
+                                               int is_user, uintptr_t retaddr);
+ 
+ #define MMUSUFFIX _mmu
+@@ -2286,23 +2325,20 @@ static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write,
+ #define SHIFT 3
+ #include "softmmu_template.h"
+ 
+-static void do_unaligned_access(target_ulong addr, int is_write,
+-                                int is_user, uintptr_t retaddr)
++static void do_unaligned_access(CPUMIPSState *env, target_ulong addr,
++                                int is_write, int is_user, uintptr_t retaddr)
+ {
+     env->CP0_BadVAddr = addr;
+-    do_restore_state (retaddr);
+-    helper_raise_exception ((is_write == 1) ? EXCP_AdES : EXCP_AdEL);
++    do_restore_state(env, retaddr);
++    helper_raise_exception(env, (is_write == 1) ? EXCP_AdES : EXCP_AdEL);
+ }
+ 
+-void tlb_fill(CPUMIPSState *env1, target_ulong addr, int is_write, int mmu_idx,
++void tlb_fill(CPUMIPSState *env, target_ulong addr, int is_write, int mmu_idx,
+               uintptr_t retaddr)
+ {
+     TranslationBlock *tb;
+-    CPUMIPSState *saved_env;
+     int ret;
+ 
+-    saved_env = env;
+-    env = env1;
+     ret = cpu_mips_handle_mmu_fault(env, addr, is_write, mmu_idx);
+     if (ret) {
+         if (retaddr) {
+@@ -2314,20 +2350,17 @@ void tlb_fill(CPUMIPSState *env1, target_ulong addr, int is_write, int mmu_idx,
+                 cpu_restore_state(tb, env, retaddr);
+             }
+         }
+-        helper_raise_exception_err(env->exception_index, env->error_code);
++        helper_raise_exception_err(env, env->exception_index, env->error_code);
+     }
+-    env = saved_env;
+ }
+ 
+-void cpu_unassigned_access(CPUMIPSState *env1, target_phys_addr_t addr,
++void cpu_unassigned_access(CPUMIPSState *env, target_phys_addr_t addr,
+                            int is_write, int is_exec, int unused, int size)
+ {
+-    env = env1;
+-
+     if (is_exec)
+-        helper_raise_exception(EXCP_IBE);
++        helper_raise_exception(env, EXCP_IBE);
+     else
+-        helper_raise_exception(EXCP_DBE);
++        helper_raise_exception(env, EXCP_DBE);
+ }
+ #endif /* !CONFIG_USER_ONLY */
+ 
+@@ -2356,7 +2389,7 @@ static unsigned int ieee_rm[] = {
+ #define RESTORE_FLUSH_MODE \
+     set_flush_to_zero((env->active_fpu.fcr31 & (1 << 24)) != 0, &env->active_fpu.fp_status);
+ 
+-target_ulong helper_cfc1 (uint32_t reg)
++target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
+ {
+     target_ulong arg1;
+ 
+@@ -2381,7 +2414,7 @@ target_ulong helper_cfc1 (uint32_t reg)
+     return arg1;
+ }
+ 
+-void helper_ctc1 (target_ulong arg1, uint32_t reg)
++void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t reg)
+ {
+     switch(reg) {
+     case 25:
+@@ -2415,7 +2448,7 @@ void helper_ctc1 (target_ulong arg1, uint32_t reg)
+     RESTORE_FLUSH_MODE;
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) & GET_FP_CAUSE(env->active_fpu.fcr31))
+-        helper_raise_exception(EXCP_FPE);
++        helper_raise_exception(env, EXCP_FPE);
+ }
+ 
+ static inline int ieee_ex_to_mips(int xcpt)
+@@ -2441,13 +2474,13 @@ static inline int ieee_ex_to_mips(int xcpt)
+     return ret;
+ }
+ 
+-static inline void update_fcr31(void)
++static inline void update_fcr31(CPUMIPSState *env)
+ {
+     int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->active_fpu.fp_status));
+ 
+     SET_FP_CAUSE(env->active_fpu.fcr31, tmp);
+     if (GET_FP_ENABLE(env->active_fpu.fcr31) & tmp)
+-        helper_raise_exception(EXCP_FPE);
++        helper_raise_exception(env, EXCP_FPE);
+     else
+         UPDATE_FP_FLAGS(env->active_fpu.fcr31, tmp);
+ }
+@@ -2458,71 +2491,71 @@ static inline void update_fcr31(void)
+    paired single lower "pl", paired single upper "pu".  */
+ 
+ /* unary operations, modifying fp status  */
+-uint64_t helper_float_sqrt_d(uint64_t fdt0)
++uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     return float64_sqrt(fdt0, &env->active_fpu.fp_status);
+ }
+ 
+-uint32_t helper_float_sqrt_s(uint32_t fst0)
++uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     return float32_sqrt(fst0, &env->active_fpu.fp_status);
+ }
+ 
+-uint64_t helper_float_cvtd_s(uint32_t fst0)
++uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint64_t fdt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fdt2;
+ }
+ 
+-uint64_t helper_float_cvtd_w(uint32_t wt0)
++uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
+ {
+     uint64_t fdt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fdt2;
+ }
+ 
+-uint64_t helper_float_cvtd_l(uint64_t dt0)
++uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
+ {
+     uint64_t fdt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fdt2;
+ }
+ 
+-uint64_t helper_float_cvtl_d(uint64_t fdt0)
++uint64_t helper_float_cvtl_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint64_t dt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         dt2 = FLOAT_SNAN64;
+     return dt2;
+ }
+ 
+-uint64_t helper_float_cvtl_s(uint32_t fst0)
++uint64_t helper_float_cvtl_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint64_t dt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         dt2 = FLOAT_SNAN64;
+     return dt2;
+ }
+ 
+-uint64_t helper_float_cvtps_pw(uint64_t dt0)
++uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
+ {
+     uint32_t fst2;
+     uint32_t fsth2;
+@@ -2530,11 +2563,11 @@ uint64_t helper_float_cvtps_pw(uint64_t dt0)
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
+     fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return ((uint64_t)fsth2 << 32) | fst2;
+ }
+ 
+-uint64_t helper_float_cvtpw_ps(uint64_t fdt0)
++uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint32_t wt2;
+     uint32_t wth2;
+@@ -2542,7 +2575,7 @@ uint64_t helper_float_cvtpw_ps(uint64_t fdt0)
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
+     wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID)) {
+         wt2 = FLOAT_SNAN32;
+         wth2 = FLOAT_SNAN32;
+@@ -2550,81 +2583,81 @@ uint64_t helper_float_cvtpw_ps(uint64_t fdt0)
+     return ((uint64_t)wth2 << 32) | wt2;
+ }
+ 
+-uint32_t helper_float_cvts_d(uint64_t fdt0)
++uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint32_t fst2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fst2;
+ }
+ 
+-uint32_t helper_float_cvts_w(uint32_t wt0)
++uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
+ {
+     uint32_t fst2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fst2;
+ }
+ 
+-uint32_t helper_float_cvts_l(uint64_t dt0)
++uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
+ {
+     uint32_t fst2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fst2;
+ }
+ 
+-uint32_t helper_float_cvts_pl(uint32_t wt0)
++uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
+ {
+     uint32_t wt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     wt2 = wt0;
+-    update_fcr31();
++    update_fcr31(env);
+     return wt2;
+ }
+ 
+-uint32_t helper_float_cvts_pu(uint32_t wth0)
++uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
+ {
+     uint32_t wt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     wt2 = wth0;
+-    update_fcr31();
++    update_fcr31(env);
+     return wt2;
+ }
+ 
+-uint32_t helper_float_cvtw_s(uint32_t fst0)
++uint32_t helper_float_cvtw_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint32_t wt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         wt2 = FLOAT_SNAN32;
+     return wt2;
+ }
+ 
+-uint32_t helper_float_cvtw_d(uint64_t fdt0)
++uint32_t helper_float_cvtw_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint32_t wt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         wt2 = FLOAT_SNAN32;
+     return wt2;
+ }
+ 
+-uint64_t helper_float_roundl_d(uint64_t fdt0)
++uint64_t helper_float_roundl_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint64_t dt2;
+ 
+@@ -2632,13 +2665,13 @@ uint64_t helper_float_roundl_d(uint64_t fdt0)
+     set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
+     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         dt2 = FLOAT_SNAN64;
+     return dt2;
+ }
+ 
+-uint64_t helper_float_roundl_s(uint32_t fst0)
++uint64_t helper_float_roundl_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint64_t dt2;
+ 
+@@ -2646,13 +2679,13 @@ uint64_t helper_float_roundl_s(uint32_t fst0)
+     set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
+     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         dt2 = FLOAT_SNAN64;
+     return dt2;
+ }
+ 
+-uint32_t helper_float_roundw_d(uint64_t fdt0)
++uint32_t helper_float_roundw_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint32_t wt2;
+ 
+@@ -2660,13 +2693,13 @@ uint32_t helper_float_roundw_d(uint64_t fdt0)
+     set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
+     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         wt2 = FLOAT_SNAN32;
+     return wt2;
+ }
+ 
+-uint32_t helper_float_roundw_s(uint32_t fst0)
++uint32_t helper_float_roundw_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint32_t wt2;
+ 
+@@ -2674,61 +2707,61 @@ uint32_t helper_float_roundw_s(uint32_t fst0)
+     set_float_rounding_mode(float_round_nearest_even, &env->active_fpu.fp_status);
+     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         wt2 = FLOAT_SNAN32;
+     return wt2;
+ }
+ 
+-uint64_t helper_float_truncl_d(uint64_t fdt0)
++uint64_t helper_float_truncl_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint64_t dt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         dt2 = FLOAT_SNAN64;
+     return dt2;
+ }
+ 
+-uint64_t helper_float_truncl_s(uint32_t fst0)
++uint64_t helper_float_truncl_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint64_t dt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         dt2 = FLOAT_SNAN64;
+     return dt2;
+ }
+ 
+-uint32_t helper_float_truncw_d(uint64_t fdt0)
++uint32_t helper_float_truncw_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint32_t wt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         wt2 = FLOAT_SNAN32;
+     return wt2;
+ }
+ 
+-uint32_t helper_float_truncw_s(uint32_t fst0)
++uint32_t helper_float_truncw_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint32_t wt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         wt2 = FLOAT_SNAN32;
+     return wt2;
+ }
+ 
+-uint64_t helper_float_ceill_d(uint64_t fdt0)
++uint64_t helper_float_ceill_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint64_t dt2;
+ 
+@@ -2736,13 +2769,13 @@ uint64_t helper_float_ceill_d(uint64_t fdt0)
+     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
+     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         dt2 = FLOAT_SNAN64;
+     return dt2;
+ }
+ 
+-uint64_t helper_float_ceill_s(uint32_t fst0)
++uint64_t helper_float_ceill_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint64_t dt2;
+ 
+@@ -2750,13 +2783,13 @@ uint64_t helper_float_ceill_s(uint32_t fst0)
+     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
+     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         dt2 = FLOAT_SNAN64;
+     return dt2;
+ }
+ 
+-uint32_t helper_float_ceilw_d(uint64_t fdt0)
++uint32_t helper_float_ceilw_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint32_t wt2;
+ 
+@@ -2764,13 +2797,13 @@ uint32_t helper_float_ceilw_d(uint64_t fdt0)
+     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
+     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         wt2 = FLOAT_SNAN32;
+     return wt2;
+ }
+ 
+-uint32_t helper_float_ceilw_s(uint32_t fst0)
++uint32_t helper_float_ceilw_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint32_t wt2;
+ 
+@@ -2778,13 +2811,13 @@ uint32_t helper_float_ceilw_s(uint32_t fst0)
+     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
+     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         wt2 = FLOAT_SNAN32;
+     return wt2;
+ }
+ 
+-uint64_t helper_float_floorl_d(uint64_t fdt0)
++uint64_t helper_float_floorl_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint64_t dt2;
+ 
+@@ -2792,13 +2825,13 @@ uint64_t helper_float_floorl_d(uint64_t fdt0)
+     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
+     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         dt2 = FLOAT_SNAN64;
+     return dt2;
+ }
+ 
+-uint64_t helper_float_floorl_s(uint32_t fst0)
++uint64_t helper_float_floorl_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint64_t dt2;
+ 
+@@ -2806,13 +2839,13 @@ uint64_t helper_float_floorl_s(uint32_t fst0)
+     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
+     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         dt2 = FLOAT_SNAN64;
+     return dt2;
+ }
+ 
+-uint32_t helper_float_floorw_d(uint64_t fdt0)
++uint32_t helper_float_floorw_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint32_t wt2;
+ 
+@@ -2820,13 +2853,13 @@ uint32_t helper_float_floorw_d(uint64_t fdt0)
+     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
+     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         wt2 = FLOAT_SNAN32;
+     return wt2;
+ }
+ 
+-uint32_t helper_float_floorw_s(uint32_t fst0)
++uint32_t helper_float_floorw_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint32_t wt2;
+ 
+@@ -2834,7 +2867,7 @@ uint32_t helper_float_floorw_s(uint32_t fst0)
+     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
+     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
+     RESTORE_ROUNDING_MODE;
+-    update_fcr31();
++    update_fcr31(env);
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & (FP_OVERFLOW | FP_INVALID))
+         wt2 = FLOAT_SNAN32;
+     return wt2;
+@@ -2864,69 +2897,69 @@ FLOAT_UNOP(chs)
+ #undef FLOAT_UNOP
+ 
+ /* MIPS specific unary operations */
+-uint64_t helper_float_recip_d(uint64_t fdt0)
++uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint64_t fdt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fdt2 = float64_div(FLOAT_ONE64, fdt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fdt2;
+ }
+ 
+-uint32_t helper_float_recip_s(uint32_t fst0)
++uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint32_t fst2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = float32_div(FLOAT_ONE32, fst0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fst2;
+ }
+ 
+-uint64_t helper_float_rsqrt_d(uint64_t fdt0)
++uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint64_t fdt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
+     fdt2 = float64_div(FLOAT_ONE64, fdt2, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fdt2;
+ }
+ 
+-uint32_t helper_float_rsqrt_s(uint32_t fst0)
++uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint32_t fst2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
+     fst2 = float32_div(FLOAT_ONE32, fst2, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fst2;
+ }
+ 
+-uint64_t helper_float_recip1_d(uint64_t fdt0)
++uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint64_t fdt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fdt2 = float64_div(FLOAT_ONE64, fdt0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fdt2;
+ }
+ 
+-uint32_t helper_float_recip1_s(uint32_t fst0)
++uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint32_t fst2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = float32_div(FLOAT_ONE32, fst0, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fst2;
+ }
+ 
+-uint64_t helper_float_recip1_ps(uint64_t fdt0)
++uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint32_t fst2;
+     uint32_t fsth2;
+@@ -2934,33 +2967,33 @@ uint64_t helper_float_recip1_ps(uint64_t fdt0)
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = float32_div(FLOAT_ONE32, fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
+     fsth2 = float32_div(FLOAT_ONE32, fdt0 >> 32, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return ((uint64_t)fsth2 << 32) | fst2;
+ }
+ 
+-uint64_t helper_float_rsqrt1_d(uint64_t fdt0)
++uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint64_t fdt2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
+     fdt2 = float64_div(FLOAT_ONE64, fdt2, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fdt2;
+ }
+ 
+-uint32_t helper_float_rsqrt1_s(uint32_t fst0)
++uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
+ {
+     uint32_t fst2;
+ 
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
+     fst2 = float32_div(FLOAT_ONE32, fst2, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return fst2;
+ }
+ 
+-uint64_t helper_float_rsqrt1_ps(uint64_t fdt0)
++uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
+ {
+     uint32_t fst2;
+     uint32_t fsth2;
+@@ -2970,39 +3003,43 @@ uint64_t helper_float_rsqrt1_ps(uint64_t fdt0)
+     fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
+     fst2 = float32_div(FLOAT_ONE32, fst2, &env->active_fpu.fp_status);
+     fsth2 = float32_div(FLOAT_ONE32, fsth2, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return ((uint64_t)fsth2 << 32) | fst2;
+ }
+ 
+-#define FLOAT_OP(name, p) void helper_float_##name##_##p(void)
++#define FLOAT_OP(name, p) void helper_float_##name##_##p(CPUMIPSState *env)
+ 
+ /* binary operations */
+ #define FLOAT_BINOP(name)                                          \
+-uint64_t helper_float_ ## name ## _d(uint64_t fdt0, uint64_t fdt1)     \
++uint64_t helper_float_ ## name ## _d(CPUMIPSState *env,            \
++                                     uint64_t fdt0, uint64_t fdt1) \
+ {                                                                  \
+     uint64_t dt2;                                                  \
+                                                                    \
+     set_float_exception_flags(0, &env->active_fpu.fp_status);            \
+     dt2 = float64_ ## name (fdt0, fdt1, &env->active_fpu.fp_status);     \
+-    update_fcr31();                                                \
++    update_fcr31(env);                                             \
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID)                \
+         dt2 = FLOAT_QNAN64;                                        \
+     return dt2;                                                    \
+ }                                                                  \
+                                                                    \
+-uint32_t helper_float_ ## name ## _s(uint32_t fst0, uint32_t fst1)     \
++uint32_t helper_float_ ## name ## _s(CPUMIPSState *env,            \
++                                     uint32_t fst0, uint32_t fst1) \
+ {                                                                  \
+     uint32_t wt2;                                                  \
+                                                                    \
+     set_float_exception_flags(0, &env->active_fpu.fp_status);            \
+     wt2 = float32_ ## name (fst0, fst1, &env->active_fpu.fp_status);     \
+-    update_fcr31();                                                \
++    update_fcr31(env);                                             \
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID)                \
+         wt2 = FLOAT_QNAN32;                                        \
+     return wt2;                                                    \
+ }                                                                  \
+                                                                    \
+-uint64_t helper_float_ ## name ## _ps(uint64_t fdt0, uint64_t fdt1)    \
++uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,           \
++                                      uint64_t fdt0,               \
++                                      uint64_t fdt1)               \
+ {                                                                  \
+     uint32_t fst0 = fdt0 & 0XFFFFFFFF;                             \
+     uint32_t fsth0 = fdt0 >> 32;                                   \
+@@ -3014,7 +3051,7 @@ uint64_t helper_float_ ## name ## _ps(uint64_t fdt0, uint64_t fdt1)    \
+     set_float_exception_flags(0, &env->active_fpu.fp_status);            \
+     wt2 = float32_ ## name (fst0, fst1, &env->active_fpu.fp_status);     \
+     wth2 = float32_ ## name (fsth0, fsth1, &env->active_fpu.fp_status);  \
+-    update_fcr31();                                                \
++    update_fcr31(env);                                             \
+     if (GET_FP_CAUSE(env->active_fpu.fcr31) & FP_INVALID) {              \
+         wt2 = FLOAT_QNAN32;                                        \
+         wth2 = FLOAT_QNAN32;                                       \
+@@ -3030,22 +3067,28 @@ FLOAT_BINOP(div)
+ 
+ /* ternary operations */
+ #define FLOAT_TERNOP(name1, name2)                                        \
+-uint64_t helper_float_ ## name1 ## name2 ## _d(uint64_t fdt0, uint64_t fdt1,  \
+-                                           uint64_t fdt2)                 \
++uint64_t helper_float_ ## name1 ## name2 ## _d(CPUMIPSState *env,         \
++                                               uint64_t fdt0,             \
++                                               uint64_t fdt1,             \
++                                               uint64_t fdt2)             \
+ {                                                                         \
+     fdt0 = float64_ ## name1 (fdt0, fdt1, &env->active_fpu.fp_status);          \
+     return float64_ ## name2 (fdt0, fdt2, &env->active_fpu.fp_status);          \
+ }                                                                         \
+                                                                           \
+-uint32_t helper_float_ ## name1 ## name2 ## _s(uint32_t fst0, uint32_t fst1,  \
+-                                           uint32_t fst2)                 \
++uint32_t helper_float_ ## name1 ## name2 ## _s(CPUMIPSState *env,         \
++                                               uint32_t fst0,             \
++                                               uint32_t fst1,             \
++                                               uint32_t fst2)             \
+ {                                                                         \
+     fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status);          \
+     return float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status);          \
+ }                                                                         \
+                                                                           \
+-uint64_t helper_float_ ## name1 ## name2 ## _ps(uint64_t fdt0, uint64_t fdt1, \
+-                                            uint64_t fdt2)                \
++uint64_t helper_float_ ## name1 ## name2 ## _ps(CPUMIPSState *env,        \
++                                                uint64_t fdt0,            \
++                                                uint64_t fdt1,            \
++                                                uint64_t fdt2)            \
+ {                                                                         \
+     uint32_t fst0 = fdt0 & 0XFFFFFFFF;                                    \
+     uint32_t fsth0 = fdt0 >> 32;                                          \
+@@ -3067,24 +3110,30 @@ FLOAT_TERNOP(mul, sub)
+ 
+ /* negated ternary operations */
+ #define FLOAT_NTERNOP(name1, name2)                                       \
+-uint64_t helper_float_n ## name1 ## name2 ## _d(uint64_t fdt0, uint64_t fdt1, \
+-                                           uint64_t fdt2)                 \
++uint64_t helper_float_n ## name1 ## name2 ## _d(CPUMIPSState *env,        \
++                                                uint64_t fdt0,            \
++                                                uint64_t fdt1,            \
++                                                uint64_t fdt2)            \
+ {                                                                         \
+     fdt0 = float64_ ## name1 (fdt0, fdt1, &env->active_fpu.fp_status);          \
+     fdt2 = float64_ ## name2 (fdt0, fdt2, &env->active_fpu.fp_status);          \
+     return float64_chs(fdt2);                                             \
+ }                                                                         \
+                                                                           \
+-uint32_t helper_float_n ## name1 ## name2 ## _s(uint32_t fst0, uint32_t fst1, \
+-                                           uint32_t fst2)                 \
++uint32_t helper_float_n ## name1 ## name2 ## _s(CPUMIPSState *env,        \
++                                                uint32_t fst0,            \
++                                                uint32_t fst1,            \
++                                                uint32_t fst2)            \
+ {                                                                         \
+     fst0 = float32_ ## name1 (fst0, fst1, &env->active_fpu.fp_status);          \
+     fst2 = float32_ ## name2 (fst0, fst2, &env->active_fpu.fp_status);          \
+     return float32_chs(fst2);                                             \
+ }                                                                         \
+                                                                           \
+-uint64_t helper_float_n ## name1 ## name2 ## _ps(uint64_t fdt0, uint64_t fdt1,\
+-                                           uint64_t fdt2)                 \
++uint64_t helper_float_n ## name1 ## name2 ## _ps(CPUMIPSState *env,       \
++                                                 uint64_t fdt0,           \
++                                                 uint64_t fdt1,           \
++                                                 uint64_t fdt2)           \
+ {                                                                         \
+     uint32_t fst0 = fdt0 & 0XFFFFFFFF;                                    \
+     uint32_t fsth0 = fdt0 >> 32;                                          \
+@@ -3107,25 +3156,25 @@ FLOAT_NTERNOP(mul, sub)
+ #undef FLOAT_NTERNOP
+ 
+ /* MIPS specific binary operations */
+-uint64_t helper_float_recip2_d(uint64_t fdt0, uint64_t fdt2)
++uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
+ {
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
+     fdt2 = float64_chs(float64_sub(fdt2, FLOAT_ONE64, &env->active_fpu.fp_status));
+-    update_fcr31();
++    update_fcr31(env);
+     return fdt2;
+ }
+ 
+-uint32_t helper_float_recip2_s(uint32_t fst0, uint32_t fst2)
++uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
+ {
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
+     fst2 = float32_chs(float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status));
+-    update_fcr31();
++    update_fcr31(env);
+     return fst2;
+ }
+ 
+-uint64_t helper_float_recip2_ps(uint64_t fdt0, uint64_t fdt2)
++uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
+ {
+     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
+     uint32_t fsth0 = fdt0 >> 32;
+@@ -3137,31 +3186,31 @@ uint64_t helper_float_recip2_ps(uint64_t fdt0, uint64_t fdt2)
+     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
+     fst2 = float32_chs(float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status));
+     fsth2 = float32_chs(float32_sub(fsth2, FLOAT_ONE32, &env->active_fpu.fp_status));
+-    update_fcr31();
++    update_fcr31(env);
+     return ((uint64_t)fsth2 << 32) | fst2;
+ }
+ 
+-uint64_t helper_float_rsqrt2_d(uint64_t fdt0, uint64_t fdt2)
++uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
+ {
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
+     fdt2 = float64_sub(fdt2, FLOAT_ONE64, &env->active_fpu.fp_status);
+     fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64, &env->active_fpu.fp_status));
+-    update_fcr31();
++    update_fcr31(env);
+     return fdt2;
+ }
+ 
+-uint32_t helper_float_rsqrt2_s(uint32_t fst0, uint32_t fst2)
++uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
+ {
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
+     fst2 = float32_sub(fst2, FLOAT_ONE32, &env->active_fpu.fp_status);
+     fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, &env->active_fpu.fp_status));
+-    update_fcr31();
++    update_fcr31(env);
+     return fst2;
+ }
+ 
+-uint64_t helper_float_rsqrt2_ps(uint64_t fdt0, uint64_t fdt2)
++uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
+ {
+     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
+     uint32_t fsth0 = fdt0 >> 32;
+@@ -3175,11 +3224,11 @@ uint64_t helper_float_rsqrt2_ps(uint64_t fdt0, uint64_t fdt2)
+     fsth2 = float32_sub(fsth2, FLOAT_ONE32, &env->active_fpu.fp_status);
+     fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, &env->active_fpu.fp_status));
+     fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32, &env->active_fpu.fp_status));
+-    update_fcr31();
++    update_fcr31(env);
+     return ((uint64_t)fsth2 << 32) | fst2;
+ }
+ 
+-uint64_t helper_float_addr_ps(uint64_t fdt0, uint64_t fdt1)
++uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
+ {
+     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
+     uint32_t fsth0 = fdt0 >> 32;
+@@ -3191,11 +3240,11 @@ uint64_t helper_float_addr_ps(uint64_t fdt0, uint64_t fdt1)
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = float32_add (fst0, fsth0, &env->active_fpu.fp_status);
+     fsth2 = float32_add (fst1, fsth1, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return ((uint64_t)fsth2 << 32) | fst2;
+ }
+ 
+-uint64_t helper_float_mulr_ps(uint64_t fdt0, uint64_t fdt1)
++uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
+ {
+     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
+     uint32_t fsth0 = fdt0 >> 32;
+@@ -3207,31 +3256,33 @@ uint64_t helper_float_mulr_ps(uint64_t fdt0, uint64_t fdt1)
+     set_float_exception_flags(0, &env->active_fpu.fp_status);
+     fst2 = float32_mul (fst0, fsth0, &env->active_fpu.fp_status);
+     fsth2 = float32_mul (fst1, fsth1, &env->active_fpu.fp_status);
+-    update_fcr31();
++    update_fcr31(env);
+     return ((uint64_t)fsth2 << 32) | fst2;
+ }
+ 
+ /* compare operations */
+ #define FOP_COND_D(op, cond)                                   \
+-void helper_cmp_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
++void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
++                         uint64_t fdt1, int cc)                \
+ {                                                              \
+     int c;                                                     \
+     set_float_exception_flags(0, &env->active_fpu.fp_status);  \
+     c = cond;                                                  \
+-    update_fcr31();                                            \
++    update_fcr31(env);                                         \
+     if (c)                                                     \
+         SET_FP_COND(cc, env->active_fpu);                      \
+     else                                                       \
+         CLEAR_FP_COND(cc, env->active_fpu);                    \
+ }                                                              \
+-void helper_cmpabs_d_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
++void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
++                            uint64_t fdt1, int cc)             \
+ {                                                              \
+     int c;                                                     \
+     set_float_exception_flags(0, &env->active_fpu.fp_status);  \
+     fdt0 = float64_abs(fdt0);                                  \
+     fdt1 = float64_abs(fdt1);                                  \
+     c = cond;                                                  \
+-    update_fcr31();                                            \
++    update_fcr31(env);                                         \
+     if (c)                                                     \
+         SET_FP_COND(cc, env->active_fpu);                      \
+     else                                                       \
+@@ -3260,25 +3311,27 @@ FOP_COND_D(le,  float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+ FOP_COND_D(ngt, float64_unordered(fdt1, fdt0, &env->active_fpu.fp_status)  || float64_le(fdt0, fdt1, &env->active_fpu.fp_status))
+ 
+ #define FOP_COND_S(op, cond)                                   \
+-void helper_cmp_s_ ## op (uint32_t fst0, uint32_t fst1, int cc)    \
++void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,     \
++                         uint32_t fst1, int cc)                \
+ {                                                              \
+     int c;                                                     \
+     set_float_exception_flags(0, &env->active_fpu.fp_status);  \
+     c = cond;                                                  \
+-    update_fcr31();                                            \
++    update_fcr31(env);                                         \
+     if (c)                                                     \
+         SET_FP_COND(cc, env->active_fpu);                      \
+     else                                                       \
+         CLEAR_FP_COND(cc, env->active_fpu);                    \
+ }                                                              \
+-void helper_cmpabs_s_ ## op (uint32_t fst0, uint32_t fst1, int cc) \
++void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0,  \
++                            uint32_t fst1, int cc)             \
+ {                                                              \
+     int c;                                                     \
+     set_float_exception_flags(0, &env->active_fpu.fp_status);  \
+     fst0 = float32_abs(fst0);                                  \
+     fst1 = float32_abs(fst1);                                  \
+     c = cond;                                                  \
+-    update_fcr31();                                            \
++    update_fcr31(env);                                         \
+     if (c)                                                     \
+         SET_FP_COND(cc, env->active_fpu);                      \
+     else                                                       \
+@@ -3307,7 +3360,8 @@ FOP_COND_S(le,  float32_le(fst0, fst1, &env->active_fpu.fp_status))
+ FOP_COND_S(ngt, float32_unordered(fst1, fst0, &env->active_fpu.fp_status)  || float32_le(fst0, fst1, &env->active_fpu.fp_status))
+ 
+ #define FOP_COND_PS(op, condl, condh)                           \
+-void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
++void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
++                          uint64_t fdt1, int cc)                \
+ {                                                               \
+     uint32_t fst0, fsth0, fst1, fsth1;                          \
+     int ch, cl;                                                 \
+@@ -3318,7 +3372,7 @@ void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
+     fsth1 = fdt1 >> 32;                                         \
+     cl = condl;                                                 \
+     ch = condh;                                                 \
+-    update_fcr31();                                             \
++    update_fcr31(env);                                          \
+     if (cl)                                                     \
+         SET_FP_COND(cc, env->active_fpu);                       \
+     else                                                        \
+@@ -3328,7 +3382,8 @@ void helper_cmp_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc)    \
+     else                                                        \
+         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
+ }                                                               \
+-void helper_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
++void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
++                             uint64_t fdt1, int cc)             \
+ {                                                               \
+     uint32_t fst0, fsth0, fst1, fsth1;                          \
+     int ch, cl;                                                 \
+@@ -3338,7 +3393,7 @@ void helper_cmpabs_ps_ ## op (uint64_t fdt0, uint64_t fdt1, int cc) \
+     fsth1 = float32_abs(fdt1 >> 32);                            \
+     cl = condl;                                                 \
+     ch = condh;                                                 \
+-    update_fcr31();                                             \
++    update_fcr31(env);                                          \
+     if (cl)                                                     \
+         SET_FP_COND(cc, env->active_fpu);                       \
+     else                                                        \
+diff --git a/target-mips/translate.c b/target-mips/translate.c
+index b293419..7ab769f 100644
+--- a/target-mips/translate.c
++++ b/target-mips/translate.c
+@@ -483,27 +483,45 @@ static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
+ 
+ #include "gen-icount.h"
+ 
+-#define gen_helper_0i(name, arg) do {                             \
++#define gen_helper_0e0i(name, arg) do {                           \
+     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
+-    gen_helper_##name(helper_tmp);                                \
++    gen_helper_##name(cpu_env, helper_tmp);                       \
+     tcg_temp_free_i32(helper_tmp);                                \
+     } while(0)
+ 
+-#define gen_helper_1i(name, arg1, arg2) do {                      \
++#define gen_helper_0e1i(name, arg1, arg2) do {                    \
+     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
+-    gen_helper_##name(arg1, helper_tmp);                          \
++    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
+     tcg_temp_free_i32(helper_tmp);                                \
+     } while(0)
+ 
+-#define gen_helper_2i(name, arg1, arg2, arg3) do {                \
++#define gen_helper_1e0i(name, ret, arg1) do {                     \
++    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
++    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
++    tcg_temp_free_i32(helper_tmp);                                \
++    } while(0)
++
++#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
++    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
++    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
++    tcg_temp_free_i32(helper_tmp);                                \
++    } while(0)
++
++#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
++    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
++    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
++    tcg_temp_free_i32(helper_tmp);                                \
++    } while(0)
++
++#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
+     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
+-    gen_helper_##name(arg1, arg2, helper_tmp);                    \
++    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
+     tcg_temp_free_i32(helper_tmp);                                \
+     } while(0)
+ 
+-#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
++#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
+     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
+-    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
++    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
+     tcg_temp_free_i32(helper_tmp);                                \
+     } while(0)
+ 
+@@ -748,7 +766,7 @@ generate_exception_err (DisasContext *ctx, int excp, int err)
+     TCGv_i32 texcp = tcg_const_i32(excp);
+     TCGv_i32 terr = tcg_const_i32(err);
+     save_cpu_state(ctx, 1);
+-    gen_helper_raise_exception_err(texcp, terr);
++    gen_helper_raise_exception_err(cpu_env, texcp, terr);
+     tcg_temp_free_i32(terr);
+     tcg_temp_free_i32(texcp);
+ }
+@@ -757,7 +775,7 @@ static inline void
+ generate_exception (DisasContext *ctx, int excp)
+ {
+     save_cpu_state(ctx, 1);
+-    gen_helper_0i(raise_exception, excp);
++    gen_helper_0e0i(raise_exception, excp);
+ }
+ 
+ /* Addresses computation */
+@@ -871,22 +889,22 @@ static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
+     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
+     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
+     switch (n) {                                                              \
+-    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
+-    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
+-    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
+-    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
+-    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
+-    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
+-    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
+-    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
+-    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
+-    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
+-    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
+-    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
+-    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
+-    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
+-    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
+-    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
++    case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
++    case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
++    case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
++    case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
++    case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
++    case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
++    case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
++    case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
++    case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
++    case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
++    case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
++    case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
++    case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
++    case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
++    case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
++    case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
+     default: abort();                                                         \
+     }                                                                         \
+     tcg_temp_free_i##bits (fp0);                                              \
+@@ -948,7 +966,7 @@ static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
+ #define OP_LD_ATOMIC(insn,fname)                                           \
+ static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
+ {                                                                          \
+-    gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
++    gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx);                        \
+ }
+ #endif
+ OP_LD_ATOMIC(ll,ld32s);
+@@ -975,7 +993,7 @@ static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx)
+     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
+     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
+     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
+-    gen_helper_0i(raise_exception, EXCP_SC);                                 \
++    gen_helper_0e0i(raise_exception, EXCP_SC);                               \
+     gen_set_label(l2);                                                       \
+     tcg_gen_movi_tl(t0, 0);                                                  \
+     gen_store_gpr(t0, rt);                                                   \
+@@ -986,7 +1004,7 @@ static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx)
+ static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
+ {                                                                            \
+     TCGv t0 = tcg_temp_new();                                                \
+-    gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
++    gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx);                     \
+     gen_store_gpr(t0, rt);                                                   \
+     tcg_temp_free(t0);                                                       \
+ }
+@@ -1066,14 +1084,14 @@ static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
+     case OPC_LDL:
+         save_cpu_state(ctx, 1);
+         gen_load_gpr(t1, rt);
+-        gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
++        gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
+         gen_store_gpr(t1, rt);
+         opn = "ldl";
+         break;
+     case OPC_LDR:
+         save_cpu_state(ctx, 1);
+         gen_load_gpr(t1, rt);
+-        gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
++        gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
+         gen_store_gpr(t1, rt);
+         opn = "ldr";
+         break;
+@@ -1127,14 +1145,14 @@ static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
+     case OPC_LWL:
+         save_cpu_state(ctx, 1);
+         gen_load_gpr(t1, rt);
+-        gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
++        gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
+         gen_store_gpr(t1, rt);
+         opn = "lwl";
+         break;
+     case OPC_LWR:
+         save_cpu_state(ctx, 1);
+         gen_load_gpr(t1, rt);
+-        gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
++        gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
+         gen_store_gpr(t1, rt);
+         opn = "lwr";
+         break;
+@@ -1170,12 +1188,12 @@ static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
+         break;
+     case OPC_SDL:
+         save_cpu_state(ctx, 1);
+-        gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
++        gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
+         opn = "sdl";
+         break;
+     case OPC_SDR:
+         save_cpu_state(ctx, 1);
+-        gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
++        gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
+         opn = "sdr";
+         break;
+ #endif
+@@ -1196,12 +1214,12 @@ static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
+         break;
+     case OPC_SWL:
+         save_cpu_state(ctx, 1);
+-        gen_helper_2i(swl, t1, t0, ctx->mem_idx);
++        gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
+         opn = "swl";
+         break;
+     case OPC_SWR:
+         save_cpu_state(ctx, 1);
+-        gen_helper_2i(swr, t1, t0, ctx->mem_idx);
++        gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
+         opn = "swr";
+         break;
+     }
+@@ -2138,11 +2156,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
+         opn = "ddivu";
+         break;
+     case OPC_DMULT:
+-        gen_helper_dmult(t0, t1);
++        gen_helper_dmult(cpu_env, t0, t1);
+         opn = "dmult";
+         break;
+     case OPC_DMULTU:
+-        gen_helper_dmultu(t0, t1);
++        gen_helper_dmultu(cpu_env, t0, t1);
+         opn = "dmultu";
+         break;
+ #endif
+@@ -2254,59 +2272,59 @@ static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
+ 
+     switch (opc) {
+     case OPC_VR54XX_MULS:
+-        gen_helper_muls(t0, t0, t1);
++        gen_helper_muls(t0, cpu_env, t0, t1);
+         opn = "muls";
+         break;
+     case OPC_VR54XX_MULSU:
+-        gen_helper_mulsu(t0, t0, t1);
++        gen_helper_mulsu(t0, cpu_env, t0, t1);
+         opn = "mulsu";
+         break;
+     case OPC_VR54XX_MACC:
+-        gen_helper_macc(t0, t0, t1);
++        gen_helper_macc(t0, cpu_env, t0, t1);
+         opn = "macc";
+         break;
+     case OPC_VR54XX_MACCU:
+-        gen_helper_maccu(t0, t0, t1);
++        gen_helper_maccu(t0, cpu_env, t0, t1);
+         opn = "maccu";
+         break;
+     case OPC_VR54XX_MSAC:
+-        gen_helper_msac(t0, t0, t1);
++        gen_helper_msac(t0, cpu_env, t0, t1);
+         opn = "msac";
+         break;
+     case OPC_VR54XX_MSACU:
+-        gen_helper_msacu(t0, t0, t1);
++        gen_helper_msacu(t0, cpu_env, t0, t1);
+         opn = "msacu";
+         break;
+     case OPC_VR54XX_MULHI:
+-        gen_helper_mulhi(t0, t0, t1);
++        gen_helper_mulhi(t0, cpu_env, t0, t1);
+         opn = "mulhi";
+         break;
+     case OPC_VR54XX_MULHIU:
+-        gen_helper_mulhiu(t0, t0, t1);
++        gen_helper_mulhiu(t0, cpu_env, t0, t1);
+         opn = "mulhiu";
+         break;
+     case OPC_VR54XX_MULSHI:
+-        gen_helper_mulshi(t0, t0, t1);
++        gen_helper_mulshi(t0, cpu_env, t0, t1);
+         opn = "mulshi";
+         break;
+     case OPC_VR54XX_MULSHIU:
+-        gen_helper_mulshiu(t0, t0, t1);
++        gen_helper_mulshiu(t0, cpu_env, t0, t1);
+         opn = "mulshiu";
+         break;
+     case OPC_VR54XX_MACCHI:
+-        gen_helper_macchi(t0, t0, t1);
++        gen_helper_macchi(t0, cpu_env, t0, t1);
+         opn = "macchi";
+         break;
+     case OPC_VR54XX_MACCHIU:
+-        gen_helper_macchiu(t0, t0, t1);
++        gen_helper_macchiu(t0, cpu_env, t0, t1);
+         opn = "macchiu";
+         break;
+     case OPC_VR54XX_MSACHI:
+-        gen_helper_msachi(t0, t0, t1);
++        gen_helper_msachi(t0, cpu_env, t0, t1);
+         opn = "msachi";
+         break;
+     case OPC_VR54XX_MSACHIU:
+-        gen_helper_msachiu(t0, t0, t1);
++        gen_helper_msachiu(t0, cpu_env, t0, t1);
+         opn = "msachiu";
+         break;
+     default:
+@@ -2683,7 +2701,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
+         gen_save_pc(dest);
+         if (ctx->singlestep_enabled) {
+             save_cpu_state(ctx, 0);
+-            gen_helper_0i(raise_exception, EXCP_DEBUG);
++            gen_helper_0e0i(raise_exception, EXCP_DEBUG);
+         }
+         tcg_gen_exit_tb(0);
+     }
+@@ -3187,17 +3205,17 @@ static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+             break;
+         case 1:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_mvpcontrol(arg);
++            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
+             rn = "MVPControl";
+             break;
+         case 2:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_mvpconf0(arg);
++            gen_helper_mfc0_mvpconf0(arg, cpu_env);
+             rn = "MVPConf0";
+             break;
+         case 3:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_mvpconf1(arg);
++            gen_helper_mfc0_mvpconf1(arg, cpu_env);
+             rn = "MVPConf1";
+             break;
+         default:
+@@ -3207,7 +3225,7 @@ static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 1:
+         switch (sel) {
+         case 0:
+-            gen_helper_mfc0_random(arg);
++            gen_helper_mfc0_random(arg, cpu_env);
+             rn = "Random";
+             break;
+         case 1:
+@@ -3258,37 +3276,37 @@ static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+             break;
+         case 1:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_tcstatus(arg);
++            gen_helper_mfc0_tcstatus(arg, cpu_env);
+             rn = "TCStatus";
+             break;
+         case 2:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_tcbind(arg);
++            gen_helper_mfc0_tcbind(arg, cpu_env);
+             rn = "TCBind";
+             break;
+         case 3:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_tcrestart(arg);
++            gen_helper_mfc0_tcrestart(arg, cpu_env);
+             rn = "TCRestart";
+             break;
+         case 4:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_tchalt(arg);
++            gen_helper_mfc0_tchalt(arg, cpu_env);
+             rn = "TCHalt";
+             break;
+         case 5:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_tccontext(arg);
++            gen_helper_mfc0_tccontext(arg, cpu_env);
+             rn = "TCContext";
+             break;
+         case 6:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_tcschedule(arg);
++            gen_helper_mfc0_tcschedule(arg, cpu_env);
+             rn = "TCSchedule";
+             break;
+         case 7:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_tcschefback(arg);
++            gen_helper_mfc0_tcschefback(arg, cpu_env);
+             rn = "TCScheFBack";
+             break;
+         default:
+@@ -3399,7 +3417,7 @@ static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+             /* Mark as an IO operation because we read the time.  */
+             if (use_icount)
+                 gen_io_start();
+-            gen_helper_mfc0_count(arg);
++            gen_helper_mfc0_count(arg, cpu_env);
+             if (use_icount) {
+                 gen_io_end();
+             }
+@@ -3531,7 +3549,7 @@ static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 17:
+         switch (sel) {
+         case 0:
+-            gen_helper_mfc0_lladdr(arg);
++            gen_helper_mfc0_lladdr(arg, cpu_env);
+             rn = "LLAddr";
+             break;
+         default:
+@@ -3541,7 +3559,7 @@ static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 18:
+         switch (sel) {
+         case 0 ... 7:
+-            gen_helper_1i(mfc0_watchlo, arg, sel);
++            gen_helper_1e0i(mfc0_watchlo, arg, sel);
+             rn = "WatchLo";
+             break;
+         default:
+@@ -3551,7 +3569,7 @@ static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 19:
+         switch (sel) {
+         case 0 ...7:
+-            gen_helper_1i(mfc0_watchhi, arg, sel);
++            gen_helper_1e0i(mfc0_watchhi, arg, sel);
+             rn = "WatchHi";
+             break;
+         default:
+@@ -3590,7 +3608,7 @@ static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 23:
+         switch (sel) {
+         case 0:
+-            gen_helper_mfc0_debug(arg); /* EJTAG support */
++            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
+             rn = "Debug";
+             break;
+         case 1:
+@@ -3765,12 +3783,12 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 0:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_index(arg);
++            gen_helper_mtc0_index(cpu_env, arg);
+             rn = "Index";
+             break;
+         case 1:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_mvpcontrol(arg);
++            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
+             rn = "MVPControl";
+             break;
+         case 2:
+@@ -3795,22 +3813,22 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+             break;
+         case 1:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_vpecontrol(arg);
++            gen_helper_mtc0_vpecontrol(cpu_env, arg);
+             rn = "VPEControl";
+             break;
+         case 2:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_vpeconf0(arg);
++            gen_helper_mtc0_vpeconf0(cpu_env, arg);
+             rn = "VPEConf0";
+             break;
+         case 3:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_vpeconf1(arg);
++            gen_helper_mtc0_vpeconf1(cpu_env, arg);
+             rn = "VPEConf1";
+             break;
+         case 4:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_yqmask(arg);
++            gen_helper_mtc0_yqmask(cpu_env, arg);
+             rn = "YQMask";
+             break;
+         case 5:
+@@ -3825,7 +3843,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+             break;
+         case 7:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_vpeopt(arg);
++            gen_helper_mtc0_vpeopt(cpu_env, arg);
+             rn = "VPEOpt";
+             break;
+         default:
+@@ -3835,42 +3853,42 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 2:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_entrylo0(arg);
++            gen_helper_mtc0_entrylo0(cpu_env, arg);
+             rn = "EntryLo0";
+             break;
+         case 1:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tcstatus(arg);
++            gen_helper_mtc0_tcstatus(cpu_env, arg);
+             rn = "TCStatus";
+             break;
+         case 2:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tcbind(arg);
++            gen_helper_mtc0_tcbind(cpu_env, arg);
+             rn = "TCBind";
+             break;
+         case 3:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tcrestart(arg);
++            gen_helper_mtc0_tcrestart(cpu_env, arg);
+             rn = "TCRestart";
+             break;
+         case 4:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tchalt(arg);
++            gen_helper_mtc0_tchalt(cpu_env, arg);
+             rn = "TCHalt";
+             break;
+         case 5:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tccontext(arg);
++            gen_helper_mtc0_tccontext(cpu_env, arg);
+             rn = "TCContext";
+             break;
+         case 6:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tcschedule(arg);
++            gen_helper_mtc0_tcschedule(cpu_env, arg);
+             rn = "TCSchedule";
+             break;
+         case 7:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tcschefback(arg);
++            gen_helper_mtc0_tcschefback(cpu_env, arg);
+             rn = "TCScheFBack";
+             break;
+         default:
+@@ -3880,7 +3898,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 3:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_entrylo1(arg);
++            gen_helper_mtc0_entrylo1(cpu_env, arg);
+             rn = "EntryLo1";
+             break;
+         default:
+@@ -3890,11 +3908,11 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 4:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_context(arg);
++            gen_helper_mtc0_context(cpu_env, arg);
+             rn = "Context";
+             break;
+         case 1:
+-//            gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
++//            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
+             rn = "ContextConfig";
+ //            break;
+         default:
+@@ -3904,12 +3922,12 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 5:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_pagemask(arg);
++            gen_helper_mtc0_pagemask(cpu_env, arg);
+             rn = "PageMask";
+             break;
+         case 1:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_pagegrain(arg);
++            gen_helper_mtc0_pagegrain(cpu_env, arg);
+             rn = "PageGrain";
+             break;
+         default:
+@@ -3919,32 +3937,32 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 6:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_wired(arg);
++            gen_helper_mtc0_wired(cpu_env, arg);
+             rn = "Wired";
+             break;
+         case 1:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsconf0(arg);
++            gen_helper_mtc0_srsconf0(cpu_env, arg);
+             rn = "SRSConf0";
+             break;
+         case 2:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsconf1(arg);
++            gen_helper_mtc0_srsconf1(cpu_env, arg);
+             rn = "SRSConf1";
+             break;
+         case 3:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsconf2(arg);
++            gen_helper_mtc0_srsconf2(cpu_env, arg);
+             rn = "SRSConf2";
+             break;
+         case 4:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsconf3(arg);
++            gen_helper_mtc0_srsconf3(cpu_env, arg);
+             rn = "SRSConf3";
+             break;
+         case 5:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsconf4(arg);
++            gen_helper_mtc0_srsconf4(cpu_env, arg);
+             rn = "SRSConf4";
+             break;
+         default:
+@@ -3955,7 +3973,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+         switch (sel) {
+         case 0:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_hwrena(arg);
++            gen_helper_mtc0_hwrena(cpu_env, arg);
+             rn = "HWREna";
+             break;
+         default:
+@@ -3969,7 +3987,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 9:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_count(arg);
++            gen_helper_mtc0_count(cpu_env, arg);
+             rn = "Count";
+             break;
+         /* 6,7 are implementation dependent */
+@@ -3980,7 +3998,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 10:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_entryhi(arg);
++            gen_helper_mtc0_entryhi(cpu_env, arg);
+             rn = "EntryHi";
+             break;
+         default:
+@@ -3990,7 +4008,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 11:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_compare(arg);
++            gen_helper_mtc0_compare(cpu_env, arg);
+             rn = "Compare";
+             break;
+         /* 6,7 are implementation dependent */
+@@ -4002,7 +4020,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+         switch (sel) {
+         case 0:
+             save_cpu_state(ctx, 1);
+-            gen_helper_mtc0_status(arg);
++            gen_helper_mtc0_status(cpu_env, arg);
+             /* BS_STOP isn't good enough here, hflags may have changed. */
+             gen_save_pc(ctx->pc + 4);
+             ctx->bstate = BS_EXCP;
+@@ -4010,14 +4028,14 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+             break;
+         case 1:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_intctl(arg);
++            gen_helper_mtc0_intctl(cpu_env, arg);
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+             rn = "IntCtl";
+             break;
+         case 2:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsctl(arg);
++            gen_helper_mtc0_srsctl(cpu_env, arg);
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+             rn = "SRSCtl";
+@@ -4037,7 +4055,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+         switch (sel) {
+         case 0:
+             save_cpu_state(ctx, 1);
+-            gen_helper_mtc0_cause(arg);
++            gen_helper_mtc0_cause(cpu_env, arg);
+             rn = "Cause";
+             break;
+         default:
+@@ -4062,7 +4080,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+             break;
+         case 1:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_ebase(arg);
++            gen_helper_mtc0_ebase(cpu_env, arg);
+             rn = "EBase";
+             break;
+         default:
+@@ -4072,7 +4090,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 16:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_config0(arg);
++            gen_helper_mtc0_config0(cpu_env, arg);
+             rn = "Config";
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+@@ -4082,7 +4100,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+             rn = "Config1";
+             break;
+         case 2:
+-            gen_helper_mtc0_config2(arg);
++            gen_helper_mtc0_config2(cpu_env, arg);
+             rn = "Config2";
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+@@ -4109,7 +4127,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 17:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_lladdr(arg);
++            gen_helper_mtc0_lladdr(cpu_env, arg);
+             rn = "LLAddr";
+             break;
+         default:
+@@ -4119,7 +4137,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 18:
+         switch (sel) {
+         case 0 ... 7:
+-            gen_helper_1i(mtc0_watchlo, arg, sel);
++            gen_helper_0e1i(mtc0_watchlo, arg, sel);
+             rn = "WatchLo";
+             break;
+         default:
+@@ -4129,7 +4147,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 19:
+         switch (sel) {
+         case 0 ... 7:
+-            gen_helper_1i(mtc0_watchhi, arg, sel);
++            gen_helper_0e1i(mtc0_watchhi, arg, sel);
+             rn = "WatchHi";
+             break;
+         default:
+@@ -4141,7 +4159,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+         case 0:
+ #if defined(TARGET_MIPS64)
+             check_insn(env, ctx, ISA_MIPS3);
+-            gen_helper_mtc0_xcontext(arg);
++            gen_helper_mtc0_xcontext(cpu_env, arg);
+             rn = "XContext";
+             break;
+ #endif
+@@ -4153,7 +4171,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+        /* Officially reserved, but sel 0 is used for R1x000 framemask */
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_framemask(arg);
++            gen_helper_mtc0_framemask(cpu_env, arg);
+             rn = "Framemask";
+             break;
+         default:
+@@ -4167,20 +4185,20 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 23:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_debug(arg); /* EJTAG support */
++            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
+             /* BS_STOP isn't good enough here, hflags may have changed. */
+             gen_save_pc(ctx->pc + 4);
+             ctx->bstate = BS_EXCP;
+             rn = "Debug";
+             break;
+         case 1:
+-//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
++//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
+             rn = "TraceControl";
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+ //            break;
+         case 2:
+-//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
++//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
+             rn = "TraceControl2";
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+@@ -4188,13 +4206,13 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+         case 3:
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+-//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
++//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
+             rn = "UserTraceData";
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+ //            break;
+         case 4:
+-//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
++//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+             rn = "TraceBPC";
+@@ -4217,7 +4235,7 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+     case 25:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_performance0(arg);
++            gen_helper_mtc0_performance0(cpu_env, arg);
+             rn = "Performance0";
+             break;
+         case 1:
+@@ -4272,14 +4290,14 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+         case 2:
+         case 4:
+         case 6:
+-            gen_helper_mtc0_taglo(arg);
++            gen_helper_mtc0_taglo(cpu_env, arg);
+             rn = "TagLo";
+             break;
+         case 1:
+         case 3:
+         case 5:
+         case 7:
+-            gen_helper_mtc0_datalo(arg);
++            gen_helper_mtc0_datalo(cpu_env, arg);
+             rn = "DataLo";
+             break;
+         default:
+@@ -4292,14 +4310,14 @@ static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, i
+         case 2:
+         case 4:
+         case 6:
+-            gen_helper_mtc0_taghi(arg);
++            gen_helper_mtc0_taghi(cpu_env, arg);
+             rn = "TagHi";
+             break;
+         case 1:
+         case 3:
+         case 5:
+         case 7:
+-            gen_helper_mtc0_datahi(arg);
++            gen_helper_mtc0_datahi(cpu_env, arg);
+             rn = "DataHi";
+             break;
+         default:
+@@ -4364,17 +4382,17 @@ static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+             break;
+         case 1:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_mvpcontrol(arg);
++            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
+             rn = "MVPControl";
+             break;
+         case 2:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_mvpconf0(arg);
++            gen_helper_mfc0_mvpconf0(arg, cpu_env);
+             rn = "MVPConf0";
+             break;
+         case 3:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_mvpconf1(arg);
++            gen_helper_mfc0_mvpconf1(arg, cpu_env);
+             rn = "MVPConf1";
+             break;
+         default:
+@@ -4384,7 +4402,7 @@ static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 1:
+         switch (sel) {
+         case 0:
+-            gen_helper_mfc0_random(arg);
++            gen_helper_mfc0_random(arg, cpu_env);
+             rn = "Random";
+             break;
+         case 1:
+@@ -4434,37 +4452,37 @@ static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+             break;
+         case 1:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_tcstatus(arg);
++            gen_helper_mfc0_tcstatus(arg, cpu_env);
+             rn = "TCStatus";
+             break;
+         case 2:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mfc0_tcbind(arg);
++            gen_helper_mfc0_tcbind(arg, cpu_env);
+             rn = "TCBind";
+             break;
+         case 3:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_dmfc0_tcrestart(arg);
++            gen_helper_dmfc0_tcrestart(arg, cpu_env);
+             rn = "TCRestart";
+             break;
+         case 4:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_dmfc0_tchalt(arg);
++            gen_helper_dmfc0_tchalt(arg, cpu_env);
+             rn = "TCHalt";
+             break;
+         case 5:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_dmfc0_tccontext(arg);
++            gen_helper_dmfc0_tccontext(arg, cpu_env);
+             rn = "TCContext";
+             break;
+         case 6:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_dmfc0_tcschedule(arg);
++            gen_helper_dmfc0_tcschedule(arg, cpu_env);
+             rn = "TCSchedule";
+             break;
+         case 7:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_dmfc0_tcschefback(arg);
++            gen_helper_dmfc0_tcschefback(arg, cpu_env);
+             rn = "TCScheFBack";
+             break;
+         default:
+@@ -4572,7 +4590,7 @@ static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+             /* Mark as an IO operation because we read the time.  */
+             if (use_icount)
+                 gen_io_start();
+-            gen_helper_mfc0_count(arg);
++            gen_helper_mfc0_count(arg, cpu_env);
+             if (use_icount) {
+                 gen_io_end();
+             }
+@@ -4701,7 +4719,7 @@ static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 17:
+         switch (sel) {
+         case 0:
+-            gen_helper_dmfc0_lladdr(arg);
++            gen_helper_dmfc0_lladdr(arg, cpu_env);
+             rn = "LLAddr";
+             break;
+         default:
+@@ -4711,7 +4729,7 @@ static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 18:
+         switch (sel) {
+         case 0 ... 7:
+-            gen_helper_1i(dmfc0_watchlo, arg, sel);
++            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
+             rn = "WatchLo";
+             break;
+         default:
+@@ -4721,7 +4739,7 @@ static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 19:
+         switch (sel) {
+         case 0 ... 7:
+-            gen_helper_1i(mfc0_watchhi, arg, sel);
++            gen_helper_1e0i(mfc0_watchhi, arg, sel);
+             rn = "WatchHi";
+             break;
+         default:
+@@ -4757,23 +4775,23 @@ static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 23:
+         switch (sel) {
+         case 0:
+-            gen_helper_mfc0_debug(arg); /* EJTAG support */
++            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
+             rn = "Debug";
+             break;
+         case 1:
+-//            gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
++//            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
+             rn = "TraceControl";
+ //            break;
+         case 2:
+-//            gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
++//            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
+             rn = "TraceControl2";
+ //            break;
+         case 3:
+-//            gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
++//            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
+             rn = "UserTraceData";
+ //            break;
+         case 4:
+-//            gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
++//            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
+             rn = "TraceBPC";
+ //            break;
+         default:
+@@ -4931,12 +4949,12 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 0:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_index(arg);
++            gen_helper_mtc0_index(cpu_env, arg);
+             rn = "Index";
+             break;
+         case 1:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_mvpcontrol(arg);
++            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
+             rn = "MVPControl";
+             break;
+         case 2:
+@@ -4961,22 +4979,22 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+             break;
+         case 1:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_vpecontrol(arg);
++            gen_helper_mtc0_vpecontrol(cpu_env, arg);
+             rn = "VPEControl";
+             break;
+         case 2:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_vpeconf0(arg);
++            gen_helper_mtc0_vpeconf0(cpu_env, arg);
+             rn = "VPEConf0";
+             break;
+         case 3:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_vpeconf1(arg);
++            gen_helper_mtc0_vpeconf1(cpu_env, arg);
+             rn = "VPEConf1";
+             break;
+         case 4:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_yqmask(arg);
++            gen_helper_mtc0_yqmask(cpu_env, arg);
+             rn = "YQMask";
+             break;
+         case 5:
+@@ -4991,7 +5009,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+             break;
+         case 7:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_vpeopt(arg);
++            gen_helper_mtc0_vpeopt(cpu_env, arg);
+             rn = "VPEOpt";
+             break;
+         default:
+@@ -5001,42 +5019,42 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 2:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_entrylo0(arg);
++            gen_helper_mtc0_entrylo0(cpu_env, arg);
+             rn = "EntryLo0";
+             break;
+         case 1:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tcstatus(arg);
++            gen_helper_mtc0_tcstatus(cpu_env, arg);
+             rn = "TCStatus";
+             break;
+         case 2:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tcbind(arg);
++            gen_helper_mtc0_tcbind(cpu_env, arg);
+             rn = "TCBind";
+             break;
+         case 3:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tcrestart(arg);
++            gen_helper_mtc0_tcrestart(cpu_env, arg);
+             rn = "TCRestart";
+             break;
+         case 4:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tchalt(arg);
++            gen_helper_mtc0_tchalt(cpu_env, arg);
+             rn = "TCHalt";
+             break;
+         case 5:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tccontext(arg);
++            gen_helper_mtc0_tccontext(cpu_env, arg);
+             rn = "TCContext";
+             break;
+         case 6:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tcschedule(arg);
++            gen_helper_mtc0_tcschedule(cpu_env, arg);
+             rn = "TCSchedule";
+             break;
+         case 7:
+             check_insn(env, ctx, ASE_MT);
+-            gen_helper_mtc0_tcschefback(arg);
++            gen_helper_mtc0_tcschefback(cpu_env, arg);
+             rn = "TCScheFBack";
+             break;
+         default:
+@@ -5046,7 +5064,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 3:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_entrylo1(arg);
++            gen_helper_mtc0_entrylo1(cpu_env, arg);
+             rn = "EntryLo1";
+             break;
+         default:
+@@ -5056,11 +5074,11 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 4:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_context(arg);
++            gen_helper_mtc0_context(cpu_env, arg);
+             rn = "Context";
+             break;
+         case 1:
+-//           gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
++//           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
+             rn = "ContextConfig";
+ //           break;
+         default:
+@@ -5070,12 +5088,12 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 5:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_pagemask(arg);
++            gen_helper_mtc0_pagemask(cpu_env, arg);
+             rn = "PageMask";
+             break;
+         case 1:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_pagegrain(arg);
++            gen_helper_mtc0_pagegrain(cpu_env, arg);
+             rn = "PageGrain";
+             break;
+         default:
+@@ -5085,32 +5103,32 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 6:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_wired(arg);
++            gen_helper_mtc0_wired(cpu_env, arg);
+             rn = "Wired";
+             break;
+         case 1:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsconf0(arg);
++            gen_helper_mtc0_srsconf0(cpu_env, arg);
+             rn = "SRSConf0";
+             break;
+         case 2:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsconf1(arg);
++            gen_helper_mtc0_srsconf1(cpu_env, arg);
+             rn = "SRSConf1";
+             break;
+         case 3:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsconf2(arg);
++            gen_helper_mtc0_srsconf2(cpu_env, arg);
+             rn = "SRSConf2";
+             break;
+         case 4:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsconf3(arg);
++            gen_helper_mtc0_srsconf3(cpu_env, arg);
+             rn = "SRSConf3";
+             break;
+         case 5:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsconf4(arg);
++            gen_helper_mtc0_srsconf4(cpu_env, arg);
+             rn = "SRSConf4";
+             break;
+         default:
+@@ -5121,7 +5139,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+         switch (sel) {
+         case 0:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_hwrena(arg);
++            gen_helper_mtc0_hwrena(cpu_env, arg);
+             rn = "HWREna";
+             break;
+         default:
+@@ -5135,7 +5153,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 9:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_count(arg);
++            gen_helper_mtc0_count(cpu_env, arg);
+             rn = "Count";
+             break;
+         /* 6,7 are implementation dependent */
+@@ -5148,7 +5166,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 10:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_entryhi(arg);
++            gen_helper_mtc0_entryhi(cpu_env, arg);
+             rn = "EntryHi";
+             break;
+         default:
+@@ -5158,7 +5176,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 11:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_compare(arg);
++            gen_helper_mtc0_compare(cpu_env, arg);
+             rn = "Compare";
+             break;
+         /* 6,7 are implementation dependent */
+@@ -5172,7 +5190,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+         switch (sel) {
+         case 0:
+             save_cpu_state(ctx, 1);
+-            gen_helper_mtc0_status(arg);
++            gen_helper_mtc0_status(cpu_env, arg);
+             /* BS_STOP isn't good enough here, hflags may have changed. */
+             gen_save_pc(ctx->pc + 4);
+             ctx->bstate = BS_EXCP;
+@@ -5180,14 +5198,14 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+             break;
+         case 1:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_intctl(arg);
++            gen_helper_mtc0_intctl(cpu_env, arg);
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+             rn = "IntCtl";
+             break;
+         case 2:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_srsctl(arg);
++            gen_helper_mtc0_srsctl(cpu_env, arg);
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+             rn = "SRSCtl";
+@@ -5212,7 +5230,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+             if (use_icount) {
+                 gen_io_start();
+             }
+-            gen_helper_mtc0_cause(arg);
++            gen_helper_mtc0_cause(cpu_env, arg);
+             if (use_icount) {
+                 gen_io_end();
+             }
+@@ -5242,7 +5260,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+             break;
+         case 1:
+             check_insn(env, ctx, ISA_MIPS32R2);
+-            gen_helper_mtc0_ebase(arg);
++            gen_helper_mtc0_ebase(cpu_env, arg);
+             rn = "EBase";
+             break;
+         default:
+@@ -5252,7 +5270,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 16:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_config0(arg);
++            gen_helper_mtc0_config0(cpu_env, arg);
+             rn = "Config";
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+@@ -5262,7 +5280,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+             rn = "Config1";
+             break;
+         case 2:
+-            gen_helper_mtc0_config2(arg);
++            gen_helper_mtc0_config2(cpu_env, arg);
+             rn = "Config2";
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+@@ -5280,7 +5298,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 17:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_lladdr(arg);
++            gen_helper_mtc0_lladdr(cpu_env, arg);
+             rn = "LLAddr";
+             break;
+         default:
+@@ -5290,7 +5308,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 18:
+         switch (sel) {
+         case 0 ... 7:
+-            gen_helper_1i(mtc0_watchlo, arg, sel);
++            gen_helper_0e1i(mtc0_watchlo, arg, sel);
+             rn = "WatchLo";
+             break;
+         default:
+@@ -5300,7 +5318,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 19:
+         switch (sel) {
+         case 0 ... 7:
+-            gen_helper_1i(mtc0_watchhi, arg, sel);
++            gen_helper_0e1i(mtc0_watchhi, arg, sel);
+             rn = "WatchHi";
+             break;
+         default:
+@@ -5311,7 +5329,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+         switch (sel) {
+         case 0:
+             check_insn(env, ctx, ISA_MIPS3);
+-            gen_helper_mtc0_xcontext(arg);
++            gen_helper_mtc0_xcontext(cpu_env, arg);
+             rn = "XContext";
+             break;
+         default:
+@@ -5322,7 +5340,7 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+        /* Officially reserved, but sel 0 is used for R1x000 framemask */
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_framemask(arg);
++            gen_helper_mtc0_framemask(cpu_env, arg);
+             rn = "Framemask";
+             break;
+         default:
+@@ -5336,32 +5354,32 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 23:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_debug(arg); /* EJTAG support */
++            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
+             /* BS_STOP isn't good enough here, hflags may have changed. */
+             gen_save_pc(ctx->pc + 4);
+             ctx->bstate = BS_EXCP;
+             rn = "Debug";
+             break;
+         case 1:
+-//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
++//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+             rn = "TraceControl";
+ //            break;
+         case 2:
+-//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
++//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+             rn = "TraceControl2";
+ //            break;
+         case 3:
+-//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
++//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+             rn = "UserTraceData";
+ //            break;
+         case 4:
+-//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
++//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
+             /* Stop translation as we may have switched the execution mode */
+             ctx->bstate = BS_STOP;
+             rn = "TraceBPC";
+@@ -5384,35 +5402,35 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+     case 25:
+         switch (sel) {
+         case 0:
+-            gen_helper_mtc0_performance0(arg);
++            gen_helper_mtc0_performance0(cpu_env, arg);
+             rn = "Performance0";
+             break;
+         case 1:
+-//            gen_helper_mtc0_performance1(arg);
++//            gen_helper_mtc0_performance1(cpu_env, arg);
+             rn = "Performance1";
+ //            break;
+         case 2:
+-//            gen_helper_mtc0_performance2(arg);
++//            gen_helper_mtc0_performance2(cpu_env, arg);
+             rn = "Performance2";
+ //            break;
+         case 3:
+-//            gen_helper_mtc0_performance3(arg);
++//            gen_helper_mtc0_performance3(cpu_env, arg);
+             rn = "Performance3";
+ //            break;
+         case 4:
+-//            gen_helper_mtc0_performance4(arg);
++//            gen_helper_mtc0_performance4(cpu_env, arg);
+             rn = "Performance4";
+ //            break;
+         case 5:
+-//            gen_helper_mtc0_performance5(arg);
++//            gen_helper_mtc0_performance5(cpu_env, arg);
+             rn = "Performance5";
+ //            break;
+         case 6:
+-//            gen_helper_mtc0_performance6(arg);
++//            gen_helper_mtc0_performance6(cpu_env, arg);
+             rn = "Performance6";
+ //            break;
+         case 7:
+-//            gen_helper_mtc0_performance7(arg);
++//            gen_helper_mtc0_performance7(cpu_env, arg);
+             rn = "Performance7";
+ //            break;
+         default:
+@@ -5439,14 +5457,14 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+         case 2:
+         case 4:
+         case 6:
+-            gen_helper_mtc0_taglo(arg);
++            gen_helper_mtc0_taglo(cpu_env, arg);
+             rn = "TagLo";
+             break;
+         case 1:
+         case 3:
+         case 5:
+         case 7:
+-            gen_helper_mtc0_datalo(arg);
++            gen_helper_mtc0_datalo(cpu_env, arg);
+             rn = "DataLo";
+             break;
+         default:
+@@ -5459,14 +5477,14 @@ static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg,
+         case 2:
+         case 4:
+         case 6:
+-            gen_helper_mtc0_taghi(arg);
++            gen_helper_mtc0_taghi(cpu_env, arg);
+             rn = "TagHi";
+             break;
+         case 1:
+         case 3:
+         case 5:
+         case 7:
+-            gen_helper_mtc0_datahi(arg);
++            gen_helper_mtc0_datahi(cpu_env, arg);
+             rn = "DataHi";
+             break;
+         default:
+@@ -5533,10 +5551,10 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+         case 1:
+             switch (sel) {
+             case 1:
+-                gen_helper_mftc0_vpecontrol(t0);
++                gen_helper_mftc0_vpecontrol(t0, cpu_env);
+                 break;
+             case 2:
+-                gen_helper_mftc0_vpeconf0(t0);
++                gen_helper_mftc0_vpeconf0(t0, cpu_env);
+                 break;
+             default:
+                 goto die;
+@@ -5546,25 +5564,25 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+         case 2:
+             switch (sel) {
+             case 1:
+-                gen_helper_mftc0_tcstatus(t0);
++                gen_helper_mftc0_tcstatus(t0, cpu_env);
+                 break;
+             case 2:
+-                gen_helper_mftc0_tcbind(t0);
++                gen_helper_mftc0_tcbind(t0, cpu_env);
+                 break;
+             case 3:
+-                gen_helper_mftc0_tcrestart(t0);
++                gen_helper_mftc0_tcrestart(t0, cpu_env);
+                 break;
+             case 4:
+-                gen_helper_mftc0_tchalt(t0);
++                gen_helper_mftc0_tchalt(t0, cpu_env);
+                 break;
+             case 5:
+-                gen_helper_mftc0_tccontext(t0);
++                gen_helper_mftc0_tccontext(t0, cpu_env);
+                 break;
+             case 6:
+-                gen_helper_mftc0_tcschedule(t0);
++                gen_helper_mftc0_tcschedule(t0, cpu_env);
+                 break;
+             case 7:
+-                gen_helper_mftc0_tcschefback(t0);
++                gen_helper_mftc0_tcschefback(t0, cpu_env);
+                 break;
+             default:
+                 gen_mfc0(env, ctx, t0, rt, sel);
+@@ -5574,7 +5592,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+         case 10:
+             switch (sel) {
+             case 0:
+-                gen_helper_mftc0_entryhi(t0);
++                gen_helper_mftc0_entryhi(t0, cpu_env);
+                 break;
+             default:
+                 gen_mfc0(env, ctx, t0, rt, sel);
+@@ -5583,7 +5601,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+         case 12:
+             switch (sel) {
+             case 0:
+-                gen_helper_mftc0_status(t0);
++                gen_helper_mftc0_status(t0, cpu_env);
+                 break;
+             default:
+                 gen_mfc0(env, ctx, t0, rt, sel);
+@@ -5592,7 +5610,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+         case 13:
+             switch (sel) {
+             case 0:
+-                gen_helper_mftc0_cause(t0);
++                gen_helper_mftc0_cause(t0, cpu_env);
+                 break;
+             default:
+                 goto die;
+@@ -5602,7 +5620,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+         case 14:
+             switch (sel) {
+             case 0:
+-                gen_helper_mftc0_epc(t0);
++                gen_helper_mftc0_epc(t0, cpu_env);
+                 break;
+             default:
+                 goto die;
+@@ -5612,7 +5630,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+         case 15:
+             switch (sel) {
+             case 1:
+-                gen_helper_mftc0_ebase(t0);
++                gen_helper_mftc0_ebase(t0, cpu_env);
+                 break;
+             default:
+                 goto die;
+@@ -5622,7 +5640,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+         case 16:
+             switch (sel) {
+             case 0 ... 7:
+-                gen_helper_mftc0_configx(t0, tcg_const_tl(sel));
++                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
+                 break;
+             default:
+                 goto die;
+@@ -5632,7 +5650,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+         case 23:
+             switch (sel) {
+             case 0:
+-                gen_helper_mftc0_debug(t0);
++                gen_helper_mftc0_debug(t0, cpu_env);
+                 break;
+             default:
+                 gen_mfc0(env, ctx, t0, rt, sel);
+@@ -5645,49 +5663,49 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+     } else switch (sel) {
+     /* GPR registers. */
+     case 0:
+-        gen_helper_1i(mftgpr, t0, rt);
++        gen_helper_1e0i(mftgpr, t0, rt);
+         break;
+     /* Auxiliary CPU registers */
+     case 1:
+         switch (rt) {
+         case 0:
+-            gen_helper_1i(mftlo, t0, 0);
++            gen_helper_1e0i(mftlo, t0, 0);
+             break;
+         case 1:
+-            gen_helper_1i(mfthi, t0, 0);
++            gen_helper_1e0i(mfthi, t0, 0);
+             break;
+         case 2:
+-            gen_helper_1i(mftacx, t0, 0);
++            gen_helper_1e0i(mftacx, t0, 0);
+             break;
+         case 4:
+-            gen_helper_1i(mftlo, t0, 1);
++            gen_helper_1e0i(mftlo, t0, 1);
+             break;
+         case 5:
+-            gen_helper_1i(mfthi, t0, 1);
++            gen_helper_1e0i(mfthi, t0, 1);
+             break;
+         case 6:
+-            gen_helper_1i(mftacx, t0, 1);
++            gen_helper_1e0i(mftacx, t0, 1);
+             break;
+         case 8:
+-            gen_helper_1i(mftlo, t0, 2);
++            gen_helper_1e0i(mftlo, t0, 2);
+             break;
+         case 9:
+-            gen_helper_1i(mfthi, t0, 2);
++            gen_helper_1e0i(mfthi, t0, 2);
+             break;
+         case 10:
+-            gen_helper_1i(mftacx, t0, 2);
++            gen_helper_1e0i(mftacx, t0, 2);
+             break;
+         case 12:
+-            gen_helper_1i(mftlo, t0, 3);
++            gen_helper_1e0i(mftlo, t0, 3);
+             break;
+         case 13:
+-            gen_helper_1i(mfthi, t0, 3);
++            gen_helper_1e0i(mfthi, t0, 3);
+             break;
+         case 14:
+-            gen_helper_1i(mftacx, t0, 3);
++            gen_helper_1e0i(mftacx, t0, 3);
+             break;
+         case 16:
+-            gen_helper_mftdsp(t0);
++            gen_helper_mftdsp(t0, cpu_env);
+             break;
+         default:
+             goto die;
+@@ -5712,7 +5730,7 @@ static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
+         break;
+     case 3:
+         /* XXX: For now we support only a single FPU context. */
+-        gen_helper_1i(cfc1, t0, rt);
++        gen_helper_1e0i(cfc1, t0, rt);
+         break;
+     /* COP2: Not implemented. */
+     case 4:
+@@ -5751,10 +5769,10 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
+         case 1:
+             switch (sel) {
+             case 1:
+-                gen_helper_mttc0_vpecontrol(t0);
++                gen_helper_mttc0_vpecontrol(cpu_env, t0);
+                 break;
+             case 2:
+-                gen_helper_mttc0_vpeconf0(t0);
++                gen_helper_mttc0_vpeconf0(cpu_env, t0);
+                 break;
+             default:
+                 goto die;
+@@ -5764,25 +5782,25 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
+         case 2:
+             switch (sel) {
+             case 1:
+-                gen_helper_mttc0_tcstatus(t0);
++                gen_helper_mttc0_tcstatus(cpu_env, t0);
+                 break;
+             case 2:
+-                gen_helper_mttc0_tcbind(t0);
++                gen_helper_mttc0_tcbind(cpu_env, t0);
+                 break;
+             case 3:
+-                gen_helper_mttc0_tcrestart(t0);
++                gen_helper_mttc0_tcrestart(cpu_env, t0);
+                 break;
+             case 4:
+-                gen_helper_mttc0_tchalt(t0);
++                gen_helper_mttc0_tchalt(cpu_env, t0);
+                 break;
+             case 5:
+-                gen_helper_mttc0_tccontext(t0);
++                gen_helper_mttc0_tccontext(cpu_env, t0);
+                 break;
+             case 6:
+-                gen_helper_mttc0_tcschedule(t0);
++                gen_helper_mttc0_tcschedule(cpu_env, t0);
+                 break;
+             case 7:
+-                gen_helper_mttc0_tcschefback(t0);
++                gen_helper_mttc0_tcschefback(cpu_env, t0);
+                 break;
+             default:
+                 gen_mtc0(env, ctx, t0, rd, sel);
+@@ -5792,7 +5810,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
+         case 10:
+             switch (sel) {
+             case 0:
+-                gen_helper_mttc0_entryhi(t0);
++                gen_helper_mttc0_entryhi(cpu_env, t0);
+                 break;
+             default:
+                 gen_mtc0(env, ctx, t0, rd, sel);
+@@ -5801,7 +5819,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
+         case 12:
+             switch (sel) {
+             case 0:
+-                gen_helper_mttc0_status(t0);
++                gen_helper_mttc0_status(cpu_env, t0);
+                 break;
+             default:
+                 gen_mtc0(env, ctx, t0, rd, sel);
+@@ -5810,7 +5828,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
+         case 13:
+             switch (sel) {
+             case 0:
+-                gen_helper_mttc0_cause(t0);
++                gen_helper_mttc0_cause(cpu_env, t0);
+                 break;
+             default:
+                 goto die;
+@@ -5820,7 +5838,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
+         case 15:
+             switch (sel) {
+             case 1:
+-                gen_helper_mttc0_ebase(t0);
++                gen_helper_mttc0_ebase(cpu_env, t0);
+                 break;
+             default:
+                 goto die;
+@@ -5830,7 +5848,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
+         case 23:
+             switch (sel) {
+             case 0:
+-                gen_helper_mttc0_debug(t0);
++                gen_helper_mttc0_debug(cpu_env, t0);
+                 break;
+             default:
+                 gen_mtc0(env, ctx, t0, rd, sel);
+@@ -5843,49 +5861,49 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
+     } else switch (sel) {
+     /* GPR registers. */
+     case 0:
+-        gen_helper_1i(mttgpr, t0, rd);
++        gen_helper_0e1i(mttgpr, t0, rd);
+         break;
+     /* Auxiliary CPU registers */
+     case 1:
+         switch (rd) {
+         case 0:
+-            gen_helper_1i(mttlo, t0, 0);
++            gen_helper_0e1i(mttlo, t0, 0);
+             break;
+         case 1:
+-            gen_helper_1i(mtthi, t0, 0);
++            gen_helper_0e1i(mtthi, t0, 0);
+             break;
+         case 2:
+-            gen_helper_1i(mttacx, t0, 0);
++            gen_helper_0e1i(mttacx, t0, 0);
+             break;
+         case 4:
+-            gen_helper_1i(mttlo, t0, 1);
++            gen_helper_0e1i(mttlo, t0, 1);
+             break;
+         case 5:
+-            gen_helper_1i(mtthi, t0, 1);
++            gen_helper_0e1i(mtthi, t0, 1);
+             break;
+         case 6:
+-            gen_helper_1i(mttacx, t0, 1);
++            gen_helper_0e1i(mttacx, t0, 1);
+             break;
+         case 8:
+-            gen_helper_1i(mttlo, t0, 2);
++            gen_helper_0e1i(mttlo, t0, 2);
+             break;
+         case 9:
+-            gen_helper_1i(mtthi, t0, 2);
++            gen_helper_0e1i(mtthi, t0, 2);
+             break;
+         case 10:
+-            gen_helper_1i(mttacx, t0, 2);
++            gen_helper_0e1i(mttacx, t0, 2);
+             break;
+         case 12:
+-            gen_helper_1i(mttlo, t0, 3);
++            gen_helper_0e1i(mttlo, t0, 3);
+             break;
+         case 13:
+-            gen_helper_1i(mtthi, t0, 3);
++            gen_helper_0e1i(mtthi, t0, 3);
+             break;
+         case 14:
+-            gen_helper_1i(mttacx, t0, 3);
++            gen_helper_0e1i(mttacx, t0, 3);
+             break;
+         case 16:
+-            gen_helper_mttdsp(t0);
++            gen_helper_mttdsp(cpu_env, t0);
+             break;
+         default:
+             goto die;
+@@ -5910,7 +5928,7 @@ static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
+         break;
+     case 3:
+         /* XXX: For now we support only a single FPU context. */
+-        gen_helper_1i(ctc1, t0, rd);
++        gen_helper_0e1i(ctc1, t0, rd);
+         break;
+     /* COP2: Not implemented. */
+     case 4:
+@@ -5995,30 +6013,30 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
+         opn = "tlbwi";
+         if (!env->tlb->helper_tlbwi)
+             goto die;
+-        gen_helper_tlbwi();
++        gen_helper_tlbwi(cpu_env);
+         break;
+     case OPC_TLBWR:
+         opn = "tlbwr";
+         if (!env->tlb->helper_tlbwr)
+             goto die;
+-        gen_helper_tlbwr();
++        gen_helper_tlbwr(cpu_env);
+         break;
+     case OPC_TLBP:
+         opn = "tlbp";
+         if (!env->tlb->helper_tlbp)
+             goto die;
+-        gen_helper_tlbp();
++        gen_helper_tlbp(cpu_env);
+         break;
+     case OPC_TLBR:
+         opn = "tlbr";
+         if (!env->tlb->helper_tlbr)
+             goto die;
+-        gen_helper_tlbr();
++        gen_helper_tlbr(cpu_env);
+         break;
+     case OPC_ERET:
+         opn = "eret";
+         check_insn(env, ctx, ISA_MIPS2);
+-        gen_helper_eret();
++        gen_helper_eret(cpu_env);
+         ctx->bstate = BS_EXCP;
+         break;
+     case OPC_DERET:
+@@ -6028,7 +6046,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
+             MIPS_INVAL(opn);
+             generate_exception(ctx, EXCP_RI);
+         } else {
+-            gen_helper_deret();
++            gen_helper_deret(cpu_env);
+             ctx->bstate = BS_EXCP;
+         }
+         break;
+@@ -6039,7 +6057,7 @@ static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt,
+         ctx->pc += 4;
+         save_cpu_state(ctx, 1);
+         ctx->pc -= 4;
+-        gen_helper_wait();
++        gen_helper_wait(cpu_env);
+         ctx->bstate = BS_EXCP;
+         break;
+     default:
+@@ -6340,13 +6358,13 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
+         opn = "mtc1";
+         break;
+     case OPC_CFC1:
+-        gen_helper_1i(cfc1, t0, fs);
++        gen_helper_1e0i(cfc1, t0, fs);
+         gen_store_gpr(t0, rt);
+         opn = "cfc1";
+         break;
+     case OPC_CTC1:
+         gen_load_gpr(t0, rt);
+-        gen_helper_1i(ctc1, t0, fs);
++        gen_helper_0e1i(ctc1, t0, fs);
+         opn = "ctc1";
+         break;
+ #if defined(TARGET_MIPS64)
+@@ -6543,7 +6561,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr32(fp0, fs);
+             gen_load_fpr32(fp1, ft);
+-            gen_helper_float_add_s(fp0, fp0, fp1);
++            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i32(fp1);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+@@ -6558,7 +6576,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr32(fp0, fs);
+             gen_load_fpr32(fp1, ft);
+-            gen_helper_float_sub_s(fp0, fp0, fp1);
++            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i32(fp1);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+@@ -6573,7 +6591,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr32(fp0, fs);
+             gen_load_fpr32(fp1, ft);
+-            gen_helper_float_mul_s(fp0, fp0, fp1);
++            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i32(fp1);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+@@ -6588,7 +6606,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr32(fp0, fs);
+             gen_load_fpr32(fp1, ft);
+-            gen_helper_float_div_s(fp0, fp0, fp1);
++            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i32(fp1);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+@@ -6601,7 +6619,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_sqrt_s(fp0, fp0);
++            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -6646,7 +6664,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr32(fp32, fs);
+-            gen_helper_float_roundl_s(fp64, fp32);
++            gen_helper_float_roundl_s(fp64, cpu_env, fp32);
+             tcg_temp_free_i32(fp32);
+             gen_store_fpr64(ctx, fp64, fd);
+             tcg_temp_free_i64(fp64);
+@@ -6660,7 +6678,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr32(fp32, fs);
+-            gen_helper_float_truncl_s(fp64, fp32);
++            gen_helper_float_truncl_s(fp64, cpu_env, fp32);
+             tcg_temp_free_i32(fp32);
+             gen_store_fpr64(ctx, fp64, fd);
+             tcg_temp_free_i64(fp64);
+@@ -6674,7 +6692,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr32(fp32, fs);
+-            gen_helper_float_ceill_s(fp64, fp32);
++            gen_helper_float_ceill_s(fp64, cpu_env, fp32);
+             tcg_temp_free_i32(fp32);
+             gen_store_fpr64(ctx, fp64, fd);
+             tcg_temp_free_i64(fp64);
+@@ -6688,7 +6706,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr32(fp32, fs);
+-            gen_helper_float_floorl_s(fp64, fp32);
++            gen_helper_float_floorl_s(fp64, cpu_env, fp32);
+             tcg_temp_free_i32(fp32);
+             gen_store_fpr64(ctx, fp64, fd);
+             tcg_temp_free_i64(fp64);
+@@ -6700,7 +6718,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_roundw_s(fp0, fp0);
++            gen_helper_float_roundw_s(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -6711,7 +6729,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_truncw_s(fp0, fp0);
++            gen_helper_float_truncw_s(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -6722,7 +6740,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_ceilw_s(fp0, fp0);
++            gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -6733,7 +6751,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_floorw_s(fp0, fp0);
++            gen_helper_float_floorw_s(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -6781,7 +6799,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_recip_s(fp0, fp0);
++            gen_helper_float_recip_s(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -6793,7 +6811,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_rsqrt_s(fp0, fp0);
++            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -6807,7 +6825,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr32(fp0, fs);
+             gen_load_fpr32(fp1, ft);
+-            gen_helper_float_recip2_s(fp0, fp0, fp1);
++            gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i32(fp1);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+@@ -6820,7 +6838,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_recip1_s(fp0, fp0);
++            gen_helper_float_recip1_s(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -6832,7 +6850,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_rsqrt1_s(fp0, fp0);
++            gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -6846,7 +6864,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr32(fp0, fs);
+             gen_load_fpr32(fp1, ft);
+-            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
++            gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i32(fp1);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+@@ -6860,7 +6878,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr32(fp32, fs);
+-            gen_helper_float_cvtd_s(fp64, fp32);
++            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
+             tcg_temp_free_i32(fp32);
+             gen_store_fpr64(ctx, fp64, fd);
+             tcg_temp_free_i64(fp64);
+@@ -6872,7 +6890,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_cvtw_s(fp0, fp0);
++            gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -6885,7 +6903,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr32(fp32, fs);
+-            gen_helper_float_cvtl_s(fp64, fp32);
++            gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
+             tcg_temp_free_i32(fp32);
+             gen_store_fpr64(ctx, fp64, fd);
+             tcg_temp_free_i64(fp64);
+@@ -6941,7 +6959,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_add_d(fp0, fp0, fp1);
++            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -6957,7 +6975,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_sub_d(fp0, fp0, fp1);
++            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -6973,7 +6991,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_mul_d(fp0, fp0, fp1);
++            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -6989,7 +7007,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_div_d(fp0, fp0, fp1);
++            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -7003,7 +7021,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_sqrt_d(fp0, fp0);
++            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7050,7 +7068,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_roundl_d(fp0, fp0);
++            gen_helper_float_roundl_d(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7062,7 +7080,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_truncl_d(fp0, fp0);
++            gen_helper_float_truncl_d(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7074,7 +7092,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_ceill_d(fp0, fp0);
++            gen_helper_float_ceill_d(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7086,7 +7104,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_floorl_d(fp0, fp0);
++            gen_helper_float_floorl_d(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7099,7 +7117,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp64, fs);
+-            gen_helper_float_roundw_d(fp32, fp64);
++            gen_helper_float_roundw_d(fp32, cpu_env, fp64);
+             tcg_temp_free_i64(fp64);
+             gen_store_fpr32(fp32, fd);
+             tcg_temp_free_i32(fp32);
+@@ -7113,7 +7131,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp64, fs);
+-            gen_helper_float_truncw_d(fp32, fp64);
++            gen_helper_float_truncw_d(fp32, cpu_env, fp64);
+             tcg_temp_free_i64(fp64);
+             gen_store_fpr32(fp32, fd);
+             tcg_temp_free_i32(fp32);
+@@ -7127,7 +7145,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp64, fs);
+-            gen_helper_float_ceilw_d(fp32, fp64);
++            gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
+             tcg_temp_free_i64(fp64);
+             gen_store_fpr32(fp32, fd);
+             tcg_temp_free_i32(fp32);
+@@ -7141,7 +7159,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp64, fs);
+-            gen_helper_float_floorw_d(fp32, fp64);
++            gen_helper_float_floorw_d(fp32, cpu_env, fp64);
+             tcg_temp_free_i64(fp64);
+             gen_store_fpr32(fp32, fd);
+             tcg_temp_free_i32(fp32);
+@@ -7190,7 +7208,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_recip_d(fp0, fp0);
++            gen_helper_float_recip_d(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7202,7 +7220,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_rsqrt_d(fp0, fp0);
++            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7216,7 +7234,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_recip2_d(fp0, fp0, fp1);
++            gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -7229,7 +7247,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_recip1_d(fp0, fp0);
++            gen_helper_float_recip1_d(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7241,7 +7259,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_rsqrt1_d(fp0, fp0);
++            gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7255,7 +7273,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
++            gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -7293,7 +7311,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp64, fs);
+-            gen_helper_float_cvts_d(fp32, fp64);
++            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
+             tcg_temp_free_i64(fp64);
+             gen_store_fpr32(fp32, fd);
+             tcg_temp_free_i32(fp32);
+@@ -7307,7 +7325,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp64, fs);
+-            gen_helper_float_cvtw_d(fp32, fp64);
++            gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
+             tcg_temp_free_i64(fp64);
+             gen_store_fpr32(fp32, fd);
+             tcg_temp_free_i32(fp32);
+@@ -7320,7 +7338,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_cvtl_d(fp0, fp0);
++            gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7331,7 +7349,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_cvts_w(fp0, fp0);
++            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -7344,7 +7362,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr32(fp32, fs);
+-            gen_helper_float_cvtd_w(fp64, fp32);
++            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
+             tcg_temp_free_i32(fp32);
+             gen_store_fpr64(ctx, fp64, fd);
+             tcg_temp_free_i64(fp64);
+@@ -7358,7 +7376,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp64 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp64, fs);
+-            gen_helper_float_cvts_l(fp32, fp64);
++            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
+             tcg_temp_free_i64(fp64);
+             gen_store_fpr32(fp32, fd);
+             tcg_temp_free_i32(fp32);
+@@ -7371,7 +7389,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_cvtd_l(fp0, fp0);
++            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7383,7 +7401,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_cvtps_pw(fp0, fp0);
++            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7397,7 +7415,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_add_ps(fp0, fp0, fp1);
++            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -7412,7 +7430,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_sub_ps(fp0, fp0, fp1);
++            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -7427,7 +7445,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_mul_ps(fp0, fp0, fp1);
++            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -7515,7 +7533,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, ft);
+             gen_load_fpr64(ctx, fp1, fs);
+-            gen_helper_float_addr_ps(fp0, fp0, fp1);
++            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -7530,7 +7548,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, ft);
+             gen_load_fpr64(ctx, fp1, fs);
+-            gen_helper_float_mulr_ps(fp0, fp0, fp1);
++            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -7545,7 +7563,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_recip2_ps(fp0, fp0, fp1);
++            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -7558,7 +7576,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_recip1_ps(fp0, fp0);
++            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7570,7 +7588,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_rsqrt1_ps(fp0, fp0);
++            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7584,7 +7602,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+-            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
++            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+@@ -7597,7 +7615,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32h(fp0, fs);
+-            gen_helper_float_cvts_pu(fp0, fp0);
++            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -7609,7 +7627,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i64 fp0 = tcg_temp_new_i64();
+ 
+             gen_load_fpr64(ctx, fp0, fs);
+-            gen_helper_float_cvtpw_ps(fp0, fp0);
++            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
+             gen_store_fpr64(ctx, fp0, fd);
+             tcg_temp_free_i64(fp0);
+         }
+@@ -7621,7 +7639,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1,
+             TCGv_i32 fp0 = tcg_temp_new_i32();
+ 
+             gen_load_fpr32(fp0, fs);
+-            gen_helper_float_cvts_pl(fp0, fp0);
++            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
+             gen_store_fpr32(fp0, fd);
+             tcg_temp_free_i32(fp0);
+         }
+@@ -7887,7 +7905,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr32(fp0, fs);
+             gen_load_fpr32(fp1, ft);
+             gen_load_fpr32(fp2, fr);
+-            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
++            gen_helper_float_muladd_s(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i32(fp0);
+             tcg_temp_free_i32(fp1);
+             gen_store_fpr32(fp2, fd);
+@@ -7906,7 +7924,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+             gen_load_fpr64(ctx, fp2, fr);
+-            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
++            gen_helper_float_muladd_d(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i64(fp0);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp2, fd);
+@@ -7924,7 +7942,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+             gen_load_fpr64(ctx, fp2, fr);
+-            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
++            gen_helper_float_muladd_ps(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i64(fp0);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp2, fd);
+@@ -7942,7 +7960,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr32(fp0, fs);
+             gen_load_fpr32(fp1, ft);
+             gen_load_fpr32(fp2, fr);
+-            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
++            gen_helper_float_mulsub_s(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i32(fp0);
+             tcg_temp_free_i32(fp1);
+             gen_store_fpr32(fp2, fd);
+@@ -7961,7 +7979,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+             gen_load_fpr64(ctx, fp2, fr);
+-            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
++            gen_helper_float_mulsub_d(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i64(fp0);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp2, fd);
+@@ -7979,7 +7997,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+             gen_load_fpr64(ctx, fp2, fr);
+-            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
++            gen_helper_float_mulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i64(fp0);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp2, fd);
+@@ -7997,7 +8015,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr32(fp0, fs);
+             gen_load_fpr32(fp1, ft);
+             gen_load_fpr32(fp2, fr);
+-            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
++            gen_helper_float_nmuladd_s(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i32(fp0);
+             tcg_temp_free_i32(fp1);
+             gen_store_fpr32(fp2, fd);
+@@ -8016,7 +8034,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+             gen_load_fpr64(ctx, fp2, fr);
+-            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
++            gen_helper_float_nmuladd_d(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i64(fp0);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp2, fd);
+@@ -8034,7 +8052,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+             gen_load_fpr64(ctx, fp2, fr);
+-            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
++            gen_helper_float_nmuladd_ps(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i64(fp0);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp2, fd);
+@@ -8052,7 +8070,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr32(fp0, fs);
+             gen_load_fpr32(fp1, ft);
+             gen_load_fpr32(fp2, fr);
+-            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
++            gen_helper_float_nmulsub_s(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i32(fp0);
+             tcg_temp_free_i32(fp1);
+             gen_store_fpr32(fp2, fd);
+@@ -8071,7 +8089,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+             gen_load_fpr64(ctx, fp2, fr);
+-            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
++            gen_helper_float_nmulsub_d(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i64(fp0);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp2, fd);
+@@ -8089,7 +8107,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
+             gen_load_fpr64(ctx, fp0, fs);
+             gen_load_fpr64(ctx, fp1, ft);
+             gen_load_fpr64(ctx, fp2, fr);
+-            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
++            gen_helper_float_nmulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
+             tcg_temp_free_i64(fp0);
+             tcg_temp_free_i64(fp1);
+             gen_store_fpr64(ctx, fp2, fd);
+@@ -8122,22 +8140,22 @@ gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
+     switch (rd) {
+     case 0:
+         save_cpu_state(ctx, 1);
+-        gen_helper_rdhwr_cpunum(t0);
++        gen_helper_rdhwr_cpunum(t0, cpu_env);
+         gen_store_gpr(t0, rt);
+         break;
+     case 1:
+         save_cpu_state(ctx, 1);
+-        gen_helper_rdhwr_synci_step(t0);
++        gen_helper_rdhwr_synci_step(t0, cpu_env);
+         gen_store_gpr(t0, rt);
+         break;
+     case 2:
+         save_cpu_state(ctx, 1);
+-        gen_helper_rdhwr_cc(t0);
++        gen_helper_rdhwr_cc(t0, cpu_env);
+         gen_store_gpr(t0, rt);
+         break;
+     case 3:
+         save_cpu_state(ctx, 1);
+-        gen_helper_rdhwr_ccres(t0);
++        gen_helper_rdhwr_ccres(t0, cpu_env);
+         gen_store_gpr(t0, rt);
+         break;
+     case 29:
+@@ -8214,7 +8232,7 @@ static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
+             }
+             if (ctx->singlestep_enabled) {
+                 save_cpu_state(ctx, 0);
+-                gen_helper_0i(raise_exception, EXCP_DEBUG);
++                gen_helper_0e0i(raise_exception, EXCP_DEBUG);
+             }
+             tcg_gen_exit_tb(0);
+             break;
+@@ -8678,7 +8696,7 @@ static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
+ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
+                                        int *is_branch)
+ {
+-    int extend = lduw_code(ctx->pc + 2);
++    int extend = cpu_lduw_code(env, ctx->pc + 2);
+     int op, rx, ry, funct, sa;
+     int16_t imm, offset;
+ 
+@@ -8904,7 +8922,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
+         /* No delay slot, so just process as a normal instruction */
+         break;
+     case M16_OPC_JAL:
+-        offset = lduw_code(ctx->pc + 2);
++        offset = cpu_lduw_code(env, ctx->pc + 2);
+         offset = (((ctx->opcode & 0x1f) << 21)
+                   | ((ctx->opcode >> 5) & 0x1f) << 16
+                   | offset) << 2;
+@@ -9855,17 +9873,17 @@ static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
+     save_cpu_state(ctx, 1);
+     switch (opc) {
+     case LWM32:
+-        gen_helper_lwm(t0, t1, t2);
++        gen_helper_lwm(cpu_env, t0, t1, t2);
+         break;
+     case SWM32:
+-        gen_helper_swm(t0, t1, t2);
++        gen_helper_swm(cpu_env, t0, t1, t2);
+         break;
+ #ifdef TARGET_MIPS64
+     case LDM:
+-        gen_helper_ldm(t0, t1, t2);
++        gen_helper_ldm(cpu_env, t0, t1, t2);
+         break;
+     case SDM:
+-        gen_helper_sdm(t0, t1, t2);
++        gen_helper_sdm(cpu_env, t0, t1, t2);
+         break;
+ #endif
+     }
+@@ -10287,7 +10305,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
+                 TCGv t0 = tcg_temp_new();
+ 
+                 save_cpu_state(ctx, 1);
+-                gen_helper_di(t0);
++                gen_helper_di(t0, cpu_env);
+                 gen_store_gpr(t0, rs);
+                 /* Stop translation as we may have switched the execution mode */
+                 ctx->bstate = BS_STOP;
+@@ -10300,7 +10318,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
+                 TCGv t0 = tcg_temp_new();
+ 
+                 save_cpu_state(ctx, 1);
+-                gen_helper_ei(t0);
++                gen_helper_ei(t0, cpu_env);
+                 gen_store_gpr(t0, rs);
+                 /* Stop translation as we may have switched the execution mode */
+                 ctx->bstate = BS_STOP;
+@@ -10635,7 +10653,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
+     uint32_t op, minor, mips32_op;
+     uint32_t cond, fmt, cc;
+ 
+-    insn = lduw_code(ctx->pc + 2);
++    insn = cpu_lduw_code(env, ctx->pc + 2);
+     ctx->opcode = (ctx->opcode << 16) | insn;
+ 
+     rt = (ctx->opcode >> 21) & 0x1f;
+@@ -11827,7 +11845,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
+             MIPS_INVAL("PMON / selsl");
+             generate_exception(ctx, EXCP_RI);
+ #else
+-            gen_helper_0i(pmon, sa);
++            gen_helper_0e0i(pmon, sa);
+ #endif
+             break;
+         case OPC_SYSCALL:
+@@ -12045,7 +12063,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
+ 
+                 save_cpu_state(ctx, 1);
+                 gen_load_gpr(t0, rs);
+-                gen_helper_yield(t0, t0);
++                gen_helper_yield(t0, cpu_env, t0);
+                 gen_store_gpr(t0, rd);
+                 tcg_temp_free(t0);
+             }
+@@ -12144,18 +12162,18 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
+                     break;
+                 case OPC_DVPE:
+                     check_insn(env, ctx, ASE_MT);
+-                    gen_helper_dvpe(t0);
++                    gen_helper_dvpe(t0, cpu_env);
+                     gen_store_gpr(t0, rt);
+                     break;
+                 case OPC_EVPE:
+                     check_insn(env, ctx, ASE_MT);
+-                    gen_helper_evpe(t0);
++                    gen_helper_evpe(t0, cpu_env);
+                     gen_store_gpr(t0, rt);
+                     break;
+                 case OPC_DI:
+                     check_insn(env, ctx, ISA_MIPS32R2);
+                     save_cpu_state(ctx, 1);
+-                    gen_helper_di(t0);
++                    gen_helper_di(t0, cpu_env);
+                     gen_store_gpr(t0, rt);
+                     /* Stop translation as we may have switched the execution mode */
+                     ctx->bstate = BS_STOP;
+@@ -12163,7 +12181,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
+                 case OPC_EI:
+                     check_insn(env, ctx, ISA_MIPS32R2);
+                     save_cpu_state(ctx, 1);
+-                    gen_helper_ei(t0);
++                    gen_helper_ei(t0, cpu_env);
+                     gen_store_gpr(t0, rt);
+                     /* Stop translation as we may have switched the execution mode */
+                     ctx->bstate = BS_STOP;
+@@ -12432,7 +12450,7 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
+                 if (bp->pc == ctx.pc) {
+                     save_cpu_state(&ctx, 1);
+                     ctx.bstate = BS_BRANCH;
+-                    gen_helper_0i(raise_exception, EXCP_DEBUG);
++                    gen_helper_0e0i(raise_exception, EXCP_DEBUG);
+                     /* Include the breakpoint location or the tb won't
+                      * be flushed when it must be.  */
+                     ctx.pc += 4;
+@@ -12458,14 +12476,14 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
+ 
+         is_branch = 0;
+         if (!(ctx.hflags & MIPS_HFLAG_M16)) {
+-            ctx.opcode = ldl_code(ctx.pc);
++            ctx.opcode = cpu_ldl_code(env, ctx.pc);
+             insn_bytes = 4;
+             decode_opc(env, &ctx, &is_branch);
+         } else if (env->insn_flags & ASE_MICROMIPS) {
+-            ctx.opcode = lduw_code(ctx.pc);
++            ctx.opcode = cpu_lduw_code(env, ctx.pc);
+             insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
+         } else if (env->insn_flags & ASE_MIPS16) {
+-            ctx.opcode = lduw_code(ctx.pc);
++            ctx.opcode = cpu_lduw_code(env, ctx.pc);
+             insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
+         } else {
+             generate_exception(&ctx, EXCP_RI);
+@@ -12502,7 +12520,7 @@ gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
+         gen_io_end();
+     if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
+         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
+-        gen_helper_0i(raise_exception, EXCP_DEBUG);
++        gen_helper_0e0i(raise_exception, EXCP_DEBUG);
+     } else {
+         switch (ctx.bstate) {
+         case BS_STOP:
+-- 
+1.7.12.1
+
diff --git a/0039-Remove-unused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch b/0039-Remove-unused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch
new file mode 100644
index 0000000..72c61e8
--- /dev/null
+++ b/0039-Remove-unused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch
@@ -0,0 +1,1683 @@
+From 3ec8ca067ea6617b5bd4423d0b40c894b39a4924 Mon Sep 17 00:00:00 2001
+From: Blue Swirl <blauwirbel at gmail.com>
+Date: Sun, 2 Sep 2012 15:28:56 +0000
+Subject: [PATCH] Remove unused CONFIG_TCG_PASS_AREG0 and dead code
+
+Now that CONFIG_TCG_PASS_AREG0 is enabled for all targets,
+remove dead code and support for !CONFIG_TCG_PASS_AREG0 case.
+
+Remove dyngen-exec.h and all references to it. Although included by
+hw/spapr_hcall.c, it does not seem to use it.
+
+Remove unused HELPER_CFLAGS.
+
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ Makefile.target            |  8 ------
+ configure                  | 11 -------
+ cpu-all.h                  | 11 -------
+ cputlb.c                   |  5 ----
+ dyngen-exec.h              | 70 --------------------------------------------
+ exec-all.h                 |  4 ---
+ hw/spapr_hcall.c           |  1 -
+ softmmu_defs.h             | 21 --------------
+ softmmu_header.h           | 63 +++++++++++++---------------------------
+ softmmu_template.h         | 72 +++++++++++++++++-----------------------------
+ target-m68k/op_helper.c    |  3 --
+ target-sparc/Makefile.objs |  2 --
+ tcg/arm/tcg-target.c       | 31 ++------------------
+ tcg/arm/tcg-target.h       |  1 -
+ tcg/hppa/tcg-target.c      | 24 ----------------
+ tcg/hppa/tcg-target.h      |  1 -
+ tcg/i386/tcg-target.c      | 30 -------------------
+ tcg/i386/tcg-target.h      |  1 -
+ tcg/ia64/tcg-target.c      | 34 ----------------------
+ tcg/ia64/tcg-target.h      |  1 -
+ tcg/mips/tcg-target.c      | 31 ++------------------
+ tcg/mips/tcg-target.h      |  1 -
+ tcg/ppc/tcg-target.c       | 38 ------------------------
+ tcg/ppc64/tcg-target.c     | 28 ------------------
+ tcg/s390/tcg-target.c      | 24 ----------------
+ tcg/s390/tcg-target.h      |  1 -
+ tcg/sparc/tcg-target.c     | 30 -------------------
+ tcg/sparc/tcg-target.h     |  1 -
+ tcg/tci/tcg-target.c       |  4 ---
+ tci.c                      | 12 --------
+ user-exec.c                | 14 ---------
+ 31 files changed, 53 insertions(+), 525 deletions(-)
+ delete mode 100644 dyngen-exec.h
+
+diff --git a/Makefile.target b/Makefile.target
+index 7892a8d..d9d54b8 100644
+--- a/Makefile.target
++++ b/Makefile.target
+@@ -80,14 +80,6 @@ obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
+ 
+ tci-dis.o: QEMU_CFLAGS += -I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/tci
+ 
+-# HELPER_CFLAGS is used for all the legacy code compiled with static register
+-# variables
+-user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+-
+-# Note: this is a workaround. The real fix is to avoid compiling
+-# cpu_signal_handler() in user-exec.c.
+-%/signal.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+-
+ #########################################################
+ # Linux user emulator target
+ 
+diff --git a/configure b/configure
+index 83b068d..816f0f9 100755
+--- a/configure
++++ b/configure
+@@ -118,7 +118,6 @@ audio_card_list="ac97 es1370 sb16 hda"
+ audio_possible_cards="ac97 es1370 sb16 cs4231a adlib gus hda"
+ block_drv_whitelist=""
+ host_cc="gcc"
+-helper_cflags=""
+ libs_softmmu=""
+ libs_tools=""
+ audio_pt_int=""
+@@ -904,7 +903,6 @@ case "$cpu" in
+            QEMU_CFLAGS="-m32 -ffixed-g2 -ffixed-g3 $QEMU_CFLAGS"
+            if test "$solaris" = "no" ; then
+              QEMU_CFLAGS="-ffixed-g1 -ffixed-g6 $QEMU_CFLAGS"
+-             helper_cflags="-ffixed-i0"
+            fi
+            ;;
+     sparc64)
+@@ -929,7 +927,6 @@ case "$cpu" in
+            QEMU_CFLAGS="-m32 $QEMU_CFLAGS"
+            LDFLAGS="-m32 $LDFLAGS"
+            cc_i386='$(CC) -m32'
+-           helper_cflags="-fomit-frame-pointer"
+            host_guest_base="yes"
+            ;;
+     x86_64)
+@@ -3582,7 +3579,6 @@ if test "$sparse" = "yes" ; then
+   echo "HOST_CC      := REAL_CC=\"\$(HOST_CC)\" cgcc"  >> $config_host_mak
+   echo "QEMU_CFLAGS  += -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_host_mak
+ fi
+-echo "HELPER_CFLAGS=$helper_cflags" >> $config_host_mak
+ echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
+ echo "ARLIBS_BEGIN=$arlibs_begin" >> $config_host_mak
+ echo "ARLIBS_END=$arlibs_end" >> $config_host_mak
+@@ -3837,13 +3833,6 @@ fi
+ 
+ symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+ 
+-
+-case "$target_arch2" in
+-  alpha | arm* | cris | i386 | lm32 | m68k | microblaze* | mips* | or32 | s390x | sh4* | sparc* | unicore32 | x86_64 | xtensa* | ppc*)
+-    echo "CONFIG_TCG_PASS_AREG0=y" >> $config_target_mak
+-  ;;
+-esac
+-
+ upper() {
+     echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]'
+ }
+diff --git a/cpu-all.h b/cpu-all.h
+index 5e07d28..74d3681 100644
+--- a/cpu-all.h
++++ b/cpu-all.h
+@@ -260,14 +260,6 @@ extern unsigned long reserved_va;
+ #define stfl(p, v) stfl_raw(p, v)
+ #define stfq(p, v) stfq_raw(p, v)
+ 
+-#ifndef CONFIG_TCG_PASS_AREG0
+-#define ldub_code(p) ldub_raw(p)
+-#define ldsb_code(p) ldsb_raw(p)
+-#define lduw_code(p) lduw_raw(p)
+-#define ldsw_code(p) ldsw_raw(p)
+-#define ldl_code(p) ldl_raw(p)
+-#define ldq_code(p) ldq_raw(p)
+-#else
+ #define cpu_ldub_code(env1, p) ldub_raw(p)
+ #define cpu_ldsb_code(env1, p) ldsb_raw(p)
+ #define cpu_lduw_code(env1, p) lduw_raw(p)
+@@ -296,7 +288,6 @@ extern unsigned long reserved_va;
+ #define cpu_stw_kernel(env, addr, data) stw_raw(addr, data)
+ #define cpu_stl_kernel(env, addr, data) stl_raw(addr, data)
+ #define cpu_stq_kernel(env, addr, data) stq_raw(addr, data)
+-#endif
+ 
+ #define ldub_kernel(p) ldub_raw(p)
+ #define ldsb_kernel(p) ldsb_raw(p)
+@@ -313,7 +304,6 @@ extern unsigned long reserved_va;
+ #define stfl_kernel(p, v) stfl_raw(p, v)
+ #define stfq_kernel(p, vt) stfq_raw(p, v)
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ #define cpu_ldub_data(env, addr) ldub_raw(addr)
+ #define cpu_lduw_data(env, addr) lduw_raw(addr)
+ #define cpu_ldl_data(env, addr) ldl_raw(addr)
+@@ -321,7 +311,6 @@ extern unsigned long reserved_va;
+ #define cpu_stb_data(env, addr, data) stb_raw(addr, data)
+ #define cpu_stw_data(env, addr, data) stw_raw(addr, data)
+ #define cpu_stl_data(env, addr, data) stl_raw(addr, data)
+-#endif
+ #endif /* defined(CONFIG_USER_ONLY) */
+ 
+ /* page related stuff */
+diff --git a/cputlb.c b/cputlb.c
+index d3e7b25..51b5897 100644
+--- a/cputlb.c
++++ b/cputlb.c
+@@ -325,11 +325,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
+     mmu_idx = cpu_mmu_index(env1);
+     if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
+                  (addr & TARGET_PAGE_MASK))) {
+-#ifdef CONFIG_TCG_PASS_AREG0
+         cpu_ldub_code(env1, addr);
+-#else
+-        ldub_code(addr);
+-#endif
+     }
+     pd = env1->iotlb[mmu_idx][page_index] & ~TARGET_PAGE_MASK;
+     mr = iotlb_to_region(pd);
+@@ -348,7 +344,6 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
+ #define MMUSUFFIX _cmmu
+ #undef GETPC
+ #define GETPC() ((uintptr_t)0)
+-#define env cpu_single_env
+ #define SOFTMMU_CODE_ACCESS
+ 
+ #define SHIFT 0
+diff --git a/dyngen-exec.h b/dyngen-exec.h
+deleted file mode 100644
+index 083e20b..0000000
+--- a/dyngen-exec.h
++++ /dev/null
+@@ -1,70 +0,0 @@
+-/*
+- *  dyngen defines for micro operation code
+- *
+- *  Copyright (c) 2003 Fabrice Bellard
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Lesser General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library 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
+- * Lesser General Public License for more details.
+- *
+- * You should have received a copy of the GNU Lesser General Public
+- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+- */
+-#if !defined(__DYNGEN_EXEC_H__)
+-#define __DYNGEN_EXEC_H__
+-
+-#if defined(CONFIG_TCG_INTERPRETER)
+-/* The TCG interpreter does not need a special register AREG0,
+- * but it is possible to use one by defining AREG0.
+- * On i386, register edi seems to work. */
+-/* Run without special register AREG0 or use a value defined elsewhere. */
+-#elif defined(__i386__)
+-#define AREG0 "ebp"
+-#elif defined(__x86_64__)
+-#define AREG0 "r14"
+-#elif defined(_ARCH_PPC)
+-#define AREG0 "r27"
+-#elif defined(__arm__)
+-#define AREG0 "r6"
+-#elif defined(__hppa__)
+-#define AREG0 "r17"
+-#elif defined(__mips__)
+-#define AREG0 "s0"
+-#elif defined(__sparc__)
+-#ifdef CONFIG_SOLARIS
+-#define AREG0 "g2"
+-#else
+-#ifdef __sparc_v9__
+-#define AREG0 "g5"
+-#else
+-#define AREG0 "g6"
+-#endif
+-#endif
+-#elif defined(__s390__)
+-#define AREG0 "r10"
+-#elif defined(__alpha__)
+-/* Note $15 is the frame pointer, so anything in op-i386.c that would
+-   require a frame pointer, like alloca, would probably loose.  */
+-#define AREG0 "$15"
+-#elif defined(__mc68000)
+-#define AREG0 "%a5"
+-#elif defined(__ia64__)
+-#define AREG0 "r7"
+-#else
+-#error unsupported CPU
+-#endif
+-
+-#if defined(AREG0)
+-register CPUArchState *env asm(AREG0);
+-#else
+-/* TODO: Try env = cpu_single_env. */
+-extern CPUArchState *env;
+-#endif
+-
+-#endif /* !defined(__DYNGEN_EXEC_H__) */
+diff --git a/exec-all.h b/exec-all.h
+index c5ec8e1..c5d3a13 100644
+--- a/exec-all.h
++++ b/exec-all.h
+@@ -323,9 +323,6 @@ void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
+ 
+ #define ACCESS_TYPE (NB_MMU_MODES + 1)
+ #define MEMSUFFIX _code
+-#ifndef CONFIG_TCG_PASS_AREG0
+-#define env cpu_single_env
+-#endif
+ 
+ #define DATA_SIZE 1
+ #include "softmmu_header.h"
+@@ -341,7 +338,6 @@ void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
+ 
+ #undef ACCESS_TYPE
+ #undef MEMSUFFIX
+-#undef env
+ 
+ #endif
+ 
+diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
+index a5990a9..abd847f 100644
+--- a/hw/spapr_hcall.c
++++ b/hw/spapr_hcall.c
+@@ -1,6 +1,5 @@
+ #include "sysemu.h"
+ #include "cpu.h"
+-#include "dyngen-exec.h"
+ #include "qemu-char.h"
+ #include "sysemu.h"
+ #include "qemu-char.h"
+diff --git a/softmmu_defs.h b/softmmu_defs.h
+index 8d59f9d..1f25e33 100644
+--- a/softmmu_defs.h
++++ b/softmmu_defs.h
+@@ -9,25 +9,6 @@
+ #ifndef SOFTMMU_DEFS_H
+ #define SOFTMMU_DEFS_H
+ 
+-#ifndef CONFIG_TCG_PASS_AREG0
+-uint8_t __ldb_mmu(target_ulong addr, int mmu_idx);
+-void __stb_mmu(target_ulong addr, uint8_t val, int mmu_idx);
+-uint16_t __ldw_mmu(target_ulong addr, int mmu_idx);
+-void __stw_mmu(target_ulong addr, uint16_t val, int mmu_idx);
+-uint32_t __ldl_mmu(target_ulong addr, int mmu_idx);
+-void __stl_mmu(target_ulong addr, uint32_t val, int mmu_idx);
+-uint64_t __ldq_mmu(target_ulong addr, int mmu_idx);
+-void __stq_mmu(target_ulong addr, uint64_t val, int mmu_idx);
+-
+-uint8_t __ldb_cmmu(target_ulong addr, int mmu_idx);
+-void __stb_cmmu(target_ulong addr, uint8_t val, int mmu_idx);
+-uint16_t __ldw_cmmu(target_ulong addr, int mmu_idx);
+-void __stw_cmmu(target_ulong addr, uint16_t val, int mmu_idx);
+-uint32_t __ldl_cmmu(target_ulong addr, int mmu_idx);
+-void __stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx);
+-uint64_t __ldq_cmmu(target_ulong addr, int mmu_idx);
+-void __stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx);
+-#else
+ uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
+ void helper_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
+                     int mmu_idx);
+@@ -54,5 +35,3 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
+ void helper_stq_cmmu(CPUArchState *env, target_ulong addr, uint64_t val,
+                      int mmu_idx);
+ #endif
+-
+-#endif
+diff --git a/softmmu_header.h b/softmmu_header.h
+index cf1aa38..d8d9c81 100644
+--- a/softmmu_header.h
++++ b/softmmu_header.h
+@@ -78,23 +78,10 @@
+ #define ADDR_READ addr_read
+ #endif
+ 
+-#ifndef CONFIG_TCG_PASS_AREG0
+-#define ENV_PARAM
+-#define ENV_VAR
+-#define CPU_PREFIX
+-#define HELPER_PREFIX __
+-#else
+-#define ENV_PARAM CPUArchState *env,
+-#define ENV_VAR env,
+-#define CPU_PREFIX cpu_
+-#define HELPER_PREFIX helper_
+-#endif
+-
+ /* generic load/store macros */
+ 
+ static inline RES_TYPE
+-glue(glue(glue(CPU_PREFIX, ld), USUFFIX), MEMSUFFIX)(ENV_PARAM
+-                                                     target_ulong ptr)
++glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
+ {
+     int page_index;
+     RES_TYPE res;
+@@ -106,9 +93,7 @@ glue(glue(glue(CPU_PREFIX, ld), USUFFIX), MEMSUFFIX)(ENV_PARAM
+     mmu_idx = CPU_MMU_INDEX;
+     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
+                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
+-        res = glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_VAR
+-                                                                     addr,
+-                                                                     mmu_idx);
++        res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
+     } else {
+         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
+         res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
+@@ -118,8 +103,7 @@ glue(glue(glue(CPU_PREFIX, ld), USUFFIX), MEMSUFFIX)(ENV_PARAM
+ 
+ #if DATA_SIZE <= 2
+ static inline int
+-glue(glue(glue(CPU_PREFIX, lds), SUFFIX), MEMSUFFIX)(ENV_PARAM
+-                                                     target_ulong ptr)
++glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
+ {
+     int res, page_index;
+     target_ulong addr;
+@@ -130,8 +114,8 @@ glue(glue(glue(CPU_PREFIX, lds), SUFFIX), MEMSUFFIX)(ENV_PARAM
+     mmu_idx = CPU_MMU_INDEX;
+     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
+                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
+-        res = (DATA_STYPE)glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
+-                               MMUSUFFIX)(ENV_VAR addr, mmu_idx);
++        res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
++                               MMUSUFFIX)(env, addr, mmu_idx);
+     } else {
+         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
+         res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
+@@ -145,8 +129,8 @@ glue(glue(glue(CPU_PREFIX, lds), SUFFIX), MEMSUFFIX)(ENV_PARAM
+ /* generic store macro */
+ 
+ static inline void
+-glue(glue(glue(CPU_PREFIX, st), SUFFIX), MEMSUFFIX)(ENV_PARAM target_ulong ptr,
+-                                                    RES_TYPE v)
++glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
++                                      RES_TYPE v)
+ {
+     int page_index;
+     target_ulong addr;
+@@ -157,8 +141,7 @@ glue(glue(glue(CPU_PREFIX, st), SUFFIX), MEMSUFFIX)(ENV_PARAM target_ulong ptr,
+     mmu_idx = CPU_MMU_INDEX;
+     if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
+                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
+-        glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_VAR addr, v,
+-                                                               mmu_idx);
++        glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
+     } else {
+         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
+         glue(glue(st, SUFFIX), _raw)(hostaddr, v);
+@@ -170,52 +153,50 @@ glue(glue(glue(CPU_PREFIX, st), SUFFIX), MEMSUFFIX)(ENV_PARAM target_ulong ptr,
+ #if ACCESS_TYPE != (NB_MMU_MODES + 1)
+ 
+ #if DATA_SIZE == 8
+-static inline float64 glue(glue(CPU_PREFIX, ldfq), MEMSUFFIX)(ENV_PARAM
+-                                                              target_ulong ptr)
++static inline float64 glue(cpu_ldfq, MEMSUFFIX)(CPUArchState *env,
++                                                target_ulong ptr)
+ {
+     union {
+         float64 d;
+         uint64_t i;
+     } u;
+-    u.i = glue(glue(CPU_PREFIX, ldq), MEMSUFFIX)(ENV_VAR ptr);
++    u.i = glue(cpu_ldq, MEMSUFFIX)(env, ptr);
+     return u.d;
+ }
+ 
+-static inline void glue(glue(CPU_PREFIX, stfq), MEMSUFFIX)(ENV_PARAM
+-                                                           target_ulong ptr,
+-                                                           float64 v)
++static inline void glue(cpu_stfq, MEMSUFFIX)(CPUArchState *env,
++                                             target_ulong ptr, float64 v)
+ {
+     union {
+         float64 d;
+         uint64_t i;
+     } u;
+     u.d = v;
+-    glue(glue(CPU_PREFIX, stq), MEMSUFFIX)(ENV_VAR ptr, u.i);
++    glue(cpu_stq, MEMSUFFIX)(env, ptr, u.i);
+ }
+ #endif /* DATA_SIZE == 8 */
+ 
+ #if DATA_SIZE == 4
+-static inline float32 glue(glue(CPU_PREFIX, ldfl), MEMSUFFIX)(ENV_PARAM
+-                                                              target_ulong ptr)
++static inline float32 glue(cpu_ldfl, MEMSUFFIX)(CPUArchState *env,
++                                                target_ulong ptr)
+ {
+     union {
+         float32 f;
+         uint32_t i;
+     } u;
+-    u.i = glue(glue(CPU_PREFIX, ldl), MEMSUFFIX)(ENV_VAR ptr);
++    u.i = glue(cpu_ldl, MEMSUFFIX)(env, ptr);
+     return u.f;
+ }
+ 
+-static inline void glue(glue(CPU_PREFIX, stfl), MEMSUFFIX)(ENV_PARAM
+-                                                           target_ulong ptr,
+-                                                           float32 v)
++static inline void glue(cpu_stfl, MEMSUFFIX)(CPUArchState *env,
++                                             target_ulong ptr, float32 v)
+ {
+     union {
+         float32 f;
+         uint32_t i;
+     } u;
+     u.f = v;
+-    glue(glue(CPU_PREFIX, stl), MEMSUFFIX)(ENV_VAR ptr, u.i);
++    glue(cpu_stl, MEMSUFFIX)(env, ptr, u.i);
+ }
+ #endif /* DATA_SIZE == 4 */
+ 
+@@ -230,7 +211,3 @@ static inline void glue(glue(CPU_PREFIX, stfl), MEMSUFFIX)(ENV_PARAM
+ #undef CPU_MMU_INDEX
+ #undef MMUSUFFIX
+ #undef ADDR_READ
+-#undef ENV_PARAM
+-#undef ENV_VAR
+-#undef CPU_PREFIX
+-#undef HELPER_PREFIX
+diff --git a/softmmu_template.h b/softmmu_template.h
+index b8bd700..e2490f0 100644
+--- a/softmmu_template.h
++++ b/softmmu_template.h
+@@ -54,23 +54,11 @@
+ #define ADDR_READ addr_read
+ #endif
+ 
+-#ifndef CONFIG_TCG_PASS_AREG0
+-#define ENV_PARAM
+-#define ENV_VAR
+-#define CPU_PREFIX
+-#define HELPER_PREFIX __
+-#else
+-#define ENV_PARAM CPUArchState *env,
+-#define ENV_VAR env,
+-#define CPU_PREFIX cpu_
+-#define HELPER_PREFIX helper_
+-#endif
+-
+-static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
++static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
+                                                         target_ulong addr,
+                                                         int mmu_idx,
+                                                         uintptr_t retaddr);
+-static inline DATA_TYPE glue(io_read, SUFFIX)(ENV_PARAM
++static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
+                                               target_phys_addr_t physaddr,
+                                               target_ulong addr,
+                                               uintptr_t retaddr)
+@@ -104,9 +92,8 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(ENV_PARAM
+ 
+ /* handle all cases except unaligned access which span two pages */
+ DATA_TYPE
+-glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
+-                                                       target_ulong addr,
+-                                                       int mmu_idx)
++glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
++                                         int mmu_idx)
+ {
+     DATA_TYPE res;
+     int index;
+@@ -126,15 +113,15 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
+                 goto do_unaligned_access;
+             retaddr = GETPC();
+             ioaddr = env->iotlb[mmu_idx][index];
+-            res = glue(io_read, SUFFIX)(ENV_VAR ioaddr, addr, retaddr);
++            res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
+         } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
+             /* slow unaligned access (it spans two pages or IO) */
+         do_unaligned_access:
+             retaddr = GETPC();
+ #ifdef ALIGNED_ONLY
+-            do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
++            do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
+ #endif
+-            res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_VAR addr,
++            res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(env, addr,
+                                                          mmu_idx, retaddr);
+         } else {
+             /* unaligned/aligned access in the same page */
+@@ -142,7 +129,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
+ #ifdef ALIGNED_ONLY
+             if ((addr & (DATA_SIZE - 1)) != 0) {
+                 retaddr = GETPC();
+-                do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
++                do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
+             }
+ #endif
+             addend = env->tlb_table[mmu_idx][index].addend;
+@@ -154,7 +141,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
+         retaddr = GETPC();
+ #ifdef ALIGNED_ONLY
+         if ((addr & (DATA_SIZE - 1)) != 0)
+-            do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
++            do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
+ #endif
+         tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
+         goto redo;
+@@ -164,7 +151,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
+ 
+ /* handle all unaligned cases */
+ static DATA_TYPE
+-glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
++glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
+                                        target_ulong addr,
+                                        int mmu_idx,
+                                        uintptr_t retaddr)
+@@ -183,15 +170,15 @@ glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
+             if ((addr & (DATA_SIZE - 1)) != 0)
+                 goto do_unaligned_access;
+             ioaddr = env->iotlb[mmu_idx][index];
+-            res = glue(io_read, SUFFIX)(ENV_VAR ioaddr, addr, retaddr);
++            res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
+         } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
+         do_unaligned_access:
+             /* slow unaligned access (it spans two pages) */
+             addr1 = addr & ~(DATA_SIZE - 1);
+             addr2 = addr1 + DATA_SIZE;
+-            res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_VAR addr1,
++            res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(env, addr1,
+                                                           mmu_idx, retaddr);
+-            res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_VAR addr2,
++            res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(env, addr2,
+                                                           mmu_idx, retaddr);
+             shift = (addr & (DATA_SIZE - 1)) * 8;
+ #ifdef TARGET_WORDS_BIGENDIAN
+@@ -216,13 +203,13 @@ glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
+ 
+ #ifndef SOFTMMU_CODE_ACCESS
+ 
+-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
++static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
+                                                    target_ulong addr,
+                                                    DATA_TYPE val,
+                                                    int mmu_idx,
+                                                    uintptr_t retaddr);
+ 
+-static inline void glue(io_write, SUFFIX)(ENV_PARAM
++static inline void glue(io_write, SUFFIX)(CPUArchState *env,
+                                           target_phys_addr_t physaddr,
+                                           DATA_TYPE val,
+                                           target_ulong addr,
+@@ -253,10 +240,9 @@ static inline void glue(io_write, SUFFIX)(ENV_PARAM
+ #endif /* SHIFT > 2 */
+ }
+ 
+-void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
+-                                                            target_ulong addr,
+-                                                            DATA_TYPE val,
+-                                                            int mmu_idx)
++void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
++                                              target_ulong addr, DATA_TYPE val,
++                                              int mmu_idx)
+ {
+     target_phys_addr_t ioaddr;
+     target_ulong tlb_addr;
+@@ -273,14 +259,14 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
+                 goto do_unaligned_access;
+             retaddr = GETPC();
+             ioaddr = env->iotlb[mmu_idx][index];
+-            glue(io_write, SUFFIX)(ENV_VAR ioaddr, val, addr, retaddr);
++            glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr);
+         } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
+         do_unaligned_access:
+             retaddr = GETPC();
+ #ifdef ALIGNED_ONLY
+-            do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
++            do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
+ #endif
+-            glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_VAR addr, val,
++            glue(glue(slow_st, SUFFIX), MMUSUFFIX)(env, addr, val,
+                                                    mmu_idx, retaddr);
+         } else {
+             /* aligned/unaligned access in the same page */
+@@ -288,7 +274,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
+ #ifdef ALIGNED_ONLY
+             if ((addr & (DATA_SIZE - 1)) != 0) {
+                 retaddr = GETPC();
+-                do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
++                do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
+             }
+ #endif
+             addend = env->tlb_table[mmu_idx][index].addend;
+@@ -300,7 +286,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
+         retaddr = GETPC();
+ #ifdef ALIGNED_ONLY
+         if ((addr & (DATA_SIZE - 1)) != 0)
+-            do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
++            do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
+ #endif
+         tlb_fill(env, addr, 1, mmu_idx, retaddr);
+         goto redo;
+@@ -308,7 +294,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
+ }
+ 
+ /* handles all unaligned cases */
+-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
++static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
+                                                    target_ulong addr,
+                                                    DATA_TYPE val,
+                                                    int mmu_idx,
+@@ -327,7 +313,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
+             if ((addr & (DATA_SIZE - 1)) != 0)
+                 goto do_unaligned_access;
+             ioaddr = env->iotlb[mmu_idx][index];
+-            glue(io_write, SUFFIX)(ENV_VAR ioaddr, val, addr, retaddr);
++            glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr);
+         } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
+         do_unaligned_access:
+             /* XXX: not efficient, but simple */
+@@ -335,11 +321,11 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
+              * previous page from the TLB cache.  */
+             for(i = DATA_SIZE - 1; i >= 0; i--) {
+ #ifdef TARGET_WORDS_BIGENDIAN
+-                glue(slow_stb, MMUSUFFIX)(ENV_VAR addr + i,
++                glue(slow_stb, MMUSUFFIX)(env, addr + i,
+                                           val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
+                                           mmu_idx, retaddr);
+ #else
+-                glue(slow_stb, MMUSUFFIX)(ENV_VAR addr + i,
++                glue(slow_stb, MMUSUFFIX)(env, addr + i,
+                                           val >> (i * 8),
+                                           mmu_idx, retaddr);
+ #endif
+@@ -366,7 +352,3 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
+ #undef USUFFIX
+ #undef DATA_SIZE
+ #undef ADDR_READ
+-#undef ENV_PARAM
+-#undef ENV_VAR
+-#undef CPU_PREFIX
+-#undef HELPER_PREFIX
+diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
+index 3116287..aa00504 100644
+--- a/target-m68k/op_helper.c
++++ b/target-m68k/op_helper.c
+@@ -192,9 +192,6 @@ void HELPER(divu)(CPUM68KState *env, uint32_t word)
+     quot = num / den;
+     rem = num % den;
+     flags = 0;
+-    /* Avoid using a PARAM1 of zero.  This breaks dyngen because it uses
+-       the address of a symbol, and gcc knows symbols can't have address
+-       zero.  */
+     if (word && quot > 0xffff)
+         flags |= CCF_V;
+     if (quot == 0)
+diff --git a/target-sparc/Makefile.objs b/target-sparc/Makefile.objs
+index a93e07d..9fc42ea 100644
+--- a/target-sparc/Makefile.objs
++++ b/target-sparc/Makefile.objs
+@@ -4,5 +4,3 @@ obj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
+ obj-$(TARGET_SPARC) += int32_helper.o
+ obj-$(TARGET_SPARC64) += int64_helper.o
+ obj-$(TARGET_SPARC64) += vis_helper.o
+-
+-$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
+index cf0ca3d..aed3b53 100644
+--- a/tcg/arm/tcg-target.c
++++ b/tcg/arm/tcg-target.c
+@@ -176,7 +176,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+            so don't use these. */
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
+-#if defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64)
++#if TARGET_LONG_BITS == 64
+         /* If we're passing env to the helper as r0 and need a regpair
+          * for the address then r2 will be overwritten as we're setting
+          * up the args to the helper.
+@@ -204,8 +204,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+            use these. */
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R0);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R1);
+-#if defined(CONFIG_SOFTMMU) && \
+-    defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64)
++#if defined(CONFIG_SOFTMMU) && (TARGET_LONG_BITS == 64)
+         /* Avoid clashes with registers being used for helper args */
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
+@@ -223,7 +222,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+ #ifdef CONFIG_SOFTMMU
+         /* r2 is still needed to load data_reg, so don't use it. */
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R2);
+-#if defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64)
++#if TARGET_LONG_BITS == 64
+         /* Avoid clashes with registers being used for helper args */
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
+ #endif
+@@ -954,7 +953,6 @@ static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
+ 
+ #include "../../softmmu_defs.h"
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
+    int mmu_idx) */
+ static const void * const qemu_ld_helpers[4] = {
+@@ -972,25 +970,6 @@ static const void * const qemu_st_helpers[4] = {
+     helper_stl_mmu,
+     helper_stq_mmu,
+ };
+-#else
+-/* legacy helper signature: __ld_mmu(target_ulong addr, int
+-   mmu_idx) */
+-static void *qemu_ld_helpers[4] = {
+-    __ldb_mmu,
+-    __ldw_mmu,
+-    __ldl_mmu,
+-    __ldq_mmu,
+-};
+-
+-/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
+-   int mmu_idx) */
+-static void *qemu_st_helpers[4] = {
+-    __stb_mmu,
+-    __stw_mmu,
+-    __stl_mmu,
+-    __stq_mmu,
+-};
+-#endif
+ 
+ /* Helper routines for marshalling helper function arguments into
+  * the correct registers and stack.
+@@ -1203,9 +1182,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+      * trash by moving the earlier arguments into them.
+      */
+     argreg = TCG_REG_R0;
+-#ifdef CONFIG_TCG_PASS_AREG0
+     argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
+-#endif
+ #if TARGET_LONG_BITS == 64
+     argreg = tcg_out_arg_reg64(s, argreg, addr_reg, addr_reg2);
+ #else
+@@ -1421,9 +1398,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
+      * trash by moving the earlier arguments into them.
+      */
+     argreg = TCG_REG_R0;
+-#ifdef CONFIG_TCG_PASS_AREG0
+     argreg = tcg_out_arg_reg32(s, argreg, TCG_AREG0);
+-#endif
+ #if TARGET_LONG_BITS == 64
+     argreg = tcg_out_arg_reg64(s, argreg, addr_reg, addr_reg2);
+ #else
+diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
+index f90b834..c0b8f72 100644
+--- a/tcg/arm/tcg-target.h
++++ b/tcg/arm/tcg-target.h
+@@ -77,7 +77,6 @@ typedef enum {
+ #define TCG_TARGET_HAS_GUEST_BASE
+ 
+ enum {
+-    /* Note: must be synced with dyngen-exec.h */
+     TCG_AREG0 = TCG_REG_R6,
+ };
+ 
+diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
+index 2885212..8b81b70 100644
+--- a/tcg/hppa/tcg-target.c
++++ b/tcg/hppa/tcg-target.c
+@@ -882,7 +882,6 @@ static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret,
+ #if defined(CONFIG_SOFTMMU)
+ #include "../../softmmu_defs.h"
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
+    int mmu_idx) */
+ static const void * const qemu_ld_helpers[4] = {
+@@ -900,25 +899,6 @@ static const void * const qemu_st_helpers[4] = {
+     helper_stl_mmu,
+     helper_stq_mmu,
+ };
+-#else
+-/* legacy helper signature: __ld_mmu(target_ulong addr, int
+-   mmu_idx) */
+-static void *qemu_ld_helpers[4] = {
+-    __ldb_mmu,
+-    __ldw_mmu,
+-    __ldl_mmu,
+-    __ldq_mmu,
+-};
+-
+-/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
+-   int mmu_idx) */
+-static void *qemu_st_helpers[4] = {
+-    __stb_mmu,
+-    __stw_mmu,
+-    __stl_mmu,
+-    __stq_mmu,
+-};
+-#endif
+ 
+ /* Load and compare a TLB entry, and branch if TLB miss.  OFFSET is set to
+    the offset of the first ADDR_READ or ADDR_WRITE member of the appropriate
+@@ -1085,7 +1065,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+     }
+     tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+     /* XXX/FIXME: suboptimal */
+     tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
+                 tcg_target_call_iarg_regs[1]);
+@@ -1093,7 +1072,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+                 tcg_target_call_iarg_regs[0]);
+     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+                 TCG_AREG0);
+-#endif
+     tcg_out_call(s, qemu_ld_helpers[opc & 3]);
+ 
+     switch (opc) {
+@@ -1245,7 +1223,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
+         tcg_abort();
+     }
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+     /* XXX/FIXME: suboptimal */
+     tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
+                 tcg_target_call_iarg_regs[2]);
+@@ -1255,7 +1232,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
+                 tcg_target_call_iarg_regs[0]);
+     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+                 TCG_AREG0);
+-#endif
+     tcg_out_call(s, qemu_st_helpers[opc]);
+ 
+     /* label2: */
+diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
+index d4bf6fe..01ef960 100644
+--- a/tcg/hppa/tcg-target.h
++++ b/tcg/hppa/tcg-target.h
+@@ -104,7 +104,6 @@ typedef enum {
+ 
+ #define TCG_TARGET_HAS_GUEST_BASE
+ 
+-/* Note: must be synced with dyngen-exec.h */
+ #define TCG_AREG0 TCG_REG_R17
+ 
+ 
+diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
+index da17bba..34c2df8 100644
+--- a/tcg/i386/tcg-target.c
++++ b/tcg/i386/tcg-target.c
+@@ -183,9 +183,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+             tcg_regset_set32(ct->u.regs, 0, 0xffff);
+             tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[0]);
+             tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[1]);
+-#ifdef CONFIG_TCG_PASS_AREG0
+             tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[2]);
+-#endif
+         } else {
+             tcg_regset_set32(ct->u.regs, 0, 0xff);
+             tcg_regset_reset_reg(ct->u.regs, TCG_REG_EAX);
+@@ -965,7 +963,6 @@ static void tcg_out_jmp(TCGContext *s, tcg_target_long dest)
+ 
+ #include "../../softmmu_defs.h"
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
+    int mmu_idx) */
+ static const void *qemu_ld_helpers[4] = {
+@@ -983,25 +980,6 @@ static const void *qemu_st_helpers[4] = {
+     helper_stl_mmu,
+     helper_stq_mmu,
+ };
+-#else
+-/* legacy helper signature: __ld_mmu(target_ulong addr, int
+-   mmu_idx) */
+-static void *qemu_ld_helpers[4] = {
+-    __ldb_mmu,
+-    __ldw_mmu,
+-    __ldl_mmu,
+-    __ldq_mmu,
+-};
+-
+-/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
+-   int mmu_idx) */
+-static void *qemu_st_helpers[4] = {
+-    __stb_mmu,
+-    __stw_mmu,
+-    __stl_mmu,
+-    __stq_mmu,
+-};
+-#endif
+ 
+ /* Perform the TLB load and compare.
+ 
+@@ -1220,16 +1198,13 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+     }
+     tcg_out_push(s, args[addrlo_idx]);
+     stack_adjust += 4;
+-#ifdef CONFIG_TCG_PASS_AREG0
+     tcg_out_push(s, TCG_AREG0);
+     stack_adjust += 4;
+-#endif
+ #else
+     /* The first argument is already loaded with addrlo.  */
+     arg_idx = 1;
+     tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[arg_idx],
+                  mem_index);
+-#ifdef CONFIG_TCG_PASS_AREG0
+     /* XXX/FIXME: suboptimal */
+     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
+                 tcg_target_call_iarg_regs[2]);
+@@ -1240,7 +1215,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
+                 TCG_AREG0);
+ #endif
+-#endif
+ 
+     tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
+ 
+@@ -1436,16 +1410,13 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
+     }
+     tcg_out_push(s, args[addrlo_idx]);
+     stack_adjust += 4;
+-#ifdef CONFIG_TCG_PASS_AREG0
+     tcg_out_push(s, TCG_AREG0);
+     stack_adjust += 4;
+-#endif
+ #else
+     tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
+                 tcg_target_call_iarg_regs[1], data_reg);
+     tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], mem_index);
+     stack_adjust = 0;
+-#ifdef CONFIG_TCG_PASS_AREG0
+     /* XXX/FIXME: suboptimal */
+     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
+                 tcg_target_call_iarg_regs[2]);
+@@ -1456,7 +1427,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
+     tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
+                 TCG_AREG0);
+ #endif
+-#endif
+ 
+     tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
+ 
+diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
+index c3cfe05..8be42f3 100644
+--- a/tcg/i386/tcg-target.h
++++ b/tcg/i386/tcg-target.h
+@@ -116,7 +116,6 @@ typedef enum {
+ 
+ #define TCG_TARGET_HAS_GUEST_BASE
+ 
+-/* Note: must be synced with dyngen-exec.h */
+ #if TCG_TARGET_REG_BITS == 64
+ # define TCG_AREG0 TCG_REG_R14
+ #else
+diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
+index dc588db..1745038 100644
+--- a/tcg/ia64/tcg-target.c
++++ b/tcg/ia64/tcg-target.c
+@@ -1452,7 +1452,6 @@ static inline void tcg_out_qemu_tlb(TCGContext *s, TCGArg addr_reg,
+                                TCG_REG_P7, TCG_REG_R3, TCG_REG_R57));
+ }
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
+    int mmu_idx) */
+ static const void * const qemu_ld_helpers[4] = {
+@@ -1461,16 +1460,6 @@ static const void * const qemu_ld_helpers[4] = {
+     helper_ldl_mmu,
+     helper_ldq_mmu,
+ };
+-#else
+-/* legacy helper signature: __ld_mmu(target_ulong addr, int
+-   mmu_idx) */
+-static void *qemu_ld_helpers[4] = {
+-    __ldb_mmu,
+-    __ldw_mmu,
+-    __ldl_mmu,
+-    __ldq_mmu,
+-};
+-#endif
+ 
+ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+ {
+@@ -1530,7 +1519,6 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+                        tcg_opc_m1 (TCG_REG_P7, OPC_LD8_M1, TCG_REG_R1, TCG_REG_R2),
+                        tcg_opc_i18(TCG_REG_P0, OPC_NOP_I18, 0));
+     }
+-#ifdef CONFIG_TCG_PASS_AREG0
+     /* XXX/FIXME: suboptimal */
+     tcg_out_bundle(s, mII,
+                    tcg_opc_a5 (TCG_REG_P7, OPC_ADDL_A5, TCG_REG_R58,
+@@ -1539,7 +1527,6 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+                                TCG_REG_R57, 0, TCG_REG_R56),
+                    tcg_opc_a4 (TCG_REG_P7, OPC_ADDS_A4,
+                                TCG_REG_R56, 0, TCG_AREG0));
+-#endif
+     if (!bswap || s_bits == 0) {
+         tcg_out_bundle(s, miB,
+                        tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+@@ -1570,7 +1557,6 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+     }
+ }
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ /* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
+    uintxx_t val, int mmu_idx) */
+ static const void * const qemu_st_helpers[4] = {
+@@ -1579,16 +1565,6 @@ static const void * const qemu_st_helpers[4] = {
+     helper_stl_mmu,
+     helper_stq_mmu,
+ };
+-#else
+-/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
+-   int mmu_idx) */
+-static void *qemu_st_helpers[4] = {
+-    __stb_mmu,
+-    __stw_mmu,
+-    __stl_mmu,
+-    __stq_mmu,
+-};
+-#endif
+ 
+ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
+ {
+@@ -1658,7 +1634,6 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
+         data_reg = TCG_REG_R2;
+     }
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+     /* XXX/FIXME: suboptimal */
+     tcg_out_bundle(s, mII,
+                    tcg_opc_a5 (TCG_REG_P7, OPC_ADDL_A5, TCG_REG_R59,
+@@ -1674,15 +1649,6 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
+                                TCG_REG_R56, 0, TCG_AREG0),
+                    tcg_opc_b5 (TCG_REG_P7, OPC_BR_CALL_SPTK_MANY_B5,
+                                TCG_REG_B0, TCG_REG_B6));
+-#else
+-    tcg_out_bundle(s, miB,
+-                   tcg_opc_m4 (TCG_REG_P6, opc_st_m4[opc],
+-                               data_reg, TCG_REG_R3),
+-                   tcg_opc_a5 (TCG_REG_P7, OPC_ADDL_A5, TCG_REG_R58,
+-                               mem_index, TCG_REG_R0),
+-                   tcg_opc_b5 (TCG_REG_P7, OPC_BR_CALL_SPTK_MANY_B5,
+-                               TCG_REG_B0, TCG_REG_B6));
+-#endif
+ }
+ 
+ #else /* !CONFIG_SOFTMMU */
+diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
+index 0631b9f..c22962a 100644
+--- a/tcg/ia64/tcg-target.h
++++ b/tcg/ia64/tcg-target.h
+@@ -140,7 +140,6 @@ typedef enum {
+ #define TCG_TARGET_HAS_not_i32          0 /* xor r1, -1, r3 */
+ #define TCG_TARGET_HAS_not_i64          0 /* xor r1, -1, r3 */
+ 
+-/* Note: must be synced with dyngen-exec.h */
+ #define TCG_AREG0 TCG_REG_R7
+ 
+ /* Guest base is supported */
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index 1006e28..74db83d 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -217,7 +217,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+         tcg_regset_set(ct->u.regs, 0xffffffff);
+ #if defined(CONFIG_SOFTMMU)
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
+-# if defined(CONFIG_TCG_PASS_AREG0) && (TARGET_LONG_BITS == 64)
++# if (TARGET_LONG_BITS == 64)
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
+ # endif
+ #endif
+@@ -227,12 +227,11 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+         tcg_regset_set(ct->u.regs, 0xffffffff);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A0);
+ #if defined(CONFIG_SOFTMMU)
+-# if (defined(CONFIG_TCG_PASS_AREG0) && TARGET_LONG_BITS == 32) || \
+-     (!defined(CONFIG_TCG_PASS_AREG0) && TARGET_LONG_BITS == 64)
++# if (TARGET_LONG_BITS == 32)
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A1);
+ # endif
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A2);
+-# if defined(CONFIG_TCG_PASS_AREG0) && TARGET_LONG_BITS == 64
++# if TARGET_LONG_BITS == 64
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_A3);
+ # endif
+ #endif
+@@ -821,7 +820,6 @@ static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
+ 
+ #include "../../softmmu_defs.h"
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
+    int mmu_idx) */
+ static const void * const qemu_ld_helpers[4] = {
+@@ -839,25 +837,6 @@ static const void * const qemu_st_helpers[4] = {
+     helper_stl_mmu,
+     helper_stq_mmu,
+ };
+-#else
+-/* legacy helper signature: __ld_mmu(target_ulong addr, int
+-   mmu_idx) */
+-static void *qemu_ld_helpers[4] = {
+-    __ldb_mmu,
+-    __ldw_mmu,
+-    __ldl_mmu,
+-    __ldq_mmu,
+-};
+-
+-/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
+-   int mmu_idx) */
+-static void *qemu_st_helpers[4] = {
+-    __stb_mmu,
+-    __stw_mmu,
+-    __stl_mmu,
+-    __stq_mmu,
+-};
+-#endif
+ #endif
+ 
+ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+@@ -942,9 +921,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+ 
+     /* slow path */
+     arg_num = 0;
+-# ifdef CONFIG_TCG_PASS_AREG0
+     tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
+-# endif
+ # if TARGET_LONG_BITS == 64
+     tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
+ # else
+@@ -1127,9 +1104,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
+ 
+     /* slow path */
+     arg_num = 0;
+-# ifdef CONFIG_TCG_PASS_AREG0
+     tcg_out_call_iarg_reg32(s, &arg_num, TCG_AREG0);
+-# endif
+ # if TARGET_LONG_BITS == 64
+     tcg_out_call_iarg_reg64(s, &arg_num, addr_regl, addr_regh);
+ # else
+diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
+index d3c804d..1c61931 100644
+--- a/tcg/mips/tcg-target.h
++++ b/tcg/mips/tcg-target.h
+@@ -96,7 +96,6 @@ typedef enum {
+ #define TCG_TARGET_HAS_ext8u_i32        0 /* andi rt, rs, 0xff   */
+ #define TCG_TARGET_HAS_ext16u_i32       0 /* andi rt, rs, 0xffff */
+ 
+-/* Note: must be synced with dyngen-exec.h */
+ #define TCG_AREG0 TCG_REG_S0
+ 
+ /* guest base is supported */
+diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
+index 0cff181..26c4b33 100644
+--- a/tcg/ppc/tcg-target.c
++++ b/tcg/ppc/tcg-target.c
+@@ -248,7 +248,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
+-#ifdef CONFIG_TCG_PASS_AREG0
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
+ #if TARGET_LONG_BITS == 64
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
+@@ -256,11 +255,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
+ #endif
+ #endif
+-#else /* !AREG0 */
+-#if TARGET_LONG_BITS == 64
+-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
+-#endif
+-#endif
+         break;
+     case 'K':                   /* qemu_st[8..32] constraint */
+         ct->ct |= TCG_CT_REG;
+@@ -268,7 +262,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
+-#ifdef CONFIG_TCG_PASS_AREG0
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
+ #if TARGET_LONG_BITS == 64
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
+@@ -276,11 +269,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R8);
+ #endif
+ #endif
+-#else /* !AREG0 */
+-#if TARGET_LONG_BITS == 64
+-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
+-#endif
+-#endif
+         break;
+     case 'M':                   /* qemu_st64 constraint */
+         ct->ct |= TCG_CT_REG;
+@@ -290,12 +278,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
+-#if defined(CONFIG_TCG_PASS_AREG0)
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R8);
+ #ifdef TCG_TARGET_CALL_ALIGN_ARGS
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R9);
+ #endif
+-#endif
+         break;
+ #else
+     case 'L':
+@@ -541,7 +527,6 @@ static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
+ 
+ #include "../../softmmu_defs.h"
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
+    int mmu_idx) */
+ static const void * const qemu_ld_helpers[4] = {
+@@ -559,25 +544,6 @@ static const void * const qemu_st_helpers[4] = {
+     helper_stl_mmu,
+     helper_stq_mmu,
+ };
+-#else
+-/* legacy helper signature: __ld_mmu(target_ulong addr, int
+-   mmu_idx) */
+-static void *qemu_ld_helpers[4] = {
+-    __ldb_mmu,
+-    __ldw_mmu,
+-    __ldl_mmu,
+-    __ldq_mmu,
+-};
+-
+-/* legacy helper signature: __ld_mmu(target_ulong addr, int
+-   mmu_idx) */
+-static void *qemu_st_helpers[4] = {
+-    __stb_mmu,
+-    __stw_mmu,
+-    __stl_mmu,
+-    __stq_mmu,
+-};
+-#endif
+ #endif
+ 
+ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
+@@ -647,9 +613,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
+ 
+     /* slow path */
+     ir = 3;
+-#ifdef CONFIG_TCG_PASS_AREG0
+     tcg_out_mov (s, TCG_TYPE_I32, ir++, TCG_AREG0);
+-#endif
+ #if TARGET_LONG_BITS == 32
+     tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
+ #else
+@@ -849,9 +813,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
+ 
+     /* slow path */
+     ir = 3;
+-#ifdef CONFIG_TCG_PASS_AREG0
+     tcg_out_mov (s, TCG_TYPE_I32, ir++, TCG_AREG0);
+-#endif
+ #if TARGET_LONG_BITS == 32
+     tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
+ #else
+diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
+index 27a0ae8..337cd41 100644
+--- a/tcg/ppc64/tcg-target.c
++++ b/tcg/ppc64/tcg-target.c
+@@ -235,10 +235,8 @@ static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str)
+         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R3);
+ #ifdef CONFIG_SOFTMMU
+         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
+-#ifdef CONFIG_TCG_PASS_AREG0
+         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
+ #endif
+-#endif
+         break;
+     case 'S':                   /* qemu_st constraint */
+         ct->ct |= TCG_CT_REG;
+@@ -247,10 +245,8 @@ static int target_parse_constraint (TCGArgConstraint *ct, const char **pct_str)
+ #ifdef CONFIG_SOFTMMU
+         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R4);
+         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R5);
+-#ifdef CONFIG_TCG_PASS_AREG0
+         tcg_regset_reset_reg (ct->u.regs, TCG_REG_R6);
+ #endif
+-#endif
+         break;
+     case 'Z':
+         ct->ct |= TCG_CT_CONST_U32;
+@@ -558,7 +554,6 @@ static void tcg_out_ldsta (TCGContext *s, int ret, int addr,
+ 
+ #include "../../softmmu_defs.h"
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
+    int mmu_idx) */
+ static const void * const qemu_ld_helpers[4] = {
+@@ -576,25 +571,6 @@ static const void * const qemu_st_helpers[4] = {
+     helper_stl_mmu,
+     helper_stq_mmu,
+ };
+-#else
+-/* legacy helper signature: __ld_mmu(target_ulong addr, int
+-   mmu_idx) */
+-static void *qemu_ld_helpers[4] = {
+-    __ldb_mmu,
+-    __ldw_mmu,
+-    __ldl_mmu,
+-    __ldq_mmu,
+-};
+-
+-/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
+-   int mmu_idx) */
+-static void *qemu_st_helpers[4] = {
+-    __stb_mmu,
+-    __stw_mmu,
+-    __stl_mmu,
+-    __stq_mmu,
+-};
+-#endif
+ 
+ static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
+                               int addr_reg, int s_bits, int offset)
+@@ -676,9 +652,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
+ 
+     /* slow path */
+     ir = 3;
+-#ifdef CONFIG_TCG_PASS_AREG0
+     tcg_out_mov (s, TCG_TYPE_I64, ir++, TCG_AREG0);
+-#endif
+     tcg_out_mov (s, TCG_TYPE_I64, ir++, addr_reg);
+     tcg_out_movi (s, TCG_TYPE_I64, ir++, mem_index);
+ 
+@@ -827,9 +801,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
+ 
+     /* slow path */
+     ir = 3;
+-#ifdef CONFIG_TCG_PASS_AREG0
+     tcg_out_mov (s, TCG_TYPE_I64, ir++, TCG_AREG0);
+-#endif
+     tcg_out_mov (s, TCG_TYPE_I64, ir++, addr_reg);
+     tcg_out_rld (s, RLDICL, ir++, data_reg, 0, 64 - (1 << (3 + opc)));
+     tcg_out_movi (s, TCG_TYPE_I64, ir++, mem_index);
+diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
+index 99b5339..aac11d9 100644
+--- a/tcg/s390/tcg-target.c
++++ b/tcg/s390/tcg-target.c
+@@ -301,7 +301,6 @@ static const uint8_t tcg_cond_to_ltr_cond[10] = {
+ 
+ #include "../../softmmu_defs.h"
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
+    int mmu_idx) */
+ static const void * const qemu_ld_helpers[4] = {
+@@ -319,25 +318,6 @@ static const void * const qemu_st_helpers[4] = {
+     helper_stl_mmu,
+     helper_stq_mmu,
+ };
+-#else
+-/* legacy helper signature: __ld_mmu(target_ulong addr, int
+-   mmu_idx) */
+-static void *qemu_ld_helpers[4] = {
+-    __ldb_mmu,
+-    __ldw_mmu,
+-    __ldl_mmu,
+-    __ldq_mmu,
+-};
+-
+-/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
+-   int mmu_idx) */
+-static void *qemu_st_helpers[4] = {
+-    __stb_mmu,
+-    __stw_mmu,
+-    __stl_mmu,
+-    __stq_mmu,
+-};
+-#endif
+ #endif
+ 
+ static uint8_t *tb_ret_addr;
+@@ -1507,7 +1487,6 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
+             tcg_abort();
+         }
+         tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R4, mem_index);
+-#ifdef CONFIG_TCG_PASS_AREG0
+         /* XXX/FIXME: suboptimal */
+         tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[3],
+                     tcg_target_call_iarg_regs[2]);
+@@ -1517,11 +1496,9 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
+                     tcg_target_call_iarg_regs[0]);
+         tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
+                     TCG_AREG0);
+-#endif
+         tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
+     } else {
+         tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
+-#ifdef CONFIG_TCG_PASS_AREG0
+         /* XXX/FIXME: suboptimal */
+         tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
+                     tcg_target_call_iarg_regs[1]);
+@@ -1529,7 +1506,6 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, TCGReg data_reg,
+                     tcg_target_call_iarg_regs[0]);
+         tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0],
+                     TCG_AREG0);
+-#endif
+         tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
+ 
+         /* sign extension */
+diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
+index d12f90b..4f7dfab 100644
+--- a/tcg/s390/tcg-target.h
++++ b/tcg/s390/tcg-target.h
+@@ -96,7 +96,6 @@ typedef enum TCGReg {
+ #define TCG_TARGET_EXTEND_ARGS 1
+ 
+ enum {
+-    /* Note: must be synced with dyngen-exec.h */
+     TCG_AREG0 = TCG_REG_R10,
+ };
+ 
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index 247a278..baed3b4 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -59,11 +59,7 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
+ };
+ #endif
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ #define ARG_OFFSET 1
+-#else
+-#define ARG_OFFSET 0
+-#endif
+ 
+ static const int tcg_target_reg_alloc_order[] = {
+     TCG_REG_L0,
+@@ -161,9 +157,7 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
+-#ifdef CONFIG_TCG_PASS_AREG0
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O3);
+-#endif
+         break;
+     case 'I':
+         ct->ct |= TCG_CT_CONST_S11;
+@@ -715,7 +709,6 @@ static void tcg_target_qemu_prologue(TCGContext *s)
+ 
+ #include "../../softmmu_defs.h"
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+ /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
+    int mmu_idx) */
+ static const void * const qemu_ld_helpers[4] = {
+@@ -733,25 +726,6 @@ static const void * const qemu_st_helpers[4] = {
+     helper_stl_mmu,
+     helper_stq_mmu,
+ };
+-#else
+-/* legacy helper signature: __ld_mmu(target_ulong addr, int
+-   mmu_idx) */
+-static const void * const qemu_ld_helpers[4] = {
+-    __ldb_mmu,
+-    __ldw_mmu,
+-    __ldl_mmu,
+-    __ldq_mmu,
+-};
+-
+-/* legacy helper signature: __st_mmu(target_ulong addr, uintxx_t val,
+-   int mmu_idx) */
+-static const void * const qemu_st_helpers[4] = {
+-    __stb_mmu,
+-    __stw_mmu,
+-    __stl_mmu,
+-    __stq_mmu,
+-};
+-#endif
+ #endif
+ 
+ #if TARGET_LONG_BITS == 32
+@@ -834,7 +808,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+ 
+     /* mov */
+     tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
+-#ifdef CONFIG_TCG_PASS_AREG0
+     /* XXX/FIXME: suboptimal */
+     tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
+                 tcg_target_call_iarg_regs[2]);
+@@ -844,7 +817,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+                 tcg_target_call_iarg_regs[0]);
+     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+                 TCG_AREG0);
+-#endif
+ 
+     /* XXX: move that code at the end of the TB */
+     /* qemu_ld_helper[s_bits](arg0, arg1) */
+@@ -1061,7 +1033,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
+     /* mov */
+     tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
+ 
+-#ifdef CONFIG_TCG_PASS_AREG0
+     /* XXX/FIXME: suboptimal */
+     tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
+                 tcg_target_call_iarg_regs[2]);
+@@ -1071,7 +1042,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
+                 tcg_target_call_iarg_regs[0]);
+     tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+                 TCG_AREG0);
+-#endif
+     /* XXX: move that code at the end of the TB */
+     /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
+     tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
+diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
+index ee2274d..0ea87be 100644
+--- a/tcg/sparc/tcg-target.h
++++ b/tcg/sparc/tcg-target.h
+@@ -125,7 +125,6 @@ typedef enum {
+ #define TCG_TARGET_HAS_deposit_i64      0
+ #endif
+ 
+-/* Note: must be synced with dyngen-exec.h */
+ #ifdef CONFIG_SOLARIS
+ #define TCG_AREG0 TCG_REG_G2
+ #elif defined(__sparc_v9__)
+diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
+index ef8580f..003244c 100644
+--- a/tcg/tci/tcg-target.c
++++ b/tcg/tci/tcg-target.c
+@@ -798,9 +798,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+     case INDEX_op_qemu_st8:
+     case INDEX_op_qemu_st16:
+     case INDEX_op_qemu_st32:
+-#ifdef CONFIG_TCG_PASS_AREG0
+         tcg_out_r(s, TCG_AREG0);
+-#endif
+         tcg_out_r(s, *args++);
+         tcg_out_r(s, *args++);
+ #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
+@@ -811,9 +809,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+ #endif
+         break;
+     case INDEX_op_qemu_st64:
+-#ifdef CONFIG_TCG_PASS_AREG0
+         tcg_out_r(s, TCG_AREG0);
+-#endif
+         tcg_out_r(s, *args++);
+ #if TCG_TARGET_REG_BITS == 32
+         tcg_out_r(s, *args++);
+diff --git a/tci.c b/tci.c
+index c79350d..ce8a988 100644
+--- a/tci.c
++++ b/tci.c
+@@ -25,7 +25,6 @@
+ #endif
+ 
+ #include "qemu-common.h"
+-#include "dyngen-exec.h"        /* env */
+ #include "exec-all.h"           /* MAX_OPC_PARAM_IARGS */
+ #include "tcg-op.h"
+ 
+@@ -63,17 +62,6 @@ uintptr_t tci_tb_ptr;
+ 
+ static tcg_target_ulong tci_reg[TCG_TARGET_NB_REGS];
+ 
+-#if !defined(CONFIG_TCG_PASS_AREG0)
+-# define helper_ldb_mmu(env, addr, mmu_idx) __ldb_mmu(addr, mmu_idx)
+-# define helper_ldw_mmu(env, addr, mmu_idx) __ldw_mmu(addr, mmu_idx)
+-# define helper_ldl_mmu(env, addr, mmu_idx) __ldl_mmu(addr, mmu_idx)
+-# define helper_ldq_mmu(env, addr, mmu_idx) __ldq_mmu(addr, mmu_idx)
+-# define helper_stb_mmu(env, addr, val, mmu_idx) __stb_mmu(addr, val, mmu_idx)
+-# define helper_stw_mmu(env, addr, val, mmu_idx) __stw_mmu(addr, val, mmu_idx)
+-# define helper_stl_mmu(env, addr, val, mmu_idx) __stl_mmu(addr, val, mmu_idx)
+-# define helper_stq_mmu(env, addr, val, mmu_idx) __stq_mmu(addr, val, mmu_idx)
+-#endif /* !CONFIG_TCG_PASS_AREG0 */
+-
+ static tcg_target_ulong tci_read_reg(TCGReg index)
+ {
+     assert(index < ARRAY_SIZE(tci_reg));
+diff --git a/user-exec.c b/user-exec.c
+index b9ea9dd..ef9b172 100644
+--- a/user-exec.c
++++ b/user-exec.c
+@@ -18,9 +18,6 @@
+  */
+ #include "config.h"
+ #include "cpu.h"
+-#ifndef CONFIG_TCG_PASS_AREG0
+-#include "dyngen-exec.h"
+-#endif
+ #include "disas.h"
+ #include "tcg.h"
+ 
+@@ -60,12 +57,6 @@ void cpu_resume_from_signal(CPUArchState *env1, void *puc)
+     struct sigcontext *uc = puc;
+ #endif
+ 
+-#ifndef CONFIG_TCG_PASS_AREG0
+-    env = env1;
+-
+-    /* XXX: restore cpu registers saved in host registers */
+-#endif
+-
+     if (puc) {
+         /* XXX: use siglongjmp ? */
+ #ifdef __linux__
+@@ -93,11 +84,6 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
+     TranslationBlock *tb;
+     int ret;
+ 
+-#ifndef CONFIG_TCG_PASS_AREG0
+-    if (cpu_single_env) {
+-        env = cpu_single_env; /* XXX: find a correct solution for multithread */
+-    }
+-#endif
+ #if defined(DEBUG_SIGNAL)
+     qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
+                 pc, address, is_write, *(unsigned long *)old_set);
+-- 
+1.7.12.1
+
diff --git a/0040-tcg-i386-allow-constants-in-load-store-ops.patch b/0040-tcg-i386-allow-constants-in-load-store-ops.patch
new file mode 100644
index 0000000..0c9066c
--- /dev/null
+++ b/0040-tcg-i386-allow-constants-in-load-store-ops.patch
@@ -0,0 +1,114 @@
+From 83b25655bcd988054a2bb2a0a38dc662d4901b08 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Mon, 10 Sep 2012 13:56:24 +0200
+Subject: [PATCH] tcg/i386: allow constants in load/store ops
+
+On x86, it is possible to move a constant value to memory. Add code to
+handle a constant argument to load/store ops.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/i386/tcg-target.c | 50 +++++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 37 insertions(+), 13 deletions(-)
+
+diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
+index 34c2df8..3017858 100644
+--- a/tcg/i386/tcg-target.c
++++ b/tcg/i386/tcg-target.c
+@@ -263,6 +263,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
+ #define OPC_MOVB_EvGv	(0x88)		/* stores, more or less */
+ #define OPC_MOVL_EvGv	(0x89)		/* stores, more or less */
+ #define OPC_MOVL_GvEv	(0x8b)		/* loads, more or less */
++#define OPC_MOVB_EvIz   (0xc6)
+ #define OPC_MOVL_EvIz	(0xc7)
+ #define OPC_MOVL_Iv     (0xb8)
+ #define OPC_MOVSBL	(0xbe | P_EXT)
+@@ -1543,18 +1544,35 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
+         break;
+ 
+     OP_32_64(st8):
+-        tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
+-                             args[0], args[1], args[2]);
++        if (const_args[0]) {
++            tcg_out_modrm_offset(s, OPC_MOVB_EvIz,
++                                 0, args[1], args[2]);
++            tcg_out8(s, args[0]);
++        } else {
++            tcg_out_modrm_offset(s, OPC_MOVB_EvGv | P_REXB_R,
++                                 args[0], args[1], args[2]);
++        }
+         break;
+     OP_32_64(st16):
+-        tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
+-                             args[0], args[1], args[2]);
++        if (const_args[0]) {
++            tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_DATA16,
++                                 0, args[1], args[2]);
++            tcg_out16(s, args[0]);
++        } else {
++            tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
++                                 args[0], args[1], args[2]);
++        }
+         break;
+ #if TCG_TARGET_REG_BITS == 64
+     case INDEX_op_st32_i64:
+ #endif
+     case INDEX_op_st_i32:
+-        tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
++        if (const_args[0]) {
++            tcg_out_modrm_offset(s, OPC_MOVL_EvIz, 0, args[1], args[2]);
++            tcg_out32(s, args[0]);
++        } else {
++            tcg_out_st(s, TCG_TYPE_I32, args[0], args[1], args[2]);
++        }
+         break;
+ 
+     OP_32_64(add):
+@@ -1758,7 +1776,13 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
+         tcg_out_ld(s, TCG_TYPE_I64, args[0], args[1], args[2]);
+         break;
+     case INDEX_op_st_i64:
+-        tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
++        if (const_args[0]) {
++            tcg_out_modrm_offset(s, OPC_MOVL_EvIz | P_REXW,
++                                 0, args[1], args[2]);
++            tcg_out32(s, args[0]);
++        } else {
++            tcg_out_st(s, TCG_TYPE_I64, args[0], args[1], args[2]);
++        }
+         break;
+     case INDEX_op_qemu_ld32s:
+         tcg_out_qemu_ld(s, args, 2 | 4);
+@@ -1820,9 +1844,9 @@ static const TCGTargetOpDef x86_op_defs[] = {
+     { INDEX_op_ld16u_i32, { "r", "r" } },
+     { INDEX_op_ld16s_i32, { "r", "r" } },
+     { INDEX_op_ld_i32, { "r", "r" } },
+-    { INDEX_op_st8_i32, { "q", "r" } },
+-    { INDEX_op_st16_i32, { "r", "r" } },
+-    { INDEX_op_st_i32, { "r", "r" } },
++    { INDEX_op_st8_i32, { "qi", "r" } },
++    { INDEX_op_st16_i32, { "ri", "r" } },
++    { INDEX_op_st_i32, { "ri", "r" } },
+ 
+     { INDEX_op_add_i32, { "r", "r", "ri" } },
+     { INDEX_op_sub_i32, { "r", "0", "ri" } },
+@@ -1873,10 +1897,10 @@ static const TCGTargetOpDef x86_op_defs[] = {
+     { INDEX_op_ld32u_i64, { "r", "r" } },
+     { INDEX_op_ld32s_i64, { "r", "r" } },
+     { INDEX_op_ld_i64, { "r", "r" } },
+-    { INDEX_op_st8_i64, { "r", "r" } },
+-    { INDEX_op_st16_i64, { "r", "r" } },
+-    { INDEX_op_st32_i64, { "r", "r" } },
+-    { INDEX_op_st_i64, { "r", "r" } },
++    { INDEX_op_st8_i64, { "ri", "r" } },
++    { INDEX_op_st16_i64, { "ri", "r" } },
++    { INDEX_op_st32_i64, { "ri", "r" } },
++    { INDEX_op_st_i64, { "re", "r" } },
+ 
+     { INDEX_op_add_i64, { "r", "0", "re" } },
+     { INDEX_op_mul_i64, { "r", "0", "re" } },
+-- 
+1.7.12.1
+
diff --git a/0041-tcg-mark-set_label-with-TCG_OPF_BB_END-flag.patch b/0041-tcg-mark-set_label-with-TCG_OPF_BB_END-flag.patch
new file mode 100644
index 0000000..bfab53b
--- /dev/null
+++ b/0041-tcg-mark-set_label-with-TCG_OPF_BB_END-flag.patch
@@ -0,0 +1,53 @@
+From 1610a0e56c0be3e4bfd3034e5323188b1d05badd Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Mon, 10 Sep 2012 14:23:49 +0200
+Subject: [PATCH] tcg: mark set_label with TCG_OPF_BB_END flag
+
+set_label is effectively the end of a basic block, as no optimization
+can be made accross it. It was treated as such in the liveness analysis
+code, but as a special case.
+
+Mark it with TCG_OPF_BB_END flag so that this information can be used
+by other parts of the TCG code, and remove the special case in the liveness
+analysis code.
+
+Cc: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/tcg-opc.h | 2 +-
+ tcg/tcg.c     | 5 -----
+ 2 files changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
+index 8e06d03..d12e8d0 100644
+--- a/tcg/tcg-opc.h
++++ b/tcg/tcg-opc.h
+@@ -36,7 +36,7 @@ DEF(nopn, 0, 0, 1, 0) /* variable number of parameters */
+ 
+ DEF(discard, 1, 0, 0, 0)
+ 
+-DEF(set_label, 0, 0, 1, 0)
++DEF(set_label, 0, 0, 1, TCG_OPF_BB_END)
+ DEF(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */
+ DEF(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+ DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+diff --git a/tcg/tcg.c b/tcg/tcg.c
+index 8386b70..c002a88 100644
+--- a/tcg/tcg.c
++++ b/tcg/tcg.c
+@@ -1297,11 +1297,6 @@ static void tcg_liveness_analysis(TCGContext *s)
+                 args--;
+             }
+             break;
+-        case INDEX_op_set_label:
+-            args--;
+-            /* mark end of basic block */
+-            tcg_la_bb_end(s, dead_temps);
+-            break;
+         case INDEX_op_debug_insn_start:
+             args -= def->nb_args;
+             break;
+-- 
+1.7.12.1
+
diff --git a/0042-revert-TCG-fix-copy-propagation.patch b/0042-revert-TCG-fix-copy-propagation.patch
new file mode 100644
index 0000000..9e0a169
--- /dev/null
+++ b/0042-revert-TCG-fix-copy-propagation.patch
@@ -0,0 +1,85 @@
+From 2b8d0049e88c17749ccb978509d3f8fda180d35f Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Mon, 10 Sep 2012 13:14:12 +0200
+Subject: [PATCH] revert "TCG: fix copy propagation"
+
+Given the copy propagation breakage on 32-bit hosts has been fixed
+commit e31b0a7c050711884ad570fe73df806520953618 can be reverted.
+
+Cc: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 15 ++++++---------
+ tcg/tcg.h      |  5 -----
+ 2 files changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index fba0ed9..10d9773 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -107,15 +107,12 @@ static TCGOpcode op_to_movi(TCGOpcode op)
+     }
+ }
+ 
+-static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args, TCGArg dst,
+-                            TCGArg src, int nb_temps, int nb_globals)
++static void tcg_opt_gen_mov(TCGArg *gen_args, TCGArg dst, TCGArg src,
++                            int nb_temps, int nb_globals)
+ {
+         reset_temp(dst, nb_temps, nb_globals);
+         assert(temps[src].state != TCG_TEMP_COPY);
+-        /* Don't try to copy if one of temps is a global or either one
+-           is local and another is register */
+-        if (src >= nb_globals && dst >= nb_globals &&
+-            tcg_arg_is_local(s, src) == tcg_arg_is_local(s, dst)) {
++        if (src >= nb_globals) {
+             assert(temps[src].state != TCG_TEMP_CONST);
+             if (temps[src].state != TCG_TEMP_HAS_COPY) {
+                 temps[src].state = TCG_TEMP_HAS_COPY;
+@@ -444,7 +441,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else {
+                     gen_opc_buf[op_index] = op_to_mov(op);
+-                    tcg_opt_gen_mov(s, gen_args, args[0], args[1],
++                    tcg_opt_gen_mov(gen_args, args[0], args[1],
+                                     nb_temps, nb_globals);
+                     gen_args += 2;
+                 }
+@@ -482,7 +479,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else {
+                     gen_opc_buf[op_index] = op_to_mov(op);
+-                    tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps,
++                    tcg_opt_gen_mov(gen_args, args[0], args[1], nb_temps,
+                                     nb_globals);
+                     gen_args += 2;
+                 }
+@@ -507,7 +504,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 break;
+             }
+             if (temps[args[1]].state != TCG_TEMP_CONST) {
+-                tcg_opt_gen_mov(s, gen_args, args[0], args[1],
++                tcg_opt_gen_mov(gen_args, args[0], args[1],
+                                 nb_temps, nb_globals);
+                 gen_args += 2;
+                 args += 2;
+diff --git a/tcg/tcg.h b/tcg/tcg.h
+index d710694..8fbbc81 100644
+--- a/tcg/tcg.h
++++ b/tcg/tcg.h
+@@ -458,11 +458,6 @@ static inline TCGv_i64 tcg_temp_local_new_i64(void)
+ void tcg_temp_free_i64(TCGv_i64 arg);
+ char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
+ 
+-static inline bool tcg_arg_is_local(TCGContext *s, TCGArg arg)
+-{
+-    return s->temps[arg].temp_local;
+-}
+-
+ #if defined(CONFIG_DEBUG_TCG)
+ /* If you call tcg_clear_temp_count() at the start of a section of
+  * code which is not supposed to leak any TCG temporaries, then
+-- 
+1.7.12.1
+
diff --git a/0043-target-mips-Set-opn-in-gen_ldst_multiple.patch b/0043-target-mips-Set-opn-in-gen_ldst_multiple.patch
new file mode 100644
index 0000000..874c31e
--- /dev/null
+++ b/0043-target-mips-Set-opn-in-gen_ldst_multiple.patch
@@ -0,0 +1,55 @@
+From 3380afc68a701604e51fa22637ef48d93514d678 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Tue, 18 Sep 2012 21:55:32 -0700
+Subject: [PATCH] target-mips: Set opn in gen_ldst_multiple.
+
+Used by MIPS_DEBUG, when enabled.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Acked-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-mips/translate.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/target-mips/translate.c b/target-mips/translate.c
+index 7ab769f..c31f91c 100644
+--- a/target-mips/translate.c
++++ b/target-mips/translate.c
+@@ -9855,6 +9855,7 @@ static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
+ static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
+                                int base, int16_t offset)
+ {
++    const char *opn = "ldst_multiple";
+     TCGv t0, t1;
+     TCGv_i32 t2;
+ 
+@@ -9874,19 +9875,24 @@ static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
+     switch (opc) {
+     case LWM32:
+         gen_helper_lwm(cpu_env, t0, t1, t2);
++        opn = "lwm";
+         break;
+     case SWM32:
+         gen_helper_swm(cpu_env, t0, t1, t2);
++        opn = "swm";
+         break;
+ #ifdef TARGET_MIPS64
+     case LDM:
+         gen_helper_ldm(cpu_env, t0, t1, t2);
++        opn = "ldm";
+         break;
+     case SDM:
+         gen_helper_sdm(cpu_env, t0, t1, t2);
++        opn = "sdm";
+         break;
+ #endif
+     }
++    (void)opn;
+     MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
+     tcg_temp_free(t0);
+     tcg_temp_free(t1);
+-- 
+1.7.12.1
+
diff --git a/0044-target-mips-Fix-MIPS_DEBUG.patch b/0044-target-mips-Fix-MIPS_DEBUG.patch
new file mode 100644
index 0000000..0fa094a
--- /dev/null
+++ b/0044-target-mips-Fix-MIPS_DEBUG.patch
@@ -0,0 +1,288 @@
+From 5dd8e9207a39d8fe41eaa110edfdba5e37064562 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Tue, 18 Sep 2012 21:55:33 -0700
+Subject: [PATCH] target-mips: Fix MIPS_DEBUG.
+
+The macro uses the DisasContext.  Pass it around as needed.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Acked-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-mips/translate.c | 74 +++++++++++++++++++++++++------------------------
+ 1 file changed, 38 insertions(+), 36 deletions(-)
+
+diff --git a/target-mips/translate.c b/target-mips/translate.c
+index c31f91c..4937f6b 100644
+--- a/target-mips/translate.c
++++ b/target-mips/translate.c
+@@ -1431,7 +1431,8 @@ static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
+ }
+ 
+ /* Logic with immediate operand */
+-static void gen_logic_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
++static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
++                          int rt, int rs, int16_t imm)
+ {
+     target_ulong uimm;
+     const char *opn = "imm logic";
+@@ -1474,7 +1475,8 @@ static void gen_logic_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int1
+ }
+ 
+ /* Set on less than with immediate operand */
+-static void gen_slt_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
++static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
++                        int rt, int rs, int16_t imm)
+ {
+     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
+     const char *opn = "imm arith";
+@@ -1775,7 +1777,8 @@ static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
+ }
+ 
+ /* Conditional move */
+-static void gen_cond_move (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
++static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
++                          int rd, int rs, int rt)
+ {
+     const char *opn = "cond move";
+     int l1;
+@@ -1813,7 +1816,8 @@ static void gen_cond_move (CPUMIPSState *env, uint32_t opc, int rd, int rs, int
+ }
+ 
+ /* Logic */
+-static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
++static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
++                      int rd, int rs, int rt)
+ {
+     const char *opn = "logic";
+ 
+@@ -1874,7 +1878,8 @@ static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
+ }
+ 
+ /* Set on lower than */
+-static void gen_slt (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
++static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
++                    int rd, int rs, int rt)
+ {
+     const char *opn = "slt";
+     TCGv t0, t1;
+@@ -8778,10 +8783,10 @@ static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
+         gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
+         break;
+     case M16_OPC_SLTI:
+-        gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
++        gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
+         break;
+     case M16_OPC_SLTIU:
+-        gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
++        gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
+         break;
+     case M16_OPC_I8:
+         switch (funct) {
+@@ -8992,15 +8997,13 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
+     case M16_OPC_SLTI:
+         {
+             int16_t imm = (uint8_t) ctx->opcode;
+-
+-            gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
++            gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
+         }
+         break;
+     case M16_OPC_SLTIU:
+         {
+             int16_t imm = (uint8_t) ctx->opcode;
+-
+-            gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
++            gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
+         }
+         break;
+     case M16_OPC_I8:
+@@ -9075,8 +9078,7 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
+     case M16_OPC_CMPI:
+         {
+             int16_t imm = (uint8_t) ctx->opcode;
+-
+-            gen_logic_imm(env, OPC_XORI, 24, rx, imm);
++            gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
+         }
+         break;
+ #if defined(TARGET_MIPS64)
+@@ -9188,10 +9190,10 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
+             }
+             break;
+         case RR_SLT:
+-            gen_slt(env, OPC_SLT, 24, rx, ry);
++            gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
+             break;
+         case RR_SLTU:
+-            gen_slt(env, OPC_SLTU, 24, rx, ry);
++            gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
+             break;
+         case RR_BREAK:
+             generate_exception(ctx, EXCP_BREAK);
+@@ -9212,22 +9214,22 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
+             break;
+ #endif
+         case RR_CMP:
+-            gen_logic(env, OPC_XOR, 24, rx, ry);
++            gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
+             break;
+         case RR_NEG:
+             gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
+             break;
+         case RR_AND:
+-            gen_logic(env, OPC_AND, rx, rx, ry);
++            gen_logic(env, ctx, OPC_AND, rx, rx, ry);
+             break;
+         case RR_OR:
+-            gen_logic(env, OPC_OR, rx, rx, ry);
++            gen_logic(env, ctx, OPC_OR, rx, rx, ry);
+             break;
+         case RR_XOR:
+-            gen_logic(env, OPC_XOR, rx, rx, ry);
++            gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
+             break;
+         case RR_NOT:
+-            gen_logic(env, OPC_NOR, rx, ry, 0);
++            gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
+             break;
+         case RR_MFHI:
+             gen_HILO(ctx, OPC_MFHI, rx);
+@@ -9849,7 +9851,7 @@ static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
+     int rs = mmreg(uMIPS_RS(ctx->opcode));
+     int encoded = ZIMM(ctx->opcode, 0, 4);
+ 
+-    gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
++    gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
+ }
+ 
+ static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
+@@ -9911,25 +9913,25 @@ static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_bran
+     case NOT16 + 1:
+     case NOT16 + 2:
+     case NOT16 + 3:
+-        gen_logic(env, OPC_NOR, rd, rs, 0);
++        gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
+         break;
+     case XOR16 + 0:
+     case XOR16 + 1:
+     case XOR16 + 2:
+     case XOR16 + 3:
+-        gen_logic(env, OPC_XOR, rd, rd, rs);
++        gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
+         break;
+     case AND16 + 0:
+     case AND16 + 1:
+     case AND16 + 2:
+     case AND16 + 3:
+-        gen_logic(env, OPC_AND, rd, rd, rs);
++        gen_logic(env, ctx, OPC_AND, rd, rd, rs);
+         break;
+     case OR16 + 0:
+     case OR16 + 1:
+     case OR16 + 2:
+     case OR16 + 3:
+-        gen_logic(env, OPC_OR, rd, rd, rs);
++        gen_logic(env, ctx, OPC_OR, rd, rd, rs);
+         break;
+     case LWM16 + 0:
+     case LWM16 + 1:
+@@ -10743,7 +10745,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
+             case XOR32:
+                 mips32_op = OPC_XOR;
+             do_logic:
+-                gen_logic(env, mips32_op, rd, rs, rt);
++                gen_logic(env, ctx, mips32_op, rd, rs, rt);
+                 break;
+                 /* Set less than */
+             case SLT:
+@@ -10752,7 +10754,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
+             case SLTU:
+                 mips32_op = OPC_SLTU;
+             do_slt:
+-                gen_slt(env, mips32_op, rd, rs, rt);
++                gen_slt(env, ctx, mips32_op, rd, rs, rt);
+                 break;
+             default:
+                 goto pool32a_invalid;
+@@ -10768,7 +10770,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
+             case MOVZ:
+                 mips32_op = OPC_MOVZ;
+             do_cmov:
+-                gen_cond_move(env, mips32_op, rd, rs, rt);
++                gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
+                 break;
+             case LWXS:
+                 gen_ldxs(ctx, rs, rt, rd);
+@@ -11181,7 +11183,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
+                target. */
+             break;
+         case LUI:
+-            gen_logic_imm(env, OPC_LUI, rs, -1, imm);
++            gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
+             break;
+         case SYNCI:
+             break;
+@@ -11300,7 +11302,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
+     case ANDI32:
+         mips32_op = OPC_ANDI;
+     do_logici:
+-        gen_logic_imm(env, mips32_op, rt, rs, imm);
++        gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
+         break;
+ 
+         /* Set less than immediate */
+@@ -11310,7 +11312,7 @@ static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
+     case SLTIU32:
+         mips32_op = OPC_SLTIU;
+     do_slti:
+-        gen_slt_imm(env, mips32_op, rt, rs, imm);
++        gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
+         break;
+     case JALX32:
+         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
+@@ -11787,7 +11789,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
+         case OPC_MOVZ:
+             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
+                                  INSN_LOONGSON2E | INSN_LOONGSON2F);
+-            gen_cond_move(env, op1, rd, rs, rt);
++            gen_cond_move(env, ctx, op1, rd, rs, rt);
+             break;
+         case OPC_ADD ... OPC_SUBU:
+             gen_arith(env, ctx, op1, rd, rs, rt);
+@@ -11814,13 +11816,13 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
+             break;
+         case OPC_SLT:          /* Set on less than */
+         case OPC_SLTU:
+-            gen_slt(env, op1, rd, rs, rt);
++            gen_slt(env, ctx, op1, rd, rs, rt);
+             break;
+         case OPC_AND:          /* Logic*/
+         case OPC_OR:
+         case OPC_NOR:
+         case OPC_XOR:
+-            gen_logic(env, op1, rd, rs, rt);
++            gen_logic(env, ctx, op1, rd, rs, rt);
+             break;
+         case OPC_MULT ... OPC_DIVU:
+             if (sa) {
+@@ -12221,13 +12223,13 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
+          break;
+     case OPC_SLTI: /* Set on less than with immediate opcode */
+     case OPC_SLTIU:
+-         gen_slt_imm(env, op, rt, rs, imm);
++         gen_slt_imm(env, ctx, op, rt, rs, imm);
+          break;
+     case OPC_ANDI: /* Arithmetic with immediate opcode */
+     case OPC_LUI:
+     case OPC_ORI:
+     case OPC_XORI:
+-         gen_logic_imm(env, op, rt, rs, imm);
++         gen_logic_imm(env, ctx, op, rt, rs, imm);
+          break;
+     case OPC_J ... OPC_JAL: /* Jump */
+          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
+-- 
+1.7.12.1
+
diff --git a/0045-target-mips-Always-evaluate-debugging-macro-argument.patch b/0045-target-mips-Always-evaluate-debugging-macro-argument.patch
new file mode 100644
index 0000000..e424bcf
--- /dev/null
+++ b/0045-target-mips-Always-evaluate-debugging-macro-argument.patch
@@ -0,0 +1,70 @@
+From e6f923b4e3e71661343f6d2eecd7f102022e5635 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Tue, 18 Sep 2012 21:55:34 -0700
+Subject: [PATCH] target-mips: Always evaluate debugging macro arguments
+
+this will prevent some of the compilation errors with debugging
+enabled from creeping back in.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-mips/translate.c | 31 +++++++++++++++++--------------
+ 1 file changed, 17 insertions(+), 14 deletions(-)
+
+diff --git a/target-mips/translate.c b/target-mips/translate.c
+index 4937f6b..aba7935 100644
+--- a/target-mips/translate.c
++++ b/target-mips/translate.c
+@@ -28,7 +28,7 @@
+ #define GEN_HELPER 1
+ #include "helper.h"
+ 
+-//#define MIPS_DEBUG_DISAS
++#define MIPS_DEBUG_DISAS 0
+ //#define MIPS_DEBUG_SIGN_EXTENSIONS
+ 
+ /* MIPS major opcodes */
+@@ -566,22 +566,25 @@ static const char *fregnames[] =
+       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
+ 
+-#ifdef MIPS_DEBUG_DISAS
+-#define MIPS_DEBUG(fmt, ...)                         \
+-        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
+-                       TARGET_FMT_lx ": %08x " fmt "\n", \
+-                       ctx->pc, ctx->opcode , ## __VA_ARGS__)
+-#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
+-#else
+-#define MIPS_DEBUG(fmt, ...) do { } while(0)
+-#define LOG_DISAS(...) do { } while (0)
+-#endif
++#define MIPS_DEBUG(fmt, ...)                                                  \
++    do {                                                                      \
++        if (MIPS_DEBUG_DISAS) {                                               \
++            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
++                          TARGET_FMT_lx ": %08x " fmt "\n",                   \
++                          ctx->pc, ctx->opcode , ## __VA_ARGS__);             \
++        }                                                                     \
++    } while (0)
++
++#define LOG_DISAS(...)                                                        \
++    do {                                                                      \
++        if (MIPS_DEBUG_DISAS) {                                               \
++            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
++        }                                                                     \
++    } while (0)
+ 
+ #define MIPS_INVAL(op)                                                        \
+-do {                                                                          \
+     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
+-               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
+-} while (0)
++               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
+ 
+ /* General purpose registers moves. */
+ static inline void gen_load_gpr (TCGv t, int reg)
+-- 
+1.7.12.1
+
diff --git a/0046-tcg-optimize-fix-end-of-basic-block-detection.patch b/0046-tcg-optimize-fix-end-of-basic-block-detection.patch
new file mode 100644
index 0000000..c498962
--- /dev/null
+++ b/0046-tcg-optimize-fix-end-of-basic-block-detection.patch
@@ -0,0 +1,62 @@
+From 4ce7a1e0aaecb220016af9b4f390b76f7fffcce8 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Wed, 19 Sep 2012 21:40:30 +0200
+Subject: [PATCH] tcg/optimize: fix end of basic block detection
+
+Commit e31b0a7c050711884ad570fe73df806520953618 fixed copy propagation on
+32-bit host by restricting the copy between different types. This was the
+wrong fix.
+
+The real problem is that the all temps states should be reset at the end
+of a basic block. This was done by adding such operations in the switch,
+but brcond2 was forgotten (that's why the crash was only observed on 32-bit
+hosts).
+
+Fix that by looking at the TCG_OPF_BB_END instead. We need to keep the case
+for op_set_label as temps might be modified through another path.
+
+Cc: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 22 +++++++++-------------
+ 1 file changed, 9 insertions(+), 13 deletions(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 10d9773..9da333c 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -632,21 +632,17 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 i--;
+             }
+             break;
+-        case INDEX_op_set_label:
+-        case INDEX_op_jmp:
+-        case INDEX_op_br:
+-            memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+-            for (i = 0; i < def->nb_args; i++) {
+-                *gen_args = *args;
+-                args++;
+-                gen_args++;
+-            }
+-            break;
+         default:
+             /* Default case: we do know nothing about operation so no
+-               propagation is done.  We only trash output args.  */
+-            for (i = 0; i < def->nb_oargs; i++) {
+-                reset_temp(args[i], nb_temps, nb_globals);
++               propagation is done.  We trash everything if the operation
++               is the end of a basic block, otherwise we only trash the
++               output args.  */
++            if (def->flags & TCG_OPF_BB_END) {
++                memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
++            } else {
++                for (i = 0; i < def->nb_oargs; i++) {
++                    reset_temp(args[i], nb_temps, nb_globals);
++                }
+             }
+             for (i = 0; i < def->nb_args; i++) {
+                 gen_args[i] = args[i];
+-- 
+1.7.12.1
+
diff --git a/0047-target-xtensa-fix-extui-shift-amount.patch b/0047-target-xtensa-fix-extui-shift-amount.patch
new file mode 100644
index 0000000..c654322
--- /dev/null
+++ b/0047-target-xtensa-fix-extui-shift-amount.patch
@@ -0,0 +1,57 @@
+From 1c596a9498830485a1b2f4a4445643a149179b99 Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc at gmail.com>
+Date: Fri, 21 Sep 2012 02:59:49 +0400
+Subject: [PATCH] target-xtensa: fix extui shift amount
+
+extui opcode only uses lowermost op1 bit for sa4.
+
+Reported-by: malc <av1474 at comtv.ru>
+Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
+Cc: qemu-stable <qemu-stable at nongnu.org>
+Signed-off-by: malc <av1474 at comtv.ru>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-xtensa/translate.c | 24 +++++++++++++++++++++---
+ 1 file changed, 21 insertions(+), 3 deletions(-)
+
+diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
+index 1900bd5..7a1c528 100644
+--- a/target-xtensa/translate.c
++++ b/target-xtensa/translate.c
+@@ -1778,12 +1778,30 @@ static void disas_xtensa_insn(DisasContext *dc)
+         case 5:
+             gen_window_check2(dc, RRR_R, RRR_T);
+             {
+-                int shiftimm = RRR_S | (OP1 << 4);
++                int shiftimm = RRR_S | ((OP1 & 1) << 4);
+                 int maskimm = (1 << (OP2 + 1)) - 1;
+ 
+                 TCGv_i32 tmp = tcg_temp_new_i32();
+-                tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
+-                tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
++
++                if (shiftimm) {
++                    tcg_gen_shri_i32(tmp, cpu_R[RRR_T], shiftimm);
++                } else {
++                    tcg_gen_mov_i32(tmp, cpu_R[RRR_T]);
++                }
++
++                switch (maskimm) {
++                case 0xff:
++                    tcg_gen_ext8u_i32(cpu_R[RRR_R], tmp);
++                    break;
++
++                case 0xffff:
++                    tcg_gen_ext16u_i32(cpu_R[RRR_R], tmp);
++                    break;
++
++                default:
++                    tcg_gen_andi_i32(cpu_R[RRR_R], tmp, maskimm);
++                    break;
++                }
+                 tcg_temp_free(tmp);
+             }
+             break;
+-- 
+1.7.12.1
+
diff --git a/0048-target-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch b/0048-target-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch
new file mode 100644
index 0000000..2e8e219
--- /dev/null
+++ b/0048-target-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch
@@ -0,0 +1,35 @@
+From ba9c2acb955f0453ae80077a791a4d1c27b5d6e6 Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc at gmail.com>
+Date: Fri, 21 Sep 2012 02:59:50 +0400
+Subject: [PATCH] target-xtensa: don't emit extra tcg_gen_goto_tb
+
+Unconditional gen_check_loop_end at the end of disas_xtensa_insn
+can emit tcg_gen_goto_tb with slot id already used in the TB (e.g. when
+TB ends at LEND with a branch).
+
+Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
+Cc: qemu-stable <qemu-stable at nongnu.org>
+Signed-off-by: malc <av1474 at comtv.ru>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-xtensa/translate.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
+index 7a1c528..b6643eb 100644
+--- a/target-xtensa/translate.c
++++ b/target-xtensa/translate.c
+@@ -2520,7 +2520,9 @@ static void disas_xtensa_insn(DisasContext *dc)
+         break;
+     }
+ 
+-    gen_check_loop_end(dc, 0);
++    if (dc->is_jmp == DISAS_NEXT) {
++        gen_check_loop_end(dc, 0);
++    }
+     dc->pc = dc->next_pc;
+ 
+     return;
+-- 
+1.7.12.1
+
diff --git a/0049-tcg-Introduce-movcond.patch b/0049-tcg-Introduce-movcond.patch
new file mode 100644
index 0000000..3ead932
--- /dev/null
+++ b/0049-tcg-Introduce-movcond.patch
@@ -0,0 +1,333 @@
+From a977d2c7f02eb2ed7fc879979d6f5525c017a881 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 10:13:34 -0700
+Subject: [PATCH] tcg: Introduce movcond
+
+Implemented with setcond if the target does not provide
+the optional opcode.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/README             |  6 ++++++
+ tcg/arm/tcg-target.h   |  1 +
+ tcg/hppa/tcg-target.h  |  1 +
+ tcg/i386/tcg-target.h  |  2 ++
+ tcg/ia64/tcg-target.h  |  2 ++
+ tcg/mips/tcg-target.h  |  1 +
+ tcg/ppc/tcg-target.h   |  1 +
+ tcg/ppc64/tcg-target.h |  2 ++
+ tcg/s390/tcg-target.h  |  2 ++
+ tcg/sparc/tcg-target.h |  2 ++
+ tcg/tcg-op.h           | 40 ++++++++++++++++++++++++++++++++++++++++
+ tcg/tcg-opc.h          |  2 ++
+ tcg/tcg.c              | 11 +++++------
+ tcg/tcg.h              |  1 +
+ tcg/tci/tcg-target.h   |  2 ++
+ 15 files changed, 70 insertions(+), 6 deletions(-)
+
+diff --git a/tcg/README b/tcg/README
+index cfdfd96..d03ae05 100644
+--- a/tcg/README
++++ b/tcg/README
+@@ -307,6 +307,12 @@ dest = (t1 cond t2)
+ 
+ Set DEST to 1 if (T1 cond T2) is true, otherwise set to 0.
+ 
++* movcond_i32/i64 cond, dest, c1, c2, v1, v2
++
++dest = (c1 cond c2 ? v1 : v2)
++
++Set DEST to V1 if (C1 cond C2) is true, otherwise set to V2.
++
+ ********* Type conversions
+ 
+ * ext_i32_i64 t0, t1
+diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
+index c0b8f72..e2299ca 100644
+--- a/tcg/arm/tcg-target.h
++++ b/tcg/arm/tcg-target.h
+@@ -73,6 +73,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_GUEST_BASE
+ 
+diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
+index 01ef960..4defd28 100644
+--- a/tcg/hppa/tcg-target.h
++++ b/tcg/hppa/tcg-target.h
+@@ -96,6 +96,7 @@ typedef enum {
+ #define TCG_TARGET_HAS_nand_i32         0
+ #define TCG_TARGET_HAS_nor_i32          0
+ #define TCG_TARGET_HAS_deposit_i32      1
++#define TCG_TARGET_HAS_movcond_i32      0
+ 
+ /* optional instructions automatically implemented */
+ #define TCG_TARGET_HAS_neg_i32          0 /* sub rd, 0, rs */
+diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
+index 8be42f3..504f953 100644
+--- a/tcg/i386/tcg-target.h
++++ b/tcg/i386/tcg-target.h
+@@ -86,6 +86,7 @@ typedef enum {
+ #define TCG_TARGET_HAS_nand_i32         0
+ #define TCG_TARGET_HAS_nor_i32          0
+ #define TCG_TARGET_HAS_deposit_i32      1
++#define TCG_TARGET_HAS_movcond_i32      0
+ 
+ #if TCG_TARGET_REG_BITS == 64
+ #define TCG_TARGET_HAS_div2_i64         1
+@@ -107,6 +108,7 @@ typedef enum {
+ #define TCG_TARGET_HAS_nand_i64         0
+ #define TCG_TARGET_HAS_nor_i64          0
+ #define TCG_TARGET_HAS_deposit_i64      1
++#define TCG_TARGET_HAS_movcond_i64      0
+ #endif
+ 
+ #define TCG_TARGET_deposit_i32_valid(ofs, len) \
+diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
+index c22962a..368aee4 100644
+--- a/tcg/ia64/tcg-target.h
++++ b/tcg/ia64/tcg-target.h
+@@ -133,6 +133,8 @@ typedef enum {
+ #define TCG_TARGET_HAS_rot_i64          1
+ #define TCG_TARGET_HAS_deposit_i32      0
+ #define TCG_TARGET_HAS_deposit_i64      0
++#define TCG_TARGET_HAS_movcond_i32      0
++#define TCG_TARGET_HAS_movcond_i64      0
+ 
+ /* optional instructions automatically implemented */
+ #define TCG_TARGET_HAS_neg_i32          0 /* sub r1, r0, r3 */
+diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
+index 1c61931..9c68a32 100644
+--- a/tcg/mips/tcg-target.h
++++ b/tcg/mips/tcg-target.h
+@@ -90,6 +90,7 @@ typedef enum {
+ #define TCG_TARGET_HAS_eqv_i32          0
+ #define TCG_TARGET_HAS_nand_i32         0
+ #define TCG_TARGET_HAS_deposit_i32      0
++#define TCG_TARGET_HAS_movcond_i32      0
+ 
+ /* optional instructions automatically implemented */
+ #define TCG_TARGET_HAS_neg_i32          0 /* sub  rd, zero, rt   */
+diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
+index 2f37fd2..177eea1 100644
+--- a/tcg/ppc/tcg-target.h
++++ b/tcg/ppc/tcg-target.h
+@@ -92,6 +92,7 @@ typedef enum {
+ #define TCG_TARGET_HAS_nand_i32         1
+ #define TCG_TARGET_HAS_nor_i32          1
+ #define TCG_TARGET_HAS_deposit_i32      1
++#define TCG_TARGET_HAS_movcond_i32      0
+ 
+ #define TCG_AREG0 TCG_REG_R27
+ 
+diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
+index 97eec08..57569e8 100644
+--- a/tcg/ppc64/tcg-target.h
++++ b/tcg/ppc64/tcg-target.h
+@@ -83,6 +83,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_div_i64          1
+ #define TCG_TARGET_HAS_rot_i64          0
+@@ -103,6 +104,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_AREG0 TCG_REG_R27
+ 
+diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
+index 4f7dfab..ed55c33 100644
+--- a/tcg/s390/tcg-target.h
++++ b/tcg/s390/tcg-target.h
+@@ -63,6 +63,7 @@ typedef enum TCGReg {
+ #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
+ 
+ #if TCG_TARGET_REG_BITS == 64
+ #define TCG_TARGET_HAS_div2_i64         1
+@@ -84,6 +85,7 @@ typedef enum TCGReg {
+ #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
+ #endif
+ 
+ #define TCG_TARGET_HAS_GUEST_BASE
+diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
+index 0ea87be..d762574 100644
+--- a/tcg/sparc/tcg-target.h
++++ b/tcg/sparc/tcg-target.h
+@@ -102,6 +102,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
+ 
+ #if TCG_TARGET_REG_BITS == 64
+ #define TCG_TARGET_HAS_div_i64          1
+@@ -123,6 +124,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
+ #endif
+ 
+ #ifdef CONFIG_SOLARIS
+diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
+index 169d3b2..6d28f82 100644
+--- a/tcg/tcg-op.h
++++ b/tcg/tcg-op.h
+@@ -2118,6 +2118,44 @@ static inline void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1,
+     tcg_temp_free_i64(t1);
+ }
+ 
++static inline void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret,
++                                       TCGv_i32 c1, TCGv_i32 c2,
++                                       TCGv_i32 v1, TCGv_i32 v2)
++{
++    if (TCG_TARGET_HAS_movcond_i32) {
++        tcg_gen_op6i_i32(INDEX_op_movcond_i32, ret, c1, c2, v1, v2, cond);
++    } else {
++        TCGv_i32 t0 = tcg_temp_new_i32();
++        TCGv_i32 t1 = tcg_temp_new_i32();
++        tcg_gen_setcond_i32(cond, t0, c1, c2);
++        tcg_gen_neg_i32(t0, t0);
++        tcg_gen_and_i32(t1, v1, t0);
++        tcg_gen_andc_i32(ret, v2, t0);
++        tcg_gen_or_i32(ret, ret, t1);
++        tcg_temp_free_i32(t0);
++        tcg_temp_free_i32(t1);
++    }
++}
++
++static inline void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret,
++                                       TCGv_i64 c1, TCGv_i64 c2,
++                                       TCGv_i64 v1, TCGv_i64 v2)
++{
++    if (TCG_TARGET_HAS_movcond_i64) {
++        tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
++    } else {
++        TCGv_i64 t0 = tcg_temp_new_i64();
++        TCGv_i64 t1 = tcg_temp_new_i64();
++        tcg_gen_setcond_i64(cond, t0, c1, c2);
++        tcg_gen_neg_i64(t0, t0);
++        tcg_gen_and_i64(t1, v1, t0);
++        tcg_gen_andc_i64(ret, v2, t0);
++        tcg_gen_or_i64(ret, ret, t1);
++        tcg_temp_free_i64(t0);
++        tcg_temp_free_i64(t1);
++    }
++}
++
+ /***************************************/
+ /* QEMU specific operations. Their type depend on the QEMU CPU
+    type. */
+@@ -2434,6 +2472,7 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
+ #define tcg_gen_deposit_tl tcg_gen_deposit_i64
+ #define tcg_const_tl tcg_const_i64
+ #define tcg_const_local_tl tcg_const_local_i64
++#define tcg_gen_movcond_tl tcg_gen_movcond_i64
+ #else
+ #define tcg_gen_movi_tl tcg_gen_movi_i32
+ #define tcg_gen_mov_tl tcg_gen_mov_i32
+@@ -2505,6 +2544,7 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index)
+ #define tcg_gen_deposit_tl tcg_gen_deposit_i32
+ #define tcg_const_tl tcg_const_i32
+ #define tcg_const_local_tl tcg_const_local_i32
++#define tcg_gen_movcond_tl tcg_gen_movcond_i32
+ #endif
+ 
+ #if TCG_TARGET_REG_BITS == 32
+diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
+index d12e8d0..dbb0e39 100644
+--- a/tcg/tcg-opc.h
++++ b/tcg/tcg-opc.h
+@@ -51,6 +51,7 @@ DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+ DEF(mov_i32, 1, 1, 0, 0)
+ DEF(movi_i32, 1, 0, 1, 0)
+ DEF(setcond_i32, 1, 2, 1, 0)
++DEF(movcond_i32, 1, 4, 1, IMPL(TCG_TARGET_HAS_movcond_i32))
+ /* load/store */
+ DEF(ld8u_i32, 1, 1, 1, 0)
+ DEF(ld8s_i32, 1, 1, 1, 0)
+@@ -107,6 +108,7 @@ DEF(nor_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nor_i32))
+ DEF(mov_i64, 1, 1, 0, IMPL64)
+ DEF(movi_i64, 1, 0, 1, IMPL64)
+ DEF(setcond_i64, 1, 2, 1, IMPL64)
++DEF(movcond_i64, 1, 4, 1, IMPL64 | IMPL(TCG_TARGET_HAS_movcond_i64))
+ /* load/store */
+ DEF(ld8u_i64, 1, 1, 1, IMPL64)
+ DEF(ld8s_i64, 1, 1, 1, IMPL64)
+diff --git a/tcg/tcg.c b/tcg/tcg.c
+index c002a88..24ce830 100644
+--- a/tcg/tcg.c
++++ b/tcg/tcg.c
+@@ -991,16 +991,15 @@ void tcg_dump_ops(TCGContext *s)
+             }
+             switch (c) {
+             case INDEX_op_brcond_i32:
+-#if TCG_TARGET_REG_BITS == 32
+-            case INDEX_op_brcond2_i32:
+-#elif TCG_TARGET_REG_BITS == 64
+-            case INDEX_op_brcond_i64:
+-#endif
+             case INDEX_op_setcond_i32:
++            case INDEX_op_movcond_i32:
+ #if TCG_TARGET_REG_BITS == 32
++            case INDEX_op_brcond2_i32:
+             case INDEX_op_setcond2_i32:
+-#elif TCG_TARGET_REG_BITS == 64
++#else
++            case INDEX_op_brcond_i64:
+             case INDEX_op_setcond_i64:
++            case INDEX_op_movcond_i64:
+ #endif
+                 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
+                     qemu_log(",%s", cond_name[args[k++]]);
+diff --git a/tcg/tcg.h b/tcg/tcg.h
+index 8fbbc81..f454107 100644
+--- a/tcg/tcg.h
++++ b/tcg/tcg.h
+@@ -79,6 +79,7 @@ typedef uint64_t TCGRegSet;
+ #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
+ #endif
+ 
+ #ifndef TCG_TARGET_deposit_i32_valid
+diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
+index 30a0f21..6d89495 100644
+--- a/tcg/tci/tcg-target.h
++++ b/tcg/tci/tcg-target.h
+@@ -75,6 +75,7 @@
+ #define TCG_TARGET_HAS_not_i32          1
+ #define TCG_TARGET_HAS_orc_i32          0
+ #define TCG_TARGET_HAS_rot_i32          1
++#define TCG_TARGET_HAS_movcond_i32      0
+ 
+ #if TCG_TARGET_REG_BITS == 64
+ #define TCG_TARGET_HAS_bswap16_i64      1
+@@ -98,6 +99,7 @@
+ #define TCG_TARGET_HAS_not_i64          1
+ #define TCG_TARGET_HAS_orc_i64          0
+ #define TCG_TARGET_HAS_rot_i64          1
++#define TCG_TARGET_HAS_movcond_i64      0
+ #endif /* TCG_TARGET_REG_BITS == 64 */
+ 
+ /* Offset to user memory in user mode. */
+-- 
+1.7.12.1
+
diff --git a/0050-target-alpha-Use-movcond.patch b/0050-target-alpha-Use-movcond.patch
new file mode 100644
index 0000000..0bd5272
--- /dev/null
+++ b/0050-target-alpha-Use-movcond.patch
@@ -0,0 +1,160 @@
+From 4bf321d3f494134fe2e03c9cbc042e28ec3a1045 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 10:13:35 -0700
+Subject: [PATCH] target-alpha: Use movcond
+
+For proper cmov insns, as well as the non-goto-tb case
+of conditional branch.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-alpha/translate.c | 102 ++++++++++++++++++++++-------------------------
+ 1 file changed, 48 insertions(+), 54 deletions(-)
+
+diff --git a/target-alpha/translate.c b/target-alpha/translate.c
+index 12de6a3..4a9011a 100644
+--- a/target-alpha/translate.c
++++ b/target-alpha/translate.c
+@@ -426,27 +426,15 @@ static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
+ 
+         return EXIT_GOTO_TB;
+     } else {
+-        int lab_over = gen_new_label();
+-
+-        /* ??? Consider using either
+-             movi pc, next
+-             addi tmp, pc, disp
+-             movcond pc, cond, 0, tmp, pc
+-           or
+-             setcond tmp, cond, 0
+-             movi pc, next
+-             neg tmp, tmp
+-             andi tmp, tmp, disp
+-             add pc, pc, tmp
+-           The current diamond subgraph surely isn't efficient.  */
++        TCGv_i64 z = tcg_const_i64(0);
++        TCGv_i64 d = tcg_const_i64(dest);
++        TCGv_i64 p = tcg_const_i64(ctx->pc);
+ 
+-        tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
+-        tcg_gen_movi_i64(cpu_pc, ctx->pc);
+-        tcg_gen_br(lab_over);
+-        gen_set_label(lab_true);
+-        tcg_gen_movi_i64(cpu_pc, dest);
+-        gen_set_label(lab_over);
++        tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
+ 
++        tcg_temp_free_i64(z);
++        tcg_temp_free_i64(d);
++        tcg_temp_free_i64(p);
+         return EXIT_PC_UPDATED;
+     }
+ }
+@@ -521,61 +509,67 @@ static ExitStatus gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
+ static void gen_cmov(TCGCond cond, int ra, int rb, int rc,
+                      int islit, uint8_t lit, int mask)
+ {
+-    TCGCond inv_cond = tcg_invert_cond(cond);
+-    int l1;
++    TCGv_i64 c1, z, v1;
+ 
+-    if (unlikely(rc == 31))
++    if (unlikely(rc == 31)) {
+         return;
++    }
+ 
+-    l1 = gen_new_label();
+-
+-    if (ra != 31) {
+-        if (mask) {
+-            TCGv tmp = tcg_temp_new();
+-            tcg_gen_andi_i64(tmp, cpu_ir[ra], 1);
+-            tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
+-            tcg_temp_free(tmp);
+-        } else
+-            tcg_gen_brcondi_i64(inv_cond, cpu_ir[ra], 0, l1);
+-    } else {
++    if (ra == 31) {
+         /* Very uncommon case - Do not bother to optimize.  */
+-        TCGv tmp = tcg_const_i64(0);
+-        tcg_gen_brcondi_i64(inv_cond, tmp, 0, l1);
+-        tcg_temp_free(tmp);
++        c1 = tcg_const_i64(0);
++    } else if (mask) {
++        c1 = tcg_const_i64(1);
++        tcg_gen_and_i64(c1, c1, cpu_ir[ra]);
++    } else {
++        c1 = cpu_ir[ra];
+     }
++    if (islit) {
++        v1 = tcg_const_i64(lit);
++    } else {
++        v1 = cpu_ir[rb];
++    }
++    z = tcg_const_i64(0);
+ 
+-    if (islit)
+-        tcg_gen_movi_i64(cpu_ir[rc], lit);
+-    else
+-        tcg_gen_mov_i64(cpu_ir[rc], cpu_ir[rb]);
+-    gen_set_label(l1);
++    tcg_gen_movcond_i64(cond, cpu_ir[rc], c1, z, v1, cpu_ir[rc]);
++
++    tcg_temp_free_i64(z);
++    if (ra == 31 || mask) {
++        tcg_temp_free_i64(c1);
++    }
++    if (islit) {
++        tcg_temp_free_i64(v1);
++    }
+ }
+ 
+ static void gen_fcmov(TCGCond cond, int ra, int rb, int rc)
+ {
+-    TCGv cmp_tmp;
+-    int l1;
++    TCGv_i64 c1, z, v1;
+ 
+     if (unlikely(rc == 31)) {
+         return;
+     }
+ 
+-    cmp_tmp = tcg_temp_new();
++    c1 = tcg_temp_new_i64();
+     if (unlikely(ra == 31)) {
+-        tcg_gen_movi_i64(cmp_tmp, 0);
++        tcg_gen_movi_i64(c1, 0);
++    } else {
++        gen_fold_mzero(cond, c1, cpu_fir[ra]);
++    }
++    if (rb == 31) {
++        v1 = tcg_const_i64(0);
+     } else {
+-        gen_fold_mzero(cond, cmp_tmp, cpu_fir[ra]);
++        v1 = cpu_fir[rb];
+     }
++    z = tcg_const_i64(0);
+ 
+-    l1 = gen_new_label();
+-    tcg_gen_brcondi_i64(tcg_invert_cond(cond), cmp_tmp, 0, l1);
+-    tcg_temp_free(cmp_tmp);
++    tcg_gen_movcond_i64(cond, cpu_fir[rc], c1, z, v1, cpu_fir[rc]);
+ 
+-    if (rb != 31)
+-        tcg_gen_mov_i64(cpu_fir[rc], cpu_fir[rb]);
+-    else
+-        tcg_gen_movi_i64(cpu_fir[rc], 0);
+-    gen_set_label(l1);
++    tcg_temp_free_i64(z);
++    tcg_temp_free_i64(c1);
++    if (rb == 31) {
++        tcg_temp_free_i64(v1);
++    }
+ }
+ 
+ #define QUAL_RM_N       0x080   /* Round mode nearest even */
+-- 
+1.7.12.1
+
diff --git a/0051-tcg-i386-Implement-movcond.patch b/0051-tcg-i386-Implement-movcond.patch
new file mode 100644
index 0000000..4d3983f
--- /dev/null
+++ b/0051-tcg-i386-Implement-movcond.patch
@@ -0,0 +1,118 @@
+From 7a6273e2995b6c439441316467ab19bd6a48f03f Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 10:13:36 -0700
+Subject: [PATCH] tcg-i386: Implement movcond
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/i386/tcg-target.c | 29 +++++++++++++++++++++++++++++
+ tcg/i386/tcg-target.h |  7 ++++++-
+ 2 files changed, 35 insertions(+), 1 deletion(-)
+
+diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
+index 3017858..aa1fa9f 100644
+--- a/tcg/i386/tcg-target.c
++++ b/tcg/i386/tcg-target.c
+@@ -249,6 +249,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
+ #define OPC_ADD_GvEv	(OPC_ARITH_GvEv | (ARITH_ADD << 3))
+ #define OPC_BSWAP	(0xc8 | P_EXT)
+ #define OPC_CALL_Jz	(0xe8)
++#define OPC_CMOVCC      (0x40 | P_EXT)  /* ... plus condition code */
+ #define OPC_CMP_GvEv	(OPC_ARITH_GvEv | (ARITH_CMP << 3))
+ #define OPC_DEC_r32	(0x48)
+ #define OPC_IMUL_GvEv	(0xaf | P_EXT)
+@@ -936,6 +937,24 @@ static void tcg_out_setcond2(TCGContext *s, const TCGArg *args,
+ }
+ #endif
+ 
++static void tcg_out_movcond32(TCGContext *s, TCGCond cond, TCGArg dest,
++                              TCGArg c1, TCGArg c2, int const_c2,
++                              TCGArg v1)
++{
++    tcg_out_cmp(s, c1, c2, const_c2, 0);
++    tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond], dest, v1);
++}
++
++#if TCG_TARGET_REG_BITS == 64
++static void tcg_out_movcond64(TCGContext *s, TCGCond cond, TCGArg dest,
++                              TCGArg c1, TCGArg c2, int const_c2,
++                              TCGArg v1)
++{
++    tcg_out_cmp(s, c1, c2, const_c2, P_REXW);
++    tcg_out_modrm(s, OPC_CMOVCC | tcg_cond_to_jcc[cond] | P_REXW, dest, v1);
++}
++#endif
++
+ static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest)
+ {
+     tcg_target_long disp = dest - (tcg_target_long)s->code_ptr - 5;
+@@ -1668,6 +1687,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
+         tcg_out_setcond32(s, args[3], args[0], args[1],
+                           args[2], const_args[2]);
+         break;
++    case INDEX_op_movcond_i32:
++        tcg_out_movcond32(s, args[5], args[0], args[1],
++                          args[2], const_args[2], args[3]);
++        break;
+ 
+     OP_32_64(bswap16):
+         tcg_out_rolw_8(s, args[0]);
+@@ -1796,6 +1819,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
+         tcg_out_setcond64(s, args[3], args[0], args[1],
+                           args[2], const_args[2]);
+         break;
++    case INDEX_op_movcond_i64:
++        tcg_out_movcond64(s, args[5], args[0], args[1],
++                          args[2], const_args[2], args[3]);
++        break;
+ 
+     case INDEX_op_bswap64_i64:
+         tcg_out_bswap64(s, args[0]);
+@@ -1880,6 +1907,7 @@ static const TCGTargetOpDef x86_op_defs[] = {
+     { INDEX_op_setcond_i32, { "q", "r", "ri" } },
+ 
+     { INDEX_op_deposit_i32, { "Q", "0", "Q" } },
++    { INDEX_op_movcond_i32, { "r", "r", "ri", "r", "0" } },
+ 
+ #if TCG_TARGET_REG_BITS == 32
+     { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
+@@ -1934,6 +1962,7 @@ static const TCGTargetOpDef x86_op_defs[] = {
+     { INDEX_op_ext32u_i64, { "r", "r" } },
+ 
+     { INDEX_op_deposit_i64, { "Q", "0", "Q" } },
++    { INDEX_op_movcond_i64, { "r", "r", "re", "r", "0" } },
+ #endif
+ 
+ #if TCG_TARGET_REG_BITS == 64
+diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
+index 504f953..b356d76 100644
+--- a/tcg/i386/tcg-target.h
++++ b/tcg/i386/tcg-target.h
+@@ -86,7 +86,12 @@ typedef enum {
+ #define TCG_TARGET_HAS_nand_i32         0
+ #define TCG_TARGET_HAS_nor_i32          0
+ #define TCG_TARGET_HAS_deposit_i32      1
++#if defined(__x86_64__) || defined(__i686__)
++/* Use cmov only if the compiler is already doing so.  */
++#define TCG_TARGET_HAS_movcond_i32      1
++#else
+ #define TCG_TARGET_HAS_movcond_i32      0
++#endif
+ 
+ #if TCG_TARGET_REG_BITS == 64
+ #define TCG_TARGET_HAS_div2_i64         1
+@@ -108,7 +113,7 @@ typedef enum {
+ #define TCG_TARGET_HAS_nand_i64         0
+ #define TCG_TARGET_HAS_nor_i64          0
+ #define TCG_TARGET_HAS_deposit_i64      1
+-#define TCG_TARGET_HAS_movcond_i64      0
++#define TCG_TARGET_HAS_movcond_i64      1
+ #endif
+ 
+ #define TCG_TARGET_deposit_i32_valid(ofs, len) \
+-- 
+1.7.12.1
+
diff --git a/0052-tcg-Optimize-movcond-for-constant-comparisons.patch b/0052-tcg-Optimize-movcond-for-constant-comparisons.patch
new file mode 100644
index 0000000..ce0f00b
--- /dev/null
+++ b/0052-tcg-Optimize-movcond-for-constant-comparisons.patch
@@ -0,0 +1,73 @@
+From c489b380d3f827be91b5f8b80b88585fb4014fbb Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 10:13:37 -0700
+Subject: [PATCH] tcg: Optimize movcond for constant comparisons
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 40 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 9da333c..26038a6 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -394,6 +394,14 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 args[3] = tcg_swap_cond(args[3]);
+             }
+             break;
++        CASE_OP_32_64(movcond):
++            if (temps[args[1]].state == TCG_TEMP_CONST
++                && temps[args[2]].state != TCG_TEMP_CONST) {
++                tmp = args[1];
++                args[1] = args[2];
++                args[2] = tmp;
++                args[5] = tcg_swap_cond(args[5]);
++            }
+         default:
+             break;
+         }
+@@ -614,6 +622,38 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             }
+             args += 4;
+             break;
++        CASE_OP_32_64(movcond):
++            if (temps[args[1]].state == TCG_TEMP_CONST
++                && temps[args[2]].state == TCG_TEMP_CONST) {
++                tmp = do_constant_folding_cond(op, temps[args[1]].val,
++                                               temps[args[2]].val, args[5]);
++                if (args[0] == args[4-tmp]
++                    || (temps[args[4-tmp]].state == TCG_TEMP_COPY
++                        && temps[args[4-tmp]].val == args[0])) {
++                    gen_opc_buf[op_index] = INDEX_op_nop;
++                } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
++                    gen_opc_buf[op_index] = op_to_movi(op);
++                    tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val,
++                                     nb_temps, nb_globals);
++                    gen_args += 2;
++                } else {
++                    gen_opc_buf[op_index] = op_to_mov(op);
++                    tcg_opt_gen_mov(gen_args, args[0], args[4-tmp],
++                                    nb_temps, nb_globals);
++                    gen_args += 2;
++                }
++            } else {
++                reset_temp(args[0], nb_temps, nb_globals);
++                gen_args[0] = args[0];
++                gen_args[1] = args[1];
++                gen_args[2] = args[2];
++                gen_args[3] = args[3];
++                gen_args[4] = args[4];
++                gen_args[5] = args[5];
++                gen_args += 6;
++            }
++            args += 6;
++            break;
+         case INDEX_op_call:
+             nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
+             if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
+-- 
+1.7.12.1
+
diff --git a/0053-tcg-Optimize-two-address-commutative-operations.patch b/0053-tcg-Optimize-two-address-commutative-operations.patch
new file mode 100644
index 0000000..adacbb8
--- /dev/null
+++ b/0053-tcg-Optimize-two-address-commutative-operations.patch
@@ -0,0 +1,57 @@
+From af2bf6bcc6614622c87d28e9d763b57408c17500 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 10:13:38 -0700
+Subject: [PATCH] tcg: Optimize two-address commutative operations
+
+While swapping constants to the second operand, swap
+sources matching destinations to the first operand.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 26038a6..1be7631 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -334,6 +334,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+     const TCGOpDef *def;
+     TCGArg *gen_args;
+     TCGArg tmp;
++    TCGCond cond;
++
+     /* Array VALS has an element for each temp.
+        If this temp holds a constant then its value is kept in VALS' element.
+        If this temp is a copy of other ones then this equivalence class'
+@@ -395,13 +397,24 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             }
+             break;
+         CASE_OP_32_64(movcond):
++            cond = args[5];
+             if (temps[args[1]].state == TCG_TEMP_CONST
+                 && temps[args[2]].state != TCG_TEMP_CONST) {
+                 tmp = args[1];
+                 args[1] = args[2];
+                 args[2] = tmp;
+-                args[5] = tcg_swap_cond(args[5]);
++                cond = tcg_swap_cond(cond);
++            }
++            /* For movcond, we canonicalize the "false" input reg to match
++               the destination reg so that the tcg backend can implement
++               a "move if true" operation.  */
++            if (args[0] == args[3]) {
++                tmp = args[3];
++                args[3] = args[4];
++                args[4] = tmp;
++                cond = tcg_invert_cond(cond);
+             }
++            args[5] = cond;
+         default:
+             break;
+         }
+-- 
+1.7.12.1
+
diff --git a/0054-gdbstub-sh4-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch b/0054-gdbstub-sh4-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch
new file mode 100644
index 0000000..250f893
--- /dev/null
+++ b/0054-gdbstub-sh4-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch
@@ -0,0 +1,192 @@
+From b6407e30c30268cdeddec6e2b115f419647cc07f Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Sun, 16 Sep 2012 13:12:21 +0200
+Subject: [PATCH] gdbstub/sh4: fix build with USE_SOFTFLOAT_STRUCT_TYPES
+
+We have to use different type to access float values when
+USE_SOFTFLOAT_STRUCT_TYPES is defined.
+
+Rework SH4 version of cpu_gdb_{read,write}_register() using
+a single case, and fixing the coding style. Use ldll_p() and
+stfl_p() to access float values.
+
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ gdbstub.c | 144 +++++++++++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 90 insertions(+), 54 deletions(-)
+
+diff --git a/gdbstub.c b/gdbstub.c
+index 5d37dd9..a91709f 100644
+--- a/gdbstub.c
++++ b/gdbstub.c
+@@ -1226,33 +1226,48 @@ static int cpu_gdb_write_register(CPUOpenRISCState *env,
+ 
+ static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
+ {
+-    if (n < 8) {
++    switch (n) {
++    case 0 ... 7:
+         if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
+             GET_REGL(env->gregs[n + 16]);
+         } else {
+             GET_REGL(env->gregs[n]);
+         }
+-    } else if (n < 16) {
++    case 8 ... 15:
+         GET_REGL(env->gregs[n]);
+-    } else if (n >= 25 && n < 41) {
+-	GET_REGL(env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)]);
+-    } else if (n >= 43 && n < 51) {
+-	GET_REGL(env->gregs[n - 43]);
+-    } else if (n >= 51 && n < 59) {
+-	GET_REGL(env->gregs[n - (51 - 16)]);
+-    }
+-    switch (n) {
+-    case 16: GET_REGL(env->pc);
+-    case 17: GET_REGL(env->pr);
+-    case 18: GET_REGL(env->gbr);
+-    case 19: GET_REGL(env->vbr);
+-    case 20: GET_REGL(env->mach);
+-    case 21: GET_REGL(env->macl);
+-    case 22: GET_REGL(env->sr);
+-    case 23: GET_REGL(env->fpul);
+-    case 24: GET_REGL(env->fpscr);
+-    case 41: GET_REGL(env->ssr);
+-    case 42: GET_REGL(env->spc);
++    case 16:
++        GET_REGL(env->pc);
++    case 17:
++        GET_REGL(env->pr);
++    case 18:
++        GET_REGL(env->gbr);
++    case 19:
++        GET_REGL(env->vbr);
++    case 20:
++        GET_REGL(env->mach);
++    case 21:
++        GET_REGL(env->macl);
++    case 22:
++        GET_REGL(env->sr);
++    case 23:
++        GET_REGL(env->fpul);
++    case 24:
++        GET_REGL(env->fpscr);
++    case 25 ... 40:
++        if (env->fpscr & FPSCR_FR) {
++            stfl_p(mem_buf, env->fregs[n - 9]);
++        } else {
++            stfl_p(mem_buf, env->fregs[n - 25]);
++        }
++        return 4;
++    case 41:
++        GET_REGL(env->ssr);
++    case 42:
++        GET_REGL(env->spc);
++    case 43 ... 50:
++        GET_REGL(env->gregs[n - 43]);
++    case 51 ... 58:
++        GET_REGL(env->gregs[n - (51 - 16)]);
+     }
+ 
+     return 0;
+@@ -1260,42 +1275,63 @@ static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
+ 
+ static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n)
+ {
+-    uint32_t tmp;
+-
+-    tmp = ldl_p(mem_buf);
+-
+-    if (n < 8) {
++    switch (n) {
++    case 0 ... 7:
+         if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
+-            env->gregs[n + 16] = tmp;
++            env->gregs[n + 16] = ldl_p(mem_buf);
+         } else {
+-            env->gregs[n] = tmp;
++            env->gregs[n] = ldl_p(mem_buf);
+         }
+-	return 4;
+-    } else if (n < 16) {
+-        env->gregs[n] = tmp;
+-	return 4;
+-    } else if (n >= 25 && n < 41) {
+-	env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)] = tmp;
+-	return 4;
+-    } else if (n >= 43 && n < 51) {
+-	env->gregs[n - 43] = tmp;
+-	return 4;
+-    } else if (n >= 51 && n < 59) {
+-	env->gregs[n - (51 - 16)] = tmp;
+-	return 4;
+-    }
+-    switch (n) {
+-    case 16: env->pc = tmp; break;
+-    case 17: env->pr = tmp; break;
+-    case 18: env->gbr = tmp; break;
+-    case 19: env->vbr = tmp; break;
+-    case 20: env->mach = tmp; break;
+-    case 21: env->macl = tmp; break;
+-    case 22: env->sr = tmp; break;
+-    case 23: env->fpul = tmp; break;
+-    case 24: env->fpscr = tmp; break;
+-    case 41: env->ssr = tmp; break;
+-    case 42: env->spc = tmp; break;
++        break;
++    case 8 ... 15:
++        env->gregs[n] = ldl_p(mem_buf);
++        break;
++    case 16:
++        env->pc = ldl_p(mem_buf);
++        break;
++    case 17:
++        env->pr = ldl_p(mem_buf);
++        break;
++    case 18:
++        env->gbr = ldl_p(mem_buf);
++        break;
++    case 19:
++        env->vbr = ldl_p(mem_buf);
++        break;
++    case 20:
++        env->mach = ldl_p(mem_buf);
++        break;
++    case 21:
++        env->macl = ldl_p(mem_buf);
++        break;
++    case 22:
++        env->sr = ldl_p(mem_buf);
++        break;
++    case 23:
++        env->fpul = ldl_p(mem_buf);
++        break;
++    case 24:
++        env->fpscr = ldl_p(mem_buf);
++        break;
++    case 25 ... 40:
++        if (env->fpscr & FPSCR_FR) {
++            env->fregs[n - 9] = ldfl_p(mem_buf);
++        } else {
++            env->fregs[n - 25] = ldfl_p(mem_buf);
++        }
++        break;
++    case 41:
++        env->ssr = ldl_p(mem_buf);
++        break;
++    case 42:
++        env->spc = ldl_p(mem_buf);
++        break;
++    case 43 ... 50:
++        env->gregs[n - 43] = ldl_p(mem_buf);
++        break;
++    case 51 ... 58:
++        env->gregs[n - (51 - 16)] = ldl_p(mem_buf);
++        break;
+     default: return 0;
+     }
+ 
+-- 
+1.7.12.1
+
diff --git a/0055-tcg-Fix-USE_DIRECT_JUMP.patch b/0055-tcg-Fix-USE_DIRECT_JUMP.patch
new file mode 100644
index 0000000..3f88ee8
--- /dev/null
+++ b/0055-tcg-Fix-USE_DIRECT_JUMP.patch
@@ -0,0 +1,35 @@
+From 03ddebf0c48dc78070c846b7cfdc2665fe7df854 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Mon, 17 Sep 2012 08:28:52 -0700
+Subject: [PATCH] tcg: Fix !USE_DIRECT_JUMP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit 6375e09e changed the type of TranslationBlock.tb_next,
+but failed to change the type of TCGContext.tb_next.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Reviewed-by: Andreas Färber <afaerber at suse.de>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/tcg.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tcg/tcg.h b/tcg/tcg.h
+index f454107..609ed86 100644
+--- a/tcg/tcg.h
++++ b/tcg/tcg.h
+@@ -344,7 +344,7 @@ struct TCGContext {
+ 
+     /* goto_tb support */
+     uint8_t *code_buf;
+-    unsigned long *tb_next;
++    uintptr_t *tb_next;
+     uint16_t *tb_next_offset;
+     uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
+ 
+-- 
+1.7.12.1
+
diff --git a/0056-tcg-hppa-Fix-brcond2-and-setcond2.patch b/0056-tcg-hppa-Fix-brcond2-and-setcond2.patch
new file mode 100644
index 0000000..fa1f7cb
--- /dev/null
+++ b/0056-tcg-hppa-Fix-brcond2-and-setcond2.patch
@@ -0,0 +1,108 @@
+From 3616400bc0065f7114172ad7801d9d88332ef981 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Tue, 18 Sep 2012 19:59:47 -0700
+Subject: [PATCH] tcg-hppa: Fix brcond2 and setcond2
+
+Neither of these functions were performing double-word
+compares properly.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/hppa/tcg-target.c | 51 ++++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 42 insertions(+), 9 deletions(-)
+
+diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
+index 8b81b70..a76569d 100644
+--- a/tcg/hppa/tcg-target.c
++++ b/tcg/hppa/tcg-target.c
+@@ -820,19 +820,34 @@ static void tcg_out_comclr(TCGContext *s, int cond, TCGArg ret,
+     tcg_out32(s, op);
+ }
+ 
++static TCGCond const tcg_high_cond[] = {
++    [TCG_COND_EQ] = TCG_COND_EQ,
++    [TCG_COND_NE] = TCG_COND_NE,
++    [TCG_COND_LT] = TCG_COND_LT,
++    [TCG_COND_LE] = TCG_COND_LT,
++    [TCG_COND_GT] = TCG_COND_GT,
++    [TCG_COND_GE] = TCG_COND_GT,
++    [TCG_COND_LTU] = TCG_COND_LTU,
++    [TCG_COND_LEU] = TCG_COND_LTU,
++    [TCG_COND_GTU] = TCG_COND_GTU,
++    [TCG_COND_GEU] = TCG_COND_GTU
++};
++
+ static void tcg_out_brcond2(TCGContext *s, int cond, TCGArg al, TCGArg ah,
+                             TCGArg bl, int blconst, TCGArg bh, int bhconst,
+                             int label_index)
+ {
+     switch (cond) {
+     case TCG_COND_EQ:
++        tcg_out_comclr(s, TCG_COND_NE, TCG_REG_R0, al, bl, blconst);
++        tcg_out_brcond(s, TCG_COND_EQ, ah, bh, bhconst, label_index);
++        break;
+     case TCG_COND_NE:
+-        tcg_out_comclr(s, tcg_invert_cond(cond), TCG_REG_R0, al, bl, blconst);
+-        tcg_out_brcond(s, cond, ah, bh, bhconst, label_index);
++        tcg_out_brcond(s, TCG_COND_NE, al, bl, bhconst, label_index);
++        tcg_out_brcond(s, TCG_COND_NE, ah, bh, bhconst, label_index);
+         break;
+-
+     default:
+-        tcg_out_brcond(s, cond, ah, bh, bhconst, label_index);
++        tcg_out_brcond(s, tcg_high_cond[cond], ah, bh, bhconst, label_index);
+         tcg_out_comclr(s, TCG_COND_NE, TCG_REG_R0, ah, bh, bhconst);
+         tcg_out_brcond(s, tcg_unsigned_cond(cond),
+                        al, bl, blconst, label_index);
+@@ -853,9 +868,8 @@ static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret,
+ {
+     int scratch = TCG_REG_R20;
+ 
+-    if (ret != al && ret != ah
+-        && (blconst || ret != bl)
+-        && (bhconst || ret != bh)) {
++    /* Note that the low parts are fully consumed before scratch is set.  */
++    if (ret != ah && (bhconst || ret != bh)) {
+         scratch = ret;
+     }
+ 
+@@ -867,13 +881,32 @@ static void tcg_out_setcond2(TCGContext *s, int cond, TCGArg ret,
+         tcg_out_movi(s, TCG_TYPE_I32, scratch, cond == TCG_COND_NE);
+         break;
+ 
+-    default:
++    case TCG_COND_GE:
++    case TCG_COND_GEU:
++    case TCG_COND_LT:
++    case TCG_COND_LTU:
++        /* Optimize compares with low part zero.  */
++        if (bl == 0) {
++            tcg_out_setcond(s, cond, ret, ah, bh, bhconst);
++            return;
++        }
++        /* FALLTHRU */
++
++    case TCG_COND_LE:
++    case TCG_COND_LEU:
++    case TCG_COND_GT:
++    case TCG_COND_GTU:
++        /* <= : ah < bh | (ah == bh && al <= bl) */
+         tcg_out_setcond(s, tcg_unsigned_cond(cond), scratch, al, bl, blconst);
+         tcg_out_comclr(s, TCG_COND_EQ, TCG_REG_R0, ah, bh, bhconst);
+         tcg_out_movi(s, TCG_TYPE_I32, scratch, 0);
+-        tcg_out_comclr(s, cond, TCG_REG_R0, ah, bh, bhconst);
++        tcg_out_comclr(s, tcg_invert_cond(tcg_high_cond[cond]),
++                       TCG_REG_R0, ah, bh, bhconst);
+         tcg_out_movi(s, TCG_TYPE_I32, scratch, 1);
+         break;
++
++    default:
++        tcg_abort();
+     }
+ 
+     tcg_out_mov(s, TCG_TYPE_I32, ret, scratch);
+-- 
+1.7.12.1
+
diff --git a/0057-tcg-hppa-Fix-broken-load-store-helpers.patch b/0057-tcg-hppa-Fix-broken-load-store-helpers.patch
new file mode 100644
index 0000000..3666a95
--- /dev/null
+++ b/0057-tcg-hppa-Fix-broken-load-store-helpers.patch
@@ -0,0 +1,249 @@
+From c13ecfea174994d3f7f7d392f0faaed6d40efd9e Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Tue, 18 Sep 2012 19:59:48 -0700
+Subject: [PATCH] tcg-hppa: Fix broken load/store helpers
+
+The CONFIG_TCG_PASS_AREG0 code for calling ld/st helpers
+was not respecting the ABI requirement for 64-bit values
+being aligned in registers.
+
+Mirror the ARM port in use of helper functions to marshal
+arguments into the correct registers.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/hppa/tcg-target.c | 136 +++++++++++++++++++++++++++-----------------------
+ 1 file changed, 74 insertions(+), 62 deletions(-)
+
+diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
+index a76569d..5385d45 100644
+--- a/tcg/hppa/tcg-target.c
++++ b/tcg/hppa/tcg-target.c
+@@ -976,10 +976,11 @@ static int tcg_out_tlb_read(TCGContext *s, int r0, int r1, int addrlo,
+         tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, r1, offset);
+     }
+ 
+-    /* Compute the value that ought to appear in the TLB for a hit, namely, the page
+-       of the address.  We include the low N bits of the address to catch unaligned
+-       accesses and force them onto the slow path.  Do this computation after having
+-       issued the load from the TLB slot to give the load time to complete.  */
++    /* Compute the value that ought to appear in the TLB for a hit, namely,
++       the page of the address.  We include the low N bits of the address
++       to catch unaligned accesses and force them onto the slow path.  Do
++       this computation after having issued the load from the TLB slot to
++       give the load time to complete.  */
+     tcg_out_andi(s, r0, addrlo, TARGET_PAGE_MASK | ((1 << s_bits) - 1));
+ 
+     /* If not equal, jump to lab_miss. */
+@@ -992,6 +993,36 @@ static int tcg_out_tlb_read(TCGContext *s, int r0, int r1, int addrlo,
+ 
+     return ret;
+ }
++
++static int tcg_out_arg_reg32(TCGContext *s, int argno, TCGArg v, bool vconst)
++{
++    if (argno < 4) {
++        if (vconst) {
++            tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[argno], v);
++        } else {
++            tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[argno], v);
++        }
++    } else {
++        if (vconst && v != 0) {
++            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_R20, v);
++            v = TCG_REG_R20;
++        }
++        tcg_out_st(s, TCG_TYPE_I32, v, TCG_REG_CALL_STACK,
++                   TCG_TARGET_CALL_STACK_OFFSET - ((argno - 3) * 4));
++    }
++    return argno + 1;
++}
++
++static int tcg_out_arg_reg64(TCGContext *s, int argno, TCGArg vl, TCGArg vh)
++{
++    /* 64-bit arguments must go in even reg pairs and stack slots.  */
++    if (argno & 1) {
++        argno++;
++    }
++    argno = tcg_out_arg_reg32(s, argno, vl, false);
++    argno = tcg_out_arg_reg32(s, argno, vh, false);
++    return argno;
++}
+ #endif
+ 
+ static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo_reg, int datahi_reg,
+@@ -1072,39 +1103,36 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+     /* Note that addrhi_reg is only used for 64-bit guests.  */
+     int addrhi_reg = (TARGET_LONG_BITS == 64 ? *args++ : TCG_REG_R0);
+     int mem_index = *args;
+-    int lab1, lab2, argreg, offset;
++    int lab1, lab2, argno, offset;
+ 
+     lab1 = gen_new_label();
+     lab2 = gen_new_label();
+ 
+     offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
+-    offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg, addrhi_reg,
+-                              opc & 3, lab1, offset);
++    offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg,
++                              addrhi_reg, opc & 3, lab1, offset);
+ 
+     /* TLB Hit.  */
+-    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : TCG_REG_R25),
++    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20,
++               (offset ? TCG_REG_R1 : TCG_REG_R25),
+                offsetof(CPUArchState, tlb_table[mem_index][0].addend) - offset);
+-    tcg_out_qemu_ld_direct(s, datalo_reg, datahi_reg, addrlo_reg, TCG_REG_R20, opc);
++    tcg_out_qemu_ld_direct(s, datalo_reg, datahi_reg, addrlo_reg,
++                           TCG_REG_R20, opc);
+     tcg_out_branch(s, lab2, 1);
+ 
+     /* TLB Miss.  */
+     /* label1: */
+     tcg_out_label(s, lab1, s->code_ptr);
+ 
+-    argreg = TCG_REG_R26;
+-    tcg_out_mov(s, TCG_TYPE_I32, argreg--, addrlo_reg);
++    argno = 0;
++    argno = tcg_out_arg_reg32(s, argno, TCG_AREG0, false);
+     if (TARGET_LONG_BITS == 64) {
+-        tcg_out_mov(s, TCG_TYPE_I32, argreg--, addrhi_reg);
++        argno = tcg_out_arg_reg64(s, argno, addrlo_reg, addrhi_reg);
++    } else {
++        argno = tcg_out_arg_reg32(s, argno, addrlo_reg, false);
+     }
+-    tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
+-
+-    /* XXX/FIXME: suboptimal */
+-    tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
+-                tcg_target_call_iarg_regs[1]);
+-    tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+-                tcg_target_call_iarg_regs[0]);
+-    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+-                TCG_AREG0);
++    argno = tcg_out_arg_reg32(s, argno, mem_index, true);
++
+     tcg_out_call(s, qemu_ld_helpers[opc & 3]);
+ 
+     switch (opc) {
+@@ -1140,8 +1168,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
+ #endif
+ }
+ 
+-static void tcg_out_qemu_st_direct(TCGContext *s, int datalo_reg, int datahi_reg,
+-                                   int addr_reg, int opc)
++static void tcg_out_qemu_st_direct(TCGContext *s, int datalo_reg,
++                                   int datahi_reg, int addr_reg, int opc)
+ {
+ #ifdef TARGET_WORDS_BIGENDIAN
+     const int bswap = 0;
+@@ -1194,17 +1222,18 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
+     /* Note that addrhi_reg is only used for 64-bit guests.  */
+     int addrhi_reg = (TARGET_LONG_BITS == 64 ? *args++ : TCG_REG_R0);
+     int mem_index = *args;
+-    int lab1, lab2, argreg, offset;
++    int lab1, lab2, argno, next, offset;
+ 
+     lab1 = gen_new_label();
+     lab2 = gen_new_label();
+ 
+     offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
+-    offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg, addrhi_reg,
+-                              opc, lab1, offset);
++    offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg,
++                              addrhi_reg, opc, lab1, offset);
+ 
+     /* TLB Hit.  */
+-    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : TCG_REG_R25),
++    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20,
++               (offset ? TCG_REG_R1 : TCG_REG_R25),
+                offsetof(CPUArchState, tlb_table[mem_index][0].addend) - offset);
+ 
+     /* There are no indexed stores, so we must do this addition explitly.
+@@ -1217,63 +1246,46 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
+     /* label1: */
+     tcg_out_label(s, lab1, s->code_ptr);
+ 
+-    argreg = TCG_REG_R26;
+-    tcg_out_mov(s, TCG_TYPE_I32, argreg--, addrlo_reg);
++    argno = 0;
++    argno = tcg_out_arg_reg32(s, argno, TCG_AREG0, false);
+     if (TARGET_LONG_BITS == 64) {
+-        tcg_out_mov(s, TCG_TYPE_I32, argreg--, addrhi_reg);
++        argno = tcg_out_arg_reg64(s, argno, addrlo_reg, addrhi_reg);
++    } else {
++        argno = tcg_out_arg_reg32(s, argno, addrlo_reg, false);
+     }
+ 
++    next = (argno < 4 ? tcg_target_call_iarg_regs[argno] : TCG_REG_R20);
+     switch(opc) {
+     case 0:
+-        tcg_out_andi(s, argreg--, datalo_reg, 0xff);
+-        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
++        tcg_out_andi(s, next, datalo_reg, 0xff);
++        argno = tcg_out_arg_reg32(s, argno, next, false);
+         break;
+     case 1:
+-        tcg_out_andi(s, argreg--, datalo_reg, 0xffff);
+-        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
++        tcg_out_andi(s, next, datalo_reg, 0xffff);
++        argno = tcg_out_arg_reg32(s, argno, next, false);
+         break;
+     case 2:
+-        tcg_out_mov(s, TCG_TYPE_I32, argreg--, datalo_reg);
+-        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
++        argno = tcg_out_arg_reg32(s, argno, datalo_reg, false);
+         break;
+     case 3:
+-        /* Because of the alignment required by the 64-bit data argument,
+-           we will always use R23/R24.  Also, we will always run out of
+-           argument registers for storing mem_index, so that will have
+-           to go on the stack.  */
+-        if (mem_index == 0) {
+-            argreg = TCG_REG_R0;
+-        } else {
+-            argreg = TCG_REG_R20;
+-            tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
+-        }
+-        tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R23, datahi_reg);
+-        tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R24, datalo_reg);
+-        tcg_out_st(s, TCG_TYPE_I32, argreg, TCG_REG_CALL_STACK,
+-                   TCG_TARGET_CALL_STACK_OFFSET - 4);
++        argno = tcg_out_arg_reg64(s, argno, datalo_reg, datahi_reg);
+         break;
+     default:
+         tcg_abort();
+     }
++    argno = tcg_out_arg_reg32(s, argno, mem_index, true);
+ 
+-    /* XXX/FIXME: suboptimal */
+-    tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
+-                tcg_target_call_iarg_regs[2]);
+-    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
+-                tcg_target_call_iarg_regs[1]);
+-    tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+-                tcg_target_call_iarg_regs[0]);
+-    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+-                TCG_AREG0);
+     tcg_out_call(s, qemu_st_helpers[opc]);
+ 
+     /* label2: */
+     tcg_out_label(s, lab2, s->code_ptr);
+ #else
+-    /* There are no indexed stores, so if GUEST_BASE is set we must do the add
+-       explicitly.  Careful to avoid R20, which is used for the bswaps to follow.  */
++    /* There are no indexed stores, so if GUEST_BASE is set we must do
++       the add explicitly.  Careful to avoid R20, which is used for the
++       bswaps to follow.  */
+     if (GUEST_BASE != 0) {
+-        tcg_out_arith(s, TCG_REG_R31, addrlo_reg, TCG_GUEST_BASE_REG, INSN_ADDL);
++        tcg_out_arith(s, TCG_REG_R31, addrlo_reg,
++                      TCG_GUEST_BASE_REG, INSN_ADDL);
+         addrlo_reg = TCG_REG_R31;
+     }
+     tcg_out_qemu_st_direct(s, datalo_reg, datahi_reg, addrlo_reg, opc);
+-- 
+1.7.12.1
+
diff --git a/0058-tcg-mips-fix-wrong-usage-of-Z-constraint.patch b/0058-tcg-mips-fix-wrong-usage-of-Z-constraint.patch
new file mode 100644
index 0000000..a4e1059
--- /dev/null
+++ b/0058-tcg-mips-fix-wrong-usage-of-Z-constraint.patch
@@ -0,0 +1,65 @@
+From 061d22ad76512e8ec10af89eda1dcc7c185360d2 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 18:20:25 +0200
+Subject: [PATCH] tcg-mips: fix wrong usage of 'Z' constraint
+
+The 'Z' constraint has been introduced to map the zero register. However
+when the op also accept a constant, there is no point to accept the zero
+register in addition.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index 74db83d..9293745 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -1453,24 +1453,24 @@ static const TCGTargetOpDef mips_op_defs[] = {
+     { INDEX_op_st16_i32, { "rZ", "r" } },
+     { INDEX_op_st_i32, { "rZ", "r" } },
+ 
+-    { INDEX_op_add_i32, { "r", "rZ", "rJZ" } },
++    { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
+     { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
+     { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
+     { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
+     { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
+     { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
+     { INDEX_op_remu_i32, { "r", "rZ", "rZ" } },
+-    { INDEX_op_sub_i32, { "r", "rZ", "rJZ" } },
++    { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
+ 
+-    { INDEX_op_and_i32, { "r", "rZ", "rIZ" } },
++    { INDEX_op_and_i32, { "r", "rZ", "rI" } },
+     { INDEX_op_nor_i32, { "r", "rZ", "rZ" } },
+     { INDEX_op_not_i32, { "r", "rZ" } },
+     { INDEX_op_or_i32, { "r", "rZ", "rIZ" } },
+     { INDEX_op_xor_i32, { "r", "rZ", "rIZ" } },
+ 
+-    { INDEX_op_shl_i32, { "r", "rZ", "riZ" } },
+-    { INDEX_op_shr_i32, { "r", "rZ", "riZ" } },
+-    { INDEX_op_sar_i32, { "r", "rZ", "riZ" } },
++    { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
++    { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
++    { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
+ 
+     { INDEX_op_ext8s_i32, { "r", "rZ" } },
+     { INDEX_op_ext16s_i32, { "r", "rZ" } },
+@@ -1479,8 +1479,8 @@ static const TCGTargetOpDef mips_op_defs[] = {
+     { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
+     { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
+ 
+-    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
+-    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJZ", "rJZ" } },
++    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
++    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
+     { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },
+ 
+ #if TARGET_LONG_BITS == 32
+-- 
+1.7.12.1
+
diff --git a/0059-tcg-mips-kill-warnings-in-user-mode.patch b/0059-tcg-mips-kill-warnings-in-user-mode.patch
new file mode 100644
index 0000000..96de9cb
--- /dev/null
+++ b/0059-tcg-mips-kill-warnings-in-user-mode.patch
@@ -0,0 +1,166 @@
+From e63a3c6c70c9933320c6d8b23c3ea4cf4724d316 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 18:20:25 +0200
+Subject: [PATCH] tcg/mips: kill warnings in user mode
+
+Recent versions of GCC emit warnings when compiling user mode targets.
+Kill them by reordering a bit the #ifdef.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 84 ++++++++++++++++++++++++++-------------------------
+ 1 file changed, 43 insertions(+), 41 deletions(-)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index 9293745..a09c0d6 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -842,18 +842,16 @@ static const void * const qemu_st_helpers[4] = {
+ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+                             int opc)
+ {
+-    int addr_regl, addr_meml;
+-    int data_regl, data_regh, data_reg1, data_reg2;
+-    int mem_index, s_bits;
++    int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
+ #if defined(CONFIG_SOFTMMU)
+     void *label1_ptr, *label2_ptr;
+     int arg_num;
+-#endif
+-#if TARGET_LONG_BITS == 64
+-# if defined(CONFIG_SOFTMMU)
++    int mem_index, s_bits;
++    int addr_meml;
++# if TARGET_LONG_BITS == 64
+     uint8_t *label3_ptr;
+-# endif
+     int addr_regh, addr_memh;
++# endif
+ #endif
+     data_regl = *args++;
+     if (opc == 3)
+@@ -861,11 +859,22 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+     else
+         data_regh = 0;
+     addr_regl = *args++;
+-#if TARGET_LONG_BITS == 64
++#if defined(CONFIG_SOFTMMU)
++# if TARGET_LONG_BITS == 64
+     addr_regh = *args++;
+-#endif
++#  if defined(TCG_TARGET_WORDS_BIGENDIAN)
++    addr_memh = 0;
++    addr_meml = 4;
++#  else
++    addr_memh = 4;
++    addr_meml = 0;
++#  endif
++# else
++    addr_meml = 0;
++# endif
+     mem_index = *args;
+     s_bits = opc & 3;
++#endif
+ 
+     if (opc == 3) {
+ #if defined(TCG_TARGET_WORDS_BIGENDIAN)
+@@ -879,18 +888,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+         data_reg1 = data_regl;
+         data_reg2 = 0;
+     }
+-#if TARGET_LONG_BITS == 64
+-# if defined(TCG_TARGET_WORDS_BIGENDIAN)
+-    addr_memh = 0;
+-    addr_meml = 4;
+-# else
+-    addr_memh = 4;
+-    addr_meml = 0;
+-# endif
+-#else
+-    addr_meml = 0;
+-#endif
+-
+ #if defined(CONFIG_SOFTMMU)
+     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
+     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_A0, TCG_REG_A0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
+@@ -1029,50 +1026,55 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
+                             int opc)
+ {
+-    int addr_regl, addr_meml;
+-    int data_regl, data_regh, data_reg1, data_reg2;
+-    int mem_index, s_bits;
++    int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
+ #if defined(CONFIG_SOFTMMU)
+     uint8_t *label1_ptr, *label2_ptr;
+     int arg_num;
++    int mem_index, s_bits;
++    int addr_meml;
+ #endif
+ #if TARGET_LONG_BITS == 64
+ # if defined(CONFIG_SOFTMMU)
+     uint8_t *label3_ptr;
+-# endif
+     int addr_regh, addr_memh;
++# endif
+ #endif
+-
+     data_regl = *args++;
+     if (opc == 3) {
+         data_regh = *args++;
+-#if defined(TCG_TARGET_WORDS_BIGENDIAN)
+-        data_reg1 = data_regh;
+-        data_reg2 = data_regl;
+-#else
+-        data_reg1 = data_regl;
+-        data_reg2 = data_regh;
+-#endif
+     } else {
+-        data_reg1 = data_regl;
+-        data_reg2 = 0;
+         data_regh = 0;
+     }
+     addr_regl = *args++;
+-#if TARGET_LONG_BITS == 64
++#if defined(CONFIG_SOFTMMU)
++# if TARGET_LONG_BITS == 64
+     addr_regh = *args++;
+-# if defined(TCG_TARGET_WORDS_BIGENDIAN)
++#  if defined(TCG_TARGET_WORDS_BIGENDIAN)
+     addr_memh = 0;
+     addr_meml = 4;
+-# else
++#  else
+     addr_memh = 4;
+     addr_meml = 0;
+-# endif
+-#else
++#  endif
++# else
+     addr_meml = 0;
+-#endif
++# endif
+     mem_index = *args;
+     s_bits = opc;
++#endif
++
++    if (opc == 3) {
++#if defined(TCG_TARGET_WORDS_BIGENDIAN)
++        data_reg1 = data_regh;
++        data_reg2 = data_regl;
++#else
++        data_reg1 = data_regl;
++        data_reg2 = data_regh;
++#endif
++    } else {
++        data_reg1 = data_regl;
++        data_reg2 = 0;
++    }
+ 
+ #if defined(CONFIG_SOFTMMU)
+     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_A0, addr_regl, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
+-- 
+1.7.12.1
+
diff --git a/0060-tcg-mips-use-TCGArg-or-TCGReg-instead-of-int.patch b/0060-tcg-mips-use-TCGArg-or-TCGReg-instead-of-int.patch
new file mode 100644
index 0000000..a6eb42f
--- /dev/null
+++ b/0060-tcg-mips-use-TCGArg-or-TCGReg-instead-of-int.patch
@@ -0,0 +1,246 @@
+From 7b817977fbb87ee2e34018d92b64907197974a75 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 18:20:26 +0200
+Subject: [PATCH] tcg/mips: use TCGArg or TCGReg instead of int
+
+Instead of int, use the correct TCGArg and TCGReg type: TCGReg when
+representing a TCG target register, TCGArg when representing the latter
+or a constant.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 63 ++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 35 insertions(+), 28 deletions(-)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index a09c0d6..8b38f98 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -68,7 +68,7 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
+ #endif
+ 
+ /* check if we really need so many registers :P */
+-static const int tcg_target_reg_alloc_order[] = {
++static const TCGReg tcg_target_reg_alloc_order[] = {
+     TCG_REG_S0,
+     TCG_REG_S1,
+     TCG_REG_S2,
+@@ -94,14 +94,14 @@ static const int tcg_target_reg_alloc_order[] = {
+     TCG_REG_V1
+ };
+ 
+-static const int tcg_target_call_iarg_regs[4] = {
++static const TCGReg tcg_target_call_iarg_regs[4] = {
+     TCG_REG_A0,
+     TCG_REG_A1,
+     TCG_REG_A2,
+     TCG_REG_A3
+ };
+ 
+-static const int tcg_target_call_oarg_regs[2] = {
++static const TCGReg tcg_target_call_oarg_regs[2] = {
+     TCG_REG_V0,
+     TCG_REG_V1
+ };
+@@ -327,7 +327,8 @@ enum {
+ /*
+  * Type reg
+  */
+-static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int rt)
++static inline void tcg_out_opc_reg(TCGContext *s, int opc,
++                                   TCGReg rd, TCGReg rs, TCGReg rt)
+ {
+     int32_t inst;
+ 
+@@ -341,7 +342,8 @@ static inline void tcg_out_opc_reg(TCGContext *s, int opc, int rd, int rs, int r
+ /*
+  * Type immediate
+  */
+-static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int imm)
++static inline void tcg_out_opc_imm(TCGContext *s, int opc,
++                                   TCGReg rt, TCGReg rs, TCGArg imm)
+ {
+     int32_t inst;
+ 
+@@ -355,7 +357,8 @@ static inline void tcg_out_opc_imm(TCGContext *s, int opc, int rt, int rs, int i
+ /*
+  * Type branch
+  */
+-static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
++static inline void tcg_out_opc_br(TCGContext *s, int opc,
++                                  TCGReg rt, TCGReg rs)
+ {
+     /* We pay attention here to not modify the branch target by reading
+        the existing value and using it again. This ensure that caches and
+@@ -368,7 +371,8 @@ static inline void tcg_out_opc_br(TCGContext *s, int opc, int rt, int rs)
+ /*
+  * Type sa
+  */
+-static inline void tcg_out_opc_sa(TCGContext *s, int opc, int rd, int rt, int sa)
++static inline void tcg_out_opc_sa(TCGContext *s, int opc,
++                                  TCGReg rd, TCGReg rt, TCGArg sa)
+ {
+     int32_t inst;
+ 
+@@ -407,7 +411,7 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
+     }
+ }
+ 
+-static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
++static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
+     /* ret and arg can't be register at */
+     if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
+@@ -422,7 +426,7 @@ static inline void tcg_out_bswap16(TCGContext *s, int ret, int arg)
+     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+ }
+ 
+-static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
++static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
+     /* ret and arg can't be register at */
+     if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
+@@ -437,7 +441,7 @@ static inline void tcg_out_bswap16s(TCGContext *s, int ret, int arg)
+     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+ }
+ 
+-static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
++static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
+     /* ret and arg must be different and can't be register at */
+     if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
+@@ -458,7 +462,7 @@ static inline void tcg_out_bswap32(TCGContext *s, int ret, int arg)
+     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+ }
+ 
+-static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
++static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
+ #ifdef _MIPS_ARCH_MIPS32R2
+     tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
+@@ -468,7 +472,7 @@ static inline void tcg_out_ext8s(TCGContext *s, int ret, int arg)
+ #endif
+ }
+ 
+-static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
++static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
+ #ifdef _MIPS_ARCH_MIPS32R2
+     tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
+@@ -478,8 +482,8 @@ static inline void tcg_out_ext16s(TCGContext *s, int ret, int arg)
+ #endif
+ }
+ 
+-static inline void tcg_out_ldst(TCGContext *s, int opc, int arg,
+-                              int arg1, tcg_target_long arg2)
++static inline void tcg_out_ldst(TCGContext *s, int opc, TCGArg arg,
++                                TCGReg arg1, TCGArg arg2)
+ {
+     if (arg2 == (int16_t) arg2) {
+         tcg_out_opc_imm(s, opc, arg, arg1, arg2);
+@@ -502,7 +506,7 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
+     tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
+ }
+ 
+-static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
++static inline void tcg_out_addi(TCGContext *s, TCGReg reg, TCGArg val)
+ {
+     if (val == (int16_t)val) {
+         tcg_out_opc_imm(s, OPC_ADDIU, reg, reg, val);
+@@ -543,7 +547,7 @@ DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_reg16, TCGReg arg)
+ #undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
+ #define DEFINE_TCG_OUT_CALL_IARG_GET_ARG(A) \
+     tcg_out_movi(s, TCG_TYPE_I32, A, arg);
+-DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, uint32_t arg)
++DEFINE_TCG_OUT_CALL_IARG(tcg_out_call_iarg_imm32, TCGArg arg)
+ #undef DEFINE_TCG_OUT_CALL_IARG_GET_ARG
+ 
+ /* We don't use the macro for this one to avoid an unnecessary reg-reg
+@@ -573,8 +577,8 @@ static inline void tcg_out_call_iarg_reg64(TCGContext *s, int *arg_num,
+ #endif
+ }
+ 
+-static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
+-                           int arg2, int label_index)
++static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
++                           TCGArg arg2, int label_index)
+ {
+     TCGLabel *l = &s->labels[label_index];
+ 
+@@ -631,8 +635,9 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, int arg1,
+ 
+ /* XXX: we implement it at the target level to avoid having to
+    handle cross basic blocks temporaries */
+-static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
+-                            int arg2, int arg3, int arg4, int label_index)
++static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGArg arg1,
++                            TCGArg arg2, TCGArg arg3, TCGArg arg4,
++                            int label_index)
+ {
+     void *label_ptr;
+ 
+@@ -694,8 +699,8 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, int arg1,
+     reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
+ }
+ 
+-static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
+-                            int arg1, int arg2)
++static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
++                            TCGArg arg1, TCGArg arg2)
+ {
+     switch (cond) {
+     case TCG_COND_EQ:
+@@ -754,8 +759,8 @@ static void tcg_out_setcond(TCGContext *s, TCGCond cond, int ret,
+ 
+ /* XXX: we implement it at the target level to avoid having to
+    handle cross basic blocks temporaries */
+-static void tcg_out_setcond2(TCGContext *s, TCGCond cond, int ret,
+-                             int arg1, int arg2, int arg3, int arg4)
++static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
++                             TCGArg arg1, TCGArg arg2, TCGArg arg3, TCGArg arg4)
+ {
+     switch (cond) {
+     case TCG_COND_EQ:
+@@ -842,7 +847,7 @@ static const void * const qemu_st_helpers[4] = {
+ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+                             int opc)
+ {
+-    int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
++    TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
+ #if defined(CONFIG_SOFTMMU)
+     void *label1_ptr, *label2_ptr;
+     int arg_num;
+@@ -850,7 +855,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+     int addr_meml;
+ # if TARGET_LONG_BITS == 64
+     uint8_t *label3_ptr;
+-    int addr_regh, addr_memh;
++    TCGReg addr_regh;
++    int addr_memh;
+ # endif
+ #endif
+     data_regl = *args++;
+@@ -1026,7 +1032,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
+                             int opc)
+ {
+-    int addr_regl, data_regl, data_regh, data_reg1, data_reg2;
++    TCGReg addr_regl, data_regl, data_regh, data_reg1, data_reg2;
+ #if defined(CONFIG_SOFTMMU)
+     uint8_t *label1_ptr, *label2_ptr;
+     int arg_num;
+@@ -1036,7 +1042,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
+ #if TARGET_LONG_BITS == 64
+ # if defined(CONFIG_SOFTMMU)
+     uint8_t *label3_ptr;
+-    int addr_regh, addr_memh;
++    TCGReg addr_regh;
++    int addr_memh;
+ # endif
+ #endif
+     data_regl = *args++;
+-- 
+1.7.12.1
+
diff --git a/0061-tcg-mips-don-t-use-global-pointer.patch b/0061-tcg-mips-don-t-use-global-pointer.patch
new file mode 100644
index 0000000..a9aaf69
--- /dev/null
+++ b/0061-tcg-mips-don-t-use-global-pointer.patch
@@ -0,0 +1,37 @@
+From 9a4f545e4526f946613548a427fcab4c2a089ac0 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 18:20:26 +0200
+Subject: [PATCH] tcg/mips: don't use global pointer
+
+Don't use the global pointer in TCG, in case helpers try access global
+variables.
+
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index 8b38f98..0ea6a76 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -1529,7 +1529,6 @@ static int tcg_target_callee_save_regs[] = {
+     TCG_REG_S5,
+     TCG_REG_S6,
+     TCG_REG_S7,
+-    TCG_REG_GP,
+     TCG_REG_FP,
+     TCG_REG_RA,       /* should be last for ABI compliance */
+ };
+@@ -1595,6 +1594,7 @@ static void tcg_target_init(TCGContext *s)
+     tcg_regset_set_reg(s->reserved_regs, TCG_REG_T0);   /* internal use */
+     tcg_regset_set_reg(s->reserved_regs, TCG_REG_RA);   /* return address */
+     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
++    tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
+ 
+     tcg_add_target_add_op_defs(mips_op_defs);
+     tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
+-- 
+1.7.12.1
+
diff --git a/0062-tcg-mips-use-stack-for-TCG-temps.patch b/0062-tcg-mips-use-stack-for-TCG-temps.patch
new file mode 100644
index 0000000..09ea3fb
--- /dev/null
+++ b/0062-tcg-mips-use-stack-for-TCG-temps.patch
@@ -0,0 +1,47 @@
+From c914ae50df4dc2f2ab589c87c0cd2ce2f14d9639 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 18:20:26 +0200
+Subject: [PATCH] tcg/mips: use stack for TCG temps
+
+Use stack instead of temp_buf array in CPUState for TCG
+temps.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index 0ea6a76..c05169f 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -1538,11 +1538,15 @@ static void tcg_target_qemu_prologue(TCGContext *s)
+ {
+     int i, frame_size;
+ 
+-    /* reserve some stack space */
++    /* reserve some stack space, also for TCG temps. */
+     frame_size = ARRAY_SIZE(tcg_target_callee_save_regs) * 4
+-                 + TCG_STATIC_CALL_ARGS_SIZE;
++                 + TCG_STATIC_CALL_ARGS_SIZE
++                 + CPU_TEMP_BUF_NLONGS * sizeof(long);
+     frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
+                  ~(TCG_TARGET_STACK_ALIGN - 1);
++    tcg_set_frame(s, TCG_REG_SP, ARRAY_SIZE(tcg_target_callee_save_regs) * 4
++                  + TCG_STATIC_CALL_ARGS_SIZE,
++                  CPU_TEMP_BUF_NLONGS * sizeof(long));
+ 
+     /* TB prologue */
+     tcg_out_addi(s, TCG_REG_SP, -frame_size);
+@@ -1597,6 +1601,4 @@ static void tcg_target_init(TCGContext *s)
+     tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */
+ 
+     tcg_add_target_add_op_defs(mips_op_defs);
+-    tcg_set_frame(s, TCG_AREG0, offsetof(CPUArchState, temp_buf),
+-                  CPU_TEMP_BUF_NLONGS * sizeof(long));
+ }
+-- 
+1.7.12.1
+
diff --git a/0063-tcg-mips-optimize-brcond-arg-0.patch b/0063-tcg-mips-optimize-brcond-arg-0.patch
new file mode 100644
index 0000000..e21fcac
--- /dev/null
+++ b/0063-tcg-mips-optimize-brcond-arg-0.patch
@@ -0,0 +1,99 @@
+From e30cf829e9d8200364b53b9189c76d2155a32876 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 18:20:26 +0200
+Subject: [PATCH] tcg/mips: optimize brcond arg, 0
+
+MIPS has some conditional branch instructions when comparing with zero.
+Use them.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 38 ++++++++++++++++++++++++++++++--------
+ 1 file changed, 30 insertions(+), 8 deletions(-)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index c05169f..6aa4527 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -278,6 +278,8 @@ static inline int tcg_target_const_match(tcg_target_long val,
+ enum {
+     OPC_BEQ      = 0x04 << 26,
+     OPC_BNE      = 0x05 << 26,
++    OPC_BLEZ     = 0x06 << 26,
++    OPC_BGTZ     = 0x07 << 26,
+     OPC_ADDIU    = 0x09 << 26,
+     OPC_SLTI     = 0x0A << 26,
+     OPC_SLTIU    = 0x0B << 26,
+@@ -319,6 +321,10 @@ enum {
+     OPC_SLT      = OPC_SPECIAL | 0x2A,
+     OPC_SLTU     = OPC_SPECIAL | 0x2B,
+ 
++    OPC_REGIMM   = 0x01 << 26,
++    OPC_BLTZ     = OPC_REGIMM | (0x00 << 16),
++    OPC_BGEZ     = OPC_REGIMM | (0x01 << 16),
++
+     OPC_SPECIAL3 = 0x1f << 26,
+     OPC_SEB      = OPC_SPECIAL3 | 0x420,
+     OPC_SEH      = OPC_SPECIAL3 | 0x620,
+@@ -590,32 +596,48 @@ static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGArg arg1,
+         tcg_out_opc_br(s, OPC_BNE, arg1, arg2);
+         break;
+     case TCG_COND_LT:
+-        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
+-        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
++        if (arg2 == 0) {
++            tcg_out_opc_br(s, OPC_BLTZ, 0, arg1);
++        } else {
++            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
++            tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
++        }
+         break;
+     case TCG_COND_LTU:
+         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
+         tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
+         break;
+     case TCG_COND_GE:
+-        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
+-        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
++        if (arg2 == 0) {
++            tcg_out_opc_br(s, OPC_BGEZ, 0, arg1);
++        } else {
++            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg1, arg2);
++            tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
++        }
+         break;
+     case TCG_COND_GEU:
+         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg1, arg2);
+         tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
+         break;
+     case TCG_COND_LE:
+-        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
+-        tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
++        if (arg2 == 0) {
++            tcg_out_opc_br(s, OPC_BLEZ, 0, arg1);
++        } else {
++            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
++            tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
++        }
+         break;
+     case TCG_COND_LEU:
+         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
+         tcg_out_opc_br(s, OPC_BEQ, TCG_REG_AT, TCG_REG_ZERO);
+         break;
+     case TCG_COND_GT:
+-        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
+-        tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
++        if (arg2 == 0) {
++            tcg_out_opc_br(s, OPC_BGTZ, 0, arg1);
++        } else {
++            tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, arg2, arg1);
++            tcg_out_opc_br(s, OPC_BNE, TCG_REG_AT, TCG_REG_ZERO);
++        }
+         break;
+     case TCG_COND_GTU:
+         tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, arg2, arg1);
+-- 
+1.7.12.1
+
diff --git a/0064-tcg-mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch b/0064-tcg-mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch
new file mode 100644
index 0000000..45a881d
--- /dev/null
+++ b/0064-tcg-mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch
@@ -0,0 +1,161 @@
+From 879794c3d3974b1206bbc52011c8f2525709f396 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 18:20:26 +0200
+Subject: [PATCH] tcg/mips: optimize bswap{16,16s,32} on MIPS32R2
+
+bswap operations can be optimized on MIPS32 Release 2 using the ROTR,
+WSBH and SEH instructions. We can't use the non-R2 code to implement the
+ops due to registers constraints, so don't define the corresponding
+TCG_TARGET_HAS_bswap* values.
+
+Also bswap16* operations are supposed to be called with the 16 high bits
+zeroed. This is the case everywhere (including for TCG by definition)
+except when called from the store helper. Remove the AND instructions from
+bswap16* and move it there.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 34 +++++++++++++++++++++++++++++-----
+ tcg/mips/tcg-target.h | 11 +++++++++--
+ 2 files changed, 38 insertions(+), 7 deletions(-)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index 6aa4527..8b2f9fc 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -326,6 +326,7 @@ enum {
+     OPC_BGEZ     = OPC_REGIMM | (0x01 << 16),
+ 
+     OPC_SPECIAL3 = 0x1f << 26,
++    OPC_WSBH     = OPC_SPECIAL3 | 0x0a0,
+     OPC_SEB      = OPC_SPECIAL3 | 0x420,
+     OPC_SEH      = OPC_SPECIAL3 | 0x620,
+ };
+@@ -419,36 +420,45 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
+ 
+ static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
++#ifdef _MIPS_ARCH_MIPS32R2
++    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
++#else
+     /* ret and arg can't be register at */
+     if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
+         tcg_abort();
+     }
+ 
+     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
+-    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0x00ff);
+-
+     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
+     tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
+     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
++#endif
+ }
+ 
+ static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
++#ifdef _MIPS_ARCH_MIPS32R2
++    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
++    tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
++#else
+     /* ret and arg can't be register at */
+     if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
+         tcg_abort();
+     }
+ 
+     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
+-    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff);
+-
+     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
+     tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
+     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
++#endif
+ }
+ 
+ static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
++#ifdef _MIPS_ARCH_MIPS32R2
++    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
++    tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
++#else
+     /* ret and arg must be different and can't be register at */
+     if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
+         tcg_abort();
+@@ -466,6 +476,7 @@ static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
+     tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
+     tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
+     tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
++#endif
+ }
+ 
+ static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
+@@ -1188,7 +1199,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
+         break;
+     case 1:
+         if (TCG_NEED_BSWAP) {
+-            tcg_out_bswap16(s, TCG_REG_T0, data_reg1);
++            tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_T0, data_reg1, 0xffff);
++            tcg_out_bswap16(s, TCG_REG_T0, TCG_REG_T0);
+             tcg_out_opc_imm(s, OPC_SH, TCG_REG_T0, TCG_REG_A0, 0);
+         } else {
+             tcg_out_opc_imm(s, OPC_SH, data_reg1, TCG_REG_A0, 0);
+@@ -1409,6 +1421,15 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
+         }
+         break;
+ 
++    /* The bswap routines do not work on non-R2 CPU. In that case
++       we let TCG generating the corresponding code. */
++    case INDEX_op_bswap16_i32:
++        tcg_out_bswap16(s, args[0], args[1]);
++        break;
++    case INDEX_op_bswap32_i32:
++        tcg_out_bswap32(s, args[0], args[1]);
++        break;
++
+     case INDEX_op_ext8s_i32:
+         tcg_out_ext8s(s, args[0], args[1]);
+         break;
+@@ -1503,6 +1524,9 @@ static const TCGTargetOpDef mips_op_defs[] = {
+     { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
+     { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
+ 
++    { INDEX_op_bswap16_i32, { "r", "r" } },
++    { INDEX_op_bswap32_i32, { "r", "r" } },
++
+     { INDEX_op_ext8s_i32, { "r", "rZ" } },
+     { INDEX_op_ext16s_i32, { "r", "rZ" } },
+ 
+diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
+index 9c68a32..c5c13f7 100644
+--- a/tcg/mips/tcg-target.h
++++ b/tcg/mips/tcg-target.h
+@@ -83,8 +83,6 @@ typedef enum {
+ #define TCG_TARGET_HAS_rot_i32          0
+ #define TCG_TARGET_HAS_ext8s_i32        1
+ #define TCG_TARGET_HAS_ext16s_i32       1
+-#define TCG_TARGET_HAS_bswap32_i32      0
+-#define TCG_TARGET_HAS_bswap16_i32      0
+ #define TCG_TARGET_HAS_andc_i32         0
+ #define TCG_TARGET_HAS_orc_i32          0
+ #define TCG_TARGET_HAS_eqv_i32          0
+@@ -92,6 +90,15 @@ typedef enum {
+ #define TCG_TARGET_HAS_deposit_i32      0
+ #define TCG_TARGET_HAS_movcond_i32      0
+ 
++/* optional instructions only implemented on MIPS32R2 */
++#ifdef _MIPS_ARCH_MIPS32R2
++#define TCG_TARGET_HAS_bswap16_i32      1
++#define TCG_TARGET_HAS_bswap32_i32      1
++#else
++#define TCG_TARGET_HAS_bswap16_i32      0
++#define TCG_TARGET_HAS_bswap32_i32      0
++#endif
++
+ /* optional instructions automatically implemented */
+ #define TCG_TARGET_HAS_neg_i32          0 /* sub  rd, zero, rt   */
+ #define TCG_TARGET_HAS_ext8u_i32        0 /* andi rt, rs, 0xff   */
+-- 
+1.7.12.1
+
diff --git a/0065-tcg-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch b/0065-tcg-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch
new file mode 100644
index 0000000..6134676
--- /dev/null
+++ b/0065-tcg-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch
@@ -0,0 +1,92 @@
+From d19858a5515cd15dabf88b8f180754c1c3f3eb76 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 18:20:26 +0200
+Subject: [PATCH] tcg/mips: implement rotl/rotr ops on MIPS32R2
+
+rotr operations can be optimized on MIPS32 Release 2 using the ROTR and
+ROTRV instructions. Also implemented rotl operations by subtracting the
+shift from 32.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 20 ++++++++++++++++++++
+ tcg/mips/tcg-target.h |  3 ++-
+ 2 files changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index 8b2f9fc..592e42a 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -300,9 +300,11 @@ enum {
+     OPC_SPECIAL  = 0x00 << 26,
+     OPC_SLL      = OPC_SPECIAL | 0x00,
+     OPC_SRL      = OPC_SPECIAL | 0x02,
++    OPC_ROTR     = OPC_SPECIAL | (0x01 << 21) | 0x02,
+     OPC_SRA      = OPC_SPECIAL | 0x03,
+     OPC_SLLV     = OPC_SPECIAL | 0x04,
+     OPC_SRLV     = OPC_SPECIAL | 0x06,
++    OPC_ROTRV    = OPC_SPECIAL | (0x01 <<  6) | 0x06,
+     OPC_SRAV     = OPC_SPECIAL | 0x07,
+     OPC_JR       = OPC_SPECIAL | 0x08,
+     OPC_JALR     = OPC_SPECIAL | 0x09,
+@@ -1420,6 +1422,22 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
+             tcg_out_opc_reg(s, OPC_SRLV, args[0], args[2], args[1]);
+         }
+         break;
++    case INDEX_op_rotl_i32:
++        if (const_args[2]) {
++            tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], 0x20 - args[2]);
++        } else {
++            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_AT, 32);
++            tcg_out_opc_reg(s, OPC_SUBU, TCG_REG_AT, TCG_REG_AT, args[2]);
++            tcg_out_opc_reg(s, OPC_ROTRV, args[0], TCG_REG_AT, args[1]);
++        }
++        break;
++    case INDEX_op_rotr_i32:
++        if (const_args[2]) {
++            tcg_out_opc_sa(s, OPC_ROTR, args[0], args[1], args[2]);
++        } else {
++            tcg_out_opc_reg(s, OPC_ROTRV, args[0], args[2], args[1]);
++        }
++        break;
+ 
+     /* The bswap routines do not work on non-R2 CPU. In that case
+        we let TCG generating the corresponding code. */
+@@ -1523,6 +1541,8 @@ static const TCGTargetOpDef mips_op_defs[] = {
+     { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
+     { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
+     { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
++    { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
++    { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
+ 
+     { INDEX_op_bswap16_i32, { "r", "r" } },
+     { INDEX_op_bswap32_i32, { "r", "r" } },
+diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
+index c5c13f7..470314c 100644
+--- a/tcg/mips/tcg-target.h
++++ b/tcg/mips/tcg-target.h
+@@ -80,7 +80,6 @@ typedef enum {
+ #define TCG_TARGET_HAS_div_i32          1
+ #define TCG_TARGET_HAS_not_i32          1
+ #define TCG_TARGET_HAS_nor_i32          1
+-#define TCG_TARGET_HAS_rot_i32          0
+ #define TCG_TARGET_HAS_ext8s_i32        1
+ #define TCG_TARGET_HAS_ext16s_i32       1
+ #define TCG_TARGET_HAS_andc_i32         0
+@@ -94,9 +93,11 @@ typedef enum {
+ #ifdef _MIPS_ARCH_MIPS32R2
+ #define TCG_TARGET_HAS_bswap16_i32      1
+ #define TCG_TARGET_HAS_bswap32_i32      1
++#define TCG_TARGET_HAS_rot_i32          1
+ #else
+ #define TCG_TARGET_HAS_bswap16_i32      0
+ #define TCG_TARGET_HAS_bswap32_i32      0
++#define TCG_TARGET_HAS_rot_i32          0
+ #endif
+ 
+ /* optional instructions automatically implemented */
+-- 
+1.7.12.1
+
diff --git a/0066-tcg-mips-implement-deposit-op-on-MIPS32R2.patch b/0066-tcg-mips-implement-deposit-op-on-MIPS32R2.patch
new file mode 100644
index 0000000..fe54bc0
--- /dev/null
+++ b/0066-tcg-mips-implement-deposit-op-on-MIPS32R2.patch
@@ -0,0 +1,77 @@
+From 7c3e573b364a65d4abce5266c376f4e77624b039 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 18:20:26 +0200
+Subject: [PATCH] tcg/mips: implement deposit op on MIPS32R2
+
+deposit operations can be optimized on MIPS32 Release 2 using the INS
+instruction.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 8 ++++++++
+ tcg/mips/tcg-target.h | 3 ++-
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index 592e42a..b2e1056 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -328,6 +328,7 @@ enum {
+     OPC_BGEZ     = OPC_REGIMM | (0x01 << 16),
+ 
+     OPC_SPECIAL3 = 0x1f << 26,
++    OPC_INS      = OPC_SPECIAL3 | 0x004,
+     OPC_WSBH     = OPC_SPECIAL3 | 0x0a0,
+     OPC_SEB      = OPC_SPECIAL3 | 0x420,
+     OPC_SEH      = OPC_SPECIAL3 | 0x620,
+@@ -1455,6 +1456,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
+         tcg_out_ext16s(s, args[0], args[1]);
+         break;
+ 
++    case INDEX_op_deposit_i32:
++        tcg_out_opc_imm(s, OPC_INS, args[0], args[2],
++                        ((args[3] + args[4] - 1) << 11) | (args[3] << 6));
++        break;
++
+     case INDEX_op_brcond_i32:
+         tcg_out_brcond(s, args[2], args[0], args[1], args[3]);
+         break;
+@@ -1550,6 +1556,8 @@ static const TCGTargetOpDef mips_op_defs[] = {
+     { INDEX_op_ext8s_i32, { "r", "rZ" } },
+     { INDEX_op_ext16s_i32, { "r", "rZ" } },
+ 
++    { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
++
+     { INDEX_op_brcond_i32, { "rZ", "rZ" } },
+     { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
+     { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
+diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
+index 470314c..897a737 100644
+--- a/tcg/mips/tcg-target.h
++++ b/tcg/mips/tcg-target.h
+@@ -86,7 +86,6 @@ typedef enum {
+ #define TCG_TARGET_HAS_orc_i32          0
+ #define TCG_TARGET_HAS_eqv_i32          0
+ #define TCG_TARGET_HAS_nand_i32         0
+-#define TCG_TARGET_HAS_deposit_i32      0
+ #define TCG_TARGET_HAS_movcond_i32      0
+ 
+ /* optional instructions only implemented on MIPS32R2 */
+@@ -94,10 +93,12 @@ typedef enum {
+ #define TCG_TARGET_HAS_bswap16_i32      1
+ #define TCG_TARGET_HAS_bswap32_i32      1
+ #define TCG_TARGET_HAS_rot_i32          1
++#define TCG_TARGET_HAS_deposit_i32      1
+ #else
+ #define TCG_TARGET_HAS_bswap16_i32      0
+ #define TCG_TARGET_HAS_bswap32_i32      0
+ #define TCG_TARGET_HAS_rot_i32          0
++#define TCG_TARGET_HAS_deposit_i32      0
+ #endif
+ 
+ /* optional instructions automatically implemented */
+-- 
+1.7.12.1
+
diff --git a/0067-tcg-mips-implement-movcond-op-on-MIPS32R2.patch b/0067-tcg-mips-implement-movcond-op-on-MIPS32R2.patch
new file mode 100644
index 0000000..7f06797
--- /dev/null
+++ b/0067-tcg-mips-implement-movcond-op-on-MIPS32R2.patch
@@ -0,0 +1,140 @@
+From 552720cea4c1ca99dd1919cb8a80b6b8f3b13cda Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 18:20:26 +0200
+Subject: [PATCH] tcg/mips: implement movcond op on MIPS32R2
+
+movcond operation can be implemented on MIPS32 Release 2 using the MOVN,
+MOVZ, SLT and SLTU instructions.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ tcg/mips/tcg-target.h |  8 ++++++
+ 2 files changed, 77 insertions(+)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index b2e1056..c272b38 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -308,6 +308,8 @@ enum {
+     OPC_SRAV     = OPC_SPECIAL | 0x07,
+     OPC_JR       = OPC_SPECIAL | 0x08,
+     OPC_JALR     = OPC_SPECIAL | 0x09,
++    OPC_MOVZ     = OPC_SPECIAL | 0x0A,
++    OPC_MOVN     = OPC_SPECIAL | 0x0B,
+     OPC_MFHI     = OPC_SPECIAL | 0x10,
+     OPC_MFLO     = OPC_SPECIAL | 0x12,
+     OPC_MULT     = OPC_SPECIAL | 0x18,
+@@ -735,6 +737,68 @@ static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGArg arg1,
+     reloc_pc16(label_ptr, (tcg_target_long) s->code_ptr);
+ }
+ 
++static void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGReg ret,
++                            TCGArg c1, TCGArg c2, TCGArg v)
++{
++    switch (cond) {
++    case TCG_COND_EQ:
++        if (c1 == 0) {
++            tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c2);
++        } else if (c2 == 0) {
++            tcg_out_opc_reg(s, OPC_MOVZ, ret, v, c1);
++        } else {
++            tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
++            tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
++        }
++        break;
++    case TCG_COND_NE:
++        if (c1 == 0) {
++            tcg_out_opc_reg(s, OPC_MOVN, ret, v, c2);
++        } else if (c2 == 0) {
++            tcg_out_opc_reg(s, OPC_MOVN, ret, v, c1);
++        } else {
++            tcg_out_opc_reg(s, OPC_XOR, TCG_REG_AT, c1, c2);
++            tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
++        }
++        break;
++    case TCG_COND_LT:
++        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
++        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
++        break;
++    case TCG_COND_LTU:
++        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
++        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
++        break;
++    case TCG_COND_GE:
++        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c1, c2);
++        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
++        break;
++    case TCG_COND_GEU:
++        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c1, c2);
++        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
++        break;
++    case TCG_COND_LE:
++        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
++        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
++        break;
++    case TCG_COND_LEU:
++        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
++        tcg_out_opc_reg(s, OPC_MOVZ, ret, v, TCG_REG_AT);
++        break;
++    case TCG_COND_GT:
++        tcg_out_opc_reg(s, OPC_SLT, TCG_REG_AT, c2, c1);
++        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
++        break;
++    case TCG_COND_GTU:
++        tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_AT, c2, c1);
++        tcg_out_opc_reg(s, OPC_MOVN, ret, v, TCG_REG_AT);
++        break;
++    default:
++        tcg_abort();
++        break;
++    }
++}
++
+ static void tcg_out_setcond(TCGContext *s, TCGCond cond, TCGReg ret,
+                             TCGArg arg1, TCGArg arg2)
+ {
+@@ -1468,6 +1532,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
+         tcg_out_brcond2(s, args[4], args[0], args[1], args[2], args[3], args[5]);
+         break;
+ 
++    case INDEX_op_movcond_i32:
++        tcg_out_movcond(s, args[5], args[0], args[1], args[2], args[3]);
++        break;
++
+     case INDEX_op_setcond_i32:
+         tcg_out_setcond(s, args[3], args[0], args[1], args[2]);
+         break;
+@@ -1559,6 +1627,7 @@ static const TCGTargetOpDef mips_op_defs[] = {
+     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
+ 
+     { INDEX_op_brcond_i32, { "rZ", "rZ" } },
++    { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
+     { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
+     { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
+ 
+diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
+index 897a737..d147e70 100644
+--- a/tcg/mips/tcg-target.h
++++ b/tcg/mips/tcg-target.h
+@@ -86,7 +86,15 @@ typedef enum {
+ #define TCG_TARGET_HAS_orc_i32          0
+ #define TCG_TARGET_HAS_eqv_i32          0
+ #define TCG_TARGET_HAS_nand_i32         0
++
++/* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
++#if defined(_MIPS_ARCH_MIPS4) || defined(_MIPS_ARCH_MIPS32) || \
++    defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_LOONGSON2E) || \
++    defined(_MIPS_ARCH_LOONGSON2F)
++#define TCG_TARGET_HAS_movcond_i32      1
++#else
+ #define TCG_TARGET_HAS_movcond_i32      0
++#endif
+ 
+ /* optional instructions only implemented on MIPS32R2 */
+ #ifdef _MIPS_ARCH_MIPS32R2
+-- 
+1.7.12.1
+
diff --git a/0068-tcg-optimize-remove-TCG_TEMP_ANY.patch b/0068-tcg-optimize-remove-TCG_TEMP_ANY.patch
new file mode 100644
index 0000000..0702187
--- /dev/null
+++ b/0068-tcg-optimize-remove-TCG_TEMP_ANY.patch
@@ -0,0 +1,62 @@
+From 848750a4acf9ea5c473be596d41720e702d770f0 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Mon, 10 Sep 2012 23:51:42 +0200
+Subject: [PATCH] tcg/optimize: remove TCG_TEMP_ANY
+
+TCG_TEMP_ANY has no different meaning than TCG_TEMP_UNDEF, so use
+the later instead.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 1be7631..308b7f9 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -39,8 +39,7 @@ typedef enum {
+     TCG_TEMP_UNDEF = 0,
+     TCG_TEMP_CONST,
+     TCG_TEMP_COPY,
+-    TCG_TEMP_HAS_COPY,
+-    TCG_TEMP_ANY
++    TCG_TEMP_HAS_COPY
+ } tcg_temp_state;
+ 
+ struct tcg_temp_info {
+@@ -52,7 +51,7 @@ struct tcg_temp_info {
+ 
+ static struct tcg_temp_info temps[TCG_MAX_TEMPS];
+ 
+-/* Reset TEMP's state to TCG_TEMP_ANY.  If TEMP was a representative of some
++/* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP was a representative of some
+    class of equivalent temp's, a new representative should be chosen in this
+    class. */
+ static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
+@@ -69,7 +68,7 @@ static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
+         }
+         for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) {
+             if (new_base == (TCGArg)-1) {
+-                temps[i].state = TCG_TEMP_ANY;
++                temps[i].state = TCG_TEMP_UNDEF;
+             } else {
+                 temps[i].val = new_base;
+             }
+@@ -81,9 +80,9 @@ static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
+         temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
+         new_base = temps[temp].val;
+     }
+-    temps[temp].state = TCG_TEMP_ANY;
++    temps[temp].state = TCG_TEMP_UNDEF;
+     if (new_base != (TCGArg)-1 && temps[new_base].next_copy == new_base) {
+-        temps[new_base].state = TCG_TEMP_ANY;
++        temps[new_base].state = TCG_TEMP_UNDEF;
+     }
+ }
+ 
+-- 
+1.7.12.1
+
diff --git a/0069-tcg-optimize-check-types-in-copy-propagation.patch b/0069-tcg-optimize-check-types-in-copy-propagation.patch
new file mode 100644
index 0000000..6627679
--- /dev/null
+++ b/0069-tcg-optimize-check-types-in-copy-propagation.patch
@@ -0,0 +1,78 @@
+From 71f0bcf065ddd00d5659e846ddfdffb9a06ee896 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Tue, 11 Sep 2012 12:26:23 +0200
+Subject: [PATCH] tcg/optimize: check types in copy propagation
+
+The copy propagation doesn't check the types of the temps during copy
+propagation. However TCG is using the mov_i32 for the i64 to i32
+conversion and thus the two are not equivalent.
+
+With this patch tcg_opt_gen_mov() doesn't consider two temps of
+different type as copies anymore.
+
+So far it seems the optimization was not aggressive enough to trigger
+this bug, but it will be triggered later in this series once the copy
+propagation is improved.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 308b7f9..da8dffe 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -106,12 +106,13 @@ static TCGOpcode op_to_movi(TCGOpcode op)
+     }
+ }
+ 
+-static void tcg_opt_gen_mov(TCGArg *gen_args, TCGArg dst, TCGArg src,
+-                            int nb_temps, int nb_globals)
++static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args,
++                            TCGArg dst, TCGArg src)
+ {
+-        reset_temp(dst, nb_temps, nb_globals);
++        reset_temp(dst, s->nb_temps, s->nb_globals);
+         assert(temps[src].state != TCG_TEMP_COPY);
+-        if (src >= nb_globals) {
++        /* Only consider temps with the same type (width) as copies. */
++        if (src >= s->nb_globals && s->temps[dst].type == s->temps[src].type) {
+             assert(temps[src].state != TCG_TEMP_CONST);
+             if (temps[src].state != TCG_TEMP_HAS_COPY) {
+                 temps[src].state = TCG_TEMP_HAS_COPY;
+@@ -461,8 +462,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else {
+                     gen_opc_buf[op_index] = op_to_mov(op);
+-                    tcg_opt_gen_mov(gen_args, args[0], args[1],
+-                                    nb_temps, nb_globals);
++                    tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
+                     gen_args += 2;
+                 }
+                 args += 3;
+@@ -499,8 +499,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else {
+                     gen_opc_buf[op_index] = op_to_mov(op);
+-                    tcg_opt_gen_mov(gen_args, args[0], args[1], nb_temps,
+-                                    nb_globals);
++                    tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
+                     gen_args += 2;
+                 }
+                 args += 3;
+@@ -524,8 +523,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 break;
+             }
+             if (temps[args[1]].state != TCG_TEMP_CONST) {
+-                tcg_opt_gen_mov(gen_args, args[0], args[1],
+-                                nb_temps, nb_globals);
++                tcg_opt_gen_mov(s, gen_args, args[0], args[1]);
+                 gen_args += 2;
+                 args += 2;
+                 break;
+-- 
+1.7.12.1
+
diff --git a/0070-tcg-optimize-rework-copy-progagation.patch b/0070-tcg-optimize-rework-copy-progagation.patch
new file mode 100644
index 0000000..ca39c5a
--- /dev/null
+++ b/0070-tcg-optimize-rework-copy-progagation.patch
@@ -0,0 +1,377 @@
+From bf408071104de13f79a0c3c8cac892f440462e7c Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Tue, 11 Sep 2012 12:31:21 +0200
+Subject: [PATCH] tcg/optimize: rework copy progagation
+
+The copy propagation pass tries to keep track what is a copy of what
+and what has copy of what, and in addition it keep a circular list of
+of all the copies. Unfortunately this doesn't fully work: a mov from
+a temp which has a state "COPY" changed it into a state "HAS_COPY".
+Later when this temp is used again, it is considered has not having
+copy and thus no propagation is done.
+
+This patch fixes that by removing the hiearchy between copies, and thus
+only keeping a "COPY" state both meaning "is a copy" and "has a copy".
+The decision of which copy to use is deferred to the actual temp
+replacement. At this stage there is not one best choice to do, but only
+better choices than others. For doing the best choice the operation
+would have to be parsed in reversed to know if a temp is going to be
+used later or not. That what is done by the liveness analysis. At this
+stage it is known that globals will be always live, that local temps
+will be dead at the end of the translation block, and that the temps
+will be dead at the end of the basic block. This means that this stage
+should try to replace temps by local temps or globals and local temps
+by globals.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 167 +++++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 92 insertions(+), 75 deletions(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index da8dffe..1904b39 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -39,7 +39,6 @@ typedef enum {
+     TCG_TEMP_UNDEF = 0,
+     TCG_TEMP_CONST,
+     TCG_TEMP_COPY,
+-    TCG_TEMP_HAS_COPY
+ } tcg_temp_state;
+ 
+ struct tcg_temp_info {
+@@ -51,39 +50,19 @@ struct tcg_temp_info {
+ 
+ static struct tcg_temp_info temps[TCG_MAX_TEMPS];
+ 
+-/* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP was a representative of some
+-   class of equivalent temp's, a new representative should be chosen in this
+-   class. */
+-static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
++/* Reset TEMP's state to TCG_TEMP_UNDEF.  If TEMP only had one copy, remove
++   the copy flag from the left temp.  */
++static void reset_temp(TCGArg temp)
+ {
+-    int i;
+-    TCGArg new_base = (TCGArg)-1;
+-    if (temps[temp].state == TCG_TEMP_HAS_COPY) {
+-        for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) {
+-            if (i >= nb_globals) {
+-                temps[i].state = TCG_TEMP_HAS_COPY;
+-                new_base = i;
+-                break;
+-            }
+-        }
+-        for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) {
+-            if (new_base == (TCGArg)-1) {
+-                temps[i].state = TCG_TEMP_UNDEF;
+-            } else {
+-                temps[i].val = new_base;
+-            }
++    if (temps[temp].state == TCG_TEMP_COPY) {
++        if (temps[temp].prev_copy == temps[temp].next_copy) {
++            temps[temps[temp].next_copy].state = TCG_TEMP_UNDEF;
++        } else {
++            temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
++            temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
+         }
+-        temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
+-        temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
+-    } else if (temps[temp].state == TCG_TEMP_COPY) {
+-        temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy;
+-        temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy;
+-        new_base = temps[temp].val;
+     }
+     temps[temp].state = TCG_TEMP_UNDEF;
+-    if (new_base != (TCGArg)-1 && temps[new_base].next_copy == new_base) {
+-        temps[new_base].state = TCG_TEMP_UNDEF;
+-    }
+ }
+ 
+ static int op_bits(TCGOpcode op)
+@@ -106,34 +85,83 @@ static TCGOpcode op_to_movi(TCGOpcode op)
+     }
+ }
+ 
++static TCGArg find_better_copy(TCGContext *s, TCGArg temp)
++{
++    TCGArg i;
++
++    /* If this is already a global, we can't do better. */
++    if (temp < s->nb_globals) {
++        return temp;
++    }
++
++    /* Search for a global first. */
++    for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
++        if (i < s->nb_globals) {
++            return i;
++        }
++    }
++
++    /* If it is a temp, search for a temp local. */
++    if (!s->temps[temp].temp_local) {
++        for (i = temps[temp].next_copy ; i != temp ; i = temps[i].next_copy) {
++            if (s->temps[i].temp_local) {
++                return i;
++            }
++        }
++    }
++
++    /* Failure to find a better representation, return the same temp. */
++    return temp;
++}
++
++static bool temps_are_copies(TCGArg arg1, TCGArg arg2)
++{
++    TCGArg i;
++
++    if (arg1 == arg2) {
++        return true;
++    }
++
++    if (temps[arg1].state != TCG_TEMP_COPY
++        || temps[arg2].state != TCG_TEMP_COPY) {
++        return false;
++    }
++
++    for (i = temps[arg1].next_copy ; i != arg1 ; i = temps[i].next_copy) {
++        if (i == arg2) {
++            return true;
++        }
++    }
++
++    return false;
++}
++
+ static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args,
+                             TCGArg dst, TCGArg src)
+ {
+-        reset_temp(dst, s->nb_temps, s->nb_globals);
+-        assert(temps[src].state != TCG_TEMP_COPY);
+-        /* Only consider temps with the same type (width) as copies. */
+-        if (src >= s->nb_globals && s->temps[dst].type == s->temps[src].type) {
+-            assert(temps[src].state != TCG_TEMP_CONST);
+-            if (temps[src].state != TCG_TEMP_HAS_COPY) {
+-                temps[src].state = TCG_TEMP_HAS_COPY;
++        reset_temp(dst);
++        assert(temps[src].state != TCG_TEMP_CONST);
++
++        if (s->temps[src].type == s->temps[dst].type) {
++            if (temps[src].state != TCG_TEMP_COPY) {
++                temps[src].state = TCG_TEMP_COPY;
+                 temps[src].next_copy = src;
+                 temps[src].prev_copy = src;
+             }
+             temps[dst].state = TCG_TEMP_COPY;
+-            temps[dst].val = src;
+             temps[dst].next_copy = temps[src].next_copy;
+             temps[dst].prev_copy = src;
+             temps[temps[dst].next_copy].prev_copy = dst;
+             temps[src].next_copy = dst;
+         }
++
+         gen_args[0] = dst;
+         gen_args[1] = src;
+ }
+ 
+-static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val,
+-                             int nb_temps, int nb_globals)
++static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val)
+ {
+-        reset_temp(dst, nb_temps, nb_globals);
++        reset_temp(dst);
+         temps[dst].state = TCG_TEMP_CONST;
+         temps[dst].val = val;
+         gen_args[0] = dst;
+@@ -324,7 +352,6 @@ static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
+     tcg_abort();
+ }
+ 
+-
+ /* Propagate constants and copies, fold constant expressions. */
+ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                                     TCGArg *args, TCGOpDef *tcg_op_defs)
+@@ -338,10 +365,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+ 
+     /* Array VALS has an element for each temp.
+        If this temp holds a constant then its value is kept in VALS' element.
+-       If this temp is a copy of other ones then this equivalence class'
+-       representative is kept in VALS' element.
+-       If this temp is neither copy nor constant then corresponding VALS'
+-       element is unused. */
++       If this temp is a copy of other ones then the other copies are
++       available through the doubly linked circular list. */
+ 
+     nb_temps = s->nb_temps;
+     nb_globals = s->nb_globals;
+@@ -357,7 +382,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             assert(op != INDEX_op_call);
+             for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) {
+                 if (temps[args[i]].state == TCG_TEMP_COPY) {
+-                    args[i] = temps[args[i]].val;
++                    args[i] = find_better_copy(s, args[i]);
+                 }
+             }
+         }
+@@ -429,7 +454,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             if (temps[args[1]].state == TCG_TEMP_CONST
+                 && temps[args[1]].val == 0) {
+                 gen_opc_buf[op_index] = op_to_movi(op);
+-                tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
++                tcg_opt_gen_movi(gen_args, args[0], 0);
+                 args += 3;
+                 gen_args += 2;
+                 continue;
+@@ -456,9 +481,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             }
+             if (temps[args[2]].state == TCG_TEMP_CONST
+                 && temps[args[2]].val == 0) {
+-                if ((temps[args[0]].state == TCG_TEMP_COPY
+-                    && temps[args[0]].val == args[1])
+-                    || args[0] == args[1]) {
++                if (temps_are_copies(args[0], args[1])) {
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else {
+                     gen_opc_buf[op_index] = op_to_mov(op);
+@@ -480,7 +503,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             if ((temps[args[2]].state == TCG_TEMP_CONST
+                 && temps[args[2]].val == 0)) {
+                 gen_opc_buf[op_index] = op_to_movi(op);
+-                tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals);
++                tcg_opt_gen_movi(gen_args, args[0], 0);
+                 args += 3;
+                 gen_args += 2;
+                 continue;
+@@ -495,7 +518,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+         CASE_OP_32_64(or):
+         CASE_OP_32_64(and):
+             if (args[1] == args[2]) {
+-                if (args[1] == args[0]) {
++                if (temps_are_copies(args[0], args[1])) {
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else {
+                     gen_opc_buf[op_index] = op_to_mov(op);
+@@ -515,9 +538,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+            allocator where needed and possible.  Also detect copies. */
+         switch (op) {
+         CASE_OP_32_64(mov):
+-            if ((temps[args[1]].state == TCG_TEMP_COPY
+-                && temps[args[1]].val == args[0])
+-                || args[0] == args[1]) {
++            if (temps_are_copies(args[0], args[1])) {
+                 args += 2;
+                 gen_opc_buf[op_index] = INDEX_op_nop;
+                 break;
+@@ -535,7 +556,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             args[1] = temps[args[1]].val;
+             /* fallthrough */
+         CASE_OP_32_64(movi):
+-            tcg_opt_gen_movi(gen_args, args[0], args[1], nb_temps, nb_globals);
++            tcg_opt_gen_movi(gen_args, args[0], args[1]);
+             gen_args += 2;
+             args += 2;
+             break;
+@@ -550,9 +571,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             if (temps[args[1]].state == TCG_TEMP_CONST) {
+                 gen_opc_buf[op_index] = op_to_movi(op);
+                 tmp = do_constant_folding(op, temps[args[1]].val, 0);
+-                tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
++                tcg_opt_gen_movi(gen_args, args[0], tmp);
+             } else {
+-                reset_temp(args[0], nb_temps, nb_globals);
++                reset_temp(args[0]);
+                 gen_args[0] = args[0];
+                 gen_args[1] = args[1];
+             }
+@@ -580,10 +601,10 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 gen_opc_buf[op_index] = op_to_movi(op);
+                 tmp = do_constant_folding(op, temps[args[1]].val,
+                                           temps[args[2]].val);
+-                tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
++                tcg_opt_gen_movi(gen_args, args[0], tmp);
+                 gen_args += 2;
+             } else {
+-                reset_temp(args[0], nb_temps, nb_globals);
++                reset_temp(args[0]);
+                 gen_args[0] = args[0];
+                 gen_args[1] = args[1];
+                 gen_args[2] = args[2];
+@@ -597,10 +618,10 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 gen_opc_buf[op_index] = op_to_movi(op);
+                 tmp = do_constant_folding_cond(op, temps[args[1]].val,
+                                                temps[args[2]].val, args[3]);
+-                tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals);
++                tcg_opt_gen_movi(gen_args, args[0], tmp);
+                 gen_args += 2;
+             } else {
+-                reset_temp(args[0], nb_temps, nb_globals);
++                reset_temp(args[0]);
+                 gen_args[0] = args[0];
+                 gen_args[1] = args[1];
+                 gen_args[2] = args[2];
+@@ -623,7 +644,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 }
+             } else {
+                 memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+-                reset_temp(args[0], nb_temps, nb_globals);
++                reset_temp(args[0]);
+                 gen_args[0] = args[0];
+                 gen_args[1] = args[1];
+                 gen_args[2] = args[2];
+@@ -637,23 +658,19 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 && temps[args[2]].state == TCG_TEMP_CONST) {
+                 tmp = do_constant_folding_cond(op, temps[args[1]].val,
+                                                temps[args[2]].val, args[5]);
+-                if (args[0] == args[4-tmp]
+-                    || (temps[args[4-tmp]].state == TCG_TEMP_COPY
+-                        && temps[args[4-tmp]].val == args[0])) {
++                if (temps_are_copies(args[0], args[4-tmp])) {
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
+                     gen_opc_buf[op_index] = op_to_movi(op);
+-                    tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val,
+-                                     nb_temps, nb_globals);
++                    tcg_opt_gen_movi(gen_args, args[0], temps[args[4-tmp]].val);
+                     gen_args += 2;
+                 } else {
+                     gen_opc_buf[op_index] = op_to_mov(op);
+-                    tcg_opt_gen_mov(gen_args, args[0], args[4-tmp],
+-                                    nb_temps, nb_globals);
++                    tcg_opt_gen_mov(s, gen_args, args[0], args[4-tmp]);
+                     gen_args += 2;
+                 }
+             } else {
+-                reset_temp(args[0], nb_temps, nb_globals);
++                reset_temp(args[0]);
+                 gen_args[0] = args[0];
+                 gen_args[1] = args[1];
+                 gen_args[2] = args[2];
+@@ -668,11 +685,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             nb_call_args = (args[0] >> 16) + (args[0] & 0xffff);
+             if (!(args[nb_call_args + 1] & (TCG_CALL_CONST | TCG_CALL_PURE))) {
+                 for (i = 0; i < nb_globals; i++) {
+-                    reset_temp(i, nb_temps, nb_globals);
++                    reset_temp(i);
+                 }
+             }
+             for (i = 0; i < (args[0] >> 16); i++) {
+-                reset_temp(args[i + 1], nb_temps, nb_globals);
++                reset_temp(args[i + 1]);
+             }
+             i = nb_call_args + 3;
+             while (i) {
+@@ -691,7 +708,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+                 memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+             } else {
+                 for (i = 0; i < def->nb_oargs; i++) {
+-                    reset_temp(args[i], nb_temps, nb_globals);
++                    reset_temp(args[i]);
+                 }
+             }
+             for (i = 0; i < def->nb_args; i++) {
+-- 
+1.7.12.1
+
diff --git a/0071-tcg-optimize-do-copy-propagation-for-all-operations.patch b/0071-tcg-optimize-do-copy-propagation-for-all-operations.patch
new file mode 100644
index 0000000..62a4efb
--- /dev/null
+++ b/0071-tcg-optimize-do-copy-propagation-for-all-operations.patch
@@ -0,0 +1,42 @@
+From 7c1a67bb734f364ea0643b549e030f04d4eed798 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Tue, 11 Sep 2012 16:18:49 +0200
+Subject: [PATCH] tcg/optimize: do copy propagation for all operations
+
+It is possible to due copy propagation for all operations, even the one
+that have side effects or clobber arguments (it only concerns input
+arguments). That said, the call operation should be handled differently
+due to the variable number of arguments.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index 1904b39..aeb2225 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -378,8 +378,15 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+         op = gen_opc_buf[op_index];
+         def = &tcg_op_defs[op];
+         /* Do copy propagation */
+-        if (!(def->flags & (TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS))) {
+-            assert(op != INDEX_op_call);
++        if (op == INDEX_op_call) {
++            int nb_oargs = args[0] >> 16;
++            int nb_iargs = args[0] & 0xffff;
++            for (i = nb_oargs + 1; i < nb_oargs + nb_iargs + 1; i++) {
++                if (temps[args[i]].state == TCG_TEMP_COPY) {
++                    args[i] = find_better_copy(s, args[i]);
++                }
++            }
++        } else {
+             for (i = def->nb_oargs; i < def->nb_oargs + def->nb_iargs; i++) {
+                 if (temps[args[i]].state == TCG_TEMP_COPY) {
+                     args[i] = find_better_copy(s, args[i]);
+-- 
+1.7.12.1
+
diff --git a/0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch b/0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch
new file mode 100644
index 0000000..65f5c50
--- /dev/null
+++ b/0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch
@@ -0,0 +1,31 @@
+From e38329760e40a354e37d11c7f5d8c86cdb90736c Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Tue, 18 Sep 2012 19:11:32 +0200
+Subject: [PATCH] tcg/optimize: optimize "op r, a, a => mov r, a"
+
+Now that we can easily detect all copies, we can optimize the
+"op r, a, a => mov r, a" case a bit more.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index aeb2225..b9a7da9 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -524,7 +524,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+         switch (op) {
+         CASE_OP_32_64(or):
+         CASE_OP_32_64(and):
+-            if (args[1] == args[2]) {
++            if (temps_are_copies(args[1], args[2])) {
+                 if (temps_are_copies(args[0], args[1])) {
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else {
+-- 
+1.7.12.1
+
diff --git a/0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch b/0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch
new file mode 100644
index 0000000..48ad5fe
--- /dev/null
+++ b/0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch
@@ -0,0 +1,46 @@
+From 363479b4d4f729959eafb1209d48ad75e928c00a Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Tue, 18 Sep 2012 19:12:36 +0200
+Subject: [PATCH] tcg/optimize: optimize "op r, a, a => movi r, 0"
+
+Now that it's possible to detect copies, we can optimize the case
+the "op r, a, a => movi r, 0". This helps in the computation of
+overflow flags when one of the two args is 0.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index b9a7da9..ceea644 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -540,6 +540,22 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             break;
+         }
+ 
++        /* Simplify expression for "op r, a, a => movi r, 0" cases */
++        switch (op) {
++        CASE_OP_32_64(sub):
++        CASE_OP_32_64(xor):
++            if (temps_are_copies(args[1], args[2])) {
++                gen_opc_buf[op_index] = op_to_movi(op);
++                tcg_opt_gen_movi(gen_args, args[0], 0);
++                gen_args += 2;
++                args += 3;
++                continue;
++            }
++            break;
++        default:
++            break;
++        }
++
+         /* Propagate constants through copy operations and do constant
+            folding.  Constants will be substituted to arguments by register
+            allocator where needed and possible.  Also detect copies. */
+-- 
+1.7.12.1
+
diff --git a/0074-tcg-optimize-further-optimize-brcond-movcond-setcond.patch b/0074-tcg-optimize-further-optimize-brcond-movcond-setcond.patch
new file mode 100644
index 0000000..9b9180d
--- /dev/null
+++ b/0074-tcg-optimize-further-optimize-brcond-movcond-setcond.patch
@@ -0,0 +1,192 @@
+From 8d5f3ca9ccace2374fd73d46fad56decc02e0a44 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Tue, 18 Sep 2012 19:37:00 +0200
+Subject: [PATCH] tcg/optimize: further optimize brcond/movcond/setcond
+
+When both argument of brcond/movcond/setcond are the same or when one
+of the two values is a constant equal to zero, it's possible to do
+further optimizations.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 127 ++++++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 76 insertions(+), 51 deletions(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index ceea644..abe016a 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -292,58 +292,88 @@ static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
+     return res;
+ }
+ 
++/* Return 2 if the condition can't be simplified, and the result
++   of the condition (0 or 1) if it can */
+ static TCGArg do_constant_folding_cond(TCGOpcode op, TCGArg x,
+                                        TCGArg y, TCGCond c)
+ {
+-    switch (op_bits(op)) {
+-    case 32:
++    if (temps[x].state == TCG_TEMP_CONST && temps[y].state == TCG_TEMP_CONST) {
++        switch (op_bits(op)) {
++        case 32:
++            switch (c) {
++            case TCG_COND_EQ:
++                return (uint32_t)temps[x].val == (uint32_t)temps[y].val;
++            case TCG_COND_NE:
++                return (uint32_t)temps[x].val != (uint32_t)temps[y].val;
++            case TCG_COND_LT:
++                return (int32_t)temps[x].val < (int32_t)temps[y].val;
++            case TCG_COND_GE:
++                return (int32_t)temps[x].val >= (int32_t)temps[y].val;
++            case TCG_COND_LE:
++                return (int32_t)temps[x].val <= (int32_t)temps[y].val;
++            case TCG_COND_GT:
++                return (int32_t)temps[x].val > (int32_t)temps[y].val;
++            case TCG_COND_LTU:
++                return (uint32_t)temps[x].val < (uint32_t)temps[y].val;
++            case TCG_COND_GEU:
++                return (uint32_t)temps[x].val >= (uint32_t)temps[y].val;
++            case TCG_COND_LEU:
++                return (uint32_t)temps[x].val <= (uint32_t)temps[y].val;
++            case TCG_COND_GTU:
++                return (uint32_t)temps[x].val > (uint32_t)temps[y].val;
++            }
++            break;
++        case 64:
++            switch (c) {
++            case TCG_COND_EQ:
++                return (uint64_t)temps[x].val == (uint64_t)temps[y].val;
++            case TCG_COND_NE:
++                return (uint64_t)temps[x].val != (uint64_t)temps[y].val;
++            case TCG_COND_LT:
++                return (int64_t)temps[x].val < (int64_t)temps[y].val;
++            case TCG_COND_GE:
++                return (int64_t)temps[x].val >= (int64_t)temps[y].val;
++            case TCG_COND_LE:
++                return (int64_t)temps[x].val <= (int64_t)temps[y].val;
++            case TCG_COND_GT:
++                return (int64_t)temps[x].val > (int64_t)temps[y].val;
++            case TCG_COND_LTU:
++                return (uint64_t)temps[x].val < (uint64_t)temps[y].val;
++            case TCG_COND_GEU:
++                return (uint64_t)temps[x].val >= (uint64_t)temps[y].val;
++            case TCG_COND_LEU:
++                return (uint64_t)temps[x].val <= (uint64_t)temps[y].val;
++            case TCG_COND_GTU:
++                return (uint64_t)temps[x].val > (uint64_t)temps[y].val;
++            }
++            break;
++        }
++    } else if (temps_are_copies(x, y)) {
+         switch (c) {
+-        case TCG_COND_EQ:
+-            return (uint32_t)x == (uint32_t)y;
+-        case TCG_COND_NE:
+-            return (uint32_t)x != (uint32_t)y;
+-        case TCG_COND_LT:
+-            return (int32_t)x < (int32_t)y;
+-        case TCG_COND_GE:
+-            return (int32_t)x >= (int32_t)y;
+-        case TCG_COND_LE:
+-            return (int32_t)x <= (int32_t)y;
+         case TCG_COND_GT:
+-            return (int32_t)x > (int32_t)y;
+         case TCG_COND_LTU:
+-            return (uint32_t)x < (uint32_t)y;
+-        case TCG_COND_GEU:
+-            return (uint32_t)x >= (uint32_t)y;
+-        case TCG_COND_LEU:
+-            return (uint32_t)x <= (uint32_t)y;
++        case TCG_COND_LT:
+         case TCG_COND_GTU:
+-            return (uint32_t)x > (uint32_t)y;
+-        }
+-        break;
+-    case 64:
+-        switch (c) {
+-        case TCG_COND_EQ:
+-            return (uint64_t)x == (uint64_t)y;
+         case TCG_COND_NE:
+-            return (uint64_t)x != (uint64_t)y;
+-        case TCG_COND_LT:
+-            return (int64_t)x < (int64_t)y;
++            return 0;
+         case TCG_COND_GE:
+-            return (int64_t)x >= (int64_t)y;
++        case TCG_COND_GEU:
+         case TCG_COND_LE:
+-            return (int64_t)x <= (int64_t)y;
+-        case TCG_COND_GT:
+-            return (int64_t)x > (int64_t)y;
++        case TCG_COND_LEU:
++        case TCG_COND_EQ:
++            return 1;
++        }
++    } else if (temps[y].state == TCG_TEMP_CONST && temps[y].val == 0) {
++        switch (c) {
+         case TCG_COND_LTU:
+-            return (uint64_t)x < (uint64_t)y;
++            return 0;
+         case TCG_COND_GEU:
+-            return (uint64_t)x >= (uint64_t)y;
+-        case TCG_COND_LEU:
+-            return (uint64_t)x <= (uint64_t)y;
+-        case TCG_COND_GTU:
+-            return (uint64_t)x > (uint64_t)y;
++            return 1;
++        default:
++            return 2;
+         }
+-        break;
++    } else {
++        return 2;
+     }
+ 
+     fprintf(stderr,
+@@ -636,11 +666,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             args += 3;
+             break;
+         CASE_OP_32_64(setcond):
+-            if (temps[args[1]].state == TCG_TEMP_CONST
+-                && temps[args[2]].state == TCG_TEMP_CONST) {
++            tmp = do_constant_folding_cond(op, args[1], args[2], args[3]);
++            if (tmp != 2) {
+                 gen_opc_buf[op_index] = op_to_movi(op);
+-                tmp = do_constant_folding_cond(op, temps[args[1]].val,
+-                                               temps[args[2]].val, args[3]);
+                 tcg_opt_gen_movi(gen_args, args[0], tmp);
+                 gen_args += 2;
+             } else {
+@@ -654,10 +682,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             args += 4;
+             break;
+         CASE_OP_32_64(brcond):
+-            if (temps[args[0]].state == TCG_TEMP_CONST
+-                && temps[args[1]].state == TCG_TEMP_CONST) {
+-                if (do_constant_folding_cond(op, temps[args[0]].val,
+-                                             temps[args[1]].val, args[2])) {
++            tmp = do_constant_folding_cond(op, args[0], args[1], args[2]);
++            if (tmp != 2) {
++                if (tmp) {
+                     memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info));
+                     gen_opc_buf[op_index] = INDEX_op_br;
+                     gen_args[0] = args[3];
+@@ -677,10 +704,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             args += 4;
+             break;
+         CASE_OP_32_64(movcond):
+-            if (temps[args[1]].state == TCG_TEMP_CONST
+-                && temps[args[2]].state == TCG_TEMP_CONST) {
+-                tmp = do_constant_folding_cond(op, temps[args[1]].val,
+-                                               temps[args[2]].val, args[5]);
++            tmp = do_constant_folding_cond(op, args[1], args[2], args[5]);
++            if (tmp != 2) {
+                 if (temps_are_copies(args[0], args[4-tmp])) {
+                     gen_opc_buf[op_index] = INDEX_op_nop;
+                 } else if (temps[args[4-tmp]].state == TCG_TEMP_CONST) {
+-- 
+1.7.12.1
+
diff --git a/0075-tcg-optimize-prefer-the-op-a-a-b-form-for-commutativ.patch b/0075-tcg-optimize-prefer-the-op-a-a-b-form-for-commutativ.patch
new file mode 100644
index 0000000..4cb003b
--- /dev/null
+++ b/0075-tcg-optimize-prefer-the-op-a-a-b-form-for-commutativ.patch
@@ -0,0 +1,38 @@
+From a0b71ad6a3f8aeb8b5ea6d112a7afeadc7c004a4 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Wed, 19 Sep 2012 22:00:22 +0200
+Subject: [PATCH] tcg/optimize: prefer the "op a, a, b" form for commutative
+ ops
+
+The "op a, a, b" form is better handled on non-RISC host than the "op
+a, b, a" form, so swap the arguments to this form when possible, and
+when b is not a constant.
+
+This reduces the number of generated instructions by a tiny bit.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index abe016a..c8ae50b 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -434,7 +434,10 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+         CASE_OP_32_64(eqv):
+         CASE_OP_32_64(nand):
+         CASE_OP_32_64(nor):
+-            if (temps[args[1]].state == TCG_TEMP_CONST) {
++            /* Prefer the constant in second argument, and then the form
++               op a, a, b, which is better handled on non-RISC hosts. */
++            if (temps[args[1]].state == TCG_TEMP_CONST || (args[0] == args[2]
++                && temps[args[2]].state != TCG_TEMP_CONST)) {
+                 tmp = args[1];
+                 args[1] = args[2];
+                 args[2] = tmp;
+-- 
+1.7.12.1
+
diff --git a/0076-tcg-remove-ifdef-endif-around-TCGOpcode-tests.patch b/0076-tcg-remove-ifdef-endif-around-TCGOpcode-tests.patch
new file mode 100644
index 0000000..214a022
--- /dev/null
+++ b/0076-tcg-remove-ifdef-endif-around-TCGOpcode-tests.patch
@@ -0,0 +1,68 @@
+From 3942910a66f682b98ac53ac2d2fba65b9c75eefd Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 10:02:45 +0200
+Subject: [PATCH] tcg: remove #ifdef #endif around TCGOpcode tests
+
+Commit 25c4d9cc changed all TCGOpcode enums to be available, so we don't
+need to #ifdef #endif the one that are available only on some targets.
+This makes the code easier to read.
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/tcg.c | 13 +------------
+ 1 file changed, 1 insertion(+), 12 deletions(-)
+
+diff --git a/tcg/tcg.c b/tcg/tcg.c
+index 24ce830..93421cd 100644
+--- a/tcg/tcg.c
++++ b/tcg/tcg.c
+@@ -937,11 +937,7 @@ void tcg_dump_ops(TCGContext *s)
+                                                        args[nb_oargs + i]));
+                 }
+             }
+-        } else if (c == INDEX_op_movi_i32 
+-#if TCG_TARGET_REG_BITS == 64
+-                   || c == INDEX_op_movi_i64
+-#endif
+-                   ) {
++        } else if (c == INDEX_op_movi_i32 || c == INDEX_op_movi_i64) {
+             tcg_target_ulong val;
+             TCGHelperInfo *th;
+ 
+@@ -993,14 +989,11 @@ void tcg_dump_ops(TCGContext *s)
+             case INDEX_op_brcond_i32:
+             case INDEX_op_setcond_i32:
+             case INDEX_op_movcond_i32:
+-#if TCG_TARGET_REG_BITS == 32
+             case INDEX_op_brcond2_i32:
+             case INDEX_op_setcond2_i32:
+-#else
+             case INDEX_op_brcond_i64:
+             case INDEX_op_setcond_i64:
+             case INDEX_op_movcond_i64:
+-#endif
+                 if (args[k] < ARRAY_SIZE(cond_name) && cond_name[args[k]]) {
+                     qemu_log(",%s", cond_name[args[k++]]);
+                 } else {
+@@ -2095,16 +2088,12 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
+ #endif
+         switch(opc) {
+         case INDEX_op_mov_i32:
+-#if TCG_TARGET_REG_BITS == 64
+         case INDEX_op_mov_i64:
+-#endif
+             dead_args = s->op_dead_args[op_index];
+             tcg_reg_alloc_mov(s, def, args, dead_args);
+             break;
+         case INDEX_op_movi_i32:
+-#if TCG_TARGET_REG_BITS == 64
+         case INDEX_op_movi_i64:
+-#endif
+             tcg_reg_alloc_movi(s, args);
+             break;
+         case INDEX_op_debug_insn_start:
+-- 
+1.7.12.1
+
diff --git a/0077-tcg-optimize-add-constant-folding-for-deposit.patch b/0077-tcg-optimize-add-constant-folding-for-deposit.patch
new file mode 100644
index 0000000..63566ce
--- /dev/null
+++ b/0077-tcg-optimize-add-constant-folding-for-deposit.patch
@@ -0,0 +1,46 @@
+From 04edfbcf025b5588e0f3b86c74356a4339745f35 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Fri, 21 Sep 2012 11:07:29 +0200
+Subject: [PATCH] tcg/optimize: add constant folding for deposit
+
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/optimize.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/tcg/optimize.c b/tcg/optimize.c
+index c8ae50b..35532a1 100644
+--- a/tcg/optimize.c
++++ b/tcg/optimize.c
+@@ -668,6 +668,26 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
+             }
+             args += 3;
+             break;
++        CASE_OP_32_64(deposit):
++            if (temps[args[1]].state == TCG_TEMP_CONST
++                && temps[args[2]].state == TCG_TEMP_CONST) {
++                gen_opc_buf[op_index] = op_to_movi(op);
++                tmp = ((1ull << args[4]) - 1);
++                tmp = (temps[args[1]].val & ~(tmp << args[3]))
++                      | ((temps[args[2]].val & tmp) << args[3]);
++                tcg_opt_gen_movi(gen_args, args[0], tmp);
++                gen_args += 2;
++            } else {
++                reset_temp(args[0]);
++                gen_args[0] = args[0];
++                gen_args[1] = args[1];
++                gen_args[2] = args[2];
++                gen_args[3] = args[3];
++                gen_args[4] = args[4];
++                gen_args += 5;
++            }
++            args += 5;
++            break;
+         CASE_OP_32_64(setcond):
+             tmp = do_constant_folding_cond(op, args[1], args[2], args[3]);
+             if (tmp != 2) {
+-- 
+1.7.12.1
+
diff --git a/0078-tcg-README-document-tcg_gen_goto_tb-restrictions.patch b/0078-tcg-README-document-tcg_gen_goto_tb-restrictions.patch
new file mode 100644
index 0000000..b47b1f1
--- /dev/null
+++ b/0078-tcg-README-document-tcg_gen_goto_tb-restrictions.patch
@@ -0,0 +1,33 @@
+From 08de143bdd34e906c3e89443cb6b24665f7c088d Mon Sep 17 00:00:00 2001
+From: Max Filippov <jcmvbkbc at gmail.com>
+Date: Fri, 21 Sep 2012 04:18:07 +0400
+Subject: [PATCH] tcg/README: document tcg_gen_goto_tb restrictions
+
+See
+http://lists.nongnu.org/archive/html/qemu-devel/2012-09/msg03196.html
+for the whole story.
+
+Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/README | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/tcg/README b/tcg/README
+index d03ae05..33783ee 100644
+--- a/tcg/README
++++ b/tcg/README
+@@ -392,7 +392,8 @@ Exit the current TB and return the value t0 (word type).
+ 
+ Exit the current TB and jump to the TB index 'index' (constant) if the
+ current TB was linked to this TB. Otherwise execute the next
+-instructions.
++instructions. Only indices 0 and 1 are valid and tcg_gen_goto_tb may be issued
++at most once with each slot index per TB.
+ 
+ * qemu_ld8u t0, t1, flags
+ qemu_ld8s t0, t1, flags
+-- 
+1.7.12.1
+
diff --git a/0079-w64-Fix-TCG-helper-functions-with-5-arguments.patch b/0079-w64-Fix-TCG-helper-functions-with-5-arguments.patch
new file mode 100644
index 0000000..3cea914
--- /dev/null
+++ b/0079-w64-Fix-TCG-helper-functions-with-5-arguments.patch
@@ -0,0 +1,57 @@
+From e35e8b9bb446ff2693962151b8c80c5c88294959 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Thu, 13 Sep 2012 19:37:43 +0200
+Subject: [PATCH] w64: Fix TCG helper functions with 5 arguments
+
+TCG uses 6 registers for function arguments on 64 bit Linux hosts,
+but only 4 registers on W64 hosts.
+
+Commit 2999a0b20074a7e4a58f56572bb1436749368f59 increased the number
+of arguments for some important helper functions from 4 to 5
+which triggered a bug for W64 hosts: QEMU aborts when executing
+helper_lcall_real in the guest's BIOS because function
+tcg_target_get_call_iarg_regs_count always returned 6.
+
+As W64 has only 4 registers for arguments, the 5th argument must be
+passed on the stack using a correct stack offset.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/i386/tcg-target.c | 2 +-
+ tcg/i386/tcg-target.h | 4 ++++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
+index aa1fa9f..85c6b81 100644
+--- a/tcg/i386/tcg-target.c
++++ b/tcg/i386/tcg-target.c
+@@ -118,7 +118,7 @@ static void patch_reloc(uint8_t *code_ptr, int type,
+ static inline int tcg_target_get_call_iarg_regs_count(int flags)
+ {
+     if (TCG_TARGET_REG_BITS == 64) {
+-        return 6;
++        return ARRAY_SIZE(tcg_target_call_iarg_regs);
+     }
+ 
+     return 0;
+diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
+index b356d76..ace63ba 100644
+--- a/tcg/i386/tcg-target.h
++++ b/tcg/i386/tcg-target.h
+@@ -67,7 +67,11 @@ typedef enum {
+ /* used for function call generation */
+ #define TCG_REG_CALL_STACK TCG_REG_ESP 
+ #define TCG_TARGET_STACK_ALIGN 16
++#if defined(_WIN64)
++#define TCG_TARGET_CALL_STACK_OFFSET 32
++#else
+ #define TCG_TARGET_CALL_STACK_OFFSET 0
++#endif
+ 
+ /* optional instructions */
+ #define TCG_TARGET_HAS_div2_i32         1
+-- 
+1.7.12.1
+
diff --git a/0080-tcg-ppc32-Implement-movcond32.patch b/0080-tcg-ppc32-Implement-movcond32.patch
new file mode 100644
index 0000000..2877379
--- /dev/null
+++ b/0080-tcg-ppc32-Implement-movcond32.patch
@@ -0,0 +1,137 @@
+From d65d20819ac52207befffa9a7aa858cc7de9cbaf Mon Sep 17 00:00:00 2001
+From: malc <av1474 at comtv.ru>
+Date: Sat, 22 Sep 2012 19:14:33 +0400
+Subject: [PATCH] tcg/ppc32: Implement movcond32
+
+Thanks to Richard Henderson
+
+Signed-off-by: malc <av1474 at comtv.ru>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/ppc/tcg-target.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ tcg/ppc/tcg-target.h |  2 +-
+ 2 files changed, 76 insertions(+), 1 deletion(-)
+
+diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
+index 26c4b33..8f8b193 100644
+--- a/tcg/ppc/tcg-target.c
++++ b/tcg/ppc/tcg-target.c
+@@ -390,6 +390,7 @@ static int tcg_target_const_match(tcg_target_long val,
+ #define ORC    XO31(412)
+ #define EQV    XO31(284)
+ #define NAND   XO31(476)
++#define ISEL   XO31( 15)
+ 
+ #define LBZX   XO31( 87)
+ #define LHZX   XO31(279)
+@@ -1269,6 +1270,72 @@ static void tcg_out_setcond2 (TCGContext *s, const TCGArg *args,
+         );
+ }
+ 
++static void tcg_out_movcond (TCGContext *s, TCGCond cond,
++                             TCGArg dest,
++                             TCGArg c1, TCGArg c2,
++                             TCGArg v1, TCGArg v2,
++                             int const_c2)
++{
++    tcg_out_cmp (s, cond, c1, c2, const_c2, 7);
++
++    if (1) {
++        /* At least here on 7747A bit twiddling hacks are outperformed
++           by jumpy code (the testing was not scientific) */
++        if (dest == v2) {
++            cond = tcg_invert_cond (cond);
++            v2 = v1;
++        }
++        else {
++            if (dest != v1) {
++                tcg_out_mov (s, TCG_TYPE_I32, dest, v1);
++            }
++        }
++        /* Branch forward over one insn */
++        tcg_out32 (s, tcg_to_bc[cond] | 8);
++        tcg_out_mov (s, TCG_TYPE_I32, dest, v2);
++    }
++    else {
++        /* isel version, "if (1)" above should be replaced once a way
++           to figure out availability of isel on the underlying
++           hardware is found */
++        int tab, bc;
++
++        switch (cond) {
++        case TCG_COND_EQ:
++            tab = TAB (dest, v1, v2);
++            bc = CR_EQ;
++            break;
++        case TCG_COND_NE:
++            tab = TAB (dest, v2, v1);
++            bc = CR_EQ;
++            break;
++        case TCG_COND_LTU:
++        case TCG_COND_LT:
++            tab = TAB (dest, v1, v2);
++            bc = CR_LT;
++            break;
++        case TCG_COND_GEU:
++        case TCG_COND_GE:
++            tab = TAB (dest, v2, v1);
++            bc = CR_LT;
++            break;
++        case TCG_COND_LEU:
++        case TCG_COND_LE:
++            tab = TAB (dest, v2, v1);
++            bc = CR_GT;
++            break;
++        case TCG_COND_GTU:
++        case TCG_COND_GT:
++            tab = TAB (dest, v1, v2);
++            bc = CR_GT;
++            break;
++        default:
++            tcg_abort ();
++        }
++        tcg_out32 (s, ISEL | tab | ((bc + 28) << 6));
++    }
++}
++
+ static void tcg_out_brcond (TCGContext *s, TCGCond cond,
+                             TCGArg arg1, TCGArg arg2, int const_arg2,
+                             int label_index)
+@@ -1826,6 +1893,13 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+             );
+         break;
+ 
++    case INDEX_op_movcond_i32:
++        tcg_out_movcond (s, args[5], args[0],
++                         args[1], args[2],
++                         args[3], args[4],
++                         const_args[2]);
++        break;
++
+     default:
+         tcg_dump_ops (s);
+         tcg_abort ();
+@@ -1922,6 +1996,7 @@ static const TCGTargetOpDef ppc_op_defs[] = {
+     { INDEX_op_ext16u_i32, { "r", "r" } },
+ 
+     { INDEX_op_deposit_i32, { "r", "0", "r" } },
++    { INDEX_op_movcond_i32, { "r", "r", "ri", "r", "r" } },
+ 
+     { -1 },
+ };
+diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
+index 177eea1..3259d89 100644
+--- a/tcg/ppc/tcg-target.h
++++ b/tcg/ppc/tcg-target.h
+@@ -92,7 +92,7 @@ typedef enum {
+ #define TCG_TARGET_HAS_nand_i32         1
+ #define TCG_TARGET_HAS_nor_i32          1
+ #define TCG_TARGET_HAS_deposit_i32      1
+-#define TCG_TARGET_HAS_movcond_i32      0
++#define TCG_TARGET_HAS_movcond_i32      1
+ 
+ #define TCG_AREG0 TCG_REG_R27
+ 
+-- 
+1.7.12.1
+
diff --git a/0081-tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch b/0081-tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch
new file mode 100644
index 0000000..f84d719
--- /dev/null
+++ b/0081-tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch
@@ -0,0 +1,30 @@
+From da65fa6c51ef1c999ffc75a162e95285d4cb915b Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Sat, 24 Mar 2012 21:30:20 +0100
+Subject: [PATCH] tcg-sparc: Hack in qemu_ld/st64 for 32-bit.
+
+Not actually implemented, but at least we avoid the tcg assert at startup.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/sparc/tcg-target.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index baed3b4..608fc46 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -1556,6 +1556,9 @@ static const TCGTargetOpDef sparc_op_defs[] = {
+ 
+     { INDEX_op_brcond_i64, { "r", "rJ" } },
+     { INDEX_op_setcond_i64, { "r", "r", "rJ" } },
++#else
++    { INDEX_op_qemu_ld64, { "L", "L", "L" } },
++    { INDEX_op_qemu_st64, { "L", "L", "L" } },
+ #endif
+     { -1 },
+ };
+-- 
+1.7.12.1
+
diff --git a/0082-tcg-sparc-Fix-ADDX-opcode.patch b/0082-tcg-sparc-Fix-ADDX-opcode.patch
new file mode 100644
index 0000000..af3a51a
--- /dev/null
+++ b/0082-tcg-sparc-Fix-ADDX-opcode.patch
@@ -0,0 +1,27 @@
+From b92aceeb9604c74e4a66db8ea5dd399d892e94bc Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 23 Mar 2012 23:57:12 +0100
+Subject: [PATCH] tcg-sparc: Fix ADDX opcode.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/sparc/tcg-target.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index 608fc46..0a19313 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -236,7 +236,7 @@ static inline int tcg_target_const_match(tcg_target_long val,
+ #define ARITH_XOR  (INSN_OP(2) | INSN_OP3(0x03))
+ #define ARITH_SUB  (INSN_OP(2) | INSN_OP3(0x04))
+ #define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
+-#define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x10))
++#define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x08))
+ #define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
+ #define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
+ #define ARITH_UDIV (INSN_OP(2) | INSN_OP3(0x0e))
+-- 
+1.7.12.1
+
diff --git a/0083-tcg-sparc-Don-t-MAP_FIXED-on-top-of-the-program.patch b/0083-tcg-sparc-Don-t-MAP_FIXED-on-top-of-the-program.patch
new file mode 100644
index 0000000..3e7946c
--- /dev/null
+++ b/0083-tcg-sparc-Don-t-MAP_FIXED-on-top-of-the-program.patch
@@ -0,0 +1,45 @@
+From 59aadb4f5b15eff968ed00ad29816ac19bef507d Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 10:40:48 -0700
+Subject: [PATCH] tcg-sparc: Don't MAP_FIXED on top of the program
+
+The address we pick in sparc64.ld is also 0x60000000, so doing a fixed map
+on top of that is guaranteed to blow up.  Choosing 0x40000000 is exactly
+right for the max of code_gen_buffer_size set below.
+
+No need to ever use MAP_FIXED.  While getting our desired address helps
+optimize the generated code, we won't fail if we don't get it.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ exec.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/exec.c b/exec.c
+index 5834766..871a68a 100644
+--- a/exec.c
++++ b/exec.c
+@@ -543,8 +543,7 @@ static void code_gen_alloc(unsigned long tb_size)
+             code_gen_buffer_size = (800 * 1024 * 1024);
+ #elif defined(__sparc_v9__)
+         // Map the buffer below 2G, so we can use direct calls and branches
+-        flags |= MAP_FIXED;
+-        start = (void *) 0x60000000UL;
++        start = (void *) 0x40000000UL;
+         if (code_gen_buffer_size > (512 * 1024 * 1024))
+             code_gen_buffer_size = (512 * 1024 * 1024);
+ #elif defined(__arm__)
+@@ -584,8 +583,7 @@ static void code_gen_alloc(unsigned long tb_size)
+             code_gen_buffer_size = (800 * 1024 * 1024);
+ #elif defined(__sparc_v9__)
+         // Map the buffer below 2G, so we can use direct calls and branches
+-        flags |= MAP_FIXED;
+-        addr = (void *) 0x60000000UL;
++        addr = (void *) 0x40000000UL;
+         if (code_gen_buffer_size > (512 * 1024 * 1024)) {
+             code_gen_buffer_size = (512 * 1024 * 1024);
+         }
+-- 
+1.7.12.1
+
diff --git a/0084-tcg-sparc-Assume-v9-cpu-always-i.e.-force-v8plus-in-.patch b/0084-tcg-sparc-Assume-v9-cpu-always-i.e.-force-v8plus-in-.patch
new file mode 100644
index 0000000..a68474a
--- /dev/null
+++ b/0084-tcg-sparc-Assume-v9-cpu-always-i.e.-force-v8plus-in-.patch
@@ -0,0 +1,286 @@
+From cf873edf4227be439a9ffa5abb3da61ff1fd6527 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 10:34:21 -0700
+Subject: [PATCH] tcg-sparc: Assume v9 cpu always, i.e. force v8plus in 32-bit
+ mode.
+
+Current code doesn't actually work in 32-bit mode at all.  Since
+no one really noticed, drop the complication of v7 and v8 cpus.
+Eliminate the --sparc_cpu configure option and standardize macro
+testing on TCG_TARGET_REG_BITS / HOST_LONG_BITS
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure              | 40 ++++------------------------------------
+ disas.c                |  2 --
+ exec.c                 |  6 +++---
+ qemu-timer.h           |  8 +++++---
+ tcg/sparc/tcg-target.c | 20 +++++---------------
+ tcg/sparc/tcg-target.h |  7 ++++---
+ tcg/tcg.c              |  3 ++-
+ 7 files changed, 23 insertions(+), 63 deletions(-)
+
+diff --git a/configure b/configure
+index 816f0f9..0590f16 100755
+--- a/configure
++++ b/configure
+@@ -111,7 +111,6 @@ source_path=`dirname "$0"`
+ cpu=""
+ interp_prefix="/usr/gnemul/qemu-%M"
+ static="no"
+-sparc_cpu=""
+ cross_prefix=""
+ audio_drv_list=""
+ audio_card_list="ac97 es1370 sb16 hda"
+@@ -249,21 +248,6 @@ for opt do
+   ;;
+   --disable-debug-info) debug_info="no"
+   ;;
+-  --sparc_cpu=*)
+-    sparc_cpu="$optarg"
+-    case $sparc_cpu in
+-    v7|v8|v8plus|v8plusa)
+-      cpu="sparc"
+-    ;;
+-    v9)
+-      cpu="sparc64"
+-    ;;
+-    *)
+-      echo "undefined SPARC architecture. Exiting";
+-      exit 1
+-    ;;
+-    esac
+-  ;;
+   esac
+ done
+ # OS specific
+@@ -351,8 +335,6 @@ elif check_define __i386__ ; then
+ elif check_define __x86_64__ ; then
+   cpu="x86_64"
+ elif check_define __sparc__ ; then
+-  # We can't check for 64 bit (when gcc is biarch) or V8PLUSA
+-  # They must be specified using --sparc_cpu
+   if check_define __arch64__ ; then
+     cpu="sparc64"
+   else
+@@ -798,8 +780,6 @@ for opt do
+   ;;
+   --enable-uname-release=*) uname_release="$optarg"
+   ;;
+-  --sparc_cpu=*)
+-  ;;
+   --enable-werror) werror="yes"
+   ;;
+   --disable-werror) werror="no"
+@@ -883,31 +863,19 @@ for opt do
+   esac
+ done
+ 
+-#
+-# If cpu ~= sparc and  sparc_cpu hasn't been defined, plug in the right
+-# QEMU_CFLAGS/LDFLAGS (assume sparc_v8plus for 32-bit and sparc_v9 for 64-bit)
+-#
+ host_guest_base="no"
+ case "$cpu" in
+-    sparc) case $sparc_cpu in
+-           v7|v8)
+-             QEMU_CFLAGS="-mcpu=${sparc_cpu} -D__sparc_${sparc_cpu}__ $QEMU_CFLAGS"
+-           ;;
+-           v8plus|v8plusa)
+-             QEMU_CFLAGS="-mcpu=ultrasparc -D__sparc_${sparc_cpu}__ $QEMU_CFLAGS"
+-           ;;
+-           *) # sparc_cpu not defined in the command line
+-             QEMU_CFLAGS="-mcpu=ultrasparc -D__sparc_v8plus__ $QEMU_CFLAGS"
+-           esac
++    sparc)
+            LDFLAGS="-m32 $LDFLAGS"
+-           QEMU_CFLAGS="-m32 -ffixed-g2 -ffixed-g3 $QEMU_CFLAGS"
++           QEMU_CFLAGS="-m32 -mcpu=ultrasparc $QEMU_CFLAGS"
++           QEMU_CFLAGS="-ffixed-g2 -ffixed-g3 $QEMU_CFLAGS"
+            if test "$solaris" = "no" ; then
+              QEMU_CFLAGS="-ffixed-g1 -ffixed-g6 $QEMU_CFLAGS"
+            fi
+            ;;
+     sparc64)
+-           QEMU_CFLAGS="-m64 -mcpu=ultrasparc -D__sparc_v9__ $QEMU_CFLAGS"
+            LDFLAGS="-m64 $LDFLAGS"
++           QEMU_CFLAGS="-m64 -mcpu=ultrasparc $QEMU_CFLAGS"
+            QEMU_CFLAGS="-ffixed-g5 -ffixed-g6 -ffixed-g7 $QEMU_CFLAGS"
+            if test "$solaris" != "no" ; then
+              QEMU_CFLAGS="-ffixed-g1 $QEMU_CFLAGS"
+diff --git a/disas.c b/disas.c
+index 7b2acc9..b801c8f 100644
+--- a/disas.c
++++ b/disas.c
+@@ -316,9 +316,7 @@ void disas(FILE *out, void *code, unsigned long size)
+     print_insn = print_insn_alpha;
+ #elif defined(__sparc__)
+     print_insn = print_insn_sparc;
+-#if defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
+     disasm_info.mach = bfd_mach_sparc_v9b;
+-#endif
+ #elif defined(__arm__)
+     print_insn = print_insn_arm;
+ #elif defined(__MIPSEB__)
+diff --git a/exec.c b/exec.c
+index 871a68a..ad175db 100644
+--- a/exec.c
++++ b/exec.c
+@@ -86,7 +86,7 @@ static int nb_tbs;
+ /* any access to the tbs or the page table must use this lock */
+ spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
+ 
+-#if defined(__arm__) || defined(__sparc_v9__)
++#if defined(__arm__) || defined(__sparc__)
+ /* The prologue must be reachable with a direct jump. ARM and Sparc64
+  have limited branch ranges (possibly also PPC) so place it in a
+  section close to code segment. */
+@@ -541,7 +541,7 @@ static void code_gen_alloc(unsigned long tb_size)
+         /* Cannot map more than that */
+         if (code_gen_buffer_size > (800 * 1024 * 1024))
+             code_gen_buffer_size = (800 * 1024 * 1024);
+-#elif defined(__sparc_v9__)
++#elif defined(__sparc__) && HOST_LONG_BITS == 64
+         // Map the buffer below 2G, so we can use direct calls and branches
+         start = (void *) 0x40000000UL;
+         if (code_gen_buffer_size > (512 * 1024 * 1024))
+@@ -581,7 +581,7 @@ static void code_gen_alloc(unsigned long tb_size)
+         /* Cannot map more than that */
+         if (code_gen_buffer_size > (800 * 1024 * 1024))
+             code_gen_buffer_size = (800 * 1024 * 1024);
+-#elif defined(__sparc_v9__)
++#elif defined(__sparc__) && HOST_LONG_BITS == 64
+         // Map the buffer below 2G, so we can use direct calls and branches
+         addr = (void *) 0x40000000UL;
+         if (code_gen_buffer_size > (512 * 1024 * 1024)) {
+diff --git a/qemu-timer.h b/qemu-timer.h
+index f8af595..da7e97c 100644
+--- a/qemu-timer.h
++++ b/qemu-timer.h
+@@ -218,7 +218,7 @@ static inline int64_t cpu_get_real_ticks(void)
+     return val;
+ }
+ 
+-#elif defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
++#elif defined(__sparc__)
+ 
+ static inline int64_t cpu_get_real_ticks (void)
+ {
+@@ -227,6 +227,8 @@ static inline int64_t cpu_get_real_ticks (void)
+     asm volatile("rd %%tick,%0" : "=r"(rval));
+     return rval;
+ #else
++    /* We need an %o or %g register for this.  For recent enough gcc
++       there is an "h" constraint for that.  Don't bother with that.  */
+     union {
+         uint64_t i64;
+         struct {
+@@ -234,8 +236,8 @@ static inline int64_t cpu_get_real_ticks (void)
+             uint32_t low;
+         }       i32;
+     } rval;
+-    asm volatile("rd %%tick,%1; srlx %1,32,%0"
+-                 : "=r"(rval.i32.high), "=r"(rval.i32.low));
++    asm volatile("rd %%tick,%%g1; srlx %%g1,32,%0; mov %%g1,%1"
++                 : "=r"(rval.i32.high), "=r"(rval.i32.low) : : "g1");
+     return rval.i64;
+ #endif
+ }
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index 0a19313..23c2fda 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -621,18 +621,10 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
+ 
+     default:
+         tcg_out_cmp(s, c1, c2, c2const);
+-#if defined(__sparc_v9__) || defined(__sparc_v8plus__)
+         tcg_out_movi_imm13(s, ret, 0);
+-        tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret)
+-                   | INSN_RS1(tcg_cond_to_bcond[cond])
+-                   | MOVCC_ICC | INSN_IMM11(1));
+-#else
+-        t = gen_new_label();
+-        tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), t);
+-        tcg_out_movi_imm13(s, ret, 1);
+-        tcg_out_movi_imm13(s, ret, 0);
+-        tcg_out_label(s, t, s->code_ptr);
+-#endif
++        tcg_out32(s, ARITH_MOVCC | INSN_RD(ret)
++                  | INSN_RS1(tcg_cond_to_bcond[cond])
++                  | MOVCC_ICC | INSN_IMM11(1));
+         return;
+     }
+ 
+@@ -742,7 +734,7 @@ static const void * const qemu_st_helpers[4] = {
+ #endif
+ #endif
+ 
+-#ifdef __arch64__
++#if TCG_TARGET_REG_BITS == 64
+ #define HOST_LD_OP LDX
+ #define HOST_ST_OP STX
+ #define HOST_SLL_OP SHIFT_SLLX
+@@ -1600,11 +1592,9 @@ static void tcg_target_init(TCGContext *s)
+ 
+ #if TCG_TARGET_REG_BITS == 64
+ # define ELF_HOST_MACHINE  EM_SPARCV9
+-#elif defined(__sparc_v8plus__)
++#else
+ # define ELF_HOST_MACHINE  EM_SPARC32PLUS
+ # define ELF_HOST_FLAGS    EF_SPARC_32PLUS
+-#else
+-# define ELF_HOST_MACHINE  EM_SPARC
+ #endif
+ 
+ typedef struct {
+diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
+index d762574..adca1d2 100644
+--- a/tcg/sparc/tcg-target.h
++++ b/tcg/sparc/tcg-target.h
+@@ -67,7 +67,8 @@ typedef enum {
+ 
+ /* used for function call generation */
+ #define TCG_REG_CALL_STACK TCG_REG_I6
+-#ifdef __arch64__
++
++#if TCG_TARGET_REG_BITS == 64
+ // Reserve space for AREG0
+ #define TCG_TARGET_STACK_MINFRAME (176 + 4 * (int)sizeof(long) + \
+                                    TCG_STATIC_CALL_ARGS_SIZE)
+@@ -81,7 +82,7 @@ typedef enum {
+ #define TCG_TARGET_STACK_ALIGN 8
+ #endif
+ 
+-#ifdef __arch64__
++#if TCG_TARGET_REG_BITS == 64
+ #define TCG_TARGET_EXTEND_ARGS 1
+ #endif
+ 
+@@ -129,7 +130,7 @@ typedef enum {
+ 
+ #ifdef CONFIG_SOLARIS
+ #define TCG_AREG0 TCG_REG_G2
+-#elif defined(__sparc_v9__)
++#elif HOST_LONG_BITS == 64
+ #define TCG_AREG0 TCG_REG_G5
+ #else
+ #define TCG_AREG0 TCG_REG_G6
+diff --git a/tcg/tcg.c b/tcg/tcg.c
+index 93421cd..16c4e1d 100644
+--- a/tcg/tcg.c
++++ b/tcg/tcg.c
+@@ -1450,7 +1450,8 @@ static void temp_allocate_frame(TCGContext *s, int temp)
+ {
+     TCGTemp *ts;
+     ts = &s->temps[temp];
+-#ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */
++#if !(defined(__sparc__) && TCG_TARGET_REG_BITS == 64)
++    /* Sparc64 stack is accessed with offset of 2047 */
+     s->current_frame_offset = (s->current_frame_offset +
+                                (tcg_target_long)sizeof(tcg_target_long) - 1) &
+         ~(sizeof(tcg_target_long) - 1);
+-- 
+1.7.12.1
+
diff --git a/0085-tcg-sparc-Fix-qemu_ld-st-to-handle-32-bit-host.patch b/0085-tcg-sparc-Fix-qemu_ld-st-to-handle-32-bit-host.patch
new file mode 100644
index 0000000..beaf45b
--- /dev/null
+++ b/0085-tcg-sparc-Fix-qemu_ld-st-to-handle-32-bit-host.patch
@@ -0,0 +1,967 @@
+From 138dfa905538bf918af390ff365a27de49364578 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 23 Mar 2012 23:27:39 +0100
+Subject: [PATCH] tcg-sparc: Fix qemu_ld/st to handle 32-bit host.
+
+At the same time, split out the tlb load logic to a new function.
+Fixes the cases of two data registers and two address registers.
+Fixes the signature of, and adds missing, qemu_ld/st opcodes.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/sparc/tcg-target.c | 777 ++++++++++++++++++++++---------------------------
+ 1 file changed, 348 insertions(+), 429 deletions(-)
+
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index 23c2fda..d89c19b 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -59,8 +59,6 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
+ };
+ #endif
+ 
+-#define ARG_OFFSET 1
+-
+ static const int tcg_target_reg_alloc_order[] = {
+     TCG_REG_L0,
+     TCG_REG_L1,
+@@ -288,6 +286,16 @@ static inline int tcg_target_const_match(tcg_target_long val,
+ #define ASI_PRIMARY_LITTLE 0x88
+ #endif
+ 
++#define LDUH_LE    (LDUHA | INSN_ASI(ASI_PRIMARY_LITTLE))
++#define LDSH_LE    (LDSHA | INSN_ASI(ASI_PRIMARY_LITTLE))
++#define LDUW_LE    (LDUWA | INSN_ASI(ASI_PRIMARY_LITTLE))
++#define LDSW_LE    (LDSWA | INSN_ASI(ASI_PRIMARY_LITTLE))
++#define LDX_LE     (LDXA  | INSN_ASI(ASI_PRIMARY_LITTLE))
++
++#define STH_LE     (STHA  | INSN_ASI(ASI_PRIMARY_LITTLE))
++#define STW_LE     (STWA  | INSN_ASI(ASI_PRIMARY_LITTLE))
++#define STX_LE     (STXA  | INSN_ASI(ASI_PRIMARY_LITTLE))
++
+ static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2,
+                                  int op)
+ {
+@@ -360,64 +368,43 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
+     }
+ }
+ 
+-static inline void tcg_out_ld_raw(TCGContext *s, int ret,
+-                                  tcg_target_long arg)
+-{
+-    tcg_out_sethi(s, ret, arg);
+-    tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
+-              INSN_IMM13(arg & 0x3ff));
+-}
+-
+-static inline void tcg_out_ld_ptr(TCGContext *s, int ret,
+-                                  tcg_target_long arg)
++static inline void tcg_out_ldst_rr(TCGContext *s, int data, int a1,
++                                   int a2, int op)
+ {
+-    if (!check_fit_tl(arg, 10))
+-        tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ffULL);
+-    if (TCG_TARGET_REG_BITS == 64) {
+-        tcg_out32(s, LDX | INSN_RD(ret) | INSN_RS1(ret) |
+-                  INSN_IMM13(arg & 0x3ff));
+-    } else {
+-        tcg_out32(s, LDUW | INSN_RD(ret) | INSN_RS1(ret) |
+-                  INSN_IMM13(arg & 0x3ff));
+-    }
++    tcg_out32(s, op | INSN_RD(data) | INSN_RS1(a1) | INSN_RS2(a2));
+ }
+ 
+-static inline void tcg_out_ldst(TCGContext *s, int ret, int addr, int offset, int op)
++static inline void tcg_out_ldst(TCGContext *s, int ret, int addr,
++                                int offset, int op)
+ {
+-    if (check_fit_tl(offset, 13))
++    if (check_fit_tl(offset, 13)) {
+         tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
+                   INSN_IMM13(offset));
+-    else {
++    } else {
+         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
+-        tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
+-                  INSN_RS2(addr));
++        tcg_out_ldst_rr(s, ret, addr, TCG_REG_I5, op);
+     }
+ }
+ 
+-static inline void tcg_out_ldst_asi(TCGContext *s, int ret, int addr,
+-                                    int offset, int op, int asi)
+-{
+-    tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
+-    tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(TCG_REG_I5) |
+-              INSN_ASI(asi) | INSN_RS2(addr));
+-}
+-
+ static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
+                               TCGReg arg1, tcg_target_long arg2)
+ {
+-    if (type == TCG_TYPE_I32)
+-        tcg_out_ldst(s, ret, arg1, arg2, LDUW);
+-    else
+-        tcg_out_ldst(s, ret, arg1, arg2, LDX);
++    tcg_out_ldst(s, ret, arg1, arg2, (type == TCG_TYPE_I32 ? LDUW : LDX));
+ }
+ 
+ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
+                               TCGReg arg1, tcg_target_long arg2)
+ {
+-    if (type == TCG_TYPE_I32)
+-        tcg_out_ldst(s, arg, arg1, arg2, STW);
+-    else
+-        tcg_out_ldst(s, arg, arg1, arg2, STX);
++    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)
++{
++    if (!check_fit_tl(arg, 10)) {
++        tcg_out_movi(s, TCG_TYPE_PTR, ret, arg & ~0x3ff);
++    }
++    tcg_out_ld(s, TCG_TYPE_PTR, ret, ret, arg & 0x3ff);
+ }
+ 
+ static inline void tcg_out_sety(TCGContext *s, int rs)
+@@ -442,14 +429,15 @@ static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
+     }
+ }
+ 
+-static inline void tcg_out_andi(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, reg, reg, val, ARITH_AND);
++            tcg_out_arithi(s, rd, rs, val, ARITH_AND);
+         else {
+             tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, val);
+-            tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_AND);
++            tcg_out_arith(s, rd, rs, TCG_REG_I5, ARITH_AND);
+         }
+     }
+ }
+@@ -718,418 +706,328 @@ static const void * const qemu_st_helpers[4] = {
+     helper_stl_mmu,
+     helper_stq_mmu,
+ };
+-#endif
+ 
+-#if TARGET_LONG_BITS == 32
+-#define TARGET_LD_OP LDUW
+-#else
+-#define TARGET_LD_OP LDX
+-#endif
++/* Perform the TLB load and compare.
+ 
+-#if defined(CONFIG_SOFTMMU)
+-#if HOST_LONG_BITS == 32
+-#define TARGET_ADDEND_LD_OP LDUW
++   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.
++
++   MEM_INDEX and S_BITS are the memory context and log2 size of the load.
++
++   WHICH is the offset into the CPUTLBEntry structure of the slot to read.
++   This should be offsetof addr_read or addr_write.
++
++   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,
++                            int s_bits, const TCGArg *args, 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;
++    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_arith(s, r0, r0, r1, ARITH_OR);
++    }
++
++    /* Shift the page number down to tlb-entry.  */
++    tcg_out_arithi(s, r1, addrlo,
++                   TARGET_PAGE_BITS - CPU_TLB_ENTRY_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));
++
++    /* Compute tlb index, modulo tlb size.  */
++    tcg_out_andi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
++
++    /* Relative to the current ENV.  */
++    tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);
++
++    /* 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;
++    }
++
++    /* Load the tlb comparator and the addend.  */
++    tcg_out_ld(s, TCG_TYPE_TL, r2, r1, tlb_ofs + which);
++    tcg_out_ld(s, TCG_TYPE_PTR, r1, r1, tlb_ofs+offsetof(CPUTLBEntry, addend));
++
++    /* subcc arg0, arg2, %g0 */
++    tcg_out_cmp(s, r0, r2, 0);
++
++    /* If the guest address must be zero-extended, do so now.  */
++    if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
++        tcg_out_arithi(s, r0, addrlo, 0, SHIFT_SRL);
++        return r0;
++    }
++    return addrlo;
++}
++#endif /* CONFIG_SOFTMMU */
++
++static const int qemu_ld_opc[8] = {
++#ifdef TARGET_WORDS_BIGENDIAN
++    LDUB, LDUH, LDUW, LDX, LDSB, LDSH, LDSW, LDX
+ #else
+-#define TARGET_ADDEND_LD_OP LDX
+-#endif
++    LDUB, LDUH_LE, LDUW_LE, LDX_LE, LDSB, LDSH_LE, LDSW_LE, LDX_LE
+ #endif
++};
+ 
+-#if TCG_TARGET_REG_BITS == 64
+-#define HOST_LD_OP LDX
+-#define HOST_ST_OP STX
+-#define HOST_SLL_OP SHIFT_SLLX
+-#define HOST_SRA_OP SHIFT_SRAX
++static const int qemu_st_opc[4] = {
++#ifdef TARGET_WORDS_BIGENDIAN
++    STB, STH, STW, STX
+ #else
+-#define HOST_LD_OP LDUW
+-#define HOST_ST_OP STW
+-#define HOST_SLL_OP SHIFT_SLL
+-#define HOST_SRA_OP SHIFT_SRA
++    STB, STH_LE, STW_LE, STX_LE
+ #endif
++};
+ 
+-static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
+-                            int opc)
++static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
+ {
+-    int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
++    int addrlo_idx = 1, datalo, datahi, addr_reg;
+ #if defined(CONFIG_SOFTMMU)
+-    uint32_t *label1_ptr, *label2_ptr;
++    int memi_idx, memi, s_bits, n;
++    uint32_t *label_ptr[2];
+ #endif
+ 
+-    data_reg = *args++;
+-    addr_reg = *args++;
+-    mem_index = *args;
+-    s_bits = opc & 3;
+-
+-    arg0 = TCG_REG_O0;
+-    arg1 = TCG_REG_O1;
+-    arg2 = TCG_REG_O2;
++    datahi = datalo = args[0];
++    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
++        datahi = args[1];
++        addrlo_idx = 2;
++    }
+ 
+ #if defined(CONFIG_SOFTMMU)
+-    /* srl addr_reg, x, arg1 */
+-    tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
+-                   SHIFT_SRL);
+-    /* and addr_reg, x, arg0 */
+-    tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
+-                   ARITH_AND);
++    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) {
++        int reg64;
++
++        /* bne,pn %[xi]cc, label0 */
++        label_ptr[0] = (uint32_t *)s->code_ptr;
++        tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_NE, 0) | INSN_OP2(0x1)
++                      | ((TARGET_LONG_BITS == 64) << 21)));
++
++        /* 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]);
++
++        /* Move the two 32-bit pieces into the destination registers.  */
++        tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
++        if (reg64 != datalo) {
++            tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
++        }
+ 
+-    /* and arg1, x, arg1 */
+-    tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
++        /* b,a,pt label1 */
++        label_ptr[1] = (uint32_t *)s->code_ptr;
++        tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x1)
++                      | (1 << 29) | (1 << 19)));
++    } else {
++        /* The fast path is exactly one insn.  Thus we can perform the
++           entire TLB Hit in the (annulled) delay slot of the branch
++           over the TLB Miss case.  */
++
++        /* beq,a,pt %[xi]cc, label0 */
++        label_ptr[0] = NULL;
++        label_ptr[1] = (uint32_t *)s->code_ptr;
++        tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1)
++                      | ((TARGET_LONG_BITS == 64) << 21)
++                      | (1 << 29) | (1 << 19)));
++        /* delay slot */
++        tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_O1, qemu_ld_opc[sizeop]);
++    }
+ 
+-    /* add arg1, x, arg1 */
+-    tcg_out_addi(s, arg1, offsetof(CPUArchState,
+-                                   tlb_table[mem_index][0].addr_read));
++    /* TLB Miss.  */
+ 
+-    /* add env, arg1, arg1 */
+-    tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
++    if (label_ptr[0]) {
++        *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);
++    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++],
++                args[addrlo_idx]);
+ 
+-    /* ld [arg1], arg2 */
+-    tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
+-              INSN_RS2(TCG_REG_G0));
++    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
++       global registers */
++    tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
++               TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
++               sizeof(long));
+ 
+-    /* subcc arg0, arg2, %g0 */
+-    tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
+-
+-    /* will become:
+-       be label1
+-        or
+-       be,pt %xcc label1 */
+-    label1_ptr = (uint32_t *)s->code_ptr;
+-    tcg_out32(s, 0);
+-
+-    /* mov (delay slot) */
+-    tcg_out_mov(s, TCG_TYPE_PTR, arg0, addr_reg);
+-
+-    /* mov */
+-    tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
+-    /* XXX/FIXME: suboptimal */
+-    tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
+-                tcg_target_call_iarg_regs[2]);
+-    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
+-                tcg_target_call_iarg_regs[1]);
+-    tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+-                tcg_target_call_iarg_regs[0]);
+-    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+-                TCG_AREG0);
+-
+-    /* XXX: move that code at the end of the TB */
+     /* 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));
+-    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
+-       global registers */
+-    // delay slot
+-    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
+-                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-                 sizeof(long), HOST_ST_OP);
+-    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
+-                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-                 sizeof(long), HOST_LD_OP);
+-
+-    /* data_reg = sign_extend(arg0) */
+-    switch(opc) {
++    /* delay slot */
++    tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[n], memi);
++
++    /* Reload AREG0.  */
++    tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
++               TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
++               sizeof(long));
++
++    n = tcg_target_call_oarg_regs[0];
++    /* datalo = sign_extend(arg0) */
++    switch (sizeop) {
+     case 0 | 4:
+-        /* sll arg0, 24/56, data_reg */
+-        tcg_out_arithi(s, data_reg, arg0, (int)sizeof(tcg_target_long) * 8 - 8,
+-                       HOST_SLL_OP);
+-        /* sra data_reg, 24/56, data_reg */
+-        tcg_out_arithi(s, data_reg, data_reg,
+-                       (int)sizeof(tcg_target_long) * 8 - 8, HOST_SRA_OP);
++        /* 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:
+-        /* sll arg0, 16/48, data_reg */
+-        tcg_out_arithi(s, data_reg, arg0,
+-                       (int)sizeof(tcg_target_long) * 8 - 16, HOST_SLL_OP);
+-        /* sra data_reg, 16/48, data_reg */
+-        tcg_out_arithi(s, data_reg, data_reg,
+-                       (int)sizeof(tcg_target_long) * 8 - 16, HOST_SRA_OP);
++        tcg_out_arithi(s, datalo, n, 16, SHIFT_SLL);
++        tcg_out_arithi(s, datalo, datalo, 16, SHIFT_SRA);
+         break;
+     case 2 | 4:
+-        /* sll arg0, 32, data_reg */
+-        tcg_out_arithi(s, data_reg, arg0, 32, HOST_SLL_OP);
+-        /* sra data_reg, 32, data_reg */
+-        tcg_out_arithi(s, data_reg, data_reg, 32, HOST_SRA_OP);
++        tcg_out_arithi(s, datalo, n, 0, SHIFT_SRA);
+         break;
++    case 3:
++        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 3:
+     default:
+         /* mov */
+-        tcg_out_mov(s, TCG_TYPE_REG, data_reg, arg0);
++        tcg_out_mov(s, TCG_TYPE_REG, datalo, n);
+         break;
+     }
+ 
+-    /* will become:
+-       ba label2 */
+-    label2_ptr = (uint32_t *)s->code_ptr;
+-    tcg_out32(s, 0);
+-
+-    /* nop (delay slot */
+-    tcg_out_nop(s);
+-
+-    /* label1: */
+-#if TARGET_LONG_BITS == 32
+-    /* be label1 */
+-    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
+-                   INSN_OFF22((unsigned long)s->code_ptr -
+-                              (unsigned long)label1_ptr));
+-#else
+-    /* be,pt %xcc label1 */
+-    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
+-                   (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
+-                              (unsigned long)label1_ptr));
+-#endif
+-
+-    /* ld [arg1 + x], arg1 */
+-    tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
+-                 offsetof(CPUTLBEntry, addr_read), TARGET_ADDEND_LD_OP);
+-
+-#if TARGET_LONG_BITS == 32
+-    /* and addr_reg, x, arg0 */
+-    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
+-    tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
+-    /* add arg0, arg1, arg0 */
+-    tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
++    *label_ptr[1] |= INSN_OFF19((unsigned long)s->code_ptr -
++                                (unsigned long)label_ptr[1]);
+ #else
+-    /* add addr_reg, arg1, arg0 */
+-    tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
+-#endif
++    addr_reg = args[addrlo_idx];
++    if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
++        tcg_out_arithi(s, TCG_REG_I5, addr_reg, 0, SHIFT_SRL);
++        addr_reg = TCG_REG_I5;
++    }
++    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
++        int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
+ 
+-#else
+-    arg0 = addr_reg;
+-#endif
++        tcg_out_ldst_rr(s, reg64, addr_reg, TCG_REG_G0, qemu_ld_opc[sizeop]);
+ 
+-    switch(opc) {
+-    case 0:
+-        /* ldub [arg0], data_reg */
+-        tcg_out_ldst(s, data_reg, arg0, 0, LDUB);
+-        break;
+-    case 0 | 4:
+-        /* ldsb [arg0], data_reg */
+-        tcg_out_ldst(s, data_reg, arg0, 0, LDSB);
+-        break;
+-    case 1:
+-#ifdef TARGET_WORDS_BIGENDIAN
+-        /* lduh [arg0], data_reg */
+-        tcg_out_ldst(s, data_reg, arg0, 0, LDUH);
+-#else
+-        /* lduha [arg0] ASI_PRIMARY_LITTLE, data_reg */
+-        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUHA, ASI_PRIMARY_LITTLE);
+-#endif
+-        break;
+-    case 1 | 4:
+-#ifdef TARGET_WORDS_BIGENDIAN
+-        /* ldsh [arg0], data_reg */
+-        tcg_out_ldst(s, data_reg, arg0, 0, LDSH);
+-#else
+-        /* ldsha [arg0] ASI_PRIMARY_LITTLE, data_reg */
+-        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSHA, ASI_PRIMARY_LITTLE);
+-#endif
+-        break;
+-    case 2:
+-#ifdef TARGET_WORDS_BIGENDIAN
+-        /* lduw [arg0], data_reg */
+-        tcg_out_ldst(s, data_reg, arg0, 0, LDUW);
+-#else
+-        /* lduwa [arg0] ASI_PRIMARY_LITTLE, data_reg */
+-        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDUWA, ASI_PRIMARY_LITTLE);
+-#endif
+-        break;
+-    case 2 | 4:
+-#ifdef TARGET_WORDS_BIGENDIAN
+-        /* ldsw [arg0], data_reg */
+-        tcg_out_ldst(s, data_reg, arg0, 0, LDSW);
+-#else
+-        /* ldswa [arg0] ASI_PRIMARY_LITTLE, data_reg */
+-        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDSWA, ASI_PRIMARY_LITTLE);
+-#endif
+-        break;
+-    case 3:
+-#ifdef TARGET_WORDS_BIGENDIAN
+-        /* ldx [arg0], data_reg */
+-        tcg_out_ldst(s, data_reg, arg0, 0, LDX);
+-#else
+-        /* ldxa [arg0] ASI_PRIMARY_LITTLE, data_reg */
+-        tcg_out_ldst_asi(s, data_reg, arg0, 0, LDXA, ASI_PRIMARY_LITTLE);
+-#endif
+-        break;
+-    default:
+-        tcg_abort();
++        tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
++        if (reg64 != datalo) {
++            tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
++        }
++    } else {
++        tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_G0, qemu_ld_opc[sizeop]);
+     }
+-
+-#if defined(CONFIG_SOFTMMU)
+-    /* label2: */
+-    *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
+-                   INSN_OFF22((unsigned long)s->code_ptr -
+-                              (unsigned long)label2_ptr));
+-#endif
++#endif /* CONFIG_SOFTMMU */
+ }
+ 
+-static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
+-                            int opc)
++static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
+ {
+-    int addr_reg, data_reg, arg0, arg1, arg2, mem_index, s_bits;
++    int addrlo_idx = 1, datalo, datahi, addr_reg;
+ #if defined(CONFIG_SOFTMMU)
+-    uint32_t *label1_ptr, *label2_ptr;
++    int memi_idx, memi, n;
++    uint32_t *label_ptr;
+ #endif
+ 
+-    data_reg = *args++;
+-    addr_reg = *args++;
+-    mem_index = *args;
+-
+-    s_bits = opc;
+-
+-    arg0 = TCG_REG_O0;
+-    arg1 = TCG_REG_O1;
+-    arg2 = TCG_REG_O2;
++    datahi = datalo = args[0];
++    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
++        datahi = args[1];
++        addrlo_idx = 2;
++    }
+ 
+ #if defined(CONFIG_SOFTMMU)
+-    /* srl addr_reg, x, arg1 */
+-    tcg_out_arithi(s, arg1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
+-                   SHIFT_SRL);
+-
+-    /* and addr_reg, x, arg0 */
+-    tcg_out_arithi(s, arg0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
+-                   ARITH_AND);
+-
+-    /* and arg1, x, arg1 */
+-    tcg_out_andi(s, arg1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
+-
+-    /* add arg1, x, arg1 */
+-    tcg_out_addi(s, arg1, offsetof(CPUArchState,
+-                                   tlb_table[mem_index][0].addr_write));
++    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,
++                                offsetof(CPUTLBEntry, addr_write));
++
++    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
++        /* Reconstruct the full 64-bit value in %g1, using %o2 as temp.  */
++        /* ??? Redefine the temps from %i4/%i5 so that we have a o/g temp. */
++        tcg_out_arithi(s, TCG_REG_G1, datalo, 0, SHIFT_SRL);
++        tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
++        tcg_out_arith(s, TCG_REG_G1, TCG_REG_G1, TCG_REG_O2, ARITH_OR);
++        datalo = TCG_REG_G1;
++    }
+ 
+-    /* add env, arg1, arg1 */
+-    tcg_out_arith(s, arg1, TCG_AREG0, arg1, ARITH_ADD);
++    /* The fast path is exactly one insn.  Thus we can perform the entire
++       TLB Hit in the (annulled) delay slot of the branch over TLB Miss.  */
++    /* beq,a,pt %[xi]cc, label0 */
++    label_ptr = (uint32_t *)s->code_ptr;
++    tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1)
++                  | ((TARGET_LONG_BITS == 64) << 21)
++                  | (1 << 29) | (1 << 19)));
++    /* delay slot */
++    tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_O1, qemu_st_opc[sizeop]);
++
++    /* TLB Miss.  */
++
++    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++],
++                args[addrlo_idx]);
++    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
++        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);
+ 
+-    /* ld [arg1], arg2 */
+-    tcg_out32(s, TARGET_LD_OP | INSN_RD(arg2) | INSN_RS1(arg1) |
+-              INSN_RS2(TCG_REG_G0));
++    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
++       global registers */
++    tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
++               TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
++               sizeof(long));
+ 
+-    /* subcc arg0, arg2, %g0 */
+-    tcg_out_arith(s, TCG_REG_G0, arg0, arg2, ARITH_SUBCC);
+-
+-    /* will become:
+-       be label1
+-        or
+-       be,pt %xcc label1 */
+-    label1_ptr = (uint32_t *)s->code_ptr;
+-    tcg_out32(s, 0);
+-
+-    /* mov (delay slot) */
+-    tcg_out_mov(s, TCG_TYPE_PTR, arg0, addr_reg);
+-
+-    /* mov */
+-    tcg_out_mov(s, TCG_TYPE_REG, arg1, data_reg);
+-
+-    /* mov */
+-    tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
+-
+-    /* XXX/FIXME: suboptimal */
+-    tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
+-                tcg_target_call_iarg_regs[2]);
+-    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
+-                tcg_target_call_iarg_regs[1]);
+-    tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+-                tcg_target_call_iarg_regs[0]);
+-    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+-                TCG_AREG0);
+-    /* XXX: move that code at the end of the TB */
+     /* qemu_st_helper[s_bits](arg0, arg1, arg2) */
+-    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
++    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[sizeop]
+                            - (tcg_target_ulong)s->code_ptr) >> 2)
+                          & 0x3fffffff));
+-    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
+-       global registers */
+-    // delay slot
+-    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
+-                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-                 sizeof(long), HOST_ST_OP);
+-    tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
+-                 TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-                 sizeof(long), HOST_LD_OP);
+-
+-    /* will become:
+-       ba label2 */
+-    label2_ptr = (uint32_t *)s->code_ptr;
+-    tcg_out32(s, 0);
+-
+-    /* nop (delay slot) */
+-    tcg_out_nop(s);
++    /* delay slot */
++    tcg_out_movi(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n], memi);
+ 
+-#if TARGET_LONG_BITS == 32
+-    /* be label1 */
+-    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x2) |
+-                   INSN_OFF22((unsigned long)s->code_ptr -
+-                              (unsigned long)label1_ptr));
+-#else
+-    /* be,pt %xcc label1 */
+-    *label1_ptr = (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1) |
+-                   (0x5 << 19) | INSN_OFF19((unsigned long)s->code_ptr -
+-                              (unsigned long)label1_ptr));
+-#endif
+-
+-    /* ld [arg1 + x], arg1 */
+-    tcg_out_ldst(s, arg1, arg1, offsetof(CPUTLBEntry, addend) -
+-                 offsetof(CPUTLBEntry, addr_write), TARGET_ADDEND_LD_OP);
++    /* Reload AREG0.  */
++    tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
++               TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
++               sizeof(long));
+ 
+-#if TARGET_LONG_BITS == 32
+-    /* and addr_reg, x, arg0 */
+-    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_I5, 0xffffffff);
+-    tcg_out_arith(s, arg0, addr_reg, TCG_REG_I5, ARITH_AND);
+-    /* add arg0, arg1, arg0 */
+-    tcg_out_arith(s, arg0, arg0, arg1, ARITH_ADD);
++    *label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
++                             (unsigned long)label_ptr);
+ #else
+-    /* add addr_reg, arg1, arg0 */
+-    tcg_out_arith(s, arg0, addr_reg, arg1, ARITH_ADD);
+-#endif
+-
+-#else
+-    arg0 = addr_reg;
+-#endif
+-
+-    switch(opc) {
+-    case 0:
+-        /* stb data_reg, [arg0] */
+-        tcg_out_ldst(s, data_reg, arg0, 0, STB);
+-        break;
+-    case 1:
+-#ifdef TARGET_WORDS_BIGENDIAN
+-        /* sth data_reg, [arg0] */
+-        tcg_out_ldst(s, data_reg, arg0, 0, STH);
+-#else
+-        /* stha data_reg, [arg0] ASI_PRIMARY_LITTLE */
+-        tcg_out_ldst_asi(s, data_reg, arg0, 0, STHA, ASI_PRIMARY_LITTLE);
+-#endif
+-        break;
+-    case 2:
+-#ifdef TARGET_WORDS_BIGENDIAN
+-        /* stw data_reg, [arg0] */
+-        tcg_out_ldst(s, data_reg, arg0, 0, STW);
+-#else
+-        /* stwa data_reg, [arg0] ASI_PRIMARY_LITTLE */
+-        tcg_out_ldst_asi(s, data_reg, arg0, 0, STWA, ASI_PRIMARY_LITTLE);
+-#endif
+-        break;
+-    case 3:
+-#ifdef TARGET_WORDS_BIGENDIAN
+-        /* stx data_reg, [arg0] */
+-        tcg_out_ldst(s, data_reg, arg0, 0, STX);
+-#else
+-        /* stxa data_reg, [arg0] ASI_PRIMARY_LITTLE */
+-        tcg_out_ldst_asi(s, data_reg, arg0, 0, STXA, ASI_PRIMARY_LITTLE);
+-#endif
+-        break;
+-    default:
+-        tcg_abort();
++    addr_reg = args[addrlo_idx];
++    if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
++        tcg_out_arithi(s, TCG_REG_I5, addr_reg, 0, SHIFT_SRL);
++        addr_reg = TCG_REG_I5;
+     }
+-
+-#if defined(CONFIG_SOFTMMU)
+-    /* label2: */
+-    *label2_ptr = (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2) |
+-                   INSN_OFF22((unsigned long)s->code_ptr -
+-                              (unsigned long)label2_ptr));
+-#endif
++    if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
++        /* Reconstruct the full 64-bit value in %g1, using %o2 as temp.  */
++        /* ??? Redefine the temps from %i4/%i5 so that we have a o/g temp. */
++        tcg_out_arithi(s, TCG_REG_G1, datalo, 0, SHIFT_SRL);
++        tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
++        tcg_out_arith(s, TCG_REG_G1, TCG_REG_G1, TCG_REG_O2, ARITH_OR);
++        datalo = TCG_REG_G1;
++    }
++    tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_G0, qemu_st_opc[sizeop]);
++#endif /* CONFIG_SOFTMMU */
+ }
+ 
+ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+@@ -1175,12 +1073,12 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+         /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
+            global registers */
+         // delay slot
+-        tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
+-                     TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-                     sizeof(long), HOST_ST_OP);
+-        tcg_out_ldst(s, TCG_AREG0, TCG_REG_CALL_STACK,
+-                     TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-                     sizeof(long), HOST_LD_OP);
++        tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
++                   TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
++                   sizeof(long));
++        tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
++                   TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
++                   sizeof(long));
+         break;
+     case INDEX_op_jmp:
+     case INDEX_op_br:
+@@ -1348,6 +1246,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+         tcg_out_qemu_ld(s, args, 2 | 4);
+         break;
+ #endif
++    case INDEX_op_qemu_ld64:
++        tcg_out_qemu_ld(s, args, 3);
++        break;
+     case INDEX_op_qemu_st8:
+         tcg_out_qemu_st(s, args, 0);
+         break;
+@@ -1357,6 +1258,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+     case INDEX_op_qemu_st32:
+         tcg_out_qemu_st(s, args, 2);
+         break;
++    case INDEX_op_qemu_st64:
++        tcg_out_qemu_st(s, args, 3);
++        break;
+ 
+ #if TCG_TARGET_REG_BITS == 64
+     case INDEX_op_movi_i64:
+@@ -1421,13 +1325,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+                             args[2], const_args[2]);
+         break;
+ 
+-    case INDEX_op_qemu_ld64:
+-        tcg_out_qemu_ld(s, args, 3);
+-        break;
+-    case INDEX_op_qemu_st64:
+-        tcg_out_qemu_st(s, args, 3);
+-        break;
+-
+ #endif
+     gen_arith:
+         tcg_out_arithc(s, args[0], args[1], args[2], const_args[2], c);
+@@ -1492,20 +1389,6 @@ static const TCGTargetOpDef sparc_op_defs[] = {
+     { INDEX_op_mulu2_i32, { "r", "r", "r", "rJ" } },
+ #endif
+ 
+-    { 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" } },
+-#if TCG_TARGET_REG_BITS == 64
+-    { INDEX_op_qemu_ld32u, { "r", "L" } },
+-    { INDEX_op_qemu_ld32s, { "r", "L" } },
+-#endif
+-
+-    { INDEX_op_qemu_st8, { "L", "L" } },
+-    { INDEX_op_qemu_st16, { "L", "L" } },
+-    { INDEX_op_qemu_st32, { "L", "L" } },
+-
+ #if TCG_TARGET_REG_BITS == 64
+     { INDEX_op_mov_i64, { "r", "r" } },
+     { INDEX_op_movi_i64, { "r" } },
+@@ -1520,8 +1403,6 @@ static const TCGTargetOpDef sparc_op_defs[] = {
+     { INDEX_op_st16_i64, { "r", "r" } },
+     { INDEX_op_st32_i64, { "r", "r" } },
+     { INDEX_op_st_i64, { "r", "r" } },
+-    { INDEX_op_qemu_ld64, { "L", "L" } },
+-    { INDEX_op_qemu_st64, { "L", "L" } },
+ 
+     { INDEX_op_add_i64, { "r", "r", "rJ" } },
+     { INDEX_op_mul_i64, { "r", "r", "rJ" } },
+@@ -1548,10 +1429,48 @@ static const TCGTargetOpDef sparc_op_defs[] = {
+ 
+     { INDEX_op_brcond_i64, { "r", "rJ" } },
+     { INDEX_op_setcond_i64, { "r", "r", "rJ" } },
+-#else
+-    { INDEX_op_qemu_ld64, { "L", "L", "L" } },
++#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" } },
++#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" } },
++#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" } },
+ #endif
++
+     { -1 },
+ };
+ 
+-- 
+1.7.12.1
+
diff --git a/0086-tcg-sparc-Support-GUEST_BASE.patch b/0086-tcg-sparc-Support-GUEST_BASE.patch
new file mode 100644
index 0000000..3e8a175
--- /dev/null
+++ b/0086-tcg-sparc-Support-GUEST_BASE.patch
@@ -0,0 +1,113 @@
+From fecc7bd255206876152baab622c61902133066bd Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Sat, 24 Mar 2012 22:11:25 +0100
+Subject: [PATCH] tcg-sparc: Support GUEST_BASE.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure              |  2 ++
+ tcg/sparc/tcg-target.c | 26 +++++++++++++++++++++++---
+ tcg/sparc/tcg-target.h |  2 ++
+ 3 files changed, 27 insertions(+), 3 deletions(-)
+
+diff --git a/configure b/configure
+index 0590f16..9139b5c 100755
+--- a/configure
++++ b/configure
+@@ -872,6 +872,7 @@ case "$cpu" in
+            if test "$solaris" = "no" ; then
+              QEMU_CFLAGS="-ffixed-g1 -ffixed-g6 $QEMU_CFLAGS"
+            fi
++           host_guest_base="yes"
+            ;;
+     sparc64)
+            LDFLAGS="-m64 $LDFLAGS"
+@@ -880,6 +881,7 @@ case "$cpu" in
+            if test "$solaris" != "no" ; then
+              QEMU_CFLAGS="-ffixed-g1 $QEMU_CFLAGS"
+            fi
++           host_guest_base="yes"
+            ;;
+     s390)
+            QEMU_CFLAGS="-m31 -march=z990 $QEMU_CFLAGS"
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index d89c19b..5acfeba 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -59,6 +59,12 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
+ };
+ #endif
+ 
++#ifdef CONFIG_USE_GUEST_BASE
++# define TCG_GUEST_BASE_REG TCG_REG_I3
++#else
++# define TCG_GUEST_BASE_REG TCG_REG_G0
++#endif
++
+ static const int tcg_target_reg_alloc_order[] = {
+     TCG_REG_L0,
+     TCG_REG_L1,
+@@ -680,6 +686,14 @@ static void tcg_target_qemu_prologue(TCGContext *s)
+     tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
+               INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME +
+                            CPU_TEMP_BUF_NLONGS * (int)sizeof(long))));
++
++#ifdef CONFIG_USE_GUEST_BASE
++    if (GUEST_BASE != 0) {
++        tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE);
++        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
++    }
++#endif
++
+     tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
+               INSN_RS2(TCG_REG_G0));
+     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0);
+@@ -925,14 +939,18 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
+     if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
+         int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
+ 
+-        tcg_out_ldst_rr(s, reg64, addr_reg, TCG_REG_G0, qemu_ld_opc[sizeop]);
++        tcg_out_ldst_rr(s, reg64, addr_reg,
++                        (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
++                        qemu_ld_opc[sizeop]);
+ 
+         tcg_out_arithi(s, datahi, reg64, 32, SHIFT_SRLX);
+         if (reg64 != datalo) {
+             tcg_out_mov(s, TCG_TYPE_I32, datalo, reg64);
+         }
+     } else {
+-        tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_G0, qemu_ld_opc[sizeop]);
++        tcg_out_ldst_rr(s, datalo, addr_reg,
++                        (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
++                        qemu_ld_opc[sizeop]);
+     }
+ #endif /* CONFIG_SOFTMMU */
+ }
+@@ -1026,7 +1044,9 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
+         tcg_out_arith(s, TCG_REG_G1, TCG_REG_G1, TCG_REG_O2, ARITH_OR);
+         datalo = TCG_REG_G1;
+     }
+-    tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_G0, qemu_st_opc[sizeop]);
++    tcg_out_ldst_rr(s, datalo, addr_reg,
++                    (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
++                    qemu_st_opc[sizeop]);
+ #endif /* CONFIG_SOFTMMU */
+ }
+ 
+diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
+index adca1d2..99e9f57 100644
+--- a/tcg/sparc/tcg-target.h
++++ b/tcg/sparc/tcg-target.h
+@@ -128,6 +128,8 @@ typedef enum {
+ #define TCG_TARGET_HAS_movcond_i64      0
+ #endif
+ 
++#define TCG_TARGET_HAS_GUEST_BASE
++
+ #ifdef CONFIG_SOLARIS
+ #define TCG_AREG0 TCG_REG_G2
+ #elif HOST_LONG_BITS == 64
+-- 
+1.7.12.1
+
diff --git a/0087-tcg-sparc-Change-AREG0-in-generated-code-to-i0.patch b/0087-tcg-sparc-Change-AREG0-in-generated-code-to-i0.patch
new file mode 100644
index 0000000..336d7fe
--- /dev/null
+++ b/0087-tcg-sparc-Change-AREG0-in-generated-code-to-i0.patch
@@ -0,0 +1,51 @@
+From d526285d4339f02e3be64a7287d1e009dd5bff3d Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Sun, 25 Mar 2012 19:52:11 +0200
+Subject: [PATCH] tcg-sparc: Change AREG0 in generated code to %i0.
+
+We can now move the TCG variable from %g[56] to a call-preserved
+windowed register.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/sparc/tcg-target.c | 3 ++-
+ tcg/sparc/tcg-target.h | 8 +-------
+ 2 files changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index 5acfeba..9ab5746 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -696,7 +696,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
+ 
+     tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
+               INSN_RS2(TCG_REG_G0));
+-    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0);
++    /* delay slot */
++    tcg_out_nop(s);
+ }
+ 
+ #if defined(CONFIG_SOFTMMU)
+diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
+index 99e9f57..ee154d0 100644
+--- a/tcg/sparc/tcg-target.h
++++ b/tcg/sparc/tcg-target.h
+@@ -130,13 +130,7 @@ typedef enum {
+ 
+ #define TCG_TARGET_HAS_GUEST_BASE
+ 
+-#ifdef CONFIG_SOLARIS
+-#define TCG_AREG0 TCG_REG_G2
+-#elif HOST_LONG_BITS == 64
+-#define TCG_AREG0 TCG_REG_G5
+-#else
+-#define TCG_AREG0 TCG_REG_G6
+-#endif
++#define TCG_AREG0 TCG_REG_I0
+ 
+ static inline void flush_icache_range(tcg_target_ulong start,
+                                       tcg_target_ulong stop)
+-- 
+1.7.12.1
+
diff --git a/0088-tcg-sparc-Clean-up-cruft-stemming-from-attempts-to-u.patch b/0088-tcg-sparc-Clean-up-cruft-stemming-from-attempts-to-u.patch
new file mode 100644
index 0000000..15c4571
--- /dev/null
+++ b/0088-tcg-sparc-Clean-up-cruft-stemming-from-attempts-to-u.patch
@@ -0,0 +1,203 @@
+From 5767c23140f2c92b899d9caeaa8e08711cb63868 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Sun, 25 Mar 2012 21:21:46 +0200
+Subject: [PATCH] tcg-sparc: Clean up cruft stemming from attempts to use
+ global registers.
+
+Don't use -ffixed-gN.  Don't link statically.  Don't save/restore
+AREG0 around calls.  Don't allocate space on the stack for AREG0 save.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure              | 12 -----------
+ tcg/sparc/tcg-target.c | 55 +++++++++++++++++---------------------------------
+ tcg/sparc/tcg-target.h | 18 +++++++----------
+ 3 files changed, 26 insertions(+), 59 deletions(-)
+
+diff --git a/configure b/configure
+index 9139b5c..8ffddf4 100755
+--- a/configure
++++ b/configure
+@@ -868,19 +868,11 @@ case "$cpu" in
+     sparc)
+            LDFLAGS="-m32 $LDFLAGS"
+            QEMU_CFLAGS="-m32 -mcpu=ultrasparc $QEMU_CFLAGS"
+-           QEMU_CFLAGS="-ffixed-g2 -ffixed-g3 $QEMU_CFLAGS"
+-           if test "$solaris" = "no" ; then
+-             QEMU_CFLAGS="-ffixed-g1 -ffixed-g6 $QEMU_CFLAGS"
+-           fi
+            host_guest_base="yes"
+            ;;
+     sparc64)
+            LDFLAGS="-m64 $LDFLAGS"
+            QEMU_CFLAGS="-m64 -mcpu=ultrasparc $QEMU_CFLAGS"
+-           QEMU_CFLAGS="-ffixed-g5 -ffixed-g6 -ffixed-g7 $QEMU_CFLAGS"
+-           if test "$solaris" != "no" ; then
+-             QEMU_CFLAGS="-ffixed-g1 $QEMU_CFLAGS"
+-           fi
+            host_guest_base="yes"
+            ;;
+     s390)
+@@ -4055,10 +4047,6 @@ fi
+ 
+ if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
+   case "$ARCH" in
+-  sparc)
+-    # -static is used to avoid g1/g3 usage by the dynamic linker
+-    ldflags="$linker_script -static $ldflags"
+-    ;;
+   alpha | s390x)
+     # The default placement of the application is fine.
+     ;;
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index 9ab5746..e625aa3 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -161,7 +161,6 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
+         tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
+-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O3);
+         break;
+     case 'I':
+         ct->ct |= TCG_CT_CONST_S11;
+@@ -681,11 +680,22 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
+ /* Generate global QEMU prologue and epilogue code */
+ static void tcg_target_qemu_prologue(TCGContext *s)
+ {
+-    tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_CALL_STACK_OFFSET,
+-                  CPU_TEMP_BUF_NLONGS * (int)sizeof(long));
++    int tmp_buf_size, frame_size;
++
++    /* The TCG temp buffer is at the top of the frame, immediately
++       below the frame pointer.  */
++    tmp_buf_size = CPU_TEMP_BUF_NLONGS * (int)sizeof(long);
++    tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_STACK_BIAS - tmp_buf_size,
++                  tmp_buf_size);
++
++    /* TCG_TARGET_CALL_STACK_OFFSET includes the stack bias, but is
++       otherwise the minimal frame usable by callees.  */
++    frame_size = TCG_TARGET_CALL_STACK_OFFSET - TCG_TARGET_STACK_BIAS;
++    frame_size += TCG_STATIC_CALL_ARGS_SIZE + tmp_buf_size;
++    frame_size += TCG_TARGET_STACK_ALIGN - 1;
++    frame_size &= -TCG_TARGET_STACK_ALIGN;
+     tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
+-              INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME +
+-                           CPU_TEMP_BUF_NLONGS * (int)sizeof(long))));
++              INSN_IMM13(-frame_size));
+ 
+ #ifdef CONFIG_USE_GUEST_BASE
+     if (GUEST_BASE != 0) {
+@@ -698,6 +708,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
+               INSN_RS2(TCG_REG_G0));
+     /* delay slot */
+     tcg_out_nop(s);
++
++    /* No epilogue required.  We issue ret + restore directly in the TB.  */
+ }
+ 
+ #if defined(CONFIG_SOFTMMU)
+@@ -880,12 +892,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
+     tcg_out_mov(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n++],
+                 args[addrlo_idx]);
+ 
+-    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
+-       global registers */
+-    tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
+-               TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-               sizeof(long));
+-
+     /* 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)
+@@ -893,11 +899,6 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
+     /* delay slot */
+     tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[n], memi);
+ 
+-    /* Reload AREG0.  */
+-    tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
+-               TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-               sizeof(long));
+-
+     n = tcg_target_call_oarg_regs[0];
+     /* datalo = sign_extend(arg0) */
+     switch (sizeop) {
+@@ -1011,12 +1012,6 @@ 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);
+ 
+-    /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
+-       global registers */
+-    tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
+-               TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-               sizeof(long));
+-
+     /* 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)
+@@ -1024,11 +1019,6 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
+     /* delay slot */
+     tcg_out_movi(s, TCG_TYPE_REG, tcg_target_call_iarg_regs[n], memi);
+ 
+-    /* Reload AREG0.  */
+-    tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
+-               TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-               sizeof(long));
+-
+     *label_ptr |= INSN_OFF19((unsigned long)s->code_ptr -
+                              (unsigned long)label_ptr);
+ #else
+@@ -1091,15 +1081,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+             tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_I5) |
+                       INSN_RS2(TCG_REG_G0));
+         }
+-        /* Store AREG0 in stack to avoid ugly glibc bugs that mangle
+-           global registers */
+-        // delay slot
+-        tcg_out_st(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
+-                   TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-                   sizeof(long));
+-        tcg_out_ld(s, TCG_TYPE_REG, TCG_AREG0, TCG_REG_CALL_STACK,
+-                   TCG_TARGET_CALL_STACK_OFFSET - TCG_STATIC_CALL_ARGS_SIZE -
+-                   sizeof(long));
++        /* delay slot */
++        tcg_out_nop(s);
+         break;
+     case INDEX_op_jmp:
+     case INDEX_op_br:
+diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
+index ee154d0..6314ffb 100644
+--- a/tcg/sparc/tcg-target.h
++++ b/tcg/sparc/tcg-target.h
+@@ -66,20 +66,16 @@ typedef enum {
+ #define TCG_CT_CONST_S13 0x200
+ 
+ /* used for function call generation */
+-#define TCG_REG_CALL_STACK TCG_REG_I6
++#define TCG_REG_CALL_STACK TCG_REG_O6
+ 
+ #if TCG_TARGET_REG_BITS == 64
+-// Reserve space for AREG0
+-#define TCG_TARGET_STACK_MINFRAME (176 + 4 * (int)sizeof(long) + \
+-                                   TCG_STATIC_CALL_ARGS_SIZE)
+-#define TCG_TARGET_CALL_STACK_OFFSET (2047 - 16)
+-#define TCG_TARGET_STACK_ALIGN 16
++#define TCG_TARGET_STACK_BIAS           2047
++#define TCG_TARGET_STACK_ALIGN          16
++#define TCG_TARGET_CALL_STACK_OFFSET    (128 + 6*8 + TCG_TARGET_STACK_BIAS)
+ #else
+-// AREG0 + one word for alignment
+-#define TCG_TARGET_STACK_MINFRAME (92 + (2 + 1) * (int)sizeof(long) + \
+-                                   TCG_STATIC_CALL_ARGS_SIZE)
+-#define TCG_TARGET_CALL_STACK_OFFSET TCG_TARGET_STACK_MINFRAME
+-#define TCG_TARGET_STACK_ALIGN 8
++#define TCG_TARGET_STACK_BIAS           0
++#define TCG_TARGET_STACK_ALIGN          8
++#define TCG_TARGET_CALL_STACK_OFFSET    (64 + 4 + 6*4)
+ #endif
+ 
+ #if TCG_TARGET_REG_BITS == 64
+-- 
+1.7.12.1
+
diff --git a/0089-tcg-sparc-Mask-shift-immediates-to-avoid-illegal-ins.patch b/0089-tcg-sparc-Mask-shift-immediates-to-avoid-illegal-ins.patch
new file mode 100644
index 0000000..7ce69d1
--- /dev/null
+++ b/0089-tcg-sparc-Mask-shift-immediates-to-avoid-illegal-ins.patch
@@ -0,0 +1,62 @@
+From 12e60f780a097837840ab1e7bb7d54b8c15112e8 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Sun, 25 Mar 2012 21:36:28 +0200
+Subject: [PATCH] tcg-sparc: Mask shift immediates to avoid illegal insns.
+
+The xtensa-test image generates a sra_i32 with count 0x40.
+Whether this is accident of tcg constant propagation or
+originating directly from the instruction stream is immaterial.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/sparc/tcg-target.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index e625aa3..be5c170 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -1154,13 +1154,16 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+         goto gen_arith;
+     case INDEX_op_shl_i32:
+         c = SHIFT_SLL;
+-        goto gen_arith;
++    do_shift32:
++        /* Limit immediate shift count lest we create an illegal insn.  */
++        tcg_out_arithc(s, args[0], args[1], args[2] & 31, const_args[2], c);
++        break;
+     case INDEX_op_shr_i32:
+         c = SHIFT_SRL;
+-        goto gen_arith;
++        goto do_shift32;
+     case INDEX_op_sar_i32:
+         c = SHIFT_SRA;
+-        goto gen_arith;
++        goto do_shift32;
+     case INDEX_op_mul_i32:
+         c = ARITH_UMUL;
+         goto gen_arith;
+@@ -1281,13 +1284,16 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+         break;
+     case INDEX_op_shl_i64:
+         c = SHIFT_SLLX;
+-        goto gen_arith;
++    do_shift64:
++        /* Limit immediate shift count lest we create an illegal insn.  */
++        tcg_out_arithc(s, args[0], args[1], args[2] & 63, const_args[2], c);
++        break;
+     case INDEX_op_shr_i64:
+         c = SHIFT_SRLX;
+-        goto gen_arith;
++        goto do_shift64;
+     case INDEX_op_sar_i64:
+         c = SHIFT_SRAX;
+-        goto gen_arith;
++        goto do_shift64;
+     case INDEX_op_mul_i64:
+         c = ARITH_MULX;
+         goto gen_arith;
+-- 
+1.7.12.1
+
diff --git a/0090-tcg-sparc-Use-defines-for-temporaries.patch b/0090-tcg-sparc-Use-defines-for-temporaries.patch
new file mode 100644
index 0000000..c837d22
--- /dev/null
+++ b/0090-tcg-sparc-Use-defines-for-temporaries.patch
@@ -0,0 +1,275 @@
+From fc9726f880dea515a2cf98456c5f03a1388e4e14 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Sun, 25 Mar 2012 22:04:59 +0200
+Subject: [PATCH] tcg-sparc: Use defines for temporaries.
+
+And change from %i4/%i5 to %g1/%o7 to remove a v8plus fixme.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/sparc/tcg-target.c | 115 +++++++++++++++++++++++++------------------------
+ 1 file changed, 59 insertions(+), 56 deletions(-)
+
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index be5c170..d401f8e 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -59,8 +59,12 @@ static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
+ };
+ #endif
+ 
++/* Define some temporary registers.  T2 is used for constant generation.  */
++#define TCG_REG_T1  TCG_REG_G1
++#define TCG_REG_T2  TCG_REG_O7
++
+ #ifdef CONFIG_USE_GUEST_BASE
+-# define TCG_GUEST_BASE_REG TCG_REG_I3
++# define TCG_GUEST_BASE_REG TCG_REG_I5
+ #else
+ # define TCG_GUEST_BASE_REG TCG_REG_G0
+ #endif
+@@ -79,6 +83,7 @@ static const int tcg_target_reg_alloc_order[] = {
+     TCG_REG_I2,
+     TCG_REG_I3,
+     TCG_REG_I4,
++    TCG_REG_I5,
+ };
+ 
+ static const int tcg_target_call_iarg_regs[6] = {
+@@ -366,10 +371,10 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
+         tcg_out_sethi(s, ret, ~arg);
+         tcg_out_arithi(s, ret, ret, (arg & 0x3ff) | -0x400, ARITH_XOR);
+     } else {
+-        tcg_out_movi_imm32(s, TCG_REG_I4, arg >> (TCG_TARGET_REG_BITS / 2));
+-        tcg_out_arithi(s, TCG_REG_I4, TCG_REG_I4, 32, SHIFT_SLLX);
+-        tcg_out_movi_imm32(s, ret, arg);
+-        tcg_out_arith(s, ret, ret, TCG_REG_I4, ARITH_OR);
++        tcg_out_movi_imm32(s, ret, arg >> (TCG_TARGET_REG_BITS / 2));
++        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);
+     }
+ }
+ 
+@@ -386,8 +391,8 @@ static inline void tcg_out_ldst(TCGContext *s, int ret, int addr,
+         tcg_out32(s, op | INSN_RD(ret) | INSN_RS1(addr) |
+                   INSN_IMM13(offset));
+     } else {
+-        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, offset);
+-        tcg_out_ldst_rr(s, ret, addr, TCG_REG_I5, op);
++        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, offset);
++        tcg_out_ldst_rr(s, ret, addr, TCG_REG_T1, op);
+     }
+ }
+ 
+@@ -428,8 +433,8 @@ static inline void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
+         if (check_fit_tl(val, 13))
+             tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
+         else {
+-            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val);
+-            tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_ADD);
++            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_T1, val);
++            tcg_out_arith(s, reg, reg, TCG_REG_T1, ARITH_ADD);
+         }
+     }
+ }
+@@ -441,8 +446,8 @@ static inline void tcg_out_andi(TCGContext *s, int rd, int rs,
+         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_I5, val);
+-            tcg_out_arith(s, rd, rs, TCG_REG_I5, ARITH_AND);
++            tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_T1, val);
++            tcg_out_arith(s, rd, rs, TCG_REG_T1, ARITH_AND);
+         }
+     }
+ }
+@@ -454,8 +459,8 @@ static void tcg_out_div32(TCGContext *s, int rd, int rs1,
+     if (uns) {
+         tcg_out_sety(s, TCG_REG_G0);
+     } else {
+-        tcg_out_arithi(s, TCG_REG_I5, rs1, 31, SHIFT_SRA);
+-        tcg_out_sety(s, TCG_REG_I5);
++        tcg_out_arithi(s, TCG_REG_T1, rs1, 31, SHIFT_SRA);
++        tcg_out_sety(s, TCG_REG_T1);
+     }
+ 
+     tcg_out_arithc(s, rd, rs1, val2, val2const,
+@@ -601,8 +606,8 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
+     case TCG_COND_GTU:
+     case TCG_COND_GEU:
+         if (c2const && c2 != 0) {
+-            tcg_out_movi_imm13(s, TCG_REG_I5, c2);
+-            c2 = TCG_REG_I5;
++            tcg_out_movi_imm13(s, TCG_REG_T1, c2);
++            c2 = TCG_REG_T1;
+         }
+         t = c1, c1 = c2, c2 = t, c2const = 0;
+         cond = tcg_swap_cond(cond);
+@@ -649,15 +654,15 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
+ 
+     switch (cond) {
+     case TCG_COND_EQ:
+-        tcg_out_setcond_i32(s, TCG_COND_EQ, TCG_REG_I5, al, bl, blconst);
++        tcg_out_setcond_i32(s, TCG_COND_EQ, TCG_REG_T1, al, bl, blconst);
+         tcg_out_setcond_i32(s, TCG_COND_EQ, ret, ah, bh, bhconst);
+-        tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_AND);
++        tcg_out_arith(s, ret, ret, TCG_REG_T1, ARITH_AND);
+         break;
+ 
+     case TCG_COND_NE:
+-        tcg_out_setcond_i32(s, TCG_COND_NE, TCG_REG_I5, al, al, blconst);
++        tcg_out_setcond_i32(s, TCG_COND_NE, TCG_REG_T1, al, al, blconst);
+         tcg_out_setcond_i32(s, TCG_COND_NE, ret, ah, bh, bhconst);
+-        tcg_out_arith(s, ret, ret, TCG_REG_I5, ARITH_OR);
++        tcg_out_arith(s, ret, ret, TCG_REG_T1, ARITH_OR);
+         break;
+ 
+     default:
+@@ -935,8 +940,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
+ #else
+     addr_reg = args[addrlo_idx];
+     if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
+-        tcg_out_arithi(s, TCG_REG_I5, addr_reg, 0, SHIFT_SRL);
+-        addr_reg = TCG_REG_I5;
++        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) {
+         int reg64 = (datalo < 16 ? datalo : TCG_REG_O0);
+@@ -979,12 +984,11 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
+                                 offsetof(CPUTLBEntry, addr_write));
+ 
+     if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
+-        /* Reconstruct the full 64-bit value in %g1, using %o2 as temp.  */
+-        /* ??? Redefine the temps from %i4/%i5 so that we have a o/g temp. */
+-        tcg_out_arithi(s, TCG_REG_G1, datalo, 0, SHIFT_SRL);
++        /* 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);
+-        tcg_out_arith(s, TCG_REG_G1, TCG_REG_G1, TCG_REG_O2, ARITH_OR);
+-        datalo = TCG_REG_G1;
++        tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
++        datalo = TCG_REG_O2;
+     }
+ 
+     /* The fast path is exactly one insn.  Thus we can perform the entire
+@@ -1024,16 +1028,14 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
+ #else
+     addr_reg = args[addrlo_idx];
+     if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 32) {
+-        tcg_out_arithi(s, TCG_REG_I5, addr_reg, 0, SHIFT_SRL);
+-        addr_reg = TCG_REG_I5;
++        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) {
+-        /* Reconstruct the full 64-bit value in %g1, using %o2 as temp.  */
+-        /* ??? Redefine the temps from %i4/%i5 so that we have a o/g temp. */
+-        tcg_out_arithi(s, TCG_REG_G1, datalo, 0, SHIFT_SRL);
++        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_G1, TCG_REG_G1, TCG_REG_O2, ARITH_OR);
+-        datalo = TCG_REG_G1;
++        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,
+                     (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_G0),
+@@ -1057,28 +1059,29 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+     case INDEX_op_goto_tb:
+         if (s->tb_jmp_offset) {
+             /* direct jump method */
+-            tcg_out_sethi(s, TCG_REG_I5, args[0] & 0xffffe000);
+-            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
++            tcg_out_sethi(s, TCG_REG_T1, args[0] & 0xffffe000);
++            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_T1) |
+                       INSN_IMM13((args[0] & 0x1fff)));
+             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
+         } else {
+             /* indirect jump method */
+-            tcg_out_ld_ptr(s, TCG_REG_I5, (tcg_target_long)(s->tb_next + args[0]));
+-            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |
++            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_nop(s);
+         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+         break;
+     case INDEX_op_call:
+-        if (const_args[0])
++        if (const_args[0]) {
+             tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]
+                                    - (tcg_target_ulong)s->code_ptr) >> 2)
+                                  & 0x3fffffff));
+-        else {
+-            tcg_out_ld_ptr(s, TCG_REG_I5,
++        } 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_I5) |
++            tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_T1) |
+                       INSN_RS2(TCG_REG_G0));
+         }
+         /* delay slot */
+@@ -1184,11 +1187,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+ 
+     case INDEX_op_rem_i32:
+     case INDEX_op_remu_i32:
+-        tcg_out_div32(s, TCG_REG_I5, args[1], args[2], const_args[2],
++        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_I5, TCG_REG_I5, args[2], const_args[2],
++        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_I5, ARITH_SUB);
++        tcg_out_arith(s, args[0], args[1], TCG_REG_T1, ARITH_SUB);
+         break;
+ 
+     case INDEX_op_brcond_i32:
+@@ -1305,11 +1308,11 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+         goto gen_arith;
+     case INDEX_op_rem_i64:
+     case INDEX_op_remu_i64:
+-        tcg_out_arithc(s, TCG_REG_I5, args[1], args[2], const_args[2],
++        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_I5, TCG_REG_I5, args[2], const_args[2],
++        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_I5, ARITH_SUB);
++        tcg_out_arith(s, args[0], args[1], TCG_REG_T1, ARITH_SUB);
+         break;
+     case INDEX_op_ext32s_i64:
+         if (const_args[1]) {
+@@ -1507,15 +1510,15 @@ static void tcg_target_init(TCGContext *s)
+                      (1 << TCG_REG_O7));
+ 
+     tcg_regset_clear(s->reserved_regs);
+-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0);
+-#if TCG_TARGET_REG_BITS == 64
+-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I4); // for internal use
+-#endif
+-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I5); // for internal use
+-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6);
+-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7);
+-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);
+-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
++    tcg_regset_set_reg(s->reserved_regs, TCG_REG_G0); /* zero */
++    tcg_regset_set_reg(s->reserved_regs, TCG_REG_G6); /* reserved for os */
++    tcg_regset_set_reg(s->reserved_regs, TCG_REG_G7); /* thread pointer */
++    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I6); /* frame pointer */
++    tcg_regset_set_reg(s->reserved_regs, TCG_REG_I7); /* return address */
++    tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6); /* stack pointer */
++    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T1); /* for internal use */
++    tcg_regset_set_reg(s->reserved_regs, TCG_REG_T2); /* for internal use */
++
+     tcg_add_target_add_op_defs(sparc_op_defs);
+ }
+ 
+-- 
+1.7.12.1
+
diff --git a/0091-tcg-sparc-Add-g-o-registers-to-alloc_order.patch b/0091-tcg-sparc-Add-g-o-registers-to-alloc_order.patch
new file mode 100644
index 0000000..2bf9e95
--- /dev/null
+++ b/0091-tcg-sparc-Add-g-o-registers-to-alloc_order.patch
@@ -0,0 +1,44 @@
+From ca72cdf648b56d851c4bc9145a1abfcbeeec0579 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Sun, 25 Mar 2012 22:43:17 +0200
+Subject: [PATCH] tcg-sparc: Add %g/%o registers to alloc_order
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/sparc/tcg-target.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index d401f8e..03c385a 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -78,12 +78,25 @@ static const int tcg_target_reg_alloc_order[] = {
+     TCG_REG_L5,
+     TCG_REG_L6,
+     TCG_REG_L7,
++
+     TCG_REG_I0,
+     TCG_REG_I1,
+     TCG_REG_I2,
+     TCG_REG_I3,
+     TCG_REG_I4,
+     TCG_REG_I5,
++
++    TCG_REG_G2,
++    TCG_REG_G3,
++    TCG_REG_G4,
++    TCG_REG_G5,
++
++    TCG_REG_O0,
++    TCG_REG_O1,
++    TCG_REG_O2,
++    TCG_REG_O3,
++    TCG_REG_O4,
++    TCG_REG_O5,
+ };
+ 
+ static const int tcg_target_call_iarg_regs[6] = {
+-- 
+1.7.12.1
+
diff --git a/0092-tcg-sparc-Fix-and-enable-direct-TB-chaining.patch b/0092-tcg-sparc-Fix-and-enable-direct-TB-chaining.patch
new file mode 100644
index 0000000..7b876c0
--- /dev/null
+++ b/0092-tcg-sparc-Fix-and-enable-direct-TB-chaining.patch
@@ -0,0 +1,79 @@
+From 1338a6f18ff9b651c12ee1f7edd1d2b7684bd6aa Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 10:48:51 -0700
+Subject: [PATCH] tcg-sparc: Fix and enable direct TB chaining.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ exec-all.h             |  9 ++++++---
+ tcg/sparc/tcg-target.c | 21 ++++++++++++++++++---
+ 2 files changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/exec-all.h b/exec-all.h
+index c5d3a13..1f81da7 100644
+--- a/exec-all.h
++++ b/exec-all.h
+@@ -132,9 +132,10 @@ static inline void tlb_flush(CPUArchState *env, int flush_global)
+ #define CODE_GEN_AVG_BLOCK_SIZE 64
+ #endif
+ 
+-#if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__) || defined(__i386__)
+-#define USE_DIRECT_JUMP
+-#elif defined(CONFIG_TCG_INTERPRETER)
++#if defined(__arm__) || defined(_ARCH_PPC) \
++    || defined(__x86_64__) || defined(__i386__) \
++    || defined(__sparc__) \
++    || defined(CONFIG_TCG_INTERPRETER)
+ #define USE_DIRECT_JUMP
+ #endif
+ 
+@@ -244,6 +245,8 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
+     __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
+ #endif
+ }
++#elif defined(__sparc__)
++void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);
+ #else
+ #error tb_set_jmp_target1 is missing
+ #endif
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index 03c385a..1db0c9d 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -1072,10 +1072,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+     case INDEX_op_goto_tb:
+         if (s->tb_jmp_offset) {
+             /* direct jump method */
+-            tcg_out_sethi(s, TCG_REG_T1, args[0] & 0xffffe000);
+-            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_T1) |
+-                      INSN_IMM13((args[0] & 0x1fff)));
++            uint32_t old_insn = *(uint32_t *)s->code_ptr;
+             s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
++            /* Make sure to preserve links during retranslation.  */
++            tcg_out32(s, CALL | (old_insn & ~INSN_OP(-1)));
+         } else {
+             /* indirect jump method */
+             tcg_out_ld_ptr(s, TCG_REG_T1,
+@@ -1595,3 +1595,18 @@ void tcg_register_jit(void *buf, size_t buf_size)
+ 
+     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
+ }
++
++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;
++
++    /* 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();
++    }
++
++    *ptr = CALL | (disp & 0x3fffffff);
++    flush_icache_range(jmp_addr, jmp_addr + 4);
++}
+-- 
+1.7.12.1
+
diff --git a/0093-tcg-sparc-Preserve-branch-destinations-during-retran.patch b/0093-tcg-sparc-Preserve-branch-destinations-during-retran.patch
new file mode 100644
index 0000000..167dc41
--- /dev/null
+++ b/0093-tcg-sparc-Preserve-branch-destinations-during-retran.patch
@@ -0,0 +1,60 @@
+From 2cbc27913eb9eb7cdc4a41fc6efafccf3db7ebe6 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 11:00:23 -0700
+Subject: [PATCH] tcg-sparc: Preserve branch destinations during retranslation
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/sparc/tcg-target.c | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
+index 1db0c9d..876da4f 100644
+--- a/tcg/sparc/tcg-target.c
++++ b/tcg/sparc/tcg-target.c
+@@ -488,30 +488,33 @@ static inline void tcg_out_nop(TCGContext *s)
+ static void tcg_out_branch_i32(TCGContext *s, int opc, int label_index)
+ {
+     TCGLabel *l = &s->labels[label_index];
++    uint32_t off22;
+ 
+     if (l->has_value) {
+-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2)
+-                      | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr)));
++        off22 = INSN_OFF22(l->u.value - (unsigned long)s->code_ptr);
+     } else {
++        /* Make sure to preserve destinations during retranslation.  */
++        off22 = *(uint32_t *)s->code_ptr & INSN_OFF22(-1);
+         tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0);
+-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | 0));
+     }
++    tcg_out32(s, INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | off22);
+ }
+ 
+ #if TCG_TARGET_REG_BITS == 64
+ static void tcg_out_branch_i64(TCGContext *s, int opc, int label_index)
+ {
+     TCGLabel *l = &s->labels[label_index];
++    uint32_t off19;
+ 
+     if (l->has_value) {
+-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
+-                      (0x5 << 19) |
+-                      INSN_OFF19(l->u.value - (unsigned long)s->code_ptr)));
++        off19 = INSN_OFF19(l->u.value - (unsigned long)s->code_ptr);
+     } else {
++        /* Make sure to preserve destinations during retranslation.  */
++        off19 = *(uint32_t *)s->code_ptr & INSN_OFF19(-1);
+         tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label_index, 0);
+-        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
+-                      (0x5 << 19) | 0));
+     }
++    tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
++                  (0x5 << 19) | off19));
+ }
+ #endif
+ 
+-- 
+1.7.12.1
+
diff --git a/0094-target-alpha-Initialize-env-cpu_model_str.patch b/0094-target-alpha-Initialize-env-cpu_model_str.patch
new file mode 100644
index 0000000..9734b0e
--- /dev/null
+++ b/0094-target-alpha-Initialize-env-cpu_model_str.patch
@@ -0,0 +1,33 @@
+From fcf8cef0c7d8d197e863c1e8b7bcb567fa1fe729 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 14:15:36 +0200
+Subject: [PATCH] target-alpha: Initialize env->cpu_model_str
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Save the cpu_model_str so that we have a non-null value when
+creating a new cpu during clone.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Andreas Färber <afaerber at suse.de>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-alpha/translate.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/target-alpha/translate.c b/target-alpha/translate.c
+index 4a9011a..3f9aee1 100644
+--- a/target-alpha/translate.c
++++ b/target-alpha/translate.c
+@@ -3543,6 +3543,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
+     }
+     env->implver = implver;
+     env->amask = amask;
++    env->cpu_model_str = cpu_model;
+ 
+     qemu_init_vcpu(env);
+     return env;
+-- 
+1.7.12.1
+
diff --git a/0095-tcg-mips-fix-MIPS32-R2-detection.patch b/0095-tcg-mips-fix-MIPS32-R2-detection.patch
new file mode 100644
index 0000000..e145e3b
--- /dev/null
+++ b/0095-tcg-mips-fix-MIPS32-R2-detection.patch
@@ -0,0 +1,93 @@
+From 66588d01b8cb710d746c249a34f31f7f353bc697 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Sat, 22 Sep 2012 23:08:38 +0200
+Subject: [PATCH] tcg/mips: fix MIPS32(R2) detection
+
+Fix the MIPS32(R2) cpu detection so that it also works with
+-march=octeon. Thanks to Andrew Pinski for the hint.
+
+Cc: Andrew Pinski <apinski at cavium.com>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/mips/tcg-target.c | 10 +++++-----
+ tcg/mips/tcg-target.h |  8 ++++----
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
+index c272b38..e9a1ffb 100644
+--- a/tcg/mips/tcg-target.c
++++ b/tcg/mips/tcg-target.c
+@@ -425,7 +425,7 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
+ 
+ static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
+-#ifdef _MIPS_ARCH_MIPS32R2
++#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+     tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
+ #else
+     /* ret and arg can't be register at */
+@@ -442,7 +442,7 @@ static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
+ 
+ static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
+-#ifdef _MIPS_ARCH_MIPS32R2
++#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+     tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
+     tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
+ #else
+@@ -460,7 +460,7 @@ static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
+ 
+ static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
+-#ifdef _MIPS_ARCH_MIPS32R2
++#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+     tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
+     tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
+ #else
+@@ -486,7 +486,7 @@ static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
+ 
+ static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
+-#ifdef _MIPS_ARCH_MIPS32R2
++#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+     tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
+ #else
+     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
+@@ -496,7 +496,7 @@ static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
+ 
+ static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
+ {
+-#ifdef _MIPS_ARCH_MIPS32R2
++#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+     tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
+ #else
+     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
+diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
+index d147e70..7020d65 100644
+--- a/tcg/mips/tcg-target.h
++++ b/tcg/mips/tcg-target.h
+@@ -88,16 +88,16 @@ typedef enum {
+ #define TCG_TARGET_HAS_nand_i32         0
+ 
+ /* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
+-#if defined(_MIPS_ARCH_MIPS4) || defined(_MIPS_ARCH_MIPS32) || \
+-    defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_LOONGSON2E) || \
+-    defined(_MIPS_ARCH_LOONGSON2F)
++#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
++    defined(_MIPS_ARCH_LOONGSON2E) || defined(_MIPS_ARCH_LOONGSON2F) || \
++    defined(_MIPS_ARCH_MIPS4)
+ #define TCG_TARGET_HAS_movcond_i32      1
+ #else
+ #define TCG_TARGET_HAS_movcond_i32      0
+ #endif
+ 
+ /* optional instructions only implemented on MIPS32R2 */
+-#ifdef _MIPS_ARCH_MIPS32R2
++#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+ #define TCG_TARGET_HAS_bswap16_i32      1
+ #define TCG_TARGET_HAS_bswap32_i32      1
+ #define TCG_TARGET_HAS_rot_i32          1
+-- 
+1.7.12.1
+
diff --git a/0096-tcg-Adjust-descriptions-of-cond-opcodes.patch b/0096-tcg-Adjust-descriptions-of-cond-opcodes.patch
new file mode 100644
index 0000000..64c62cb
--- /dev/null
+++ b/0096-tcg-Adjust-descriptions-of-cond-opcodes.patch
@@ -0,0 +1,67 @@
+From a2c90b264762d3ddcc9a830653315a6fe9107055 Mon Sep 17 00:00:00 2001
+From: Richard Henderson <rth at twiddle.net>
+Date: Fri, 21 Sep 2012 17:18:09 -0700
+Subject: [PATCH] tcg: Adjust descriptions of *cond opcodes
+
+The README file documented the operand ordering of the tcg_gen_*
+functions.  Since we're documenting opcodes here, use the true
+operand ordering.
+
+Signed-off-by: Richard Henderson <rth at twiddle.net>
+Cc: malc <av1474 at comtv.ru>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/README | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/tcg/README b/tcg/README
+index 33783ee..27846f1 100644
+--- a/tcg/README
++++ b/tcg/README
+@@ -141,7 +141,7 @@ Define label 'label' at the current program point.
+ 
+ Jump to label.
+ 
+-* brcond_i32/i64 cond, t0, t1, label
++* brcond_i32/i64 t0, t1, cond, label
+ 
+ Conditional jump if t0 cond t1 is true. cond can be:
+     TCG_COND_EQ
+@@ -301,13 +301,13 @@ This operation would be equivalent to
+ 
+ ********* Conditional moves
+ 
+-* setcond_i32/i64 cond, dest, t1, t2
++* setcond_i32/i64 dest, t1, t2, cond
+ 
+ dest = (t1 cond t2)
+ 
+ Set DEST to 1 if (T1 cond T2) is true, otherwise set to 0.
+ 
+-* movcond_i32/i64 cond, dest, c1, c2, v1, v2
++* movcond_i32/i64 dest, c1, c2, v1, v2, cond
+ 
+ dest = (c1 cond c2 ? v1 : v2)
+ 
+@@ -360,7 +360,7 @@ The following opcodes are internal to TCG.  Thus they are to be implemented by
+ 32-bit host code generators, but are not to be emitted by guest translators.
+ They are emitted as needed by inline functions within "tcg-op.h".
+ 
+-* brcond2_i32 cond, t0_low, t0_high, t1_low, t1_high, label
++* brcond2_i32 t0_low, t0_high, t1_low, t1_high, cond, label
+ 
+ Similar to brcond, except that the 64-bit values T0 and T1
+ are formed from two 32-bit arguments.
+@@ -377,7 +377,7 @@ is returned in two 32-bit outputs.
+ Similar to mul, except two 32-bit (unsigned) inputs T1 and T2 yielding
+ the full 64-bit product T0.  The later is returned in two 32-bit outputs.
+ 
+-* setcond2_i32 cond, dest, t1_low, t1_high, t2_low, t2_high
++* setcond2_i32 dest, t1_low, t1_high, t2_low, t2_high, cond
+ 
+ Similar to setcond, except that the 64-bit values T1 and T2 are
+ formed from two 32-bit arguments.  The result is a 32-bit value.
+-- 
+1.7.12.1
+
diff --git a/0097-tcg-i386-fix-build-with-march-i686.patch b/0097-tcg-i386-fix-build-with-march-i686.patch
new file mode 100644
index 0000000..a841086
--- /dev/null
+++ b/0097-tcg-i386-fix-build-with-march-i686.patch
@@ -0,0 +1,34 @@
+From 5d3868bb343df0c13240521e36d0cc942c7a2d04 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Wed, 26 Sep 2012 00:30:12 +0200
+Subject: [PATCH] tcg/i386: fix build with -march < i686
+
+The movcond_i32 op has to be protected with TCG_TARGET_HAS_movcond_i32
+to fix the build with -march < i686.
+
+Thanks to Richard Henderson for the hint.
+
+Reported-by: Alex Barcelo <abarcelo at ac.upc.edu>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/i386/tcg-target.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
+index 85c6b81..616ef23 100644
+--- a/tcg/i386/tcg-target.c
++++ b/tcg/i386/tcg-target.c
+@@ -1907,7 +1907,9 @@ static const TCGTargetOpDef x86_op_defs[] = {
+     { INDEX_op_setcond_i32, { "q", "r", "ri" } },
+ 
+     { INDEX_op_deposit_i32, { "Q", "0", "Q" } },
++#if TCG_TARGET_HAS_movcond_i32
+     { INDEX_op_movcond_i32, { "r", "r", "ri", "r", "0" } },
++#endif
+ 
+ #if TCG_TARGET_REG_BITS == 32
+     { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
+-- 
+1.7.12.1
+
diff --git a/0098-tcg-Fix-MAX_OPC_PARAM_IARGS.patch b/0098-tcg-Fix-MAX_OPC_PARAM_IARGS.patch
new file mode 100644
index 0000000..dfc44fa
--- /dev/null
+++ b/0098-tcg-Fix-MAX_OPC_PARAM_IARGS.patch
@@ -0,0 +1,52 @@
+From 86aeba1e72542270a2ae2570cdfcfa6b9e59eeb8 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Wed, 12 Sep 2012 19:18:55 +0200
+Subject: [PATCH] tcg: Fix MAX_OPC_PARAM_IARGS
+
+DEF_HELPER_FLAGS_5 was added some time ago without adjusting
+MAX_OPC_PARAM_IARGS.
+
+Fixing the definition becomes more important as QEMU is using
+an increasing number of helper functions called with 5 arguments.
+
+Add also a comment to avoid future problems when DEF_HELPER_FLAGS_6
+will be added.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Reviewed-by: Richard Henderson <rth at twiddle.net>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ def-helper.h | 2 ++
+ exec-all.h   | 2 +-
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/def-helper.h b/def-helper.h
+index b98ff69..022a9ce 100644
+--- a/def-helper.h
++++ b/def-helper.h
+@@ -128,6 +128,8 @@
+ #define DEF_HELPER_5(name, ret, t1, t2, t3, t4, t5) \
+     DEF_HELPER_FLAGS_5(name, 0, ret, t1, t2, t3, t4, t5)
+ 
++/* MAX_OPC_PARAM_IARGS must be set to n if last entry is DEF_HELPER_FLAGS_n. */
++
+ #endif /* DEF_HELPER_H */
+ 
+ #ifndef GEN_HELPER
+diff --git a/exec-all.h b/exec-all.h
+index 1f81da7..6516da0 100644
+--- a/exec-all.h
++++ b/exec-all.h
+@@ -51,7 +51,7 @@ typedef struct TranslationBlock TranslationBlock;
+ #else
+ #define MAX_OPC_PARAM_PER_ARG 1
+ #endif
+-#define MAX_OPC_PARAM_IARGS 4
++#define MAX_OPC_PARAM_IARGS 5
+ #define MAX_OPC_PARAM_OARGS 1
+ #define MAX_OPC_PARAM_ARGS (MAX_OPC_PARAM_IARGS + MAX_OPC_PARAM_OARGS)
+ 
+-- 
+1.7.12.1
+
diff --git a/0099-tci-Fix-for-AREG0-free-mode.patch b/0099-tci-Fix-for-AREG0-free-mode.patch
new file mode 100644
index 0000000..c67e4a3
--- /dev/null
+++ b/0099-tci-Fix-for-AREG0-free-mode.patch
@@ -0,0 +1,119 @@
+From 2acbc7d596b022dca4fc147eb89e3d5f297acb1f Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Tue, 18 Sep 2012 22:43:38 +0200
+Subject: [PATCH] tci: Fix for AREG0 free mode
+
+Support for helper functions with 5 arguments was missing
+in the code generator and in the interpreter.
+
+There is no need to pass the constant TCG_AREG0 from the
+code generator to the interpreter. Remove that code for
+the INDEX_op_qemu_st* opcodes.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ tcg/tci/tcg-target.c | 10 +++++-----
+ tci.c                | 13 +++++++++----
+ 2 files changed, 14 insertions(+), 9 deletions(-)
+
+diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
+index 003244c..c8c2f1d 100644
+--- a/tcg/tci/tcg-target.c
++++ b/tcg/tci/tcg-target.c
+@@ -300,7 +300,7 @@ static const int tcg_target_reg_alloc_order[] = {
+ #endif
+ };
+ 
+-#if MAX_OPC_PARAM_IARGS != 4
++#if MAX_OPC_PARAM_IARGS != 5
+ # error Fix needed, number of supported input arguments changed!
+ #endif
+ 
+@@ -309,16 +309,18 @@ static const int tcg_target_call_iarg_regs[] = {
+     TCG_REG_R1,
+     TCG_REG_R2,
+     TCG_REG_R3,
+-#if TCG_TARGET_REG_BITS == 32
+-    /* 32 bit hosts need 2 * MAX_OPC_PARAM_IARGS registers. */
+ #if 0 /* used for TCG_REG_CALL_STACK */
+     TCG_REG_R4,
+ #endif
+     TCG_REG_R5,
++#if TCG_TARGET_REG_BITS == 32
++    /* 32 bit hosts need 2 * MAX_OPC_PARAM_IARGS registers. */
+     TCG_REG_R6,
+     TCG_REG_R7,
+ #if TCG_TARGET_NB_REGS >= 16
+     TCG_REG_R8,
++    TCG_REG_R9,
++    TCG_REG_R10,
+ #else
+ # error Too few input registers available
+ #endif
+@@ -798,7 +800,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+     case INDEX_op_qemu_st8:
+     case INDEX_op_qemu_st16:
+     case INDEX_op_qemu_st32:
+-        tcg_out_r(s, TCG_AREG0);
+         tcg_out_r(s, *args++);
+         tcg_out_r(s, *args++);
+ #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
+@@ -809,7 +810,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
+ #endif
+         break;
+     case INDEX_op_qemu_st64:
+-        tcg_out_r(s, TCG_AREG0);
+         tcg_out_r(s, *args++);
+ #if TCG_TARGET_REG_BITS == 32
+         tcg_out_r(s, *args++);
+diff --git a/tci.c b/tci.c
+index ce8a988..a4f7b78 100644
+--- a/tci.c
++++ b/tci.c
+@@ -36,17 +36,19 @@
+         tcg_abort(); \
+     } while (0)
+ 
+-#if MAX_OPC_PARAM_IARGS != 4
++#if MAX_OPC_PARAM_IARGS != 5
+ # error Fix needed, number of supported input arguments changed!
+ #endif
+ #if TCG_TARGET_REG_BITS == 32
+ typedef uint64_t (*helper_function)(tcg_target_ulong, tcg_target_ulong,
+                                     tcg_target_ulong, tcg_target_ulong,
+                                     tcg_target_ulong, tcg_target_ulong,
++                                    tcg_target_ulong, tcg_target_ulong,
+                                     tcg_target_ulong, tcg_target_ulong);
+ #else
+ typedef uint64_t (*helper_function)(tcg_target_ulong, tcg_target_ulong,
+-                                    tcg_target_ulong, tcg_target_ulong);
++                                    tcg_target_ulong, tcg_target_ulong,
++                                    tcg_target_ulong);
+ #endif
+ 
+ /* TCI can optionally use a global register variable for env. */
+@@ -489,14 +491,17 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
+                                           tci_read_reg(TCG_REG_R5),
+                                           tci_read_reg(TCG_REG_R6),
+                                           tci_read_reg(TCG_REG_R7),
+-                                          tci_read_reg(TCG_REG_R8));
++                                          tci_read_reg(TCG_REG_R8),
++                                          tci_read_reg(TCG_REG_R9),
++                                          tci_read_reg(TCG_REG_R10));
+             tci_write_reg(TCG_REG_R0, tmp64);
+             tci_write_reg(TCG_REG_R1, tmp64 >> 32);
+ #else
+             tmp64 = ((helper_function)t0)(tci_read_reg(TCG_REG_R0),
+                                           tci_read_reg(TCG_REG_R1),
+                                           tci_read_reg(TCG_REG_R2),
+-                                          tci_read_reg(TCG_REG_R3));
++                                          tci_read_reg(TCG_REG_R3),
++                                          tci_read_reg(TCG_REG_R5));
+             tci_write_reg(TCG_REG_R0, tmp64);
+ #endif
+             break;
+-- 
+1.7.12.1
+
diff --git a/0201-spice-abort-on-invalid-streaming-cmdline-params.patch b/0100-spice-abort-on-invalid-streaming-cmdline-params.patch
similarity index 82%
rename from 0201-spice-abort-on-invalid-streaming-cmdline-params.patch
rename to 0100-spice-abort-on-invalid-streaming-cmdline-params.patch
index fa5c5b1..d73d347 100644
--- a/0201-spice-abort-on-invalid-streaming-cmdline-params.patch
+++ b/0100-spice-abort-on-invalid-streaming-cmdline-params.patch
@@ -1,7 +1,7 @@
-From 46851363e2aed89fc535803c8a23f6bed9934312 Mon Sep 17 00:00:00 2001
+From 9fa75115d0f300817a372dd8b9460d6b65a30b20 Mon Sep 17 00:00:00 2001
 From: Christophe Fergeau <cfergeau at redhat.com>
 Date: Mon, 13 Aug 2012 10:32:32 +0200
-Subject: [PATCH 201/215] spice: abort on invalid streaming cmdline params
+Subject: [PATCH] spice: abort on invalid streaming cmdline params
 
 When parsing its command line parameters, spice aborts when it
 finds unexpected values, except for the 'streaming-video' option.
@@ -15,6 +15,9 @@ so let's change to that now.
 Fixes rhbz#831708
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 835cab85ad83ed8dfe1c13243aeda5959b153e3e)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  ui/spice-core.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)
@@ -34,5 +37,5 @@ index 4fc48f8..bb4f585 100644
  static const char *compression_names[] = {
      [ SPICE_IMAGE_COMPRESS_OFF ]      = "off",
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0202-spice-notify-spice-server-on-vm-start-stop.patch b/0101-spice-notify-spice-server-on-vm-start-stop.patch
similarity index 84%
rename from 0202-spice-notify-spice-server-on-vm-start-stop.patch
rename to 0101-spice-notify-spice-server-on-vm-start-stop.patch
index 150bb5c..708bfe0 100644
--- a/0202-spice-notify-spice-server-on-vm-start-stop.patch
+++ b/0101-spice-notify-spice-server-on-vm-start-stop.patch
@@ -1,7 +1,7 @@
-From 2d2ccb50223c16fbf08140b9dd59275657de2a61 Mon Sep 17 00:00:00 2001
+From 7fbcbd48d2898935369b443a489ea79d49fe19c4 Mon Sep 17 00:00:00 2001
 From: Yonit Halperin <yhalperi at redhat.com>
 Date: Tue, 21 Aug 2012 11:51:55 +0300
-Subject: [PATCH 202/215] spice: notify spice server on vm start/stop
+Subject: [PATCH] spice: notify spice server on vm start/stop
 
 Spice server needs to know about the vm state in order to prevent
 attempts to write to devices when they are stopped, mainly during
@@ -11,6 +11,9 @@ target side, after migration completes.
 
 Signed-off-by: Yonit Halperin <yhalperi at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit f5bb039c6d97ef3e664094eab3c9a4dc1824ed73)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  ui/spice-core.c | 14 ++++++++++++++
  1 file changed, 14 insertions(+)
@@ -48,5 +51,5 @@ index bb4f585..a515c94 100644
      g_free(x509_cert_file);
      g_free(x509_cacert_file);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0203-spice-notify-on-vm-state-change-only-via-spice_serve.patch b/0102-spice-notify-on-vm-state-change-only-via-spice_serve.patch
similarity index 95%
rename from 0203-spice-notify-on-vm-state-change-only-via-spice_serve.patch
rename to 0102-spice-notify-on-vm-state-change-only-via-spice_serve.patch
index e0b42d0..c599743 100644
--- a/0203-spice-notify-on-vm-state-change-only-via-spice_serve.patch
+++ b/0102-spice-notify-on-vm-state-change-only-via-spice_serve.patch
@@ -1,13 +1,16 @@
-From f7d481b35b63f2df58aaef5afcac5ca1e67ce233 Mon Sep 17 00:00:00 2001
+From c50f358fbd549b5ec3b5dd82e29ed06ce969e50a Mon Sep 17 00:00:00 2001
 From: Yonit Halperin <yhalperi at redhat.com>
 Date: Tue, 21 Aug 2012 11:51:56 +0300
-Subject: [PATCH 203/215] spice: notify on vm state change only via
+Subject: [PATCH] spice: notify on vm state change only via
  spice_server_vm_start/stop
 
 QXLWorker->start/stop are deprecated since spice-server 0.11.2
 
 Signed-off-by: Yonit Halperin <yhalperi at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 71d388d420e68ac77cd42f15f7e68cf5a6fb01b2)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/qxl.c           |  7 ++++---
  ui/spice-core.c    |  4 ++++
@@ -166,5 +169,5 @@ index 12e50b6..672d65e 100644
 +#endif
 +int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0204-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch b/0103-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch
similarity index 91%
rename from 0204-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch
rename to 0103-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch
index 631271a..e8580c2 100644
--- a/0204-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch
+++ b/0103-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch
@@ -1,7 +1,7 @@
-From d8543fcc36b38c76a638d15ed95d8b5acf27d93a Mon Sep 17 00:00:00 2001
+From 8470a0f943e8605739b7bc0081507f787bed412d Mon Sep 17 00:00:00 2001
 From: Yonit Halperin <yhalperi at redhat.com>
 Date: Tue, 21 Aug 2012 11:51:57 +0300
-Subject: [PATCH 204/215] spice migration: add QEVENT_SPICE_MIGRATE_COMPLETED
+Subject: [PATCH] spice migration: add QEVENT_SPICE_MIGRATE_COMPLETED
 
 When migrating, libvirt queries the migration status, and upon migration
 completions, it closes the migration src. On the other hand, when
@@ -14,6 +14,9 @@ for this event before quitting the src process.
 
 Signed-off-by: Yonit Halperin <yhalperi at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 2fdd16e239c2a2763aa3266e637718123328688c)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  monitor.c       | 1 +
  monitor.h       | 1 +
@@ -21,7 +24,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  3 files changed, 10 insertions(+), 1 deletion(-)
 
 diff --git a/monitor.c b/monitor.c
-index c14698d..99eee98 100644
+index 29e4287..f45cf92 100644
 --- a/monitor.c
 +++ b/monitor.c
 @@ -455,6 +455,7 @@ static const char *monitor_event_names[] = {
@@ -86,5 +89,5 @@ index 1a7a773..851e869 100644
          spice_server_migrate_end(spice_server, true);
      } else if (migration_has_failed(s)) {
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0205-spice-add-migrated-flag-to-spice-info.patch b/0104-spice-add-migrated-flag-to-spice-info.patch
similarity index 92%
rename from 0205-spice-add-migrated-flag-to-spice-info.patch
rename to 0104-spice-add-migrated-flag-to-spice-info.patch
index 0e63c64..0247edd 100644
--- a/0205-spice-add-migrated-flag-to-spice-info.patch
+++ b/0104-spice-add-migrated-flag-to-spice-info.patch
@@ -1,7 +1,7 @@
-From ad7734d7a3cb4560dcc0bef2794adeddc793af75 Mon Sep 17 00:00:00 2001
+From a4155f1a9fac362bfc1558790de9ea4cdb0a3c8a Mon Sep 17 00:00:00 2001
 From: Yonit Halperin <yhalperi at redhat.com>
 Date: Tue, 21 Aug 2012 11:51:58 +0300
-Subject: [PATCH 205/215] spice: add 'migrated' flag to spice info
+Subject: [PATCH] spice: add 'migrated' flag to spice info
 
 The flag is 'true' when spice migration has completed on the src side.
 It is needed for a case where libvirt dies before migration completes
@@ -11,6 +11,9 @@ to query spice and check if its migration has completed.
 
 Signed-off-by: Yonit Halperin <yhalperi at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 61c4efe2cb85b0a9c6bc68f6a2dd107c8d7ec080)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hmp.c            | 2 ++
  qapi-schema.json | 5 ++++-
@@ -90,5 +93,5 @@ index 851e869..ab069c5 100644
          spice_server_migrate_end(spice_server, true);
      } else if (migration_has_failed(s)) {
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0206-spice-adding-seamless-migration-option-to-the-comman.patch b/0105-spice-adding-seamless-migration-option-to-the-comman.patch
similarity index 89%
rename from 0206-spice-adding-seamless-migration-option-to-the-comman.patch
rename to 0105-spice-adding-seamless-migration-option-to-the-comman.patch
index ac0e9a7..70eb7c0 100644
--- a/0206-spice-adding-seamless-migration-option-to-the-comman.patch
+++ b/0105-spice-adding-seamless-migration-option-to-the-comman.patch
@@ -1,8 +1,7 @@
-From 978a72a62c36e932a4b7ae18a5cf23d2d30e9755 Mon Sep 17 00:00:00 2001
+From b15c26620bb765e25c96163383d79c1c56df7901 Mon Sep 17 00:00:00 2001
 From: Yonit Halperin <yhalperi at redhat.com>
 Date: Tue, 21 Aug 2012 11:51:59 +0300
-Subject: [PATCH 206/215] spice: adding seamless-migration option to the
- command line
+Subject: [PATCH] spice: adding seamless-migration option to the command line
 
 The seamless-migration flag is required in order to identify
 whether libvirt supports the new QEVENT_SPICE_MIGRATE_COMPLETED or not
@@ -13,6 +12,9 @@ can result in data loss.
 
 Signed-off-by: Yonit Halperin <yhalperi at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 8c9570530c819821b9b5cc3113d2b2966afe7621)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  qemu-config.c   | 3 +++
  qemu-options.hx | 3 +++
@@ -73,5 +75,5 @@ index ab069c5..ba0d0bd 100644
          error_report("failed to initialize spice server");
          exit(1);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0207-spice-increase-the-verbosity-of-spice-section-in-qem.patch b/0106-spice-increase-the-verbosity-of-spice-section-in-qem.patch
similarity index 86%
rename from 0207-spice-increase-the-verbosity-of-spice-section-in-qem.patch
rename to 0106-spice-increase-the-verbosity-of-spice-section-in-qem.patch
index 6440642..24ad9ff 100644
--- a/0207-spice-increase-the-verbosity-of-spice-section-in-qem.patch
+++ b/0106-spice-increase-the-verbosity-of-spice-section-in-qem.patch
@@ -1,14 +1,17 @@
-From 54704702dbbb1d55f2aaecf5c837a583d9e209a5 Mon Sep 17 00:00:00 2001
+From 589cb6a669e11e1ce4b077e8ba0fbb9fc8d5bd40 Mon Sep 17 00:00:00 2001
 From: Yonit Halperin <yhalperi at redhat.com>
 Date: Tue, 21 Aug 2012 13:54:20 +0300
-Subject: [PATCH 207/215] spice: increase the verbosity of spice section in
- "qemu --help"
+Subject: [PATCH] spice: increase the verbosity of spice section in "qemu
+ --help"
 
 Added all spice options to the help string. This can be used by libvirt
 to determine which spice related features are supported by qemu.
 
 Signed-off-by: Yonit Halperin <yhalperi at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 27af778828db9aa893fa1de928744141e5de20e5)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  qemu-options.hx | 18 +++++++++++++++++-
  1 file changed, 17 insertions(+), 1 deletion(-)
@@ -43,5 +46,5 @@ index dd7aa63..1af4fec 100644
  @item -spice @var{option}[, at var{option}[,...]]
  @findex -spice
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0208-qxl-update_area_io-guest_bug-on-invalid-parameters.patch b/0107-qxl-update_area_io-guest_bug-on-invalid-parameters.patch
similarity index 80%
rename from 0208-qxl-update_area_io-guest_bug-on-invalid-parameters.patch
rename to 0107-qxl-update_area_io-guest_bug-on-invalid-parameters.patch
index beefe40..7572299 100644
--- a/0208-qxl-update_area_io-guest_bug-on-invalid-parameters.patch
+++ b/0107-qxl-update_area_io-guest_bug-on-invalid-parameters.patch
@@ -1,10 +1,13 @@
-From c3236169b390617d13ede20ff0aed5d0bc1aba66 Mon Sep 17 00:00:00 2001
+From 8a3d428e1e0f3e4793b1a1353c638e155a3a8a86 Mon Sep 17 00:00:00 2001
 From: Alon Levy <alevy at redhat.com>
 Date: Tue, 21 Aug 2012 13:51:31 +0300
-Subject: [PATCH 208/215] qxl/update_area_io: guest_bug on invalid parameters
+Subject: [PATCH] qxl/update_area_io: guest_bug on invalid parameters
 
 Signed-off-by: Alon Levy <alevy at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 511b13e2c9b426b3c56060909693de5097f0b496)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/qxl.c | 12 ++++++++++++
  1 file changed, 12 insertions(+)
@@ -33,5 +36,5 @@ index 95bbc03..baf9bb4 100644
              cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
                                      QXL_IO_UPDATE_AREA_ASYNC);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0210-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch b/0108-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch
similarity index 89%
rename from 0210-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch
rename to 0108-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch
index a628f52..50dbee0 100644
--- a/0210-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch
+++ b/0108-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch
@@ -1,7 +1,7 @@
-From cc8b6a27e848cb88a4df98d48517c5b658d70efc Mon Sep 17 00:00:00 2001
+From e9062966428416da41ec5f9ace3d2ef58b3265b1 Mon Sep 17 00:00:00 2001
 From: Alon Levy <alevy at redhat.com>
 Date: Wed, 22 Aug 2012 11:16:25 +0300
-Subject: [PATCH 210/215] qxl: add QXL_IO_MONITORS_CONFIG_ASYNC
+Subject: [PATCH] qxl: add QXL_IO_MONITORS_CONFIG_ASYNC
 
 Revision bumped to 4 for new IO support, enabled for spice-server >=
 0.11.1. New io enabled if revision is 4. Revision can be set to 4.
@@ -25,19 +25,26 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
 fixup
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 020af1c45fec664d5d4cf3b8e5117f8bc1d691f2)
+
+Conflicts:
+
+	hw/qxl.c
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  configure          |  7 ++++
- hw/qxl.c           | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++---
+ hw/qxl.c           | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
  hw/qxl.h           |  7 ++++
  trace-events       |  1 +
  ui/spice-display.h |  1 +
- 5 files changed, 109 insertions(+), 4 deletions(-)
+ 5 files changed, 111 insertions(+), 3 deletions(-)
 
 diff --git a/configure b/configure
-index 9fc4fb5..c57d1c1 100755
+index 8ffddf4..b5cea26 100755
 --- a/configure
 +++ b/configure
-@@ -2711,6 +2711,9 @@ EOF
+@@ -2670,6 +2670,9 @@ EOF
      spice="yes"
      libs_softmmu="$libs_softmmu $spice_libs"
      QEMU_CFLAGS="$QEMU_CFLAGS $spice_cflags"
@@ -47,7 +54,7 @@ index 9fc4fb5..c57d1c1 100755
    else
      if test "$spice" = "yes" ; then
        feature_not_found "spice"
-@@ -3448,6 +3451,10 @@ if test "$spice" = "yes" ; then
+@@ -3407,6 +3410,10 @@ if test "$spice" = "yes" ; then
    echo "CONFIG_SPICE=y" >> $config_host_mak
  fi
  
@@ -59,7 +66,7 @@ index 9fc4fb5..c57d1c1 100755
    echo "CONFIG_SMARTCARD=y" >> $config_host_mak
  fi
 diff --git a/hw/qxl.c b/hw/qxl.c
-index d134a70..adf17fd 100644
+index baf9bb4..27f3779 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
 @@ -27,6 +27,11 @@
@@ -180,11 +187,10 @@ index d134a70..adf17fd 100644
      default:
          qxl_set_guest_bug(d, "%s: unexpected ioport=0x%x\n", __func__, io_port);
      }
-@@ -1798,9 +1851,17 @@ static int qxl_init_common(PCIQXLDevice *qxl)
+@@ -1798,6 +1851,17 @@ static int qxl_init_common(PCIQXLDevice *qxl)
          io_size = 16;
          break;
      case 3: /* qxl-3 */
--        pci_device_rev = QXL_DEFAULT_REVISION;
 +        pci_device_rev = QXL_REVISION_STABLE_V10;
 +        io_size = 32; /* PCI region size must be pow2 */
 +        break;
@@ -193,13 +199,13 @@ index d134a70..adf17fd 100644
 +        defined(CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC)
 +    case 4: /* qxl-4 */
 +        pci_device_rev = QXL_REVISION_STABLE_V12;
-         io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
-         break;
++        io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
++        break;
 +#endif
      default:
-         error_report("Invalid revision %d for qxl device (max %d)",
-                      qxl->revision, QXL_DEFAULT_REVISION);
-@@ -1999,7 +2060,9 @@ static int qxl_post_load(void *opaque, int version)
+         pci_device_rev = QXL_DEFAULT_REVISION;
+         io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
+@@ -1996,7 +2060,9 @@ static int qxl_post_load(void *opaque, int version)
          }
          qxl_spice_loadvm_commands(d, cmds, out);
          g_free(cmds);
@@ -210,7 +216,7 @@ index d134a70..adf17fd 100644
          break;
      case QXL_MODE_COMPAT:
          /* note: no need to call qxl_create_memslots, qxl_set_mode
-@@ -2012,6 +2075,14 @@ static int qxl_post_load(void *opaque, int version)
+@@ -2009,6 +2075,14 @@ static int qxl_post_load(void *opaque, int version)
  
  #define QXL_SAVE_VERSION 21
  
@@ -225,7 +231,7 @@ index d134a70..adf17fd 100644
  static VMStateDescription qxl_memslot = {
      .name               = "qxl-memslot",
      .version_id         = QXL_SAVE_VERSION,
-@@ -2042,6 +2113,16 @@ static VMStateDescription qxl_surface = {
+@@ -2039,6 +2113,16 @@ static VMStateDescription qxl_surface = {
      }
  };
  
@@ -242,7 +248,7 @@ index d134a70..adf17fd 100644
  static VMStateDescription qxl_vmstate = {
      .name               = "qxl",
      .version_id         = QXL_SAVE_VERSION,
-@@ -2049,7 +2130,7 @@ static VMStateDescription qxl_vmstate = {
+@@ -2046,7 +2130,7 @@ static VMStateDescription qxl_vmstate = {
      .pre_save           = qxl_pre_save,
      .pre_load           = qxl_pre_load,
      .post_load          = qxl_post_load,
@@ -251,7 +257,7 @@ index d134a70..adf17fd 100644
          VMSTATE_PCI_DEVICE(pci, PCIQXLDevice),
          VMSTATE_STRUCT(vga, PCIQXLDevice, 0, vmstate_vga_common, VGACommonState),
          VMSTATE_UINT32(shadow_rom.mode, PCIQXLDevice),
-@@ -2068,6 +2149,14 @@ static VMStateDescription qxl_vmstate = {
+@@ -2065,6 +2149,14 @@ static VMStateDescription qxl_vmstate = {
          VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
          VMSTATE_END_OF_LIST()
      },
@@ -293,10 +299,10 @@ index 172baf6..9cfedb7 100644
  /* qxl.c */
  void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
 diff --git a/trace-events b/trace-events
-index 0de70d9..a58b0b7 100644
+index 04b0723..8fcbc50 100644
 --- a/trace-events
 +++ b/trace-events
-@@ -967,6 +967,7 @@ qxl_spice_destroy_surfaces(int qid, int async) "%d async=%d"
+@@ -956,6 +956,7 @@ qxl_spice_destroy_surfaces(int qid, int async) "%d async=%d"
  qxl_spice_destroy_surface_wait_complete(int qid, uint32_t id) "%d sid=%d"
  qxl_spice_destroy_surface_wait(int qid, uint32_t id, int async) "%d sid=%d async=%d"
  qxl_spice_flush_surfaces_async(int qid, uint32_t surface_count, uint32_t num_free_res) "%d s#=%d, res#=%d"
@@ -317,5 +323,5 @@ index 672d65e..bcff114 100644
  
  typedef struct QXLCookie {
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0211-configure-print-spice-protocol-and-spice-server-vers.patch b/0109-configure-print-spice-protocol-and-spice-server-vers.patch
similarity index 73%
rename from 0211-configure-print-spice-protocol-and-spice-server-vers.patch
rename to 0109-configure-print-spice-protocol-and-spice-server-vers.patch
index 711256c..9e7f529 100644
--- a/0211-configure-print-spice-protocol-and-spice-server-vers.patch
+++ b/0109-configure-print-spice-protocol-and-spice-server-vers.patch
@@ -1,20 +1,22 @@
-From 1d2790682dfac06c2358ac99f5e0bad6a065702d Mon Sep 17 00:00:00 2001
+From b132bd0cdb4d684105b91a8173c172296cd191af Mon Sep 17 00:00:00 2001
 From: Alon Levy <alevy at redhat.com>
 Date: Wed, 22 Aug 2012 11:16:26 +0300
-Subject: [PATCH 211/215] configure: print spice-protocol and spice-server
- versions
+Subject: [PATCH] configure: print spice-protocol and spice-server versions
 
 Signed-off-by: Alon Levy <alevy at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 2e0e3c399aa8067148055b9ea0edb822c5b584d2)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  configure | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)
 
 diff --git a/configure b/configure
-index c57d1c1..25c406f 100755
+index b5cea26..d7a948f 100755
 --- a/configure
 +++ b/configure
-@@ -2711,6 +2711,8 @@ EOF
+@@ -2670,6 +2670,8 @@ EOF
      spice="yes"
      libs_softmmu="$libs_softmmu $spice_libs"
      QEMU_CFLAGS="$QEMU_CFLAGS $spice_cflags"
@@ -23,7 +25,7 @@ index c57d1c1..25c406f 100755
      if $pkg_config --atleast-version=0.12.0 spice-protocol >/dev/null 2>&1; then
          spice_qxl_io_monitors_config_async="yes"
      fi
-@@ -3169,7 +3171,7 @@ echo "libcap-ng support $cap_ng"
+@@ -3128,7 +3130,7 @@ echo "libcap-ng support $cap_ng"
  echo "vhost-net support $vhost_net"
  echo "Trace backend     $trace_backend"
  echo "Trace output file $trace_file-<pid>"
@@ -33,5 +35,5 @@ index c57d1c1..25c406f 100755
  echo "xfsctl support    $xfs"
  echo "nss used          $smartcard_nss"
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0110-fix-doc-of-using-raw-values-with-sendkey.patch b/0110-fix-doc-of-using-raw-values-with-sendkey.patch
new file mode 100644
index 0000000..9e59097
--- /dev/null
+++ b/0110-fix-doc-of-using-raw-values-with-sendkey.patch
@@ -0,0 +1,42 @@
+From 211b2548bfbdab72051a7ef1e9982ff4ec0fd98f Mon Sep 17 00:00:00 2001
+From: Amos Kong <akong at redhat.com>
+Date: Fri, 31 Aug 2012 10:56:20 +0800
+Subject: [PATCH] fix doc of using raw values with sendkey
+
+(qemu) sendkey a
+(qemu) sendkey 0x1e
+(qemu) sendkey #0x1e
+ unknown key: '#0x1e'
+
+The last command doesn't work, '#' is not requested before
+raw values, and the raw value in decimal format is not supported.
+
+Signed-off-by: Amos Kong <akong at redhat.com>
+Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
+(cherry picked from commit 886cc706ce5d4d3d1c296f028ddc2991cfbe3bbe)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hmp-commands.hx | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/hmp-commands.hx b/hmp-commands.hx
+index 13f28cf..a72614d 100644
+--- a/hmp-commands.hx
++++ b/hmp-commands.hx
+@@ -512,9 +512,9 @@ STEXI
+ @item sendkey @var{keys}
+ @findex sendkey
+ 
+-Send @var{keys} to the emulator. @var{keys} could be the name of the
+-key or @code{#} followed by the raw value in either decimal or hexadecimal
+-format. Use @code{-} to press several keys simultaneously. Example:
++Send @var{keys} to the guest. @var{keys} could be the name of the
++key or the raw value in hexadecimal format. Use @code{-} to press
++several keys simultaneously. Example:
+ @example
+ sendkey ctrl-alt-f1
+ @end example
+-- 
+1.7.12.1
+
diff --git a/0111-qapi-Fix-potential-NULL-pointer-segfault.patch b/0111-qapi-Fix-potential-NULL-pointer-segfault.patch
new file mode 100644
index 0000000..8f15921
--- /dev/null
+++ b/0111-qapi-Fix-potential-NULL-pointer-segfault.patch
@@ -0,0 +1,38 @@
+From d01c76a8d9d0d80ba00a407103e7b79112a21fce Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Sat, 1 Sep 2012 09:30:39 +0200
+Subject: [PATCH] qapi: Fix potential NULL pointer segfault
+
+Report from smatch:
+
+qapi-visit.c:1640 visit_type_BlockdevAction(8) error:
+ we previously assumed 'obj' could be null (see line 1639)
+qapi-visit.c:2432 visit_type_NetClientOptions(8) error:
+ we previously assumed 'obj' could be null (see line 2431)
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
+Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
+(cherry picked from commit 227ccf6bff234c29974c2c18ecd3a29e6b965e3d)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ scripts/qapi-visit.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
+index 04ef7c4..5b15ee3 100644
+--- a/scripts/qapi-visit.py
++++ b/scripts/qapi-visit.py
+@@ -157,7 +157,7 @@ void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **
+     if (!error_is_set(errp)) {
+         visit_start_struct(m, (void **)obj, "%(name)s", name, sizeof(%(name)s), &err);
+         if (!err) {
+-            if (!obj || *obj) {
++            if (obj && *obj) {
+                 visit_type_%(name)sKind(m, &(*obj)->kind, "type", &err);
+                 if (!err) {
+                     switch ((*obj)->kind) {
+-- 
+1.7.12.1
+
diff --git a/0112-json-parser-Fix-potential-NULL-pointer-segfault.patch b/0112-json-parser-Fix-potential-NULL-pointer-segfault.patch
new file mode 100644
index 0000000..8198f24
--- /dev/null
+++ b/0112-json-parser-Fix-potential-NULL-pointer-segfault.patch
@@ -0,0 +1,40 @@
+From f6df33dc89bfa16645e3a8b76e9457986c07b271 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Mon, 3 Sep 2012 21:19:11 +0200
+Subject: [PATCH] json-parser: Fix potential NULL pointer segfault
+
+Report from smatch:
+json-parser.c:474 parse_object(62) error: potential null derefence 'dict'.
+json-parser.c:553 parse_array(75) error: potential null derefence 'list'.
+
+Label 'out' in json-parser.c can be called with list == NULL
+which is passed to QDECREF.
+
+Modify QDECREF to handle a NULL argument (inline function qobject_decref
+already handles them, too).
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
+(cherry picked from commit 149474c93490e1c66f838391bd491db83136d91d)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ qobject.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/qobject.h b/qobject.h
+index d42386d..9124649 100644
+--- a/qobject.h
++++ b/qobject.h
+@@ -71,7 +71,7 @@ typedef struct QObject {
+ 
+ /* High-level interface for qobject_decref() */
+ #define QDECREF(obj)              \
+-    qobject_decref(QOBJECT(obj))
++    qobject_decref(obj ? QOBJECT(obj) : NULL)
+ 
+ /* Initialize an object to default values */
+ #define QOBJECT_INIT(obj, qtype_type)   \
+-- 
+1.7.12.1
+
diff --git a/0113-pcie-drop-version_id-field-for-live-migration.patch b/0113-pcie-drop-version_id-field-for-live-migration.patch
new file mode 100644
index 0000000..c3a469f
--- /dev/null
+++ b/0113-pcie-drop-version_id-field-for-live-migration.patch
@@ -0,0 +1,79 @@
+From 7544abf3b783fc82b031d40d0685d2047709492a Mon Sep 17 00:00:00 2001
+From: Jason Baron <jbaron at redhat.com>
+Date: Wed, 8 Aug 2012 14:29:12 -0400
+Subject: [PATCH] pcie: drop version_id field for live migration
+
+While testing q35 live migration, I found that the migration would abort with
+the following error: "Unknown savevm section type 76".
+
+The error is due to this check failing in 'vmstate_load_state()':
+
+    while(field->name) {
+        if ((field->field_exists &&
+             field->field_exists(opaque, version_id)) ||
+            (!field->field_exists &&
+             field->version_id <= version_id)) {
+
+The VMSTATE_PCIE_DEVICE() currently has a 'version_id' set to 2. However,
+'version_id' in the above check is 1. And thus we fail to load the pcie device
+field. Further the code returns to 'qemu_loadvm_state()' which produces the
+error that I saw.
+
+I'm proposing to fix this by simply dropping the 'version_id' field from
+VMSTATE_PCIE_DEVICE(). VMSTATE_PCI_DEVICE() defines no such field and further
+the vmstate_pcie_device that VMSTATE_PCI_DEVICE() refers to is already
+versioned. Thus, any versioning issues could be detected at the vmsd level.
+
+Taking a step back, I think that the 'field->version_id' should be compared
+against a saved version number for the field not the 'version_id'. Futhermore,
+once vmstate_load_state() is called recursively on another vmsd, the check of:
+
+    if (version_id > vmsd->version_id) {
+        return -EINVAL;
+    }
+
+Will never fail since version_id is always equal to vmsd->version_id. So I'm
+wondering why we aren't storing the vmsd version id of the source in the
+migration stream?
+
+This patch also renames the 'name' field of vmstate_pcie_device from:
+PCIDevice -> PCIEDevice to differentiate it from vmstate_pci_device.
+
+Signed-off-by: Jason Baron <jbaron at redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+(cherry picked from commit 1de53459272d89c52bb21b45d5d970de40fbb642)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/pci.c  | 2 +-
+ hw/pcie.h | 1 -
+ 2 files changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/hw/pci.c b/hw/pci.c
+index 4d95984..f855cf3 100644
+--- a/hw/pci.c
++++ b/hw/pci.c
+@@ -439,7 +439,7 @@ const VMStateDescription vmstate_pci_device = {
+ };
+ 
+ const VMStateDescription vmstate_pcie_device = {
+-    .name = "PCIDevice",
++    .name = "PCIEDevice",
+     .version_id = 2,
+     .minimum_version_id = 1,
+     .minimum_version_id_old = 1,
+diff --git a/hw/pcie.h b/hw/pcie.h
+index b8ab0c7..4889194 100644
+--- a/hw/pcie.h
++++ b/hw/pcie.h
+@@ -133,7 +133,6 @@ extern const VMStateDescription vmstate_pcie_device;
+ 
+ #define VMSTATE_PCIE_DEVICE(_field, _state) {                        \
+     .name       = (stringify(_field)),                               \
+-    .version_id = 2,                                                 \
+     .size       = sizeof(PCIDevice),                                 \
+     .vmsd       = &vmstate_pcie_device,                              \
+     .flags      = VMS_STRUCT,                                        \
+-- 
+1.7.12.1
+
diff --git a/0114-pcie_aer-clear-cmask-for-Advanced-Error-Interrupt-Me.patch b/0114-pcie_aer-clear-cmask-for-Advanced-Error-Interrupt-Me.patch
new file mode 100644
index 0000000..80aad2b
--- /dev/null
+++ b/0114-pcie_aer-clear-cmask-for-Advanced-Error-Interrupt-Me.patch
@@ -0,0 +1,40 @@
+From 89df4609568433f67999c27f9b9cd12e91a7d0b5 Mon Sep 17 00:00:00 2001
+From: Jason Baron <jbaron at redhat.com>
+Date: Tue, 4 Sep 2012 16:22:46 -0400
+Subject: [PATCH] pcie_aer: clear cmask for Advanced Error Interrupt Message
+ Number
+
+The Advanced Error Interrupt Message Number (bits 31:27 of the Root
+Error Status Register) is updated when the number of msi messages assigned to a
+device changes. Migration of windows 7 on q35 chipset failed because the check
+in get_pci_config_device() fails due to cmask being set on these bits. Its valid
+to update these bits and we must restore this state across migration.
+
+Signed-off-by: Jason Baron <jbaron at redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+(cherry picked from commit 0e180d9c8a7429c55d23d2e7855f1e490a063aaa)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/pcie_aer.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c
+index 3b6981c..b04c164 100644
+--- a/hw/pcie_aer.c
++++ b/hw/pcie_aer.c
+@@ -738,6 +738,11 @@ void pcie_aer_root_init(PCIDevice *dev)
+                  PCI_ERR_ROOT_CMD_EN_MASK);
+     pci_set_long(dev->w1cmask + pos + PCI_ERR_ROOT_STATUS,
+                  PCI_ERR_ROOT_STATUS_REPORT_MASK);
++    /* PCI_ERR_ROOT_IRQ is RO but devices change it using a
++     * device-specific method.
++     */
++    pci_set_long(dev->cmask + pos + PCI_ERR_ROOT_STATUS,
++                 ~PCI_ERR_ROOT_IRQ);
+ }
+ 
+ void pcie_aer_root_reset(PCIDevice *dev)
+-- 
+1.7.12.1
+
diff --git a/0115-fix-entry-pointer-for-ELF-kernels-loaded-with-kernel.patch b/0115-fix-entry-pointer-for-ELF-kernels-loaded-with-kernel.patch
new file mode 100644
index 0000000..4488d60
--- /dev/null
+++ b/0115-fix-entry-pointer-for-ELF-kernels-loaded-with-kernel.patch
@@ -0,0 +1,42 @@
+From 3d24d0452bb11e371c710a68b88f09c3accee51f Mon Sep 17 00:00:00 2001
+From: Henning Schild <henning at hennsch.de>
+Date: Wed, 5 Sep 2012 14:56:39 +0200
+Subject: [PATCH] fix entry pointer for ELF kernels loaded with -kernel option
+
+ Find a hopefully proper patch attached. Take it or leave it.
+
+Reviewed-by: Kevin Wolf <kwolf at redhat.com>
+Signed-off-by: Henning Schild <henning at hennsch.de>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+(cherry picked from commit 7e9c7ffe9fd9dfc3d0168dd584936db8144b230b)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/elf_ops.h | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/hw/elf_ops.h b/hw/elf_ops.h
+index fa65ce2..731a983 100644
+--- a/hw/elf_ops.h
++++ b/hw/elf_ops.h
+@@ -269,6 +269,17 @@ static int glue(load_elf, SZ)(const char *name, int fd,
+                 addr = ph->p_paddr;
+             }
+ 
++            /* the entry pointer in the ELF header is a virtual
++             * address, if the text segments paddr and vaddr differ
++             * we need to adjust the entry */
++            if (pentry && !translate_fn &&
++                    ph->p_vaddr != ph->p_paddr &&
++                    ehdr.e_entry >= ph->p_vaddr &&
++                    ehdr.e_entry < ph->p_vaddr + ph->p_filesz &&
++                    ph->p_flags & PF_X) {
++                *pentry = ehdr.e_entry - ph->p_vaddr + ph->p_paddr;
++            }
++
+             snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
+             rom_add_blob_fixed(label, data, mem_size, addr);
+ 
+-- 
+1.7.12.1
+
diff --git a/0116-lan9118-fix-multicast-filtering.patch b/0116-lan9118-fix-multicast-filtering.patch
new file mode 100644
index 0000000..19cb229
--- /dev/null
+++ b/0116-lan9118-fix-multicast-filtering.patch
@@ -0,0 +1,37 @@
+From 0ea96930bcd85734da46de0cd44d1d0408cbb9be Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Sun, 10 Jun 2012 23:18:44 +0200
+Subject: [PATCH] lan9118: fix multicast filtering
+
+The lan9118 emulation tries to compute the multicast index by calling
+directly the crc32() function from zlib, but fails to get the correct
+result.
+
+Use the common compute_mcast_idx() function instead, which gives the
+correct result. This fixes IPv6 support.
+
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+(cherry picked from commit 449bc90e1f2e2fbafb64eb0c76d16c9352b0d2df)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/lan9118.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/lan9118.c b/hw/lan9118.c
+index ff0a50b..ceaf96f 100644
+--- a/hw/lan9118.c
++++ b/hw/lan9118.c
+@@ -500,7 +500,7 @@ static int lan9118_filter(lan9118_state *s, const uint8_t *addr)
+         }
+     } else {
+         /* Hash matching  */
+-        hash = (crc32(~0, addr, 6) >> 26);
++        hash = compute_mcast_idx(addr);
+         if (hash & 0x20) {
+             return (s->mac_hashh >> (hash & 0x1f)) & 1;
+         } else {
+-- 
+1.7.12.1
+
diff --git a/0117-MIPS-user-Fix-reset-CPU-state-initialization.patch b/0117-MIPS-user-Fix-reset-CPU-state-initialization.patch
new file mode 100644
index 0000000..e98d248
--- /dev/null
+++ b/0117-MIPS-user-Fix-reset-CPU-state-initialization.patch
@@ -0,0 +1,196 @@
+From 608a36df28b4db83124d06081029023e01901fc9 Mon Sep 17 00:00:00 2001
+From: "Maciej W. Rozycki" <macro at codesourcery.com>
+Date: Fri, 8 Jun 2012 02:04:40 +0100
+Subject: [PATCH] MIPS/user: Fix reset CPU state initialization
+
+ This change updates the CPU reset sequence to use a common piece of code
+that figures out CPU state flags, fixing the problem with MIPS_HFLAG_COP1X
+not being set where applicable that causes floating-point MADD family
+instructions (and other instructions from the MIPS IV FP subset) to trap.
+
+ As compute_hflags is now shared between op_helper.c and translate.c, the
+function is now moved to a common header.  There are no changes to this
+function.
+
+ The problem was seen with the 24Kf MIPS32r2 processor in user emulation.
+The new approach prevents system and user emulation from diverging -- all
+the hflags state is initialized in one place now.
+
+Signed-off-by: Maciej W. Rozycki <macro at codesourcery.com>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+(cherry picked from commit 03e6e5017757645f00b2f3b4f3a257973985e455)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-mips/cpu.h       | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
+ target-mips/op_helper.c | 49 -------------------------------------------------
+ target-mips/translate.c | 16 +++-------------
+ 3 files changed, 52 insertions(+), 62 deletions(-)
+
+diff --git a/target-mips/cpu.h b/target-mips/cpu.h
+index be4f805..b7a5112 100644
+--- a/target-mips/cpu.h
++++ b/target-mips/cpu.h
+@@ -742,4 +742,53 @@ static inline void cpu_pc_from_tb(CPUMIPSState *env, TranslationBlock *tb)
+     env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
+ }
+ 
++static inline void compute_hflags(CPUMIPSState *env)
++{
++    env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
++                     MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
++                     MIPS_HFLAG_UX);
++    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
++        !(env->CP0_Status & (1 << CP0St_ERL)) &&
++        !(env->hflags & MIPS_HFLAG_DM)) {
++        env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
++    }
++#if defined(TARGET_MIPS64)
++    if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
++        (env->CP0_Status & (1 << CP0St_PX)) ||
++        (env->CP0_Status & (1 << CP0St_UX))) {
++        env->hflags |= MIPS_HFLAG_64;
++    }
++    if (env->CP0_Status & (1 << CP0St_UX)) {
++        env->hflags |= MIPS_HFLAG_UX;
++    }
++#endif
++    if ((env->CP0_Status & (1 << CP0St_CU0)) ||
++        !(env->hflags & MIPS_HFLAG_KSU)) {
++        env->hflags |= MIPS_HFLAG_CP0;
++    }
++    if (env->CP0_Status & (1 << CP0St_CU1)) {
++        env->hflags |= MIPS_HFLAG_FPU;
++    }
++    if (env->CP0_Status & (1 << CP0St_FR)) {
++        env->hflags |= MIPS_HFLAG_F64;
++    }
++    if (env->insn_flags & ISA_MIPS32R2) {
++        if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
++            env->hflags |= MIPS_HFLAG_COP1X;
++        }
++    } else if (env->insn_flags & ISA_MIPS32) {
++        if (env->hflags & MIPS_HFLAG_64) {
++            env->hflags |= MIPS_HFLAG_COP1X;
++        }
++    } else if (env->insn_flags & ISA_MIPS4) {
++        /* All supported MIPS IV CPUs use the XX (CU3) to enable
++           and disable the MIPS IV extensions to the MIPS III ISA.
++           Some other MIPS IV CPUs ignore the bit, so the check here
++           would be too restrictive for them.  */
++        if (env->CP0_Status & (1 << CP0St_CU3)) {
++            env->hflags |= MIPS_HFLAG_COP1X;
++        }
++    }
++}
++
+ #endif /* !defined (__MIPS_CPU_H__) */
+diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
+index d2a8a55..ce5ddaf 100644
+--- a/target-mips/op_helper.c
++++ b/target-mips/op_helper.c
+@@ -30,55 +30,6 @@
+ static inline void cpu_mips_tlb_flush (CPUMIPSState *env, int flush_global);
+ #endif
+ 
+-static inline void compute_hflags(CPUMIPSState *env)
+-{
+-    env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
+-                     MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
+-                     MIPS_HFLAG_UX);
+-    if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
+-        !(env->CP0_Status & (1 << CP0St_ERL)) &&
+-        !(env->hflags & MIPS_HFLAG_DM)) {
+-        env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
+-    }
+-#if defined(TARGET_MIPS64)
+-    if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
+-        (env->CP0_Status & (1 << CP0St_PX)) ||
+-        (env->CP0_Status & (1 << CP0St_UX))) {
+-        env->hflags |= MIPS_HFLAG_64;
+-    }
+-    if (env->CP0_Status & (1 << CP0St_UX)) {
+-        env->hflags |= MIPS_HFLAG_UX;
+-    }
+-#endif
+-    if ((env->CP0_Status & (1 << CP0St_CU0)) ||
+-        !(env->hflags & MIPS_HFLAG_KSU)) {
+-        env->hflags |= MIPS_HFLAG_CP0;
+-    }
+-    if (env->CP0_Status & (1 << CP0St_CU1)) {
+-        env->hflags |= MIPS_HFLAG_FPU;
+-    }
+-    if (env->CP0_Status & (1 << CP0St_FR)) {
+-        env->hflags |= MIPS_HFLAG_F64;
+-    }
+-    if (env->insn_flags & ISA_MIPS32R2) {
+-        if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
+-            env->hflags |= MIPS_HFLAG_COP1X;
+-        }
+-    } else if (env->insn_flags & ISA_MIPS32) {
+-        if (env->hflags & MIPS_HFLAG_64) {
+-            env->hflags |= MIPS_HFLAG_COP1X;
+-        }
+-    } else if (env->insn_flags & ISA_MIPS4) {
+-        /* All supported MIPS IV CPUs use the XX (CU3) to enable
+-           and disable the MIPS IV extensions to the MIPS III ISA.
+-           Some other MIPS IV CPUs ignore the bit, so the check here
+-           would be too restrictive for them.  */
+-        if (env->CP0_Status & (1 << CP0St_CU3)) {
+-            env->hflags |= MIPS_HFLAG_COP1X;
+-        }
+-    }
+-}
+-
+ /*****************************************************************************/
+ /* Exceptions processing helpers */
+ 
+diff --git a/target-mips/translate.c b/target-mips/translate.c
+index aba7935..4e04e97 100644
+--- a/target-mips/translate.c
++++ b/target-mips/translate.c
+@@ -12816,18 +12816,13 @@ void cpu_state_reset(CPUMIPSState *env)
+     env->insn_flags = env->cpu_model->insn_flags;
+ 
+ #if defined(CONFIG_USER_ONLY)
+-    env->hflags = MIPS_HFLAG_UM;
++    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
+     /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
+        hardware registers.  */
+     env->CP0_HWREna |= 0x0000000F;
+     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
+-        env->hflags |= MIPS_HFLAG_FPU;
++        env->CP0_Status |= (1 << CP0St_CU1);
+     }
+-#ifdef TARGET_MIPS64
+-    if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
+-        env->hflags |= MIPS_HFLAG_F64;
+-    }
+-#endif
+ #else
+     if (env->hflags & MIPS_HFLAG_BMASK) {
+         /* If the exception was raised from a delay slot,
+@@ -12857,7 +12852,6 @@ void cpu_state_reset(CPUMIPSState *env)
+     }
+     /* Count register increments in debug mode, EJTAG version 1 */
+     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
+-    env->hflags = MIPS_HFLAG_CP0;
+ 
+     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+         int i;
+@@ -12885,11 +12879,7 @@ void cpu_state_reset(CPUMIPSState *env)
+         }
+     }
+ #endif
+-#if defined(TARGET_MIPS64)
+-    if (env->cpu_model->insn_flags & ISA_MIPS3) {
+-        env->hflags |= MIPS_HFLAG_64;
+-    }
+-#endif
++    compute_hflags(env);
+     env->exception_index = EXCP_NONE;
+ }
+ 
+-- 
+1.7.12.1
+
diff --git a/0118-Add-MAINTAINERS-entry-for-leon3.patch b/0118-Add-MAINTAINERS-entry-for-leon3.patch
new file mode 100644
index 0000000..cbc0ff8
--- /dev/null
+++ b/0118-Add-MAINTAINERS-entry-for-leon3.patch
@@ -0,0 +1,34 @@
+From 6bfc31b2f98dabc0e636cd8955c8de93bcac0961 Mon Sep 17 00:00:00 2001
+From: Fabien Chouteau <chouteau at adacore.com>
+Date: Tue, 22 May 2012 10:14:28 +0200
+Subject: [PATCH] Add MAINTAINERS entry for leon3
+
+Signed-off-by: Fabien Chouteau <chouteau at adacore.com>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+(cherry picked from commit ce6c760c37b9a88db87c5b9b9bf39ca866e570f6)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ MAINTAINERS | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 6d864c1..61f8b45 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -398,6 +398,12 @@ M: Blue Swirl <blauwirbel at gmail.com>
+ S: Maintained
+ F: hw/sun4u.c
+ 
++Leon3
++M: Fabien Chouteau <chouteau at adacore.com>
++S: Maintained
++F: hw/leon3.c
++F: hw/grlib*
++
+ S390 Machines
+ -------------
+ S390 Virtio
+-- 
+1.7.12.1
+
diff --git a/0119-musicpal-Fix-flash-mapping.patch b/0119-musicpal-Fix-flash-mapping.patch
new file mode 100644
index 0000000..9c95c49
--- /dev/null
+++ b/0119-musicpal-Fix-flash-mapping.patch
@@ -0,0 +1,42 @@
+From 2182aa5c2ca5a5a6bf9c2d06d18b3e2db3aa3c7a Mon Sep 17 00:00:00 2001
+From: Jan Kiszka <jan.kiszka at web.de>
+Date: Sat, 8 Sep 2012 11:52:39 +0200
+Subject: [PATCH] musicpal: Fix flash mapping
+
+The old arithmetic assumed 32 physical address bits which is no longer
+true for ARM since 3cc0cd61f4.
+
+Signed-off-by: Jan Kiszka <jan.kiszka at web.de>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+(cherry picked from commit 0c267217ca9985e6d118ec8368bebd382db7a099)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/musicpal.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/musicpal.c b/hw/musicpal.c
+index ad725b5..f305e21 100644
+--- a/hw/musicpal.c
++++ b/hw/musicpal.c
+@@ -1583,7 +1583,7 @@ static void musicpal_init(ram_addr_t ram_size,
+          * image is smaller than 32 MB.
+          */
+ #ifdef TARGET_WORDS_BIGENDIAN
+-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, NULL,
++        pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
+                               "musicpal.flash", flash_size,
+                               dinfo->bdrv, 0x10000,
+                               (flash_size + 0xffff) >> 16,
+@@ -1591,7 +1591,7 @@ static void musicpal_init(ram_addr_t ram_size,
+                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
+                               0x5555, 0x2AAA, 1);
+ #else
+-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, NULL,
++        pflash_cfi02_register(0x100000000ULL-MP_FLASH_SIZE_MAX, NULL,
+                               "musicpal.flash", flash_size,
+                               dinfo->bdrv, 0x10000,
+                               (flash_size + 0xffff) >> 16,
+-- 
+1.7.12.1
+
diff --git a/0120-qemu-Use-valgrind-annotations-to-mark-kvm-guest-memo.patch b/0120-qemu-Use-valgrind-annotations-to-mark-kvm-guest-memo.patch
new file mode 100644
index 0000000..40caa2c
--- /dev/null
+++ b/0120-qemu-Use-valgrind-annotations-to-mark-kvm-guest-memo.patch
@@ -0,0 +1,84 @@
+From e688bfbda0f6893b08d1e51f4fb26d4b38e922d4 Mon Sep 17 00:00:00 2001
+From: Christian Borntraeger <borntraeger at de.ibm.com>
+Date: Fri, 10 Aug 2012 15:11:45 +0200
+Subject: [PATCH] qemu: Use valgrind annotations to mark kvm guest memory as
+ defined
+
+valgrind with kvm produces a big amount of false positives regarding
+"Conditional jump or move depends on uninitialised value(s)". This
+happens because the guest memory is allocated with qemu_vmalloc which
+boils down posix_memalign etc. This function is (correctly) considered
+by valgrind as returning undefined memory.
+
+Since valgrind is based on jitting code, it will not be able to see
+changes made by the guest to guest memory if this is done by KVM_RUN,
+thus keeping most of the guest memory undefined.
+
+Now lots of places in qemu will then use guest memory to change behaviour.
+To avoid the flood of these messages, lets declare the whole guest
+memory as defined. This will reduce the noise and allows us to see real
+problems.
+
+In the future we might want to make this conditional, since there
+is actually something that we can use those false positives for:
+These messages will point to code that depends on guest memory, so
+we can use these backtraces to actually make an audit that is focussed
+only at those code places. For normal development we dont want to
+see those messages, though.
+
+Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
+Signed-off-by: Avi Kivity <avi at redhat.com>
+(cherry picked from commit 62fe83318d2fc5b31f473d66326910d94c1c4907)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure | 3 ++-
+ kvm-all.c | 7 +++++++
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/configure b/configure
+index d7a948f..8874eff 100755
+--- a/configure
++++ b/configure
+@@ -2937,11 +2937,12 @@ if compile_prog "-Werror" "" ; then
+ fi
+ 
+ ########################################
+-# check if we have valgrind/valgrind.h
++# check if we have valgrind/valgrind.h and valgrind/memcheck.h
+ 
+ valgrind_h=no
+ cat > $TMPC << EOF
+ #include <valgrind/valgrind.h>
++#include <valgrind/memcheck.h>
+ int main(void) {
+   return 0;
+ }
+diff --git a/kvm-all.c b/kvm-all.c
+index badf1d8..90c71f9 100644
+--- a/kvm-all.c
++++ b/kvm-all.c
+@@ -39,6 +39,10 @@
+ #include <sys/eventfd.h>
+ #endif
+ 
++#ifdef CONFIG_VALGRIND_H
++#include <valgrind/memcheck.h>
++#endif
++
+ /* KVM uses PAGE_SIZE in its definition of COALESCED_MMIO_MAX */
+ #define PAGE_SIZE TARGET_PAGE_SIZE
+ 
+@@ -1769,6 +1773,9 @@ void *kvm_vmalloc(ram_addr_t size)
+ 
+ void kvm_setup_guest_memory(void *start, size_t size)
+ {
++#ifdef CONFIG_VALGRIND_H
++    VALGRIND_MAKE_MEM_DEFINED(start, size);
++#endif
+     if (!kvm_has_sync_mmu()) {
+         int ret = qemu_madvise(start, size, QEMU_MADV_DONTFORK);
+ 
+-- 
+1.7.12.1
+
diff --git a/0121-hw-wm8750-Fix-potential-buffer-overflow.patch b/0121-hw-wm8750-Fix-potential-buffer-overflow.patch
new file mode 100644
index 0000000..2b3acbe
--- /dev/null
+++ b/0121-hw-wm8750-Fix-potential-buffer-overflow.patch
@@ -0,0 +1,43 @@
+From 044cadadb3bb63396a1e8d72a0c90673ccd7be98 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Mon, 3 Sep 2012 22:56:00 +0200
+Subject: [PATCH] hw/wm8750: Fix potential buffer overflow
+
+Report from smatch:
+
+hw/wm8750.c:369 wm8750_tx(12) error: buffer overflow 's->i2c_data' 2 <= 2
+
+It looks like the preprocessor statements were simply misplaced.
+
+Replace also __FUNCTION__ by __func__ to please checkpatch.pl.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+(cherry picked from commit 149eeb5fe57b853081e8059575d91b8a58a4f96c)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/wm8750.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/wm8750.c b/hw/wm8750.c
+index 11bcec3..44f138f 100644
+--- a/hw/wm8750.c
++++ b/hw/wm8750.c
+@@ -361,10 +361,10 @@ static int wm8750_tx(I2CSlave *i2c, uint8_t data)
+     uint16_t value;
+ 
+     if (s->i2c_len >= 2) {
+-        printf("%s: long message (%i bytes)\n", __FUNCTION__, s->i2c_len);
+ #ifdef VERBOSE
+-        return 1;
++        printf("%s: long message (%i bytes)\n", __func__, s->i2c_len);
+ #endif
++        return 1;
+     }
+     s->i2c_data[s->i2c_len ++] = data;
+     if (s->i2c_len != 2)
+-- 
+1.7.12.1
+
diff --git a/0122-hw-mcf5206-Fix-buffer-overflow-for-MBAR-read-write.patch b/0122-hw-mcf5206-Fix-buffer-overflow-for-MBAR-read-write.patch
new file mode 100644
index 0000000..c5fe15f
--- /dev/null
+++ b/0122-hw-mcf5206-Fix-buffer-overflow-for-MBAR-read-write.patch
@@ -0,0 +1,87 @@
+From 90c742c7f36f45249c62c0c5db2e138a604e44ac Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Tue, 4 Sep 2012 19:37:39 +0200
+Subject: [PATCH] hw/mcf5206: Fix buffer overflow for MBAR read / write
+
+Report from smatch:
+
+mcf5206.c:384 m5206_mbar_readb(7) error: buffer overflow 'm5206_mbar_width' 128 <= 128
+mcf5206.c:403 m5206_mbar_readw(8) error: buffer overflow 'm5206_mbar_width' 128 <= 128
+mcf5206.c:427 m5206_mbar_readl(8) error: buffer overflow 'm5206_mbar_width' 128 <= 128
+mcf5206.c:451 m5206_mbar_writeb(9) error: buffer overflow 'm5206_mbar_width' 128 <= 128
+mcf5206.c:475 m5206_mbar_writew(9) error: buffer overflow 'm5206_mbar_width' 128 <= 128
+mcf5206.c:503 m5206_mbar_writel(9) error: buffer overflow 'm5206_mbar_width' 128 <= 128
+
+m5206_mbar_width has 0x80 elements and supports 0 <= offset < 0x200.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+(cherry picked from commit a32354e206895400d17c3de9a8df1de96d3df289)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/mcf5206.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/hw/mcf5206.c b/hw/mcf5206.c
+index 539b391..27753e2 100644
+--- a/hw/mcf5206.c
++++ b/hw/mcf5206.c
+@@ -378,7 +378,7 @@ static uint32_t m5206_mbar_readb(void *opaque, target_phys_addr_t offset)
+ {
+     m5206_mbar_state *s = (m5206_mbar_state *)opaque;
+     offset &= 0x3ff;
+-    if (offset > 0x200) {
++    if (offset >= 0x200) {
+         hw_error("Bad MBAR read offset 0x%x", (int)offset);
+     }
+     if (m5206_mbar_width[offset >> 2] > 1) {
+@@ -397,7 +397,7 @@ static uint32_t m5206_mbar_readw(void *opaque, target_phys_addr_t offset)
+     m5206_mbar_state *s = (m5206_mbar_state *)opaque;
+     int width;
+     offset &= 0x3ff;
+-    if (offset > 0x200) {
++    if (offset >= 0x200) {
+         hw_error("Bad MBAR read offset 0x%x", (int)offset);
+     }
+     width = m5206_mbar_width[offset >> 2];
+@@ -421,7 +421,7 @@ static uint32_t m5206_mbar_readl(void *opaque, target_phys_addr_t offset)
+     m5206_mbar_state *s = (m5206_mbar_state *)opaque;
+     int width;
+     offset &= 0x3ff;
+-    if (offset > 0x200) {
++    if (offset >= 0x200) {
+         hw_error("Bad MBAR read offset 0x%x", (int)offset);
+     }
+     width = m5206_mbar_width[offset >> 2];
+@@ -445,7 +445,7 @@ static void m5206_mbar_writeb(void *opaque, target_phys_addr_t offset,
+     m5206_mbar_state *s = (m5206_mbar_state *)opaque;
+     int width;
+     offset &= 0x3ff;
+-    if (offset > 0x200) {
++    if (offset >= 0x200) {
+         hw_error("Bad MBAR write offset 0x%x", (int)offset);
+     }
+     width = m5206_mbar_width[offset >> 2];
+@@ -469,7 +469,7 @@ static void m5206_mbar_writew(void *opaque, target_phys_addr_t offset,
+     m5206_mbar_state *s = (m5206_mbar_state *)opaque;
+     int width;
+     offset &= 0x3ff;
+-    if (offset > 0x200) {
++    if (offset >= 0x200) {
+         hw_error("Bad MBAR write offset 0x%x", (int)offset);
+     }
+     width = m5206_mbar_width[offset >> 2];
+@@ -497,7 +497,7 @@ static void m5206_mbar_writel(void *opaque, target_phys_addr_t offset,
+     m5206_mbar_state *s = (m5206_mbar_state *)opaque;
+     int width;
+     offset &= 0x3ff;
+-    if (offset > 0x200) {
++    if (offset >= 0x200) {
+         hw_error("Bad MBAR write offset 0x%x", (int)offset);
+     }
+     width = m5206_mbar_width[offset >> 2];
+-- 
+1.7.12.1
+
diff --git a/0123-use-libexecdir-instead-of-ignoring-it-first-and-rein.patch b/0123-use-libexecdir-instead-of-ignoring-it-first-and-rein.patch
new file mode 100644
index 0000000..9764f22
--- /dev/null
+++ b/0123-use-libexecdir-instead-of-ignoring-it-first-and-rein.patch
@@ -0,0 +1,94 @@
+From 6762c144443bca8fa97a389289bda7693bd4c8d4 Mon Sep 17 00:00:00 2001
+From: Michael Tokarev <mjt at tls.msk.ru>
+Date: Thu, 7 Jun 2012 01:11:00 +0400
+Subject: [PATCH] use --libexecdir instead of ignoring it first and
+ reinventing it later
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit 7b93fadf3a38d1ed65ea5536a52efc2772c6e3b8 "Add basic version
+of bridge helper" put the bridge helper executable into a fixed
+${prefix}/libexec/ location, instead of using ${libexecdir} for
+this.  At the same time, --libexecdir is being happily ignored
+by ./configure.  Even more, the same patch sets unused $libexecdir
+variable in the generated config-host.mak, and uses fixed string
+(\${prefix}/libexecdir) for the bridge helper binary.
+
+Fix this braindamage by introducing $libexecdir variable, using
+it for the bridge helper binary, and recognizing --libexecdir.
+
+This patch is applicable to stable-1.1.
+
+Reviewed-by: Andreas Färber <afaerber at suse.de>
+Reviewed-by: Corey Bryant <coreyb at linux.vnet.ibm.com>
+Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>
+Cc: Corey Bryant <coreyb at linux.vnet.ibm.com>
+Cc: Richa Marwaha <rmarwah at linux.vnet.ibm.com>
+Cc: qemu-stable at nongnu.org
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit 8bf188aa18ef7a8355d9edbd43871d590468c4ed)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/configure b/configure
+index 8874eff..d01f9dc 100755
+--- a/configure
++++ b/configure
+@@ -191,6 +191,7 @@ datadir="\${prefix}/share"
+ qemu_docdir="\${prefix}/share/doc/qemu"
+ bindir="\${prefix}/bin"
+ libdir="\${prefix}/lib"
++libexecdir="\${prefix}/libexec"
+ includedir="\${prefix}/include"
+ sysconfdir="\${prefix}/etc"
+ confsuffix="/qemu"
+@@ -624,6 +625,8 @@ for opt do
+   ;;
+   --libdir=*) libdir="$optarg"
+   ;;
++  --libexecdir=*) libexecdir="$optarg"
++  ;;
+   --includedir=*) includedir="$optarg"
+   ;;
+   --datadir=*) datadir="$optarg"
+@@ -634,7 +637,7 @@ for opt do
+   ;;
+   --sysconfdir=*) sysconfdir="$optarg"
+   ;;
+-  --sbindir=*|--libexecdir=*|--sharedstatedir=*|--localstatedir=*|\
++  --sbindir=*|--sharedstatedir=*|--localstatedir=*|\
+   --oldincludedir=*|--datarootdir=*|--infodir=*|--localedir=*|\
+   --htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*)
+     # These switches are silently ignored, for compatibility with
+@@ -3055,6 +3058,7 @@ echo "Install prefix    $prefix"
+ echo "BIOS directory    `eval echo $qemu_datadir`"
+ echo "binary directory  `eval echo $bindir`"
+ echo "library directory `eval echo $libdir`"
++echo "libexec directory `eval echo $libexecdir`"
+ echo "include directory `eval echo $includedir`"
+ echo "config directory  `eval echo $sysconfdir`"
+ if test "$mingw32" = "no" ; then
+@@ -3158,14 +3162,14 @@ echo all: >> $config_host_mak
+ echo "prefix=$prefix" >> $config_host_mak
+ echo "bindir=$bindir" >> $config_host_mak
+ echo "libdir=$libdir" >> $config_host_mak
++echo "libexecdir=$libexecdir" >> $config_host_mak
+ echo "includedir=$includedir" >> $config_host_mak
+ echo "mandir=$mandir" >> $config_host_mak
+ echo "sysconfdir=$sysconfdir" >> $config_host_mak
+ echo "qemu_confdir=$qemu_confdir" >> $config_host_mak
+ echo "qemu_datadir=$qemu_datadir" >> $config_host_mak
+ echo "qemu_docdir=$qemu_docdir" >> $config_host_mak
+-echo "libexecdir=\${prefix}/libexec" >> $config_host_mak
+-echo "CONFIG_QEMU_HELPERDIR=\"$prefix/libexec\"" >> $config_host_mak
++echo "CONFIG_QEMU_HELPERDIR=\"$libexecdir\"" >> $config_host_mak
+ 
+ echo "ARCH=$ARCH" >> $config_host_mak
+ if test "$debug_tcg" = "yes" ; then
+-- 
+1.7.12.1
+
diff --git a/0124-socket-don-t-attempt-to-reconnect-a-TCP-socket-in-se.patch b/0124-socket-don-t-attempt-to-reconnect-a-TCP-socket-in-se.patch
new file mode 100644
index 0000000..cff77f8
--- /dev/null
+++ b/0124-socket-don-t-attempt-to-reconnect-a-TCP-socket-in-se.patch
@@ -0,0 +1,43 @@
+From 40874e295225675fec7b42bb8e015fb3f2065a69 Mon Sep 17 00:00:00 2001
+From: Anthony Liguori <aliguori at us.ibm.com>
+Date: Wed, 5 Sep 2012 13:52:49 -0500
+Subject: [PATCH] socket: don't attempt to reconnect a TCP socket in server
+ mode
+
+Commit c3767ed0eb5d0bb25fe409ae5dec06e3411ff1b6 introduced a possible SEGV when
+using a socket chardev with server=on because it assumes that all TCP sockets
+are in client mode.
+
+This patch adds a check to only reconnect when in client mode.
+
+Cc: Lei Li <lilei at linux.vnet.ibm.com>
+Reported-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit 455aa1e0818653c41fd794435b982426ce21ba2f)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ qemu-char.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/qemu-char.c b/qemu-char.c
+index 398baf1..767da93 100644
+--- a/qemu-char.c
++++ b/qemu-char.c
+@@ -2148,10 +2148,12 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+     TCPCharDriver *s = chr->opaque;
+     if (s->connected) {
+         return send_all(s->fd, buf, len);
+-    } else {
++    } else if (s->listen_fd == -1) {
+         /* (Re-)connect for unconnected writing */
+         tcp_chr_connect(chr);
+         return 0;
++    } else {
++        return len;
+     }
+ }
+ 
+-- 
+1.7.12.1
+
diff --git a/0125-Add-ability-to-force-enable-disable-of-tools-build.patch b/0125-Add-ability-to-force-enable-disable-of-tools-build.patch
new file mode 100644
index 0000000..35e05ee
--- /dev/null
+++ b/0125-Add-ability-to-force-enable-disable-of-tools-build.patch
@@ -0,0 +1,83 @@
+From d9f498f4b7b7ca2ff96b4d87827713caea3743b5 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange at redhat.com>
+Date: Mon, 10 Sep 2012 12:26:29 +0100
+Subject: [PATCH] Add ability to force enable/disable of tools build
+
+The qemu-img, qemu-nbd and qemu-io tools are built conditionally
+based on whether any softmmu target is enabled. These are useful
+self-contained tools which can be used in many other scenarios.
+Add new --enable-tools/--disable-tools args to configure to allow
+the user to explicitly turn on / off their build. The default
+behaviour is now to build these tools are all times, regardless
+of whether any softmmu target is enabled
+
+Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit 4b1c11fd20e8901f04a2d9c225cd10fc05a762ff)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+diff --git a/configure b/configure
+index d01f9dc..a8061c1 100755
+--- a/configure
++++ b/configure
+@@ -225,6 +225,7 @@ usb_redir=""
+ opengl=""
+ zlib="yes"
+ guest_agent="yes"
++want_tools="yes"
+ libiscsi=""
+ coroutine=""
+ seccomp=""
+@@ -857,6 +858,10 @@ for opt do
+   ;;
+   --disable-guest-agent) guest_agent="no"
+   ;;
++  --enable-tools) want_tools="yes"
++  ;;
++  --disable-tools) want_tools="no"
++  ;;
+   --enable-seccomp) seccomp="yes"
+   ;;
+   --disable-seccomp) seccomp="no"
+@@ -3017,9 +3022,14 @@ fi
+ qemu_confdir=$sysconfdir$confsuffix
+ qemu_datadir=$datadir$confsuffix
+ 
+-tools=
+-if test "$softmmu" = yes ; then
++tools=""
++if test "$want_tools" = "yes" ; then
+   tools="qemu-img\$(EXESUF) qemu-io\$(EXESUF) $tools"
++  if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
++    tools="qemu-nbd\$(EXESUF) $tools"
++  fi
++fi
++if test "$softmmu" = yes ; then
+   if test "$virtfs" != no ; then
+     if test "$cap" = yes && test "$linux" = yes && test "$attr" = yes ; then
+       virtfs=yes
+@@ -3033,14 +3043,13 @@ if test "$softmmu" = yes ; then
+     fi
+   fi
+   if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
+-      tools="qemu-nbd\$(EXESUF) $tools"
+     if [ "$guest_agent" = "yes" ]; then
+       tools="qemu-ga\$(EXESUF) $tools"
+     fi
+   fi
+-fi
+-if test "$smartcard_nss" = "yes" ; then
+-  tools="vscclient\$(EXESUF) $tools"
++  if test "$smartcard_nss" = "yes" ; then
++    tools="vscclient\$(EXESUF) $tools"
++  fi
+ fi
+ 
+ # Mac OS X ships with a broken assembler
+-- 
+1.7.12.1
+
diff --git a/0301-usb-controllers-do-not-need-to-check-for-babble-them.patch b/0126-usb-controllers-do-not-need-to-check-for-babble-them.patch
similarity index 86%
rename from 0301-usb-controllers-do-not-need-to-check-for-babble-them.patch
rename to 0126-usb-controllers-do-not-need-to-check-for-babble-them.patch
index a1cfa08..2630139 100644
--- a/0301-usb-controllers-do-not-need-to-check-for-babble-them.patch
+++ b/0126-usb-controllers-do-not-need-to-check-for-babble-them.patch
@@ -1,8 +1,7 @@
-From d69c3f589874de55e2eae03110a0c696485b8fa7 Mon Sep 17 00:00:00 2001
+From 074f49c02e7f2fd50533a246b4060051f95f8b09 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Fri, 17 Aug 2012 11:39:16 +0200
-Subject: [PATCH 301/366] usb: controllers do not need to check for babble
- themselves
+Subject: [PATCH] usb: controllers do not need to check for babble themselves
 
 If an (emulated) usb-device tries to write more data to a packet then
 its iov len, this will trigger an assert in usb_packet_copy(), and if
@@ -15,6 +14,9 @@ both the usb-host os and the qemu usb-device code already check for it.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 45b339b18c660eb85af2ba25bfcaed5469660d77)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 4 ----
  hw/usb/hcd-uhci.c | 5 -----
@@ -52,5 +54,5 @@ index b0db921..c7c8786 100644
              *int_mask |= 0x02;
              /* short packet: do not update QH */
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0302-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch b/0127-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch
similarity index 77%
rename from 0302-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch
rename to 0127-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch
index e40f57d..1bbaed0 100644
--- a/0302-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch
+++ b/0127-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch
@@ -1,14 +1,16 @@
-From ae5b888748b713d018ca7b339262b32bf88ec1be Mon Sep 17 00:00:00 2001
+From bcd7c845fbfbafe03e320fbffcaa32417cfd5267 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 3 Sep 2012 12:33:44 +0200
-Subject: [PATCH 302/366] usb-core: Don't set packet state to complete on a
- nak
+Subject: [PATCH] usb-core: Don't set packet state to complete on a nak
 
 This way the hcd can re-use the same packet to retry without needing
 to re-init it.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit cc40997489260f405aecccd30d4626ceee862502)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/core.c | 6 ++++--
  1 file changed, 4 insertions(+), 2 deletions(-)
@@ -31,5 +33,5 @@ index 2da38e7..be6d936 100644
      } else {
          ret = USB_RET_ASYNC;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0303-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch b/0128-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch
similarity index 84%
rename from 0303-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch
rename to 0128-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch
index c3ed784..994e450 100644
--- a/0303-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch
+++ b/0128-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch
@@ -1,11 +1,13 @@
-From d42de93ca42a6d3b5101ec3db474f52a87a07a63 Mon Sep 17 00:00:00 2001
+From 3c2f94fdc5e776ee66bccc704884f3b1b090b4c6 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Tue, 28 Aug 2012 09:43:18 +0200
-Subject: [PATCH 303/366] usb-core: Add a usb_ep_find_packet_by_id() helper
- function
+Subject: [PATCH] usb-core: Add a usb_ep_find_packet_by_id() helper function
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit c13a9e61366cc3e28299d8faeb65e65c6e5964cf)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb.h      |  2 ++
  hw/usb/core.c | 15 +++++++++++++++
@@ -48,5 +50,5 @@ index be6d936..fe431d0 100644
 +    return NULL;
 +}
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0304-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch b/0129-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch
similarity index 77%
rename from 0304-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch
rename to 0129-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch
index ffcd31a..c264ca1 100644
--- a/0304-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch
+++ b/0129-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch
@@ -1,8 +1,8 @@
-From d0c16c3cd8dc1f2dc5ca6dae0d09e5f066332531 Mon Sep 17 00:00:00 2001
+From 2a2b40b145764ece12d0872ae5bb7b7ec2dc271f Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 3 Sep 2012 12:48:49 +0200
-Subject: [PATCH 304/366] usb-core: Allow the first packet of a pipelined ep
- to complete immediately
+Subject: [PATCH] usb-core: Allow the first packet of a pipelined ep to
+ complete immediately
 
 This can happen with usb-redir live-migration when the packet gets re-queued
 after the migration and the original queuing from the migration source side
@@ -10,6 +10,9 @@ has already finished.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 9c1f67654ab611553bbfca54a1e0922728c25760)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/core.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
@@ -28,5 +31,5 @@ index fe431d0..b9f1f7a 100644
                  p->result = ret;
                  usb_packet_set_state(p, USB_PACKET_COMPLETE);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0305-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch b/0130-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch
similarity index 94%
rename from 0305-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch
rename to 0130-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch
index 6d8c7e9..ae5d4d3 100644
--- a/0305-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch
+++ b/0130-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch
@@ -1,7 +1,7 @@
-From eccc0da01324939a52a74c763ade93e4a38d7328 Mon Sep 17 00:00:00 2001
+From 4547897358a12c0f31d688da9922236984742242 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Wed, 29 Aug 2012 10:12:52 +0200
-Subject: [PATCH 305/366] Revert "ehci: don't flush cache on doorbell rings."
+Subject: [PATCH] Revert "ehci: don't flush cache on doorbell rings."
 
 This reverts commit 9bc3a3a216e2689bfcdd36c3e079333bbdbf3ba0, which got
 added to fix an issue where the real, underlying cause was not stopping
@@ -17,6 +17,9 @@ usb-core packet-id generation where qtd addresses are used as ids, causes
 duplicate ids for in flight packets.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+(cherry picked from commit 66f092d25697e11847b61d761c38ddebedaed8d1)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 35 ++++++-----------------------------
  1 file changed, 6 insertions(+), 29 deletions(-)
@@ -117,5 +120,5 @@ index 9523247..e7c36f4 100644
  
      default:
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0306-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch b/0131-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch
similarity index 90%
rename from 0306-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch
rename to 0131-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch
index 7af3a27..a0b0897 100644
--- a/0306-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch
+++ b/0131-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch
@@ -1,14 +1,16 @@
-From 1ee48073d05a8a0dfe08ad2853be125a87f176de Mon Sep 17 00:00:00 2001
+From 46bfd14f89404e4a0eb93c3d9c5b9745724cee2d Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Wed, 29 Aug 2012 10:37:37 +0200
-Subject: [PATCH 306/366] ehci: Validate qh is not changed unexpectedly by the
- guest
+Subject: [PATCH] ehci: Validate qh is not changed unexpectedly by the guest
 
 -combine the qh check with the check for devaddr changes
 -also ensure that p gets set to NULL when the queue gets cancelled on
  devaddr change, which was not done properly before this patch
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+(cherry picked from commit dafe31fc2a8653b535d58f8c7b250c0827b14420)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 39 ++++++++++++++++++++++++++++-----------
  1 file changed, 28 insertions(+), 11 deletions(-)
@@ -80,5 +82,5 @@ index e7c36f4..35eb441 100644
          q->dev = ehci_find_device(q->ehci, devaddr);
      }
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0307-ehci-Update-copyright-headers-to-reflect-recent-work.patch b/0132-ehci-Update-copyright-headers-to-reflect-recent-work.patch
similarity index 75%
rename from 0307-ehci-Update-copyright-headers-to-reflect-recent-work.patch
rename to 0132-ehci-Update-copyright-headers-to-reflect-recent-work.patch
index edfb6e0..020cb38 100644
--- a/0307-ehci-Update-copyright-headers-to-reflect-recent-work.patch
+++ b/0132-ehci-Update-copyright-headers-to-reflect-recent-work.patch
@@ -1,13 +1,15 @@
-From faeefe2a1fdb5895bffb1380b318f3cc396cb057 Mon Sep 17 00:00:00 2001
+From cd7309e7fdd000a9b595ab24e6b03d66100c6fde Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Tue, 28 Aug 2012 16:21:12 +0200
-Subject: [PATCH 307/366] ehci: Update copyright headers to reflect recent
- work
+Subject: [PATCH] ehci: Update copyright headers to reflect recent work
 
 Update copyright headers to reflect all the work Gerd and I have been doing
 on the EHCI emulation.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+(cherry picked from commit 522079dd4461c38b9a88bf31a65ea038c5b2be45)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 5 +++++
  1 file changed, 5 insertions(+)
@@ -29,5 +31,5 @@ index 35eb441..78a248f 100644
   * EHCI project was started by Mark Burkley, with contributions by
   * Niels de Vos.  David S. Ahern continued working on it.  Kevin Wolf,
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0308-ehci-Properly-cleanup-packets-on-cancel.patch b/0133-ehci-Properly-cleanup-packets-on-cancel.patch
similarity index 73%
rename from 0308-ehci-Properly-cleanup-packets-on-cancel.patch
rename to 0133-ehci-Properly-cleanup-packets-on-cancel.patch
index 03b9ce4..1e20c4f 100644
--- a/0308-ehci-Properly-cleanup-packets-on-cancel.patch
+++ b/0133-ehci-Properly-cleanup-packets-on-cancel.patch
@@ -1,9 +1,12 @@
-From 95a792a46e8daae4bfb0997f6340bcd8dddea06c Mon Sep 17 00:00:00 2001
+From 35fe185a5455160db638820211bad5aed45a669f Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Thu, 30 Aug 2012 15:00:33 +0200
-Subject: [PATCH 308/366] ehci: Properly cleanup packets on cancel
+Subject: [PATCH] ehci: Properly cleanup packets on cancel
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+(cherry picked from commit 0e7953525f52aa6c098dc0c1ce0b4a80ce82da45)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 2 ++
  1 file changed, 2 insertions(+)
@@ -22,5 +25,5 @@ index 78a248f..4fe85c8 100644
      QTAILQ_REMOVE(&p->queue->packets, p, next);
      usb_packet_cleanup(&p->packet);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0309-ehci-Properly-report-completed-but-not-yet-processed.patch b/0134-ehci-Properly-report-completed-but-not-yet-processed.patch
similarity index 85%
rename from 0309-ehci-Properly-report-completed-but-not-yet-processed.patch
rename to 0134-ehci-Properly-report-completed-but-not-yet-processed.patch
index 445b322..e70d469 100644
--- a/0309-ehci-Properly-report-completed-but-not-yet-processed.patch
+++ b/0134-ehci-Properly-report-completed-but-not-yet-processed.patch
@@ -1,14 +1,17 @@
-From 584606864261092041b46806030e4889b747ad41 Mon Sep 17 00:00:00 2001
+From c7251f2557d09ce4b8466eeccd0f3264c297c515 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Thu, 30 Aug 2012 15:18:24 +0200
-Subject: [PATCH 309/366] ehci: Properly report completed but not yet
- processed packets to the guest
+Subject: [PATCH] ehci: Properly report completed but not yet processed
+ packets to the guest
 
 Reported packets which have completed before being cancelled as such to the
 host. Note that the new code path this patch adds is untested since it I've
 been unable to actually trigger the race which needs this code path.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+(cherry picked from commit 4b63a0df3bda8a2c278e45d9d94d9ba6d5791d8d)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 13 +++++++++++++
  1 file changed, 13 insertions(+)
@@ -45,5 +48,5 @@ index 4fe85c8..0a6c9ef 100644
      usb_packet_cleanup(&p->packet);
      g_free(p);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0310-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch b/0135-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch
similarity index 85%
rename from 0310-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch
rename to 0135-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch
index bcb596c..f53bbe2 100644
--- a/0310-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch
+++ b/0135-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch
@@ -1,13 +1,16 @@
-From 6f009493144d09e417997caa13b62a38798dc206 Mon Sep 17 00:00:00 2001
+From b3950fe894e2b26f9dba0888af092cb43d01a466 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Fri, 31 Aug 2012 10:31:54 +0200
-Subject: [PATCH 310/366] ehci: check for EHCI_ASYNC_FINISHED first in
+Subject: [PATCH] ehci: check for EHCI_ASYNC_FINISHED first in
  ehci_free_packet
 
 Otherwise we'll see the packet free twice in the trace log even though
 it actually happens only once.
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 616789cde2a83fad5e634880fd20214f0c984fd5)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 12 ++++++------
  1 file changed, 6 insertions(+), 6 deletions(-)
@@ -43,5 +46,5 @@ index 0a6c9ef..23221d0 100644
      usb_packet_cleanup(&p->packet);
      g_free(p);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0311-ehci-trace-guest-bugs.patch b/0136-ehci-trace-guest-bugs.patch
similarity index 93%
rename from 0311-ehci-trace-guest-bugs.patch
rename to 0136-ehci-trace-guest-bugs.patch
index 0abd96e..52c2f4a 100644
--- a/0311-ehci-trace-guest-bugs.patch
+++ b/0136-ehci-trace-guest-bugs.patch
@@ -1,13 +1,16 @@
-From 044dcae94243d03739c309935a68b646424a4d4e Mon Sep 17 00:00:00 2001
+From 82b29b635d26ad0f5e14fabdf0956e9b8e7dbbfb Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Fri, 31 Aug 2012 10:44:21 +0200
-Subject: [PATCH 311/366] ehci: trace guest bugs
+Subject: [PATCH] ehci: trace guest bugs
 
 make qemu_queue_{cancel,reset} return the number of packets released,
 so the caller can figure whenever there have been active packets even
 though there shouldn't have been any.  Add tracepoint to log this.
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 5c514681abbb3ae2f61f517c1aa3197f2f3ca93c)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 26 ++++++++++++++++++++------
  trace-events      |  1 +
@@ -102,5 +105,5 @@ index 8fcbc50..5112a47 100644
  # hw/usb/hcd-uhci.c
  usb_uhci_reset(void) "=== RESET ==="
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0312-ehci-add-doorbell-trace-events.patch b/0137-ehci-add-doorbell-trace-events.patch
similarity index 87%
rename from 0312-ehci-add-doorbell-trace-events.patch
rename to 0137-ehci-add-doorbell-trace-events.patch
index 817132d..33fb2a2 100644
--- a/0312-ehci-add-doorbell-trace-events.patch
+++ b/0137-ehci-add-doorbell-trace-events.patch
@@ -1,9 +1,12 @@
-From 77e3a7e6bf15a85040101e7c0990dd82abdc9e9c Mon Sep 17 00:00:00 2001
+From bd1c78528cbd45629fe31127f5bde708263d6e17 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Fri, 31 Aug 2012 12:41:43 +0200
-Subject: [PATCH 312/366] ehci: add doorbell trace events
+Subject: [PATCH] ehci: add doorbell trace events
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 1defcbd1e81d67476b6e4e486bcd4d869162900d)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 3 ++-
  trace-events      | 2 ++
@@ -44,5 +47,5 @@ index 5112a47..10bc04e 100644
  # hw/usb/hcd-uhci.c
  usb_uhci_reset(void) "=== RESET ==="
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0313-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch b/0138-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch
similarity index 90%
rename from 0313-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch
rename to 0138-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch
index 0587c98..8a62ee7 100644
--- a/0313-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch
+++ b/0138-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch
@@ -1,11 +1,13 @@
-From cbbfcc647e26708cdd78c8ddf28d99f8a1e1e6b0 Mon Sep 17 00:00:00 2001
+From 9dc252544b41a626bbdf436a3e6f229fa0014143 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 3 Sep 2012 10:22:16 +0200
-Subject: [PATCH 313/366] ehci: Add some additional ehci_trace_guest_bug()
- calls
+Subject: [PATCH] ehci: Add some additional ehci_trace_guest_bug() calls
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 3a8ca08e01ea4baafff2a513655008cdd00feebf)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 19 +++++++++++++------
  1 file changed, 13 insertions(+), 6 deletions(-)
@@ -82,5 +84,5 @@ index 398f5e0..5a88268 100644
      }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0314-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch b/0139-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch
similarity index 93%
rename from 0314-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch
rename to 0139-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch
index 3c82869..b144ab4 100644
--- a/0314-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch
+++ b/0139-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch
@@ -1,7 +1,7 @@
-From 68851693ee59d3f17c14983902076a5ef49e2e80 Mon Sep 17 00:00:00 2001
+From 5d369bd44cf2611f47fec52c7402472cd2436b4a Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 3 Sep 2012 11:01:13 +0200
-Subject: [PATCH 314/366] ehci: Fix memory leak in handling of NAK-ed packets
+Subject: [PATCH] ehci: Fix memory leak in handling of NAK-ed packets
 
 Currently each time we try to execute a NAK-ed packet we redo
 ehci_init_transfer, and usb_packet_map, re-allocing (without freeing) the
@@ -12,6 +12,9 @@ that we also properly cleanup a NAK-ed packet on cancel.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit ef5b234477df80700b128f561f5877a0688a70c8)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 38 +++++++++++++++++++++++++++-----------
  1 file changed, 27 insertions(+), 11 deletions(-)
@@ -113,5 +116,5 @@ index 5a88268..d87aca8 100644
              break;
          case EHCI_ASYNC_FINISHED:
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0315-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch b/0140-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch
similarity index 85%
rename from 0315-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch
rename to 0140-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch
index a52d3db..74b2853 100644
--- a/0315-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch
+++ b/0140-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch
@@ -1,13 +1,16 @@
-From 1599d0b01712fb16c3ad291b653a31f768f7f5ef Mon Sep 17 00:00:00 2001
+From 90905dca56de07f7c394ef8cbe480a0d08e0d8cd Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 3 Sep 2012 11:35:58 +0200
-Subject: [PATCH 315/366] ehci: Handle USB_RET_PROCERR in ehci_fill_queue
+Subject: [PATCH] ehci: Handle USB_RET_PROCERR in ehci_fill_queue
 
 USB_RET_PROCERR can be triggered by the guest (by for example requesting more
 then BUFFSIZE bytes), so don't assert on it.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit eff6dce79bd7ad3c16d75c5e55b5a2a137ba6a60)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 9 ++++++---
  1 file changed, 6 insertions(+), 3 deletions(-)
@@ -50,5 +53,5 @@ index d87aca8..2534394 100644
      }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0316-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch b/0141-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch
similarity index 81%
rename from 0316-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch
rename to 0141-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch
index 8bd379d..99c1351 100644
--- a/0316-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch
+++ b/0141-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch
@@ -1,8 +1,7 @@
-From d17b1ad80cba3354b3eca5b8464bf7bb3f8e95c1 Mon Sep 17 00:00:00 2001
+From e598e28401bb25d4d639b29f297a549badbf0cfa Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 3 Sep 2012 12:17:48 +0200
-Subject: [PATCH 316/366] ehci: Correct a comment in fetchqtd packet
- processing
+Subject: [PATCH] ehci: Correct a comment in fetchqtd packet processing
 
 Since my previous comment said "Should never happen", I tried changing the
 next line to an assert(0), which did not go well, which as the new comments
@@ -10,6 +9,9 @@ explains is logical if you think about it for a moment.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit cf1f81691d1998fa8fe5bfcb8b498fb3723cf3c3)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 5 ++++-
  1 file changed, 4 insertions(+), 1 deletion(-)
@@ -31,5 +33,5 @@ index 2534394..2f3e9c0 100644
              break;
          }
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0317-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch b/0142-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch
similarity index 78%
rename from 0317-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch
rename to 0142-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch
index 01ce1e1..f2723ac 100644
--- a/0317-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch
+++ b/0142-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch
@@ -1,8 +1,8 @@
-From a15db9c6d428a756f6ad4055334e476cd90b31f6 Mon Sep 17 00:00:00 2001
+From 262c9bb1e59c2cd561dad1cf9d47c50f07af0e0f Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Fri, 17 Aug 2012 17:27:08 +0200
-Subject: [PATCH 317/366] usb-redir: Never return USB_RET_NAK for async
- handled packets
+Subject: [PATCH] usb-redir: Never return USB_RET_NAK for async handled
+ packets
 
 USB_RET_NAK is not a valid response for async handled packets (and will
 trigger an assert as such).
@@ -13,15 +13,18 @@ by the usbredir-host while transfers are pending.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 181133404f520fab40a3ad40d935d91cf3cf546c)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/redirect.c | 9 ++++++---
  1 file changed, 6 insertions(+), 3 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 1460515..9ba964e 100644
+index 10b4fbb..7f3719b 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
-@@ -1055,11 +1055,14 @@ static int usbredir_handle_status(USBRedirDevice *dev,
+@@ -1028,11 +1028,14 @@ static int usbredir_handle_status(USBRedirDevice *dev,
      case usb_redir_stall:
          return USB_RET_STALL;
      case usb_redir_cancelled:
@@ -40,5 +43,5 @@ index 1460515..9ba964e 100644
          return USB_RET_BABBLE;
      case usb_redir_ioerror:
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0318-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch b/0143-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch
similarity index 91%
rename from 0318-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch
rename to 0143-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch
index 4994684..33f3ae9 100644
--- a/0318-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch
+++ b/0143-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch
@@ -1,8 +1,8 @@
-From acf269a7bbed7c969eb9be02943f7e4b52196a8f Mon Sep 17 00:00:00 2001
+From b89a0cc1ec9dbe30cbe002f12d487a52950da166 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Thu, 23 Aug 2012 16:37:19 +0200
-Subject: [PATCH 318/366] usb-redir: Don't delay handling of open events to a
- bottom half
+Subject: [PATCH] usb-redir: Don't delay handling of open events to a bottom
+ half
 
 There is no need for this, and doing so means that a backend trying to
 write immediately after an open event will see qemu_chr_be_can_write
@@ -11,12 +11,15 @@ mechanism to detect when the frontend does become writable.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit ed9873bfbf145c084d039baab08c63b9d67e7bd3)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/redirect.c | 100 +++++++++++++++++++++++++++++-------------------------
  1 file changed, 53 insertions(+), 47 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 9ba964e..8ac8637 100644
+index 7f3719b..5cc3334 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
 @@ -79,8 +79,8 @@ struct USBRedirDevice {
@@ -30,7 +33,7 @@ index 9ba964e..8ac8637 100644
      /* To delay the usb attach in case of quick chardev close + open */
      QEMUTimer *attach_timer;
      int64_t next_attach_time;
-@@ -794,18 +794,11 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
+@@ -784,18 +784,11 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
   * from within the USBDevice data / control packet callbacks and doing a
   * usb_detach from within these callbacks is not a good idea.
   *
@@ -51,7 +54,7 @@ index 9ba964e..8ac8637 100644
  
      usbredir_device_disconnect(dev);
  
-@@ -813,36 +806,47 @@ static void usbredir_open_close_bh(void *opaque)
+@@ -803,36 +796,47 @@ static void usbredir_open_close_bh(void *opaque)
          usbredirparser_destroy(dev->parser);
          dev->parser = NULL;
      }
@@ -127,7 +130,7 @@ index 9ba964e..8ac8637 100644
  }
  
  static void usbredir_do_attach(void *opaque)
-@@ -866,13 +870,13 @@ static int usbredir_chardev_can_read(void *opaque)
+@@ -856,13 +860,13 @@ static int usbredir_chardev_can_read(void *opaque)
  {
      USBRedirDevice *dev = opaque;
  
@@ -146,7 +149,7 @@ index 9ba964e..8ac8637 100644
  }
  
  static void usbredir_chardev_read(void *opaque, const uint8_t *buf, int size)
-@@ -896,8 +900,10 @@ static void usbredir_chardev_event(void *opaque, int event)
+@@ -886,8 +890,10 @@ static void usbredir_chardev_event(void *opaque, int event)
  
      switch (event) {
      case CHR_EVENT_OPENED:
@@ -158,7 +161,7 @@ index 9ba964e..8ac8637 100644
          break;
      }
  }
-@@ -945,7 +951,7 @@ static int usbredir_initfn(USBDevice *udev)
+@@ -917,7 +923,7 @@ static int usbredir_initfn(USBDevice *udev)
          }
      }
  
@@ -167,7 +170,7 @@ index 9ba964e..8ac8637 100644
      dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
  
      QTAILQ_INIT(&dev->asyncq);
-@@ -984,7 +990,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
+@@ -957,7 +963,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
      qemu_chr_fe_close(dev->cs);
      qemu_chr_delete(dev->cs);
      /* Note must be done after qemu_chr_close, as that causes a close event */
@@ -177,5 +180,5 @@ index 9ba964e..8ac8637 100644
      qemu_del_timer(dev->attach_timer);
      qemu_free_timer(dev->attach_timer);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0319-usb-redir-Get-rid-of-async-struct-get-member.patch b/0144-usb-redir-Get-rid-of-async-struct-get-member.patch
similarity index 78%
rename from 0319-usb-redir-Get-rid-of-async-struct-get-member.patch
rename to 0144-usb-redir-Get-rid-of-async-struct-get-member.patch
index daf27ed..7ac41ee 100644
--- a/0319-usb-redir-Get-rid-of-async-struct-get-member.patch
+++ b/0144-usb-redir-Get-rid-of-async-struct-get-member.patch
@@ -1,7 +1,7 @@
-From 5f83bc6b7bf54271bc1e3460b2e6f790407964e0 Mon Sep 17 00:00:00 2001
+From a9fd3192a956ed1bce0f945f6b35bf9b162b30c3 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 27 Aug 2012 16:33:08 +0200
-Subject: [PATCH 319/366] usb-redir: Get rid of async-struct get member
+Subject: [PATCH] usb-redir: Get rid of async-struct get member
 
 This is a preparation patch for completely getting rid of the async-packet
 struct in usb-redir, instead relying on the (new) per ep queues in the
@@ -9,12 +9,15 @@ qemu usb core.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit cb897117cdedd488f19985c8ec5ea05971103a27)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/redirect.c | 9 +++------
  1 file changed, 3 insertions(+), 6 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 8ac8637..4121983 100644
+index 5cc3334..2cae8c5 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
 @@ -1,7 +1,7 @@
@@ -34,7 +37,7 @@ index 8ac8637..4121983 100644
      union {
          struct usb_redir_control_packet_header control_packet;
          struct usb_redir_bulk_packet_header bulk_packet;
-@@ -682,7 +681,6 @@ static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
+@@ -672,7 +671,6 @@ static int usbredir_get_config(USBRedirDevice *dev, USBPacket *p)
  
      DPRINTF("get config id %u\n", aurb->packet_id);
  
@@ -42,7 +45,7 @@ index 8ac8637..4121983 100644
      usbredirparser_send_get_configuration(dev->parser, aurb->packet_id);
      usbredirparser_do_write(dev->parser);
      return USB_RET_ASYNC;
-@@ -731,7 +729,6 @@ static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
+@@ -721,7 +719,6 @@ static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
      DPRINTF("get interface %d id %u\n", interface, aurb->packet_id);
  
      get_alt.interface = interface;
@@ -50,7 +53,7 @@ index 8ac8637..4121983 100644
      usbredirparser_send_get_alt_setting(dev->parser, aurb->packet_id,
                                          &get_alt);
      usbredirparser_do_write(dev->parser);
-@@ -1253,7 +1250,7 @@ static void usbredir_configuration_status(void *priv, uint32_t id,
+@@ -1226,7 +1223,7 @@ static void usbredir_configuration_status(void *priv, uint32_t id,
          return;
      }
      if (aurb->packet) {
@@ -59,7 +62,7 @@ index 8ac8637..4121983 100644
              dev->dev.data_buf[0] = config_status->configuration;
              len = 1;
          }
-@@ -1281,7 +1278,7 @@ static void usbredir_alt_setting_status(void *priv, uint32_t id,
+@@ -1254,7 +1251,7 @@ static void usbredir_alt_setting_status(void *priv, uint32_t id,
          return;
      }
      if (aurb->packet) {
@@ -69,5 +72,5 @@ index 8ac8637..4121983 100644
              len = 1;
          }
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0320-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch b/0145-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch
similarity index 83%
rename from 0320-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch
rename to 0145-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch
index ea5b5ed..eb581df 100644
--- a/0320-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch
+++ b/0145-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch
@@ -1,8 +1,7 @@
-From 3240adfcb041efcb11b4cbf4b08dc86be52b8ffc Mon Sep 17 00:00:00 2001
+From 40d22426e0e12f26c7bfa5848cf0a9857d52dc99 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Tue, 28 Aug 2012 09:05:38 +0200
-Subject: [PATCH 320/366] usb-redir: Get rid of local shadow copy of packet
- headers
+Subject: [PATCH] usb-redir: Get rid of local shadow copy of packet headers
 
 The shadow copy only serves as an extra check (besides the packet-id) to
 ensure the packet we get back is a reply to the packet we think it is.
@@ -18,12 +17,15 @@ qemu usb core.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 104981d52b63dc3d68f39d4442881c667f44bbb9)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/redirect.c | 27 ---------------------------
  1 file changed, 27 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 4121983..816a19a 100644
+index 2cae8c5..e4ef372 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
 @@ -99,11 +99,6 @@ struct AsyncURB {
@@ -38,7 +40,7 @@ index 4121983..816a19a 100644
      QTAILQ_ENTRY(AsyncURB)next;
  };
  
-@@ -510,7 +505,6 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
+@@ -500,7 +495,6 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
      bulk_packet.endpoint  = ep;
      bulk_packet.length    = p->iov.size;
      bulk_packet.stream_id = 0;
@@ -46,7 +48,7 @@ index 4121983..816a19a 100644
  
      if (ep & USB_DIR_IN) {
          usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id,
-@@ -591,7 +585,6 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
+@@ -581,7 +575,6 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
  
          interrupt_packet.endpoint  = ep;
          interrupt_packet.length    = p->iov.size;
@@ -54,7 +56,7 @@ index 4121983..816a19a 100644
  
          usb_packet_copy(p, buf, p->iov.size);
          usbredir_log_data(dev, "interrupt data out:", buf, p->iov.size);
-@@ -772,7 +765,6 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
+@@ -762,7 +755,6 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
      control_packet.value       = value;
      control_packet.index       = index;
      control_packet.length      = length;
@@ -62,7 +64,7 @@ index 4121983..816a19a 100644
  
      if (control_packet.requesttype & USB_DIR_IN) {
          usbredirparser_send_control_packet(dev->parser, aurb->packet_id,
-@@ -1353,14 +1345,6 @@ static void usbredir_control_packet(void *priv, uint32_t id,
+@@ -1326,14 +1318,6 @@ static void usbredir_control_packet(void *priv, uint32_t id,
          return;
      }
  
@@ -77,7 +79,7 @@ index 4121983..816a19a 100644
      if (aurb->packet) {
          len = usbredir_handle_status(dev, control_packet->status, len);
          if (len > 0) {
-@@ -1398,12 +1382,6 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
+@@ -1371,12 +1355,6 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
          return;
      }
  
@@ -90,7 +92,7 @@ index 4121983..816a19a 100644
      if (aurb->packet) {
          len = usbredir_handle_status(dev, bulk_packet->status, len);
          if (len > 0) {
-@@ -1482,11 +1460,6 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id,
+@@ -1455,11 +1433,6 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id,
              return;
          }
  
@@ -103,5 +105,5 @@ index 4121983..816a19a 100644
              aurb->packet->result = usbredir_handle_status(dev,
                                                 interrupt_packet->status, len);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0321-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch b/0146-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch
similarity index 72%
rename from 0321-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch
rename to 0146-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch
index 3852c31..18c7c1f 100644
--- a/0321-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch
+++ b/0146-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch
@@ -1,7 +1,7 @@
-From 1b1c99626404328b571e1f6c18b50f9bed9c2e2c Mon Sep 17 00:00:00 2001
+From 008e2fcbeea527c3aff3078ed5a178d59757bc28 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Tue, 28 Aug 2012 09:08:45 +0200
-Subject: [PATCH 321/366] usb-redir: Get rid of unused async-struct dev member
+Subject: [PATCH] usb-redir: Get rid of unused async-struct dev member
 
 This is a preparation patch for completely getting rid of the async-packet
 struct in usb-redir, instead relying on the (new) per ep queues in the
@@ -9,12 +9,15 @@ qemu usb core.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 206e7f20fe7b920b362bcc02608680c5d5527f2a)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/redirect.c | 2 --
  1 file changed, 2 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 816a19a..4a23b82 100644
+index e4ef372..6593d50 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
 @@ -96,7 +96,6 @@ struct USBRedirDevice {
@@ -25,7 +28,7 @@ index 816a19a..4a23b82 100644
      USBPacket *packet;
      uint32_t packet_id;
      QTAILQ_ENTRY(AsyncURB)next;
-@@ -255,7 +254,6 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
+@@ -245,7 +244,6 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
  static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
  {
      AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
@@ -34,5 +37,5 @@ index 816a19a..4a23b82 100644
      aurb->packet_id = dev->packet_id;
      QTAILQ_INSERT_TAIL(&dev->asyncq, aurb, next);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0322-usb-redir-Move-to-core-packet-id-and-queue-handling.patch b/0147-usb-redir-Move-to-core-packet-id-and-queue-handling.patch
similarity index 91%
rename from 0322-usb-redir-Move-to-core-packet-id-and-queue-handling.patch
rename to 0147-usb-redir-Move-to-core-packet-id-and-queue-handling.patch
index 0bf0d67..f32e6cc 100644
--- a/0322-usb-redir-Move-to-core-packet-id-and-queue-handling.patch
+++ b/0147-usb-redir-Move-to-core-packet-id-and-queue-handling.patch
@@ -1,16 +1,19 @@
-From 69642884acc4f5d5b92e16d94fdae50765d1eba7 Mon Sep 17 00:00:00 2001
+From 111194442fa38ba6dc26bc695ba0d3b76584663b Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Tue, 28 Aug 2012 11:30:13 +0200
-Subject: [PATCH 322/366] usb-redir: Move to core packet id and queue handling
+Subject: [PATCH] usb-redir: Move to core packet id and queue handling
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit de550a6afb468ed3b8171019e19b63ae8254886d)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/redirect.c | 226 ++++++++++++++++++++++--------------------------------
  1 file changed, 92 insertions(+), 134 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 4a23b82..1ce994c 100644
+index 6593d50..fd1f8cc 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
 @@ -43,7 +43,7 @@
@@ -46,7 +49,7 @@ index 4a23b82..1ce994c 100644
  };
  
  static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
-@@ -248,57 +246,58 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
+@@ -238,57 +236,58 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
  }
  
  /*
@@ -139,7 +142,7 @@ index 4a23b82..1ce994c 100644
  }
  
  static void bufp_alloc(USBRedirDevice *dev,
-@@ -494,24 +493,22 @@ static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
+@@ -484,24 +483,22 @@ static void usbredir_stop_iso_stream(USBRedirDevice *dev, uint8_t ep)
  static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
                                        uint8_t ep)
  {
@@ -167,7 +170,7 @@ index 4a23b82..1ce994c 100644
                                          &bulk_packet, buf, p->iov.size);
      }
      usbredirparser_do_write(dev->parser);
-@@ -574,19 +571,18 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
+@@ -564,19 +561,18 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
          return len;
      } else {
          /* Output interrupt endpoint, normal async operation */
@@ -190,7 +193,7 @@ index 4a23b82..1ce994c 100644
                                          &interrupt_packet, buf, p->iov.size);
          usbredirparser_do_write(dev->parser);
          return USB_RET_ASYNC;
-@@ -640,10 +636,9 @@ static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
+@@ -630,10 +626,9 @@ static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
                                  int config)
  {
      struct usb_redir_set_configuration_header set_config;
@@ -202,7 +205,7 @@ index 4a23b82..1ce994c 100644
  
      for (i = 0; i < MAX_ENDPOINTS; i++) {
          switch (dev->endpoint[i].type) {
-@@ -660,19 +655,16 @@ static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
+@@ -650,19 +645,16 @@ static int usbredir_set_config(USBRedirDevice *dev, USBPacket *p,
      }
  
      set_config.configuration = config;
@@ -225,7 +228,7 @@ index 4a23b82..1ce994c 100644
      usbredirparser_do_write(dev->parser);
      return USB_RET_ASYNC;
  }
-@@ -681,11 +673,9 @@ static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
+@@ -671,11 +663,9 @@ static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
                                     int interface, int alt)
  {
      struct usb_redir_set_alt_setting_header set_alt;
@@ -238,7 +241,7 @@ index 4a23b82..1ce994c 100644
  
      for (i = 0; i < MAX_ENDPOINTS; i++) {
          if (dev->endpoint[i].interface == interface) {
-@@ -705,8 +695,7 @@ static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
+@@ -695,8 +685,7 @@ static int usbredir_set_interface(USBRedirDevice *dev, USBPacket *p,
  
      set_alt.interface = interface;
      set_alt.alt = alt;
@@ -248,7 +251,7 @@ index 4a23b82..1ce994c 100644
      usbredirparser_do_write(dev->parser);
      return USB_RET_ASYNC;
  }
-@@ -715,13 +704,11 @@ static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
+@@ -705,13 +694,11 @@ static int usbredir_get_interface(USBRedirDevice *dev, USBPacket *p,
                                     int interface)
  {
      struct usb_redir_get_alt_setting_header get_alt;
@@ -264,7 +267,7 @@ index 4a23b82..1ce994c 100644
      usbredirparser_do_write(dev->parser);
      return USB_RET_ASYNC;
  }
-@@ -731,7 +718,6 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
+@@ -721,7 +708,6 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
  {
      USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
      struct usb_redir_control_packet_header control_packet;
@@ -272,7 +275,7 @@ index 4a23b82..1ce994c 100644
  
      /* Special cases for certain standard device requests */
      switch (request) {
-@@ -749,13 +735,10 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
+@@ -739,13 +725,10 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
          return usbredir_get_interface(dev, p, index);
      }
  
@@ -290,7 +293,7 @@ index 4a23b82..1ce994c 100644
  
      control_packet.request     = request & 0xFF;
      control_packet.requesttype = request >> 8;
-@@ -765,11 +748,11 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
+@@ -755,11 +738,11 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
      control_packet.length      = length;
  
      if (control_packet.requesttype & USB_DIR_IN) {
@@ -304,7 +307,7 @@ index 4a23b82..1ce994c 100644
                                             &control_packet, data, length);
      }
      usbredirparser_do_write(dev->parser);
-@@ -941,7 +924,7 @@ static int usbredir_initfn(USBDevice *udev)
+@@ -913,7 +896,7 @@ static int usbredir_initfn(USBDevice *udev)
      dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
      dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
  
@@ -313,7 +316,7 @@ index 4a23b82..1ce994c 100644
      for (i = 0; i < MAX_ENDPOINTS; i++) {
          QTAILQ_INIT(&dev->endpoint[i].bufpq);
      }
-@@ -959,11 +942,12 @@ static int usbredir_initfn(USBDevice *udev)
+@@ -932,11 +915,12 @@ static int usbredir_initfn(USBDevice *udev)
  
  static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
  {
@@ -329,7 +332,7 @@ index 4a23b82..1ce994c 100644
      }
      for (i = 0; i < MAX_ENDPOINTS; i++) {
          usbredir_free_bufpq(dev, I2EP(i));
-@@ -1229,33 +1213,28 @@ static void usbredir_configuration_status(void *priv, uint32_t id,
+@@ -1202,33 +1186,28 @@ static void usbredir_configuration_status(void *priv, uint32_t id,
      struct usb_redir_configuration_status_header *config_status)
  {
      USBRedirDevice *dev = priv;
@@ -369,7 +372,7 @@ index 4a23b82..1ce994c 100644
      int len = 0;
  
      DPRINTF("alt status %d intf %d alt %d id: %u\n",
-@@ -1263,20 +1242,16 @@ static void usbredir_alt_setting_status(void *priv, uint32_t id,
+@@ -1236,20 +1215,16 @@ static void usbredir_alt_setting_status(void *priv, uint32_t id,
              alt_setting_status->interface,
              alt_setting_status->alt, id);
  
@@ -394,7 +397,7 @@ index 4a23b82..1ce994c 100644
  }
  
  static void usbredir_iso_stream_status(void *priv, uint32_t id,
-@@ -1331,19 +1306,14 @@ static void usbredir_control_packet(void *priv, uint32_t id,
+@@ -1304,19 +1279,14 @@ static void usbredir_control_packet(void *priv, uint32_t id,
      uint8_t *data, int data_len)
  {
      USBRedirDevice *dev = priv;
@@ -417,7 +420,7 @@ index 4a23b82..1ce994c 100644
          len = usbredir_handle_status(dev, control_packet->status, len);
          if (len > 0) {
              usbredir_log_data(dev, "ctrl data in:", data, data_len);
-@@ -1355,10 +1325,9 @@ static void usbredir_control_packet(void *priv, uint32_t id,
+@@ -1328,10 +1298,9 @@ static void usbredir_control_packet(void *priv, uint32_t id,
                  len = USB_RET_STALL;
              }
          }
@@ -430,7 +433,7 @@ index 4a23b82..1ce994c 100644
      free(data);
  }
  
-@@ -1369,33 +1338,27 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
+@@ -1342,33 +1311,27 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
      USBRedirDevice *dev = priv;
      uint8_t ep = bulk_packet->endpoint;
      int len = bulk_packet->length;
@@ -472,7 +475,7 @@ index 4a23b82..1ce994c 100644
      free(data);
  }
  
-@@ -1453,17 +1416,12 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id,
+@@ -1426,17 +1389,12 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id,
      } else {
          int len = interrupt_packet->length;
  
@@ -495,5 +498,5 @@ index 4a23b82..1ce994c 100644
  }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0323-usb-redir-Return-babble-when-getting-more-bulk-data-.patch b/0148-usb-redir-Return-babble-when-getting-more-bulk-data-.patch
similarity index 71%
rename from 0323-usb-redir-Return-babble-when-getting-more-bulk-data-.patch
rename to 0148-usb-redir-Return-babble-when-getting-more-bulk-data-.patch
index 20a9db2..4c4e98b 100644
--- a/0323-usb-redir-Return-babble-when-getting-more-bulk-data-.patch
+++ b/0148-usb-redir-Return-babble-when-getting-more-bulk-data-.patch
@@ -1,22 +1,25 @@
-From bd0bc4416beb7ecef0baf2424250c07b9ef15fb6 Mon Sep 17 00:00:00 2001
+From 138e9d997e487dafbf686e0e1eba44a8b26dcaf7 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Tue, 28 Aug 2012 11:33:47 +0200
-Subject: [PATCH 323/366] usb-redir: Return babble when getting more bulk data
- then requested
+Subject: [PATCH] usb-redir: Return babble when getting more bulk data then
+ requested
 
 Babble is the appropriate error in this case (rather then signalling a stall).
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 2979a36183a3902cd75665e7c6bbc8668668fd17)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/redirect.c | 6 +++---
  1 file changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 1ce994c..60b8f3e 100644
+index fd1f8cc..ee75217 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
-@@ -1351,9 +1351,9 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
+@@ -1324,9 +1324,9 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
              if (data_len <= p->iov.size) {
                  usb_packet_copy(p, data, data_len);
              } else {
@@ -30,5 +33,5 @@ index 1ce994c..60b8f3e 100644
          }
          p->result = len;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0329-Better-name-usb-braille-device.patch b/0149-Better-name-usb-braille-device.patch
similarity index 74%
rename from 0329-Better-name-usb-braille-device.patch
rename to 0149-Better-name-usb-braille-device.patch
index b9cf4e6..00c8599 100644
--- a/0329-Better-name-usb-braille-device.patch
+++ b/0149-Better-name-usb-braille-device.patch
@@ -1,19 +1,22 @@
-From f83e26f01f1489af484f69bdeb2d01d4896de6ec Mon Sep 17 00:00:00 2001
+From 23d25cd58aa7da678cad0ad98d52efe37d0be4e6 Mon Sep 17 00:00:00 2001
 From: Samuel Thibault <samuel.thibault at ens-lyon.org>
 Date: Thu, 23 Aug 2012 09:59:27 +0200
-Subject: [PATCH 329/366] Better name usb braille device
+Subject: [PATCH] Better name usb braille device
 
 Windows users need to know that they have to use the Baum driver to make
 the qemu braille device work.
 
 Signed-off-by: Samuel Thibault <samuel.thibault at ens-lyon.org>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 2964cd9bfa5100e433471d3e3fedcc9d62891894)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/dev-serial.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
-index 8fc9bdd..0ddfab6 100644
+index 8aa6552..69b6e48 100644
 --- a/hw/usb/dev-serial.c
 +++ b/hw/usb/dev-serial.c
 @@ -113,7 +113,7 @@ enum {
@@ -26,5 +29,5 @@ index 8fc9bdd..0ddfab6 100644
  };
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0330-usb-audio-fix-usb-version.patch b/0150-usb-audio-fix-usb-version.patch
similarity index 75%
rename from 0330-usb-audio-fix-usb-version.patch
rename to 0150-usb-audio-fix-usb-version.patch
index c79c18f..ceeb70d 100644
--- a/0330-usb-audio-fix-usb-version.patch
+++ b/0150-usb-audio-fix-usb-version.patch
@@ -1,12 +1,15 @@
-From 77824f2b7aba75a3f31a996634dc836fe26ee2c5 Mon Sep 17 00:00:00 2001
+From 3f8a570db1637c0e7e2dd7a3bd997c92c69efc65 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 28 Aug 2012 16:43:34 +0200
-Subject: [PATCH 330/366] usb-audio: fix usb version
+Subject: [PATCH] usb-audio: fix usb version
 
 usb-audio is a full speed (1.1) device,
 but bcdUSB claims it is usb 2.0.  Fix it.
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 2bbd086c41a00dc4384727ec895a94890c688eb5)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/dev-audio.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
@@ -25,5 +28,5 @@ index 79b75fb..2594c78 100644
      .bNumConfigurations            = 1,
      .confs = (USBDescConfig[]) {
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0331-xhci-rip-out-background-transfer-code.patch b/0151-xhci-rip-out-background-transfer-code.patch
similarity index 97%
rename from 0331-xhci-rip-out-background-transfer-code.patch
rename to 0151-xhci-rip-out-background-transfer-code.patch
index 4ccdfd5..e728029 100644
--- a/0331-xhci-rip-out-background-transfer-code.patch
+++ b/0151-xhci-rip-out-background-transfer-code.patch
@@ -1,7 +1,7 @@
-From f019cdb4b17a0615e897ddac37f2ffa8866a4979 Mon Sep 17 00:00:00 2001
+From f9416f401c9eac3f69b4705a999c6ea1ff457016 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Fri, 17 Aug 2012 14:05:21 +0200
-Subject: [PATCH 331/366] xhci: rip out background transfer code
+Subject: [PATCH] xhci: rip out background transfer code
 
 original xhci code (the one which used libusb directly) used to use
 'background transfers' for iso streams.  In upstream qemu the iso
@@ -10,6 +10,9 @@ never ever need this.  It has been left in as reference, but is dead
 code anyway.  Rip it out.
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 331e9406f152b6bae6859a153d36e5076c58901d)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-xhci.c | 223 +-----------------------------------------------------
  1 file changed, 4 insertions(+), 219 deletions(-)
@@ -320,5 +323,5 @@ index 3eb27fa..c0a2476 100644
          }
          length = xhci_ring_chain_length(xhci, &epctx->ring);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0332-xhci-drop-buffering.patch b/0152-xhci-drop-buffering.patch
similarity index 98%
rename from 0332-xhci-drop-buffering.patch
rename to 0152-xhci-drop-buffering.patch
index 67de840..af60c86 100644
--- a/0332-xhci-drop-buffering.patch
+++ b/0152-xhci-drop-buffering.patch
@@ -1,7 +1,7 @@
-From ba184fe5a0e63bd40956b456d85a01da13d6183d Mon Sep 17 00:00:00 2001
+From 985807ab66338c6a9cab8d68a2b52b0cff0423ee Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Fri, 17 Aug 2012 11:04:36 +0200
-Subject: [PATCH 332/369] xhci: drop buffering
+Subject: [PATCH] xhci: drop buffering
 
 This patch splits the xhci_xfer_data function into three.
 The xhci_xfer_data function used to do does two things:
@@ -24,6 +24,9 @@ using the ISP flag.
 [ v2: fix warning ]
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit d5a15814b413869667b2a3215772986885be574a)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-xhci.c | 185 +++++++++++++++++++++---------------------------------
  trace-events      |   2 +-
@@ -379,5 +382,5 @@ index 10bc04e..c83d65e 100644
  usb_xhci_xfer_nak(void *xfer) "%p"
  usb_xhci_xfer_retry(void *xfer) "%p"
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0338-xhci-fix-runtime-write-tracepoint.patch b/0153-xhci-fix-runtime-write-tracepoint.patch
similarity index 61%
rename from 0338-xhci-fix-runtime-write-tracepoint.patch
rename to 0153-xhci-fix-runtime-write-tracepoint.patch
index a2eebfd..133df2e 100644
--- a/0338-xhci-fix-runtime-write-tracepoint.patch
+++ b/0153-xhci-fix-runtime-write-tracepoint.patch
@@ -1,18 +1,21 @@
-From 9c1e6303c5c86f20ed083a0ed9c829c08fd2ac06 Mon Sep 17 00:00:00 2001
+From 6dacb38ce3cb2ffe8c6e3a3a1bc86eee49d1e07c Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Thu, 30 Aug 2012 12:42:32 +0200
-Subject: [PATCH 338/366] xhci: fix runtime write tracepoint
+Subject: [PATCH] xhci: fix runtime write tracepoint
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 8e9f18b6db1cd67f0a7efd7d0285bee489445197)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-xhci.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 5cdaf76..e8d2372 100644
+index 446d692..24b1f87 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
-@@ -2520,7 +2520,7 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
+@@ -2348,7 +2348,7 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
  
  static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
  {
@@ -22,5 +25,5 @@ index 5cdaf76..e8d2372 100644
      switch (reg) {
      case 0x20: /* IMAN */
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0354-xhci-allow-bytewise-capability-register-reads.patch b/0154-xhci-allow-bytewise-capability-register-reads.patch
similarity index 54%
rename from 0354-xhci-allow-bytewise-capability-register-reads.patch
rename to 0154-xhci-allow-bytewise-capability-register-reads.patch
index 12b4338..0870f14 100644
--- a/0354-xhci-allow-bytewise-capability-register-reads.patch
+++ b/0154-xhci-allow-bytewise-capability-register-reads.patch
@@ -1,24 +1,31 @@
-From 25968a7c7947b7e215e351b159a5f4ebf4609aab Mon Sep 17 00:00:00 2001
+From 0233069eb2724255f03253f0afe814773eaf345c Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 4 Sep 2012 14:48:03 +0200
-Subject: [PATCH 354/366] xhci: allow bytewise capability register reads
+Subject: [PATCH] xhci: allow bytewise capability register reads
 
 Some guests need this according to
 Alejandro Martinez Ruiz <alex at securiforest.com>
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 6ee021d41078844df60a3a466e3829a3e82776f3)
+
+Conflicts:
+
+	hw/usb/hcd-xhci.c
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-xhci.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 500892d..2918e64 100644
+index 24b1f87..333df59 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
-@@ -2748,8 +2748,10 @@ static void xhci_doorbell_write(void *ptr, target_phys_addr_t reg,
- 
- static const MemoryRegionOps xhci_cap_ops = {
-     .read = xhci_cap_read,
+@@ -2474,8 +2474,10 @@ static void xhci_mem_write(void *ptr, target_phys_addr_t addr,
+ static const MemoryRegionOps xhci_mem_ops = {
+     .read = xhci_mem_read,
+     .write = xhci_mem_write,
 -    .valid.min_access_size = 4,
 +    .valid.min_access_size = 1,
      .valid.max_access_size = 4,
@@ -28,5 +35,5 @@ index 500892d..2918e64 100644
  };
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0219-qxl-dont-update-invalid-area.patch b/0155-qxl-dont-update-invalid-area.patch
similarity index 81%
rename from 0219-qxl-dont-update-invalid-area.patch
rename to 0155-qxl-dont-update-invalid-area.patch
index 8739272..902566d 100644
--- a/0219-qxl-dont-update-invalid-area.patch
+++ b/0155-qxl-dont-update-invalid-area.patch
@@ -1,7 +1,7 @@
-From 6f1652c4412ab60c7f456100143c519d124a895c Mon Sep 17 00:00:00 2001
+From 4007ba909e0188ed03d5a1fc1dde094d0ac14488 Mon Sep 17 00:00:00 2001
 From: Dunrong Huang <riegamaths at gmail.com>
 Date: Fri, 31 Aug 2012 00:44:44 +0800
-Subject: [PATCH 215/215] qxl: dont update invalid area
+Subject: [PATCH] qxl: dont update invalid area
 
 This patch fixes the following error:
 
@@ -14,15 +14,18 @@ so dont update those invalid areas.
 
 Signed-off-by: Dunrong Huang <riegamaths at gmail.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit ccc2960d654a233a6ed415b37d8ff41728d817c5)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/qxl.c | 7 +++++++
  1 file changed, 7 insertions(+)
 
 diff --git a/hw/qxl.c b/hw/qxl.c
-index b726c19..045432e 100644
+index 27f3779..038a8bb 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
-@@ -1470,6 +1470,13 @@ async_common:
+@@ -1448,6 +1448,13 @@ async_common:
              return;
          }
  
@@ -37,5 +40,5 @@ index b726c19..045432e 100644
              cookie = qxl_cookie_new(QXL_COOKIE_TYPE_IO,
                                      QXL_IO_UPDATE_AREA_ASYNC);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0355-usb-host-allow-emulated-non-async-control-requests-w.patch b/0156-usb-host-allow-emulated-non-async-control-requests-w.patch
similarity index 78%
rename from 0355-usb-host-allow-emulated-non-async-control-requests-w.patch
rename to 0156-usb-host-allow-emulated-non-async-control-requests-w.patch
index 752582f..11fcb3f 100644
--- a/0355-usb-host-allow-emulated-non-async-control-requests-w.patch
+++ b/0156-usb-host-allow-emulated-non-async-control-requests-w.patch
@@ -1,13 +1,16 @@
-From 487e24442148aa659a53f69db394642a7d93c3c6 Mon Sep 17 00:00:00 2001
+From e84037892a04dac64104b43d0a6342aee4c4e6f4 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Thu, 6 Sep 2012 12:03:41 +0200
-Subject: [PATCH 357/366] usb-host: allow emulated (non-async) control
- requests without USBPacket
+Subject: [PATCH] usb-host: allow emulated (non-async) control requests
+ without USBPacket
 
 xhci needs this for USB_REQ_SET_ADDRESS due to the way
 usb addressing is handled by the xhci hardware.
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 63587e31353b6652cadfcfb869f5692a2b69daeb)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/host-linux.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
@@ -33,5 +36,5 @@ index 8df9207..44f1a64 100644
      if (length > sizeof(dev->data_buf)) {
          fprintf(stderr, "husb: ctrl buffer too small (%d > %zu)\n",
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0221-qxl-better-cleanup-for-surface-destroy.patch b/0157-qxl-better-cleanup-for-surface-destroy.patch
similarity index 76%
rename from 0221-qxl-better-cleanup-for-surface-destroy.patch
rename to 0157-qxl-better-cleanup-for-surface-destroy.patch
index d24e093..b796173 100644
--- a/0221-qxl-better-cleanup-for-surface-destroy.patch
+++ b/0157-qxl-better-cleanup-for-surface-destroy.patch
@@ -1,7 +1,7 @@
-From 2315ba0b57785d788828e6871e528c9ab368068f Mon Sep 17 00:00:00 2001
+From 57ec733394ec42f8a144751de3b9406fb7e17217 Mon Sep 17 00:00:00 2001
 From: Uri Lublin <uril at redhat.com>
 Date: Tue, 11 Sep 2012 10:09:58 +0300
-Subject: [PATCH 221/293] qxl: better cleanup for surface destroy
+Subject: [PATCH] qxl: better cleanup for surface destroy
 
 Add back a call to qxl_spice_destroy_surface_wait_complete() in qxl_spice_destroy_surface_wait(),
 that was removed by commit c480bb7da465186b84d8427e068ef7502e47ffbf
@@ -11,12 +11,15 @@ For async, qxl_spice_destroy_surface_wait_complete is called upon operation comp
 
 Signed-off-by: Uri Lublin <uril at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 753b8b0d77ba1b343a35f9679cc777ea10a62bba)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/qxl.c | 1 +
  1 file changed, 1 insertion(+)
 
 diff --git a/hw/qxl.c b/hw/qxl.c
-index 144a002..9f06f5e 100644
+index 038a8bb..67f7100 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
 @@ -201,6 +201,7 @@ static void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id,
@@ -28,5 +31,5 @@ index 144a002..9f06f5e 100644
  }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0356-ehci-switch-to-new-style-memory-ops.patch b/0158-ehci-switch-to-new-style-memory-ops.patch
similarity index 97%
rename from 0356-ehci-switch-to-new-style-memory-ops.patch
rename to 0158-ehci-switch-to-new-style-memory-ops.patch
index 78e6b4f..4932df4 100644
--- a/0356-ehci-switch-to-new-style-memory-ops.patch
+++ b/0158-ehci-switch-to-new-style-memory-ops.patch
@@ -1,7 +1,7 @@
-From 538ee859ae415782e5be3b4a07e7db655cf70aa2 Mon Sep 17 00:00:00 2001
+From 093374b8c759db877691fde602912a7cafd72a2e Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Thu, 6 Sep 2012 11:24:51 +0200
-Subject: [PATCH 355/366] ehci: switch to new-style memory ops
+Subject: [PATCH] ehci: switch to new-style memory ops
 
 Also register different memory regions for capabilities,
 operational registers and port status registers.  Create
@@ -15,6 +15,9 @@ access on bigendian hosts.
 
 Cc: David Gibson <david at gibson.dropbear.id.au>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 3e4f910c8d490a1490409a7e381dbbb229f9d272)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 173 ++++++++++++++++++++++++++----------------------------
  trace-events      |   9 ++-
@@ -343,7 +346,7 @@ index 2f3e9c0..f5ba8e1 100644
  
      return 0;
 diff --git a/trace-events b/trace-events
-index b25ae1c..a58b0b7 100644
+index c83d65e..cf05414 100644
 --- a/trace-events
 +++ b/trace-events
 @@ -243,9 +243,12 @@ usb_port_release(int bus, const char *port) "bus %d, port %s"
@@ -363,5 +366,5 @@ index b25ae1c..a58b0b7 100644
  usb_ehci_state(const char *schedule, const char *state) "%s schedule %s"
  usb_ehci_qh_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) "q %p - QH @ %08x: next %08x qtds %08x,%08x,%08x"
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0357-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch b/0159-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch
similarity index 73%
rename from 0357-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch
rename to 0159-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch
index 803ab11..bd8d88b 100644
--- a/0357-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch
+++ b/0159-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch
@@ -1,8 +1,8 @@
-From 2ebb3309738501fcc9e8da807866fa4225bb5e91 Mon Sep 17 00:00:00 2001
+From c84ed39e601ff69d93e0ad81d92cb7234ad5d4cd Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
-Date: Mon, 10 Sep 2012 11:44:08 +0200
-Subject: [PATCH 357/369] ehci: Fix interrupts stopping when Interrupt
- Threshold Control is 8
+Date: Mon, 10 Sep 2012 12:44:10 +0200
+Subject: [PATCH] ehci: Fix interrupts stopping when Interrupt Threshold
+ Control is 8
 
 If Interrupt Threshold Control is 8 or a multiple of 8, then
 s->usbsts_frindex can become exactly 0x4000, at which point
@@ -12,6 +12,10 @@ s->usbsts_frindex will not be lowered / reset in this case.
 This patch fixes this.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit ffa1f2e088eb7e3d57f2fc35f21e7bdb23e592c5)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
@@ -30,5 +34,5 @@ index f5ba8e1..54273d7 100644
              } else {
                  ehci->usbsts_frindex = 0;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0358-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch b/0160-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch
similarity index 83%
rename from 0358-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch
rename to 0160-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch
index 9608c63..f0a4b00 100644
--- a/0358-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch
+++ b/0160-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch
@@ -1,8 +1,7 @@
-From d1034a88fdd8ad693a5cc2cb75af946e1562ff09 Mon Sep 17 00:00:00 2001
+From a5022829821b27e00790f8fe2fd9cd8090a47e36 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
-Date: Mon, 10 Sep 2012 12:38:21 +0200
-Subject: [PATCH 358/369] ehci: Don't process too much frames in 1 timer tick
- (v2)
+Date: Mon, 10 Sep 2012 12:44:11 +0200
+Subject: [PATCH] ehci: Don't process too much frames in 1 timer tick (v2)
 
 The Linux ehci isoc scheduling code fills the entire schedule ahead of
 time minus 80 frames. If we make a large jump in where we are in the
@@ -16,12 +15,16 @@ Changes in v2:
  -Stop (after the minimum number) when the guest has requested an irq
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 8f74ed1e43263293301031a10e440549bab19a6e)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 14 ++++++++++++++
  1 file changed, 14 insertions(+)
 
 diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
-index 54273d7..6ce727c 100644
+index 54273d7..017a01d 100644
 --- a/hw/usb/hcd-ehci.c
 +++ b/hw/usb/hcd-ehci.c
 @@ -139,6 +139,7 @@
@@ -36,7 +39,7 @@ index 54273d7..6ce727c 100644
          }
  
          for (i = 0; i < frames; i++) {
-+            /* 
++            /*
 +             * If we're running behind schedule, we should not catch up
 +             * too fast, as that will make some guests unhappy:
 +             * 1) We must process a minimum of MIN_FR_PER_TICK frames,
@@ -53,5 +56,5 @@ index 54273d7..6ce727c 100644
              ehci_advance_periodic_state(ehci);
              ehci->last_run_ns += FRAME_TIMER_NS;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0161-sheepdog-fix-savevm-and-loadvm.patch b/0161-sheepdog-fix-savevm-and-loadvm.patch
new file mode 100644
index 0000000..f85cc0b
--- /dev/null
+++ b/0161-sheepdog-fix-savevm-and-loadvm.patch
@@ -0,0 +1,41 @@
+From f065553b45322bb0ba14a4c9d1fb65554ae3e325 Mon Sep 17 00:00:00 2001
+From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
+Date: Thu, 30 Aug 2012 03:39:45 +0900
+Subject: [PATCH] sheepdog: fix savevm and loadvm
+
+This patch sets data to be sent to Sheepdog correctly and fixes savevm
+and loadvm operations on a Sheepdog image.
+
+Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+(cherry picked from commit 1f7a48de4467f31afc51169122453318efdb0f33)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ block/sheepdog.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/block/sheepdog.c b/block/sheepdog.c
+index df4f441..e0753ee 100644
+--- a/block/sheepdog.c
++++ b/block/sheepdog.c
+@@ -1986,7 +1986,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
+         vdi_index = pos / SD_DATA_OBJ_SIZE;
+         offset = pos % SD_DATA_OBJ_SIZE;
+ 
+-        data_len = MIN(remaining, SD_DATA_OBJ_SIZE);
++        data_len = MIN(remaining, SD_DATA_OBJ_SIZE - offset);
+ 
+         vmstate_oid = vid_to_vmstate_oid(s->inode.vdi_id, vdi_index);
+ 
+@@ -2007,6 +2007,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
+         }
+ 
+         pos += data_len;
++        data += data_len;
+         remaining -= data_len;
+     }
+     ret = size;
+-- 
+1.7.12.1
+
diff --git a/0162-ide-Fix-error-messages-from-static-code-analysis-no-.patch b/0162-ide-Fix-error-messages-from-static-code-analysis-no-.patch
new file mode 100644
index 0000000..62a21ce
--- /dev/null
+++ b/0162-ide-Fix-error-messages-from-static-code-analysis-no-.patch
@@ -0,0 +1,67 @@
+From 8557d38b8d660d07c7b6fd1bfa62182cc6c52400 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Mon, 3 Sep 2012 22:13:56 +0200
+Subject: [PATCH] ide: Fix error messages from static code analysis (no real
+ error)
+
+Report from smatch:
+hw/ide/core.c:1472 ide_exec_cmd(423) error: buffer overflow 'smart_attributes' 8 <= 29
+hw/ide/core.c:1474 ide_exec_cmd(425) error: buffer overflow 'smart_attributes' 8 <= 29
+hw/ide/core.c:1475 ide_exec_cmd(426) error: buffer overflow 'smart_attributes' 8 <= 29
+...
+
+The upper limit of 30 was never reached because both for loops terminated
+when 'smart_attributes' reached end of list, so there was no real buffer
+overflow.
+
+Nevertheless, changing the code not only fixes the error report, but also
+reduces the size of smart_attributes and simplifies the for loops.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+(cherry picked from commit 1e53537fdaa4657d11f130a0f2673fcfb1956381)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/ide/core.c | 11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+diff --git a/hw/ide/core.c b/hw/ide/core.c
+index d65ef3d..d6fb69c 100644
+--- a/hw/ide/core.c
++++ b/hw/ide/core.c
+@@ -53,8 +53,6 @@ static const int smart_attributes[][12] = {
+     { 0x0c, 0x03, 0x00, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+     /* airflow-temperature-celsius */
+     { 190,  0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32},
+-    /* end of list */
+-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+ };
+ 
+ static int ide_handle_rw_error(IDEState *s, int error, int op);
+@@ -1468,9 +1466,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
+ 	case SMART_READ_THRESH:
+ 		memset(s->io_buffer, 0, 0x200);
+ 		s->io_buffer[0] = 0x01; /* smart struct version */
+-		for (n=0; n<30; n++) {
+-		if (smart_attributes[n][0] == 0)
+-			break;
++		for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {
+ 		s->io_buffer[2+0+(n*12)] = smart_attributes[n][0];
+ 		s->io_buffer[2+1+(n*12)] = smart_attributes[n][11];
+ 		}
+@@ -1484,10 +1480,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
+ 	case SMART_READ_DATA:
+ 		memset(s->io_buffer, 0, 0x200);
+ 		s->io_buffer[0] = 0x01; /* smart struct version */
+-		for (n=0; n<30; n++) {
+-		    if (smart_attributes[n][0] == 0) {
+-			break;
+-		    }
++		for (n = 0; n < ARRAY_SIZE(smart_attributes); n++) {
+ 		    int i;
+ 		    for(i = 0; i < 11; i++) {
+ 			s->io_buffer[2+i+(n*12)] = smart_attributes[n][i];
+-- 
+1.7.12.1
+
diff --git a/0163-block-curl-Fix-wrong-free-statement.patch b/0163-block-curl-Fix-wrong-free-statement.patch
new file mode 100644
index 0000000..a37ad7f
--- /dev/null
+++ b/0163-block-curl-Fix-wrong-free-statement.patch
@@ -0,0 +1,37 @@
+From a29b7f5390e33d089dcdbf75d6e92c20bbedc562 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Sat, 1 Sep 2012 11:06:45 +0200
+Subject: [PATCH] block/curl: Fix wrong free statement
+
+Report from smatch:
+block/curl.c:546 curl_close(21) info: redundant null check on s->url calling free()
+
+The check was redundant, and free was also wrong because the memory
+was allocated using g_strdup.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+(cherry picked from commit 45724d6d02383b0d7d4a90e05787fca7c55cb070)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ block/curl.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/block/curl.c b/block/curl.c
+index e7c3634..c1074cd 100644
+--- a/block/curl.c
++++ b/block/curl.c
+@@ -542,8 +542,7 @@ static void curl_close(BlockDriverState *bs)
+     }
+     if (s->multi)
+         curl_multi_cleanup(s->multi);
+-    if (s->url)
+-        free(s->url);
++    g_free(s->url);
+ }
+ 
+ static int64_t curl_getlength(BlockDriverState *bs)
+-- 
+1.7.12.1
+
diff --git a/0164-vdi-Fix-warning-from-clang.patch b/0164-vdi-Fix-warning-from-clang.patch
new file mode 100644
index 0000000..c8e751d
--- /dev/null
+++ b/0164-vdi-Fix-warning-from-clang.patch
@@ -0,0 +1,75 @@
+From 928865de80da6a23e6f0d4d86187c52f6c940255 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Fri, 17 Aug 2012 15:23:24 +0200
+Subject: [PATCH] vdi: Fix warning from clang
+
+ccc-analyzer reports these warnings:
+
+block/vdi.c:704:13: warning: Dereference of null pointer
+            bmap[i] = VDI_UNALLOCATED;
+            ^
+block/vdi.c:702:13: warning: Dereference of null pointer
+            bmap[i] = i;
+            ^
+
+Moving some code into the if block fixes this.
+It also avoids calling function write with 0 bytes of data.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+(cherry picked from commit 514f21a5d4613e495adc2e2dd48f18091454efb8)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ block/vdi.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/block/vdi.c b/block/vdi.c
+index c4f1529..550cf58 100644
+--- a/block/vdi.c
++++ b/block/vdi.c
+@@ -628,7 +628,6 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
+     VdiHeader header;
+     size_t i;
+     size_t bmap_size;
+-    uint32_t *bmap;
+ 
+     logout("\n");
+ 
+@@ -693,21 +692,21 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
+         result = -errno;
+     }
+ 
+-    bmap = NULL;
+     if (bmap_size > 0) {
+-        bmap = (uint32_t *)g_malloc0(bmap_size);
+-    }
+-    for (i = 0; i < blocks; i++) {
+-        if (image_type == VDI_TYPE_STATIC) {
+-            bmap[i] = i;
+-        } else {
+-            bmap[i] = VDI_UNALLOCATED;
++        uint32_t *bmap = g_malloc0(bmap_size);
++        for (i = 0; i < blocks; i++) {
++            if (image_type == VDI_TYPE_STATIC) {
++                bmap[i] = i;
++            } else {
++                bmap[i] = VDI_UNALLOCATED;
++            }
+         }
++        if (write(fd, bmap, bmap_size) < 0) {
++            result = -errno;
++        }
++        g_free(bmap);
+     }
+-    if (write(fd, bmap, bmap_size) < 0) {
+-        result = -errno;
+-    }
+-    g_free(bmap);
++
+     if (image_type == VDI_TYPE_STATIC) {
+         if (ftruncate(fd, sizeof(header) + bmap_size + blocks * block_size)) {
+             result = -errno;
+-- 
+1.7.12.1
+
diff --git a/0165-block-fix-block-tray-status.patch b/0165-block-fix-block-tray-status.patch
new file mode 100644
index 0000000..6db09b8
--- /dev/null
+++ b/0165-block-fix-block-tray-status.patch
@@ -0,0 +1,36 @@
+From 8794685f3ebb2d0001ab01bc8692d99242aedb4f Mon Sep 17 00:00:00 2001
+From: Pavel Hrdina <phrdina at redhat.com>
+Date: Thu, 9 Aug 2012 12:44:48 +0200
+Subject: [PATCH] block: fix block tray status
+
+The tray status should change also if you eject empty block device.
+
+Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+(cherry picked from commit 9ca111544c64b5abed2e79cf52e19a8f227b347b)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ block.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/block.c b/block.c
+index 470bdcc..c754353 100644
+--- a/block.c
++++ b/block.c
+@@ -897,10 +897,10 @@ void bdrv_close(BlockDriverState *bs)
+             bdrv_delete(bs->file);
+             bs->file = NULL;
+         }
+-
+-        bdrv_dev_change_media_cb(bs, false);
+     }
+ 
++    bdrv_dev_change_media_cb(bs, false);
++
+     /*throttling disk I/O limits*/
+     if (bs->io_limits_enabled) {
+         bdrv_io_limits_disable(bs);
+-- 
+1.7.12.1
+
diff --git a/0166-ahci-properly-reset-PxCMD-on-HBA-reset.patch b/0166-ahci-properly-reset-PxCMD-on-HBA-reset.patch
new file mode 100644
index 0000000..ad2d6b5
--- /dev/null
+++ b/0166-ahci-properly-reset-PxCMD-on-HBA-reset.patch
@@ -0,0 +1,64 @@
+From 3248d5fbbf9c0fbfd8d42af08aa81fe1e3fe2841 Mon Sep 17 00:00:00 2001
+From: Jason Baron <jbaron at redhat.com>
+Date: Tue, 4 Sep 2012 16:08:08 -0400
+Subject: [PATCH] ahci: properly reset PxCMD on HBA reset
+
+While testing q35, I found that windows 7 (specifically, windows 7 ultimate
+with sp1 x64), wouldn't install because it can't find the cdrom or disk drive.
+The failure message is: 'A required cd/dvd device driver is missing. If you
+have a driver floppy disk, CD, DVD, or USB flash drive, please insert it now.'
+This can also be reproduced on piix by adding an ahci controller, and
+observing that windows 7 does not see any devices behind it.
+
+The problem is that when windows issues a HBA reset, qemu does not reset the
+individual ports' PxCMD register. Windows 7 then reads back the PxCMD register
+and presumably assumes that the ahci controller has already been initialized.
+Windows then never sets up the PxIE register to enable interrupts, and thus it
+never gets irqs back when it sends ata device inquiry commands.
+
+This change brings qemu into ahci 1.3 specification compliance.
+
+Section 10.4.3 HBA Reset:
+
+"
+When GHC.HR is set to '1', GHC.AE, GHC.IE, the IS register, and all port
+register fields (except PxFB/PxFBU/PxCLB/PxCLBU) that are not HwInit in the
+HBA's register memory space are reset.
+"
+
+I've also re-tested Fedora 16 and 17 to verify that they continue to work with
+this change.
+
+Signed-off-by: Jason Baron <jbaron at redhat.com>
+Acked-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+(cherry picked from commit 2a4f4f34e6fe55f4c82507c3e7ec9b58c2e24ad4)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/ide/ahci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
+index 5ea3cad..68671bc 100644
+--- a/hw/ide/ahci.c
++++ b/hw/ide/ahci.c
+@@ -1175,7 +1175,6 @@ void ahci_init(AHCIState *s, DeviceState *qdev, DMAContext *dma, int ports)
+         ad->port_no = i;
+         ad->port.dma = &ad->dma;
+         ad->port.dma->ops = &ahci_dma_ops;
+-        ad->port_regs.cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON;
+     }
+ }
+ 
+@@ -1199,6 +1198,7 @@ void ahci_reset(AHCIState *s)
+         pr->irq_stat = 0;
+         pr->irq_mask = 0;
+         pr->scr_ctl = 0;
++        pr->cmd = PORT_CMD_SPIN_UP | PORT_CMD_POWER_ON;
+         ahci_reset_port(s, i);
+     }
+ }
+-- 
+1.7.12.1
+
diff --git a/0167-Don-t-require-encryption-password-for-qemu-img-info-.patch b/0167-Don-t-require-encryption-password-for-qemu-img-info-.patch
new file mode 100644
index 0000000..6b9d67f
--- /dev/null
+++ b/0167-Don-t-require-encryption-password-for-qemu-img-info-.patch
@@ -0,0 +1,121 @@
+From 4812a358ff2d7442c33a517a6c80d7d3c301ec56 Mon Sep 17 00:00:00 2001
+From: "Daniel P. Berrange" <berrange at redhat.com>
+Date: Mon, 10 Sep 2012 12:11:31 +0100
+Subject: [PATCH] Don't require encryption password for 'qemu-img info'
+ command
+
+The encryption password is only required if I/O is going to be
+performed on a disk image. The 'qemu-img info' command merely
+reports metadata, so it should not ask for a decryption password
+
+Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+(cherry picked from commit f0536bb848ad6eb2709a7dc675f261bd160c751b)
+
+Conflicts:
+
+	qemu-img.c
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ qemu-img.c | 21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/qemu-img.c b/qemu-img.c
+index b41e670..0d208e8 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -221,7 +221,8 @@ static int print_block_option_help(const char *filename, const char *fmt)
+ 
+ static BlockDriverState *bdrv_new_open(const char *filename,
+                                        const char *fmt,
+-                                       int flags)
++                                       int flags,
++                                       bool require_io)
+ {
+     BlockDriverState *bs;
+     BlockDriver *drv;
+@@ -246,7 +247,7 @@ static BlockDriverState *bdrv_new_open(const char *filename,
+         goto fail;
+     }
+ 
+-    if (bdrv_is_encrypted(bs)) {
++    if (bdrv_is_encrypted(bs) && require_io) {
+         printf("Disk image '%s' is encrypted.\n", filename);
+         if (read_password(password, sizeof(password)) < 0) {
+             error_report("No password given");
+@@ -413,7 +414,7 @@ static int img_check(int argc, char **argv)
+     }
+     filename = argv[optind++];
+ 
+-    bs = bdrv_new_open(filename, fmt, flags);
++    bs = bdrv_new_open(filename, fmt, flags, true);
+     if (!bs) {
+         return 1;
+     }
+@@ -520,7 +521,7 @@ static int img_commit(int argc, char **argv)
+         return -1;
+     }
+ 
+-    bs = bdrv_new_open(filename, fmt, flags);
++    bs = bdrv_new_open(filename, fmt, flags, true);
+     if (!bs) {
+         return 1;
+     }
+@@ -762,7 +763,7 @@ static int img_convert(int argc, char **argv)
+ 
+     total_sectors = 0;
+     for (bs_i = 0; bs_i < bs_n; bs_i++) {
+-        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS);
++        bs[bs_i] = bdrv_new_open(argv[optind + bs_i], fmt, BDRV_O_FLAGS, true);
+         if (!bs[bs_i]) {
+             error_report("Could not open '%s'", argv[optind + bs_i]);
+             ret = -1;
+@@ -881,7 +882,7 @@ static int img_convert(int argc, char **argv)
+         return -1;
+     }
+ 
+-    out_bs = bdrv_new_open(out_filename, out_fmt, flags);
++    out_bs = bdrv_new_open(out_filename, out_fmt, flags, true);
+     if (!out_bs) {
+         ret = -1;
+         goto out;
+@@ -1135,7 +1136,7 @@ static int img_info(int argc, char **argv)
+     }
+     filename = argv[optind++];
+ 
+-    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
++    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING, false);
+     if (!bs) {
+         return 1;
+     }
+@@ -1248,7 +1249,7 @@ static int img_snapshot(int argc, char **argv)
+     filename = argv[optind++];
+ 
+     /* Open the image */
+-    bs = bdrv_new_open(filename, NULL, bdrv_oflags);
++    bs = bdrv_new_open(filename, NULL, bdrv_oflags, true);
+     if (!bs) {
+         return 1;
+     }
+@@ -1366,7 +1367,7 @@ static int img_rebase(int argc, char **argv)
+      * Ignore the old backing file for unsafe rebase in case we want to correct
+      * the reference to a renamed or moved backing file.
+      */
+-    bs = bdrv_new_open(filename, fmt, flags);
++    bs = bdrv_new_open(filename, fmt, flags, true);
+     if (!bs) {
+         return 1;
+     }
+@@ -1639,7 +1640,7 @@ static int img_resize(int argc, char **argv)
+     n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
+     qemu_opts_del(param);
+ 
+-    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR);
++    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true);
+     if (!bs) {
+         ret = -1;
+         goto out;
+-- 
+1.7.12.1
+
diff --git a/0168-block-Don-t-forget-to-delete-temporary-file.patch b/0168-block-Don-t-forget-to-delete-temporary-file.patch
new file mode 100644
index 0000000..90d07b9
--- /dev/null
+++ b/0168-block-Don-t-forget-to-delete-temporary-file.patch
@@ -0,0 +1,36 @@
+From 3306981d5631182fb1384b05d66be26918521511 Mon Sep 17 00:00:00 2001
+From: Dunrong Huang <riegamaths at gmail.com>
+Date: Wed, 5 Sep 2012 21:26:22 +0800
+Subject: [PATCH] block: Don't forget to delete temporary file
+
+The caller would not delete temporary file after failed get_tmp_filename().
+
+Signed-off-by: Dunrong Huang <riegamaths at gmail.com>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+(cherry picked from commit fe235a06e1e008dedd2ac3cc0a3a655169ce9b33)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ block.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/block.c b/block.c
+index c754353..e78039b 100644
+--- a/block.c
++++ b/block.c
+@@ -433,7 +433,11 @@ int get_tmp_filename(char *filename, int size)
+         return -EOVERFLOW;
+     }
+     fd = mkstemp(filename);
+-    if (fd < 0 || close(fd)) {
++    if (fd < 0) {
++        return -errno;
++    }
++    if (close(fd) != 0) {
++        unlink(filename);
+         return -errno;
+     }
+     return 0;
+-- 
+1.7.12.1
+
diff --git a/0222-hw-qxl-tracing-fixes.patch b/0169-hw-qxl-tracing-fixes.patch
similarity index 85%
rename from 0222-hw-qxl-tracing-fixes.patch
rename to 0169-hw-qxl-tracing-fixes.patch
index 2feba9d..74c400f 100644
--- a/0222-hw-qxl-tracing-fixes.patch
+++ b/0169-hw-qxl-tracing-fixes.patch
@@ -1,7 +1,7 @@
-From b1b9a04abd4cc461e507091fadea866788d4a60a Mon Sep 17 00:00:00 2001
+From e4a803d8ebd69719f4d997052e5bc3a5a7d91124 Mon Sep 17 00:00:00 2001
 From: Alon Levy <alevy at redhat.com>
 Date: Wed, 12 Sep 2012 16:13:26 +0300
-Subject: [PATCH 222/293] hw/qxl: tracing fixes
+Subject: [PATCH] hw/qxl: tracing fixes
 
 Add two new trace events:
 qxl_send_events(int qid, uint32_t events) "%d %d"
@@ -14,13 +14,16 @@ Change d to qxl in one place.
 
 Signed-off-by: Alon Levy <alevy at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 917ae08ca1565aab2d10c8b6269cd905d6c5c05b)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/qxl.c     | 8 +++++---
  trace-events | 6 ++++--
  2 files changed, 9 insertions(+), 5 deletions(-)
 
 diff --git a/hw/qxl.c b/hw/qxl.c
-index 9f06f5e..360f4f6 100644
+index 67f7100..59bf822 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
 @@ -141,6 +141,7 @@ static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
@@ -31,7 +34,7 @@ index 9f06f5e..360f4f6 100644
      qxl_send_events(qxl, QXL_INTERRUPT_ERROR);
      qxl->guest_bug = 1;
      if (qxl->guestdebug) {
-@@ -1408,7 +1409,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
+@@ -1381,7 +1382,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
              break;
          }
          trace_qxl_io_unexpected_vga_mode(d->id,
@@ -40,7 +43,7 @@ index 9f06f5e..360f4f6 100644
          /* be nice to buggy guest drivers */
          if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&
              io_port < QXL_IO_RANGE_SIZE) {
-@@ -1607,9 +1608,9 @@ cancel_async:
+@@ -1580,9 +1581,9 @@ cancel_async:
  static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
                              unsigned size)
  {
@@ -52,7 +55,7 @@ index 9f06f5e..360f4f6 100644
      return 0xff;
  }
  
-@@ -1639,6 +1640,7 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
+@@ -1612,6 +1613,7 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
      uint32_t old_pending;
      uint32_t le_events = cpu_to_le32(events);
  
@@ -61,10 +64,10 @@ index 9f06f5e..360f4f6 100644
      old_pending = __sync_fetch_and_or(&d->ram->int_pending, le_events);
      if ((old_pending & le_events) == le_events) {
 diff --git a/trace-events b/trace-events
-index 8fcbc50..42dfb93 100644
+index cf05414..aa79836 100644
 --- a/trace-events
 +++ b/trace-events
-@@ -925,7 +925,7 @@ qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d"
+@@ -931,7 +931,7 @@ qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d"
  qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d"
  qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s"
  qxl_io_read_unexpected(int qid) "%d"
@@ -73,7 +76,7 @@ index 8fcbc50..42dfb93 100644
  qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d"
  qxl_memslot_add_guest(int qid, uint32_t slot_id, uint64_t guest_start, uint64_t guest_end) "%d %u: guest phys 0x%"PRIx64 " - 0x%" PRIx64
  qxl_post_load(int qid, const char *mode) "%d %s"
-@@ -956,7 +956,7 @@ qxl_spice_destroy_surfaces(int qid, int async) "%d async=%d"
+@@ -962,7 +962,7 @@ qxl_spice_destroy_surfaces(int qid, int async) "%d async=%d"
  qxl_spice_destroy_surface_wait_complete(int qid, uint32_t id) "%d sid=%d"
  qxl_spice_destroy_surface_wait(int qid, uint32_t id, int async) "%d sid=%d async=%d"
  qxl_spice_flush_surfaces_async(int qid, uint32_t surface_count, uint32_t num_free_res) "%d s#=%d, res#=%d"
@@ -82,7 +85,7 @@ index 8fcbc50..42dfb93 100644
  qxl_spice_loadvm_commands(int qid, void *ext, uint32_t count) "%d ext=%p count=%d"
  qxl_spice_oom(int qid) "%d"
  qxl_spice_reset_cursor(int qid) "%d"
-@@ -965,6 +965,8 @@ qxl_spice_reset_memslots(int qid) "%d"
+@@ -971,6 +971,8 @@ qxl_spice_reset_memslots(int qid) "%d"
  qxl_spice_update_area(int qid, uint32_t surface_id, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) "%d sid=%d [%d,%d,%d,%d]"
  qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dirty_region) "%d #d=%d clear=%d"
  qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
@@ -92,5 +95,5 @@ index 8fcbc50..42dfb93 100644
  # hw/qxl-render.c
  qxl_render_blit_guest_primary_initialized(void) ""
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0359-configure-usbredir-fixes.patch b/0170-configure-usbredir-fixes.patch
similarity index 71%
rename from 0359-configure-usbredir-fixes.patch
rename to 0170-configure-usbredir-fixes.patch
index ff0454b..cf87afa 100644
--- a/0359-configure-usbredir-fixes.patch
+++ b/0170-configure-usbredir-fixes.patch
@@ -1,7 +1,7 @@
-From 31bb27a1393168657cb53deff12d4b58601e4d72 Mon Sep 17 00:00:00 2001
+From 00d9118be03020d3a905bd0a61f74eccd76edee9 Mon Sep 17 00:00:00 2001
 From: Aurelien Jarno <aurelien at aurel32.net>
-Date: Tue, 11 Sep 2012 18:57:58 +0000
-Subject: [PATCH 359/369] configure: usbredir fixes
+Date: Tue, 11 Sep 2012 20:57:58 +0200
+Subject: [PATCH] configure: usbredir fixes
 
 usbredir is only used by system emulation, so add the libraries to
 libs_softmmu instead of LIBS.
@@ -11,15 +11,18 @@ Cc: Gerd Hoffmann <kraxel at redhat.com>
 Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 56ab2ad177dc43d474dc0a0bd84e81ef00f31e11)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  configure | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/configure b/configure
-index 25c406f..d63530a 100755
+index a8061c1..dcd8e7b 100755
 --- a/configure
 +++ b/configure
-@@ -2770,7 +2770,7 @@ if test "$usb_redir" != "no" ; then
+@@ -2737,7 +2737,7 @@ if test "$usb_redir" != "no" ; then
          usb_redir_cflags=$($pkg_config --cflags libusbredirparser 2>/dev/null)
          usb_redir_libs=$($pkg_config --libs libusbredirparser 2>/dev/null)
          QEMU_CFLAGS="$QEMU_CFLAGS $usb_redir_cflags"
@@ -29,5 +32,5 @@ index 25c406f..d63530a 100755
          if test "$usb_redir" = "yes"; then
              feature_not_found "usb-redir"
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0360-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch b/0171-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch
similarity index 81%
rename from 0360-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch
rename to 0171-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch
index f40d17b..de9f4ac 100644
--- a/0360-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch
+++ b/0171-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch
@@ -1,8 +1,7 @@
-From 833eeda8129b2cf4955a34600b60c01e00652526 Mon Sep 17 00:00:00 2001
+From ade9c6dfbbf573c22800d7ff6df7f0de933e7c96 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
-Date: Wed, 5 Sep 2012 12:13:41 +0200
-Subject: [PATCH 358/366] ehci: Don't set seen to 0 when removing unseen
- queue-heads
+Date: Wed, 12 Sep 2012 15:08:32 +0200
+Subject: [PATCH] ehci: Don't set seen to 0 when removing unseen queue-heads
 
 When removing unseen queue-heads from the async queue list, we should not
 set the seen flag to 0, as this may cause them to be removed by
@@ -21,15 +20,19 @@ Note:
    "ehci: Walk async schedule before and after migration"
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 8f5457eb04140714eaf57a99bc08dc661d83fa87)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 24 ++++++++++++++++++------
  1 file changed, 18 insertions(+), 6 deletions(-)
 
 diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
-index f5ba8e1..6f48132 100644
+index 017a01d..bc86460 100644
 --- a/hw/usb/hcd-ehci.c
 +++ b/hw/usb/hcd-ehci.c
-@@ -847,10 +847,10 @@ static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr,
+@@ -848,10 +848,10 @@ static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr,
      return NULL;
  }
  
@@ -42,7 +45,7 @@ index f5ba8e1..6f48132 100644
      uint64_t maxage = FRAME_TIMER_NS * ehci->maxframes * 4;
      EHCIQueue *q, *tmp;
  
-@@ -860,13 +860,25 @@ static void ehci_queues_rip_unused(EHCIState *ehci, int async, int flush)
+@@ -861,13 +861,25 @@ static void ehci_queues_rip_unused(EHCIState *ehci, int async, int flush)
              q->ts = ehci->last_run_ns;
              continue;
          }
@@ -69,7 +72,7 @@ index f5ba8e1..6f48132 100644
  static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev, int async)
  {
      EHCIQueueHead *head = async ? &ehci->aqueues : &ehci->pqueues;
-@@ -1699,7 +1711,7 @@ static int ehci_state_waitlisthead(EHCIState *ehci,  int async)
+@@ -1700,7 +1712,7 @@ static int ehci_state_waitlisthead(EHCIState *ehci,  int async)
          ehci_set_usbsts(ehci, USBSTS_REC);
      }
  
@@ -78,7 +81,7 @@ index f5ba8e1..6f48132 100644
  
      /*  Find the head of the list (4.9.1.1) */
      for(i = 0; i < MAX_QH; i++) {
-@@ -2331,7 +2343,7 @@ static void ehci_advance_async_state(EHCIState *ehci)
+@@ -2332,7 +2344,7 @@ static void ehci_advance_async_state(EHCIState *ehci)
           */
          if (ehci->usbcmd & USBCMD_IAAD) {
              /* Remove all unseen qhs from the async qhs queue */
@@ -87,7 +90,7 @@ index f5ba8e1..6f48132 100644
              trace_usb_ehci_doorbell_ack();
              ehci->usbcmd &= ~USBCMD_IAAD;
              ehci_raise_irq(ehci, USBSTS_IAA);
-@@ -2384,7 +2396,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
+@@ -2385,7 +2397,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci)
          ehci_set_fetch_addr(ehci, async,entry);
          ehci_set_state(ehci, async, EST_FETCHENTRY);
          ehci_advance_state(ehci, async);
@@ -97,5 +100,5 @@ index f5ba8e1..6f48132 100644
  
      default:
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0361-ehci-Walk-async-schedule-before-and-after-migration.patch b/0172-ehci-Walk-async-schedule-before-and-after-migration.patch
similarity index 77%
rename from 0361-ehci-Walk-async-schedule-before-and-after-migration.patch
rename to 0172-ehci-Walk-async-schedule-before-and-after-migration.patch
index 3c2bf54..476e41e 100644
--- a/0361-ehci-Walk-async-schedule-before-and-after-migration.patch
+++ b/0172-ehci-Walk-async-schedule-before-and-after-migration.patch
@@ -1,15 +1,19 @@
-From fec70ddafe1632f40608ef6917760a7f946f278a Mon Sep 17 00:00:00 2001
+From 6b145e32e9e219c723b4911aac0a96ea2aa70e77 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
-Date: Wed, 5 Sep 2012 12:07:10 +0200
-Subject: [PATCH 359/366] ehci: Walk async schedule before and after migration
+Date: Wed, 12 Sep 2012 15:08:33 +0200
+Subject: [PATCH] ehci: Walk async schedule before and after migration
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit ceab6f96454fe6589d1b09ce64403c041d79f9d9)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-ehci.c | 28 ++++++++++++++++++++++++++++
  1 file changed, 28 insertions(+)
 
 diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
-index 6f48132..30d2b56 100644
+index bc86460..6a5da84 100644
 --- a/hw/usb/hcd-ehci.c
 +++ b/hw/usb/hcd-ehci.c
 @@ -34,6 +34,7 @@
@@ -20,7 +24,7 @@ index 6f48132..30d2b56 100644
  
  #define EHCI_DEBUG   0
  
-@@ -2558,6 +2559,32 @@ static int usb_ehci_post_load(void *opaque, int version_id)
+@@ -2572,6 +2573,32 @@ static int usb_ehci_post_load(void *opaque, int version_id)
      return 0;
  }
  
@@ -53,7 +57,7 @@ index 6f48132..30d2b56 100644
  static const VMStateDescription vmstate_ehci = {
      .name        = "ehci",
      .version_id  = 2,
-@@ -2707,6 +2734,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
+@@ -2721,6 +2748,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
      usb_packet_init(&s->ipacket);
  
      qemu_register_reset(ehci_reset, s);
@@ -62,5 +66,5 @@ index 6f48132..30d2b56 100644
      memory_region_init(&s->mem, "ehci", MMIO_SIZE);
      memory_region_init_io(&s->mem_caps, &ehci_mmio_caps_ops, s,
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0367-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch b/0173-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch
similarity index 58%
rename from 0367-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch
rename to 0173-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch
index 8a1b518..11125f2 100644
--- a/0367-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch
+++ b/0173-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch
@@ -1,7 +1,7 @@
-From 786657ed32cb68ae5cd4d099e6ea3f36290bcbcb Mon Sep 17 00:00:00 2001
+From 9f6674cd9bf6e0e3bafa8b8ec8388576756a6d13 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
-Date: Mon, 10 Sep 2012 13:49:46 +0200
-Subject: [PATCH 367/369] usb-redir: Revert usb-redir part of commit 93bfef4c
+Date: Wed, 12 Sep 2012 15:08:39 +0200
+Subject: [PATCH] usb-redir: Revert usb-redir part of commit 93bfef4c
 
 Commit 93bfef4c6e4b23caea9d51e1099d06433d8835a4 makes qemu-devices
 which report the qemu version string to the guest in some way use a
@@ -14,15 +14,23 @@ unused! For debugging purposes it is important to have the real qemu version
 in there, rather then the machine-specific version.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 35efba2cc6812dc980c336d7b9bf81dbfb5daf00)
+
+Conflicts:
+
+	hw/usb/redirect.c
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
- hw/usb/redirect.c | 8 +++-----
- 1 file changed, 3 insertions(+), 5 deletions(-)
+ hw/usb/redirect.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 86c0398..78e93a7 100644
+index ee75217..ab8d79a 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
-@@ -142,6 +142,8 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
+@@ -134,6 +134,8 @@ static void usbredir_interrupt_packet(void *priv, uint32_t id,
  static int usbredir_handle_status(USBRedirDevice *dev,
                                         int status, int actual_len);
  
@@ -31,17 +39,9 @@ index 86c0398..78e93a7 100644
  /*
   * Logging stuff
   */
-@@ -873,7 +875,6 @@ static void usbredir_chardev_close_bh(void *opaque)
- static void usbredir_chardev_open(USBRedirDevice *dev)
- {
-     uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
--    char version[32];
-     int flags = 0;
- 
-     /* Make sure any pending closes are handled (no-op if none pending) */
-@@ -882,9 +883,6 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
- 
-     DPRINTF("creating usbredirparser\n");
+@@ -777,9 +779,6 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+     usbredir_chardev_close_bh(dev);
+     qemu_bh_cancel(dev->chardev_close_bh);
  
 -    strcpy(version, "qemu usb-redir guest ");
 -    pstrcat(version, sizeof(version), qemu_get_version());
@@ -49,15 +49,15 @@ index 86c0398..78e93a7 100644
      dev->parser = qemu_oom_check(usbredirparser_create());
      dev->parser->priv = dev;
      dev->parser->log_func = usbredir_log;
-@@ -916,7 +914,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
-     if (runstate_check(RUN_STATE_INMIGRATE)) {
-         flags |= usbredirparser_fl_no_hello;
-     }
--    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE,
-+    usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE,
-                         flags);
+@@ -805,7 +804,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+ 
+     usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
+     usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
+-    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
++    usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0);
      usbredirparser_do_write(dev->parser);
  }
+ 
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0368-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch b/0174-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch
similarity index 77%
rename from 0368-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch
rename to 0174-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch
index af350d9..a135563 100644
--- a/0368-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch
+++ b/0174-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch
@@ -1,8 +1,7 @@
-From 41f5d67c0649d74b505edc2a874c91148355eb25 Mon Sep 17 00:00:00 2001
+From 48dbbecb0b010ff1c6a64a3a18a7272cce314bf8 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
-Date: Wed, 12 Sep 2012 13:30:51 +0200
-Subject: [PATCH 368/369] uhci: Don't queue up packets after one with the SPD
- flag set
+Date: Wed, 12 Sep 2012 15:08:40 +0200
+Subject: [PATCH] uhci: Don't queue up packets after one with the SPD flag set
 
 Don't queue up packets after a packet with the SPD (short packet detect)
 flag set. Since we won't know if the packet will actually be short until it
@@ -12,6 +11,10 @@ This fixes a miniature photoframe emulating a USB cdrom with the windows
 software for it not working.
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+(cherry picked from commit 72a04d0c178f01908d74539230d9de64ffc6da19)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
 ---
  hw/usb/hcd-uhci.c | 5 ++++-
  1 file changed, 4 insertions(+), 1 deletion(-)
@@ -40,5 +43,5 @@ index c7c8786..cdc8bc3 100644
              }
              link = curr_qh ? qh.link : td.link;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0175-slirp-Remove-wrong-type-casts-ins-debug-statements.patch b/0175-slirp-Remove-wrong-type-casts-ins-debug-statements.patch
new file mode 100644
index 0000000..365d586
--- /dev/null
+++ b/0175-slirp-Remove-wrong-type-casts-ins-debug-statements.patch
@@ -0,0 +1,37 @@
+From 3196332dd2ca39a9b06562856b80b825217e3c96 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Tue, 4 Sep 2012 23:20:35 +0200
+Subject: [PATCH] slirp: Remove wrong type casts ins debug statements
+
+The type casts of pointers to long are not allowed
+when sizeof(pointer) != sizeof(long).
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
+(cherry picked from commit c4d12a743c73a5b88a8705ca68ff620ce0f8bba7)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ slirp/tcp_subr.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
+index 025b374..5890d7a 100644
+--- a/slirp/tcp_subr.c
++++ b/slirp/tcp_subr.c
+@@ -114,9 +114,9 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
+ 	int win = 0;
+ 
+ 	DEBUG_CALL("tcp_respond");
+-	DEBUG_ARG("tp = %lx", (long)tp);
+-	DEBUG_ARG("ti = %lx", (long)ti);
+-	DEBUG_ARG("m = %lx", (long)m);
++	DEBUG_ARG("tp = %p", tp);
++	DEBUG_ARG("ti = %p", ti);
++	DEBUG_ARG("m = %p", m);
+ 	DEBUG_ARG("ack = %u", ack);
+ 	DEBUG_ARG("seq = %u", seq);
+ 	DEBUG_ARG("flags = %x", flags);
+-- 
+1.7.12.1
+
diff --git a/0176-slirp-Fix-error-reported-by-static-code-analysis.patch b/0176-slirp-Fix-error-reported-by-static-code-analysis.patch
new file mode 100644
index 0000000..7f2a90a
--- /dev/null
+++ b/0176-slirp-Fix-error-reported-by-static-code-analysis.patch
@@ -0,0 +1,37 @@
+From b88c1cb2b263de9ffc3dcaa2822ef7b1fbd8575a Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Tue, 4 Sep 2012 23:20:36 +0200
+Subject: [PATCH] slirp: Fix error reported by static code analysis
+
+Report from smatch:
+
+slirp/tcp_subr.c:127 tcp_respond(17) error:
+ we previously assumed 'tp' could be null (see line 124)
+
+Return if 'tp' is NULL.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
+(cherry picked from commit e56afbc54a2132c56931f44bae1992c28119944f)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ slirp/tcp_subr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
+index 5890d7a..1542e43 100644
+--- a/slirp/tcp_subr.c
++++ b/slirp/tcp_subr.c
+@@ -124,7 +124,7 @@ tcp_respond(struct tcpcb *tp, struct tcpiphdr *ti, struct mbuf *m,
+ 	if (tp)
+ 		win = sbspace(&tp->t_socket->so_rcv);
+         if (m == NULL) {
+-		if ((m = m_get(tp->t_socket->slirp)) == NULL)
++		if (!tp || (m = m_get(tp->t_socket->slirp)) == NULL)
+ 			return;
+ 		tlen = 0;
+ 		m->m_data += IF_MAXLINKHDR;
+-- 
+1.7.12.1
+
diff --git a/0177-slirp-improve-TFTP-performance.patch b/0177-slirp-improve-TFTP-performance.patch
new file mode 100644
index 0000000..65dce5d
--- /dev/null
+++ b/0177-slirp-improve-TFTP-performance.patch
@@ -0,0 +1,106 @@
+From c1b408d0c9d836e0a95d1e0695c0c6c605ceb368 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
+Date: Mon, 10 Sep 2012 20:52:25 +0200
+Subject: [PATCH] slirp: improve TFTP performance
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When transferring a file, keep it open during the whole transfer,
+instead of opening/closing it for each block.
+
+Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
+Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
+Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
+(cherry picked from commit 78be056628c76ff73eedeade86fde44b97343c79)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ slirp/tftp.c | 32 ++++++++++++++++++--------------
+ slirp/tftp.h |  1 +
+ 2 files changed, 19 insertions(+), 14 deletions(-)
+
+diff --git a/slirp/tftp.c b/slirp/tftp.c
+index b78765f..520dbd6 100644
+--- a/slirp/tftp.c
++++ b/slirp/tftp.c
+@@ -37,6 +37,10 @@ static inline void tftp_session_update(struct tftp_session *spt)
+ 
+ static void tftp_session_terminate(struct tftp_session *spt)
+ {
++    if (spt->fd >= 0) {
++        close(spt->fd);
++        spt->fd = -1;
++    }
+     g_free(spt->filename);
+     spt->slirp = NULL;
+ }
+@@ -54,7 +58,7 @@ static int tftp_session_allocate(Slirp *slirp, struct tftp_t *tp)
+ 
+     /* sessions time out after 5 inactive seconds */
+     if ((int)(curtime - spt->timestamp) > 5000) {
+-        g_free(spt->filename);
++        tftp_session_terminate(spt);
+         goto found;
+     }
+   }
+@@ -64,6 +68,7 @@ static int tftp_session_allocate(Slirp *slirp, struct tftp_t *tp)
+  found:
+   memset(spt, 0, sizeof(*spt));
+   memcpy(&spt->client_ip, &tp->ip.ip_src, sizeof(spt->client_ip));
++  spt->fd = -1;
+   spt->client_port = tp->udp.uh_sport;
+   spt->slirp = slirp;
+ 
+@@ -95,24 +100,23 @@ static int tftp_session_find(Slirp *slirp, struct tftp_t *tp)
+ static int tftp_read_data(struct tftp_session *spt, uint16_t block_nr,
+                           uint8_t *buf, int len)
+ {
+-  int fd;
+-  int bytes_read = 0;
+-
+-  fd = open(spt->filename, O_RDONLY | O_BINARY);
++    int bytes_read = 0;
+ 
+-  if (fd < 0) {
+-    return -1;
+-  }
++    if (spt->fd < 0) {
++        spt->fd = open(spt->filename, O_RDONLY | O_BINARY);
++    }
+ 
+-  if (len) {
+-    lseek(fd, block_nr * 512, SEEK_SET);
++    if (spt->fd < 0) {
++        return -1;
++    }
+ 
+-    bytes_read = read(fd, buf, len);
+-  }
++    if (len) {
++        lseek(spt->fd, block_nr * 512, SEEK_SET);
+ 
+-  close(fd);
++        bytes_read = read(spt->fd, buf, len);
++    }
+ 
+-  return bytes_read;
++    return bytes_read;
+ }
+ 
+ static int tftp_send_oack(struct tftp_session *spt,
+diff --git a/slirp/tftp.h b/slirp/tftp.h
+index 72e5e91..9c364ea 100644
+--- a/slirp/tftp.h
++++ b/slirp/tftp.h
+@@ -33,6 +33,7 @@ struct tftp_t {
+ struct tftp_session {
+     Slirp *slirp;
+     char *filename;
++    int fd;
+ 
+     struct in_addr client_ip;
+     uint16_t client_port;
+-- 
+1.7.12.1
+
diff --git a/0178-slirp-Handle-more-than-65535-blocks-in-TFTP-transfer.patch b/0178-slirp-Handle-more-than-65535-blocks-in-TFTP-transfer.patch
new file mode 100644
index 0000000..0a87572
--- /dev/null
+++ b/0178-slirp-Handle-more-than-65535-blocks-in-TFTP-transfer.patch
@@ -0,0 +1,121 @@
+From 5579c7740b29be4766ace824af36acb9ab254ecb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
+Date: Thu, 13 Sep 2012 12:39:36 +0200
+Subject: [PATCH] slirp: Handle more than 65535 blocks in TFTP transfers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+RFC 1350 does not mention block count roll-over. However, a lot of TFTP servers
+implement it to be able to transmit big files, so do it also.
+
+Current block size is 512 bytes, so TFTP files were limited to 32 MB.
+
+Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
+Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
+(cherry picked from commit 4aa401f39e048e71020cceb59f126ab941095a42)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ slirp/tftp.c | 24 ++++++++++--------------
+ slirp/tftp.h |  1 +
+ 2 files changed, 11 insertions(+), 14 deletions(-)
+
+diff --git a/slirp/tftp.c b/slirp/tftp.c
+index 520dbd6..c6a5df2 100644
+--- a/slirp/tftp.c
++++ b/slirp/tftp.c
+@@ -97,7 +97,7 @@ static int tftp_session_find(Slirp *slirp, struct tftp_t *tp)
+   return -1;
+ }
+ 
+-static int tftp_read_data(struct tftp_session *spt, uint16_t block_nr,
++static int tftp_read_data(struct tftp_session *spt, uint32_t block_nr,
+                           uint8_t *buf, int len)
+ {
+     int bytes_read = 0;
+@@ -197,19 +197,14 @@ out:
+   tftp_session_terminate(spt);
+ }
+ 
+-static int tftp_send_data(struct tftp_session *spt,
+-                          uint16_t block_nr,
+-			  struct tftp_t *recv_tp)
++static int tftp_send_next_block(struct tftp_session *spt,
++                                struct tftp_t *recv_tp)
+ {
+   struct sockaddr_in saddr, daddr;
+   struct mbuf *m;
+   struct tftp_t *tp;
+   int nobytes;
+ 
+-  if (block_nr < 1) {
+-    return -1;
+-  }
+-
+   m = m_get(spt->slirp);
+ 
+   if (!m) {
+@@ -223,7 +218,7 @@ static int tftp_send_data(struct tftp_session *spt,
+   m->m_data += sizeof(struct udpiphdr);
+ 
+   tp->tp_op = htons(TFTP_DATA);
+-  tp->x.tp_data.tp_block_nr = htons(block_nr);
++  tp->x.tp_data.tp_block_nr = htons((spt->block_nr + 1) & 0xffff);
+ 
+   saddr.sin_addr = recv_tp->ip.ip_dst;
+   saddr.sin_port = recv_tp->udp.uh_dport;
+@@ -231,7 +226,7 @@ static int tftp_send_data(struct tftp_session *spt,
+   daddr.sin_addr = spt->client_ip;
+   daddr.sin_port = spt->client_port;
+ 
+-  nobytes = tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 512);
++  nobytes = tftp_read_data(spt, spt->block_nr, tp->x.tp_data.tp_buf, 512);
+ 
+   if (nobytes < 0) {
+     m_free(m);
+@@ -255,6 +250,7 @@ static int tftp_send_data(struct tftp_session *spt,
+     tftp_session_terminate(spt);
+   }
+ 
++  spt->block_nr++;
+   return 0;
+ }
+ 
+@@ -373,7 +369,8 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
+       }
+   }
+ 
+-  tftp_send_data(spt, 1, tp);
++  spt->block_nr = 0;
++  tftp_send_next_block(spt, tp);
+ }
+ 
+ static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen)
+@@ -386,9 +383,8 @@ static void tftp_handle_ack(Slirp *slirp, struct tftp_t *tp, int pktlen)
+     return;
+   }
+ 
+-  if (tftp_send_data(&slirp->tftp_sessions[s],
+-		     ntohs(tp->x.tp_data.tp_block_nr) + 1,
+-		     tp) < 0) {
++  if (tftp_send_next_block(&slirp->tftp_sessions[s],
++                           tp) < 0) {
+     return;
+   }
+ }
+diff --git a/slirp/tftp.h b/slirp/tftp.h
+index 9c364ea..51704e4 100644
+--- a/slirp/tftp.h
++++ b/slirp/tftp.h
+@@ -37,6 +37,7 @@ struct tftp_session {
+ 
+     struct in_addr client_ip;
+     uint16_t client_port;
++    uint32_t block_nr;
+ 
+     int timestamp;
+ };
+-- 
+1.7.12.1
+
diff --git a/0179-slirp-Implement-TFTP-Blocksize-option.patch b/0179-slirp-Implement-TFTP-Blocksize-option.patch
new file mode 100644
index 0000000..38ebba3
--- /dev/null
+++ b/0179-slirp-Implement-TFTP-Blocksize-option.patch
@@ -0,0 +1,123 @@
+From e070dc7276c7958c322ca0fbf5ac10e639502b4d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= <hpoussin at reactos.org>
+Date: Thu, 13 Sep 2012 07:55:01 +0200
+Subject: [PATCH] slirp: Implement TFTP Blocksize option
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This option is described in RFC 1783. As this is only an optional field,
+we may ignore it in some situations and handle it in some others.
+
+However, MS Windows 2003 PXE boot client requests a block size of the MTU
+(most of the times 1472 bytes), and doesn't work if the option is not
+acknowledged (with whatever value).
+
+According to the RFC 1783, we cannot acknowledge the option with a bigger
+value than the requested one.
+
+As current implementation is using 512 bytes by block, accept the option
+with a value of 512 if the option was specified, and don't acknowledge it
+if it is not present or less than 512 bytes.
+
+Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
+Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
+(cherry picked from commit 95b1ad7ad86793c27ab8e9987be69571937900d1)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ slirp/tftp.c | 42 +++++++++++++++++++++++++++++++++---------
+ 1 file changed, 33 insertions(+), 9 deletions(-)
+
+diff --git a/slirp/tftp.c b/slirp/tftp.c
+index c6a5df2..37b0387 100644
+--- a/slirp/tftp.c
++++ b/slirp/tftp.c
+@@ -120,13 +120,13 @@ static int tftp_read_data(struct tftp_session *spt, uint32_t block_nr,
+ }
+ 
+ static int tftp_send_oack(struct tftp_session *spt,
+-                          const char *key, uint32_t value,
++                          const char *keys[], uint32_t values[], int nb,
+                           struct tftp_t *recv_tp)
+ {
+     struct sockaddr_in saddr, daddr;
+     struct mbuf *m;
+     struct tftp_t *tp;
+-    int n = 0;
++    int i, n = 0;
+ 
+     m = m_get(spt->slirp);
+ 
+@@ -140,10 +140,12 @@ static int tftp_send_oack(struct tftp_session *spt,
+     m->m_data += sizeof(struct udpiphdr);
+ 
+     tp->tp_op = htons(TFTP_OACK);
+-    n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s",
+-                  key) + 1;
+-    n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u",
+-                  value) + 1;
++    for (i = 0; i < nb; i++) {
++        n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%s",
++                      keys[i]) + 1;
++        n += snprintf(tp->x.tp_buf + n, sizeof(tp->x.tp_buf) - n, "%u",
++                      values[i]) + 1;
++    }
+ 
+     saddr.sin_addr = recv_tp->ip.ip_dst;
+     saddr.sin_port = recv_tp->udp.uh_dport;
+@@ -260,6 +262,9 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
+   int s, k;
+   size_t prefix_len;
+   char *req_fname;
++  const char *option_name[2];
++  uint32_t option_value[2];
++  int nb_options = 0;
+ 
+   /* check if a session already exists and if so terminate it */
+   s = tftp_session_find(slirp, tp);
+@@ -337,7 +342,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
+       return;
+   }
+ 
+-  while (k < pktlen) {
++  while (k < pktlen && nb_options < ARRAY_SIZE(option_name)) {
+       const char *key, *value;
+ 
+       key = &tp->x.tp_buf[k];
+@@ -364,11 +369,30 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
+ 	      }
+ 	  }
+ 
+-	  tftp_send_oack(spt, "tsize", tsize, tp);
+-	  return;
++          option_name[nb_options] = "tsize";
++          option_value[nb_options] = tsize;
++          nb_options++;
++      } else if (strcasecmp(key, "blksize") == 0) {
++          int blksize = atoi(value);
++
++          /* If blksize option is bigger than what we will
++           * emit, accept the option with our packet size.
++           * Otherwise, simply do as we didn't see the option.
++           */
++          if (blksize >= 512) {
++              option_name[nb_options] = "blksize";
++              option_value[nb_options] = 512;
++              nb_options++;
++          }
+       }
+   }
+ 
++  if (nb_options > 0) {
++      assert(nb_options <= ARRAY_SIZE(option_name));
++      tftp_send_oack(spt, option_name, option_value, nb_options, tp);
++      return;
++  }
++
+   spt->block_nr = 0;
+   tftp_send_next_block(spt, tp);
+ }
+-- 
+1.7.12.1
+
diff --git a/0180-srp-Don-t-use-QEMU_PACKED-for-single-elements-of-a-s.patch b/0180-srp-Don-t-use-QEMU_PACKED-for-single-elements-of-a-s.patch
new file mode 100644
index 0000000..00cb718
--- /dev/null
+++ b/0180-srp-Don-t-use-QEMU_PACKED-for-single-elements-of-a-s.patch
@@ -0,0 +1,63 @@
+From 66cbaa761bc0f6d528957f9e3bc5762acb7f5f1c Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Fri, 10 Aug 2012 22:03:27 +0200
+Subject: [PATCH] srp: Don't use QEMU_PACKED for single elements of a
+ structured type
+
+QEMU_PACKED results in a MinGW compiler warning when it is
+used for single structure elements:
+
+warning: 'gcc_struct' attribute ignored
+
+Using QEMU_PACKED for the whole structure avoids the compiler warning
+without changing the memory layout.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit 93d3ad2a8048469d2b2bb157697425b66b2a37aa)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/srp.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/hw/srp.h b/hw/srp.h
+index 3009bd5..5e0cad5 100644
+--- a/hw/srp.h
++++ b/hw/srp.h
+@@ -177,13 +177,13 @@ struct srp_tsk_mgmt {
+     uint8_t    reserved1[6];
+     uint64_t   tag;
+     uint8_t    reserved2[4];
+-    uint64_t   lun QEMU_PACKED;
++    uint64_t   lun;
+     uint8_t    reserved3[2];
+     uint8_t    tsk_mgmt_func;
+     uint8_t    reserved4;
+     uint64_t   task_tag;
+     uint8_t    reserved5[8];
+-};
++} QEMU_PACKED;
+ 
+ /*
+  * We need the packed attribute because the SRP spec only aligns the
+@@ -198,14 +198,14 @@ struct srp_cmd {
+     uint8_t    data_in_desc_cnt;
+     uint64_t   tag;
+     uint8_t    reserved2[4];
+-    uint64_t   lun QEMU_PACKED;
++    uint64_t   lun;
+     uint8_t    reserved3;
+     uint8_t    task_attr;
+     uint8_t    reserved4;
+     uint8_t    add_cdb_len;
+     uint8_t    cdb[16];
+     uint8_t    add_data[0];
+-};
++} QEMU_PACKED;
+ 
+ enum {
+     SRP_RSP_FLAG_RSPVALID = 1 << 0,
+-- 
+1.7.12.1
+
diff --git a/0181-Spelling-fixes-in-comments-and-documentation.patch b/0181-Spelling-fixes-in-comments-and-documentation.patch
new file mode 100644
index 0000000..5b696ed
--- /dev/null
+++ b/0181-Spelling-fixes-in-comments-and-documentation.patch
@@ -0,0 +1,183 @@
+From ca94ceccca88d284e5d638961b21bd83eac944db Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Fri, 10 Aug 2012 22:03:25 +0200
+Subject: [PATCH] Spelling fixes in comments and documentation
+
+These wrong spellings were detected by codespell:
+
+* successully -> successfully
+
+* alot -> a lot
+
+* wanna -> want to
+
+* infomation -> information
+
+* occured -> occurred
+
+["also is" -> "is also" and "ressources" -> "resources" suggested by
+Peter Maydell <peter.maydell at linaro.org>]
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit 0546b8c2f089867cd7606ff47e026e8931157828)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ docs/specs/ppc-spapr-hcalls.txt |  2 +-
+ docs/usb2.txt                   |  4 ++--
+ hw/xen_pt.h                     |  4 ++--
+ hw/xen_pt_config_init.c         | 14 +++++++-------
+ qemu-img.c                      |  2 +-
+ qemu-img.texi                   |  2 +-
+ 6 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/docs/specs/ppc-spapr-hcalls.txt b/docs/specs/ppc-spapr-hcalls.txt
+index 52ba8d4..667b3fa 100644
+--- a/docs/specs/ppc-spapr-hcalls.txt
++++ b/docs/specs/ppc-spapr-hcalls.txt
+@@ -31,7 +31,7 @@ Arguments:
+ 
+ Returns:
+ 
+-  H_SUCCESS   : Successully called the RTAS function (RTAS result
++  H_SUCCESS   : Successfully called the RTAS function (RTAS result
+                 will have been stored in the parameter block)
+   H_PARAMETER : Unknown token
+ 
+diff --git a/docs/usb2.txt b/docs/usb2.txt
+index d17e3c0..43dacde 100644
+--- a/docs/usb2.txt
++++ b/docs/usb2.txt
+@@ -58,11 +58,11 @@ try ...
+ xhci controller support
+ -----------------------
+ 
+-There also is xhci host controller support available.  It got alot
++There is also xhci host controller support available.  It got a lot
+ less testing than ehci and there are a bunch of known limitations, so
+ ehci may work better for you.  On the other hand the xhci hardware
+ design is much more virtualization-friendly, thus xhci emulation uses
+-less ressources (especially cpu).  If you wanna give xhci a try
++less resources (especially cpu).  If you want to give xhci a try
+ use this to add the host controller ...
+ 
+     qemu -device nec-usb-xhci,id=xhci
+diff --git a/hw/xen_pt.h b/hw/xen_pt.h
+index 41904ec..112477a 100644
+--- a/hw/xen_pt.h
++++ b/hw/xen_pt.h
+@@ -96,7 +96,7 @@ typedef struct XenPTRegion {
+  * - do NOT use ALL F for init_val, otherwise the tbl will not be registered.
+  */
+ 
+-/* emulated register infomation */
++/* emulated register information */
+ struct XenPTRegInfo {
+     uint32_t offset;
+     uint32_t size;
+@@ -140,7 +140,7 @@ typedef int (*xen_pt_reg_size_init_fn)
+     (XenPCIPassthroughState *, const XenPTRegGroupInfo *,
+      uint32_t base_offset, uint8_t *size);
+ 
+-/* emulated register group infomation */
++/* emulated register group information */
+ struct XenPTRegGroupInfo {
+     uint8_t grp_id;
+     XenPTRegisterGroupType grp_type;
+diff --git a/hw/xen_pt_config_init.c b/hw/xen_pt_config_init.c
+index 00eb3d9..e524a40 100644
+--- a/hw/xen_pt_config_init.c
++++ b/hw/xen_pt_config_init.c
+@@ -562,7 +562,7 @@ static int xen_pt_exp_rom_bar_reg_write(XenPCIPassthroughState *s,
+     return 0;
+ }
+ 
+-/* Header Type0 reg static infomation table */
++/* Header Type0 reg static information table */
+ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
+     /* Vendor ID reg */
+     {
+@@ -753,7 +753,7 @@ static XenPTRegInfo xen_pt_emu_reg_header0[] = {
+  * Vital Product Data Capability
+  */
+ 
+-/* Vital Product Data Capability Structure reg static infomation table */
++/* Vital Product Data Capability Structure reg static information table */
+ static XenPTRegInfo xen_pt_emu_reg_vpd[] = {
+     {
+         .offset     = PCI_CAP_LIST_NEXT,
+@@ -775,7 +775,7 @@ static XenPTRegInfo xen_pt_emu_reg_vpd[] = {
+  * Vendor Specific Capability
+  */
+ 
+-/* Vendor Specific Capability Structure reg static infomation table */
++/* Vendor Specific Capability Structure reg static information table */
+ static XenPTRegInfo xen_pt_emu_reg_vendor[] = {
+     {
+         .offset     = PCI_CAP_LIST_NEXT,
+@@ -866,7 +866,7 @@ static int xen_pt_linkctrl2_reg_init(XenPCIPassthroughState *s,
+     return 0;
+ }
+ 
+-/* PCI Express Capability Structure reg static infomation table */
++/* PCI Express Capability Structure reg static information table */
+ static XenPTRegInfo xen_pt_emu_reg_pcie[] = {
+     /* Next Pointer reg */
+     {
+@@ -981,7 +981,7 @@ static int xen_pt_pmcsr_reg_write(XenPCIPassthroughState *s,
+     return 0;
+ }
+ 
+-/* Power Management Capability reg static infomation table */
++/* Power Management Capability reg static information table */
+ static XenPTRegInfo xen_pt_emu_reg_pm[] = {
+     /* Next Pointer reg */
+     {
+@@ -1259,7 +1259,7 @@ static int xen_pt_msgdata_reg_write(XenPCIPassthroughState *s,
+     return 0;
+ }
+ 
+-/* MSI Capability Structure reg static infomation table */
++/* MSI Capability Structure reg static information table */
+ static XenPTRegInfo xen_pt_emu_reg_msi[] = {
+     /* Next Pointer reg */
+     {
+@@ -1396,7 +1396,7 @@ static int xen_pt_msixctrl_reg_write(XenPCIPassthroughState *s,
+     return 0;
+ }
+ 
+-/* MSI-X Capability Structure reg static infomation table */
++/* MSI-X Capability Structure reg static information table */
+ static XenPTRegInfo xen_pt_emu_reg_msix[] = {
+     /* Next Pointer reg */
+     {
+diff --git a/qemu-img.c b/qemu-img.c
+index 0d208e8..7615e91 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -89,7 +89,7 @@ static void help(void)
+            "  '-r' tries to repair any inconsistencies that are found during the check.\n"
+            "       '-r leaks' repairs only cluster leaks, whereas '-r all' fixes all\n"
+            "       kinds of errors, with a higher risk of choosing the wrong fix or\n"
+-           "       hiding corruption that has already occured.\n"
++           "       hiding corruption that has already occurred.\n"
+            "\n"
+            "Parameters to snapshot subcommand:\n"
+            "  'snapshot' is the name of the snapshot to create, apply or delete\n"
+diff --git a/qemu-img.texi b/qemu-img.texi
+index 6b42e35..360543b 100644
+--- a/qemu-img.texi
++++ b/qemu-img.texi
+@@ -87,7 +87,7 @@ Perform a consistency check on the disk image @var{filename}.
+ If @code{-r} is specified, qemu-img tries to repair any inconsistencies found
+ during the check. @code{-r leaks} repairs only cluster leaks, whereas
+ @code{-r all} fixes all kinds of errors, with a higher risk of choosing the
+-wrong fix or hiding corruption that has already occured.
++wrong fix or hiding corruption that has already occurred.
+ 
+ Only the formats @code{qcow2}, @code{qed} and @code{vdi} support
+ consistency checks.
+-- 
+1.7.12.1
+
diff --git a/0182-console-Clean-up-bytes-per-pixel-calculation.patch b/0182-console-Clean-up-bytes-per-pixel-calculation.patch
new file mode 100644
index 0000000..7815a2d
--- /dev/null
+++ b/0182-console-Clean-up-bytes-per-pixel-calculation.patch
@@ -0,0 +1,51 @@
+From 9c6751bf2b2c817c3f52a638566b99125a0ba0f1 Mon Sep 17 00:00:00 2001
+From: BALATON Zoltan <balaton at eik.bme.hu>
+Date: Wed, 22 Aug 2012 17:19:42 +0200
+Subject: [PATCH] console: Clean up bytes per pixel calculation
+
+Division with round up is the correct way to compute this even if the
+only case where division with round down gives incorrect result is
+probably 15 bpp. This case was explicitely patched up in one of these
+functions but was unhandled in the other. (I'm not sure about setting
+16 bpp for the 15bpp case either but I left that there for now.)
+
+Signed-off-by: BALATON Zoltan <balaton at eik.bme.hu>
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit feadf1a4de0d7468ffb671a2b9f681925469fa58)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ console.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/console.c b/console.c
+index 3b5cabb..8b5e21d 100644
+--- a/console.c
++++ b/console.c
+@@ -1611,7 +1611,7 @@ PixelFormat qemu_different_endianness_pixelformat(int bpp)
+     memset(&pf, 0x00, sizeof(PixelFormat));
+ 
+     pf.bits_per_pixel = bpp;
+-    pf.bytes_per_pixel = bpp / 8;
++    pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8);
+     pf.depth = bpp == 32 ? 24 : bpp;
+ 
+     switch (bpp) {
+@@ -1660,13 +1660,12 @@ PixelFormat qemu_default_pixelformat(int bpp)
+     memset(&pf, 0x00, sizeof(PixelFormat));
+ 
+     pf.bits_per_pixel = bpp;
+-    pf.bytes_per_pixel = bpp / 8;
++    pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8);
+     pf.depth = bpp == 32 ? 24 : bpp;
+ 
+     switch (bpp) {
+         case 15:
+             pf.bits_per_pixel = 16;
+-            pf.bytes_per_pixel = 2;
+             pf.rmask = 0x00007c00;
+             pf.gmask = 0x000003E0;
+             pf.bmask = 0x0000001F;
+-- 
+1.7.12.1
+
diff --git a/0183-qapi-Fix-enumeration-typo-error.patch b/0183-qapi-Fix-enumeration-typo-error.patch
new file mode 100644
index 0000000..8fc3e9f
--- /dev/null
+++ b/0183-qapi-Fix-enumeration-typo-error.patch
@@ -0,0 +1,54 @@
+From 0ac82308def3b77162f0d9cecb11e6ffd2bd7939 Mon Sep 17 00:00:00 2001
+From: Lei Li <lilei at linux.vnet.ibm.com>
+Date: Thu, 23 Aug 2012 13:14:25 +0800
+Subject: [PATCH] qapi: Fix enumeration typo error
+
+Signed-off-by: Lei Li <lilei at linux.vnet.ibm.com>
+Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 6932a69b20a88428c531805cdd20eec8acf05b27)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ qapi-schema-guest.json | 2 +-
+ qapi-schema.json       | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/qapi-schema-guest.json b/qapi-schema-guest.json
+index d955cf1..ed0eb69 100644
+--- a/qapi-schema-guest.json
++++ b/qapi-schema-guest.json
+@@ -293,7 +293,7 @@
+ ##
+ # @GuestFsFreezeStatus
+ #
+-# An enumation of filesystem freeze states
++# An enumeration of filesystem freeze states
+ #
+ # @thawed: filesystems thawed/unfrozen
+ #
+diff --git a/qapi-schema.json b/qapi-schema.json
+index 8ddde12..29dacb5 100644
+--- a/qapi-schema.json
++++ b/qapi-schema.json
+@@ -118,7 +118,7 @@
+ ##
+ # @RunState
+ #
+-# An enumation of VM run states.
++# An enumeration of VM run states.
+ #
+ # @debug: QEMU is running on a debugger
+ #
+@@ -785,7 +785,7 @@
+ ##
+ # @SpiceQueryMouseMode
+ #
+-# An enumation of Spice mouse states.
++# An enumeration of Spice mouse states.
+ #
+ # @client: Mouse cursor position is determined by the client.
+ #
+-- 
+1.7.12.1
+
diff --git a/0184-kvm-Fix-warning-from-static-code-analysis.patch b/0184-kvm-Fix-warning-from-static-code-analysis.patch
new file mode 100644
index 0000000..87ad81d
--- /dev/null
+++ b/0184-kvm-Fix-warning-from-static-code-analysis.patch
@@ -0,0 +1,49 @@
+From 0a8b8d39763f05c7862dceec9d4f44e902a9d192 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Mon, 3 Sep 2012 22:40:40 +0200
+Subject: [PATCH] kvm: Fix warning from static code analysis
+
+Report from smatch:
+
+kvm-all.c:1373 kvm_init(135) warn:
+ variable dereferenced before check 's' (see line 1360)
+
+'s' cannot by NULL (it was alloced using g_malloc0), so there is no need
+to check it here.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 6d1cc3210ccc4372ffa337c187da9db68314c0c4)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ kvm-all.c | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/kvm-all.c b/kvm-all.c
+index 90c71f9..08d6051 100644
+--- a/kvm-all.c
++++ b/kvm-all.c
+@@ -1419,13 +1419,11 @@ int kvm_init(void)
+     return 0;
+ 
+ err:
+-    if (s) {
+-        if (s->vmfd >= 0) {
+-            close(s->vmfd);
+-        }
+-        if (s->fd != -1) {
+-            close(s->fd);
+-        }
++    if (s->vmfd >= 0) {
++        close(s->vmfd);
++    }
++    if (s->fd != -1) {
++        close(s->fd);
+     }
+     g_free(s);
+ 
+-- 
+1.7.12.1
+
diff --git a/0185-arch_init.c-add-missing-symbols-before-PRIu64-in-deb.patch b/0185-arch_init.c-add-missing-symbols-before-PRIu64-in-deb.patch
new file mode 100644
index 0000000..7fcc366
--- /dev/null
+++ b/0185-arch_init.c-add-missing-symbols-before-PRIu64-in-deb.patch
@@ -0,0 +1,54 @@
+From df075bd97f2d88969e3178ec9cb302f955d31737 Mon Sep 17 00:00:00 2001
+From: Igor Mitsyanko <i.mitsyanko at samsung.com>
+Date: Wed, 5 Sep 2012 13:04:56 +0400
+Subject: [PATCH] arch_init.c: add missing '%' symbols before PRIu64 in debug
+ printfs
+
+'%' symbols were missing in front of PRIu64 macros in DPRINTF() messages in
+arch_init.c, this caused compilation warnings when compiled with DEBUG_ARCH_INIT defined.
+
+Signed-off-by: Igor Mitsyanko <i.mitsyanko at samsung.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit ef37a699a06f96e098ee00683b7052b5fbb6ad7d)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ arch_init.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch_init.c b/arch_init.c
+index 5a1173e..47977de 100644
+--- a/arch_init.c
++++ b/arch_init.c
+@@ -562,7 +562,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
+         if ((i & 63) == 0) {
+             uint64_t t1 = (qemu_get_clock_ns(rt_clock) - bwidth) / 1000000;
+             if (t1 > MAX_WAIT) {
+-                DPRINTF("big wait: " PRIu64 " milliseconds, %d iterations\n",
++                DPRINTF("big wait: %" PRIu64 " milliseconds, %d iterations\n",
+                         t1, i);
+                 break;
+             }
+@@ -587,7 +587,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
+ 
+     expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
+ 
+-    DPRINTF("ram_save_live: expected(" PRIu64 ") <= max(" PRIu64 ")?\n",
++    DPRINTF("ram_save_live: expected(%" PRIu64 ") <= max(%" PRIu64 ")?\n",
+             expected_time, migrate_max_downtime());
+ 
+     if (expected_time <= migrate_max_downtime()) {
+@@ -799,8 +799,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
+     } while (!(flags & RAM_SAVE_FLAG_EOS));
+ 
+ done:
+-    DPRINTF("Completed load of VM with exit code %d seq iteration " PRIu64 "\n",
+-            ret, seq_iter);
++    DPRINTF("Completed load of VM with exit code %d seq iteration "
++            "%" PRIu64 "\n", ret, seq_iter);
+     return ret;
+ }
+ 
+-- 
+1.7.12.1
+
diff --git a/0186-net-notify-iothread-after-flushing-queue.patch b/0186-net-notify-iothread-after-flushing-queue.patch
new file mode 100644
index 0000000..b6a9f65
--- /dev/null
+++ b/0186-net-notify-iothread-after-flushing-queue.patch
@@ -0,0 +1,105 @@
+From 7d797af90c5293b518a072da9b23ec14a1a917f7 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini at redhat.com>
+Date: Thu, 9 Aug 2012 16:45:55 +0200
+Subject: [PATCH] net: notify iothread after flushing queue
+
+virtio-net has code to flush the queue and notify the iothread
+whenever new receive buffers are added by the guest.  That is
+fine, and indeed we need to do the same in all other drivers.
+However, notifying the iothread should be work for the network
+subsystem.  And since we are at it we can add a little smartness:
+if some of the queued packets already could not be delivered,
+there is no need to notify the iothread.
+
+Reported-by: Luigi Rizzo <rizzo at iet.unipi.it>
+Cc: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Cc: Jan Kiszka <jan.kiszka at siemens.de>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+Reviewed-by: Amos Kong <akong at redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit 987a9b4800003567b1a47a379255e886a77d57ea)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/virtio-net.c | 4 ----
+ net.c           | 7 ++++++-
+ net/queue.c     | 5 +++--
+ net/queue.h     | 2 +-
+ 4 files changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/hw/virtio-net.c b/hw/virtio-net.c
+index b1998b2..6490743 100644
+--- a/hw/virtio-net.c
++++ b/hw/virtio-net.c
+@@ -447,10 +447,6 @@ static void virtio_net_handle_rx(VirtIODevice *vdev, VirtQueue *vq)
+     VirtIONet *n = to_virtio_net(vdev);
+ 
+     qemu_flush_queued_packets(&n->nic->nc);
+-
+-    /* We now have RX buffers, signal to the IO thread to break out of the
+-     * select to re-poll the tap file descriptor */
+-    qemu_notify_event();
+ }
+ 
+ static int virtio_net_can_receive(NetClientState *nc)
+diff --git a/net.c b/net.c
+index 60043dd..76a8336 100644
+--- a/net.c
++++ b/net.c
+@@ -357,7 +357,12 @@ void qemu_flush_queued_packets(NetClientState *nc)
+ {
+     nc->receive_disabled = 0;
+ 
+-    qemu_net_queue_flush(nc->send_queue);
++    if (qemu_net_queue_flush(nc->send_queue)) {
++        /* We emptied the queue successfully, signal to the IO thread to repoll
++         * the file descriptor (for tap, for example).
++         */
++        qemu_notify_event();
++    }
+ }
+ 
+ static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
+diff --git a/net/queue.c b/net/queue.c
+index e8030aa..6e64091 100644
+--- a/net/queue.c
++++ b/net/queue.c
+@@ -228,7 +228,7 @@ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from)
+     }
+ }
+ 
+-void qemu_net_queue_flush(NetQueue *queue)
++bool qemu_net_queue_flush(NetQueue *queue)
+ {
+     while (!QTAILQ_EMPTY(&queue->packets)) {
+         NetPacket *packet;
+@@ -244,7 +244,7 @@ void qemu_net_queue_flush(NetQueue *queue)
+                                      packet->size);
+         if (ret == 0) {
+             QTAILQ_INSERT_HEAD(&queue->packets, packet, entry);
+-            break;
++            return false;
+         }
+ 
+         if (packet->sent_cb) {
+@@ -253,4 +253,5 @@ void qemu_net_queue_flush(NetQueue *queue)
+ 
+         g_free(packet);
+     }
++    return true;
+ }
+diff --git a/net/queue.h b/net/queue.h
+index 9d44a9b..fc02b33 100644
+--- a/net/queue.h
++++ b/net/queue.h
+@@ -53,6 +53,6 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
+                                 NetPacketSent *sent_cb);
+ 
+ void qemu_net_queue_purge(NetQueue *queue, NetClientState *from);
+-void qemu_net_queue_flush(NetQueue *queue);
++bool qemu_net_queue_flush(NetQueue *queue);
+ 
+ #endif /* QEMU_NET_QUEUE_H */
+-- 
+1.7.12.1
+
diff --git a/0187-e1000-flush-queue-whenever-can_receive-can-go-from-f.patch b/0187-e1000-flush-queue-whenever-can_receive-can-go-from-f.patch
new file mode 100644
index 0000000..9d61ff8
--- /dev/null
+++ b/0187-e1000-flush-queue-whenever-can_receive-can-go-from-f.patch
@@ -0,0 +1,51 @@
+From a71b6050a88402c3f388b8f13afed51e6ba6f41a Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini at redhat.com>
+Date: Thu, 9 Aug 2012 16:45:56 +0200
+Subject: [PATCH] e1000: flush queue whenever can_receive can go from false to
+ true
+
+When the guests replenish the receive ring buffer, the network device
+should flush its queue of pending packets.  This is done with
+qemu_flush_queued_packets.
+
+e1000's can_receive can go from false to true when RCTL or RDT are
+modified.
+
+Reported-by: Luigi Rizzo <rizzo at iet.unipi.it>
+Cc: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Cc: Jan Kiszka <jan.kiszka at siemens.de>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+Reviewed-by: Amos Kong <akong at redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit e8b4c680b41bd960ecccd9ff076b7b058e0afcd4)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/e1000.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/hw/e1000.c b/hw/e1000.c
+index ae8a6c5..ec3a7c4 100644
+--- a/hw/e1000.c
++++ b/hw/e1000.c
+@@ -295,6 +295,7 @@ set_rx_control(E1000State *s, int index, uint32_t val)
+     s->rxbuf_min_shift = ((val / E1000_RCTL_RDMTS_QUAT) & 3) + 1;
+     DBGOUT(RX, "RCTL: %d, mac_reg[RCTL] = 0x%x\n", s->mac_reg[RDT],
+            s->mac_reg[RCTL]);
++    qemu_flush_queued_packets(&s->nic->nc);
+ }
+ 
+ static void
+@@ -926,6 +927,9 @@ set_rdt(E1000State *s, int index, uint32_t val)
+ {
+     s->check_rxov = 0;
+     s->mac_reg[index] = val & 0xffff;
++    if (e1000_has_rxbufs(s, 1)) {
++        qemu_flush_queued_packets(&s->nic->nc);
++    }
+ }
+ 
+ static void
+-- 
+1.7.12.1
+
diff --git a/0188-xen-flush-queue-when-getting-an-event.patch b/0188-xen-flush-queue-when-getting-an-event.patch
new file mode 100644
index 0000000..6c52eb4
--- /dev/null
+++ b/0188-xen-flush-queue-when-getting-an-event.patch
@@ -0,0 +1,37 @@
+From 7fc16be815b8ff85f174fc93d67f82400da08120 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini at redhat.com>
+Date: Thu, 9 Aug 2012 16:45:57 +0200
+Subject: [PATCH] xen: flush queue when getting an event
+
+xen does not have a register that, when written, will cause can_receive
+to go from false to true.  However, flushing the queue can be attempted
+whenever the front-end raises its side of the Xen event channel.  There
+is a single event channel for tx and rx.
+
+Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+Cc: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+Reviewed-by: Amos Kong <akong at redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit a98b140223d3a627eab7ee3ddec645bab630d756)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/xen_nic.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/xen_nic.c b/hw/xen_nic.c
+index 8b79bfb..cf7d559 100644
+--- a/hw/xen_nic.c
++++ b/hw/xen_nic.c
+@@ -415,6 +415,7 @@ static void net_event(struct XenDevice *xendev)
+ {
+     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
+     net_tx_packets(netdev);
++    qemu_flush_queued_packets(&netdev->nic->nc);
+ }
+ 
+ static int net_free(struct XenDevice *xendev)
+-- 
+1.7.12.1
+
diff --git a/0189-eepro100-Fix-network-hang-when-rx-buffers-run-out.patch b/0189-eepro100-Fix-network-hang-when-rx-buffers-run-out.patch
new file mode 100644
index 0000000..4e2df82
--- /dev/null
+++ b/0189-eepro100-Fix-network-hang-when-rx-buffers-run-out.patch
@@ -0,0 +1,72 @@
+From 154f1e30c09d261b12937c385632c05474989b02 Mon Sep 17 00:00:00 2001
+From: Bo Yang <boyang at suse.com>
+Date: Wed, 29 Aug 2012 19:26:11 +0800
+Subject: [PATCH] eepro100: Fix network hang when rx buffers run out
+
+This is reported by QA. When installing os with pxe, after the initial
+kernel and initrd are loaded, the procedure tries to copy files from install
+server to local harddisk, the network becomes stall because of running out of
+receive descriptor.
+
+[Whitespace fixes and removed qemu_notify_event() because Paolo's
+earlier net patches have moved it into qemu_flush_queued_packets().
+
+Additional info:
+
+I can reproduce the network hang with a tap device doing a iPXE HTTP
+boot as follows:
+
+  $ qemu -enable-kvm -m 1024 \
+    -netdev tap,id=netdev0,script=no,downscript=no \
+    -device i82559er,netdev=netdev0,romfile=80861209.rom \
+    -drive if=virtio,cache=none,file=test.img
+  iPXE> ifopen net0
+  iPXE> config # set static network configuration
+  iPXE> kernel http://mirror.bytemark.co.uk/fedora/linux/releases/17/Fedora/x86_64/os/images/pxeboot/vmlinuz
+
+I needed a vanilla iPXE ROM to get to the iPXE prompt.  I think the boot
+prompt has been disabled in the ROMs that ship with QEMU to reduce boot
+time.
+
+During the vmlinuz HTTP download there is a network hang.  hw/eepro100.c
+has reached the end of the rx descriptor list.  When the iPXE driver
+replenishes the rx descriptor list we don't kick the QEMU net subsystem
+and event loop, thereby leaving the tap netdev without its file
+descriptor in select(2).
+
+Stefan Hajnoczi <stefanha at gmail.com>]
+
+Signed-off-by: Bo Yang <boyang at suse.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 1069985fb132cd4324fc02d371f1e61492a1823f)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/eepro100.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/hw/eepro100.c b/hw/eepro100.c
+index 50d117e..5b23116 100644
+--- a/hw/eepro100.c
++++ b/hw/eepro100.c
+@@ -1036,6 +1036,7 @@ static void eepro100_ru_command(EEPRO100State * s, uint8_t val)
+         }
+         set_ru_state(s, ru_ready);
+         s->ru_offset = e100_read_reg4(s, SCBPointer);
++        qemu_flush_queued_packets(&s->nic->nc);
+         TRACE(OTHER, logout("val=0x%02x (rx start)\n", val));
+         break;
+     case RX_RESUME:
+@@ -1770,7 +1771,8 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)
+     if (rfd_command & COMMAND_EL) {
+         /* EL bit is set, so this was the last frame. */
+         logout("receive: Running out of frames\n");
+-        set_ru_state(s, ru_suspended);
++        set_ru_state(s, ru_no_resources);
++        eepro100_rnr_interrupt(s);
+     }
+     if (rfd_command & COMMAND_S) {
+         /* S bit is set. */
+-- 
+1.7.12.1
+
diff --git a/0190-net-add-receive_disabled-logic-to-iov-delivery-path.patch b/0190-net-add-receive_disabled-logic-to-iov-delivery-path.patch
new file mode 100644
index 0000000..f94a29e
--- /dev/null
+++ b/0190-net-add-receive_disabled-logic-to-iov-delivery-path.patch
@@ -0,0 +1,65 @@
+From eccdc01e744cf3a389a527406f4d529420133e89 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Date: Fri, 17 Aug 2012 21:16:42 +0100
+Subject: [PATCH] net: add receive_disabled logic to iov delivery path
+
+This patch adds the missing NetClient->receive_disabled logic in the
+sendv delivery code path.  It seems that commit
+893379efd0e1b84ceb0c42a713293f3dbd27b1bd ("net: disable receiving if
+client returns zero") only added the logic to qemu_deliver_packet() and
+not qemu_deliver_packet_iov().
+
+The receive_disabled flag should be automatically set when .receive(),
+.receive_raw(), or .receive_iov() return 0.  No further packets will be
+delivered to the NetClient until the receive_disabled flag is cleared
+again by calling qemu_flush_queued_packets().
+
+Typically the NetClient will wait until its file descriptor becomes
+writable and then invoke qemu_flush_queued_packets() to resume
+transmission.
+
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit c67f5dc10573687497f0f5c3aec19b15c35c63d7)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ net.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/net.c b/net.c
+index 76a8336..1303819 100644
+--- a/net.c
++++ b/net.c
+@@ -423,16 +423,27 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
+                                 void *opaque)
+ {
+     NetClientState *nc = opaque;
++    int ret;
+ 
+     if (nc->link_down) {
+         return iov_size(iov, iovcnt);
+     }
+ 
++    if (nc->receive_disabled) {
++        return 0;
++    }
++
+     if (nc->info->receive_iov) {
+-        return nc->info->receive_iov(nc, iov, iovcnt);
++        ret = nc->info->receive_iov(nc, iov, iovcnt);
+     } else {
+-        return nc_sendv_compat(nc, iov, iovcnt);
++        ret = nc_sendv_compat(nc, iov, iovcnt);
+     }
++
++    if (ret == 0) {
++        nc->receive_disabled = 1;
++    }
++
++    return ret;
+ }
+ 
+ ssize_t qemu_sendv_packet_async(NetClientState *sender,
+-- 
+1.7.12.1
+
diff --git a/0191-net-do-not-report-queued-packets-as-sent.patch b/0191-net-do-not-report-queued-packets-as-sent.patch
new file mode 100644
index 0000000..b6deca0
--- /dev/null
+++ b/0191-net-do-not-report-queued-packets-as-sent.patch
@@ -0,0 +1,103 @@
+From 17df2130cd8be0cd6892b86103947746f95efc2c Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Date: Mon, 20 Aug 2012 13:35:23 +0100
+Subject: [PATCH] net: do not report queued packets as sent
+
+Net send functions have a return value where 0 means the packet has not
+been sent and will be queued.  A non-zero value means the packet was
+sent or an error caused the packet to be dropped.
+
+This patch fixes two instances where packets are queued but we return
+their size.  This causes callers to believe the packets were sent.  When
+the caller uses the async send interface this creates a real problem
+because the callback will be invoked for a packet that the caller
+believed to be already sent.  This bug can cause double-frees in the
+caller.
+
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit 06b5f36d052b540a59b52150582d65674199b2ce)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ net/queue.c | 35 ++++++++++++++++-------------------
+ 1 file changed, 16 insertions(+), 19 deletions(-)
+
+diff --git a/net/queue.c b/net/queue.c
+index 6e64091..254f280 100644
+--- a/net/queue.c
++++ b/net/queue.c
+@@ -83,12 +83,12 @@ void qemu_del_net_queue(NetQueue *queue)
+     g_free(queue);
+ }
+ 
+-static ssize_t qemu_net_queue_append(NetQueue *queue,
+-                                     NetClientState *sender,
+-                                     unsigned flags,
+-                                     const uint8_t *buf,
+-                                     size_t size,
+-                                     NetPacketSent *sent_cb)
++static void qemu_net_queue_append(NetQueue *queue,
++                                  NetClientState *sender,
++                                  unsigned flags,
++                                  const uint8_t *buf,
++                                  size_t size,
++                                  NetPacketSent *sent_cb)
+ {
+     NetPacket *packet;
+ 
+@@ -100,16 +100,14 @@ static ssize_t qemu_net_queue_append(NetQueue *queue,
+     memcpy(packet->data, buf, size);
+ 
+     QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
+-
+-    return size;
+ }
+ 
+-static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
+-                                         NetClientState *sender,
+-                                         unsigned flags,
+-                                         const struct iovec *iov,
+-                                         int iovcnt,
+-                                         NetPacketSent *sent_cb)
++static void qemu_net_queue_append_iov(NetQueue *queue,
++                                      NetClientState *sender,
++                                      unsigned flags,
++                                      const struct iovec *iov,
++                                      int iovcnt,
++                                      NetPacketSent *sent_cb)
+ {
+     NetPacket *packet;
+     size_t max_len = 0;
+@@ -133,8 +131,6 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
+     }
+ 
+     QTAILQ_INSERT_TAIL(&queue->packets, packet, entry);
+-
+-    return packet->size;
+ }
+ 
+ static ssize_t qemu_net_queue_deliver(NetQueue *queue,
+@@ -177,7 +173,8 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
+     ssize_t ret;
+ 
+     if (queue->delivering || !qemu_can_send_packet(sender)) {
+-        return qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
++        qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
++        return 0;
+     }
+ 
+     ret = qemu_net_queue_deliver(queue, sender, flags, data, size);
+@@ -201,8 +198,8 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
+     ssize_t ret;
+ 
+     if (queue->delivering || !qemu_can_send_packet(sender)) {
+-        return qemu_net_queue_append_iov(queue, sender, flags,
+-                                         iov, iovcnt, sent_cb);
++        qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, sent_cb);
++        return 0;
+     }
+ 
+     ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt);
+-- 
+1.7.12.1
+
diff --git a/0192-net-add-netdev-options-to-man-page.patch b/0192-net-add-netdev-options-to-man-page.patch
new file mode 100644
index 0000000..b0272da
--- /dev/null
+++ b/0192-net-add-netdev-options-to-man-page.patch
@@ -0,0 +1,81 @@
+From 773b0a456b236ccdcf1e5329992c0d4669f0af26 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Date: Tue, 14 Aug 2012 14:14:27 +0100
+Subject: [PATCH] net: add -netdev options to man page
+
+Document the -netdev syntax which supercedes the older -net syntax.
+This patch is a first step to making -netdev prominent in the QEMU
+manual.
+
+Reported-by: Anatoly Techtonik <techtonik at gmail.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit 08d12022c7f1aba6acccc75150659c6e4c9dff23)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ qemu-options.hx | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/qemu-options.hx b/qemu-options.hx
+index 1af4fec..1021ab7 100644
+--- a/qemu-options.hx
++++ b/qemu-options.hx
+@@ -1357,6 +1357,7 @@ Valid values for @var{type} are
+ Not all devices are supported on all targets.  Use -net nic,model=?
+ for a list of available devices for your target.
+ 
++ at item -netdev user,id=@var{id}[, at var{option}][, at var{option}][,...]
+ @item -net user[, at var{option}][, at var{option}][,...]
+ Use the user mode network stack which requires no administrator
+ privilege to run. Valid options are:
+@@ -1365,6 +1366,7 @@ privilege to run. Valid options are:
+ @item vlan=@var{n}
+ Connect user mode stack to VLAN @var{n} (@var{n} = 0 is the default).
+ 
++ at item id=@var{id}
+ @item name=@var{name}
+ Assign symbolic name for use in monitor commands.
+ 
+@@ -1490,6 +1492,7 @@ processed and applied to -net user. Mixing them with the new configuration
+ syntax gives undefined results. Their use for new applications is discouraged
+ as they will be removed from future versions.
+ 
++ at item -netdev tap,id=@var{id}[,fd=@var{h}][,ifname=@var{name}][,script=@var{file}][,downscript=@var{dfile}][,helper=@var{helper}]
+ @item -net tap[,vlan=@var{n}][,name=@var{name}][,fd=@var{h}][,ifname=@var{name}][,script=@var{file}][,downscript=@var{dfile}][,helper=@var{helper}]
+ Connect the host TAP network interface @var{name} to VLAN @var{n}.
+ 
+@@ -1529,6 +1532,7 @@ qemu-system-i386 linux.img \
+                  -net nic -net tap,"helper=/usr/local/libexec/qemu-bridge-helper"
+ @end example
+ 
++ at item -netdev bridge,id=@var{id}[,br=@var{bridge}][,helper=@var{helper}]
+ @item -net bridge[,vlan=@var{n}][,name=@var{name}][,br=@var{bridge}][,helper=@var{helper}]
+ Connect a host TAP network interface to a host bridge device.
+ 
+@@ -1551,6 +1555,7 @@ qemu-system-i386 linux.img -net bridge -net nic,model=virtio
+ qemu-system-i386 linux.img -net bridge,br=qemubr0 -net nic,model=virtio
+ @end example
+ 
++ at item -netdev socket,id=@var{id}[,fd=@var{h}][,listen=[@var{host}]:@var{port}][,connect=@var{host}:@var{port}]
+ @item -net socket[,vlan=@var{n}][,name=@var{name}][,fd=@var{h}] [,listen=[@var{host}]:@var{port}][,connect=@var{host}:@var{port}]
+ 
+ Connect the VLAN @var{n} to a remote VLAN in another QEMU virtual
+@@ -1573,6 +1578,7 @@ qemu-system-i386 linux.img \
+                  -net socket,connect=127.0.0.1:1234
+ @end example
+ 
++ at item -netdev socket,id=@var{id}[,fd=@var{h}][,mcast=@var{maddr}:@var{port}[,localaddr=@var{addr}]]
+ @item -net socket[,vlan=@var{n}][,name=@var{name}][,fd=@var{h}][,mcast=@var{maddr}:@var{port}[,localaddr=@var{addr}]]
+ 
+ Create a VLAN @var{n} shared with another QEMU virtual
+@@ -1624,6 +1630,7 @@ qemu-system-i386 linux.img \
+                  -net socket,mcast=239.192.168.1:1102,localaddr=1.2.3.4
+ @end example
+ 
++ at item -netdev vde,id=@var{id}[,sock=@var{socketpath}][,port=@var{n}][,group=@var{groupname}][,mode=@var{octalmode}]
+ @item -net vde[,vlan=@var{n}][,name=@var{name}][,sock=@var{socketpath}] [,port=@var{n}][,group=@var{groupname}][,mode=@var{octalmode}]
+ Connect VLAN @var{n} to PORT @var{n} of a vde switch running on host and
+ listening for incoming connections on @var{socketpath}. Use GROUP @var{groupname}
+-- 
+1.7.12.1
+
diff --git a/0193-net-clean-up-usbnet_receive.patch b/0193-net-clean-up-usbnet_receive.patch
new file mode 100644
index 0000000..c92890e
--- /dev/null
+++ b/0193-net-clean-up-usbnet_receive.patch
@@ -0,0 +1,80 @@
+From f3f975860db11101ccef2f75238032328de00ce0 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Date: Fri, 24 Aug 2012 13:32:16 +0100
+Subject: [PATCH] net: clean up usbnet_receive()
+
+The USB network interface has two code paths depending on whether or not
+RNDIS mode is enabled.  Refactor usbnet_receive() so that there is a
+common path throughout the function instead of duplicating everything
+across if (is_rndis(s)) ... else ... code paths.
+
+Clean up coding style and 80 character line wrap along the way.
+
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit f237ddbb89142c6948a2257c459e49dee7500a7c)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/usb/dev-network.c | 30 +++++++++++++++++-------------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
+index c84892c..0b5cb71 100644
+--- a/hw/usb/dev-network.c
++++ b/hw/usb/dev-network.c
+@@ -1250,20 +1250,27 @@ static int usb_net_handle_data(USBDevice *dev, USBPacket *p)
+ static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t size)
+ {
+     USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque;
+-    struct rndis_packet_msg_type *msg;
++    uint8_t *in_buf = s->in_buf;
++    size_t total_size = size;
+ 
+     if (is_rndis(s)) {
+-        msg = (struct rndis_packet_msg_type *) s->in_buf;
+         if (s->rndis_state != RNDIS_DATA_INITIALIZED) {
+             return -1;
+         }
+-        if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf))
+-            return -1;
++        total_size += sizeof(struct rndis_packet_msg_type);
++    }
++    if (total_size > sizeof(s->in_buf)) {
++        return -1;
++    }
+ 
++    if (is_rndis(s)) {
++        struct rndis_packet_msg_type *msg;
++
++        msg = (struct rndis_packet_msg_type *)in_buf;
+         memset(msg, 0, sizeof(struct rndis_packet_msg_type));
+         msg->MessageType = cpu_to_le32(RNDIS_PACKET_MSG);
+-        msg->MessageLength = cpu_to_le32(size + sizeof(struct rndis_packet_msg_type));
+-        msg->DataOffset = cpu_to_le32(sizeof(struct rndis_packet_msg_type) - 8);
++        msg->MessageLength = cpu_to_le32(size + sizeof(*msg));
++        msg->DataOffset = cpu_to_le32(sizeof(*msg) - 8);
+         msg->DataLength = cpu_to_le32(size);
+         /* msg->OOBDataOffset;
+          * msg->OOBDataLength;
+@@ -1273,14 +1280,11 @@ static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t siz
+          * msg->VcHandle;
+          * msg->Reserved;
+          */
+-        memcpy(msg + 1, buf, size);
+-        s->in_len = size + sizeof(struct rndis_packet_msg_type);
+-    } else {
+-        if (size > sizeof(s->in_buf))
+-            return -1;
+-        memcpy(s->in_buf, buf, size);
+-        s->in_len = size;
++        in_buf += sizeof(*msg);
+     }
++
++    memcpy(in_buf, buf, size);
++    s->in_len = total_size;
+     s->in_ptr = 0;
+     return size;
+ }
+-- 
+1.7.12.1
+
diff --git a/0194-net-fix-usbnet_receive-packet-drops.patch b/0194-net-fix-usbnet_receive-packet-drops.patch
new file mode 100644
index 0000000..bbe1c76
--- /dev/null
+++ b/0194-net-fix-usbnet_receive-packet-drops.patch
@@ -0,0 +1,81 @@
+From 14294fa1c903ab239bce3d2839e9e1883141b4f1 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Date: Fri, 24 Aug 2012 13:37:29 +0100
+Subject: [PATCH] net: fix usbnet_receive() packet drops
+
+The USB network interface has a single buffer which the guest reads
+from.  This patch prevents multiple calls to usbnet_receive() from
+clobbering the input buffer.  Instead we queue packets until buffer
+space becomes available again.
+
+This is inspired by virtio-net and e1000 rxbuf handling.
+
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit 190563f9a90c9df8ad32fc7f3e4b166deda949a6)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/usb/dev-network.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
+index 0b5cb71..e4a4359 100644
+--- a/hw/usb/dev-network.c
++++ b/hw/usb/dev-network.c
+@@ -1001,6 +1001,13 @@ static int rndis_keepalive_response(USBNetState *s,
+     return 0;
+ }
+ 
++/* Prepare to receive the next packet */
++static void usb_net_reset_in_buf(USBNetState *s)
++{
++    s->in_ptr = s->in_len = 0;
++    qemu_flush_queued_packets(&s->nic->nc);
++}
++
+ static int rndis_parse(USBNetState *s, uint8_t *data, int length)
+ {
+     uint32_t msg_type;
+@@ -1025,7 +1032,8 @@ static int rndis_parse(USBNetState *s, uint8_t *data, int length)
+ 
+     case RNDIS_RESET_MSG:
+         rndis_clear_responsequeue(s);
+-        s->out_ptr = s->in_ptr = s->in_len = 0;
++        s->out_ptr = 0;
++        usb_net_reset_in_buf(s);
+         return rndis_reset_response(s, (rndis_reset_msg_type *) data);
+ 
+     case RNDIS_KEEPALIVE_MSG:
+@@ -1135,7 +1143,7 @@ static int usb_net_handle_datain(USBNetState *s, USBPacket *p)
+     int ret = USB_RET_NAK;
+ 
+     if (s->in_ptr > s->in_len) {
+-        s->in_ptr = s->in_len = 0;
++        usb_net_reset_in_buf(s);
+         ret = USB_RET_NAK;
+         return ret;
+     }
+@@ -1152,7 +1160,7 @@ static int usb_net_handle_datain(USBNetState *s, USBPacket *p)
+     if (s->in_ptr >= s->in_len &&
+                     (is_rndis(s) || (s->in_len & (64 - 1)) || !ret)) {
+         /* no short packet necessary */
+-        s->in_ptr = s->in_len = 0;
++        usb_net_reset_in_buf(s);
+     }
+ 
+ #ifdef TRAFFIC_DEBUG
+@@ -1263,6 +1271,11 @@ static ssize_t usbnet_receive(NetClientState *nc, const uint8_t *buf, size_t siz
+         return -1;
+     }
+ 
++    /* Only accept packet if input buffer is empty */
++    if (s->in_len > 0) {
++        return 0;
++    }
++
+     if (is_rndis(s)) {
+         struct rndis_packet_msg_type *msg;
+ 
+-- 
+1.7.12.1
+
diff --git a/0195-net-broadcast-hub-packets-if-at-least-one-port-can-r.patch b/0195-net-broadcast-hub-packets-if-at-least-one-port-can-r.patch
new file mode 100644
index 0000000..5cb7e1c
--- /dev/null
+++ b/0195-net-broadcast-hub-packets-if-at-least-one-port-can-r.patch
@@ -0,0 +1,51 @@
+From 25ade2154673396e432de2b3c413865d1552c9b3 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Date: Fri, 24 Aug 2012 13:50:30 +0100
+Subject: [PATCH] net: broadcast hub packets if at least one port can receive
+
+In commit 60c07d933c66c4b30a83b7ccbc8a0cb3df1b2d0e ("net: fix
+qemu_can_send_packet logic") the "VLAN" broadcast behavior was changed
+to queue packets if any net client cannot receive.  It turns out that
+this was not actually the right fix and just hides the real bug that
+hw/usb/dev-network.c:usbnet_receive() clobbers its receive buffer when
+called multiple times in a row.  The commit also introduced a new bug
+that "VLAN" packets would not be sent if one of multiple net clients was
+down.
+
+The hw/usb/dev-network.c bug has since been fixed, so this patch reverts
+broadcast behavior to send packets as long as one net client can
+receive.  Packets simply get queued for the net clients that are
+temporarily unable to receive.
+
+Reported-by: Roy.Li <rongqing.li at windriver.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit 61518a74ca98870e8ff132f91dd5dda252e31f58)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ net/hub.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/hub.c b/net/hub.c
+index ac157e3..650a8b4 100644
+--- a/net/hub.c
++++ b/net/hub.c
+@@ -97,12 +97,12 @@ static int net_hub_port_can_receive(NetClientState *nc)
+             continue;
+         }
+ 
+-        if (!qemu_can_send_packet(&port->nc)) {
+-            return 0;
++        if (qemu_can_send_packet(&port->nc)) {
++            return 1;
+         }
+     }
+ 
+-    return 1;
++    return 0;
+ }
+ 
+ static ssize_t net_hub_port_receive(NetClientState *nc,
+-- 
+1.7.12.1
+
diff --git a/0196-net-asynchronous-send-receive-infrastructure-for-net.patch b/0196-net-asynchronous-send-receive-infrastructure-for-net.patch
new file mode 100644
index 0000000..53f0722
--- /dev/null
+++ b/0196-net-asynchronous-send-receive-infrastructure-for-net.patch
@@ -0,0 +1,133 @@
+From 176b159d70cb26b24ce928497ae269b294e503d8 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Date: Mon, 20 Aug 2012 10:21:54 +0100
+Subject: [PATCH] net: asynchronous send/receive infrastructure for
+ net/socket.c
+
+The net/socket.c net client is not truly asynchronous.  This patch
+borrows the qemu_set_fd_handler2() code from net/tap.c as the basis for
+proper asynchronous send/receive.
+
+Only read packets from the socket when the peer is able to receive.
+This avoids needless queuing.
+
+Later patches implement asynchronous send.
+
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit 863f678fba4191f3b695620f41056cb7c124425d)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ net/socket.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 52 insertions(+), 6 deletions(-)
+
+diff --git a/net/socket.c b/net/socket.c
+index c172c24..54e32f0 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -42,9 +42,51 @@ typedef struct NetSocketState {
+     unsigned int packet_len;
+     uint8_t buf[4096];
+     struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
++    IOHandler *send_fn;           /* differs between SOCK_STREAM/SOCK_DGRAM */
++    bool read_poll;               /* waiting to receive data? */
++    bool write_poll;              /* waiting to transmit data? */
+ } NetSocketState;
+ 
+ static void net_socket_accept(void *opaque);
++static void net_socket_writable(void *opaque);
++
++/* Only read packets from socket when peer can receive them */
++static int net_socket_can_send(void *opaque)
++{
++    NetSocketState *s = opaque;
++
++    return qemu_can_send_packet(&s->nc);
++}
++
++static void net_socket_update_fd_handler(NetSocketState *s)
++{
++    qemu_set_fd_handler2(s->fd,
++                         s->read_poll  ? net_socket_can_send : NULL,
++                         s->read_poll  ? s->send_fn : NULL,
++                         s->write_poll ? net_socket_writable : NULL,
++                         s);
++}
++
++static void net_socket_read_poll(NetSocketState *s, bool enable)
++{
++    s->read_poll = enable;
++    net_socket_update_fd_handler(s);
++}
++
++static void net_socket_write_poll(NetSocketState *s, bool enable)
++{
++    s->write_poll = enable;
++    net_socket_update_fd_handler(s);
++}
++
++static void net_socket_writable(void *opaque)
++{
++    NetSocketState *s = opaque;
++
++    net_socket_write_poll(s, false);
++
++    qemu_flush_queued_packets(&s->nc);
++}
+ 
+ /* XXX: we consider we can send the whole packet without blocking */
+ static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t size)
+@@ -81,7 +123,8 @@ static void net_socket_send(void *opaque)
+     } else if (size == 0) {
+         /* end of connection */
+     eoc:
+-        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
++        net_socket_read_poll(s, false);
++        net_socket_write_poll(s, false);
+         if (s->listen_fd != -1) {
+             qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);
+         }
+@@ -152,7 +195,8 @@ static void net_socket_send_dgram(void *opaque)
+         return;
+     if (size == 0) {
+         /* end of connection */
+-        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
++        net_socket_read_poll(s, false);
++        net_socket_write_poll(s, false);
+         return;
+     }
+     qemu_send_packet(&s->nc, s->buf, size);
+@@ -243,7 +287,8 @@ static void net_socket_cleanup(NetClientState *nc)
+ {
+     NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
+     if (s->fd != -1) {
+-        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
++        net_socket_read_poll(s, false);
++        net_socket_write_poll(s, false);
+         close(s->fd);
+         s->fd = -1;
+     }
+@@ -314,8 +359,8 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
+ 
+     s->fd = fd;
+     s->listen_fd = -1;
+-
+-    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
++    s->send_fn = net_socket_send_dgram;
++    net_socket_read_poll(s, true);
+ 
+     /* mcast: save bound address as dst */
+     if (is_connected) {
+@@ -332,7 +377,8 @@ err:
+ static void net_socket_connect(void *opaque)
+ {
+     NetSocketState *s = opaque;
+-    qemu_set_fd_handler(s->fd, net_socket_send, NULL, s);
++    s->send_fn = net_socket_send;
++    net_socket_read_poll(s, true);
+ }
+ 
+ static NetClientInfo net_socket_info = {
+-- 
+1.7.12.1
+
diff --git a/0197-net-EAGAIN-handling-for-net-socket.c-UDP.patch b/0197-net-EAGAIN-handling-for-net-socket.c-UDP.patch
new file mode 100644
index 0000000..9745eaa
--- /dev/null
+++ b/0197-net-EAGAIN-handling-for-net-socket.c-UDP.patch
@@ -0,0 +1,45 @@
+From a2374b78f298d5755e96468bb97e4d7b660ff9d6 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Date: Mon, 20 Aug 2012 10:28:53 +0100
+Subject: [PATCH] net: EAGAIN handling for net/socket.c UDP
+
+Implement asynchronous send for UDP (or other SOCK_DGRAM) sockets.  If
+send fails with EAGAIN we wait for the socket to become writable again.
+
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit 213fd5087e2e4e2da10ad266df0ba950cf7618bf)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ net/socket.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/net/socket.c b/net/socket.c
+index 54e32f0..e5e4e8d 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -102,9 +102,19 @@ static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t
+ static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size)
+ {
+     NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
++    ssize_t ret;
+ 
+-    return sendto(s->fd, (const void *)buf, size, 0,
+-                  (struct sockaddr *)&s->dgram_dst, sizeof(s->dgram_dst));
++    do {
++        ret = sendto(s->fd, buf, size, 0,
++                     (struct sockaddr *)&s->dgram_dst,
++                     sizeof(s->dgram_dst));
++    } while (ret == -1 && errno == EINTR);
++
++    if (ret == -1 && errno == EAGAIN) {
++        net_socket_write_poll(s, true);
++        return 0;
++    }
++    return ret;
+ }
+ 
+ static void net_socket_send(void *opaque)
+-- 
+1.7.12.1
+
diff --git a/0198-net-EAGAIN-handling-for-net-socket.c-TCP.patch b/0198-net-EAGAIN-handling-for-net-socket.c-TCP.patch
new file mode 100644
index 0000000..d318bf1
--- /dev/null
+++ b/0198-net-EAGAIN-handling-for-net-socket.c-TCP.patch
@@ -0,0 +1,97 @@
+From 52d73aa49799848042c09be1c64c1bff2159a5e1 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Date: Mon, 20 Aug 2012 10:14:35 +0100
+Subject: [PATCH] net: EAGAIN handling for net/socket.c TCP
+
+Replace spinning send_all() with a proper non-blocking send.  When the
+socket write buffer limit is reached, we should stop trying to send and
+wait for the socket to become writable again.
+
+Non-blocking TCP sockets can return in two different ways when the write
+buffer limit is reached:
+
+1. ret = -1 and errno = EAGAIN/EWOULDBLOCK.  No data has been written.
+
+2. ret < total_size.  Short write, only part of the message was
+   transmitted.
+
+Handle both cases and keep track of how many bytes have been written in
+s->send_index.  (This includes the 'length' header before the actual
+payload buffer.)
+
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+(cherry picked from commit 45a7f54a8bb3928ffa58d522e0d61acaee8277bb)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ net/socket.c | 36 +++++++++++++++++++++++++++++++-----
+ 1 file changed, 31 insertions(+), 5 deletions(-)
+
+diff --git a/net/socket.c b/net/socket.c
+index e5e4e8d..c3e55b8 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -32,6 +32,7 @@
+ #include "qemu-error.h"
+ #include "qemu-option.h"
+ #include "qemu_socket.h"
++#include "iov.h"
+ 
+ typedef struct NetSocketState {
+     NetClientState nc;
+@@ -40,6 +41,7 @@ typedef struct NetSocketState {
+     int state; /* 0 = getting length, 1 = getting data */
+     unsigned int index;
+     unsigned int packet_len;
++    unsigned int send_index;      /* number of bytes sent (only SOCK_STREAM) */
+     uint8_t buf[4096];
+     struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
+     IOHandler *send_fn;           /* differs between SOCK_STREAM/SOCK_DGRAM */
+@@ -88,15 +90,39 @@ static void net_socket_writable(void *opaque)
+     qemu_flush_queued_packets(&s->nc);
+ }
+ 
+-/* XXX: we consider we can send the whole packet without blocking */
+ static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t size)
+ {
+     NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc);
+-    uint32_t len;
+-    len = htonl(size);
++    uint32_t len = htonl(size);
++    struct iovec iov[] = {
++        {
++            .iov_base = &len,
++            .iov_len  = sizeof(len),
++        }, {
++            .iov_base = (void *)buf,
++            .iov_len  = size,
++        },
++    };
++    size_t remaining;
++    ssize_t ret;
++
++    remaining = iov_size(iov, 2) - s->send_index;
++    ret = iov_send(s->fd, iov, 2, s->send_index, remaining);
+ 
+-    send_all(s->fd, (const uint8_t *)&len, sizeof(len));
+-    return send_all(s->fd, buf, size);
++    if (ret == -1 && errno == EAGAIN) {
++        ret = 0; /* handled further down */
++    }
++    if (ret == -1) {
++        s->send_index = 0;
++        return -errno;
++    }
++    if (ret < (ssize_t)remaining) {
++        s->send_index += ret;
++        net_socket_write_poll(s, true);
++        return 0;
++    }
++    s->send_index = 0;
++    return size;
+ }
+ 
+ static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size)
+-- 
+1.7.12.1
+
diff --git a/0199-configure-fix-seccomp-check.patch b/0199-configure-fix-seccomp-check.patch
new file mode 100644
index 0000000..bf742c6
--- /dev/null
+++ b/0199-configure-fix-seccomp-check.patch
@@ -0,0 +1,45 @@
+From 4a151cbe99766a8da4582234a93d4292f064108f Mon Sep 17 00:00:00 2001
+From: "Yann E. MORIN" <yann.morin.1998 at free.fr>
+Date: Thu, 6 Sep 2012 22:40:30 +0200
+Subject: [PATCH] configure: fix seccomp check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Currently, if libseccomp is missing but the user explicitly requested
+seccomp support using --enable-seccomp, configure silently ignores the
+situation and disables seccomp support.
+
+This is unlike all other tests that explicitly fail in such situation.
+
+Fix that.
+
+Signed-off-by: "Yann E. MORIN" <yann.morin.1998 at free.fr>
+Reviewed-by: Andreas Färber <afaerber at suse.de>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit e84d5956cc6215d2f098e7b6090fc5ec4cba1be3)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configure b/configure
+index dcd8e7b..9e53cc2 100755
+--- a/configure
++++ b/configure
+@@ -1405,10 +1405,10 @@ if test "$seccomp" != "no" ; then
+         LIBS=`$pkg_config --libs libseccomp`
+ 	seccomp="yes"
+     else
+-	seccomp="no"
+ 	if test "$seccomp" = "yes"; then
+             feature_not_found "libseccomp"
+ 	fi
++	seccomp="no"
+     fi
+ fi
+ ##########################################
+-- 
+1.7.12.1
+
diff --git a/0200-configure-properly-check-if-lrt-and-lm-is-needed.patch b/0200-configure-properly-check-if-lrt-and-lm-is-needed.patch
new file mode 100644
index 0000000..2e9a949
--- /dev/null
+++ b/0200-configure-properly-check-if-lrt-and-lm-is-needed.patch
@@ -0,0 +1,80 @@
+From 39b2ed0e73ac5b220accf7116bdaecb71ce759af Mon Sep 17 00:00:00 2001
+From: Natanael Copa <natanael.copa at gmail.com>
+Date: Wed, 12 Sep 2012 09:06:51 +0000
+Subject: [PATCH] configure: properly check if -lrt and -lm is needed
+
+Fixes build against uClibc.
+
+uClibc provides 2 versions of clock_gettime(), one with realtime
+support and one without (this is so you can avoid linking in -lrt
+unless actually needed). This means that the clock_gettime() don't
+need -lrt. We still need it for timer_create() so we check for this
+function in addition.
+
+We also need check if -lm is needed for isnan().
+
+Both -lm and -lrt are needed for libs_qga.
+
+Signed-off-by: Natanael Copa <ncopa at alpinelinux.org>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+(cherry picked from commit 8bacde8d86a09699207d85d4bab06162aed18dc4)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ configure | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/configure b/configure
+index 9e53cc2..a1f256c 100755
+--- a/configure
++++ b/configure
+@@ -2645,17 +2645,44 @@ fi
+ 
+ 
+ ##########################################
++# Do we need libm
++cat > $TMPC << EOF
++#include <math.h>
++int main(void) { return isnan(sin(0.0)); }
++EOF
++if compile_prog "" "" ; then
++  :
++elif compile_prog "" "-lm" ; then
++  LIBS="-lm $LIBS"
++  libs_qga="-lm $libs_qga"
++else
++  echo
++  echo "Error: libm check failed"
++  echo
++  exit 1
++fi
++
++##########################################
+ # Do we need librt
++# uClibc provides 2 versions of clock_gettime(), one with realtime
++# support and one without. This means that the clock_gettime() don't
++# need -lrt. We still need it for timer_create() so we check for this
++# function in addition.
+ cat > $TMPC <<EOF
+ #include <signal.h>
+ #include <time.h>
+-int main(void) { return clock_gettime(CLOCK_REALTIME, NULL); }
++int main(void) {
++  timer_create(CLOCK_REALTIME, NULL, NULL);
++  return clock_gettime(CLOCK_REALTIME, NULL);
++}
+ EOF
+ 
+ if compile_prog "" "" ; then
+   :
+-elif compile_prog "" "-lrt" ; then
++# we need pthread for static linking. use previous pthread test result
++elif compile_prog "" "-lrt $pthread_lib" ; then
+   LIBS="-lrt $LIBS"
++  libs_qga="-lrt $libs_qga"
+ fi
+ 
+ if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
+-- 
+1.7.12.1
+
diff --git a/0201-Revert-455aa1e08-and-c3767ed0eb.patch b/0201-Revert-455aa1e08-and-c3767ed0eb.patch
new file mode 100644
index 0000000..5466652
--- /dev/null
+++ b/0201-Revert-455aa1e08-and-c3767ed0eb.patch
@@ -0,0 +1,51 @@
+From 423df48a1277f20511f21f4d249ea977aa4fa721 Mon Sep 17 00:00:00 2001
+From: Anthony Liguori <aliguori at us.ibm.com>
+Date: Wed, 12 Sep 2012 14:34:07 -0500
+Subject: [PATCH] Revert 455aa1e08 and c3767ed0eb
+
+    commit c3767ed0eb5d0bb25fe409ae5dec06e3411ff1b6
+    qemu-char: (Re-)connect for tcp_chr_write() unconnected writing
+
+Has no hope of working because tcp_chr_connect() does not actually connect.
+
+455aa1e08 just fixes the SEGV with server() but the attempt to connect a client
+socket is still completely broken.
+
+This patch reverts both.
+
+Reported-by: Richard W.M. Jones <rjones at redhat.com>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit 6db0fdce02d72546a4c47100a9b2cd0090cf464d)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ qemu-char.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+diff --git a/qemu-char.c b/qemu-char.c
+index 767da93..10d1504 100644
+--- a/qemu-char.c
++++ b/qemu-char.c
+@@ -2141,18 +2141,13 @@ typedef struct {
+ 
+ static void tcp_chr_accept(void *opaque);
+ 
+-static void tcp_chr_connect(void *opaque);
+-
+ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+ {
+     TCPCharDriver *s = chr->opaque;
+     if (s->connected) {
+         return send_all(s->fd, buf, len);
+-    } else if (s->listen_fd == -1) {
+-        /* (Re-)connect for unconnected writing */
+-        tcp_chr_connect(chr);
+-        return 0;
+     } else {
++        /* XXX: indicate an error ? */
+         return len;
+     }
+ }
+-- 
+1.7.12.1
+
diff --git a/0202-qemu-char-BUGFIX-don-t-call-FD_ISSET-with-negative-f.patch b/0202-qemu-char-BUGFIX-don-t-call-FD_ISSET-with-negative-f.patch
new file mode 100644
index 0000000..74f8f39
--- /dev/null
+++ b/0202-qemu-char-BUGFIX-don-t-call-FD_ISSET-with-negative-f.patch
@@ -0,0 +1,59 @@
+From 04eefabaae59ad624f0baf3b97a1d1d15cf2a23d Mon Sep 17 00:00:00 2001
+From: David Gibson <david at gibson.dropbear.id.au>
+Date: Mon, 10 Sep 2012 12:30:56 +1000
+Subject: [PATCH] qemu-char: BUGFIX, don't call FD_ISSET with negative fd
+
+tcp_chr_connect(), unlike for example udp_chr_update_read_handler() does
+not check if the fd it is using is valid (>= 0) before passing it to
+qemu_set_fd_handler2().  If using e.g. a TCP serial port, which is not
+initially connected, this can result in -1 being passed to FD_ISSET, which
+has undefined behaviour.  On x86 it seems to harmlessly return 0, but on
+PowerPC, it causes a fortify buffer overflow error to be thrown.
+
+This patch fixes this by putting an extra test in tcp_chr_connect(), and
+also adds an assert qemu_set_fd_handler2() to catch other such errors on
+all platforms, rather than just some.
+
+Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit bbdd2ad0814ea0911076419ea21b7957505cf1cc)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ iohandler.c | 2 ++
+ qemu-char.c | 6 ++++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/iohandler.c b/iohandler.c
+index dea4355..a2d871b 100644
+--- a/iohandler.c
++++ b/iohandler.c
+@@ -56,6 +56,8 @@ int qemu_set_fd_handler2(int fd,
+ {
+     IOHandlerRecord *ioh;
+ 
++    assert(fd >= 0);
++
+     if (!fd_read && !fd_write) {
+         QLIST_FOREACH(ioh, &io_handlers, next) {
+             if (ioh->fd == fd) {
+diff --git a/qemu-char.c b/qemu-char.c
+index 10d1504..7f0f895 100644
+--- a/qemu-char.c
++++ b/qemu-char.c
+@@ -2329,8 +2329,10 @@ static void tcp_chr_connect(void *opaque)
+     TCPCharDriver *s = chr->opaque;
+ 
+     s->connected = 1;
+-    qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
+-                         tcp_chr_read, NULL, chr);
++    if (s->fd >= 0) {
++        qemu_set_fd_handler2(s->fd, tcp_chr_read_poll,
++                             tcp_chr_read, NULL, chr);
++    }
+     qemu_chr_generic_open(chr);
+ }
+ 
+-- 
+1.7.12.1
+
diff --git a/0203-cpu_physical_memory_write_rom-needs-to-do-TB-invalid.patch b/0203-cpu_physical_memory_write_rom-needs-to-do-TB-invalid.patch
new file mode 100644
index 0000000..cceb39c
--- /dev/null
+++ b/0203-cpu_physical_memory_write_rom-needs-to-do-TB-invalid.patch
@@ -0,0 +1,52 @@
+From 897815f54c446671cae0f202c54e9548e969d427 Mon Sep 17 00:00:00 2001
+From: David Gibson <david at gibson.dropbear.id.au>
+Date: Mon, 10 Sep 2012 12:30:57 +1000
+Subject: [PATCH] cpu_physical_memory_write_rom() needs to do TB invalidates
+
+cpu_physical_memory_write_rom(), despite the name, can also be used to
+write images into RAM - and will often be used that way if the machine
+uses load_image_targphys() into RAM addresses.
+
+However, cpu_physical_memory_write_rom(), unlike cpu_physical_memory_rw()
+doesn't invalidate any cached TBs which might be affected by the region
+written.
+
+This was breaking reset (under full emu) on the pseries machine - we loaded
+our firmware image into RAM, and while executing it rewrite the code at
+the entry point (correctly causing a TB invalidate/refresh).  When we
+reset the firmware image was reloaded, but the TB from the rewrite was
+still active and caused us to get an illegal instruction trap.
+
+This patch fixes the bug by duplicating the tb invalidate code from
+cpu_physical_memory_rw() in cpu_physical_memory_write_rom().
+
+Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit 0b57e287138728f72d88b06e69b970c5d745c44a)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ exec.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/exec.c b/exec.c
+index ad175db..3fdbbde 100644
+--- a/exec.c
++++ b/exec.c
+@@ -3521,6 +3521,13 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
+             /* ROM/RAM case */
+             ptr = qemu_get_ram_ptr(addr1);
+             memcpy(ptr, buf, l);
++            if (!cpu_physical_memory_is_dirty(addr1)) {
++                /* invalidate code */
++                tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
++                /* set dirty bit */
++                cpu_physical_memory_set_dirty_flags(
++                    addr1, (0xff & ~CODE_DIRTY_FLAG));
++            }
+             qemu_put_ram_ptr(ptr);
+         }
+         len -= l;
+-- 
+1.7.12.1
+
diff --git a/0204-arch_init.c-Improve-soundhw-help-for-non-HAS_AUDIO_C.patch b/0204-arch_init.c-Improve-soundhw-help-for-non-HAS_AUDIO_C.patch
new file mode 100644
index 0000000..d9001a5
--- /dev/null
+++ b/0204-arch_init.c-Improve-soundhw-help-for-non-HAS_AUDIO_C.patch
@@ -0,0 +1,43 @@
+From 8daf993d3d75acea92ef5054c924c7d825ae812e Mon Sep 17 00:00:00 2001
+From: Peter Maydell <peter.maydell at linaro.org>
+Date: Wed, 19 Sep 2012 14:51:38 +0100
+Subject: [PATCH] arch_init.c: Improve '-soundhw help' for
+ non-HAS_AUDIO_CHOICE archs
+
+For architectures which don't set HAS_AUDIO_CHOICE, improve the
+'-soundhw help' message so that it doesn't simply print an empty
+list, implying no sound support at all.
+
+Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: malc <av1474 at comtv.ru>
+(cherry picked from commit 55d4fd3c24bd253bd96270c7fdf1bb862f3a3400)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ arch_init.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/arch_init.c b/arch_init.c
+index 47977de..f849f9b 100644
+--- a/arch_init.c
++++ b/arch_init.c
+@@ -922,11 +922,16 @@ void select_soundhw(const char *optarg)
+     if (is_help_option(optarg)) {
+     show_valid_cards:
+ 
++#ifdef HAS_AUDIO_CHOICE
+         printf("Valid sound card names (comma separated):\n");
+         for (c = soundhw; c->name; ++c) {
+             printf ("%-11s %s\n", c->name, c->descr);
+         }
+         printf("\n-soundhw all will enable all of the above\n");
++#else
++        printf("Machine has no user-selectable audio hardware "
++               "(it may or may not have always-present audio hardware).\n");
++#endif
+         exit(!is_help_option(optarg));
+     }
+     else {
+-- 
+1.7.12.1
+
diff --git a/0205-xilinx_timer-Removed-comma-in-device-name.patch b/0205-xilinx_timer-Removed-comma-in-device-name.patch
new file mode 100644
index 0000000..26b5d66
--- /dev/null
+++ b/0205-xilinx_timer-Removed-comma-in-device-name.patch
@@ -0,0 +1,54 @@
+From 030d44c473036d44abc76562860a89b21220ca2f Mon Sep 17 00:00:00 2001
+From: "Peter A. G. Crosthwaite" <peter.crosthwaite at petalogix.com>
+Date: Thu, 28 Jun 2012 12:52:23 +1000
+Subject: [PATCH] xilinx_timer: Removed comma in device name
+
+Fixes an error in a61e4b07a30c062260d2d01771773f14820d1eb7
+
+Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
+(cherry picked from commit c0a1dcb9f0baf9269f8baeb02cbcca8dad75454c)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/xilinx.h       | 2 +-
+ hw/xilinx_timer.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/hw/xilinx.h b/hw/xilinx.h
+index 556c5aa..df06a00 100644
+--- a/hw/xilinx.h
++++ b/hw/xilinx.h
+@@ -21,7 +21,7 @@ xilinx_timer_create(target_phys_addr_t base, qemu_irq irq, int oto, int freq)
+ {
+     DeviceState *dev;
+ 
+-    dev = qdev_create(NULL, "xlnx,xps-timer");
++    dev = qdev_create(NULL, "xlnx.xps-timer");
+     qdev_prop_set_uint32(dev, "one-timer-only", oto);
+     qdev_prop_set_uint32(dev, "frequency", freq);
+     qdev_init_nofail(dev);
+diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
+index b562bd0..053ba02 100644
+--- a/hw/xilinx_timer.c
++++ b/hw/xilinx_timer.c
+@@ -217,7 +217,7 @@ static int xilinx_timer_init(SysBusDevice *dev)
+         ptimer_set_freq(xt->ptimer, t->freq_hz);
+     }
+ 
+-    memory_region_init_io(&t->mmio, &timer_ops, t, "xlnx,xps-timer",
++    memory_region_init_io(&t->mmio, &timer_ops, t, "xlnx.xps-timer",
+                           R_MAX * 4 * num_timers(t));
+     sysbus_init_mmio(dev, &t->mmio);
+     return 0;
+@@ -239,7 +239,7 @@ static void xilinx_timer_class_init(ObjectClass *klass, void *data)
+ }
+ 
+ static TypeInfo xilinx_timer_info = {
+-    .name          = "xlnx,xps-timer",
++    .name          = "xlnx.xps-timer",
+     .parent        = TYPE_SYS_BUS_DEVICE,
+     .instance_size = sizeof(struct timerblock),
+     .class_init    = xilinx_timer_class_init,
+-- 
+1.7.12.1
+
diff --git a/0206-xilinx_timer-Send-dbg-msgs-to-stderr-not-stdout.patch b/0206-xilinx_timer-Send-dbg-msgs-to-stderr-not-stdout.patch
new file mode 100644
index 0000000..e7b8ea1
--- /dev/null
+++ b/0206-xilinx_timer-Send-dbg-msgs-to-stderr-not-stdout.patch
@@ -0,0 +1,56 @@
+From c03bf619fe8eb416aaea1f8b75b313a4b314ffeb Mon Sep 17 00:00:00 2001
+From: "Peter A. G. Crosthwaite" <peter.crosthwaite at petalogix.com>
+Date: Thu, 28 Jun 2012 16:28:03 +1000
+Subject: [PATCH] xilinx_timer: Send dbg msgs to stderr not stdout
+
+Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
+(cherry picked from commit e03377ae75808d33d0a7afc803b37bcda9f796b3)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/xilinx_timer.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
+index 053ba02..c02e6ca 100644
+--- a/hw/xilinx_timer.c
++++ b/hw/xilinx_timer.c
+@@ -119,7 +119,7 @@ timer_read(void *opaque, target_phys_addr_t addr, unsigned int size)
+             break;
+ 
+     }
+-    D(printf("%s timer=%d %x=%x\n", __func__, timer, addr * 4, r));
++    D(fprintf(stderr, "%s timer=%d %x=%x\n", __func__, timer, addr * 4, r));
+     return r;
+ }
+ 
+@@ -127,7 +127,7 @@ static void timer_enable(struct xlx_timer *xt)
+ {
+     uint64_t count;
+ 
+-    D(printf("%s timer=%d down=%d\n", __func__,
++    D(fprintf(stderr, "%s timer=%d down=%d\n", __func__,
+               xt->nr, xt->regs[R_TCSR] & TCSR_UDT));
+ 
+     ptimer_stop(xt->ptimer);
+@@ -152,7 +152,7 @@ timer_write(void *opaque, target_phys_addr_t addr,
+     addr >>= 2;
+     timer = timer_from_addr(addr);
+     xt = &t->timers[timer];
+-    D(printf("%s addr=%x val=%x (timer=%d off=%d)\n",
++    D(fprintf(stderr, "%s addr=%x val=%x (timer=%d off=%d)\n",
+              __func__, addr * 4, value, timer, addr & 3));
+     /* Further decoding to address a specific timers reg.  */
+     addr &= 3;
+@@ -189,7 +189,7 @@ static void timer_hit(void *opaque)
+ {
+     struct xlx_timer *xt = opaque;
+     struct timerblock *t = xt->parent;
+-    D(printf("%s %d\n", __func__, timer));
++    D(fprintf(stderr, "%s %d\n", __func__, timer));
+     xt->regs[R_TCSR] |= TCSR_TINT;
+ 
+     if (xt->regs[R_TCSR] & TCSR_ARHT)
+-- 
+1.7.12.1
+
diff --git a/0207-xilinx.h-Error-check-when-setting-links.patch b/0207-xilinx.h-Error-check-when-setting-links.patch
new file mode 100644
index 0000000..924d91f
--- /dev/null
+++ b/0207-xilinx.h-Error-check-when-setting-links.patch
@@ -0,0 +1,54 @@
+From bfec52da020f35304f4e059bf4725fe01dbdd154 Mon Sep 17 00:00:00 2001
+From: "Peter A. G. Crosthwaite" <peter.crosthwaite at petalogix.com>
+Date: Mon, 17 Sep 2012 13:41:39 +1000
+Subject: [PATCH] xilinx.h: Error check when setting links
+
+Assert that the ethernet and dma controller are sucessfully linked to their
+peers.
+
+Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
+(cherry picked from commit 4b5e52101f9ad077d1c016f2b7130e2fdae6d2da)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/xilinx.h | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/hw/xilinx.h b/hw/xilinx.h
+index df06a00..35d6681 100644
+--- a/hw/xilinx.h
++++ b/hw/xilinx.h
+@@ -55,13 +55,16 @@ xilinx_axiethernet_create(NICInfo *nd, StreamSlave *peer,
+                           int txmem, int rxmem)
+ {
+     DeviceState *dev;
++    Error *errp = NULL;
++
+     qemu_check_nic_model(nd, "xlnx.axi-ethernet");
+ 
+     dev = qdev_create(NULL, "xlnx.axi-ethernet");
+     qdev_set_nic_properties(dev, nd);
+     qdev_prop_set_uint32(dev, "rxmem", rxmem);
+     qdev_prop_set_uint32(dev, "txmem", txmem);
+-    object_property_set_link(OBJECT(dev), OBJECT(peer), "tx_dev", NULL);
++    object_property_set_link(OBJECT(dev), OBJECT(peer), "tx_dev", &errp);
++    assert_no_error(errp);
+     qdev_init_nofail(dev);
+     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+     sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
+@@ -74,8 +77,11 @@ xilinx_axiethernetdma_init(DeviceState *dev, StreamSlave *peer,
+                            target_phys_addr_t base, qemu_irq irq,
+                            qemu_irq irq2, int freqhz)
+ {
++    Error *errp = NULL;
++
+     qdev_prop_set_uint32(dev, "freqhz", freqhz);
+-    object_property_set_link(OBJECT(dev), OBJECT(peer), "tx_dev", NULL);
++    object_property_set_link(OBJECT(dev), OBJECT(peer), "tx_dev", &errp);
++    assert_no_error(errp);
+     qdev_init_nofail(dev);
+ 
+     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+-- 
+1.7.12.1
+
diff --git a/0208-xilinx_timer-Fix-a-compile-error-if-debug-enabled.patch b/0208-xilinx_timer-Fix-a-compile-error-if-debug-enabled.patch
new file mode 100644
index 0000000..7c084bf
--- /dev/null
+++ b/0208-xilinx_timer-Fix-a-compile-error-if-debug-enabled.patch
@@ -0,0 +1,41 @@
+From 593883a749b0659ab4a2f2d96e65c34a3bd0fcca Mon Sep 17 00:00:00 2001
+From: Chris Wulff <crwulff at gmail.com>
+Date: Sun, 9 Sep 2012 20:20:07 -0400
+Subject: [PATCH] xilinx_timer: Fix a compile error if debug enabled
+
+There was a missing include of qemu-log and a variable name in a printf was out
+of date.
+
+Signed-off-by: Chris Wulff <crwulff at gmail.com>
+Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
+(cherry picked from commit 8354cd722e0afae63bee3e4cb21c8f0ddb6874c2)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/xilinx_timer.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
+index c02e6ca..f410487 100644
+--- a/hw/xilinx_timer.c
++++ b/hw/xilinx_timer.c
+@@ -24,6 +24,7 @@
+ 
+ #include "sysbus.h"
+ #include "ptimer.h"
++#include "qemu-log.h"
+ 
+ #define D(x)
+ 
+@@ -189,7 +190,7 @@ static void timer_hit(void *opaque)
+ {
+     struct xlx_timer *xt = opaque;
+     struct timerblock *t = xt->parent;
+-    D(fprintf(stderr, "%s %d\n", __func__, timer));
++    D(fprintf(stderr, "%s %d\n", __func__, xt->nr));
+     xt->regs[R_TCSR] |= TCSR_TINT;
+ 
+     if (xt->regs[R_TCSR] & TCSR_ARHT)
+-- 
+1.7.12.1
+
diff --git a/0209-pflash_cfi01-fix-vendor-specific-extended-query.patch b/0209-pflash_cfi01-fix-vendor-specific-extended-query.patch
new file mode 100644
index 0000000..40c0e51
--- /dev/null
+++ b/0209-pflash_cfi01-fix-vendor-specific-extended-query.patch
@@ -0,0 +1,49 @@
+From a53ed08e1f8ee2a235213e802f3d5bb3342adaf3 Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Mon, 3 Sep 2012 22:47:03 +0200
+Subject: [PATCH] pflash_cfi01: fix vendor specific extended query
+
+pflash_cfi01 announces a version number of 1.1, which implies
+"Protection Register Information" and "Burst Read information"
+sections, which are not provided.
+
+Decrease the version number to 1.0 so that only the "Protection
+Register Information" section is needed.
+
+Set the number of protection fields (0x3f) to 0x01, as 0x00 means 256
+protections field, which makes the CFI table bigger than the current
+implementation, causing some kernels to fail to read it.
+
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+(cherry picked from commit 262e1eaafabf32d33a9fa0b03b3c8ea426c5ae1b)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/pflash_cfi01.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
+index d1c7423..d56b51a 100644
+--- a/hw/pflash_cfi01.c
++++ b/hw/pflash_cfi01.c
+@@ -711,7 +711,7 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base,
+     pfl->cfi_table[0x33] = 'I';
+ 
+     pfl->cfi_table[0x34] = '1';
+-    pfl->cfi_table[0x35] = '1';
++    pfl->cfi_table[0x35] = '0';
+ 
+     pfl->cfi_table[0x36] = 0x00;
+     pfl->cfi_table[0x37] = 0x00;
+@@ -723,6 +723,8 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base,
+     pfl->cfi_table[0x3b] = 0x00;
+     pfl->cfi_table[0x3c] = 0x00;
+ 
++    pfl->cfi_table[0x3f] = 0x01; /* Number of protection fields */
++
+     return pfl;
+ }
+ 
+-- 
+1.7.12.1
+
diff --git a/0210-MAINTAINERS-Add-entry-for-QOM-CPU.patch b/0210-MAINTAINERS-Add-entry-for-QOM-CPU.patch
new file mode 100644
index 0000000..17385e6
--- /dev/null
+++ b/0210-MAINTAINERS-Add-entry-for-QOM-CPU.patch
@@ -0,0 +1,36 @@
+From a003aac48bda87a443bb312f478fb651e34998e5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Andreas=20F=C3=A4rber?= <afaerber at suse.de>
+Date: Mon, 17 Sep 2012 19:10:32 +0200
+Subject: [PATCH] MAINTAINERS: Add entry for QOM CPU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Andreas Färber <afaerber at suse.de>
+(cherry picked from commit f2ca052414d7eddc10517e98a5a27ba8099b19b1)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ MAINTAINERS | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 61f8b45..25733fc 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -531,6 +531,12 @@ M: Anthony Liguori <aliguori at us.ibm.com>
+ S: Maintained
+ F: qemu-char.c
+ 
++CPU
++M: Andreas Färber <afaerber at suse.de>
++S: Supported
++F: qom/cpu.c
++F: include/qemu/cpu.h
++
+ Device Tree
+ M: Peter Crosthwaite <peter.crosthwaite at petalogix.com>
+ M: Alexander Graf <agraf at suse.de>
+-- 
+1.7.12.1
+
diff --git a/0211-iSCSI-We-need-to-support-SG_IO-also-from-iscsi_ioctl.patch b/0211-iSCSI-We-need-to-support-SG_IO-also-from-iscsi_ioctl.patch
new file mode 100644
index 0000000..856ed96
--- /dev/null
+++ b/0211-iSCSI-We-need-to-support-SG_IO-also-from-iscsi_ioctl.patch
@@ -0,0 +1,59 @@
+From 76fcbe46a52b467cd2cd96a671bfccd26871153e Mon Sep 17 00:00:00 2001
+From: Ronnie Sahlberg <ronniesahlberg at gmail.com>
+Date: Thu, 30 Aug 2012 17:28:40 -0700
+Subject: [PATCH] iSCSI: We need to support SG_IO also from iscsi_ioctl()
+
+We need to support SG_IO from the synchronous iscsi_ioctl() since
+scsi-block uses this to do an INQ to the device to discover its properties
+This patch makes scsi-block work with iscsi.
+
+Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+(cherry picked from commit f1a12821d7df2e4d21be4f2206f84b4640533e53)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ block/iscsi.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/block/iscsi.c b/block/iscsi.c
+index 0b96165..ea16609 100644
+--- a/block/iscsi.c
++++ b/block/iscsi.c
+@@ -628,9 +628,17 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
+     return &acb->common;
+ }
+ 
++
++static void ioctl_cb(void *opaque, int status)
++{
++    int *p_status = opaque;
++    *p_status = status;
++}
++
+ static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
+ {
+     IscsiLun *iscsilun = bs->opaque;
++    int status;
+ 
+     switch (req) {
+     case SG_GET_VERSION_NUM:
+@@ -639,6 +647,15 @@ static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
+     case SG_GET_SCSI_ID:
+         ((struct sg_scsi_id *)buf)->scsi_type = iscsilun->type;
+         break;
++    case SG_IO:
++        status = -EINPROGRESS;
++        iscsi_aio_ioctl(bs, req, buf, ioctl_cb, &status);
++
++        while (status == -EINPROGRESS) {
++            qemu_aio_wait();
++        }
++
++        return 0;
+     default:
+         return -1;
+     }
+-- 
+1.7.12.1
+
diff --git a/0212-iSCSI-We-dont-need-to-explicitely-call-qemu_notify_e.patch b/0212-iSCSI-We-dont-need-to-explicitely-call-qemu_notify_e.patch
new file mode 100644
index 0000000..d2d4b2d
--- /dev/null
+++ b/0212-iSCSI-We-dont-need-to-explicitely-call-qemu_notify_e.patch
@@ -0,0 +1,39 @@
+From 05bfce1ee580c715dc3d220297b05097bdd007d2 Mon Sep 17 00:00:00 2001
+From: Ronnie Sahlberg <ronniesahlberg at gmail.com>
+Date: Thu, 30 Aug 2012 16:56:36 -0700
+Subject: [PATCH] iSCSI: We dont need to explicitely call qemu_notify_event()
+ any more
+
+We no longer need to explicitely call qemu_notify_event() any more
+since this is now done automatically any time the filehandles we listen
+to change.
+
+Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+(cherry picked from commit 40a13ca8d28c21062e35b10d9b80e76b92405bdf)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ block/iscsi.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/block/iscsi.c b/block/iscsi.c
+index ea16609..fb001b9 100644
+--- a/block/iscsi.c
++++ b/block/iscsi.c
+@@ -167,12 +167,6 @@ iscsi_set_events(IscsiLun *iscsilun)
+ 
+     }
+ 
+-    /* If we just added an event, the callback might be delayed
+-     * unless we call qemu_notify_event().
+-     */
+-    if (ev & ~iscsilun->events) {
+-        qemu_notify_event();
+-    }
+     iscsilun->events = ev;
+ }
+ 
+-- 
+1.7.12.1
+
diff --git a/0213-scsi-disk-introduce-check_lba_range.patch b/0213-scsi-disk-introduce-check_lba_range.patch
new file mode 100644
index 0000000..567728d
--- /dev/null
+++ b/0213-scsi-disk-introduce-check_lba_range.patch
@@ -0,0 +1,82 @@
+From dd43bce420668dcde639c55bc792cedb1bb8c950 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini at redhat.com>
+Date: Wed, 5 Sep 2012 17:46:18 +0200
+Subject: [PATCH] scsi-disk: introduce check_lba_range
+
+Abstract the test for an out-of-range (starting block, block count)
+pair.
+
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+(cherry picked from commit 444bc908611ccaf4512dc37c33ac3b54d873a62b)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/scsi-disk.c | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
+index 1585683..3959603 100644
+--- a/hw/scsi-disk.c
++++ b/hw/scsi-disk.c
+@@ -1449,6 +1449,18 @@ invalid_field:
+     return;
+ }
+ 
++static inline bool check_lba_range(SCSIDiskState *s,
++                                   uint64_t sector_num, uint32_t nb_sectors)
++{
++    /*
++     * The first line tests that no overflow happens when computing the last
++     * sector.  The second line tests that the last accessed sector is in
++     * range.
++     */
++    return (sector_num <= sector_num + nb_sectors &&
++            sector_num + nb_sectors - 1 <= s->qdev.max_lba);
++}
++
+ typedef struct UnmapCBData {
+     SCSIDiskReq *r;
+     uint8_t *inbuf;
+@@ -1473,8 +1485,7 @@ static void scsi_unmap_complete(void *opaque, int ret)
+     if (data->count > 0 && !r->req.io_canceled) {
+         sector_num = ldq_be_p(&data->inbuf[0]);
+         nb_sectors = ldl_be_p(&data->inbuf[8]) & 0xffffffffULL;
+-        if (sector_num > sector_num + nb_sectors ||
+-            sector_num + nb_sectors - 1 > s->qdev.max_lba) {
++        if (!check_lba_range(s, sector_num, nb_sectors)) {
+             scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
+             goto done;
+         }
+@@ -1802,8 +1813,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
+             scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
+             return 0;
+         }
+-        if (r->req.cmd.lba > r->req.cmd.lba + nb_sectors ||
+-            r->req.cmd.lba + nb_sectors - 1 > s->qdev.max_lba) {
++        if (!check_lba_range(s, r->req.cmd.lba, nb_sectors)) {
+             goto illegal_lba;
+         }
+ 
+@@ -1878,8 +1888,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
+         if (r->req.cmd.buf[1] & 0xe0) {
+             goto illegal_request;
+         }
+-        if (r->req.cmd.lba > r->req.cmd.lba + len ||
+-            r->req.cmd.lba + len - 1 > s->qdev.max_lba) {
++        if (!check_lba_range(s, r->req.cmd.lba, len)) {
+             goto illegal_lba;
+         }
+         r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
+@@ -1907,8 +1916,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
+         if (r->req.cmd.buf[1] & 0xe0) {
+             goto illegal_request;
+         }
+-        if (r->req.cmd.lba > r->req.cmd.lba + len ||
+-            r->req.cmd.lba + len - 1 > s->qdev.max_lba) {
++        if (!check_lba_range(s, r->req.cmd.lba, len)) {
+             goto illegal_lba;
+         }
+         r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
+-- 
+1.7.12.1
+
diff --git a/0214-scsi-disk-fix-check-for-out-of-range-LBA.patch b/0214-scsi-disk-fix-check-for-out-of-range-LBA.patch
new file mode 100644
index 0000000..9deef86
--- /dev/null
+++ b/0214-scsi-disk-fix-check-for-out-of-range-LBA.patch
@@ -0,0 +1,38 @@
+From 2fd88dcb7fdb90508a85c30a32516ff57f081cba Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini at redhat.com>
+Date: Wed, 5 Sep 2012 17:54:36 +0200
+Subject: [PATCH] scsi-disk: fix check for out-of-range LBA
+
+This fix is needed to correctly handle 0-block read and writes.
+Without it, a 0-block access at LBA 0 would underflow.
+
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+(cherry picked from commit 12ca76fc48081b3a0ad1a70546abfcf198aedfc4)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/scsi-disk.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
+index 3959603..d621852 100644
+--- a/hw/scsi-disk.c
++++ b/hw/scsi-disk.c
+@@ -1456,9 +1456,13 @@ static inline bool check_lba_range(SCSIDiskState *s,
+      * The first line tests that no overflow happens when computing the last
+      * sector.  The second line tests that the last accessed sector is in
+      * range.
++     *
++     * Careful, the computations should not underflow for nb_sectors == 0,
++     * and a 0-block read to the first LBA beyond the end of device is
++     * valid.
+      */
+     return (sector_num <= sector_num + nb_sectors &&
+-            sector_num + nb_sectors - 1 <= s->qdev.max_lba);
++            sector_num + nb_sectors <= s->qdev.max_lba + 1);
+ }
+ 
+ typedef struct UnmapCBData {
+-- 
+1.7.12.1
+
diff --git a/0215-SCSI-Standard-INQUIRY-data-should-report-HiSup-flag-.patch b/0215-SCSI-Standard-INQUIRY-data-should-report-HiSup-flag-.patch
new file mode 100644
index 0000000..840be83
--- /dev/null
+++ b/0215-SCSI-Standard-INQUIRY-data-should-report-HiSup-flag-.patch
@@ -0,0 +1,43 @@
+From 8444d4c996120a2fc21547a784c258e639f1e8fb Mon Sep 17 00:00:00 2001
+From: Ronnie Sahlberg <ronniesahlberg at gmail.com>
+Date: Fri, 14 Sep 2012 18:13:29 -0700
+Subject: [PATCH] SCSI: Standard INQUIRY data should report HiSup flag as set.
+
+QEMU as far as I know only reports LUN numbers using the modes that
+are described in SAM4.
+As such, since all LUN numbers generated by the SCSI emulation in QEMU
+follow SAM4, we should set the HiSup bit in the standard INQUIRY data
+to indicate such.
+
+From SAM4:
+  4.6.3 LUNs overview
+  All LUN formats described in this standard are hierarchical in
+  structure even when only a single level in that hierarchy is used.
+  The HISUP bit shall be set to one in the standard INQUIRY data
+  (see SPC-4) when any LUN format described in this standard is used.
+  Non-hierarchical formats are outside the scope of this standard.
+
+Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
+(cherry picked from commit 1109c894052751df99962c009fd7dbae397721f5)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/scsi-disk.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
+index d621852..7ed1bde 100644
+--- a/hw/scsi-disk.c
++++ b/hw/scsi-disk.c
+@@ -678,7 +678,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
+      * is actually implemented, but we're good enough.
+      */
+     outbuf[2] = 5;
+-    outbuf[3] = 2; /* Format 2 */
++    outbuf[3] = 2 | 0x10; /* Format 2, HiSup */
+ 
+     if (buflen > 36) {
+         outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
+-- 
+1.7.12.1
+
diff --git a/0216-audio-Fix-warning-from-static-code-analysis.patch b/0216-audio-Fix-warning-from-static-code-analysis.patch
new file mode 100644
index 0000000..d25383c
--- /dev/null
+++ b/0216-audio-Fix-warning-from-static-code-analysis.patch
@@ -0,0 +1,47 @@
+From eb26fee60bcc7b1191395c21f41c22e5e4f24182 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Mon, 3 Sep 2012 09:25:16 +0000
+Subject: [PATCH] audio: Fix warning from static code analysis
+
+smatch report:
+audio/audio_template.h:416 AUD_open_out(18) warn:
+ variable dereferenced before check 'as' (see line 414)
+
+Moving the ldebug statement after the statement which checks 'as'
+fixes that warning.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: malc <av1474 at comtv.ru>
+(cherry picked from commit 93b6599734f81328ee3d608f57667742cafeea72)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ audio/audio_template.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/audio/audio_template.h b/audio/audio_template.h
+index 519432a..16f7880 100644
+--- a/audio/audio_template.h
++++ b/audio/audio_template.h
+@@ -410,15 +410,15 @@ SW *glue (AUD_open_, TYPE) (
+     SW *old_sw = NULL;
+ #endif
+ 
+-    ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
+-            name, as->freq, as->nchannels, as->fmt);
+-
+     if (audio_bug (AUDIO_FUNC, !card || !name || !callback_fn || !as)) {
+         dolog ("card=%p name=%p callback_fn=%p as=%p\n",
+                card, name, callback_fn, as);
+         goto fail;
+     }
+ 
++    ldebug ("open %s, freq %d, nchannels %d, fmt %d\n",
++            name, as->freq, as->nchannels, as->fmt);
++
+     if (audio_bug (AUDIO_FUNC, audio_validate_settings (as))) {
+         audio_print_settings (as);
+         goto fail;
+-- 
+1.7.12.1
+
diff --git a/0217-qemu-ga-Remove-unreachable-code-after-g_error.patch b/0217-qemu-ga-Remove-unreachable-code-after-g_error.patch
new file mode 100644
index 0000000..5b64003
--- /dev/null
+++ b/0217-qemu-ga-Remove-unreachable-code-after-g_error.patch
@@ -0,0 +1,40 @@
+From 631ea4153ed0e1dc8688c463e0924b0dd8dc7ea5 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Sat, 1 Sep 2012 09:34:15 +0200
+Subject: [PATCH] qemu-ga: Remove unreachable code after g_error
+
+Report from smatch:
+qemu-ga.c:117 register_signal_handlers(11) info: ignoring unreachable code.
+qemu-ga.c:122 register_signal_handlers(16) info: ignoring unreachable code.
+
+g_error calls abort which terminates the program.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit b548828862d3bf7214b7ef9cb361356b153b89c9)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ qemu-ga.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/qemu-ga.c b/qemu-ga.c
+index 7623079..b747470 100644
+--- a/qemu-ga.c
++++ b/qemu-ga.c
+@@ -114,12 +114,10 @@ static gboolean register_signal_handlers(void)
+     ret = sigaction(SIGINT, &sigact, NULL);
+     if (ret == -1) {
+         g_error("error configuring signal handler: %s", strerror(errno));
+-        return false;
+     }
+     ret = sigaction(SIGTERM, &sigact, NULL);
+     if (ret == -1) {
+         g_error("error configuring signal handler: %s", strerror(errno));
+-        return false;
+     }
+ 
+     return true;
+-- 
+1.7.12.1
+
diff --git a/0218-qemu-sockets-Fix-potential-memory-leak.patch b/0218-qemu-sockets-Fix-potential-memory-leak.patch
new file mode 100644
index 0000000..35d9a44
--- /dev/null
+++ b/0218-qemu-sockets-Fix-potential-memory-leak.patch
@@ -0,0 +1,32 @@
+From 46193407875faf8a8be20dabc4ecfee4ceb6f1a3 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Sat, 1 Sep 2012 09:40:26 +0200
+Subject: [PATCH] qemu-sockets: Fix potential memory leak
+
+The old code leaks variable 'peer'.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 39b384591fda27d6e1213cea0b11b1ebe0ed4b74)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ qemu-sockets.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/qemu-sockets.c b/qemu-sockets.c
+index 361d890..037775b 100644
+--- a/qemu-sockets.c
++++ b/qemu-sockets.c
+@@ -353,7 +353,7 @@ int inet_dgram_opts(QemuOpts *opts)
+     if (0 != (rc = getaddrinfo(addr, port, &ai, &local))) {
+         fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
+                 gai_strerror(rc));
+-        return -1;
++        goto err;
+     }
+ 
+     /* create socket */
+-- 
+1.7.12.1
+
diff --git a/0219-cadence_uart-Fix-buffer-overflow.patch b/0219-cadence_uart-Fix-buffer-overflow.patch
new file mode 100644
index 0000000..3dbf127
--- /dev/null
+++ b/0219-cadence_uart-Fix-buffer-overflow.patch
@@ -0,0 +1,35 @@
+From d563cd7529186355aa8dc11e2cc7d16342dca1c9 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Sat, 1 Sep 2012 11:12:23 +0200
+Subject: [PATCH] cadence_uart: Fix buffer overflow
+
+Report from smatch:
+hw/cadence_uart.c:413 uart_read(13) error: buffer overflow 's->r' 18 <= 18
+
+This fixes read access to s->r[R_MAX] which is behind the limits of s->r.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 5d40097fc09fe5d34cf316a411dc27d455ac2cd0)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/cadence_uart.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/cadence_uart.c b/hw/cadence_uart.c
+index d98e531..f8afc4e 100644
+--- a/hw/cadence_uart.c
++++ b/hw/cadence_uart.c
+@@ -404,7 +404,7 @@ static uint64_t uart_read(void *opaque, target_phys_addr_t offset,
+     uint32_t c = 0;
+ 
+     offset >>= 2;
+-    if (offset > R_MAX) {
++    if (offset >= R_MAX) {
+         return 0;
+     } else if (offset == R_TX_RX) {
+         uart_read_rx_fifo(s, &c);
+-- 
+1.7.12.1
+
diff --git a/0220-lm4549-Fix-buffer-overflow.patch b/0220-lm4549-Fix-buffer-overflow.patch
new file mode 100644
index 0000000..656c9aa
--- /dev/null
+++ b/0220-lm4549-Fix-buffer-overflow.patch
@@ -0,0 +1,47 @@
+From 00338325c4a2c5b0010462b21a4373cbb4341c9d Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Sat, 1 Sep 2012 12:43:41 +0200
+Subject: [PATCH] lm4549: Fix buffer overflow
+
+Report from smatch:
+lm4549.c:234 lm4549_write_samples(14) error:
+ buffer overflow 's->buffer' 1024 <= 1024
+
+There must be enough space to add two entries starting with index
+s->buffer_level, therefore the old check was wrong.
+
+[Peter Maydell <peter.maydell at linaro.org> clarifies the nature of the
+analyser warning:
+
+I don't object to making the change to placate the analyser,
+but I don't think this is actually a buffer overrun. We always
+add and remove samples from the buffer two at a time, so it's
+not possible to get here with s->buffer_level == BUFFER_SIZE-1
+(which is the only case where the old and new conditions
+give different answers).]
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 8139626643cbe8dc07bd9acc88057effeedf8064)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/lm4549.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/lm4549.c b/hw/lm4549.c
+index 80b3ec4..e0137d5 100644
+--- a/hw/lm4549.c
++++ b/hw/lm4549.c
+@@ -224,7 +224,7 @@ uint32_t lm4549_write_samples(lm4549_state *s, uint32_t left, uint32_t right)
+        This model supports 16-bit playback.
+     */
+ 
+-    if (s->buffer_level >= LM4549_BUFFER_SIZE) {
++    if (s->buffer_level > LM4549_BUFFER_SIZE - 2) {
+         DPRINTF("write_sample Buffer full\n");
+         return 0;
+     }
+-- 
+1.7.12.1
+
diff --git a/0221-ioh3420-Remove-unreachable-code.patch b/0221-ioh3420-Remove-unreachable-code.patch
new file mode 100644
index 0000000..e465486
--- /dev/null
+++ b/0221-ioh3420-Remove-unreachable-code.patch
@@ -0,0 +1,33 @@
+From abb7dc3467f809d3d3dfc0aef70fce7ee542c550 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Sat, 1 Sep 2012 12:56:03 +0200
+Subject: [PATCH] ioh3420: Remove unreachable code
+
+Report from smatch:
+hw/ioh3420.c:128 ioh3420_initfn(35) info: ignoring unreachable code.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Reviewed-by: Juan Quintela <quintela at redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 997f15672a5ca7714cf310d92f475d2c5fe40970)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/ioh3420.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/hw/ioh3420.c b/hw/ioh3420.c
+index 94a537c..4d31473 100644
+--- a/hw/ioh3420.c
++++ b/hw/ioh3420.c
+@@ -125,7 +125,6 @@ static int ioh3420_initfn(PCIDevice *d)
+     rc = pcie_chassis_add_slot(s);
+     if (rc < 0) {
+         goto err_pcie_cap;
+-        return rc;
+     }
+     pcie_cap_root_init(d);
+     rc = pcie_aer_init(d, IOH_EP_AER_OFFSET);
+-- 
+1.7.12.1
+
diff --git a/0222-pflash_cfi01-Fix-warning-caused-by-unreachable-code.patch b/0222-pflash_cfi01-Fix-warning-caused-by-unreachable-code.patch
new file mode 100644
index 0000000..ef3cecd
--- /dev/null
+++ b/0222-pflash_cfi01-Fix-warning-caused-by-unreachable-code.patch
@@ -0,0 +1,65 @@
+From 4377b521568c8dca87cfb8fad5629b3203c08032 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Sat, 1 Sep 2012 13:00:48 +0200
+Subject: [PATCH] pflash_cfi01: Fix warning caused by unreachable code
+
+Report from smatch:
+hw/pflash_cfi01.c:431 pflash_write(180) info: ignoring unreachable code.
+
+Instead of removing the return statement after the switch statement,
+the patch replaces the return statements in the switch statement by
+break statements. Other switch statements in the same code do it also
+like that.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 12dabc79f976d66755025272f7e2e8e4da31715a)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/pflash_cfi01.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
+index d56b51a..ac503cf 100644
+--- a/hw/pflash_cfi01.c
++++ b/hw/pflash_cfi01.c
+@@ -320,7 +320,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
+         }
+         pfl->wcycle++;
+         pfl->cmd = cmd;
+-        return;
++        break;
+     case 1:
+         switch (pfl->cmd) {
+         case 0x10: /* Single Byte Program */
+@@ -375,7 +375,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
+         default:
+             goto error_flash;
+         }
+-        return;
++        break;
+     case 2:
+         switch (pfl->cmd) {
+         case 0xe8: /* Block write */
+@@ -406,7 +406,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
+         default:
+             goto error_flash;
+         }
+-        return;
++        break;
+     case 3: /* Confirm mode */
+         switch (pfl->cmd) {
+         case 0xe8: /* Block write */
+@@ -422,7 +422,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
+         default:
+             goto error_flash;
+         }
+-        return;
++        break;
+     default:
+         /* Should never happen */
+         DPRINTF("%s: invalid write state\n",  __func__);
+-- 
+1.7.12.1
+
diff --git a/0223-curses-don-t-initialize-curses-when-qemu-is-daemoniz.patch b/0223-curses-don-t-initialize-curses-when-qemu-is-daemoniz.patch
new file mode 100644
index 0000000..9f29c5e
--- /dev/null
+++ b/0223-curses-don-t-initialize-curses-when-qemu-is-daemoniz.patch
@@ -0,0 +1,90 @@
+From 949f263f90b97dadae23ad205c4c5a3671ecb3aa Mon Sep 17 00:00:00 2001
+From: Hitoshi Mitake <h.mitake at gmail.com>
+Date: Sat, 15 Sep 2012 01:15:41 +0900
+Subject: [PATCH] curses: don't initialize curses when qemu is daemonized
+
+Current qemu initializes curses even if -daemonize option is
+passed. This cause problem because shell prompt appears without
+calling endwin().
+
+This patch adds new function, is_daemonized(), to OS dependent
+code. With this function, curses_display_init() can check that qemu is
+daemonized or not. If daemonized, curses_display_init() isn't called
+and the problem is avoided.
+
+Of course, -daemonize && -curses doesn't make sense. Users shouldn't
+pass the arguments at the same time. But the problem is very painful
+because Ctrl-C cannot be delivered to the terminal.
+
+Cc: Andrzej Zaborowski  <balrog at zabor.org>
+Cc: Stefan Hajnoczi <stefanha at gmail.com>
+Cc: Anthony Liguori <aliguori at us.ibm.com>
+Cc: Michael Roth <mdroth at linux.vnet.ibm.com>
+Signed-off-by: Hitoshi Mitake <h.mitake at gmail.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 995ee2bf469de6bbe5ce133ec853392b2a4ce34c)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ os-posix.c      | 5 +++++
+ qemu-os-posix.h | 2 ++
+ qemu-os-win32.h | 5 +++++
+ vl.c            | 4 +++-
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/os-posix.c b/os-posix.c
+index 79fa228..eabccb8 100644
+--- a/os-posix.c
++++ b/os-posix.c
+@@ -360,3 +360,8 @@ int qemu_create_pidfile(const char *filename)
+     /* keep pidfile open & locked forever */
+     return 0;
+ }
++
++bool is_daemonized(void)
++{
++    return daemonize;
++}
+diff --git a/qemu-os-posix.h b/qemu-os-posix.h
+index 8e1149d..7f198e4 100644
+--- a/qemu-os-posix.h
++++ b/qemu-os-posix.h
+@@ -46,4 +46,6 @@ typedef struct timeval qemu_timeval;
+ typedef struct timespec qemu_timespec;
+ int qemu_utimens(const char *path, const qemu_timespec *times);
+ 
++bool is_daemonized(void);
++
+ #endif
+diff --git a/qemu-os-win32.h b/qemu-os-win32.h
+index 753679b..b3e451b 100644
+--- a/qemu-os-win32.h
++++ b/qemu-os-win32.h
+@@ -86,4 +86,9 @@ typedef struct {
+ } qemu_timeval;
+ int qemu_gettimeofday(qemu_timeval *tp);
+ 
++static inline bool is_daemonized(void)
++{
++    return false;
++}
++
+ #endif
+diff --git a/vl.c b/vl.c
+index c681c33..49d7a52 100644
+--- a/vl.c
++++ b/vl.c
+@@ -3692,7 +3692,9 @@ int main(int argc, char **argv, char **envp)
+         break;
+ #if defined(CONFIG_CURSES)
+     case DT_CURSES:
+-        curses_display_init(ds, full_screen);
++        if (!is_daemonized()) {
++            curses_display_init(ds, full_screen);
++        }
+         break;
+ #endif
+ #if defined(CONFIG_SDL)
+-- 
+1.7.12.1
+
diff --git a/0224-TextConsole-saturate-escape-parameter-in-TTY_STATE_C.patch b/0224-TextConsole-saturate-escape-parameter-in-TTY_STATE_C.patch
new file mode 100644
index 0000000..523d5f4
--- /dev/null
+++ b/0224-TextConsole-saturate-escape-parameter-in-TTY_STATE_C.patch
@@ -0,0 +1,36 @@
+From 93eaa3c8e14988fb38dfa9ae35067472bfd089b8 Mon Sep 17 00:00:00 2001
+From: Laszlo Ersek <lersek at redhat.com>
+Date: Mon, 17 Sep 2012 11:10:03 +0200
+Subject: [PATCH] TextConsole: saturate escape parameter in TTY_STATE_CSI
+
+Signed-off-by: Laszlo Ersek <lersek at redhat.com>
+Reviewed-by: Markus Armbruster <armbru at redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit c10600af60865ba6c60987be313102ebb5fcee57)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ console.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/console.c b/console.c
+index 8b5e21d..314f5a5 100644
+--- a/console.c
++++ b/console.c
+@@ -937,8 +937,11 @@ static void console_putchar(TextConsole *s, int ch)
+     case TTY_STATE_CSI: /* handle escape sequence parameters */
+         if (ch >= '0' && ch <= '9') {
+             if (s->nb_esc_params < MAX_ESC_PARAMS) {
+-                s->esc_params[s->nb_esc_params] =
+-                    s->esc_params[s->nb_esc_params] * 10 + ch - '0';
++                int *param = &s->esc_params[s->nb_esc_params];
++                int digit = (ch - '0');
++
++                *param = (*param <= (INT_MAX - digit) / 10) ?
++                         *param * 10 + digit : INT_MAX;
+             }
+         } else {
+             if (s->nb_esc_params < MAX_ESC_PARAMS)
+-- 
+1.7.12.1
+
diff --git a/0225-linux-user-Remove-redundant-null-check-and-replace-f.patch b/0225-linux-user-Remove-redundant-null-check-and-replace-f.patch
new file mode 100644
index 0000000..acb18c0
--- /dev/null
+++ b/0225-linux-user-Remove-redundant-null-check-and-replace-f.patch
@@ -0,0 +1,42 @@
+From 755055c908ccda2dd9410bb1bde1f3621017fb0c Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Tue, 4 Sep 2012 22:14:19 +0200
+Subject: [PATCH] linux-user: Remove redundant null check and replace free by
+ g_free
+
+Report from smatch:
+
+linux-user/syscall.c:3632 do_ioctl_dm(220) info:
+ redundant null check on big_buf calling free()
+
+'big_buf' was allocated by g_malloc0, therefore free was also
+replaced by g_free.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit ad11ad77748bdd8016370db210751683dc038dd6)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ linux-user/syscall.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/linux-user/syscall.c b/linux-user/syscall.c
+index 6257a04..471d060 100644
+--- a/linux-user/syscall.c
++++ b/linux-user/syscall.c
+@@ -3628,9 +3628,7 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
+         unlock_user(argptr, arg, target_size);
+     }
+ out:
+-    if (big_buf) {
+-        free(big_buf);
+-    }
++    g_free(big_buf);
+     return ret;
+ }
+ 
+-- 
+1.7.12.1
+
diff --git a/0226-net-socket-Fix-compiler-warning-regression-for-MinGW.patch b/0226-net-socket-Fix-compiler-warning-regression-for-MinGW.patch
new file mode 100644
index 0000000..e3cb65f
--- /dev/null
+++ b/0226-net-socket-Fix-compiler-warning-regression-for-MinGW.patch
@@ -0,0 +1,68 @@
+From 96f47b0d2c307173e0a545ea230e21f1ce8d3fa2 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Sat, 22 Sep 2012 21:13:28 +0200
+Subject: [PATCH] net/socket: Fix compiler warning (regression for MinGW)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit 213fd5087e2e4e2da10ad266df0ba950cf7618bf removed a type cast
+which is needed for MinGW:
+
+net/socket.c:136: warning:
+ pointer targets in passing argument 2 of ‘sendto’ differ in signedness
+/usr/lib/gcc/amd64-mingw32msvc/4.4.4/../../../../amd64-mingw32msvc/include/winsock2.h:1313: note:
+ expected ‘const char *’ but argument is of type ‘const uint8_t *’
+
+Add a 'qemu_sendto' macro which provides that type cast where needed
+and use the new macro instead of 'sendto'.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 73062dfe6be0050dbd43ce3516e935ebb2545add)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ net/socket.c  | 6 +++---
+ qemu-common.h | 5 +++++
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/net/socket.c b/net/socket.c
+index c3e55b8..83f21b5 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -131,9 +131,9 @@ static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf,
+     ssize_t ret;
+ 
+     do {
+-        ret = sendto(s->fd, buf, size, 0,
+-                     (struct sockaddr *)&s->dgram_dst,
+-                     sizeof(s->dgram_dst));
++        ret = qemu_sendto(s->fd, buf, size, 0,
++                          (struct sockaddr *)&s->dgram_dst,
++                          sizeof(s->dgram_dst));
+     } while (ret == -1 && errno == EINTR);
+ 
+     if (ret == -1 && errno == EAGAIN) {
+diff --git a/qemu-common.h b/qemu-common.h
+index e5c2bcd..15d9e4e 100644
+--- a/qemu-common.h
++++ b/qemu-common.h
+@@ -223,9 +223,14 @@ int qemu_pipe(int pipefd[2]);
+ #endif
+ 
+ #ifdef _WIN32
++/* MinGW needs a type cast for the 'buf' argument. */
+ #define qemu_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)
++#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
++    sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen)
+ #else
+ #define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags)
++#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
++    sendto(sockfd, buf, len, flags, destaddr, addrlen)
+ #endif
+ 
+ /* Error handling.  */
+-- 
+1.7.12.1
+
diff --git a/0227-w32-Always-use-standard-instead-of-native-format-str.patch b/0227-w32-Always-use-standard-instead-of-native-format-str.patch
new file mode 100644
index 0000000..91b7bba
--- /dev/null
+++ b/0227-w32-Always-use-standard-instead-of-native-format-str.patch
@@ -0,0 +1,52 @@
+From 675a9bdcd5bf5bd663ee58cf5e4be4acf12d34ce Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Wed, 22 Aug 2012 21:42:32 +0200
+Subject: [PATCH] w32: Always use standard instead of native format strings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+GLib 2.0 include files use __printf__ for the format attribute
+which resolves to native format strings on w32 hosts.
+
+QEMU wants standard format strings instead of native format
+strings, so we simply change any declaration with __printf__
+to use __gnu_printf__.
+
+This works because all basic printf functions support both
+kinds of format strings.
+
+This fixes a compiler warning:
+
+qapi/string-output-visitor.c: In function ‘print_type_int’:
+qapi/string-output-visitor.c:34:5: warning: unknown conversion type character ‘l’ in format [-Wformat]
+qapi/string-output-visitor.c:34:5: warning: too many arguments for format [-Wformat-extra-args]
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>
+(cherry picked from commit 95df51a4a02a853af8828c281bce2d4f2a41d6fd)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ compiler.h | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/compiler.h b/compiler.h
+index 07ba1f8..c734a71 100644
+--- a/compiler.h
++++ b/compiler.h
+@@ -44,6 +44,11 @@
+    /* Use gnu_printf when supported (qemu uses standard format strings). */
+ #  define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2)))
+ #  define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
++#  if defined(_WIN32)
++    /* Map __printf__ to __gnu_printf__ because we want standard format strings
++     * even when MinGW or GLib include files use __printf__. */
++#   define __printf__ __gnu_printf__
++#  endif
+ # endif
+ #if defined(_WIN32)
+ #define GCC_WEAK __attribute__((weak))
+-- 
+1.7.12.1
+
diff --git a/0228-w32-Add-implementation-of-gmtime_r-localtime_r.patch b/0228-w32-Add-implementation-of-gmtime_r-localtime_r.patch
new file mode 100644
index 0000000..16473ea
--- /dev/null
+++ b/0228-w32-Add-implementation-of-gmtime_r-localtime_r.patch
@@ -0,0 +1,81 @@
+From 27ca56812d2140c774f9d2b67a2919ef47c69758 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Sat, 22 Sep 2012 22:26:19 +0200
+Subject: [PATCH] w32: Add implementation of gmtime_r, localtime_r
+
+Those functions are missing in MinGW.
+
+Some versions of MinGW-w64 include defines for gmtime_r and localtime_r.
+Older versions of these macros are buggy (they return a pointer to a
+static variable), therefore we don't want them. Newer versions are
+similar to the code used here, but without the memset.
+
+The implementation which is used here is not strictly reentrant,
+but sufficiently good for QEMU on w32 or w64.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+[blauwirbel at gmail.com: added comment about locking]
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+(cherry picked from commit d3e8f95753114a827f9cd8e819b1d5cc8333f76b)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ oslib-win32.c   | 24 ++++++++++++++++++++++++
+ qemu-os-win32.h |  6 ++++++
+ 2 files changed, 30 insertions(+)
+
+diff --git a/oslib-win32.c b/oslib-win32.c
+index ffbc6d0..51b33e8 100644
+--- a/oslib-win32.c
++++ b/oslib-win32.c
+@@ -74,6 +74,30 @@ void qemu_vfree(void *ptr)
+     VirtualFree(ptr, 0, MEM_RELEASE);
+ }
+ 
++/* FIXME: add proper locking */
++struct tm *gmtime_r(const time_t *timep, struct tm *result)
++{
++    struct tm *p = gmtime(timep);
++    memset(result, 0, sizeof(*result));
++    if (p) {
++        *result = *p;
++        p = result;
++    }
++    return p;
++}
++
++/* FIXME: add proper locking */
++struct tm *localtime_r(const time_t *timep, struct tm *result)
++{
++    struct tm *p = localtime(timep);
++    memset(result, 0, sizeof(*result));
++    if (p) {
++        *result = *p;
++        p = result;
++    }
++    return p;
++}
++
+ void socket_set_block(int fd)
+ {
+     unsigned long opt = 0;
+diff --git a/qemu-os-win32.h b/qemu-os-win32.h
+index b3e451b..8ba466d 100644
+--- a/qemu-os-win32.h
++++ b/qemu-os-win32.h
+@@ -68,6 +68,12 @@
+ /* Declaration of ffs() is missing in MinGW's strings.h. */
+ int ffs(int i);
+ 
++/* Missing POSIX functions. Don't use MinGW-w64 macros. */
++#undef gmtime_r
++struct tm *gmtime_r(const time_t *timep, struct tm *result);
++#undef localtime_r
++struct tm *localtime_r(const time_t *timep, struct tm *result);
++
+ static inline void os_setup_signal_handling(void) {}
+ static inline void os_daemonize(void) {}
+ static inline void os_setup_post(void) {}
+-- 
+1.7.12.1
+
diff --git a/0229-blockdev-preserve-readonly-and-snapshot-states-acros.patch b/0229-blockdev-preserve-readonly-and-snapshot-states-acros.patch
new file mode 100644
index 0000000..19bbd20
--- /dev/null
+++ b/0229-blockdev-preserve-readonly-and-snapshot-states-acros.patch
@@ -0,0 +1,37 @@
+From 2afae8c7d44a043e36038d5f6f600034ad2b2aca Mon Sep 17 00:00:00 2001
+From: Kevin Shanahan <kmshanah at disenchant.net>
+Date: Fri, 21 Sep 2012 08:50:22 +0930
+Subject: [PATCH] blockdev: preserve readonly and snapshot states across media
+ changes
+
+If readonly=on is given at device creation time, the ->readonly flag
+needs to be set in the block driver state for this device so that
+readonly-ness is preserved across media changes (qmp change command).
+Similarly, to preserve the snapshot property requires ->open_flags to
+be correct.
+
+Signed-off-by: Kevin Shanahan <kmshanah at disenchant.net>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+(cherry picked from commit 80dd1aae3657a902d262f5d20a7a3c655b23705e)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ blockdev.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/blockdev.c b/blockdev.c
+index 4a5266e..9ba3503 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -533,6 +533,8 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
+                      if_name[type], mediastr, unit_id);
+     }
+     dinfo->bdrv = bdrv_new(dinfo->id);
++    dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
++    dinfo->bdrv->read_only = ro;
+     dinfo->devaddr = devaddr;
+     dinfo->type = type;
+     dinfo->bus = bus_id;
+-- 
+1.7.12.1
+
diff --git a/0230-block-correctly-set-the-keep_read_only-flag.patch b/0230-block-correctly-set-the-keep_read_only-flag.patch
new file mode 100644
index 0000000..ec1affa
--- /dev/null
+++ b/0230-block-correctly-set-the-keep_read_only-flag.patch
@@ -0,0 +1,104 @@
+From 48f550221420bd90ddca06c6c7492ea3aca9b644 Mon Sep 17 00:00:00 2001
+From: Jeff Cody <jcody at redhat.com>
+Date: Thu, 20 Sep 2012 15:13:17 -0400
+Subject: [PATCH] block: correctly set the keep_read_only flag
+
+I believe the bs->keep_read_only flag is supposed to reflect
+the initial open state of the device. If the device is initially
+opened R/O, then commit operations, or reopen operations changing
+to R/W, are prohibited.
+
+Currently, the keep_read_only flag is only accurate for the active
+layer, and its backing file. Subsequent images end up always having
+the keep_read_only flag set.
+
+For instance, what happens now:
+
+[  base  ]  kro = 1, ro = 1
+    |
+    v
+[ snap-1 ]  kro = 1, ro = 1
+    |
+    v
+[ snap-2 ]  kro = 0, ro = 1
+    |
+    v
+[ active ]  kro = 0, ro = 0
+
+What we want:
+
+[  base  ]  kro = 0, ro = 1
+    |
+    v
+[ snap-1 ]  kro = 0, ro = 1
+    |
+    v
+[ snap-2 ]  kro = 0, ro = 1
+    |
+    v
+[ active ]  kro = 0, ro = 0
+
+Signed-off-by: Jeff Cody <jcody at redhat.com>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+(cherry picked from commit be028adcedd68ca4d78fdc43e7e2fa4f1cdbc653)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ block.c | 14 +++++++-------
+ block.h |  1 +
+ 2 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/block.c b/block.c
+index e78039b..4c0e7f5 100644
+--- a/block.c
++++ b/block.c
+@@ -668,7 +668,7 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
+         open_flags |= BDRV_O_RDWR;
+     }
+ 
+-    bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
++    bs->read_only = !(open_flags & BDRV_O_RDWR);
+ 
+     /* Open the image, either directly or using a protocol */
+     if (drv->bdrv_file_open) {
+@@ -808,6 +808,12 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
+         goto unlink_and_fail;
+     }
+ 
++    if (flags & BDRV_O_RDWR) {
++        flags |= BDRV_O_ALLOW_RDWR;
++    }
++
++    bs->keep_read_only = !(flags & BDRV_O_ALLOW_RDWR);
++
+     /* Open the image */
+     ret = bdrv_open_common(bs, filename, flags, drv);
+     if (ret < 0) {
+@@ -837,12 +843,6 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
+             bdrv_close(bs);
+             return ret;
+         }
+-        if (bs->is_temporary) {
+-            bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
+-        } else {
+-            /* base image inherits from "parent" */
+-            bs->backing_hd->keep_read_only = bs->keep_read_only;
+-        }
+     }
+ 
+     if (!bdrv_key_required(bs)) {
+diff --git a/block.h b/block.h
+index 2e2be11..4d919c2 100644
+--- a/block.h
++++ b/block.h
+@@ -80,6 +80,7 @@ typedef struct BlockDevOps {
+ #define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */
+ #define BDRV_O_INCOMING    0x0800  /* consistency hint for incoming migration */
+ #define BDRV_O_CHECK       0x1000  /* open solely for consistency check */
++#define BDRV_O_ALLOW_RDWR  0x2000  /* allow reopen to change from r/o to r/w */
+ 
+ #define BDRV_O_CACHE_MASK  (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)
+ 
+-- 
+1.7.12.1
+
diff --git a/0231-configure-Allow-builds-without-any-system-or-user-em.patch b/0231-configure-Allow-builds-without-any-system-or-user-em.patch
new file mode 100644
index 0000000..d40c6dc
--- /dev/null
+++ b/0231-configure-Allow-builds-without-any-system-or-user-em.patch
@@ -0,0 +1,59 @@
+From 20936a5a29113b32aeb319ca5ebe2a754cd3e014 Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Fri, 14 Sep 2012 19:02:30 +0200
+Subject: [PATCH] configure: Allow builds without any system or user emulation
+
+The old code aborted configure when no emulation target was selected.
+Even after removing the 'exit 1', it tried to read from STDIN
+when QEMU was configured with
+
+    configure' '--disable-user' '--disable-system'
+
+This is fixed here.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit 8bdd3d499fe0ddffa9901c56ab3bc8911d5b8be0)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ Makefile  | 5 +++++
+ configure | 4 ----
+ 2 files changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/Makefile b/Makefile
+index 1cd5bc8..dd11e3c 100644
+--- a/Makefile
++++ b/Makefile
+@@ -52,8 +52,13 @@ SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory) BUILD_DIR=$(BUILD_DIR)
+ SUBDIR_DEVICES_MAK=$(patsubst %, %/config-devices.mak, $(TARGET_DIRS))
+ SUBDIR_DEVICES_MAK_DEP=$(patsubst %, %/config-devices.mak.d, $(TARGET_DIRS))
+ 
++ifeq ($(SUBDIR_DEVICES_MAK),)
++config-all-devices.mak:
++	$(call quiet-command,echo '# no devices' > $@,"  GEN   $@")
++else
+ config-all-devices.mak: $(SUBDIR_DEVICES_MAK)
+ 	$(call quiet-command,cat $(SUBDIR_DEVICES_MAK) | grep =y | sort -u > $@,"  GEN   $@")
++endif
+ 
+ -include $(SUBDIR_DEVICES_MAK_DEP)
+ 
+diff --git a/configure b/configure
+index a1f256c..f528146 100755
+--- a/configure
++++ b/configure
+@@ -1296,10 +1296,6 @@ if test -z "$target_list" ; then
+ else
+     target_list=`echo "$target_list" | sed -e 's/,/ /g'`
+ fi
+-if test -z "$target_list" ; then
+-    echo "No targets enabled"
+-    exit 1
+-fi
+ # see if system emulation was really requested
+ case " $target_list " in
+   *"-softmmu "*) softmmu=yes
+-- 
+1.7.12.1
+
diff --git a/0232-Refactor-inet_connect_opts-function.patch b/0232-Refactor-inet_connect_opts-function.patch
new file mode 100644
index 0000000..bd8702f
--- /dev/null
+++ b/0232-Refactor-inet_connect_opts-function.patch
@@ -0,0 +1,207 @@
+From 2f56ee52ed70bed32de06ba1c9ef22e4d4d504f0 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Mon, 24 Sep 2012 13:11:07 +0200
+Subject: [PATCH] Refactor inet_connect_opts function
+
+refactor address resolution code to fix nonblocking connect
+remove getnameinfo call
+
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Amos Kong <akong at redhat.com>
+Signed-off-by: Orit Wasserman <owasserm at redhat.com>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit 05bc1d8a4b2f77df8cc9880a552047e30c16f1f8)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ qemu-sockets.c | 148 +++++++++++++++++++++++++++++++++------------------------
+ 1 file changed, 85 insertions(+), 63 deletions(-)
+
+diff --git a/qemu-sockets.c b/qemu-sockets.c
+index 037775b..22797bf 100644
+--- a/qemu-sockets.c
++++ b/qemu-sockets.c
+@@ -209,95 +209,117 @@ listen:
+     return slisten;
+ }
+ 
+-int inet_connect_opts(QemuOpts *opts, bool *in_progress, Error **errp)
++#ifdef _WIN32
++#define QEMU_SOCKET_RC_INPROGRESS(rc) \
++    ((rc) == -EINPROGRESS || (rc) == -EWOULDBLOCK || (rc) == -WSAEALREADY)
++#else
++#define QEMU_SOCKET_RC_INPROGRESS(rc) \
++    ((rc) == -EINPROGRESS)
++#endif
++
++static int inet_connect_addr(struct addrinfo *addr, bool block,
++                             bool *in_progress)
+ {
+-    struct addrinfo ai,*res,*e;
++    int sock, rc;
++
++    if (in_progress) {
++        *in_progress = false;
++    }
++
++    sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
++    if (sock < 0) {
++        fprintf(stderr, "%s: socket(%s): %s\n", __func__,
++                inet_strfamily(addr->ai_family), strerror(errno));
++        return -1;
++    }
++    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
++    if (!block) {
++        socket_set_nonblock(sock);
++    }
++    /* connect to peer */
++    do {
++        rc = 0;
++        if (connect(sock, addr->ai_addr, addr->ai_addrlen) < 0) {
++            rc = -socket_error();
++        }
++    } while (rc == -EINTR);
++
++    if (!block && QEMU_SOCKET_RC_INPROGRESS(rc)) {
++        if (in_progress) {
++            *in_progress = true;
++        }
++    } else if (rc < 0) {
++        closesocket(sock);
++        return -1;
++    }
++    return sock;
++}
++
++static struct addrinfo *inet_parse_connect_opts(QemuOpts *opts, Error **errp)
++{
++    struct addrinfo ai, *res;
++    int rc;
+     const char *addr;
+     const char *port;
+-    char uaddr[INET6_ADDRSTRLEN+1];
+-    char uport[33];
+-    int sock,rc;
+-    bool block;
+ 
+-    memset(&ai,0, sizeof(ai));
++    memset(&ai, 0, sizeof(ai));
+     ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
+     ai.ai_family = PF_UNSPEC;
+     ai.ai_socktype = SOCK_STREAM;
+ 
+-    if (in_progress) {
+-        *in_progress = false;
+-    }
+-
+     addr = qemu_opt_get(opts, "host");
+     port = qemu_opt_get(opts, "port");
+-    block = qemu_opt_get_bool(opts, "block", 0);
+     if (addr == NULL || port == NULL) {
+-        fprintf(stderr, "inet_connect: host and/or port not specified\n");
++        fprintf(stderr,
++                "inet_parse_connect_opts: host and/or port not specified\n");
+         error_set(errp, QERR_SOCKET_CREATE_FAILED);
+-        return -1;
++        return NULL;
+     }
+ 
+-    if (qemu_opt_get_bool(opts, "ipv4", 0))
++    if (qemu_opt_get_bool(opts, "ipv4", 0)) {
+         ai.ai_family = PF_INET;
+-    if (qemu_opt_get_bool(opts, "ipv6", 0))
++    }
++    if (qemu_opt_get_bool(opts, "ipv6", 0)) {
+         ai.ai_family = PF_INET6;
++    }
+ 
+     /* lookup */
+-    if (0 != (rc = getaddrinfo(addr, port, &ai, &res))) {
+-        fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
++    rc = getaddrinfo(addr, port, &ai, &res);
++    if (rc != 0) {
++        fprintf(stderr, "getaddrinfo(%s,%s): %s\n", addr, port,
+                 gai_strerror(rc));
+         error_set(errp, QERR_SOCKET_CREATE_FAILED);
+-	return -1;
++        return NULL;
++    }
++    return res;
++}
++
++int inet_connect_opts(QemuOpts *opts, bool *in_progress, Error **errp)
++{
++    struct addrinfo *res, *e;
++    int sock = -1;
++    bool block = qemu_opt_get_bool(opts, "block", 0);
++
++    res = inet_parse_connect_opts(opts, errp);
++    if (!res) {
++        return -1;
++    }
++
++    if (in_progress) {
++        *in_progress = false;
+     }
+ 
+     for (e = res; e != NULL; e = e->ai_next) {
+-        if (getnameinfo((struct sockaddr*)e->ai_addr,e->ai_addrlen,
+-                            uaddr,INET6_ADDRSTRLEN,uport,32,
+-                            NI_NUMERICHOST | NI_NUMERICSERV) != 0) {
+-            fprintf(stderr,"%s: getnameinfo: oops\n", __FUNCTION__);
+-            continue;
+-        }
+-        sock = qemu_socket(e->ai_family, e->ai_socktype, e->ai_protocol);
+-        if (sock < 0) {
+-            fprintf(stderr,"%s: socket(%s): %s\n", __FUNCTION__,
+-            inet_strfamily(e->ai_family), strerror(errno));
+-            continue;
+-        }
+-        setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&on,sizeof(on));
+-        if (!block) {
+-            socket_set_nonblock(sock);
+-        }
+-        /* connect to peer */
+-        do {
+-            rc = 0;
+-            if (connect(sock, e->ai_addr, e->ai_addrlen) < 0) {
+-                rc = -socket_error();
+-            }
+-        } while (rc == -EINTR);
+-
+-  #ifdef _WIN32
+-        if (!block && (rc == -EINPROGRESS || rc == -EWOULDBLOCK
+-                       || rc == -WSAEALREADY)) {
+-  #else
+-        if (!block && (rc == -EINPROGRESS)) {
+-  #endif
+-            if (in_progress) {
+-                *in_progress = true;
+-            }
+-        } else if (rc < 0) {
+-            if (NULL == e->ai_next)
+-                fprintf(stderr, "%s: connect(%s,%s,%s,%s): %s\n", __FUNCTION__,
+-                        inet_strfamily(e->ai_family),
+-                        e->ai_canonname, uaddr, uport, strerror(errno));
+-            closesocket(sock);
+-            continue;
++        sock = inet_connect_addr(e, block, in_progress);
++        if (sock >= 0) {
++            break;
+         }
+-        freeaddrinfo(res);
+-        return sock;
+     }
+-    error_set(errp, QERR_SOCKET_CONNECT_FAILED);
++    if (sock < 0) {
++        error_set(errp, QERR_SOCKET_CONNECT_FAILED);
++    }
+     freeaddrinfo(res);
+-    return -1;
++    return sock;
+ }
+ 
+ int inet_dgram_opts(QemuOpts *opts)
+-- 
+1.7.12.1
+
diff --git a/0233-Separate-inet_connect-into-inet_connect-blocking-and.patch b/0233-Separate-inet_connect-into-inet_connect-blocking-and.patch
new file mode 100644
index 0000000..e017ef0
--- /dev/null
+++ b/0233-Separate-inet_connect-into-inet_connect-blocking-and.patch
@@ -0,0 +1,188 @@
+From 36f7af3f8bfd2c16f2e6c4b61d9564d5cfdd2394 Mon Sep 17 00:00:00 2001
+From: Orit Wasserman <owasserm at redhat.com>
+Date: Mon, 24 Sep 2012 13:11:08 +0200
+Subject: [PATCH] Separate inet_connect into inet_connect (blocking) and
+ inet_nonblocking_connect
+
+No need to add non blocking parameters to the blocking inet_connect
+add block parameter for inet_connect_opts instead of using QemuOpt "block".
+
+Signed-off-by: Orit Wasserman <owasserm at redhat.com>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit 5db5f44cb4b7f24b9e0efdefc9015e36b7c34881)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ migration-tcp.c |  2 +-
+ nbd.c           |  2 +-
+ qemu-char.c     |  2 +-
+ qemu-sockets.c  | 58 +++++++++++++++++++++++++++++++++++++++++++++++----------
+ qemu_socket.h   |  7 +++++--
+ ui/vnc.c        |  2 +-
+ 6 files changed, 57 insertions(+), 16 deletions(-)
+
+diff --git a/migration-tcp.c b/migration-tcp.c
+index ac891c3..7f6ad98 100644
+--- a/migration-tcp.c
++++ b/migration-tcp.c
+@@ -88,7 +88,7 @@ int tcp_start_outgoing_migration(MigrationState *s, const char *host_port,
+     s->write = socket_write;
+     s->close = tcp_close;
+ 
+-    s->fd = inet_connect(host_port, false, &in_progress, errp);
++    s->fd = inet_nonblocking_connect(host_port, &in_progress, errp);
+     if (error_is_set(errp)) {
+         migrate_fd_error(s);
+         return -1;
+diff --git a/nbd.c b/nbd.c
+index 0dd60c5..206f75c 100644
+--- a/nbd.c
++++ b/nbd.c
+@@ -162,7 +162,7 @@ int tcp_socket_outgoing(const char *address, uint16_t port)
+ 
+ int tcp_socket_outgoing_spec(const char *address_and_port)
+ {
+-    return inet_connect(address_and_port, true, NULL, NULL);
++    return inet_connect(address_and_port, NULL);
+ }
+ 
+ int tcp_socket_incoming(const char *address, uint16_t port)
+diff --git a/qemu-char.c b/qemu-char.c
+index 7f0f895..13b87b5 100644
+--- a/qemu-char.c
++++ b/qemu-char.c
+@@ -2456,7 +2456,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
+         if (is_listen) {
+             fd = inet_listen_opts(opts, 0, NULL);
+         } else {
+-            fd = inet_connect_opts(opts, NULL, NULL);
++            fd = inet_connect_opts(opts, true, NULL, NULL);
+         }
+     }
+     if (fd < 0) {
+diff --git a/qemu-sockets.c b/qemu-sockets.c
+index 22797bf..0883a66 100644
+--- a/qemu-sockets.c
++++ b/qemu-sockets.c
+@@ -54,9 +54,6 @@ static QemuOptsList dummy_opts = {
+         },{
+             .name = "ipv6",
+             .type = QEMU_OPT_BOOL,
+-        },{
+-            .name = "block",
+-            .type = QEMU_OPT_BOOL,
+         },
+         { /* end if list */ }
+     },
+@@ -294,11 +291,22 @@ static struct addrinfo *inet_parse_connect_opts(QemuOpts *opts, Error **errp)
+     return res;
+ }
+ 
+-int inet_connect_opts(QemuOpts *opts, bool *in_progress, Error **errp)
++/**
++ * Create a socket and connect it to an address.
++ *
++ * @opts: QEMU options, recognized parameters strings "host" and "port",
++ *        bools "ipv4" and "ipv6".
++ * @block: set true for blocking socket
++ * @in_progress: set to true in case of ongoing connect
++ * @errp: set on error
++ *
++ * Returns: -1 on error, file descriptor on success.
++ */
++int inet_connect_opts(QemuOpts *opts, bool block, bool *in_progress,
++                      Error **errp)
+ {
+     struct addrinfo *res, *e;
+     int sock = -1;
+-    bool block = qemu_opt_get_bool(opts, "block", 0);
+ 
+     res = inet_parse_connect_opts(opts, errp);
+     if (!res) {
+@@ -515,17 +523,47 @@ int inet_listen(const char *str, char *ostr, int olen,
+     return sock;
+ }
+ 
+-int inet_connect(const char *str, bool block, bool *in_progress, Error **errp)
++/**
++ * Create a blocking socket and connect it to an address.
++ *
++ * @str: address string
++ * @errp: set in case of an error
++ *
++ * Returns -1 in case of error, file descriptor on success
++ **/
++int inet_connect(const char *str, Error **errp)
+ {
+     QemuOpts *opts;
+     int sock = -1;
+ 
+     opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
+     if (inet_parse(opts, str) == 0) {
+-        if (block) {
+-            qemu_opt_set(opts, "block", "on");
+-        }
+-        sock = inet_connect_opts(opts, in_progress, errp);
++        sock = inet_connect_opts(opts, true, NULL, errp);
++    } else {
++        error_set(errp, QERR_SOCKET_CREATE_FAILED);
++    }
++    qemu_opts_del(opts);
++    return sock;
++}
++
++/**
++ * Create a non-blocking socket and connect it to an address.
++ *
++ * @str: address string
++ * @in_progress: set to true in case of ongoing connect
++ * @errp: set in case of an error
++ *
++ * Returns: -1 on error, file descriptor on success.
++ **/
++int inet_nonblocking_connect(const char *str, bool *in_progress,
++                             Error **errp)
++{
++    QemuOpts *opts;
++    int sock = -1;
++
++    opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
++    if (inet_parse(opts, str) == 0) {
++        sock = inet_connect_opts(opts, false, in_progress, errp);
+     } else {
+         error_set(errp, QERR_SOCKET_CREATE_FAILED);
+     }
+diff --git a/qemu_socket.h b/qemu_socket.h
+index 30ae6af..80696aa 100644
+--- a/qemu_socket.h
++++ b/qemu_socket.h
+@@ -42,8 +42,11 @@ int send_all(int fd, const void *buf, int len1);
+ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp);
+ int inet_listen(const char *str, char *ostr, int olen,
+                 int socktype, int port_offset, Error **errp);
+-int inet_connect_opts(QemuOpts *opts, bool *in_progress, Error **errp);
+-int inet_connect(const char *str, bool block, bool *in_progress, Error **errp);
++int inet_connect_opts(QemuOpts *opts, bool block, bool *in_progress,
++                      Error **errp);
++int inet_connect(const char *str, Error **errp);
++int inet_nonblocking_connect(const char *str, bool *in_progress,
++                             Error **errp);
+ int inet_dgram_opts(QemuOpts *opts);
+ const char *inet_strfamily(int family);
+ 
+diff --git a/ui/vnc.c b/ui/vnc.c
+index 385e345..01b2daf 100644
+--- a/ui/vnc.c
++++ b/ui/vnc.c
+@@ -3061,7 +3061,7 @@ int vnc_display_open(DisplayState *ds, const char *display)
+         if (strncmp(display, "unix:", 5) == 0)
+             vs->lsock = unix_connect(display+5);
+         else
+-            vs->lsock = inet_connect(display, true, NULL, NULL);
++            vs->lsock = inet_connect(display, NULL);
+         if (-1 == vs->lsock) {
+             g_free(vs->display);
+             vs->display = NULL;
+-- 
+1.7.12.1
+
diff --git a/0234-Fix-address-handling-in-inet_nonblocking_connect.patch b/0234-Fix-address-handling-in-inet_nonblocking_connect.patch
new file mode 100644
index 0000000..9e64c16
--- /dev/null
+++ b/0234-Fix-address-handling-in-inet_nonblocking_connect.patch
@@ -0,0 +1,369 @@
+From b3db72271ead92daae43b1534fdfdbe750555b0a Mon Sep 17 00:00:00 2001
+From: Orit Wasserman <owasserm at redhat.com>
+Date: Mon, 24 Sep 2012 13:11:09 +0200
+Subject: [PATCH] Fix address handling in inet_nonblocking_connect
+
+getaddrinfo can give us a list of addresses, but we only try to
+connect to the first one. If that fails we never proceed to
+the next one.  This is common on desktop setups that often have ipv6
+configured but not actually working.
+
+To fix this make inet_connect_nonblocking retry connection with a different
+address.
+callers on inet_nonblocking_connect register a callback function that will
+be called when connect opertion completes, in case of failure the fd will have
+a negative value
+
+Signed-off-by: Orit Wasserman <owasserm at redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit 233aa5c2d1cf4655ffe335025a68cf5454f87dad)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ migration-tcp.c |  37 ++++------------
+ qemu-char.c     |   2 +-
+ qemu-sockets.c  | 129 +++++++++++++++++++++++++++++++++++++++++++++-----------
+ qemu_socket.h   |  16 ++++---
+ 4 files changed, 126 insertions(+), 58 deletions(-)
+
+diff --git a/migration-tcp.c b/migration-tcp.c
+index 7f6ad98..a15c2b8 100644
+--- a/migration-tcp.c
++++ b/migration-tcp.c
+@@ -53,54 +53,35 @@ static int tcp_close(MigrationState *s)
+     return r;
+ }
+ 
+-static void tcp_wait_for_connect(void *opaque)
++static void tcp_wait_for_connect(int fd, void *opaque)
+ {
+     MigrationState *s = opaque;
+-    int val, ret;
+-    socklen_t valsize = sizeof(val);
+ 
+-    DPRINTF("connect completed\n");
+-    do {
+-        ret = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, (void *) &val, &valsize);
+-    } while (ret == -1 && (socket_error()) == EINTR);
+-
+-    if (ret < 0) {
++    if (fd < 0) {
++        DPRINTF("migrate connect error\n");
++        s->fd = -1;
+         migrate_fd_error(s);
+-        return;
+-    }
+-
+-    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
+-
+-    if (val == 0)
++    } else {
++        DPRINTF("migrate connect success\n");
++        s->fd = fd;
+         migrate_fd_connect(s);
+-    else {
+-        DPRINTF("error connecting %d\n", val);
+-        migrate_fd_error(s);
+     }
+ }
+ 
+ int tcp_start_outgoing_migration(MigrationState *s, const char *host_port,
+                                  Error **errp)
+ {
+-    bool in_progress;
+-
+     s->get_error = socket_errno;
+     s->write = socket_write;
+     s->close = tcp_close;
+ 
+-    s->fd = inet_nonblocking_connect(host_port, &in_progress, errp);
++    s->fd = inet_nonblocking_connect(host_port, tcp_wait_for_connect, s,
++                                     errp);
+     if (error_is_set(errp)) {
+         migrate_fd_error(s);
+         return -1;
+     }
+ 
+-    if (in_progress) {
+-        DPRINTF("connect in progress\n");
+-        qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s);
+-    } else {
+-        migrate_fd_connect(s);
+-    }
+-
+     return 0;
+ }
+ 
+diff --git a/qemu-char.c b/qemu-char.c
+index 13b87b5..b082bae 100644
+--- a/qemu-char.c
++++ b/qemu-char.c
+@@ -2456,7 +2456,7 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
+         if (is_listen) {
+             fd = inet_listen_opts(opts, 0, NULL);
+         } else {
+-            fd = inet_connect_opts(opts, true, NULL, NULL);
++            fd = inet_connect_opts(opts, NULL, NULL, NULL);
+         }
+     }
+     if (fd < 0) {
+diff --git a/qemu-sockets.c b/qemu-sockets.c
+index 0883a66..1f14e8b 100644
+--- a/qemu-sockets.c
++++ b/qemu-sockets.c
+@@ -24,6 +24,7 @@
+ 
+ #include "qemu_socket.h"
+ #include "qemu-common.h" /* for qemu_isdigit */
++#include "main-loop.h"
+ 
+ #ifndef AI_ADDRCONFIG
+ # define AI_ADDRCONFIG 0
+@@ -214,14 +215,66 @@ listen:
+     ((rc) == -EINPROGRESS)
+ #endif
+ 
+-static int inet_connect_addr(struct addrinfo *addr, bool block,
+-                             bool *in_progress)
++/* Struct to store connect state for non blocking connect */
++typedef struct ConnectState {
++    int fd;
++    struct addrinfo *addr_list;
++    struct addrinfo *current_addr;
++    NonBlockingConnectHandler *callback;
++    void *opaque;
++} ConnectState;
++
++static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
++                             ConnectState *connect_state);
++
++static void wait_for_connect(void *opaque)
+ {
+-    int sock, rc;
++    ConnectState *s = opaque;
++    int val = 0, rc = 0;
++    socklen_t valsize = sizeof(val);
++    bool in_progress;
++
++    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
++
++    do {
++        rc = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, (void *) &val, &valsize);
++    } while (rc == -1 && socket_error() == EINTR);
++
++    /* update rc to contain error */
++    if (!rc && val) {
++        rc = -1;
++    }
++
++    /* connect error */
++    if (rc < 0) {
++        closesocket(s->fd);
++        s->fd = rc;
++    }
++
++    /* try to connect to the next address on the list */
++    while (s->current_addr->ai_next != NULL && s->fd < 0) {
++        s->current_addr = s->current_addr->ai_next;
++        s->fd = inet_connect_addr(s->current_addr, &in_progress, s);
++        /* connect in progress */
++        if (in_progress) {
++            return;
++        }
++    }
+ 
+-    if (in_progress) {
+-        *in_progress = false;
++    freeaddrinfo(s->addr_list);
++    if (s->callback) {
++        s->callback(s->fd, s->opaque);
+     }
++    g_free(s);
++    return;
++}
++
++static int inet_connect_addr(struct addrinfo *addr, bool *in_progress,
++                             ConnectState *connect_state)
++{
++    int sock, rc;
++
++    *in_progress = false;
+ 
+     sock = qemu_socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
+     if (sock < 0) {
+@@ -230,7 +283,7 @@ static int inet_connect_addr(struct addrinfo *addr, bool block,
+         return -1;
+     }
+     setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+-    if (!block) {
++    if (connect_state != NULL) {
+         socket_set_nonblock(sock);
+     }
+     /* connect to peer */
+@@ -241,10 +294,11 @@ static int inet_connect_addr(struct addrinfo *addr, bool block,
+         }
+     } while (rc == -EINTR);
+ 
+-    if (!block && QEMU_SOCKET_RC_INPROGRESS(rc)) {
+-        if (in_progress) {
+-            *in_progress = true;
+-        }
++    if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) {
++        connect_state->fd = sock;
++        qemu_set_fd_handler2(sock, NULL, NULL, wait_for_connect,
++                             connect_state);
++        *in_progress = true;
+     } else if (rc < 0) {
+         closesocket(sock);
+         return -1;
+@@ -260,6 +314,7 @@ static struct addrinfo *inet_parse_connect_opts(QemuOpts *opts, Error **errp)
+     const char *port;
+ 
+     memset(&ai, 0, sizeof(ai));
++
+     ai.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
+     ai.ai_family = PF_UNSPEC;
+     ai.ai_socktype = SOCK_STREAM;
+@@ -296,36 +351,55 @@ static struct addrinfo *inet_parse_connect_opts(QemuOpts *opts, Error **errp)
+  *
+  * @opts: QEMU options, recognized parameters strings "host" and "port",
+  *        bools "ipv4" and "ipv6".
+- * @block: set true for blocking socket
+- * @in_progress: set to true in case of ongoing connect
+  * @errp: set on error
++ * @callback: callback function for non-blocking connect
++ * @opaque: opaque for callback function
+  *
+  * Returns: -1 on error, file descriptor on success.
++ *
++ * If @callback is non-null, the connect is non-blocking.  If this
++ * function succeeds, callback will be called when the connection
++ * completes, with the file descriptor on success, or -1 on error.
+  */
+-int inet_connect_opts(QemuOpts *opts, bool block, bool *in_progress,
+-                      Error **errp)
++int inet_connect_opts(QemuOpts *opts, Error **errp,
++                      NonBlockingConnectHandler *callback, void *opaque)
+ {
+     struct addrinfo *res, *e;
+     int sock = -1;
++    bool in_progress;
++    ConnectState *connect_state = NULL;
+ 
+     res = inet_parse_connect_opts(opts, errp);
+     if (!res) {
+         return -1;
+     }
+ 
+-    if (in_progress) {
+-        *in_progress = false;
++    if (callback != NULL) {
++        connect_state = g_malloc0(sizeof(*connect_state));
++        connect_state->addr_list = res;
++        connect_state->callback = callback;
++        connect_state->opaque = opaque;
+     }
+ 
+     for (e = res; e != NULL; e = e->ai_next) {
+-        sock = inet_connect_addr(e, block, in_progress);
+-        if (sock >= 0) {
++        if (connect_state != NULL) {
++            connect_state->current_addr = e;
++        }
++        sock = inet_connect_addr(e, &in_progress, connect_state);
++        if (in_progress) {
++            return sock;
++        } else if (sock >= 0) {
++            /* non blocking socket immediate success, call callback */
++            if (callback != NULL) {
++                callback(sock, opaque);
++            }
+             break;
+         }
+     }
+     if (sock < 0) {
+         error_set(errp, QERR_SOCKET_CONNECT_FAILED);
+     }
++    g_free(connect_state);
+     freeaddrinfo(res);
+     return sock;
+ }
+@@ -538,7 +612,7 @@ int inet_connect(const char *str, Error **errp)
+ 
+     opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
+     if (inet_parse(opts, str) == 0) {
+-        sock = inet_connect_opts(opts, true, NULL, errp);
++        sock = inet_connect_opts(opts, errp, NULL, NULL);
+     } else {
+         error_set(errp, QERR_SOCKET_CREATE_FAILED);
+     }
+@@ -548,22 +622,29 @@ int inet_connect(const char *str, Error **errp)
+ 
+ /**
+  * Create a non-blocking socket and connect it to an address.
++ * Calls the callback function with fd in case of success or -1 in case of
++ * error.
+  *
+  * @str: address string
+- * @in_progress: set to true in case of ongoing connect
++ * @callback: callback function that is called when connect completes,
++ *            cannot be NULL.
++ * @opaque: opaque for callback function
+  * @errp: set in case of an error
+  *
+- * Returns: -1 on error, file descriptor on success.
++ * Returns: -1 on immediate error, file descriptor on success.
+  **/
+-int inet_nonblocking_connect(const char *str, bool *in_progress,
+-                             Error **errp)
++int inet_nonblocking_connect(const char *str,
++                             NonBlockingConnectHandler *callback,
++                             void *opaque, Error **errp)
+ {
+     QemuOpts *opts;
+     int sock = -1;
+ 
++    g_assert(callback != NULL);
++
+     opts = qemu_opts_create(&dummy_opts, NULL, 0, NULL);
+     if (inet_parse(opts, str) == 0) {
+-        sock = inet_connect_opts(opts, false, in_progress, errp);
++        sock = inet_connect_opts(opts, errp, callback, opaque);
+     } else {
+         error_set(errp, QERR_SOCKET_CREATE_FAILED);
+     }
+diff --git a/qemu_socket.h b/qemu_socket.h
+index 80696aa..3e8aee9 100644
+--- a/qemu_socket.h
++++ b/qemu_socket.h
+@@ -38,15 +38,21 @@ void socket_set_block(int fd);
+ void socket_set_nonblock(int fd);
+ int send_all(int fd, const void *buf, int len1);
+ 
+-/* New, ipv6-ready socket helper functions, see qemu-sockets.c */
++/* callback function for nonblocking connect
++ * valid fd on success, negative error code on failure
++ */
++typedef void NonBlockingConnectHandler(int fd, void *opaque);
++
+ int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp);
+ int inet_listen(const char *str, char *ostr, int olen,
+                 int socktype, int port_offset, Error **errp);
+-int inet_connect_opts(QemuOpts *opts, bool block, bool *in_progress,
+-                      Error **errp);
++int inet_connect_opts(QemuOpts *opts, Error **errp,
++                      NonBlockingConnectHandler *callback, void *opaque);
+ int inet_connect(const char *str, Error **errp);
+-int inet_nonblocking_connect(const char *str, bool *in_progress,
+-                             Error **errp);
++int inet_nonblocking_connect(const char *str,
++                             NonBlockingConnectHandler *callback,
++                             void *opaque, Error **errp);
++
+ int inet_dgram_opts(QemuOpts *opts);
+ const char *inet_strfamily(int family);
+ 
+-- 
+1.7.12.1
+
diff --git a/0235-Clear-handler-only-for-valid-fd.patch b/0235-Clear-handler-only-for-valid-fd.patch
new file mode 100644
index 0000000..3ddcd80
--- /dev/null
+++ b/0235-Clear-handler-only-for-valid-fd.patch
@@ -0,0 +1,32 @@
+From b7b94b6016b89bf698d661ce4fd22139e771a835 Mon Sep 17 00:00:00 2001
+From: Orit Wasserman <owasserm at redhat.com>
+Date: Mon, 24 Sep 2012 13:11:10 +0200
+Subject: [PATCH] Clear handler only for valid fd
+
+Signed-off-by: Orit Wasserman <owasserm at redhat.com>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+(cherry picked from commit 3202becaa2b805497ce9e6faa6edfb83665f91b1)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ migration.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/migration.c b/migration.c
+index 1edeec5..22a05c4 100644
+--- a/migration.c
++++ b/migration.c
+@@ -240,7 +240,9 @@ static int migrate_fd_cleanup(MigrationState *s)
+ {
+     int ret = 0;
+ 
+-    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
++    if (s->fd != -1) {
++        qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
++    }
+ 
+     if (s->file) {
+         DPRINTF("closing file\n");
+-- 
+1.7.12.1
+
diff --git a/0236-pl190-fix-read-of-VECTADDR.patch b/0236-pl190-fix-read-of-VECTADDR.patch
new file mode 100644
index 0000000..c306cb5
--- /dev/null
+++ b/0236-pl190-fix-read-of-VECTADDR.patch
@@ -0,0 +1,51 @@
+From 12d4393d0830a2a63828d302f177a9b8e31f433a Mon Sep 17 00:00:00 2001
+From: Brendan Fennell <bfennell at skynet.ie>
+Date: Wed, 26 Sep 2012 16:46:28 +0100
+Subject: [PATCH] pl190: fix read of VECTADDR
+
+Reading VECTADDR was causing us to set the current priority to
+the wrong value, the most obvious effect of which was that we
+would return the vector for the wrong interrupt as the result
+of the read.
+
+Signed-off-by: Brendan Fennell <bfennell at skynet.ie>
+Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
+(cherry picked from commit 14c126baf1c38607c5bd988878de85a06cefd8cf)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/pl190.c | 18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+diff --git a/hw/pl190.c b/hw/pl190.c
+index cb50afb..7332f4d 100644
+--- a/hw/pl190.c
++++ b/hw/pl190.c
+@@ -117,12 +117,18 @@ static uint64_t pl190_read(void *opaque, target_phys_addr_t offset,
+         return s->protected;
+     case 12: /* VECTADDR */
+         /* Read vector address at the start of an ISR.  Increases the
+-           current priority level to that of the current interrupt.  */
+-        for (i = 0; i < s->priority; i++)
+-          {
+-            if ((s->level | s->soft_level) & s->prio_mask[i])
+-              break;
+-          }
++         * current priority level to that of the current interrupt.
++         *
++         * Since an enabled interrupt X at priority P causes prio_mask[Y]
++         * to have bit X set for all Y > P, this loop will stop with
++         * i == the priority of the highest priority set interrupt.
++         */
++        for (i = 0; i < s->priority; i++) {
++            if ((s->level | s->soft_level) & s->prio_mask[i + 1]) {
++                break;
++            }
++        }
++
+         /* Reading this value with no pending interrupts is undefined.
+            We return the default address.  */
+         if (i == PL190_NUM_PRIO)
+-- 
+1.7.12.1
+
diff --git a/0237-hw-armv7m_nvic-Correctly-register-GIC-region-when-se.patch b/0237-hw-armv7m_nvic-Correctly-register-GIC-region-when-se.patch
new file mode 100644
index 0000000..2f3f36d
--- /dev/null
+++ b/0237-hw-armv7m_nvic-Correctly-register-GIC-region-when-se.patch
@@ -0,0 +1,40 @@
+From f4a5b8185d067430cd605a740af654cd1cd2e2aa Mon Sep 17 00:00:00 2001
+From: Meador Inge <meadori at codesourcery.com>
+Date: Wed, 26 Sep 2012 16:46:28 +0100
+Subject: [PATCH] hw/armv7m_nvic: Correctly register GIC region when setting
+ up NVIC
+
+When setting up the NVIC memory regions the memory range
+0x100..0xcff is aliased to an IO memory region that belongs
+to the ARM GIC.  This aliased region should be added to the
+NVIC memory container, but the actual GIC IO memory region
+was being added instead.  This mixup was causing the wrong
+IO memory access functions to be called when accessing parts
+of the NVIC memory.
+
+Signed-off-by: Meador Inge <meadori at codesourcery.com>
+Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
+(cherry picked from commit 9892cae39562d2e6c00ccc5966302c00f23be6d4)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/armv7m_nvic.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
+index 6a0832e..5c09116 100644
+--- a/hw/armv7m_nvic.c
++++ b/hw/armv7m_nvic.c
+@@ -489,7 +489,8 @@ static int armv7m_nvic_init(SysBusDevice *dev)
+      */
+     memory_region_init_alias(&s->gic_iomem_alias, "nvic-gic", &s->gic.iomem,
+                              0x100, 0xc00);
+-    memory_region_add_subregion_overlap(&s->container, 0x100, &s->gic.iomem, 1);
++    memory_region_add_subregion_overlap(&s->container, 0x100,
++                                        &s->gic_iomem_alias, 1);
+     /* Map the whole thing into system memory at the location required
+      * by the v7M architecture.
+      */
+-- 
+1.7.12.1
+
diff --git a/0238-Versatile-Express-Fix-NOR-flash-0-address-and-remove.patch b/0238-Versatile-Express-Fix-NOR-flash-0-address-and-remove.patch
new file mode 100644
index 0000000..4fd2f11
--- /dev/null
+++ b/0238-Versatile-Express-Fix-NOR-flash-0-address-and-remove.patch
@@ -0,0 +1,56 @@
+From cb97f34eca351d150574c724047709b76d00d08a Mon Sep 17 00:00:00 2001
+From: Francesco Lavra <francescolavra.fl at gmail.com>
+Date: Wed, 19 Sep 2012 05:51:58 +0000
+Subject: [PATCH] Versatile Express: Fix NOR flash 0 address and remove flash
+ alias
+
+In the A series memory map (implemented in the Cortex A15 CoreTile), the
+first NOR flash bank (flash 0) is mapped to address 0x08000000, while
+address 0x00000000 can be configured as alias to either the first or the
+second flash bank. This patch fixes the definition of flash 0 address,
+and for simplicity removes the alias definition.
+
+Signed-off-by: Francesco Lavra <francescolavra.fl at gmail.com>
+Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
+(cherry picked from commit 661bafb3e14bfffcb0a7c7910534c7944608ca45)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/vexpress.c | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/hw/vexpress.c b/hw/vexpress.c
+index b615844..454c2bb 100644
+--- a/hw/vexpress.c
++++ b/hw/vexpress.c
+@@ -62,7 +62,6 @@ enum {
+     VE_COMPACTFLASH,
+     VE_CLCD,
+     VE_NORFLASH0,
+-    VE_NORFLASH0ALIAS,
+     VE_NORFLASH1,
+     VE_SRAM,
+     VE_VIDEORAM,
+@@ -104,9 +103,8 @@ static target_phys_addr_t motherboard_legacy_map[] = {
+ };
+ 
+ static target_phys_addr_t motherboard_aseries_map[] = {
+-    /* CS0: 0x00000000 .. 0x0c000000 */
+-    [VE_NORFLASH0] = 0x00000000,
+-    [VE_NORFLASH0ALIAS] = 0x08000000,
++    /* CS0: 0x08000000 .. 0x0c000000 */
++    [VE_NORFLASH0] = 0x08000000,
+     /* CS4: 0x0c000000 .. 0x10000000 */
+     [VE_NORFLASH1] = 0x0c000000,
+     /* CS5: 0x10000000 .. 0x14000000 */
+@@ -413,7 +411,6 @@ static void vexpress_common_init(const VEDBoardInfo *daughterboard,
+     sysbus_create_simple("pl111", map[VE_CLCD], pic[14]);
+ 
+     /* VE_NORFLASH0: not modelled */
+-    /* VE_NORFLASH0ALIAS: not modelled */
+     /* VE_NORFLASH1: not modelled */
+ 
+     sram_size = 0x2000000;
+-- 
+1.7.12.1
+
diff --git a/0239-i386-kvm-bit-10-of-CPUID-8000_0001-.EDX-is-reserved.patch b/0239-i386-kvm-bit-10-of-CPUID-8000_0001-.EDX-is-reserved.patch
new file mode 100644
index 0000000..772314f
--- /dev/null
+++ b/0239-i386-kvm-bit-10-of-CPUID-8000_0001-.EDX-is-reserved.patch
@@ -0,0 +1,36 @@
+From b82c558c781a79e6facf06e7cddf4771b8abf962 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost at redhat.com>
+Date: Thu, 6 Sep 2012 10:05:35 +0000
+Subject: [PATCH] i386: kvm: bit 10 of CPUID[8000_0001].EDX is reserved
+
+Bit 10 of CPUID[8000_0001].EDX is not defined as an alias of
+CPUID[1].EDX[10], so do not duplicate it on
+kvm_arch_get_supported_cpuid().
+
+Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
+Reviewed-By: Igor Mammedov <imammedo at redhat.com>
+Reviewed-by: Don Slutz <Don at CloudSwitch.com>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+(cherry picked from commit b1f4679392a03f2b26a37bfa52e95d6cc4f73d82)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ target-i386/kvm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/target-i386/kvm.c b/target-i386/kvm.c
+index 6790180..acb9369 100644
+--- a/target-i386/kvm.c
++++ b/target-i386/kvm.c
+@@ -165,7 +165,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
+                      * so add missing bits according to the AMD spec:
+                      */
+                     cpuid_1_edx = kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
+-                    ret |= cpuid_1_edx & 0x183f7ff;
++                    ret |= cpuid_1_edx & 0x183f3ff;
+                     break;
+                 }
+                 break;
+-- 
+1.7.12.1
+
diff --git a/0240-fpu-softfloat.c-Return-correctly-signed-values-from-.patch b/0240-fpu-softfloat.c-Return-correctly-signed-values-from-.patch
new file mode 100644
index 0000000..37e5c3a
--- /dev/null
+++ b/0240-fpu-softfloat.c-Return-correctly-signed-values-from-.patch
@@ -0,0 +1,44 @@
+From 41e7a1710ee9787900713a769b7d07677857260a Mon Sep 17 00:00:00 2001
+From: Peter Maydell <peter.maydell at linaro.org>
+Date: Fri, 28 Sep 2012 16:17:03 +0100
+Subject: [PATCH] fpu/softfloat.c: Return correctly signed values from
+ uint64_to_float32
+
+The uint64_to_float32() conversion function was incorrectly always
+returning numbers with the sign bit set (ie negative numbers). Correct
+this so we return positive numbers instead.
+
+Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+(cherry picked from commit e744c06fca438dc08271e626034e632a270c91c8)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ fpu/softfloat.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fpu/softfloat.c b/fpu/softfloat.c
+index b29256a..91497e8 100644
+--- a/fpu/softfloat.c
++++ b/fpu/softfloat.c
+@@ -1238,7 +1238,7 @@ float32 uint64_to_float32( uint64 a STATUS_PARAM )
+     if ( a == 0 ) return float32_zero;
+     shiftCount = countLeadingZeros64( a ) - 40;
+     if ( 0 <= shiftCount ) {
+-        return packFloat32( 1 > 0, 0x95 - shiftCount, a<<shiftCount );
++        return packFloat32(0, 0x95 - shiftCount, a<<shiftCount);
+     }
+     else {
+         shiftCount += 7;
+@@ -1248,7 +1248,7 @@ float32 uint64_to_float32( uint64 a STATUS_PARAM )
+         else {
+             a <<= shiftCount;
+         }
+-        return roundAndPackFloat32( 1 > 0, 0x9C - shiftCount, a STATUS_VAR );
++        return roundAndPackFloat32(0, 0x9C - shiftCount, a STATUS_VAR);
+     }
+ }
+ 
+-- 
+1.7.12.1
+
diff --git a/0241-pseries-Don-t-test-for-MSR_PR-for-hypercalls-under-K.patch b/0241-pseries-Don-t-test-for-MSR_PR-for-hypercalls-under-K.patch
new file mode 100644
index 0000000..7edb0b2
--- /dev/null
+++ b/0241-pseries-Don-t-test-for-MSR_PR-for-hypercalls-under-K.patch
@@ -0,0 +1,66 @@
+From 45af32e160bf339974a74bb8a38384b95aa2f555 Mon Sep 17 00:00:00 2001
+From: David Gibson <david at gibson.dropbear.id.au>
+Date: Tue, 25 Sep 2012 17:12:20 +0000
+Subject: [PATCH] pseries: Don't test for MSR_PR for hypercalls under KVM
+
+PAPR hypercalls should only be invoked from the guest kernel, not guest
+user programs, that is, with MSR[PR]=0.  Currently we check this in
+spapr_hypercall, returning H_PRIVILEGE if MSR[PR]=1.
+
+However, under KVM the state of MSR[PR] is already checked by the host
+kernel before passing the hypercall to qemu, making this check redundant.
+Worse, however, we don't generally synchronize KVM and qemu state on the
+hypercall path, meaning that qemu could incorrectly reject a hypercall
+because it has a stale MSR value.
+
+This patch fixes the problem by moving the privilege test exclusively to
+the TCG hypercall path.
+
+Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
+CC: qemu-stable at nongnu.org
+Signed-off-by: Alexander Graf <agraf at suse.de>
+(cherry picked from commit efcb9383b974114e5f682e531346006f8f2466c0)
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ hw/spapr.c       | 7 ++++++-
+ hw/spapr_hcall.c | 5 -----
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/hw/spapr.c b/hw/spapr.c
+index c34b767..5e55430 100644
+--- a/hw/spapr.c
++++ b/hw/spapr.c
+@@ -556,7 +556,12 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
+ 
+ static void emulate_spapr_hypercall(CPUPPCState *env)
+ {
+-    env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
++    if (msr_pr) {
++        hcall_dprintf("Hypercall made with MSR[PR]=1\n");
++        env->gpr[3] = H_PRIVILEGE;
++    } else {
++        env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]);
++    }
+ }
+ 
+ static void spapr_reset(void *opaque)
+diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
+index abd847f..38098f7 100644
+--- a/hw/spapr_hcall.c
++++ b/hw/spapr_hcall.c
+@@ -713,11 +713,6 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn)
+ target_ulong spapr_hypercall(CPUPPCState *env, target_ulong opcode,
+                              target_ulong *args)
+ {
+-    if (msr_pr) {
+-        hcall_dprintf("Hypercall made with MSR[PR]=1\n");
+-        return H_PRIVILEGE;
+-    }
+-
+     if ((opcode <= MAX_HCALL_OPCODE)
+         && ((opcode & 0x3) == 0)) {
+         spapr_hcall_fn fn = papr_hypercall_table[opcode / 4];
+-- 
+1.7.12.1
+
diff --git a/0242-update-VERSION-for-v1.2.1.patch b/0242-update-VERSION-for-v1.2.1.patch
new file mode 100644
index 0000000..5a2045d
--- /dev/null
+++ b/0242-update-VERSION-for-v1.2.1.patch
@@ -0,0 +1,20 @@
+From 8a0e0b51b5df80c891d264f0492697f26a790cab Mon Sep 17 00:00:00 2001
+From: Michael Roth <mdroth at linux.vnet.ibm.com>
+Date: Thu, 11 Oct 2012 21:46:55 -0500
+Subject: [PATCH] update VERSION for v1.2.1
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+---
+ VERSION | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/VERSION b/VERSION
+index 26aaba0..6085e94 100644
+--- a/VERSION
++++ b/VERSION
+@@ -1 +1 @@
+-1.2.0
++1.2.1
+-- 
+1.7.12.1
+
diff --git a/0101-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch b/0400-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch
similarity index 76%
rename from 0101-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch
rename to 0400-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch
index ea8dfc8..0df1449 100644
--- a/0101-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch
+++ b/0400-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch
@@ -1,9 +1,7 @@
-From 90a59d545ad6759c105b0bfcfca70f574482584f Mon Sep 17 00:00:00 2001
-Message-Id: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From e999fe6e315c5d6f6e8b5d4c689787fc46f10575 Mon Sep 17 00:00:00 2001
 From: Amit Shah <amit.shah at redhat.com>
 Date: Mon, 21 Mar 2011 21:57:47 +0100
-Subject: [PATCH 101/114] char: Split out tcp socket close code in a separate
- function
+Subject: [PATCH] char: Split out tcp socket close code in a separate function
 
 Signed-off-by: Amit Shah <amit.shah at redhat.com>
 Signed-off-by: Cole Robinson <crobinso at redhat.com>
@@ -12,12 +10,12 @@ Signed-off-by: Cole Robinson <crobinso at redhat.com>
  1 file changed, 16 insertions(+), 9 deletions(-)
 
 diff --git a/qemu-char.c b/qemu-char.c
-index 398baf1..8c53c05 100644
+index b082bae..a1fdf88 100644
 --- a/qemu-char.c
 +++ b/qemu-char.c
-@@ -2143,6 +2143,21 @@ static void tcp_chr_accept(void *opaque);
+@@ -2141,6 +2141,21 @@ typedef struct {
  
- static void tcp_chr_connect(void *opaque);
+ static void tcp_chr_accept(void *opaque);
  
 +static void tcp_closed(void *opaque)
 +{
@@ -37,7 +35,7 @@ index 398baf1..8c53c05 100644
  static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
  {
      TCPCharDriver *s = chr->opaque;
-@@ -2302,15 +2317,7 @@ static void tcp_chr_read(void *opaque)
+@@ -2299,15 +2314,7 @@ static void tcp_chr_read(void *opaque)
          len = s->max_size;
      size = tcp_chr_recv(chr, (void *)buf, len);
      if (size == 0) {
@@ -55,5 +53,5 @@ index 398baf1..8c53c05 100644
          if (s->do_telnetopt)
              tcp_chr_process_IAC_bytes(chr, s, buf, &size);
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0102-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch b/0401-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
similarity index 96%
rename from 0102-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
rename to 0401-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
index cd48ce3..58d0b4a 100644
--- a/0102-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
+++ b/0401-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
@@ -1,11 +1,8 @@
-From 25533bd7228f5cd62499a26ba5e32be024002beb Mon Sep 17 00:00:00 2001
-Message-Id: <25533bd7228f5cd62499a26ba5e32be024002beb.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From 5f3ba69a09688b40a4648e8818e4878ae20fc2f6 Mon Sep 17 00:00:00 2001
 From: Amit Shah <amit.shah at redhat.com>
 Date: Mon, 21 Mar 2011 20:31:45 +0100
-Subject: [PATCH 102/114] char: Add a QemuChrHandlers struct to initialise
- chardev handlers
+Subject: [PATCH] char: Add a QemuChrHandlers struct to initialise chardev
+ handlers
 
 Instead of passing each handler in the qemu_add_handlers() function,
 create a struct of handlers that can be passed to the function instead.
@@ -47,10 +44,10 @@ Signed-off-by: Cole Robinson <crobinso at redhat.com>
  31 files changed, 255 insertions(+), 88 deletions(-)
 
 diff --git a/gdbstub.c b/gdbstub.c
-index 5d37dd9..7f6b1cb 100644
+index a91709f..b905c15 100644
 --- a/gdbstub.c
 +++ b/gdbstub.c
-@@ -2929,6 +2929,12 @@ static void gdb_sigterm_handler(int signal)
+@@ -2965,6 +2965,12 @@ static void gdb_sigterm_handler(int signal)
  }
  #endif
  
@@ -63,7 +60,7 @@ index 5d37dd9..7f6b1cb 100644
  int gdbserver_start(const char *device)
  {
      GDBState *s;
-@@ -2958,8 +2964,7 @@ int gdbserver_start(const char *device)
+@@ -2994,8 +3000,7 @@ int gdbserver_start(const char *device)
          if (!chr)
              return -1;
  
@@ -74,7 +71,7 @@ index 5d37dd9..7f6b1cb 100644
  
      s = gdbserver_state;
 diff --git a/hw/cadence_uart.c b/hw/cadence_uart.c
-index d98e531..8f7d64a 100644
+index f8afc4e..c9d3b21 100644
 --- a/hw/cadence_uart.c
 +++ b/hw/cadence_uart.c
 @@ -435,6 +435,12 @@ static void cadence_uart_reset(UartState *s)
@@ -282,7 +279,7 @@ index d4eae43..f2304d2 100644
          DPRINTF("No char dev for uart at 0x%lx\n",
                  (unsigned long)s->iomem.ram_addr);
 diff --git a/hw/ivshmem.c b/hw/ivshmem.c
-index b4d65a6..f20a356 100644
+index 62fe53a..e90f691 100644
 --- a/hw/ivshmem.c
 +++ b/hw/ivshmem.c
 @@ -273,6 +273,18 @@ static void fake_irqfd(void *opaque, const uint8_t *buf, int size) {
@@ -319,7 +316,7 @@ index b4d65a6..f20a356 100644
      }
  
      return chr;
-@@ -641,6 +652,12 @@ static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
+@@ -634,6 +645,12 @@ static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
      msix_write_config(pci_dev, address, val, len);
  }
  
@@ -332,7 +329,7 @@ index b4d65a6..f20a356 100644
  static int pci_ivshmem_init(PCIDevice *dev)
  {
      IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
-@@ -731,8 +748,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
+@@ -720,8 +737,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
  
          s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *));
  
@@ -631,7 +628,7 @@ index 7150eeb..594cf31 100644
  
      return 0;
 diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c
-index 8aa6552..8fc9bdd 100644
+index 69b6e48..0ddfab6 100644
 --- a/hw/usb/dev-serial.c
 +++ b/hw/usb/dev-serial.c
 @@ -475,6 +475,12 @@ static void usb_serial_event(void *opaque, int event)
@@ -658,10 +655,10 @@ index 8aa6552..8fc9bdd 100644
      return 0;
  }
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 10b4fbb..ecb2cd4 100644
+index ab8d79a..8b22c80 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
-@@ -892,6 +892,12 @@ static void usbredir_chardev_event(void *opaque, int event)
+@@ -867,6 +867,12 @@ static void usbredir_chardev_event(void *opaque, int event)
      }
  }
  
@@ -674,7 +671,7 @@ index 10b4fbb..ecb2cd4 100644
  /*
   * init + destroy
   */
-@@ -930,8 +936,7 @@ static int usbredir_initfn(USBDevice *udev)
+@@ -905,8 +911,7 @@ static int usbredir_initfn(USBDevice *udev)
  
      /* Let the backend know we are ready */
      qemu_chr_fe_open(dev->cs);
@@ -782,10 +779,10 @@ index d0f32db..33f0cd5 100644
  }
  
 diff --git a/monitor.c b/monitor.c
-index 29e4287..c14698d 100644
+index f45cf92..99eee98 100644
 --- a/monitor.c
 +++ b/monitor.c
-@@ -4941,6 +4941,18 @@ static void sortcmdlist(void)
+@@ -4942,6 +4942,18 @@ static void sortcmdlist(void)
   * End:
   */
  
@@ -804,7 +801,7 @@ index 29e4287..c14698d 100644
  void monitor_init(CharDriverState *chr, int flags)
  {
      static int is_first_init = 1;
-@@ -4964,14 +4976,12 @@ void monitor_init(CharDriverState *chr, int flags)
+@@ -4965,14 +4977,12 @@ void monitor_init(CharDriverState *chr, int flags)
      if (monitor_ctrl_mode(mon)) {
          mon->mc = g_malloc0(sizeof(MonitorControl));
          /* Control mode requires special handlers */
@@ -848,7 +845,7 @@ index 8db66ea..63542cb 100644
      return 0;
  
 diff --git a/qemu-char.c b/qemu-char.c
-index 8c53c05..19ae993 100644
+index a1fdf88..bd443db 100644
 --- a/qemu-char.c
 +++ b/qemu-char.c
 @@ -192,19 +192,26 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
@@ -961,5 +958,5 @@ index fbfab4e..4ab5b69 100644
  
      inbuf = g_string_new("");
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0103-iohandlers-Add-enable-disable_write_fd_handler-funct.patch b/0402-iohandlers-Add-enable-disable_write_fd_handler-funct.patch
similarity index 79%
rename from 0103-iohandlers-Add-enable-disable_write_fd_handler-funct.patch
rename to 0402-iohandlers-Add-enable-disable_write_fd_handler-funct.patch
index 060937e..cfc7cd2 100644
--- a/0103-iohandlers-Add-enable-disable_write_fd_handler-funct.patch
+++ b/0402-iohandlers-Add-enable-disable_write_fd_handler-funct.patch
@@ -1,11 +1,7 @@
-From 1980701650660459d35db0f956f536c8790e2056 Mon Sep 17 00:00:00 2001
-Message-Id: <1980701650660459d35db0f956f536c8790e2056.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From 2ac23d2134611b4e5b0fb389911bd03baa685df3 Mon Sep 17 00:00:00 2001
 From: Amit Shah <amit.shah at redhat.com>
 Date: Mon, 21 Mar 2011 20:32:58 +0100
-Subject: [PATCH 103/114] iohandlers: Add enable/disable_write_fd_handler()
- functions
+Subject: [PATCH] iohandlers: Add enable/disable_write_fd_handler() functions
 
 These will be used to provide a cleaner API for the nonblocking case.
 
@@ -17,7 +13,7 @@ Signed-off-by: Cole Robinson <crobinso at redhat.com>
  2 files changed, 38 insertions(+)
 
 diff --git a/iohandler.c b/iohandler.c
-index dea4355..e663f83 100644
+index a2d871b..c00fecd 100644
 --- a/iohandler.c
 +++ b/iohandler.c
 @@ -45,6 +45,41 @@ typedef struct IOHandlerRecord {
@@ -77,5 +73,5 @@ index dce1cd9..eb31273 100644
   * qemu_set_fd_handler2: Register a file descriptor with the main loop
   *
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0104-char-Add-framework-for-a-write-unblocked-callback.patch b/0403-char-Add-framework-for-a-write-unblocked-callback.patch
similarity index 81%
rename from 0104-char-Add-framework-for-a-write-unblocked-callback.patch
rename to 0403-char-Add-framework-for-a-write-unblocked-callback.patch
index aed649e..67f83f6 100644
--- a/0104-char-Add-framework-for-a-write-unblocked-callback.patch
+++ b/0403-char-Add-framework-for-a-write-unblocked-callback.patch
@@ -1,10 +1,7 @@
-From 8767b055fe84811f1caec3854b55a5d5541f72c9 Mon Sep 17 00:00:00 2001
-Message-Id: <8767b055fe84811f1caec3854b55a5d5541f72c9.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From 8ca97117074b5eb12bf9cb0b25548116174601a8 Mon Sep 17 00:00:00 2001
 From: Amit Shah <amit.shah at redhat.com>
 Date: Mon, 21 Mar 2011 21:41:42 +0100
-Subject: [PATCH 104/114] char: Add framework for a 'write unblocked' callback
+Subject: [PATCH] char: Add framework for a 'write unblocked' callback
 
 The char layer can let users know that the driver will block on further
 input.  For users interested in not blocking, they can assign a function
@@ -20,7 +17,7 @@ Signed-off-by: Cole Robinson <crobinso at redhat.com>
  2 files changed, 7 insertions(+)
 
 diff --git a/qemu-char.c b/qemu-char.c
-index 19ae993..2c573fb 100644
+index bd443db..b5266d1 100644
 --- a/qemu-char.c
 +++ b/qemu-char.c
 @@ -211,11 +211,14 @@ void qemu_chr_add_handlers(CharDriverState *s,
@@ -61,5 +58,5 @@ index dfa8c2d..b5e23a4 100644
  };
  
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0105-char-Update-send_all-to-handle-nonblocking-chardev-w.patch b/0404-char-Update-send_all-to-handle-nonblocking-chardev-w.patch
similarity index 78%
rename from 0105-char-Update-send_all-to-handle-nonblocking-chardev-w.patch
rename to 0404-char-Update-send_all-to-handle-nonblocking-chardev-w.patch
index 6d6f3ed..b53d594 100644
--- a/0105-char-Update-send_all-to-handle-nonblocking-chardev-w.patch
+++ b/0404-char-Update-send_all-to-handle-nonblocking-chardev-w.patch
@@ -1,11 +1,8 @@
-From 1af0111d871f088f25e7854fe61302e1909ba4c4 Mon Sep 17 00:00:00 2001
-Message-Id: <1af0111d871f088f25e7854fe61302e1909ba4c4.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From dd7b138971deb72c7e37c4b79665df6ff5c1130b Mon Sep 17 00:00:00 2001
 From: Amit Shah <amit.shah at redhat.com>
 Date: Mon, 21 Mar 2011 22:00:27 +0100
-Subject: [PATCH 105/114] char: Update send_all() to handle nonblocking
- chardev write requests
+Subject: [PATCH] char: Update send_all() to handle nonblocking chardev write
+ requests
 
 The send_all function is modified to return to the caller in case the
 driver cannot handle any more data.  It returns -EAGAIN or
@@ -20,28 +17,12 @@ commits will add such capability.
 Signed-off-by: Amit Shah <amit.shah at redhat.com>
 Signed-off-by: Cole Robinson <crobinso at redhat.com>
 ---
- net/socket.c  |  4 ++--
  qemu-char.c   | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
  qemu_socket.h |  2 +-
- 3 files changed, 66 insertions(+), 9 deletions(-)
+ 2 files changed, 64 insertions(+), 7 deletions(-)
 
-diff --git a/net/socket.c b/net/socket.c
-index c172c24..aa7c99e 100644
---- a/net/socket.c
-+++ b/net/socket.c
-@@ -53,8 +53,8 @@ static ssize_t net_socket_receive(NetClientState *nc, const uint8_t *buf, size_t
-     uint32_t len;
-     len = htonl(size);
- 
--    send_all(s->fd, (const uint8_t *)&len, sizeof(len));
--    return send_all(s->fd, buf, size);
-+    send_all(NULL, s->fd, (const uint8_t *)&len, sizeof(len));
-+    return send_all(NULL, s->fd, buf, size);
- }
- 
- static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, size_t size)
 diff --git a/qemu-char.c b/qemu-char.c
-index 2c573fb..c2a3138 100644
+index b5266d1..b46cc97 100644
 --- a/qemu-char.c
 +++ b/qemu-char.c
 @@ -508,7 +508,7 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
@@ -157,7 +138,7 @@ index 2c573fb..c2a3138 100644
  }
  
  static int pty_chr_read_poll(void *opaque)
-@@ -2176,8 +2226,15 @@ static void tcp_closed(void *opaque)
+@@ -2174,8 +2224,15 @@ static void tcp_closed(void *opaque)
  static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
  {
      TCPCharDriver *s = chr->opaque;
@@ -172,10 +153,10 @@ index 2c573fb..c2a3138 100644
 +        }
 +        return ret;
      } else {
-         /* (Re-)connect for unconnected writing */
-         tcp_chr_connect(chr);
+         /* XXX: indicate an error ? */
+         return len;
 diff --git a/qemu_socket.h b/qemu_socket.h
-index 30ae6af..fc58c8d 100644
+index 3e8aee9..a537d86 100644
 --- a/qemu_socket.h
 +++ b/qemu_socket.h
 @@ -36,7 +36,7 @@ int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
@@ -185,8 +166,8 @@ index 30ae6af..fc58c8d 100644
 -int send_all(int fd, const void *buf, int len1);
 +int send_all(CharDriverState *chr, int fd, const void *buf, int len1);
  
- /* New, ipv6-ready socket helper functions, see qemu-sockets.c */
- int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp);
+ /* callback function for nonblocking connect
+  * valid fd on success, negative error code on failure
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0106-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch b/0405-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch
similarity index 79%
rename from 0106-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch
rename to 0405-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch
index a3ddec7..830ed84 100644
--- a/0106-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch
+++ b/0405-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch
@@ -1,11 +1,8 @@
-From 2fa4be9d3b84d214f4ea9da8513ef664f412ad09 Mon Sep 17 00:00:00 2001
-Message-Id: <2fa4be9d3b84d214f4ea9da8513ef664f412ad09.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From 625915146f56f77c275be1aee160f40183008b8d Mon Sep 17 00:00:00 2001
 From: Amit Shah <amit.shah at redhat.com>
 Date: Mon, 21 Mar 2011 22:02:47 +0100
-Subject: [PATCH 106/114] char: Equip the unix/tcp backend to handle
- nonblocking writes#
+Subject: [PATCH] char: Equip the unix/tcp backend to handle nonblocking
+ writes#
 
 Now that the infrastructure is in place to return -EAGAIN to callers,
 individual char drivers can set their update_fd_handlers() function to
@@ -22,7 +19,7 @@ Signed-off-by: Cole Robinson <crobinso at redhat.com>
  1 file changed, 34 insertions(+)
 
 diff --git a/qemu-char.c b/qemu-char.c
-index c2a3138..5e136fd 100644
+index b46cc97..9f8608a 100644
 --- a/qemu-char.c
 +++ b/qemu-char.c
 @@ -106,6 +106,19 @@
@@ -45,7 +42,7 @@ index c2a3138..5e136fd 100644
  void qemu_chr_be_event(CharDriverState *s, int event)
  {
      /* Keep track if the char device is open */
-@@ -2504,6 +2517,25 @@ static void tcp_chr_close(CharDriverState *chr)
+@@ -2503,6 +2516,25 @@ static void tcp_chr_close(CharDriverState *chr)
      qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
  }
  
@@ -71,7 +68,7 @@ index c2a3138..5e136fd 100644
  static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
  {
      CharDriverState *chr = NULL;
-@@ -2558,6 +2590,8 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
+@@ -2557,6 +2589,8 @@ static CharDriverState *qemu_chr_open_socket(QemuOpts *opts)
      chr->chr_close = tcp_chr_close;
      chr->get_msgfd = tcp_get_msgfd;
      chr->chr_add_client = tcp_chr_add_client;
@@ -81,5 +78,5 @@ index c2a3138..5e136fd 100644
      if (is_listen) {
          s->listen_fd = fd;
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0107-char-Throttle-when-host-connection-is-down.patch b/0406-char-Throttle-when-host-connection-is-down.patch
similarity index 77%
rename from 0107-char-Throttle-when-host-connection-is-down.patch
rename to 0406-char-Throttle-when-host-connection-is-down.patch
index ba767b6..2190637 100644
--- a/0107-char-Throttle-when-host-connection-is-down.patch
+++ b/0406-char-Throttle-when-host-connection-is-down.patch
@@ -1,10 +1,7 @@
-From 33883808e5203f398ceac6eaf0b6647326df9c1f Mon Sep 17 00:00:00 2001
-Message-Id: <33883808e5203f398ceac6eaf0b6647326df9c1f.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From 542fa14530022044ab577c543fba83202d52b703 Mon Sep 17 00:00:00 2001
 From: Amit Shah <amit.shah at redhat.com>
 Date: Mon, 21 Mar 2011 22:05:10 +0100
-Subject: [PATCH 107/114] char: Throttle when host connection is down#
+Subject: [PATCH] char: Throttle when host connection is down#
 
 When the host-side connection goes down, throttle the virtio-serial bus
 and later unthrottle when a connection gets established.  This helps
@@ -24,7 +21,7 @@ Signed-off-by: Cole Robinson <crobinso at redhat.com>
  1 file changed, 14 insertions(+)
 
 diff --git a/qemu-char.c b/qemu-char.c
-index 5e136fd..d86ee88 100644
+index 9f8608a..bfc94a5 100644
 --- a/qemu-char.c
 +++ b/qemu-char.c
 @@ -140,6 +140,9 @@ static void qemu_chr_generic_open_bh(void *opaque)
@@ -37,7 +34,7 @@ index 5e136fd..d86ee88 100644
      qemu_bh_delete(s->bh);
      s->bh = NULL;
  }
-@@ -2246,6 +2249,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+@@ -2244,6 +2247,17 @@ static int tcp_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
          ret = send_all(chr, s->fd, buf, len);
          if (ret == -1 && errno == EPIPE) {
              tcp_closed(chr);
@@ -56,5 +53,5 @@ index 5e136fd..d86ee88 100644
          return ret;
      } else {
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0108-virtio-console-Enable-port-throttling-when-chardev-i.patch b/0407-virtio-console-Enable-port-throttling-when-chardev-i.patch
similarity index 76%
rename from 0108-virtio-console-Enable-port-throttling-when-chardev-i.patch
rename to 0407-virtio-console-Enable-port-throttling-when-chardev-i.patch
index a9dab46..85630c0 100644
--- a/0108-virtio-console-Enable-port-throttling-when-chardev-i.patch
+++ b/0407-virtio-console-Enable-port-throttling-when-chardev-i.patch
@@ -1,11 +1,8 @@
-From 675cb3b8588b2ad494b304998bbf035144ed99be Mon Sep 17 00:00:00 2001
-Message-Id: <675cb3b8588b2ad494b304998bbf035144ed99be.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From feeea13d5eac9c0dd5da1ee7639a57ca519f4c91 Mon Sep 17 00:00:00 2001
 From: Amit Shah <amit.shah at redhat.com>
 Date: Mon, 21 Mar 2011 22:06:41 +0100
-Subject: [PATCH 108/114] virtio-console: Enable port throttling when chardev
- is slow to consume data
+Subject: [PATCH] virtio-console: Enable port throttling when chardev is slow
+ to consume data
 
 When a chardev indicates it can't accept more data, we tell the
 virtio-serial code to stop sending us any more data till we tell
@@ -49,5 +46,5 @@ index 066590c..2b5e515 100644
  
  static int virtconsole_initfn(VirtIOSerialPort *port)
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0109-spice-qemu-char.c-add-throttling.patch b/0408-spice-qemu-char.c-add-throttling.patch
similarity index 92%
rename from 0109-spice-qemu-char.c-add-throttling.patch
rename to 0408-spice-qemu-char.c-add-throttling.patch
index 950f861..23018ec 100644
--- a/0109-spice-qemu-char.c-add-throttling.patch
+++ b/0408-spice-qemu-char.c-add-throttling.patch
@@ -1,10 +1,7 @@
-From 3f1c594ea851fdee517a824b1eed3e034cd051ec Mon Sep 17 00:00:00 2001
-Message-Id: <3f1c594ea851fdee517a824b1eed3e034cd051ec.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From 2d1cf5b1be8cbd9c5a8c5f96ca699676fc1b23a7 Mon Sep 17 00:00:00 2001
 From: Alon Levy <alevy at redhat.com>
 Date: Tue, 22 Mar 2011 12:27:59 +0200
-Subject: [PATCH 109/114] spice-qemu-char.c: add throttling
+Subject: [PATCH] spice-qemu-char.c: add throttling
 
 BZ: 672191
 
@@ -134,5 +131,5 @@ index 09aa22d..fba2bfb 100644
  #if SPICE_SERVER_VERSION < 0x000901
      /* See comment in vmc_state() */
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0110-spice-qemu-char.c-remove-intermediate-buffer.patch b/0409-spice-qemu-char.c-remove-intermediate-buffer.patch
similarity index 86%
rename from 0110-spice-qemu-char.c-remove-intermediate-buffer.patch
rename to 0409-spice-qemu-char.c-remove-intermediate-buffer.patch
index 395019b..e1c6f0a 100644
--- a/0110-spice-qemu-char.c-remove-intermediate-buffer.patch
+++ b/0409-spice-qemu-char.c-remove-intermediate-buffer.patch
@@ -1,10 +1,7 @@
-From 682f29243b10ace00a42fed9920a94938abe2706 Mon Sep 17 00:00:00 2001
-Message-Id: <682f29243b10ace00a42fed9920a94938abe2706.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From fb481324641fc36e6f58aca8d8e5ada0536332f2 Mon Sep 17 00:00:00 2001
 From: Alon Levy <alevy at redhat.com>
 Date: Tue, 22 Mar 2011 12:28:00 +0200
-Subject: [PATCH 110/114] spice-qemu-char.c: remove intermediate buffer
+Subject: [PATCH] spice-qemu-char.c: remove intermediate buffer
 
 BZ: 672191
 upstream: not submitted (explained below)
@@ -72,5 +69,5 @@ index fba2bfb..ef44bc0 100644
          /* We'll get passed in the unconsumed data with the next call */
          s->datalen = 0;
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0111-usb-redir-Add-flow-control-support.patch b/0410-usb-redir-Add-flow-control-support.patch
similarity index 64%
rename from 0111-usb-redir-Add-flow-control-support.patch
rename to 0410-usb-redir-Add-flow-control-support.patch
index 76b5ca5..8506b22 100644
--- a/0111-usb-redir-Add-flow-control-support.patch
+++ b/0410-usb-redir-Add-flow-control-support.patch
@@ -1,22 +1,19 @@
-From 70a31fcb3f1238e92279cdc023b83ba3a3042cff Mon Sep 17 00:00:00 2001
-Message-Id: <70a31fcb3f1238e92279cdc023b83ba3a3042cff.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From 539b42dbeefbf2fc7dc40ab7c1b5d9592a87d9b8 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Tue, 19 Jul 2011 10:56:19 +0200
-Subject: [PATCH 111/114] usb-redir: Add flow control support
+Subject: [PATCH] usb-redir: Add flow control support
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Cole Robinson <crobinso at redhat.com>
 ---
- hw/usb/redirect.c | 26 ++++++++++++++++++++++++--
- 1 file changed, 24 insertions(+), 2 deletions(-)
+ hw/usb/redirect.c | 22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index ecb2cd4..1460515 100644
+index 8b22c80..b7c7f1e 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
-@@ -236,12 +236,22 @@ static int usbredir_read(void *priv, uint8_t *data, int count)
+@@ -229,12 +229,22 @@ static int usbredir_read(void *priv, uint8_t *data, int count)
  static int usbredir_write(void *priv, uint8_t *data, int count)
  {
      USBRedirDevice *dev = priv;
@@ -41,7 +38,7 @@ index ecb2cd4..1460515 100644
  }
  
  /*
-@@ -892,10 +902,18 @@ static void usbredir_chardev_event(void *opaque, int event)
+@@ -867,10 +877,18 @@ static void usbredir_chardev_event(void *opaque, int event)
      }
  }
  
@@ -61,5 +58,5 @@ index ecb2cd4..1460515 100644
  
  /*
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0112-virtio-serial-bus-replay-guest_open-on-migration.patch b/0411-virtio-serial-bus-replay-guest_open-on-migration.patch
similarity index 81%
rename from 0112-virtio-serial-bus-replay-guest_open-on-migration.patch
rename to 0411-virtio-serial-bus-replay-guest_open-on-migration.patch
index 1398ec1..7cdc9bb 100644
--- a/0112-virtio-serial-bus-replay-guest_open-on-migration.patch
+++ b/0411-virtio-serial-bus-replay-guest_open-on-migration.patch
@@ -1,10 +1,7 @@
-From 452bc9fd704b7f51a63effb05c9283a9aaf7bc99 Mon Sep 17 00:00:00 2001
-Message-Id: <452bc9fd704b7f51a63effb05c9283a9aaf7bc99.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From a9bc20afc1f0604ee81c23b7c67d627e51d2e8d4 Mon Sep 17 00:00:00 2001
 From: Alon Levy <alevy at redhat.com>
 Date: Thu, 28 Jul 2011 15:08:48 +0300
-Subject: [PATCH 112/114] virtio-serial-bus: replay guest_open on migration
+Subject: [PATCH] virtio-serial-bus: replay guest_open on migration
 
 When migrating a host with with a spice agent running the mouse becomes
 non operational after the migration. This is rhbz #725965.
@@ -50,5 +47,5 @@ index 82073f5..18c2ed3 100644
          if (host_connected != port->host_connected) {
              /*
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0113-char-Disable-write-callback-if-throttled-chardev-is-.patch b/0412-char-Disable-write-callback-if-throttled-chardev-is-.patch
similarity index 68%
rename from 0113-char-Disable-write-callback-if-throttled-chardev-is-.patch
rename to 0412-char-Disable-write-callback-if-throttled-chardev-is-.patch
index 4f449bb..ae0be6f 100644
--- a/0113-char-Disable-write-callback-if-throttled-chardev-is-.patch
+++ b/0412-char-Disable-write-callback-if-throttled-chardev-is-.patch
@@ -1,10 +1,7 @@
-From 34b7ca715ee45925b76fbeb23a24c16015adba33 Mon Sep 17 00:00:00 2001
-Message-Id: <34b7ca715ee45925b76fbeb23a24c16015adba33.1346162949.git.crobinso at redhat.com>
-In-Reply-To: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
-References: <90a59d545ad6759c105b0bfcfca70f574482584f.1346162949.git.crobinso at redhat.com>
+From f3551d3640f3436b0e5505fd208cbd7bbfef411f Mon Sep 17 00:00:00 2001
 From: Amit Shah <amit.shah at redhat.com>
 Date: Fri, 2 Dec 2011 15:42:55 +0530
-Subject: [PATCH 113/114] char: Disable write callback if throttled chardev is
+Subject: [PATCH] char: Disable write callback if throttled chardev is
  detached
 
 If a throttled chardev is detached from the frontend device, all future
@@ -20,7 +17,7 @@ Signed-off-by: Cole Robinson <crobinso at redhat.com>
  1 file changed, 5 insertions(+)
 
 diff --git a/qemu-char.c b/qemu-char.c
-index d86ee88..9defbec 100644
+index bfc94a5..67a6d73 100644
 --- a/qemu-char.c
 +++ b/qemu-char.c
 @@ -223,6 +223,11 @@ void qemu_chr_add_handlers(CharDriverState *s,
@@ -36,5 +33,5 @@ index d86ee88..9defbec 100644
      }
      s->chr_can_read = handlers->fd_can_read;
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0500-qxl-disallow-unknown-revisions.patch b/0500-qxl-disallow-unknown-revisions.patch
new file mode 100644
index 0000000..331ca45
--- /dev/null
+++ b/0500-qxl-disallow-unknown-revisions.patch
@@ -0,0 +1,31 @@
+From 4b9d4103e5ff91b022ee8e9522040829f009543a Mon Sep 17 00:00:00 2001
+From: Alon Levy <alevy at redhat.com>
+Date: Tue, 21 Aug 2012 13:51:32 +0300
+Subject: [PATCH] qxl: disallow unknown revisions
+
+Signed-off-by: Alon Levy <alevy at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ hw/qxl.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/hw/qxl.c b/hw/qxl.c
+index 59bf822..71879fe 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -1873,9 +1873,9 @@ static int qxl_init_common(PCIQXLDevice *qxl)
+         break;
+ #endif
+     default:
+-        pci_device_rev = QXL_DEFAULT_REVISION;
+-        io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
+-        break;
++        error_report("Invalid revision %d for qxl device (max %d)",
++                     qxl->revision, QXL_DEFAULT_REVISION);
++        return -1;
+     }
+ 
+     pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
+-- 
+1.7.12.1
+
diff --git a/0212-spice-make-number-of-surfaces-runtime-configurable.patch b/0501-spice-make-number-of-surfaces-runtime-configurable.patch
similarity index 88%
rename from 0212-spice-make-number-of-surfaces-runtime-configurable.patch
rename to 0501-spice-make-number-of-surfaces-runtime-configurable.patch
index 0101a20..b55c3df 100644
--- a/0212-spice-make-number-of-surfaces-runtime-configurable.patch
+++ b/0501-spice-make-number-of-surfaces-runtime-configurable.patch
@@ -1,7 +1,7 @@
-From 72e437d9b775cb92f93c3acd0109239f1bb3e6e2 Mon Sep 17 00:00:00 2001
+From 1c74b60fa972c9489f9cf8fa59165dedd0c23de2 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 4 Sep 2012 11:39:41 +0200
-Subject: [PATCH 212/215] spice: make number of surfaces runtime-configurable.
+Subject: [PATCH] spice: make number of surfaces runtime-configurable.
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
 ---
@@ -12,10 +12,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  4 files changed, 23 insertions(+), 19 deletions(-)
 
 diff --git a/hw/qxl.c b/hw/qxl.c
-index adf17fd..8725f67 100644
+index 71879fe..83df499 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
-@@ -236,7 +236,8 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
+@@ -238,7 +238,8 @@ static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl)
  {
      trace_qxl_spice_destroy_surfaces_complete(qxl->id);
      qemu_mutex_lock(&qxl->track_lock);
@@ -25,7 +25,7 @@ index adf17fd..8725f67 100644
      qxl->guest_surfaces.count = 0;
      qemu_mutex_unlock(&qxl->track_lock);
  }
-@@ -345,7 +346,7 @@ static void init_qxl_rom(PCIQXLDevice *d)
+@@ -347,7 +348,7 @@ static void init_qxl_rom(PCIQXLDevice *d)
      rom->slot_id_bits  = MEMSLOT_SLOT_BITS;
      rom->slots_start   = 1;
      rom->slots_end     = NUM_MEMSLOTS - 1;
@@ -34,7 +34,7 @@ index adf17fd..8725f67 100644
  
      for (i = 0, n = 0; i < ARRAY_SIZE(qxl_modes); i++) {
          fb = qxl_modes[i].y_res * qxl_modes[i].stride;
-@@ -449,9 +450,9 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
+@@ -451,9 +452,9 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
          }
          uint32_t id = le32_to_cpu(cmd->surface_id);
  
@@ -46,7 +46,7 @@ index adf17fd..8725f67 100644
              return 1;
          }
          qemu_mutex_lock(&qxl->track_lock);
-@@ -527,7 +528,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
+@@ -529,7 +530,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
      info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
      info->internal_groupslot_id = 0;
      info->qxl_ram_size = le32_to_cpu(qxl->shadow_rom.num_pages) << TARGET_PAGE_BITS;
@@ -55,7 +55,7 @@ index adf17fd..8725f67 100644
  }
  
  static const char *qxl_mode_to_string(int mode)
-@@ -1436,7 +1437,7 @@ async_common:
+@@ -1438,7 +1439,7 @@ async_common:
          QXLCookie *cookie = NULL;
          QXLRect update = d->ram->update_area;
  
@@ -64,7 +64,7 @@ index adf17fd..8725f67 100644
              qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: invalid surface id %d\n",
                                d->ram->update_surface);
              return;
-@@ -1529,7 +1530,7 @@ async_common:
+@@ -1538,7 +1539,7 @@ async_common:
          }
          break;
      case QXL_IO_DESTROY_SURFACE_WAIT:
@@ -73,7 +73,7 @@ index adf17fd..8725f67 100644
              qxl_set_guest_bug(d, "QXL_IO_DESTROY_SURFACE (async=%d):"
                               "%" PRIu64 " >= NUM_SURFACES", async, val);
              goto cancel_async;
-@@ -1707,7 +1708,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
+@@ -1717,7 +1718,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
      vram_start =  (intptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
  
      /* dirty the off-screen surfaces */
@@ -82,7 +82,7 @@ index adf17fd..8725f67 100644
          QXLSurfaceCmd *cmd;
          intptr_t surface_offset;
          int surface_size;
-@@ -1835,7 +1836,6 @@ static int qxl_init_common(PCIQXLDevice *qxl)
+@@ -1845,7 +1846,6 @@ static int qxl_init_common(PCIQXLDevice *qxl)
      qxl->mode = QXL_MODE_UNDEFINED;
      qxl->generation = 1;
      qxl->num_memslots = NUM_MEMSLOTS;
@@ -90,7 +90,7 @@ index adf17fd..8725f67 100644
      qemu_mutex_init(&qxl->track_lock);
      qemu_mutex_init(&qxl->async_lock);
      qxl->current_async = QXL_UNDEFINED_IO;
-@@ -1877,6 +1877,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
+@@ -1887,6 +1887,7 @@ static int qxl_init_common(PCIQXLDevice *qxl)
      init_qxl_rom(qxl);
      init_qxl_ram(qxl);
  
@@ -98,7 +98,7 @@ index adf17fd..8725f67 100644
      memory_region_init_ram(&qxl->vram_bar, "qxl.vram", qxl->vram_size);
      vmstate_register_ram(&qxl->vram_bar, &qxl->pci.qdev);
      memory_region_init_alias(&qxl->vram32_bar, "qxl.vram32", &qxl->vram_bar,
-@@ -2042,8 +2043,8 @@ static int qxl_post_load(void *opaque, int version)
+@@ -2052,8 +2053,8 @@ static int qxl_post_load(void *opaque, int version)
          qxl_create_guest_primary(d, 1, QXL_SYNC);
  
          /* replay surface-create and cursor-set commands */
@@ -109,7 +109,7 @@ index adf17fd..8725f67 100644
              if (d->guest_surfaces.cmds[in] == 0) {
                  continue;
              }
-@@ -2143,9 +2144,10 @@ static VMStateDescription qxl_vmstate = {
+@@ -2153,9 +2154,10 @@ static VMStateDescription qxl_vmstate = {
                               qxl_memslot, struct guest_slots),
          VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, 0,
                         qxl_surface, QXLSurfaceCreate),
@@ -123,7 +123,7 @@ index adf17fd..8725f67 100644
          VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
          VMSTATE_END_OF_LIST()
      },
-@@ -2173,6 +2175,7 @@ static Property qxl_properties[] = {
+@@ -2183,6 +2185,7 @@ static Property qxl_properties[] = {
          DEFINE_PROP_UINT32("vram_size_mb", PCIQXLDevice, vram32_size_mb, -1),
          DEFINE_PROP_UINT32("vram64_size_mb", PCIQXLDevice, vram_size_mb, -1),
          DEFINE_PROP_UINT32("vgamem_mb", PCIQXLDevice, vgamem_size_mb, 16),
@@ -197,5 +197,5 @@ index bcff114..512ab78 100644
      QXLRect dirty;
      int notify;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0213-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch b/0502-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch
similarity index 86%
rename from 0213-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch
rename to 0502-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch
index 4427f78..41c05f5 100644
--- a/0213-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch
+++ b/0502-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch
@@ -1,8 +1,7 @@
-From 44eab2c48c8b090fff8b7ded39b40dae6c6ce003 Mon Sep 17 00:00:00 2001
+From 0fe78ffd13555bed86a41acf96cdc15ece961b0d Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= <ssp at redhat.com>
 Date: Tue, 4 Sep 2012 10:14:48 -0400
-Subject: [PATCH 213/215] qxl: Add set_client_capabilities() interface to
- QXLInterface
+Subject: [PATCH] qxl: Add set_client_capabilities() interface to QXLInterface
 
 This new interface lets spice server inform the guest whether
 
@@ -20,10 +19,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 23 insertions(+)
 
 diff --git a/hw/qxl.c b/hw/qxl.c
-index 8725f67..2aa5848 100644
+index 83df499..d8b67b2 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
-@@ -944,6 +944,26 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
+@@ -946,6 +946,26 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
      }
  }
  
@@ -50,7 +49,7 @@ index 8725f67..2aa5848 100644
  static const QXLInterface qxl_interface = {
      .base.type               = SPICE_INTERFACE_QXL,
      .base.description        = "qxl gpu",
-@@ -965,6 +985,9 @@ static const QXLInterface qxl_interface = {
+@@ -967,6 +987,9 @@ static const QXLInterface qxl_interface = {
      .flush_resources         = interface_flush_resources,
      .async_complete          = interface_async_complete,
      .update_area_complete    = interface_update_area_complete,
@@ -61,5 +60,5 @@ index 8725f67..2aa5848 100644
  
  static void qxl_enter_vga_mode(PCIQXLDevice *d)
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0214-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch b/0503-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch
similarity index 76%
rename from 0214-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch
rename to 0503-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch
index cfae0f3..899e280 100644
--- a/0214-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch
+++ b/0503-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch
@@ -1,7 +1,7 @@
-From 666f88952fe1bcf84ba857f417a5d25f86bbf38b Mon Sep 17 00:00:00 2001
+From 0dcef831a875505fdaffb824de9e4450273ea53d Mon Sep 17 00:00:00 2001
 From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= <ssp at redhat.com>
 Date: Tue, 4 Sep 2012 10:14:49 -0400
-Subject: [PATCH 214/215] Remove #ifdef QXL_COMMAND_FLAG_COMPAT_16BPP
+Subject: [PATCH] Remove #ifdef QXL_COMMAND_FLAG_COMPAT_16BPP
 
 We require spice >= 0.8 now, so this flag is always present.
 
@@ -12,10 +12,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 2 deletions(-)
 
 diff --git a/hw/qxl.c b/hw/qxl.c
-index 2aa5848..b726c19 100644
+index d8b67b2..a6e6cf1 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
-@@ -1359,11 +1359,9 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
+@@ -1361,11 +1361,9 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
  
      d->mode = QXL_MODE_COMPAT;
      d->cmdflags = QXL_COMMAND_FLAG_COMPAT;
@@ -28,5 +28,5 @@ index 2aa5848..b726c19 100644
      d->rom->mode = cpu_to_le32(modenr);
      qxl_rom_set_dirty(d);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0215-spice-switch-to-queue-for-vga-mode-updates.patch b/0504-spice-switch-to-queue-for-vga-mode-updates.patch
similarity index 94%
rename from 0215-spice-switch-to-queue-for-vga-mode-updates.patch
rename to 0504-spice-switch-to-queue-for-vga-mode-updates.patch
index 9bd3562..b9726e8 100644
--- a/0215-spice-switch-to-queue-for-vga-mode-updates.patch
+++ b/0504-spice-switch-to-queue-for-vga-mode-updates.patch
@@ -1,7 +1,7 @@
-From 20b7c4b95c7f0c93000a68779e9cb9e63cff68da Mon Sep 17 00:00:00 2001
+From 244ff52221b4c4181422861a930d8f755a1a5c08 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Wed, 5 Sep 2012 08:25:08 +0200
-Subject: [PATCH 215/293] spice: switch to queue for vga mode updates
+Subject: [PATCH] spice: switch to queue for vga mode updates
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
 ---
@@ -11,10 +11,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  3 files changed, 19 insertions(+), 15 deletions(-)
 
 diff --git a/hw/qxl.c b/hw/qxl.c
-index b726c19..833cd77 100644
+index a6e6cf1..2ec4341 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
-@@ -597,9 +597,9 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
+@@ -599,9 +599,9 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
      case QXL_MODE_VGA:
          ret = false;
          qemu_mutex_lock(&qxl->ssd.lock);
@@ -134,5 +134,5 @@ index 512ab78..3fcb6fe 100644
  
  int qemu_spice_rect_is_empty(const QXLRect* r);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0216-spice-split-qemu_spice_create_update.patch b/0505-spice-split-qemu_spice_create_update.patch
similarity index 95%
rename from 0216-spice-split-qemu_spice_create_update.patch
rename to 0505-spice-split-qemu_spice_create_update.patch
index 711382c..d761fcf 100644
--- a/0216-spice-split-qemu_spice_create_update.patch
+++ b/0505-spice-split-qemu_spice_create_update.patch
@@ -1,7 +1,7 @@
-From a754b60d7602dae18120ab014735927058e89983 Mon Sep 17 00:00:00 2001
+From 6d196973a9adba583cf9bbc5a4196a58f2cb0eb3 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Wed, 5 Sep 2012 08:52:23 +0200
-Subject: [PATCH 216/293] spice: split qemu_spice_create_update
+Subject: [PATCH] spice: split qemu_spice_create_update
 
 Creating one function which creates a single update for a given
 rectangle.  And one (for now) pretty simple wrapper around it to
@@ -90,5 +90,5 @@ index 59c5fd7..6f68f28 100644
   * Called from spice server thread context (via interface_release_ressource)
   * We do *not* hold the global qemu mutex here, so extra care is needed
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0217-spice-add-screen-mirror.patch b/0506-spice-add-screen-mirror.patch
similarity index 96%
rename from 0217-spice-add-screen-mirror.patch
rename to 0506-spice-add-screen-mirror.patch
index 5898ba8..6ee91d1 100644
--- a/0217-spice-add-screen-mirror.patch
+++ b/0506-spice-add-screen-mirror.patch
@@ -1,7 +1,7 @@
-From d7080640a03a1c7739eb730eaec0c63e7e12cdb6 Mon Sep 17 00:00:00 2001
+From 9f4c601032d7a27e8856517a1a020c9988667ed3 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Wed, 5 Sep 2012 09:35:57 +0200
-Subject: [PATCH 217/293] spice: add screen mirror
+Subject: [PATCH] spice: add screen mirror
 
 Create a screen mirror, keep there a copy of the most recent update
 passed on to spice-server.
@@ -94,5 +94,5 @@ index 3fcb6fe..dea41c1 100644
      int bufsize;
      QXLWorker *worker;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0218-spice-send-updates-only-for-changed-screen-content.patch b/0507-spice-send-updates-only-for-changed-screen-content.patch
similarity index 95%
rename from 0218-spice-send-updates-only-for-changed-screen-content.patch
rename to 0507-spice-send-updates-only-for-changed-screen-content.patch
index 5b63fec..b575091 100644
--- a/0218-spice-send-updates-only-for-changed-screen-content.patch
+++ b/0507-spice-send-updates-only-for-changed-screen-content.patch
@@ -1,7 +1,7 @@
-From e503ba260e585c9ee56f44ae5b8da51643776369 Mon Sep 17 00:00:00 2001
+From e2da4b3f683ae63a55b8e50903a164f704be9e1d Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Wed, 5 Sep 2012 10:41:42 +0200
-Subject: [PATCH 218/293] spice: send updates only for changed screen content
+Subject: [PATCH] spice: send updates only for changed screen content
 
 when creating screen updates go compare the current guest screen
 against the mirror (which holds the most recent update sent), then
@@ -89,5 +89,5 @@ index 973cd53..d062765 100644
  }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0220-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch b/0508-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch
similarity index 88%
rename from 0220-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch
rename to 0508-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch
index 3391970..78845b8 100644
--- a/0220-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch
+++ b/0508-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch
@@ -1,4 +1,4 @@
-From 68d246d6a904e0a851c521a08a18187598e1c696 Mon Sep 17 00:00:00 2001
+From 984e5c7aee378a8de44ff54891695115b92fe585 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Fri, 7 Sep 2012 21:29:22 +0200
 Subject: [PATCH] qxl: Ignore set_client_capabilities pre/post migrate
@@ -21,10 +21,10 @@ Signed-off-by: Hans de Goede <hdegoede at redhat.com>
  1 file changed, 5 insertions(+)
 
 diff --git a/hw/qxl.c b/hw/qxl.c
-index 045432e..1b400f1 100644
+index 2ec4341..360f4f6 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
-@@ -953,6 +953,11 @@ static void interface_set_client_capabilities(QXLInstance *sin,
+@@ -955,6 +955,11 @@ static void interface_set_client_capabilities(QXLInstance *sin,
  {
      PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
  
@@ -37,5 +37,5 @@ index 045432e..1b400f1 100644
      memcpy(qxl->shadow_rom.client_capabilities, caps, sizeof(caps));
      qxl->rom->client_present = client_present;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0223-qxl-add-trace-event-for-QXL_IO_LOG.patch b/0509-qxl-add-trace-event-for-QXL_IO_LOG.patch
similarity index 85%
rename from 0223-qxl-add-trace-event-for-QXL_IO_LOG.patch
rename to 0509-qxl-add-trace-event-for-QXL_IO_LOG.patch
index 84982fa..d5093de 100644
--- a/0223-qxl-add-trace-event-for-QXL_IO_LOG.patch
+++ b/0509-qxl-add-trace-event-for-QXL_IO_LOG.patch
@@ -1,7 +1,7 @@
-From f4cebc3d7a15ecccf61809c35242427e2c2e6713 Mon Sep 17 00:00:00 2001
+From 720192d056402f47a8f71d9ac9bc4b0cf37902ed Mon Sep 17 00:00:00 2001
 From: Alon Levy <alevy at redhat.com>
 Date: Wed, 12 Sep 2012 16:13:27 +0300
-Subject: [PATCH 223/293] qxl: add trace-event for QXL_IO_LOG
+Subject: [PATCH] qxl: add trace-event for QXL_IO_LOG
 
 Signed-off-by: Alon Levy <alevy at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
@@ -23,10 +23,10 @@ index 360f4f6..1ef117a 100644
              fprintf(stderr, "qxl/guest-%d: %" PRId64 ": %s", d->id,
                      qemu_get_clock_ns(vm_clock), d->ram->log_buf);
 diff --git a/trace-events b/trace-events
-index 42dfb93..0ce69d6 100644
+index aa79836..80a52d9 100644
 --- a/trace-events
 +++ b/trace-events
-@@ -924,6 +924,7 @@ qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d
+@@ -930,6 +930,7 @@ qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d
  qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d"
  qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d"
  qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s"
@@ -35,5 +35,5 @@ index 42dfb93..0ce69d6 100644
  qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char *desc) "%d 0x%"PRIx64"=%"PRIu64" (%s)"
  qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d"
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0224-hw-qxl-support-client-monitor-configuration-via-devi.patch b/0510-hw-qxl-support-client-monitor-configuration-via-devi.patch
similarity index 94%
rename from 0224-hw-qxl-support-client-monitor-configuration-via-devi.patch
rename to 0510-hw-qxl-support-client-monitor-configuration-via-devi.patch
index 56cd1e1..4a00940 100644
--- a/0224-hw-qxl-support-client-monitor-configuration-via-devi.patch
+++ b/0510-hw-qxl-support-client-monitor-configuration-via-devi.patch
@@ -1,8 +1,7 @@
-From 3ad6b56cb328a01150fc9a61ee7f4300af2a0912 Mon Sep 17 00:00:00 2001
+From f5c2bd00890dc32e940e8b2fae09f62f758317eb Mon Sep 17 00:00:00 2001
 From: Alon Levy <alevy at redhat.com>
 Date: Wed, 12 Sep 2012 16:13:28 +0300
-Subject: [PATCH 224/293] hw/qxl: support client monitor configuration via
- device
+Subject: [PATCH] hw/qxl: support client monitor configuration via device
 
 Until now we used only the agent to change the monitor count and each
 monitor resolution. This patch introduces the qemu part of using the
@@ -25,10 +24,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  3 files changed, 91 insertions(+), 1 deletion(-)
 
 diff --git a/configure b/configure
-index 0bfef84..ebe8b1c 100755
+index f528146..83c478c 100755
 --- a/configure
 +++ b/configure
-@@ -2716,6 +2716,9 @@ EOF
+@@ -2706,6 +2706,9 @@ EOF
      if $pkg_config --atleast-version=0.12.0 spice-protocol >/dev/null 2>&1; then
          spice_qxl_io_monitors_config_async="yes"
      fi
@@ -38,7 +37,7 @@ index 0bfef84..ebe8b1c 100755
    else
      if test "$spice" = "yes" ; then
        feature_not_found "spice"
-@@ -3457,6 +3460,10 @@ if test "$spice_qxl_io_monitors_config_async" = "yes" ; then
+@@ -3453,6 +3456,10 @@ if test "$spice_qxl_io_monitors_config_async" = "yes" ; then
    echo "CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC=y" >> $config_host_mak
  fi
  
@@ -154,10 +153,10 @@ index 1ef117a..0695872 100644
  
  static void qxl_enter_vga_mode(PCIQXLDevice *d)
 diff --git a/trace-events b/trace-events
-index 0ce69d6..1b19988 100644
+index 80a52d9..07b63f1 100644
 --- a/trace-events
 +++ b/trace-events
-@@ -924,7 +924,7 @@ qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d
+@@ -930,7 +930,7 @@ qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d
  qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d"
  qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d"
  qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s"
@@ -166,7 +165,7 @@ index 0ce69d6..1b19988 100644
  qxl_io_read_unexpected(int qid) "%d"
  qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char *desc) "%d 0x%"PRIx64"=%"PRIu64" (%s)"
  qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d"
-@@ -968,6 +968,10 @@ qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dir
+@@ -974,6 +974,10 @@ qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dir
  qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
  qxl_send_events(int qid, uint32_t events) "%d %d"
  qxl_set_guest_bug(int qid) "%d"
@@ -178,5 +177,5 @@ index 0ce69d6..1b19988 100644
  # hw/qxl-render.c
  qxl_render_blit_guest_primary_initialized(void) ""
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0225-qxl-always-update-displaysurface-on-resize.patch b/0511-qxl-always-update-displaysurface-on-resize.patch
similarity index 91%
rename from 0225-qxl-always-update-displaysurface-on-resize.patch
rename to 0511-qxl-always-update-displaysurface-on-resize.patch
index ec92f32..4b556c7 100644
--- a/0225-qxl-always-update-displaysurface-on-resize.patch
+++ b/0511-qxl-always-update-displaysurface-on-resize.patch
@@ -1,7 +1,7 @@
-From 8046044514de3ef6a37bb982c8e239b9dc34208d Mon Sep 17 00:00:00 2001
+From d0b5c82d532ef14bbbc770b06a6ae68f6ec3c1a8 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Fri, 14 Sep 2012 22:09:23 +0200
-Subject: [PATCH 225/228] qxl: always update displaysurface on resize
+Subject: [PATCH] qxl: always update displaysurface on resize
 
 Don't try to be clever and skip displaysurface reinitialization in case
 the size hasn't changed.  Other parameters might have changed
@@ -40,5 +40,5 @@ index e2e3fe2..b66c168 100644
              qemu_free_displaysurface(vga->ds);
              qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0226-qxl-update_area_io-cleanup-invalid-parameters-handli.patch b/0512-qxl-update_area_io-cleanup-invalid-parameters-handli.patch
similarity index 88%
rename from 0226-qxl-update_area_io-cleanup-invalid-parameters-handli.patch
rename to 0512-qxl-update_area_io-cleanup-invalid-parameters-handli.patch
index 9082549..e742f65 100644
--- a/0226-qxl-update_area_io-cleanup-invalid-parameters-handli.patch
+++ b/0512-qxl-update_area_io-cleanup-invalid-parameters-handli.patch
@@ -1,8 +1,7 @@
-From 286f37492e7e3f746aba6fb5df4579a7fc1301da Mon Sep 17 00:00:00 2001
+From 2bbe4bb8c12976312c9421489f7568a70e5ffae3 Mon Sep 17 00:00:00 2001
 From: Michael Tokarev <mjt at tls.msk.ru>
 Date: Wed, 19 Sep 2012 17:41:26 +0400
-Subject: [PATCH 227/228] qxl/update_area_io: cleanup invalid parameters
- handling
+Subject: [PATCH] qxl/update_area_io: cleanup invalid parameters handling
 
 This cleans up two additions of almost the same code in commits
 511b13e2c9 and ccc2960d654.  While at it, make error paths
@@ -17,10 +16,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 3 insertions(+), 10 deletions(-)
 
 diff --git a/hw/qxl.c b/hw/qxl.c
-index bb0b5e1..1f0f4e7 100644
+index 0695872..720363f 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
-@@ -1551,20 +1551,13 @@ async_common:
+@@ -1547,20 +1547,13 @@ async_common:
          if (d->ram->update_surface > d->ssd.num_surfaces) {
              qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: invalid surface id %d\n",
                                d->ram->update_surface);
@@ -45,5 +44,5 @@ index bb0b5e1..1f0f4e7 100644
          }
          if (async == QXL_ASYNC) {
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0227-qxl-fix-range-check-for-rev3-io-commands.patch b/0513-qxl-fix-range-check-for-rev3-io-commands.patch
similarity index 74%
rename from 0227-qxl-fix-range-check-for-rev3-io-commands.patch
rename to 0513-qxl-fix-range-check-for-rev3-io-commands.patch
index 95df3f9..65f8763 100644
--- a/0227-qxl-fix-range-check-for-rev3-io-commands.patch
+++ b/0513-qxl-fix-range-check-for-rev3-io-commands.patch
@@ -1,7 +1,7 @@
-From 3133cf6b440dab301639ff979714bb08cab68eec Mon Sep 17 00:00:00 2001
+From 0e0d8cfb93813c0d693b14e3d433d36ee9bc6bab Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 25 Sep 2012 13:56:40 +0200
-Subject: [PATCH 228/228] qxl: fix range check for rev3 io commands.
+Subject: [PATCH] qxl: fix range check for rev3 io commands.
 
 Enables QXL_IO_FLUSH_SURFACES_ASYNC and QXL_IO_FLUSH_RELEASE
 which are part of the qxl rev3 feature set.
@@ -12,10 +12,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/hw/qxl.c b/hw/qxl.c
-index 1f0f4e7..ad5ebd5 100644
+index 720363f..9389752 100644
 --- a/hw/qxl.c
 +++ b/hw/qxl.c
-@@ -1470,7 +1470,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
+@@ -1466,7 +1466,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
      }
  
      if (d->revision <= QXL_REVISION_STABLE_V10 &&
@@ -25,5 +25,5 @@ index 1f0f4e7..ad5ebd5 100644
              io_port, d->revision);
          return;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0324-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch b/0600-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch
similarity index 89%
rename from 0324-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch
rename to 0600-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch
index e6296ec..3651fda 100644
--- a/0324-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch
+++ b/0600-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch
@@ -1,7 +1,7 @@
-From 5ea5581f88d2e4bba876c2ee2544cf3641a64eca Mon Sep 17 00:00:00 2001
+From a6400ff20f4e32eecce44931e33939cdf04e2a3e Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Fri, 31 Aug 2012 13:41:38 +0200
-Subject: [PATCH 324/366] usb-redir: Convert to new libusbredirparser 0.5 API
+Subject: [PATCH] usb-redir: Convert to new libusbredirparser 0.5 API
 
 This gives us support for 64 bit ids which is needed for using XHCI with
 the new hcd generated ids.
@@ -14,10 +14,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  2 files changed, 32 insertions(+), 32 deletions(-)
 
 diff --git a/configure b/configure
-index 0bfef84..25c406f 100755
+index 83c478c..2c4469f 100755
 --- a/configure
 +++ b/configure
-@@ -2765,7 +2765,7 @@ fi
+@@ -2758,7 +2758,7 @@ fi
  
  # check for usbredirparser for usb network redirection support
  if test "$usb_redir" != "no" ; then
@@ -27,7 +27,7 @@ index 0bfef84..25c406f 100755
          usb_redir_cflags=$($pkg_config --cflags libusbredirparser 2>/dev/null)
          usb_redir_libs=$($pkg_config --libs libusbredirparser 2>/dev/null)
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 60b8f3e..789ef51 100644
+index b7c7f1e..321f5be 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
 @@ -107,27 +107,27 @@ static void usbredir_interface_info(void *priv,
@@ -67,15 +67,15 @@ index 60b8f3e..789ef51 100644
      struct usb_redir_interrupt_packet_header *interrupt_header,
      uint8_t *data, int data_len);
  
-@@ -815,6 +815,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+@@ -814,6 +814,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
  
      usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
      usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
 +    usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
-     usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
+     usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0);
      usbredirparser_do_write(dev->parser);
  }
-@@ -1209,15 +1210,15 @@ static void usbredir_ep_info(void *priv,
+@@ -1204,15 +1205,15 @@ static void usbredir_ep_info(void *priv,
      }
  }
  
@@ -94,7 +94,7 @@ index 60b8f3e..789ef51 100644
  
      p = usbredir_find_packet_by_id(dev, 0, id);
      if (p) {
-@@ -1230,16 +1231,15 @@ static void usbredir_configuration_status(void *priv, uint32_t id,
+@@ -1225,16 +1226,15 @@ static void usbredir_configuration_status(void *priv, uint32_t id,
      }
  }
  
@@ -114,7 +114,7 @@ index 60b8f3e..789ef51 100644
              alt_setting_status->alt, id);
  
      p = usbredir_find_packet_by_id(dev, 0, id);
-@@ -1254,13 +1254,13 @@ static void usbredir_alt_setting_status(void *priv, uint32_t id,
+@@ -1249,13 +1249,13 @@ static void usbredir_alt_setting_status(void *priv, uint32_t id,
      }
  }
  
@@ -130,7 +130,7 @@ index 60b8f3e..789ef51 100644
              ep, id);
  
      if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].iso_started) {
-@@ -1274,14 +1274,14 @@ static void usbredir_iso_stream_status(void *priv, uint32_t id,
+@@ -1269,14 +1269,14 @@ static void usbredir_iso_stream_status(void *priv, uint32_t id,
      }
  }
  
@@ -147,7 +147,7 @@ index 60b8f3e..789ef51 100644
              interrupt_receiving_status->status, ep, id);
  
      if (!dev->dev.attached || !dev->endpoint[EP2I(ep)].interrupt_started) {
-@@ -1296,12 +1296,12 @@ static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
+@@ -1291,12 +1291,12 @@ static void usbredir_interrupt_receiving_status(void *priv, uint32_t id,
      }
  }
  
@@ -162,7 +162,7 @@ index 60b8f3e..789ef51 100644
      struct usb_redir_control_packet_header *control_packet,
      uint8_t *data, int data_len)
  {
-@@ -1309,7 +1309,7 @@ static void usbredir_control_packet(void *priv, uint32_t id,
+@@ -1304,7 +1304,7 @@ static void usbredir_control_packet(void *priv, uint32_t id,
      USBPacket *p;
      int len = control_packet->length;
  
@@ -171,7 +171,7 @@ index 60b8f3e..789ef51 100644
              len, id);
  
      p = usbredir_find_packet_by_id(dev, 0, id);
-@@ -1331,7 +1331,7 @@ static void usbredir_control_packet(void *priv, uint32_t id,
+@@ -1326,7 +1326,7 @@ static void usbredir_control_packet(void *priv, uint32_t id,
      free(data);
  }
  
@@ -180,7 +180,7 @@ index 60b8f3e..789ef51 100644
      struct usb_redir_bulk_packet_header *bulk_packet,
      uint8_t *data, int data_len)
  {
-@@ -1340,8 +1340,8 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
+@@ -1335,8 +1335,8 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
      int len = bulk_packet->length;
      USBPacket *p;
  
@@ -191,7 +191,7 @@ index 60b8f3e..789ef51 100644
  
      p = usbredir_find_packet_by_id(dev, ep, id);
      if (p) {
-@@ -1362,15 +1362,15 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
+@@ -1357,15 +1357,15 @@ static void usbredir_bulk_packet(void *priv, uint32_t id,
      free(data);
  }
  
@@ -210,7 +210,7 @@ index 60b8f3e..789ef51 100644
  
      if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_ISOC) {
          ERROR("received iso packet for non iso endpoint %02X\n", ep);
-@@ -1388,14 +1388,14 @@ static void usbredir_iso_packet(void *priv, uint32_t id,
+@@ -1383,14 +1383,14 @@ static void usbredir_iso_packet(void *priv, uint32_t id,
      bufp_alloc(dev, data, data_len, iso_packet->status, ep);
  }
  
@@ -228,5 +228,5 @@ index 60b8f3e..789ef51 100644
  
      if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0325-usb-redir-Set-ep-max_packet_size-if-available.patch b/0601-usb-redir-Set-ep-max_packet_size-if-available.patch
similarity index 75%
rename from 0325-usb-redir-Set-ep-max_packet_size-if-available.patch
rename to 0601-usb-redir-Set-ep-max_packet_size-if-available.patch
index d9e15a5..8dacdb4 100644
--- a/0325-usb-redir-Set-ep-max_packet_size-if-available.patch
+++ b/0601-usb-redir-Set-ep-max_packet_size-if-available.patch
@@ -1,7 +1,7 @@
-From 7c936f9e6b07f4468f49886b4e785e4120a08e11 Mon Sep 17 00:00:00 2001
+From 0995eaeb06c4810cd133e710170a7b181caf04cd Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 3 Sep 2012 11:49:07 +0200
-Subject: [PATCH 325/366] usb-redir: Set ep max_packet_size if available
+Subject: [PATCH] usb-redir: Set ep max_packet_size if available
 
 This is needed for usb-redir to work properly with the xhci emulation.
 
@@ -12,18 +12,18 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 5 insertions(+)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 789ef51..ac8bfd2 100644
+index 321f5be..b9a3633 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
-@@ -815,6 +815,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+@@ -814,6 +814,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
  
      usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
      usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
 +    usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
      usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
-     usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
+     usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0);
      usbredirparser_do_write(dev->parser);
-@@ -1207,6 +1208,10 @@ static void usbredir_ep_info(void *priv,
+@@ -1202,6 +1203,10 @@ static void usbredir_ep_info(void *priv,
                              i & 0x0f);
          usb_ep->type = dev->endpoint[i].type;
          usb_ep->ifnum = dev->endpoint[i].interface;
@@ -35,5 +35,5 @@ index 789ef51..ac8bfd2 100644
  }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0326-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch b/0602-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch
similarity index 82%
rename from 0326-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch
rename to 0602-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch
index d4cde52..cfe0fa1 100644
--- a/0326-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch
+++ b/0602-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch
@@ -1,8 +1,7 @@
-From 4ba71f5871be4d92f36097bc431fc303e1e42a7a Mon Sep 17 00:00:00 2001
+From 596013354fd1d5b102cdb54449b10e11346f9fda Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 3 Sep 2012 11:53:28 +0200
-Subject: [PATCH 326/366] usb-redir: Add a usbredir_reject_device helper
- function
+Subject: [PATCH] usb-redir: Add a usbredir_reject_device helper function
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
@@ -11,10 +10,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 11 insertions(+), 10 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index ac8bfd2..357f307 100644
+index b9a3633..a590cb2 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
-@@ -821,16 +821,21 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+@@ -820,16 +820,21 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
      usbredirparser_do_write(dev->parser);
  }
  
@@ -41,7 +40,7 @@ index ac8bfd2..357f307 100644
      }
  }
  
-@@ -1013,11 +1018,7 @@ static int usbredir_check_filter(USBRedirDevice *dev)
+@@ -1008,11 +1013,7 @@ static int usbredir_check_filter(USBRedirDevice *dev)
      return 0;
  
  error:
@@ -55,5 +54,5 @@ index ac8bfd2..357f307 100644
  }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0327-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch b/0603-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch
similarity index 83%
rename from 0327-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch
rename to 0603-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch
index f3ea67a..ef6b4a2 100644
--- a/0327-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch
+++ b/0603-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch
@@ -1,8 +1,8 @@
-From af1ecda005c043dd8186725ae7a93ea66ebfe96f Mon Sep 17 00:00:00 2001
+From 87317670541ed043a21964c29e0e613aab375224 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 3 Sep 2012 12:04:49 +0200
-Subject: [PATCH 327/366] usb-redir: Ensure our peer has the necessary caps
- when redirecting to XHCI
+Subject: [PATCH] usb-redir: Ensure our peer has the necessary caps when
+ redirecting to XHCI
 
 In order for redirection to work properly when redirecting to an emulated
 XHCI controller, the usb-redir-host must support both
@@ -17,10 +17,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 11 insertions(+)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 357f307..5b0f834 100644
+index a590cb2..f1bb692 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
-@@ -834,6 +834,17 @@ static void usbredir_do_attach(void *opaque)
+@@ -833,6 +833,17 @@ static void usbredir_do_attach(void *opaque)
  {
      USBRedirDevice *dev = opaque;
  
@@ -39,5 +39,5 @@ index 357f307..5b0f834 100644
          usbredir_reject_device(dev);
      }
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0328-usb-redir-Enable-pipelining-for-bulk-endpoints.patch b/0604-usb-redir-Enable-pipelining-for-bulk-endpoints.patch
similarity index 72%
rename from 0328-usb-redir-Enable-pipelining-for-bulk-endpoints.patch
rename to 0604-usb-redir-Enable-pipelining-for-bulk-endpoints.patch
index 48de611..cfb988e 100644
--- a/0328-usb-redir-Enable-pipelining-for-bulk-endpoints.patch
+++ b/0604-usb-redir-Enable-pipelining-for-bulk-endpoints.patch
@@ -1,7 +1,7 @@
-From 30b6793253b39f347e1f74791118403451b9886c Mon Sep 17 00:00:00 2001
+From c12ef3d896e426505ea3ca4fb2f1d9017f9cf828 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Mon, 3 Sep 2012 13:44:04 +0200
-Subject: [PATCH 328/366] usb-redir: Enable pipelining for bulk endpoints
+Subject: [PATCH] usb-redir: Enable pipelining for bulk endpoints
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
@@ -10,10 +10,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 3 insertions(+)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 5b0f834..9cbcddb 100644
+index f1bb692..f183263 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
-@@ -1224,6 +1224,9 @@ static void usbredir_ep_info(void *priv,
+@@ -1219,6 +1219,9 @@ static void usbredir_ep_info(void *priv,
                                       usb_redir_cap_ep_info_max_packet_size)) {
              usb_ep->max_packet_size = ep_info->max_packet_size[i];
          }
@@ -24,5 +24,5 @@ index 5b0f834..9cbcddb 100644
  }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0333-xhci-move-device-lookup-into-xhci_setup_packet.patch b/0605-xhci-move-device-lookup-into-xhci_setup_packet.patch
similarity index 96%
rename from 0333-xhci-move-device-lookup-into-xhci_setup_packet.patch
rename to 0605-xhci-move-device-lookup-into-xhci_setup_packet.patch
index 2ac0629..3a2ad62 100644
--- a/0333-xhci-move-device-lookup-into-xhci_setup_packet.patch
+++ b/0605-xhci-move-device-lookup-into-xhci_setup_packet.patch
@@ -1,7 +1,7 @@
-From e144accdeb05222cf671c3bad142c81c40dbacdb Mon Sep 17 00:00:00 2001
+From 2255facbc338e73aa2442e2a1dc13b3474b35f98 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Fri, 24 Aug 2012 14:21:39 +0200
-Subject: [PATCH 333/369] xhci: move device lookup into xhci_setup_packet
+Subject: [PATCH] xhci: move device lookup into xhci_setup_packet
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
 ---
@@ -9,7 +9,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 38 insertions(+), 36 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 446d692..c108c9d 100644
+index 333df59..316a303 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -1196,13 +1196,38 @@ static void xhci_stall_ep(XHCITransfer *xfer)
@@ -150,5 +150,5 @@ index 446d692..c108c9d 100644
          if (result == USB_RET_NAK) {
              return;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0334-xhci-implement-mfindex.patch b/0606-xhci-implement-mfindex.patch
similarity index 90%
rename from 0334-xhci-implement-mfindex.patch
rename to 0606-xhci-implement-mfindex.patch
index 9f00140..4e4d268 100644
--- a/0334-xhci-implement-mfindex.patch
+++ b/0606-xhci-implement-mfindex.patch
@@ -1,7 +1,7 @@
-From 6a1c694cd009fb7e4656e1c9a18756da6f89be14 Mon Sep 17 00:00:00 2001
+From 1f98b775c9f02caece1df5813edbb9c0a509bd58 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 21 Aug 2012 12:32:58 +0200
-Subject: [PATCH 334/366] xhci: implement mfindex
+Subject: [PATCH] xhci: implement mfindex
 
 Implement mfindex register and mfindex wrap event.
 
@@ -11,7 +11,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 46 insertions(+), 7 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 303e1ac..9077cb3 100644
+index 316a303..f5ba6a4 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -380,8 +380,6 @@ struct XHCIState {
@@ -92,7 +92,7 @@ index 303e1ac..9077cb3 100644
  }
  
  static void xhci_stop(XHCIState *xhci)
-@@ -2050,7 +2085,6 @@ static void xhci_reset(DeviceState *dev)
+@@ -2048,7 +2083,6 @@ static void xhci_reset(DeviceState *dev)
          xhci_update_port(xhci, xhci->ports + i, 0);
      }
  
@@ -100,7 +100,7 @@ index 303e1ac..9077cb3 100644
      xhci->iman = 0;
      xhci->imod = 0;
      xhci->erstsz = 0;
-@@ -2064,6 +2098,9 @@ static void xhci_reset(DeviceState *dev)
+@@ -2062,6 +2096,9 @@ static void xhci_reset(DeviceState *dev)
      xhci->er_full = 0;
      xhci->ev_buffer_put = 0;
      xhci->ev_buffer_get = 0;
@@ -110,7 +110,7 @@ index 303e1ac..9077cb3 100644
  }
  
  static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
-@@ -2266,6 +2303,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2264,6 +2301,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
              xhci_stop(xhci);
          }
          xhci->usbcmd = val & 0xc0f;
@@ -118,7 +118,7 @@ index 303e1ac..9077cb3 100644
          if (val & USBCMD_HCRST) {
              xhci_reset(&xhci->pci_dev.qdev);
          }
-@@ -2317,8 +2355,7 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
+@@ -2315,8 +2353,7 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
  
      switch (reg) {
      case 0x00: /* MFINDEX */
@@ -138,5 +138,5 @@ index 303e1ac..9077cb3 100644
  
      memory_region_init_io(&xhci->mem, &xhci_mem_ops, xhci,
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0335-xhci-iso-xfer-support.patch b/0607-xhci-iso-xfer-support.patch
similarity index 94%
rename from 0335-xhci-iso-xfer-support.patch
rename to 0607-xhci-iso-xfer-support.patch
index ae88244..acaee96 100644
--- a/0335-xhci-iso-xfer-support.patch
+++ b/0607-xhci-iso-xfer-support.patch
@@ -1,7 +1,7 @@
-From 9f7a9361a816479ca109e1747e45d40135fad3b0 Mon Sep 17 00:00:00 2001
+From 82508212e19333e527b64fb76cd1bc016afacc8a Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Fri, 24 Aug 2012 14:13:08 +0200
-Subject: [PATCH 335/366] xhci: iso xfer support
+Subject: [PATCH] xhci: iso xfer support
 
 Add support for iso transfers.
 
@@ -11,7 +11,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 101 insertions(+), 16 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 9077cb3..3c61bb8 100644
+index f5ba6a4..b313330 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -325,9 +325,15 @@ typedef struct XHCITransfer {
@@ -92,7 +92,7 @@ index 9077cb3..3c61bb8 100644
      g_free(epctx);
      slot->eps[epid-1] = NULL;
  
-@@ -1378,29 +1404,70 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
+@@ -1376,29 +1402,70 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
      return 0;
  }
  
@@ -170,7 +170,7 @@ index 9077cb3..3c61bb8 100644
          break;
      default:
          fprintf(stderr, "xhci: unknown or unhandled EP "
-@@ -1430,6 +1497,7 @@ static int xhci_fire_transfer(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext
+@@ -1428,6 +1495,7 @@ static int xhci_fire_transfer(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext
  static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid)
  {
      XHCIEPContext *epctx;
@@ -178,7 +178,7 @@ index 9077cb3..3c61bb8 100644
      int length;
      int i;
  
-@@ -1449,20 +1517,35 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid
+@@ -1447,20 +1515,35 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid
      }
  
      if (epctx->retry) {
@@ -222,7 +222,7 @@ index 9077cb3..3c61bb8 100644
          assert(!xfer->running_retry);
          epctx->retry = NULL;
      }
-@@ -1514,7 +1597,9 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid
+@@ -1512,7 +1595,9 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid
              if (xhci_fire_transfer(xhci, xfer, epctx) >= 0) {
                  epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;
              } else {
@@ -234,5 +234,5 @@ index 9077cb3..3c61bb8 100644
          }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0336-xhci-trace-cc-codes-in-cleartext.patch b/0608-xhci-trace-cc-codes-in-cleartext.patch
similarity index 95%
rename from 0336-xhci-trace-cc-codes-in-cleartext.patch
rename to 0608-xhci-trace-cc-codes-in-cleartext.patch
index 096d194..b2b70f6 100644
--- a/0336-xhci-trace-cc-codes-in-cleartext.patch
+++ b/0608-xhci-trace-cc-codes-in-cleartext.patch
@@ -1,7 +1,7 @@
-From 530efbfebc3b33f6b109e52d57a25e9b7fe2b588 Mon Sep 17 00:00:00 2001
+From 188fbd363df2e7f23ea37fb1b179e984bbce39e5 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Mon, 27 Aug 2012 16:09:20 +0200
-Subject: [PATCH 336/366] xhci: trace cc codes in cleartext
+Subject: [PATCH] xhci: trace cc codes in cleartext
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
 ---
@@ -10,7 +10,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  2 files changed, 48 insertions(+), 2 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 3c61bb8..ab32a7b 100644
+index b313330..ab352c0 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -465,6 +465,45 @@ static const char *TRBType_names[] = {
@@ -83,10 +83,10 @@ index 3c61bb8..ab32a7b 100644
      addr = xhci->er_start + TRB_SIZE*xhci->er_ep_idx;
      pci_dma_write(&xhci->pci_dev, addr, &ev_trb, TRB_SIZE);
 diff --git a/trace-events b/trace-events
-index c83d65e..27d59cd 100644
+index 07b63f1..b38e32a 100644
 --- a/trace-events
 +++ b/trace-events
-@@ -313,7 +313,7 @@ usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
+@@ -316,7 +316,7 @@ usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
  usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
  usb_xhci_irq_intx(uint32_t level) "level %d"
  usb_xhci_irq_msi(uint32_t nr) "nr %d"
@@ -96,5 +96,5 @@ index c83d65e..27d59cd 100644
  usb_xhci_slot_enable(uint32_t slotid) "slotid %d"
  usb_xhci_slot_disable(uint32_t slotid) "slotid %d"
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0337-xhci-add-trace_usb_xhci_ep_set_dequeue.patch b/0609-xhci-add-trace_usb_xhci_ep_set_dequeue.patch
similarity index 83%
rename from 0337-xhci-add-trace_usb_xhci_ep_set_dequeue.patch
rename to 0609-xhci-add-trace_usb_xhci_ep_set_dequeue.patch
index c36d7d8..7a07da9 100644
--- a/0337-xhci-add-trace_usb_xhci_ep_set_dequeue.patch
+++ b/0609-xhci-add-trace_usb_xhci_ep_set_dequeue.patch
@@ -1,7 +1,7 @@
-From 53adf697ca70ee8298b6abeb05ebf5a0ebebdc1c Mon Sep 17 00:00:00 2001
+From 10a1380a50e33f98d5030d75d9d356f7ce024556 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Wed, 29 Aug 2012 12:54:59 +0200
-Subject: [PATCH 337/366] xhci: add trace_usb_xhci_ep_set_dequeue
+Subject: [PATCH] xhci: add trace_usb_xhci_ep_set_dequeue
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
 ---
@@ -10,7 +10,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  2 files changed, 2 insertions(+), 1 deletion(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index ab32a7b..5cdaf76 100644
+index ab352c0..c6ab4a1 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -1145,7 +1145,7 @@ static TRBCCode xhci_set_ep_dequeue(XHCIState *xhci, unsigned int slotid,
@@ -23,10 +23,10 @@ index ab32a7b..5cdaf76 100644
  
      slot = &xhci->slots[slotid-1];
 diff --git a/trace-events b/trace-events
-index 27d59cd..a894689 100644
+index b38e32a..2db1deb 100644
 --- a/trace-events
 +++ b/trace-events
-@@ -323,6 +323,7 @@ usb_xhci_slot_evaluate(uint32_t slotid) "slotid %d"
+@@ -326,6 +326,7 @@ usb_xhci_slot_evaluate(uint32_t slotid) "slotid %d"
  usb_xhci_slot_reset(uint32_t slotid) "slotid %d"
  usb_xhci_ep_enable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
  usb_xhci_ep_disable(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
@@ -35,5 +35,5 @@ index 27d59cd..a894689 100644
  usb_xhci_ep_stop(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
  usb_xhci_ep_reset(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0339-xhci-update-register-layout.patch b/0610-xhci-update-register-layout.patch
similarity index 91%
rename from 0339-xhci-update-register-layout.patch
rename to 0610-xhci-update-register-layout.patch
index 7fc8af1..6052e50 100644
--- a/0339-xhci-update-register-layout.patch
+++ b/0610-xhci-update-register-layout.patch
@@ -1,7 +1,7 @@
-From 56a4ea65ecc929a355b0cc243099d2e3a9862843 Mon Sep 17 00:00:00 2001
+From 79e9a5ca778bfcb67073bfecd3f7cea7d93781ce Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Thu, 23 Aug 2012 13:26:25 +0200
-Subject: [PATCH 339/366] xhci: update register layout
+Subject: [PATCH] xhci: update register layout
 
 Change the register layout to be a bit more sparse and also not depend
 on the number of ports.  Useful when for making the number of ports
@@ -11,7 +11,7 @@ runtime-configurable.
  1 file changed, 13 insertions(+), 8 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index e8d2372..414b633 100644
+index c6ab4a1..d47539d 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -36,13 +36,12 @@
@@ -59,5 +59,5 @@ index e8d2372..414b633 100644
  # error Increase LEN_REGS
  #endif
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0340-xhci-update-port-handling.patch b/0611-xhci-update-port-handling.patch
similarity index 92%
rename from 0340-xhci-update-port-handling.patch
rename to 0611-xhci-update-port-handling.patch
index 289fa52..d47740a 100644
--- a/0340-xhci-update-port-handling.patch
+++ b/0611-xhci-update-port-handling.patch
@@ -1,7 +1,7 @@
-From ed16ece865cb40c9ad8ddf28905c0af3ad80e118 Mon Sep 17 00:00:00 2001
+From 0b1ccd39faa8d1ea71f2d02dbab5dfd13f54ac98 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 28 Aug 2012 13:38:01 +0200
-Subject: [PATCH 340/366] xhci: update port handling
+Subject: [PATCH] xhci: update port handling
 
 This patch changes the way xhci ports are linked to USBPorts.  The fixed
 1:1 relationship between xhci ports and USBPorts is gone.  Now each
@@ -19,7 +19,7 @@ ports 1+2 and usb2 only on ports 3+4.
  1 file changed, 97 insertions(+), 40 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 414b633..e08312e 100644
+index d47539d..5813b4a 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -36,10 +36,10 @@
@@ -121,7 +121,7 @@ index 414b633..e08312e 100644
  }
  
  static int xhci_setup_packet(XHCITransfer *xfer)
-@@ -1736,9 +1766,9 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
+@@ -1734,9 +1764,9 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
              ep0_ctx[0], ep0_ctx[1], ep0_ctx[2], ep0_ctx[3], ep0_ctx[4]);
  
      port = (slot_ctx[1]>>16) & 0xFF;
@@ -133,7 +133,7 @@ index 414b633..e08312e 100644
          fprintf(stderr, "xhci: bad port %d\n", port);
          return CC_TRB_ERROR;
      } else if (!dev) {
-@@ -1987,7 +2017,7 @@ static unsigned int xhci_get_slot(XHCIState *xhci, XHCIEvent *event, XHCITRB *tr
+@@ -1985,7 +2015,7 @@ static unsigned int xhci_get_slot(XHCIState *xhci, XHCIEvent *event, XHCITRB *tr
  static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx)
  {
      dma_addr_t ctx;
@@ -142,7 +142,7 @@ index 414b633..e08312e 100644
  
      DPRINTF("xhci_get_port_bandwidth()\n");
  
-@@ -1997,7 +2027,7 @@ static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx)
+@@ -1995,7 +2025,7 @@ static TRBCCode xhci_get_port_bandwidth(XHCIState *xhci, uint64_t pctx)
  
      /* TODO: actually implement real values here */
      bw_ctx[0] = 0;
@@ -151,7 +151,7 @@ index 414b633..e08312e 100644
      pci_dma_write(&xhci->pci_dev, ctx, bw_ctx, sizeof(bw_ctx));
  
      return CC_SUCCESS;
-@@ -2167,12 +2197,11 @@ static void xhci_process_commands(XHCIState *xhci)
+@@ -2165,12 +2195,11 @@ static void xhci_process_commands(XHCIState *xhci)
  
  static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach)
  {
@@ -167,7 +167,7 @@ index 414b633..e08312e 100644
          case USB_SPEED_LOW:
              port->portsc |= PORTSC_SPEED_LOW;
              break;
-@@ -2182,14 +2211,18 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach)
+@@ -2180,14 +2209,18 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach)
          case USB_SPEED_HIGH:
              port->portsc |= PORTSC_SPEED_HIGH;
              break;
@@ -188,7 +188,7 @@ index 414b633..e08312e 100644
      }
  }
  
-@@ -2217,7 +2250,7 @@ static void xhci_reset(DeviceState *dev)
+@@ -2215,7 +2248,7 @@ static void xhci_reset(DeviceState *dev)
          xhci_disable_slot(xhci, i+1);
      }
  
@@ -197,7 +197,7 @@ index 414b633..e08312e 100644
          xhci_update_port(xhci, xhci->ports + i, 0);
      }
  
-@@ -2248,7 +2281,8 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
+@@ -2246,7 +2279,8 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
          ret = 0x01000000 | LEN_CAP;
          break;
      case 0x04: /* HCSPARAMS 1 */
@@ -207,7 +207,7 @@ index 414b633..e08312e 100644
          break;
      case 0x08: /* HCSPARAMS 2 */
          ret = 0x0000000f;
-@@ -2278,7 +2312,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
+@@ -2276,7 +2310,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
          ret = 0x20425455; /* "USB " */
          break;
      case 0x28: /* Supported Protocol:08 */
@@ -216,7 +216,7 @@ index 414b633..e08312e 100644
          break;
      case 0x2c: /* Supported Protocol:0c */
          ret = 0x00000000; /* reserved */
-@@ -2290,7 +2324,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
+@@ -2288,7 +2322,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
          ret = 0x20425455; /* "USB " */
          break;
      case 0x38: /* Supported Protocol:08 */
@@ -225,7 +225,7 @@ index 414b633..e08312e 100644
          break;
      case 0x3c: /* Supported Protocol:0c */
          ret = 0x00000000; /* reserved */
-@@ -2309,7 +2343,7 @@ static uint32_t xhci_port_read(XHCIState *xhci, uint32_t reg)
+@@ -2307,7 +2341,7 @@ static uint32_t xhci_port_read(XHCIState *xhci, uint32_t reg)
      uint32_t port = reg >> 4;
      uint32_t ret;
  
@@ -234,7 +234,7 @@ index 414b633..e08312e 100644
          fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port);
          ret = 0;
          goto out;
-@@ -2342,7 +2376,7 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2340,7 +2374,7 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val)
  
      trace_usb_xhci_port_write(port, reg & 0x0f, val);
  
@@ -243,7 +243,7 @@ index 414b633..e08312e 100644
          fprintf(stderr, "xhci_port_read: port %d out of bounds\n", port);
          return;
      }
-@@ -2364,7 +2398,7 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2362,7 +2396,7 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val)
          /* write-1-to-start bits */
          if (val & PORTSC_PR) {
              DPRINTF("xhci: port %d reset\n", port);
@@ -348,5 +348,5 @@ index 414b633..e08312e 100644
  };
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0341-usb3-superspeed-descriptors.patch b/0612-usb3-superspeed-descriptors.patch
similarity index 93%
rename from 0341-usb3-superspeed-descriptors.patch
rename to 0612-usb3-superspeed-descriptors.patch
index 05591fe..4c60573 100644
--- a/0341-usb3-superspeed-descriptors.patch
+++ b/0612-usb3-superspeed-descriptors.patch
@@ -1,7 +1,7 @@
-From f25f31e864756f27f6a94ab7e66b20061291ffa5 Mon Sep 17 00:00:00 2001
+From 81e37421158a28277c9857ba733da4371cb06129 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 28 Aug 2012 17:28:50 +0200
-Subject: [PATCH 341/366] usb3: superspeed descriptors
+Subject: [PATCH] usb3: superspeed descriptors
 
 Add superspeed descriptor entry to USBDesc,
 advertise superspeed support when present.
@@ -60,5 +60,5 @@ index 7cf5442..d89fa41 100644
  };
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0342-usb3-superspeed-endpoint-companion.patch b/0613-usb3-superspeed-endpoint-companion.patch
similarity index 98%
rename from 0342-usb3-superspeed-endpoint-companion.patch
rename to 0613-usb3-superspeed-endpoint-companion.patch
index 7949f8f..40983e4 100644
--- a/0342-usb3-superspeed-endpoint-companion.patch
+++ b/0613-usb3-superspeed-endpoint-companion.patch
@@ -1,7 +1,7 @@
-From 5a02a74430f4628a78f43242afbb1377deea4c80 Mon Sep 17 00:00:00 2001
+From e0354b4f91dd198b5bfe1ddf649588d6af84ea9c Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 28 Aug 2012 17:28:03 +0200
-Subject: [PATCH 342/366] usb3: superspeed endpoint companion
+Subject: [PATCH] usb3: superspeed endpoint companion
 
 Add support for building superspeed endpoint companion descriptors,
 create them for superspeed usb devices.
@@ -244,5 +244,5 @@ index d89fa41..4b5e88d 100644
  
  /* control message emulation helpers */
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0343-usb3-bos-decriptor.patch b/0614-usb3-bos-decriptor.patch
similarity index 97%
rename from 0343-usb3-bos-decriptor.patch
rename to 0614-usb3-bos-decriptor.patch
index 3158fd0..99d4f81 100644
--- a/0343-usb3-bos-decriptor.patch
+++ b/0614-usb3-bos-decriptor.patch
@@ -1,7 +1,7 @@
-From 52666569c1aa34531c101e005feccec0899c14e2 Mon Sep 17 00:00:00 2001
+From 2014680cdc2834fef9b4cee5e1239f22d8dbdba3 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 28 Aug 2012 17:46:29 +0200
-Subject: [PATCH 343/366] usb3: bos decriptor
+Subject: [PATCH] usb3: bos decriptor
 
 Add support for creating BOS descriptor and
 device cappability descriptors.
@@ -199,10 +199,10 @@ index 4b5e88d..68bb570 100644
  } QEMU_PACKED USBDescriptor;
  
 diff --git a/trace-events b/trace-events
-index a894689..5bc591a 100644
+index 2db1deb..d941e78 100644
 --- a/trace-events
 +++ b/trace-events
-@@ -340,6 +340,7 @@ usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device quali
+@@ -343,6 +343,7 @@ usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device quali
  usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
  usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
  usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d"
@@ -211,5 +211,5 @@ index a894689..5bc591a 100644
  usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d"
  usb_set_interface(int addr, int iface, int alt, int ret) "dev %d, interface %d, altsetting %d, ret %d"
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0344-usb-storage-usb3-support.patch b/0615-usb-storage-usb3-support.patch
similarity index 95%
rename from 0344-usb-storage-usb3-support.patch
rename to 0615-usb-storage-usb3-support.patch
index b50fcdd..7caeb42 100644
--- a/0344-usb-storage-usb3-support.patch
+++ b/0615-usb-storage-usb3-support.patch
@@ -1,7 +1,7 @@
-From 4a6f1fdf12d8b03633dad54dadc12781a77fbf6b Mon Sep 17 00:00:00 2001
+From 9a6fd10bf6a85c4df63a7ba1cf7d6203220d722e Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 28 Aug 2012 17:29:15 +0200
-Subject: [PATCH 344/366] usb-storage: usb3 support
+Subject: [PATCH] usb-storage: usb3 support
 
 Add usb3 descriptors to usb-storage, so it shows up as superspeed
 device when connected to xhci.
@@ -90,5 +90,5 @@ index ff48d91..e732191 100644
  
  static void usb_msd_copy_data(MSDState *s, USBPacket *p)
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0345-xhci-fix-cleanup-msi.patch b/0616-xhci-fix-cleanup-msi.patch
similarity index 94%
rename from 0345-xhci-fix-cleanup-msi.patch
rename to 0616-xhci-fix-cleanup-msi.patch
index 5f25cbd..33fca14 100644
--- a/0345-xhci-fix-cleanup-msi.patch
+++ b/0616-xhci-fix-cleanup-msi.patch
@@ -1,7 +1,7 @@
-From 3ed11ea2c3b6d5db29246b4da105902aa0346d65 Mon Sep 17 00:00:00 2001
+From e97e63460859a74cf53c85e97a6d60633a92cc64 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Thu, 30 Aug 2012 10:57:12 +0200
-Subject: [PATCH 345/366] xhci: fix & cleanup msi.
+Subject: [PATCH] xhci: fix & cleanup msi.
 
 Drop custom write_config function which isn't needed any more.
 Make the msi property a bit property so it accepts 'on' & 'off'.
@@ -15,7 +15,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 9 insertions(+), 18 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index e08312e..e1d5d2a 100644
+index 5813b4a..d2e6ee6 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -386,7 +386,7 @@ struct XHCIState {
@@ -92,5 +92,5 @@ index e08312e..e1d5d2a 100644
  
  static TypeInfo xhci_info = {
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0346-xhci-rework-interrupt-handling.patch b/0617-xhci-rework-interrupt-handling.patch
similarity index 91%
rename from 0346-xhci-rework-interrupt-handling.patch
rename to 0617-xhci-rework-interrupt-handling.patch
index b0ea1df..3ac4ccc 100644
--- a/0346-xhci-rework-interrupt-handling.patch
+++ b/0617-xhci-rework-interrupt-handling.patch
@@ -1,7 +1,7 @@
-From da881a3422ae525f1d0a24f61117a47473261037 Mon Sep 17 00:00:00 2001
+From 3bf435b656390f75ce8b8990f7484efb162472c9 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Thu, 30 Aug 2012 13:05:10 +0200
-Subject: [PATCH 346/366] xhci: rework interrupt handling
+Subject: [PATCH] xhci: rework interrupt handling
 
 Split xhci_irq_update into a function which handles intx updates
 (including lowering the irq line once the guests acks the interrupt)
@@ -13,7 +13,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 33 insertions(+), 14 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index e1d5d2a..5eae32e 100644
+index d2e6ee6..1857f42 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -612,24 +612,43 @@ static XHCIPort *xhci_lookup_port(XHCIState *xhci, struct USBPort *uport)
@@ -87,7 +87,7 @@ index e1d5d2a..5eae32e 100644
  }
  
  static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring,
-@@ -2481,13 +2500,13 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2479,13 +2498,13 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
          if (val & USBCMD_HCRST) {
              xhci_reset(&xhci->pci_dev.qdev);
          }
@@ -103,7 +103,7 @@ index e1d5d2a..5eae32e 100644
          break;
  
      case 0x14: /* DNCTRL */
-@@ -2572,7 +2591,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2570,7 +2589,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
          }
          xhci->iman &= ~IMAN_IE;
          xhci->iman |= val & IMAN_IE;
@@ -113,5 +113,5 @@ index e1d5d2a..5eae32e 100644
      case 0x24: /* IMOD */
          xhci->imod = val;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0347-xhci-add-msix-support.patch b/0618-xhci-add-msix-support.patch
similarity index 92%
rename from 0347-xhci-add-msix-support.patch
rename to 0618-xhci-add-msix-support.patch
index 5110aaa..ab0abab 100644
--- a/0347-xhci-add-msix-support.patch
+++ b/0618-xhci-add-msix-support.patch
@@ -1,7 +1,7 @@
-From 03ab86ecf677d777864a3643ec8479037d3f41cd Mon Sep 17 00:00:00 2001
+From b04ba21e22b2df805af8236bc462c5c403fc6ee4 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Thu, 30 Aug 2012 12:06:59 +0200
-Subject: [PATCH 347/366] xhci: add msix support
+Subject: [PATCH] xhci: add msix support
 
 Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
 ---
@@ -10,7 +10,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  2 files changed, 49 insertions(+), 1 deletion(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 5eae32e..3bac99a 100644
+index 1857f42..777f903 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -23,6 +23,7 @@
@@ -100,7 +100,7 @@ index 5eae32e..3bac99a 100644
      if (msi_enabled(&xhci->pci_dev)) {
          trace_usb_xhci_irq_msi(0);
          msi_notify(&xhci->pci_dev, 0);
-@@ -2284,6 +2320,7 @@ static void xhci_reset(DeviceState *dev)
+@@ -2282,6 +2318,7 @@ static void xhci_reset(DeviceState *dev)
      xhci->erstba_high = 0;
      xhci->erdp_low = 0;
      xhci->erdp_high = 0;
@@ -108,7 +108,7 @@ index 5eae32e..3bac99a 100644
  
      xhci->er_ep_idx = 0;
      xhci->er_pcs = 1;
-@@ -2592,6 +2629,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2590,6 +2627,7 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
          xhci->iman &= ~IMAN_IE;
          xhci->iman |= val & IMAN_IE;
          xhci_intx_update(xhci);
@@ -138,10 +138,10 @@ index 5eae32e..3bac99a 100644
      DEFINE_PROP_UINT32("p3",  XHCIState, numports_3, 4),
      DEFINE_PROP_END_OF_LIST(),
 diff --git a/trace-events b/trace-events
-index 5bc591a..8589ca4 100644
+index d941e78..f86bbda 100644
 --- a/trace-events
 +++ b/trace-events
-@@ -313,6 +313,9 @@ usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
+@@ -316,6 +316,9 @@ usb_xhci_runtime_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
  usb_xhci_doorbell_write(uint32_t off, uint32_t val) "off 0x%04x, val 0x%08x"
  usb_xhci_irq_intx(uint32_t level) "level %d"
  usb_xhci_irq_msi(uint32_t nr) "nr %d"
@@ -152,5 +152,5 @@ index 5bc591a..8589ca4 100644
  usb_xhci_fetch_trb(uint64_t addr, const char *name, uint64_t param, uint32_t status, uint32_t control) "addr %016" PRIx64 ", %s, p %016" PRIx64 ", s %08x, c 0x%08x"
  usb_xhci_slot_enable(uint32_t slotid) "slotid %d"
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0348-xhci-move-register-update-into-xhci_intr_raise.patch b/0619-xhci-move-register-update-into-xhci_intr_raise.patch
similarity index 88%
rename from 0348-xhci-move-register-update-into-xhci_intr_raise.patch
rename to 0619-xhci-move-register-update-into-xhci_intr_raise.patch
index 60537da..f89d2a2 100644
--- a/0348-xhci-move-register-update-into-xhci_intr_raise.patch
+++ b/0619-xhci-move-register-update-into-xhci_intr_raise.patch
@@ -1,7 +1,7 @@
-From c7ca31b2f54b945ba4babf8ad329c938462c75f5 Mon Sep 17 00:00:00 2001
+From be996e1a852397f4009d08ac803081e1dfbc7326 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Thu, 30 Aug 2012 14:04:04 +0200
-Subject: [PATCH 348/366] xhci: move register update into xhci_intr_raise
+Subject: [PATCH] xhci: move register update into xhci_intr_raise
 
 Now that we have a separate function to raise an IRQ we can move
 some comon code into the function.
@@ -12,7 +12,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 5 insertions(+), 9 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 3bac99a..e39fe04 100644
+index 777f903..32d22f7 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -662,8 +662,11 @@ static void xhci_msix_update(XHCIState *xhci)
@@ -51,5 +51,5 @@ index 3bac99a..e39fe04 100644
  }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0349-xhci-add-XHCIInterrupter.patch b/0620-xhci-add-XHCIInterrupter.patch
similarity index 96%
rename from 0349-xhci-add-XHCIInterrupter.patch
rename to 0620-xhci-add-XHCIInterrupter.patch
index 3ad7de3..2992970 100644
--- a/0349-xhci-add-XHCIInterrupter.patch
+++ b/0620-xhci-add-XHCIInterrupter.patch
@@ -1,7 +1,7 @@
-From 84ce3d5155c984ad131ba7153b9c3646c88b8636 Mon Sep 17 00:00:00 2001
+From 40ddf0dafd6a8171d2a0f960a21d7d99bdf73cd6 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Thu, 30 Aug 2012 15:49:03 +0200
-Subject: [PATCH 349/366] xhci: add XHCIInterrupter
+Subject: [PATCH] xhci: add XHCIInterrupter
 
 Move all state belonging to the (single) interrupter into a separate
 struct.  First step in adding support for multiple interrupters.
@@ -13,7 +13,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  2 files changed, 161 insertions(+), 148 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index e39fe04..ddc3825 100644
+index 32d22f7..8a14ee8 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -378,6 +378,27 @@ typedef struct XHCIEvent {
@@ -453,7 +453,7 @@ index e39fe04..ddc3825 100644
              reported = 1;
              if (xfer->status != CC_SUCCESS) {
                  return;
-@@ -2246,7 +2255,7 @@ static void xhci_process_commands(XHCIState *xhci)
+@@ -2244,7 +2253,7 @@ static void xhci_process_commands(XHCIState *xhci)
              break;
          }
          event.slotid = slotid;
@@ -462,7 +462,7 @@ index e39fe04..ddc3825 100644
      }
  }
  
-@@ -2276,7 +2285,7 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach)
+@@ -2274,7 +2283,7 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach)
          port->portsc |= PORTSC_CSC;
          XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS,
                           port->portnr << 24};
@@ -471,7 +471,7 @@ index e39fe04..ddc3825 100644
          DPRINTF("xhci: port change event for port %d\n", port->portnr);
      }
  }
-@@ -2309,20 +2318,22 @@ static void xhci_reset(DeviceState *dev)
+@@ -2307,20 +2316,22 @@ static void xhci_reset(DeviceState *dev)
          xhci_update_port(xhci, xhci->ports + i, 0);
      }
  
@@ -507,7 +507,7 @@ index e39fe04..ddc3825 100644
  
      xhci->mfindex_start = qemu_get_clock_ns(vm_clock);
      xhci_mfwrap_update(xhci);
-@@ -2553,7 +2564,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2551,7 +2562,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
          if (xhci->crcr_low & (CRCR_CA|CRCR_CS) && (xhci->crcr_low & CRCR_CRR)) {
              XHCIEvent event = {ER_COMMAND_COMPLETE, CC_COMMAND_RING_STOPPED};
              xhci->crcr_low &= ~CRCR_CRR;
@@ -516,7 +516,7 @@ index e39fe04..ddc3825 100644
              DPRINTF("xhci: command ring stopped (CRCR=%08x)\n", xhci->crcr_low);
          } else {
              dma_addr_t base = xhci_addr64(xhci->crcr_low & ~0x3f, val);
-@@ -2577,6 +2588,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2575,6 +2586,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
  
  static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
  {
@@ -524,7 +524,7 @@ index e39fe04..ddc3825 100644
      uint32_t ret;
  
      switch (reg) {
-@@ -2584,25 +2596,25 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
+@@ -2582,25 +2594,25 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
          ret = xhci_mfindex_get(xhci) & 0x3fff;
          break;
      case 0x20: /* IMAN */
@@ -557,7 +557,7 @@ index e39fe04..ddc3825 100644
          break;
      default:
          fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg);
-@@ -2615,42 +2627,43 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
+@@ -2613,42 +2625,43 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
  
  static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
  {
@@ -625,10 +625,10 @@ index e39fe04..ddc3825 100644
  
  static void xhci_complete(USBPort *port, USBPacket *packet)
 diff --git a/trace-events b/trace-events
-index 8589ca4..b25ae1c 100644
+index f86bbda..f5b5097 100644
 --- a/trace-events
 +++ b/trace-events
-@@ -316,7 +316,7 @@ usb_xhci_irq_msi(uint32_t nr) "nr %d"
+@@ -319,7 +319,7 @@ usb_xhci_irq_msi(uint32_t nr) "nr %d"
  usb_xhci_irq_msix(uint32_t nr) "nr %d"
  usb_xhci_irq_msix_use(uint32_t nr) "nr %d"
  usb_xhci_irq_msix_unuse(uint32_t nr) "nr %d"
@@ -638,5 +638,5 @@ index 8589ca4..b25ae1c 100644
  usb_xhci_slot_enable(uint32_t slotid) "slotid %d"
  usb_xhci_slot_disable(uint32_t slotid) "slotid %d"
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0350-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch b/0621-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch
similarity index 93%
rename from 0350-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch
rename to 0621-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch
index 305b321..d753d08 100644
--- a/0350-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch
+++ b/0621-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch
@@ -1,7 +1,7 @@
-From 8bbd489bb885f5799ebbc108022eee3b2d5a1682 Mon Sep 17 00:00:00 2001
+From 670eba790c368e9c37b0c964d94e0ff7f0d0c443 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Thu, 30 Aug 2012 17:15:12 +0200
-Subject: [PATCH 350/366] xhci: prepare xhci_runtime_{read,write} for multiple
+Subject: [PATCH] xhci: prepare xhci_runtime_{read,write} for multiple
  interrupters
 
 Prepare xhci runtime register access function for multiple interrupters.
@@ -12,10 +12,10 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 57 insertions(+), 43 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index ddc3825..68a19ab 100644
+index 8a14ee8..6b3ff16 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
-@@ -2588,37 +2588,43 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2586,37 +2586,43 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
  
  static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
  {
@@ -89,7 +89,7 @@ index ddc3825..68a19ab 100644
      }
  
      trace_usb_xhci_runtime_read(reg, ret);
-@@ -2627,43 +2633,51 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
+@@ -2625,43 +2631,51 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
  
  static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
  {
@@ -155,5 +155,5 @@ index ddc3825..68a19ab 100644
      default:
          fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0351-xhci-pick-target-interrupter.patch b/0622-xhci-pick-target-interrupter.patch
similarity index 89%
rename from 0351-xhci-pick-target-interrupter.patch
rename to 0622-xhci-pick-target-interrupter.patch
index bf95359..e336b49 100644
--- a/0351-xhci-pick-target-interrupter.patch
+++ b/0622-xhci-pick-target-interrupter.patch
@@ -1,7 +1,7 @@
-From 11ba203517cc28be513ac31c12762c4519e98ee5 Mon Sep 17 00:00:00 2001
+From d6968ced27f697b26d7a1d5b44f15eeb300a9fd6 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Fri, 31 Aug 2012 15:30:51 +0200
-Subject: [PATCH 351/366] xhci: pick target interrupter
+Subject: [PATCH] xhci: pick target interrupter
 
 Pick the correct interrupter when queuing an event.
 
@@ -11,7 +11,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 16 insertions(+), 6 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 68a19ab..d6ab0c6 100644
+index 6b3ff16..3b03c6c 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -264,6 +264,10 @@ typedef enum TRBCCode {
@@ -52,7 +52,7 @@ index 68a19ab..d6ab0c6 100644
              reported = 1;
              if (xfer->status != CC_SUCCESS) {
                  return;
-@@ -2255,7 +2265,7 @@ static void xhci_process_commands(XHCIState *xhci)
+@@ -2253,7 +2263,7 @@ static void xhci_process_commands(XHCIState *xhci)
              break;
          }
          event.slotid = slotid;
@@ -61,7 +61,7 @@ index 68a19ab..d6ab0c6 100644
      }
  }
  
-@@ -2285,7 +2295,7 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach)
+@@ -2283,7 +2293,7 @@ static void xhci_update_port(XHCIState *xhci, XHCIPort *port, int is_detach)
          port->portsc |= PORTSC_CSC;
          XHCIEvent ev = { ER_PORT_STATUS_CHANGE, CC_SUCCESS,
                           port->portnr << 24};
@@ -70,7 +70,7 @@ index 68a19ab..d6ab0c6 100644
          DPRINTF("xhci: port change event for port %d\n", port->portnr);
      }
  }
-@@ -2564,7 +2574,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2562,7 +2572,7 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
          if (xhci->crcr_low & (CRCR_CA|CRCR_CS) && (xhci->crcr_low & CRCR_CRR)) {
              XHCIEvent event = {ER_COMMAND_COMPLETE, CC_COMMAND_RING_STOPPED};
              xhci->crcr_low &= ~CRCR_CRR;
@@ -89,5 +89,5 @@ index 68a19ab..d6ab0c6 100644
  
  static void xhci_complete(USBPort *port, USBPacket *packet)
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0352-xhci-support-multiple-interrupters.patch b/0623-xhci-support-multiple-interrupters.patch
similarity index 83%
rename from 0352-xhci-support-multiple-interrupters.patch
rename to 0623-xhci-support-multiple-interrupters.patch
index 08b1d44..0d8ffbd 100644
--- a/0352-xhci-support-multiple-interrupters.patch
+++ b/0623-xhci-support-multiple-interrupters.patch
@@ -1,7 +1,7 @@
-From d6d045365af5cef5bc98ad48dcf4172cbe35c7c4 Mon Sep 17 00:00:00 2001
+From 4e4d4191a40b5cbcd6f967ed105eea559104cd8a Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 4 Sep 2012 12:56:55 +0200
-Subject: [PATCH 352/366] xhci: support multiple interrupters
+Subject: [PATCH] xhci: support multiple interrupters
 
 Everything is in place, flip the big switch now
 and enable support for multiple interrupters.
@@ -12,7 +12,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 1 insertion(+), 5 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index d6ab0c6..55e31ec 100644
+index 3b03c6c..4992705 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -42,7 +42,7 @@
@@ -36,5 +36,5 @@ index d6ab0c6..55e31ec 100644
  #define USBCMD_RS       (1<<0)
  #define USBCMD_HCRST    (1<<1)
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0353-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch b/0624-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch
similarity index 91%
rename from 0353-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch
rename to 0624-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch
index 04a2dbf..ec23202 100644
--- a/0353-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch
+++ b/0624-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch
@@ -1,8 +1,7 @@
-From e5295db184d2b78a6a779aac019acbf58ed3da5e Mon Sep 17 00:00:00 2001
+From d2efc9f3dc62810ef6075f8759c9856016447c14 Mon Sep 17 00:00:00 2001
 From: Gerd Hoffmann <kraxel at redhat.com>
 Date: Tue, 4 Sep 2012 14:42:20 +0200
-Subject: [PATCH 353/366] xhci: kill xhci_mem_{read,write} dispatcher
- functions
+Subject: [PATCH] xhci: kill xhci_mem_{read,write} dispatcher functions
 
 ... and register subregions instead, so we offload the dispatching
 to the the memory subsystem which is designed to handle it.
@@ -13,7 +12,7 @@ Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
  1 file changed, 75 insertions(+), 65 deletions(-)
 
 diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
-index 55e31ec..500892d 100644
+index 4992705..4ba9464 100644
 --- a/hw/usb/hcd-xhci.c
 +++ b/hw/usb/hcd-xhci.c
 @@ -404,6 +404,10 @@ struct XHCIState {
@@ -27,7 +26,7 @@ index 55e31ec..500892d 100644
      const char *name;
      unsigned int devaddr;
  
-@@ -2345,8 +2349,9 @@ static void xhci_reset(DeviceState *dev)
+@@ -2343,8 +2347,9 @@ static void xhci_reset(DeviceState *dev)
      xhci_mfwrap_update(xhci);
  }
  
@@ -38,7 +37,7 @@ index 55e31ec..500892d 100644
      uint32_t ret;
  
      switch (reg) {
-@@ -2403,7 +2408,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
+@@ -2401,7 +2406,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
          ret = 0x00000000; /* reserved */
          break;
      default:
@@ -47,7 +46,7 @@ index 55e31ec..500892d 100644
          ret = 0;
      }
  
-@@ -2484,8 +2489,9 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2482,8 +2487,9 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val)
      }
  }
  
@@ -58,7 +57,7 @@ index 55e31ec..500892d 100644
      uint32_t ret;
  
      if (reg >= 0x400) {
-@@ -2521,7 +2527,7 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
+@@ -2519,7 +2525,7 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
          ret = xhci->config;
          break;
      default:
@@ -67,7 +66,7 @@ index 55e31ec..500892d 100644
          ret = 0;
      }
  
-@@ -2529,8 +2535,11 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
+@@ -2527,8 +2533,11 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
      return ret;
  }
  
@@ -80,7 +79,7 @@ index 55e31ec..500892d 100644
      if (reg >= 0x400) {
          xhci_port_write(xhci, reg - 0x400, val);
          return;
-@@ -2588,12 +2597,14 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2586,12 +2595,14 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
          xhci->config = val & 0xff;
          break;
      default:
@@ -97,7 +96,7 @@ index 55e31ec..500892d 100644
      uint32_t ret = 0;
  
      if (reg < 0x20) {
-@@ -2602,7 +2613,8 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
+@@ -2600,7 +2611,8 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
              ret = xhci_mfindex_get(xhci) & 0x3fff;
              break;
          default:
@@ -107,7 +106,7 @@ index 55e31ec..500892d 100644
              break;
          }
      } else {
-@@ -2637,14 +2649,16 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
+@@ -2635,14 +2647,16 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
      return ret;
  }
  
@@ -126,7 +125,7 @@ index 55e31ec..500892d 100644
          return;
      }
  
-@@ -2686,19 +2700,24 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2684,19 +2698,24 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
          xhci_events_update(xhci, v);
          break;
      default:
@@ -154,7 +153,7 @@ index 55e31ec..500892d 100644
      trace_usb_xhci_doorbell_write(reg, val);
  
      if (!xhci_running(xhci)) {
-@@ -2712,69 +2731,47 @@ static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val)
+@@ -2710,69 +2729,47 @@ static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val)
          if (val == 0) {
              xhci_process_commands(xhci);
          } else {
@@ -249,9 +248,9 @@ index 55e31ec..500892d 100644
 +static const MemoryRegionOps xhci_doorbell_ops = {
 +    .read = xhci_doorbell_read,
 +    .write = xhci_doorbell_write,
-     .valid.min_access_size = 4,
+     .valid.min_access_size = 1,
      .valid.max_access_size = 4,
-     .endianness = DEVICE_LITTLE_ENDIAN,
+     .impl.min_access_size = 4,
 @@ -2940,8 +2937,21 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
  
      xhci->irq = xhci->pci_dev.irq[0];
@@ -277,5 +276,5 @@ index 55e31ec..500892d 100644
                       PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
                       &xhci->mem);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0362-usb-redir-Change-cancelled-packet-code-into-a-generi.patch b/0625-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
similarity index 92%
rename from 0362-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
rename to 0625-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
index 2efd733..1f0e575 100644
--- a/0362-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
+++ b/0625-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
@@ -1,8 +1,8 @@
-From efbf5d06a89ec7b329d2aa15d3a6ea023b63c646 Mon Sep 17 00:00:00 2001
+From 5b44a6c9c102b69690adcc2c5be886857ea35ebd Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Tue, 4 Sep 2012 14:18:34 +0200
-Subject: [PATCH 361/365] usb-redir: Change cancelled packet code into a
- generic packet-id queue
+Subject: [PATCH] usb-redir: Change cancelled packet code into a generic
+ packet-id queue
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 ---
@@ -10,7 +10,7 @@ Signed-off-by: Hans de Goede <hdegoede at redhat.com>
  1 file changed, 71 insertions(+), 31 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 9cbcddb..08776d9 100644
+index f183263..e2b8159 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
 @@ -43,7 +43,6 @@
@@ -61,7 +61,7 @@ index 9cbcddb..08776d9 100644
  static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
  static void usbredir_device_connect(void *priv,
      struct usb_redir_device_connect_header *device_connect);
-@@ -249,37 +255,75 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
+@@ -251,37 +257,75 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
   * Cancelled and buffered packets helpers
   */
  
@@ -155,7 +155,7 @@ index 9cbcddb..08776d9 100644
  }
  
  static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
-@@ -942,7 +986,7 @@ static int usbredir_initfn(USBDevice *udev)
+@@ -937,7 +981,7 @@ static int usbredir_initfn(USBDevice *udev)
      dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
      dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
  
@@ -164,7 +164,7 @@ index 9cbcddb..08776d9 100644
      for (i = 0; i < MAX_ENDPOINTS; i++) {
          QTAILQ_INIT(&dev->endpoint[i].bufpq);
      }
-@@ -960,13 +1004,9 @@ static int usbredir_initfn(USBDevice *udev)
+@@ -955,13 +999,9 @@ static int usbredir_initfn(USBDevice *udev)
  
  static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
  {
@@ -180,5 +180,5 @@ index 9cbcddb..08776d9 100644
          usbredir_free_bufpq(dev, I2EP(i));
      }
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0363-usb-redir-Add-an-already_in_flight-packet-id-queue.patch b/0626-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
similarity index 87%
rename from 0363-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
rename to 0626-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
index 10c9aa3..e0e58c1 100644
--- a/0363-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
+++ b/0626-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
@@ -1,7 +1,7 @@
-From b422d151d0861ed346bed7cddb410a6b4c67711b Mon Sep 17 00:00:00 2001
+From 9a38bd644b97a4a3ae92c9246bdcdd09ba937ae8 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Tue, 4 Sep 2012 17:03:54 +0200
-Subject: [PATCH 362/365] usb-redir: Add an already_in_flight packet-id queue
+Subject: [PATCH] usb-redir: Add an already_in_flight packet-id queue
 
 After a live migration, the usb-hcd will re-queue all packets by
 walking over the schedule in the guest memory again, but requests which
@@ -19,7 +19,7 @@ Signed-off-by: Hans de Goede <hdegoede at redhat,com>
  1 file changed, 43 insertions(+)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 08776d9..1c8edd3 100644
+index e2b8159..cdd705f 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
 @@ -98,6 +98,7 @@ struct USBRedirDevice {
@@ -30,7 +30,7 @@ index 08776d9..1c8edd3 100644
      /* Data for device filtering */
      struct usb_redir_device_connect_header device_info;
      struct usb_redir_interface_info_header interface_info;
-@@ -326,6 +327,34 @@ static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id)
+@@ -328,6 +329,34 @@ static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id)
      return packet_id_queue_remove(&dev->cancelled, id);
  }
  
@@ -65,7 +65,7 @@ index 08776d9..1c8edd3 100644
  static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
      uint8_t ep, uint64_t id)
  {
-@@ -541,6 +570,10 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
+@@ -543,6 +572,10 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
  
      DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, p->iov.size, p->id);
  
@@ -76,7 +76,7 @@ index 08776d9..1c8edd3 100644
      bulk_packet.endpoint  = ep;
      bulk_packet.length    = p->iov.size;
      bulk_packet.stream_id = 0;
-@@ -621,6 +654,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
+@@ -623,6 +656,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
          DPRINTF("interrupt-out ep %02X len %zd id %"PRIu64"\n", ep,
                  p->iov.size, p->id);
  
@@ -87,7 +87,7 @@ index 08776d9..1c8edd3 100644
          interrupt_packet.endpoint  = ep;
          interrupt_packet.length    = p->iov.size;
  
-@@ -763,6 +800,10 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
+@@ -765,6 +802,10 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
      USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
      struct usb_redir_control_packet_header control_packet;
  
@@ -98,7 +98,7 @@ index 08776d9..1c8edd3 100644
      /* Special cases for certain standard device requests */
      switch (request) {
      case DeviceOutRequest | USB_REQ_SET_ADDRESS:
-@@ -987,6 +1028,7 @@ static int usbredir_initfn(USBDevice *udev)
+@@ -982,6 +1023,7 @@ static int usbredir_initfn(USBDevice *udev)
      dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
  
      packet_id_queue_init(&dev->cancelled, dev, "cancelled");
@@ -106,7 +106,7 @@ index 08776d9..1c8edd3 100644
      for (i = 0; i < MAX_ENDPOINTS; i++) {
          QTAILQ_INIT(&dev->endpoint[i].bufpq);
      }
-@@ -1007,6 +1049,7 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
+@@ -1002,6 +1044,7 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
      int i;
  
      packet_id_queue_empty(&dev->cancelled);
@@ -115,5 +115,5 @@ index 08776d9..1c8edd3 100644
          usbredir_free_bufpq(dev, I2EP(i));
      }
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0364-usb-redir-Store-max_packet_size-in-endp_data.patch b/0627-usb-redir-Store-max_packet_size-in-endp_data.patch
similarity index 83%
rename from 0364-usb-redir-Store-max_packet_size-in-endp_data.patch
rename to 0627-usb-redir-Store-max_packet_size-in-endp_data.patch
index 16f05d3..2c44744 100644
--- a/0364-usb-redir-Store-max_packet_size-in-endp_data.patch
+++ b/0627-usb-redir-Store-max_packet_size-in-endp_data.patch
@@ -1,7 +1,7 @@
-From c9917c910cf59e2407bbf51770724c5ec17d9cd1 Mon Sep 17 00:00:00 2001
+From c41be182adcd7026fcf76250fc3a64cec8a2c903 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Thu, 6 Sep 2012 20:52:36 +0200
-Subject: [PATCH 363/365] usb-redir: Store max_packet_size in endp_data
+Subject: [PATCH] usb-redir: Store max_packet_size in endp_data
 
 So that we've a place to migrate it to / from to allow restoring it after
 migration.
@@ -12,7 +12,7 @@ Signed-off-by: Hans de Goede <hdegoede at redhat.com>
  1 file changed, 3 insertions(+), 1 deletion(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 1c8edd3..d8568ae 100644
+index cdd705f..6eb3c6d 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
 @@ -57,6 +57,7 @@ struct endp_data {
@@ -23,7 +23,7 @@ index 1c8edd3..d8568ae 100644
      uint8_t iso_started;
      uint8_t iso_error; /* For reporting iso errors to the HC */
      uint8_t interrupt_started;
-@@ -1305,7 +1306,8 @@ static void usbredir_ep_info(void *priv,
+@@ -1300,7 +1301,8 @@ static void usbredir_ep_info(void *priv,
          usb_ep->ifnum = dev->endpoint[i].interface;
          if (usbredirparser_peer_has_cap(dev->parser,
                                       usb_redir_cap_ep_info_max_packet_size)) {
@@ -34,5 +34,5 @@ index 1c8edd3..d8568ae 100644
          if (ep_info->type[i] == usb_redir_type_bulk) {
              usb_ep->pipeline = true;
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0365-usb-redir-Add-support-for-migration.patch b/0628-usb-redir-Add-support-for-migration.patch
similarity index 94%
rename from 0365-usb-redir-Add-support-for-migration.patch
rename to 0628-usb-redir-Add-support-for-migration.patch
index bcbbaab..52d9002 100644
--- a/0365-usb-redir-Add-support-for-migration.patch
+++ b/0628-usb-redir-Add-support-for-migration.patch
@@ -1,7 +1,7 @@
-From 0d733a1280bdaba402c6efbfae116408d7c81bb0 Mon Sep 17 00:00:00 2001
+From a056ffda5a57d7169268e49a3e42c7d79c8f7c48 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Wed, 5 Sep 2012 09:21:44 +0200
-Subject: [PATCH 364/365] usb-redir: Add support for migration
+Subject: [PATCH] usb-redir: Add support for migration
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 ---
@@ -9,7 +9,7 @@ Signed-off-by: Hans de Goede <hdegoede at redhat.com>
  1 file changed, 346 insertions(+), 3 deletions(-)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index d8568ae..812096e 100644
+index 6eb3c6d..b7387b6 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
 @@ -65,8 +65,8 @@ struct endp_data {
@@ -23,7 +23,7 @@ index d8568ae..812096e 100644
  };
  
  struct PacketIdQueueEntry {
-@@ -241,6 +241,11 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
+@@ -243,6 +243,11 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
          return 0;
      }
  
@@ -35,7 +35,7 @@ index d8568ae..812096e 100644
      r = qemu_chr_fe_write(dev->cs, data, count);
  
      if (r < 0) {
-@@ -868,6 +873,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+@@ -870,6 +875,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
  {
      uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
      char version[32];
@@ -43,21 +43,21 @@ index d8568ae..812096e 100644
  
      /* Make sure any pending closes are handled (no-op if none pending) */
      usbredir_chardev_close_bh(dev);
-@@ -903,7 +909,12 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+@@ -902,7 +908,12 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
      usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
      usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
      usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
--    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
+-    usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE, 0);
 +
 +    if (runstate_check(RUN_STATE_INMIGRATE)) {
 +        flags |= usbredirparser_fl_no_hello;
 +    }
-+    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE,
++    usbredirparser_init(dev->parser, VERSION, caps, USB_REDIR_CAPS_SIZE,
 +                        flags);
      usbredirparser_do_write(dev->parser);
  }
  
-@@ -949,6 +960,11 @@ static int usbredir_chardev_can_read(void *opaque)
+@@ -948,6 +959,11 @@ static int usbredir_chardev_can_read(void *opaque)
          return 0;
      }
  
@@ -69,7 +69,7 @@ index d8568ae..812096e 100644
      /* usbredir_parser_do_read will consume *all* data we give it */
      return 1024 * 1024;
  }
-@@ -1004,6 +1020,15 @@ static const QemuChrHandlers usbredir_chr_handlers = {
+@@ -999,6 +1015,15 @@ static const QemuChrHandlers usbredir_chr_handlers = {
   * init + destroy
   */
  
@@ -85,7 +85,7 @@ index d8568ae..812096e 100644
  static int usbredir_initfn(USBDevice *udev)
  {
      USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
-@@ -1041,6 +1066,7 @@ static int usbredir_initfn(USBDevice *udev)
+@@ -1036,6 +1061,7 @@ static int usbredir_initfn(USBDevice *udev)
      qemu_chr_fe_open(dev->cs);
      qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev);
  
@@ -93,7 +93,7 @@ index d8568ae..812096e 100644
      add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
      return 0;
  }
-@@ -1530,6 +1556,322 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
+@@ -1525,6 +1551,322 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
      }
  }
  
@@ -416,7 +416,7 @@ index d8568ae..812096e 100644
  static Property usbredir_properties[] = {
      DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
      DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
-@@ -1550,6 +1892,7 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
+@@ -1545,6 +1887,7 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
      uc->handle_reset   = usbredir_handle_reset;
      uc->handle_data    = usbredir_handle_data;
      uc->handle_control = usbredir_handle_control;
@@ -425,5 +425,5 @@ index d8568ae..812096e 100644
  }
  
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0366-usb-redir-Add-chardev-open-close-debug-logging.patch b/0629-usb-redir-Add-chardev-open-close-debug-logging.patch
similarity index 68%
rename from 0366-usb-redir-Add-chardev-open-close-debug-logging.patch
rename to 0629-usb-redir-Add-chardev-open-close-debug-logging.patch
index 4e2f75d..5e8305d 100644
--- a/0366-usb-redir-Add-chardev-open-close-debug-logging.patch
+++ b/0629-usb-redir-Add-chardev-open-close-debug-logging.patch
@@ -1,7 +1,7 @@
-From 3efd9345ea643cf6f15776425213a92a442dd217 Mon Sep 17 00:00:00 2001
+From 5a717110d859cbd989634e8acdcedd800ee2be74 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Wed, 5 Sep 2012 15:56:57 +0200
-Subject: [PATCH 365/365] usb-redir: Add chardev open / close debug logging
+Subject: [PATCH] usb-redir: Add chardev open / close debug logging
 
 Signed-off-by: Hans de Goede <hdegoede at redhat.com>
 ---
@@ -9,10 +9,10 @@ Signed-off-by: Hans de Goede <hdegoede at redhat.com>
  1 file changed, 6 insertions(+)
 
 diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 812096e..b03c412 100644
+index b7387b6..57e6289 100644
 --- a/hw/usb/redirect.c
 +++ b/hw/usb/redirect.c
-@@ -864,6 +864,7 @@ static void usbredir_chardev_close_bh(void *opaque)
+@@ -866,6 +866,7 @@ static void usbredir_chardev_close_bh(void *opaque)
      usbredir_device_disconnect(dev);
  
      if (dev->parser) {
@@ -20,16 +20,16 @@ index 812096e..b03c412 100644
          usbredirparser_destroy(dev->parser);
          dev->parser = NULL;
      }
-@@ -879,6 +880,8 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+@@ -881,6 +882,8 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
      usbredir_chardev_close_bh(dev);
      qemu_bh_cancel(dev->chardev_close_bh);
  
 +    DPRINTF("creating usbredirparser\n");
 +
-     strcpy(version, "qemu usb-redir guest ");
-     pstrcat(version, sizeof(version), qemu_get_version());
- 
-@@ -990,9 +993,11 @@ static void usbredir_chardev_event(void *opaque, int event)
+     dev->parser = qemu_oom_check(usbredirparser_create());
+     dev->parser->priv = dev;
+     dev->parser->log_func = usbredir_log;
+@@ -989,9 +992,11 @@ static void usbredir_chardev_event(void *opaque, int event)
  
      switch (event) {
      case CHR_EVENT_OPENED:
@@ -41,7 +41,7 @@ index 812096e..b03c412 100644
          qemu_bh_schedule(dev->chardev_close_bh);
          break;
      }
-@@ -1255,6 +1260,7 @@ static void usbredir_device_disconnect(void *priv)
+@@ -1250,6 +1255,7 @@ static void usbredir_device_disconnect(void *priv)
      qemu_del_timer(dev->attach_timer);
  
      if (dev->dev.attached) {
@@ -50,5 +50,5 @@ index 812096e..b03c412 100644
          /*
           * Delay next usb device attach to give the guest a chance to see
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0630-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch b/0630-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch
new file mode 100644
index 0000000..4ffc46b
--- /dev/null
+++ b/0630-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch
@@ -0,0 +1,35 @@
+From b95fb22d2799ed07c55bccbd7ffa3cb19fb7feb3 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Sep 2012 13:49:46 +0200
+Subject: [PATCH] usb-redir: Revert usb-redir part of commit 93bfef4c
+
+Commit 93bfef4c6e4b23caea9d51e1099d06433d8835a4 makes qemu-devices
+which report the qemu version string to the guest in some way use a
+qemu_get_version function which reports a machine-specific version string.
+
+However usb-redir does not expose the qemu version to the guest, only to
+the usbredir-host as part of the initial handshake. This can then be logged
+on the usbredir-host side for debugging purposes and is otherwise completely
+unused! For debugging purposes it is important to have the real qemu version
+in there, rather then the machine-specific version.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ hw/usb/redirect.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
+index 57e6289..78e93a7 100644
+--- a/hw/usb/redirect.c
++++ b/hw/usb/redirect.c
+@@ -875,7 +875,6 @@ static void usbredir_chardev_close_bh(void *opaque)
+ static void usbredir_chardev_open(USBRedirDevice *dev)
+ {
+     uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
+-    char version[32];
+     int flags = 0;
+ 
+     /* Make sure any pending closes are handled (no-op if none pending) */
+-- 
+1.7.12.1
+
diff --git a/0369-ehci-Fix-interrupt-packet-MULT-handling.patch b/0631-ehci-Fix-interrupt-packet-MULT-handling.patch
similarity index 96%
rename from 0369-ehci-Fix-interrupt-packet-MULT-handling.patch
rename to 0631-ehci-Fix-interrupt-packet-MULT-handling.patch
index 3105ad9..17abd7f 100644
--- a/0369-ehci-Fix-interrupt-packet-MULT-handling.patch
+++ b/0631-ehci-Fix-interrupt-packet-MULT-handling.patch
@@ -1,7 +1,7 @@
-From 074e4dddddec4456026e211163e0d8d5c9bfaf0c Mon Sep 17 00:00:00 2001
+From d6fe9953a8277a54ae7f4cefa192b49d9bf99e3d Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Thu, 20 Sep 2012 16:55:02 +0200
-Subject: [PATCH 369/369] ehci: Fix interrupt packet MULT handling
+Subject: [PATCH] ehci: Fix interrupt packet MULT handling
 
 There are several issues with our handling of the MULT epcap field
 of interrupt qhs, which this patch fixes.
@@ -40,7 +40,7 @@ Signed-off-by: Hans de Goede <hdegoede at redhat.com>
  1 file changed, 19 insertions(+), 20 deletions(-)
 
 diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
-index 48a1b09..3acd881a 100644
+index 6a5da84..46f6d99 100644
 --- a/hw/usb/hcd-ehci.c
 +++ b/hw/usb/hcd-ehci.c
 @@ -373,6 +373,7 @@ struct EHCIQueue {
@@ -127,5 +127,5 @@ index 48a1b09..3acd881a 100644
  
      /* 4.10.5 */
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0370-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch b/0632-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch
similarity index 89%
rename from 0370-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch
rename to 0632-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch
index f38d08e..a8bebbd 100644
--- a/0370-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch
+++ b/0632-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch
@@ -1,8 +1,8 @@
-From a873076925e599afe3852f87546e479f23c279ba Mon Sep 17 00:00:00 2001
+From 79467d7c3fe963b39b00c884a5624cb1e754db9d Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Tue, 25 Sep 2012 13:22:21 +0200
-Subject: [PATCH 370/382] usb-redir: Adjust pkg-config check for
- usbredirparser .pc file rename (v2)
+Subject: [PATCH] usb-redir: Adjust pkg-config check for usbredirparser .pc
+ file rename (v2)
 
 The usbredir 0.5 release introduced the new API for 64 bit packet ids, but
 it kept the libusbredirparser.pc name as is, meaning that older versions of
@@ -27,10 +27,10 @@ Signed-off-by: Hans de Goede <hdegoede at redhat.com>
  1 file changed, 3 insertions(+), 3 deletions(-)
 
 diff --git a/configure b/configure
-index d63530a..6c8b8c9 100755
+index 2c4469f..f019526 100755
 --- a/configure
 +++ b/configure
-@@ -2765,10 +2765,10 @@ fi
+@@ -2758,10 +2758,10 @@ fi
  
  # check for usbredirparser for usb network redirection support
  if test "$usb_redir" != "no" ; then
@@ -45,5 +45,5 @@ index d63530a..6c8b8c9 100755
          libs_softmmu="$libs_softmmu $usb_redir_libs"
      else
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0371-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch b/0633-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch
similarity index 91%
rename from 0371-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch
rename to 0633-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch
index 2d7b66c..f39bc12 100644
--- a/0371-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch
+++ b/0633-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch
@@ -1,7 +1,7 @@
-From 0ef8cdced724a03efea3523410ffd51cf1ec308d Mon Sep 17 00:00:00 2001
+From 9ebfb490e04e1fe5466a4d31df17c5e6283236cb Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Thu, 27 Sep 2012 16:59:50 +0200
-Subject: [PATCH 371/372] usb-redir: Change usbredir_open_chardev into
+Subject: [PATCH] usb-redir: Change usbredir_open_chardev into
  usbredir_create_parser
 
 As we need to create the parser at more places.
@@ -45,5 +45,5 @@ index 78e93a7..5d16aff 100644
      case CHR_EVENT_CLOSED:
          DPRINTF("chardev close\n");
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0372-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch b/0634-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch
similarity index 89%
rename from 0372-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch
rename to 0634-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch
index 109a3f3..a222747 100644
--- a/0372-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch
+++ b/0634-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch
@@ -1,8 +1,7 @@
-From adbc805b1f775ef8565bf8d074b45813daa2e779 Mon Sep 17 00:00:00 2001
+From c57b03073357e813ade4b3b34f6c1e3c0de394c2 Mon Sep 17 00:00:00 2001
 From: Hans de Goede <hdegoede at redhat.com>
 Date: Thu, 27 Sep 2012 16:57:41 +0200
-Subject: [PATCH 372/372] usb-redir: Don't make migration fail in none
- seamless case
+Subject: [PATCH] usb-redir: Don't make migration fail in none seamless case
 
 Instead simple disconnect the device like host redirection does on
 migration.
@@ -39,5 +38,5 @@ index 5d16aff..022ba42 100644
  
      data = g_malloc(len);
 -- 
-1.7.12
+1.7.12.1
 
diff --git a/0001-mips-Fix-link-error-with-piix4_pm_init.patch b/0800-mips-Fix-link-error-with-piix4_pm_init.patch
similarity index 92%
rename from 0001-mips-Fix-link-error-with-piix4_pm_init.patch
rename to 0800-mips-Fix-link-error-with-piix4_pm_init.patch
index 723524c..3ceb891 100644
--- a/0001-mips-Fix-link-error-with-piix4_pm_init.patch
+++ b/0800-mips-Fix-link-error-with-piix4_pm_init.patch
@@ -1,4 +1,4 @@
-From 4ba58730950a376dfb9f0424acb2b2cc3fbeda4f Mon Sep 17 00:00:00 2001
+From 5196eaa783b83110e6a8b99bfeb244b758b6e9c7 Mon Sep 17 00:00:00 2001
 From: Cole Robinson <crobinso at redhat.com>
 Date: Mon, 6 Aug 2012 17:12:40 -0400
 Subject: [PATCH] mips: Fix link error with 'piix4_pm_init'
@@ -26,5 +26,5 @@ index 29a5d0d..89af0e9 100644
  
  obj-y := $(addprefix ../,$(obj-y))
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/0002-configure-Add-disable-kvm-options.patch b/0801-configure-Add-disable-kvm-options.patch
similarity index 87%
rename from 0002-configure-Add-disable-kvm-options.patch
rename to 0801-configure-Add-disable-kvm-options.patch
index 4108dea..05021f1 100644
--- a/0002-configure-Add-disable-kvm-options.patch
+++ b/0801-configure-Add-disable-kvm-options.patch
@@ -1,4 +1,4 @@
-From 7b9b4ec74c7c0f63672d3aa627d7b153b71ba427 Mon Sep 17 00:00:00 2001
+From b80fff00ed7f9baff808edb6c2c9f98f7e75e8ca Mon Sep 17 00:00:00 2001
 From: Cole Robinson <crobinso at redhat.com>
 Date: Mon, 13 Aug 2012 18:39:54 -0400
 Subject: [PATCH] configure: Add --disable-kvm-options
@@ -18,10 +18,10 @@ Signed-off-by: Cole Robinson <crobinso at redhat.com>
  1 file changed, 10 insertions(+), 1 deletion(-)
 
 diff --git a/configure b/configure
-index bf3acc8..cf2dc9f 100755
+index f019526..933754d 100755
 --- a/configure
 +++ b/configure
-@@ -211,6 +211,7 @@ bsd_user="no"
+@@ -210,6 +210,7 @@ bsd_user="no"
  guest_base=""
  uname_release=""
  mixemu="no"
@@ -29,7 +29,7 @@ index bf3acc8..cf2dc9f 100755
  aix="no"
  blobs="yes"
  pkgversion=" ($(kvm_version))"
-@@ -747,6 +748,8 @@ for opt do
+@@ -732,6 +733,8 @@ for opt do
    ;;
    --enable-kvm) kvm="yes"
    ;;
@@ -38,7 +38,7 @@ index bf3acc8..cf2dc9f 100755
    --disable-tcg-interpreter) tcg_interpreter="no"
    ;;
    --enable-tcg-interpreter) tcg_interpreter="yes"
-@@ -1113,6 +1116,8 @@ echo "  --enable-bluez           enable bluez stack connectivity"
+@@ -1080,6 +1083,8 @@ echo "  --enable-bluez           enable bluez stack connectivity"
  echo "  --disable-slirp          disable SLIRP userspace network connectivity"
  echo "  --disable-kvm            disable KVM acceleration support"
  echo "  --enable-kvm             enable KVM acceleration support"
@@ -47,7 +47,7 @@ index bf3acc8..cf2dc9f 100755
  echo "  --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI)"
  echo "  --disable-nptl           disable usermode NPTL support"
  echo "  --enable-nptl            enable usermode NPTL support"
-@@ -3156,6 +3161,7 @@ echo "ATTR/XATTR support $attr"
+@@ -3160,6 +3165,7 @@ echo "ATTR/XATTR support $attr"
  echo "Install blobs     $blobs"
  echo "KVM support       $kvm"
  echo "TCG interpreter   $tcg_interpreter"
@@ -55,7 +55,7 @@ index bf3acc8..cf2dc9f 100755
  echo "fdt support       $fdt"
  echo "preadv support    $preadv"
  echo "fdatasync         $fdatasync"
-@@ -3889,7 +3895,10 @@ case "$target_arch2" in
+@@ -3893,7 +3899,10 @@ case "$target_arch2" in
        \( "$target_arch2" = "x86_64" -a "$cpu" = "i386"   \) -o \
        \( "$target_arch2" = "i386"   -a "$cpu" = "x86_64" \) \) ; then
        echo "CONFIG_KVM=y" >> $config_target_mak
@@ -68,5 +68,5 @@ index bf3acc8..cf2dc9f 100755
          echo "CONFIG_VHOST_NET=y" >> $config_target_mak
        fi
 -- 
-1.7.11.2
+1.7.12.1
 
diff --git a/qemu.spec b/qemu.spec
index f06fa65..a596ecf 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -109,7 +109,7 @@
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
 Version: 1.2.0
-Release: 16%{?dist}
+Release: 17%{?dist}
 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
@@ -149,141 +149,324 @@ Source9: ksmtuned.conf
 Source10: qemu-guest-agent.service
 Source11: 99-qemu-guest-agent.rules
 
-# Non upstream build fix
-Patch1: 0001-mips-Fix-link-error-with-piix4_pm_init.patch
-
-# Add ./configure --disable-kvm-options
-# keep: Carrying locally until qemu-kvm is fully merged into qemu.git
-Patch2: 0002-configure-Add-disable-kvm-options.patch
+# Patches queued for 1.2.1 stable
+Patch0001: 0001-target-xtensa-convert-host-errno-values-to-guest.patch
+Patch0002: 0002-target-cris-Fix-buffer-overflow.patch
+Patch0003: 0003-target-xtensa-fix-missing-errno-codes-for-mingw32.patch
+Patch0004: 0004-target-sparc-fix-fcmp-s-d-q-instructions-wrt-excepti.patch
+Patch0005: 0005-target-s390x-fix-style.patch
+Patch0006: 0006-target-s390x-split-FPU-ops.patch
+Patch0007: 0007-target-s390x-split-condition-code-helpers.patch
+Patch0008: 0008-target-s390x-split-integer-helpers.patch
+Patch0009: 0009-target-s390x-split-memory-access-helpers.patch
+Patch0010: 0010-target-s390x-rename-op_helper.c-to-misc_helper.c.patch
+Patch0011: 0011-target-s390x-avoid-AREG0-for-FPU-helpers.patch
+Patch0012: 0012-target-s390x-avoid-AREG0-for-integer-helpers.patch
+Patch0013: 0013-target-s390x-avoid-AREG0-for-condition-code-helpers.patch
+Patch0014: 0014-target-s390x-avoid-AREG0-for-misc-helpers.patch
+Patch0015: 0015-target-s390x-switch-to-AREG0-free-mode.patch
+Patch0016: 0016-tcg-s390-fix-ld-st-with-CONFIG_TCG_PASS_AREG0.patch
+Patch0017: 0017-target-arm-Fix-potential-buffer-overflow.patch
+Patch0018: 0018-tcg-optimize-split-expression-simplification.patch
+Patch0019: 0019-tcg-optimize-simplify-or-xor-r-a-0-cases.patch
+Patch0020: 0020-tcg-optimize-simplify-and-r-a-0-cases.patch
+Patch0021: 0021-tcg-optimize-simplify-shift-rot-r-0-a-movi-r-0-cases.patch
+Patch0022: 0022-tcg-optimize-swap-brcond-setcond-arguments-when-poss.patch
+Patch0023: 0023-tcg-optimize-add-constant-folding-for-setcond.patch
+Patch0024: 0024-tcg-optimize-add-constant-folding-for-brcond.patch
+Patch0025: 0025-tcg-optimize-fix-if-else-break-coding-style.patch
+Patch0026: 0026-target-s390x-avoid-cpu_single_env.patch
+Patch0027: 0027-target-lm32-switch-to-AREG0-free-mode.patch
+Patch0028: 0028-target-m68k-switch-to-AREG0-free-mode.patch
+Patch0029: 0029-target-m68k-avoid-using-cpu_single_env.patch
+Patch0030: 0030-target-unicore32-switch-to-AREG0-free-mode.patch
+Patch0031: 0031-target-arm-convert-void-helpers.patch
+Patch0032: 0032-target-arm-convert-remaining-helpers.patch
+Patch0033: 0033-target-arm-final-conversion-to-AREG0-free-mode.patch
+Patch0034: 0034-target-microblaze-switch-to-AREG0-free-mode.patch
+Patch0035: 0035-target-cris-Avoid-AREG0-for-helpers.patch
+Patch0036: 0036-target-cris-Switch-to-AREG0-free-mode.patch
+Patch0037: 0037-target-sh4-switch-to-AREG0-free-mode.patch
+Patch0038: 0038-target-mips-switch-to-AREG0-free-mode.patch
+Patch0039: 0039-Remove-unused-CONFIG_TCG_PASS_AREG0-and-dead-code.patch
+Patch0040: 0040-tcg-i386-allow-constants-in-load-store-ops.patch
+Patch0041: 0041-tcg-mark-set_label-with-TCG_OPF_BB_END-flag.patch
+Patch0042: 0042-revert-TCG-fix-copy-propagation.patch
+Patch0043: 0043-target-mips-Set-opn-in-gen_ldst_multiple.patch
+Patch0044: 0044-target-mips-Fix-MIPS_DEBUG.patch
+Patch0045: 0045-target-mips-Always-evaluate-debugging-macro-argument.patch
+Patch0046: 0046-tcg-optimize-fix-end-of-basic-block-detection.patch
+Patch0047: 0047-target-xtensa-fix-extui-shift-amount.patch
+Patch0048: 0048-target-xtensa-don-t-emit-extra-tcg_gen_goto_tb.patch
+Patch0049: 0049-tcg-Introduce-movcond.patch
+Patch0050: 0050-target-alpha-Use-movcond.patch
+Patch0051: 0051-tcg-i386-Implement-movcond.patch
+Patch0052: 0052-tcg-Optimize-movcond-for-constant-comparisons.patch
+Patch0053: 0053-tcg-Optimize-two-address-commutative-operations.patch
+Patch0054: 0054-gdbstub-sh4-fix-build-with-USE_SOFTFLOAT_STRUCT_TYPE.patch
+Patch0055: 0055-tcg-Fix-USE_DIRECT_JUMP.patch
+Patch0056: 0056-tcg-hppa-Fix-brcond2-and-setcond2.patch
+Patch0057: 0057-tcg-hppa-Fix-broken-load-store-helpers.patch
+Patch0058: 0058-tcg-mips-fix-wrong-usage-of-Z-constraint.patch
+Patch0059: 0059-tcg-mips-kill-warnings-in-user-mode.patch
+Patch0060: 0060-tcg-mips-use-TCGArg-or-TCGReg-instead-of-int.patch
+Patch0061: 0061-tcg-mips-don-t-use-global-pointer.patch
+Patch0062: 0062-tcg-mips-use-stack-for-TCG-temps.patch
+Patch0063: 0063-tcg-mips-optimize-brcond-arg-0.patch
+Patch0064: 0064-tcg-mips-optimize-bswap-16-16s-32-on-MIPS32R2.patch
+Patch0065: 0065-tcg-mips-implement-rotl-rotr-ops-on-MIPS32R2.patch
+Patch0066: 0066-tcg-mips-implement-deposit-op-on-MIPS32R2.patch
+Patch0067: 0067-tcg-mips-implement-movcond-op-on-MIPS32R2.patch
+Patch0068: 0068-tcg-optimize-remove-TCG_TEMP_ANY.patch
+Patch0069: 0069-tcg-optimize-check-types-in-copy-propagation.patch
+Patch0070: 0070-tcg-optimize-rework-copy-progagation.patch
+Patch0071: 0071-tcg-optimize-do-copy-propagation-for-all-operations.patch
+Patch0072: 0072-tcg-optimize-optimize-op-r-a-a-mov-r-a.patch
+Patch0073: 0073-tcg-optimize-optimize-op-r-a-a-movi-r-0.patch
+Patch0074: 0074-tcg-optimize-further-optimize-brcond-movcond-setcond.patch
+Patch0075: 0075-tcg-optimize-prefer-the-op-a-a-b-form-for-commutativ.patch
+Patch0076: 0076-tcg-remove-ifdef-endif-around-TCGOpcode-tests.patch
+Patch0077: 0077-tcg-optimize-add-constant-folding-for-deposit.patch
+Patch0078: 0078-tcg-README-document-tcg_gen_goto_tb-restrictions.patch
+Patch0079: 0079-w64-Fix-TCG-helper-functions-with-5-arguments.patch
+Patch0080: 0080-tcg-ppc32-Implement-movcond32.patch
+Patch0081: 0081-tcg-sparc-Hack-in-qemu_ld-st64-for-32-bit.patch
+Patch0082: 0082-tcg-sparc-Fix-ADDX-opcode.patch
+Patch0083: 0083-tcg-sparc-Don-t-MAP_FIXED-on-top-of-the-program.patch
+Patch0084: 0084-tcg-sparc-Assume-v9-cpu-always-i.e.-force-v8plus-in-.patch
+Patch0085: 0085-tcg-sparc-Fix-qemu_ld-st-to-handle-32-bit-host.patch
+Patch0086: 0086-tcg-sparc-Support-GUEST_BASE.patch
+Patch0087: 0087-tcg-sparc-Change-AREG0-in-generated-code-to-i0.patch
+Patch0088: 0088-tcg-sparc-Clean-up-cruft-stemming-from-attempts-to-u.patch
+Patch0089: 0089-tcg-sparc-Mask-shift-immediates-to-avoid-illegal-ins.patch
+Patch0090: 0090-tcg-sparc-Use-defines-for-temporaries.patch
+Patch0091: 0091-tcg-sparc-Add-g-o-registers-to-alloc_order.patch
+Patch0092: 0092-tcg-sparc-Fix-and-enable-direct-TB-chaining.patch
+Patch0093: 0093-tcg-sparc-Preserve-branch-destinations-during-retran.patch
+Patch0094: 0094-target-alpha-Initialize-env-cpu_model_str.patch
+Patch0095: 0095-tcg-mips-fix-MIPS32-R2-detection.patch
+Patch0096: 0096-tcg-Adjust-descriptions-of-cond-opcodes.patch
+Patch0097: 0097-tcg-i386-fix-build-with-march-i686.patch
+Patch0098: 0098-tcg-Fix-MAX_OPC_PARAM_IARGS.patch
+Patch0099: 0099-tci-Fix-for-AREG0-free-mode.patch
+Patch0100: 0100-spice-abort-on-invalid-streaming-cmdline-params.patch
+Patch0101: 0101-spice-notify-spice-server-on-vm-start-stop.patch
+Patch0102: 0102-spice-notify-on-vm-state-change-only-via-spice_serve.patch
+Patch0103: 0103-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch
+Patch0104: 0104-spice-add-migrated-flag-to-spice-info.patch
+Patch0105: 0105-spice-adding-seamless-migration-option-to-the-comman.patch
+Patch0106: 0106-spice-increase-the-verbosity-of-spice-section-in-qem.patch
+Patch0107: 0107-qxl-update_area_io-guest_bug-on-invalid-parameters.patch
+Patch0108: 0108-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch
+Patch0109: 0109-configure-print-spice-protocol-and-spice-server-vers.patch
+Patch0110: 0110-fix-doc-of-using-raw-values-with-sendkey.patch
+Patch0111: 0111-qapi-Fix-potential-NULL-pointer-segfault.patch
+Patch0112: 0112-json-parser-Fix-potential-NULL-pointer-segfault.patch
+Patch0113: 0113-pcie-drop-version_id-field-for-live-migration.patch
+Patch0114: 0114-pcie_aer-clear-cmask-for-Advanced-Error-Interrupt-Me.patch
+Patch0115: 0115-fix-entry-pointer-for-ELF-kernels-loaded-with-kernel.patch
+Patch0116: 0116-lan9118-fix-multicast-filtering.patch
+Patch0117: 0117-MIPS-user-Fix-reset-CPU-state-initialization.patch
+Patch0118: 0118-Add-MAINTAINERS-entry-for-leon3.patch
+Patch0119: 0119-musicpal-Fix-flash-mapping.patch
+Patch0120: 0120-qemu-Use-valgrind-annotations-to-mark-kvm-guest-memo.patch
+Patch0121: 0121-hw-wm8750-Fix-potential-buffer-overflow.patch
+Patch0122: 0122-hw-mcf5206-Fix-buffer-overflow-for-MBAR-read-write.patch
+Patch0123: 0123-use-libexecdir-instead-of-ignoring-it-first-and-rein.patch
+Patch0124: 0124-socket-don-t-attempt-to-reconnect-a-TCP-socket-in-se.patch
+Patch0125: 0125-Add-ability-to-force-enable-disable-of-tools-build.patch
+Patch0126: 0126-usb-controllers-do-not-need-to-check-for-babble-them.patch
+Patch0127: 0127-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch
+Patch0128: 0128-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch
+Patch0129: 0129-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch
+Patch0130: 0130-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch
+Patch0131: 0131-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch
+Patch0132: 0132-ehci-Update-copyright-headers-to-reflect-recent-work.patch
+Patch0133: 0133-ehci-Properly-cleanup-packets-on-cancel.patch
+Patch0134: 0134-ehci-Properly-report-completed-but-not-yet-processed.patch
+Patch0135: 0135-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch
+Patch0136: 0136-ehci-trace-guest-bugs.patch
+Patch0137: 0137-ehci-add-doorbell-trace-events.patch
+Patch0138: 0138-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch
+Patch0139: 0139-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch
+Patch0140: 0140-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch
+Patch0141: 0141-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch
+Patch0142: 0142-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch
+Patch0143: 0143-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch
+Patch0144: 0144-usb-redir-Get-rid-of-async-struct-get-member.patch
+Patch0145: 0145-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch
+Patch0146: 0146-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch
+Patch0147: 0147-usb-redir-Move-to-core-packet-id-and-queue-handling.patch
+Patch0148: 0148-usb-redir-Return-babble-when-getting-more-bulk-data-.patch
+Patch0149: 0149-Better-name-usb-braille-device.patch
+Patch0150: 0150-usb-audio-fix-usb-version.patch
+Patch0151: 0151-xhci-rip-out-background-transfer-code.patch
+Patch0152: 0152-xhci-drop-buffering.patch
+Patch0153: 0153-xhci-fix-runtime-write-tracepoint.patch
+Patch0154: 0154-xhci-allow-bytewise-capability-register-reads.patch
+Patch0155: 0155-qxl-dont-update-invalid-area.patch
+Patch0156: 0156-usb-host-allow-emulated-non-async-control-requests-w.patch
+Patch0157: 0157-qxl-better-cleanup-for-surface-destroy.patch
+Patch0158: 0158-ehci-switch-to-new-style-memory-ops.patch
+Patch0159: 0159-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch
+Patch0160: 0160-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch
+Patch0161: 0161-sheepdog-fix-savevm-and-loadvm.patch
+Patch0162: 0162-ide-Fix-error-messages-from-static-code-analysis-no-.patch
+Patch0163: 0163-block-curl-Fix-wrong-free-statement.patch
+Patch0164: 0164-vdi-Fix-warning-from-clang.patch
+Patch0165: 0165-block-fix-block-tray-status.patch
+Patch0166: 0166-ahci-properly-reset-PxCMD-on-HBA-reset.patch
+Patch0167: 0167-Don-t-require-encryption-password-for-qemu-img-info-.patch
+Patch0168: 0168-block-Don-t-forget-to-delete-temporary-file.patch
+Patch0169: 0169-hw-qxl-tracing-fixes.patch
+Patch0170: 0170-configure-usbredir-fixes.patch
+Patch0171: 0171-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch
+Patch0172: 0172-ehci-Walk-async-schedule-before-and-after-migration.patch
+Patch0173: 0173-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch
+Patch0174: 0174-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch
+Patch0175: 0175-slirp-Remove-wrong-type-casts-ins-debug-statements.patch
+Patch0176: 0176-slirp-Fix-error-reported-by-static-code-analysis.patch
+Patch0177: 0177-slirp-improve-TFTP-performance.patch
+Patch0178: 0178-slirp-Handle-more-than-65535-blocks-in-TFTP-transfer.patch
+Patch0179: 0179-slirp-Implement-TFTP-Blocksize-option.patch
+Patch0180: 0180-srp-Don-t-use-QEMU_PACKED-for-single-elements-of-a-s.patch
+Patch0181: 0181-Spelling-fixes-in-comments-and-documentation.patch
+Patch0182: 0182-console-Clean-up-bytes-per-pixel-calculation.patch
+Patch0183: 0183-qapi-Fix-enumeration-typo-error.patch
+Patch0184: 0184-kvm-Fix-warning-from-static-code-analysis.patch
+Patch0185: 0185-arch_init.c-add-missing-symbols-before-PRIu64-in-deb.patch
+Patch0186: 0186-net-notify-iothread-after-flushing-queue.patch
+Patch0187: 0187-e1000-flush-queue-whenever-can_receive-can-go-from-f.patch
+Patch0188: 0188-xen-flush-queue-when-getting-an-event.patch
+Patch0189: 0189-eepro100-Fix-network-hang-when-rx-buffers-run-out.patch
+Patch0190: 0190-net-add-receive_disabled-logic-to-iov-delivery-path.patch
+Patch0191: 0191-net-do-not-report-queued-packets-as-sent.patch
+Patch0192: 0192-net-add-netdev-options-to-man-page.patch
+Patch0193: 0193-net-clean-up-usbnet_receive.patch
+Patch0194: 0194-net-fix-usbnet_receive-packet-drops.patch
+Patch0195: 0195-net-broadcast-hub-packets-if-at-least-one-port-can-r.patch
+Patch0196: 0196-net-asynchronous-send-receive-infrastructure-for-net.patch
+Patch0197: 0197-net-EAGAIN-handling-for-net-socket.c-UDP.patch
+Patch0198: 0198-net-EAGAIN-handling-for-net-socket.c-TCP.patch
+Patch0199: 0199-configure-fix-seccomp-check.patch
+Patch0200: 0200-configure-properly-check-if-lrt-and-lm-is-needed.patch
+Patch0201: 0201-Revert-455aa1e08-and-c3767ed0eb.patch
+Patch0202: 0202-qemu-char-BUGFIX-don-t-call-FD_ISSET-with-negative-f.patch
+Patch0203: 0203-cpu_physical_memory_write_rom-needs-to-do-TB-invalid.patch
+Patch0204: 0204-arch_init.c-Improve-soundhw-help-for-non-HAS_AUDIO_C.patch
+Patch0205: 0205-xilinx_timer-Removed-comma-in-device-name.patch
+Patch0206: 0206-xilinx_timer-Send-dbg-msgs-to-stderr-not-stdout.patch
+Patch0207: 0207-xilinx.h-Error-check-when-setting-links.patch
+Patch0208: 0208-xilinx_timer-Fix-a-compile-error-if-debug-enabled.patch
+Patch0209: 0209-pflash_cfi01-fix-vendor-specific-extended-query.patch
+Patch0210: 0210-MAINTAINERS-Add-entry-for-QOM-CPU.patch
+Patch0211: 0211-iSCSI-We-need-to-support-SG_IO-also-from-iscsi_ioctl.patch
+Patch0212: 0212-iSCSI-We-dont-need-to-explicitely-call-qemu_notify_e.patch
+Patch0213: 0213-scsi-disk-introduce-check_lba_range.patch
+Patch0214: 0214-scsi-disk-fix-check-for-out-of-range-LBA.patch
+Patch0215: 0215-SCSI-Standard-INQUIRY-data-should-report-HiSup-flag-.patch
+Patch0216: 0216-audio-Fix-warning-from-static-code-analysis.patch
+Patch0217: 0217-qemu-ga-Remove-unreachable-code-after-g_error.patch
+Patch0218: 0218-qemu-sockets-Fix-potential-memory-leak.patch
+Patch0219: 0219-cadence_uart-Fix-buffer-overflow.patch
+Patch0220: 0220-lm4549-Fix-buffer-overflow.patch
+Patch0221: 0221-ioh3420-Remove-unreachable-code.patch
+Patch0222: 0222-pflash_cfi01-Fix-warning-caused-by-unreachable-code.patch
+Patch0223: 0223-curses-don-t-initialize-curses-when-qemu-is-daemoniz.patch
+Patch0224: 0224-TextConsole-saturate-escape-parameter-in-TTY_STATE_C.patch
+Patch0225: 0225-linux-user-Remove-redundant-null-check-and-replace-f.patch
+Patch0226: 0226-net-socket-Fix-compiler-warning-regression-for-MinGW.patch
+Patch0227: 0227-w32-Always-use-standard-instead-of-native-format-str.patch
+Patch0228: 0228-w32-Add-implementation-of-gmtime_r-localtime_r.patch
+Patch0229: 0229-blockdev-preserve-readonly-and-snapshot-states-acros.patch
+Patch0230: 0230-block-correctly-set-the-keep_read_only-flag.patch
+Patch0231: 0231-configure-Allow-builds-without-any-system-or-user-em.patch
+Patch0232: 0232-Refactor-inet_connect_opts-function.patch
+Patch0233: 0233-Separate-inet_connect-into-inet_connect-blocking-and.patch
+Patch0234: 0234-Fix-address-handling-in-inet_nonblocking_connect.patch
+Patch0235: 0235-Clear-handler-only-for-valid-fd.patch
+Patch0236: 0236-pl190-fix-read-of-VECTADDR.patch
+Patch0237: 0237-hw-armv7m_nvic-Correctly-register-GIC-region-when-se.patch
+Patch0238: 0238-Versatile-Express-Fix-NOR-flash-0-address-and-remove.patch
+Patch0239: 0239-i386-kvm-bit-10-of-CPUID-8000_0001-.EDX-is-reserved.patch
+Patch0240: 0240-fpu-softfloat.c-Return-correctly-signed-values-from-.patch
+Patch0241: 0241-pseries-Don-t-test-for-MSR_PR-for-hypercalls-under-K.patch
+Patch0242: 0242-update-VERSION-for-v1.2.1.patch
 
 # The infamous chardev flow control patches
-Patch101: 0101-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch
-Patch102: 0102-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
-Patch103: 0103-iohandlers-Add-enable-disable_write_fd_handler-funct.patch
-Patch104: 0104-char-Add-framework-for-a-write-unblocked-callback.patch
-Patch105: 0105-char-Update-send_all-to-handle-nonblocking-chardev-w.patch
-Patch106: 0106-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch
-Patch107: 0107-char-Throttle-when-host-connection-is-down.patch
-Patch108: 0108-virtio-console-Enable-port-throttling-when-chardev-i.patch
-Patch109: 0109-spice-qemu-char.c-add-throttling.patch
-Patch110: 0110-spice-qemu-char.c-remove-intermediate-buffer.patch
-Patch111: 0111-usb-redir-Add-flow-control-support.patch
-Patch112: 0112-virtio-serial-bus-replay-guest_open-on-migration.patch
-Patch113: 0113-char-Disable-write-callback-if-throttled-chardev-is-.patch
+Patch0400: 0400-char-Split-out-tcp-socket-close-code-in-a-separate-f.patch
+Patch0401: 0401-char-Add-a-QemuChrHandlers-struct-to-initialise-char.patch
+Patch0402: 0402-iohandlers-Add-enable-disable_write_fd_handler-funct.patch
+Patch0403: 0403-char-Add-framework-for-a-write-unblocked-callback.patch
+Patch0404: 0404-char-Update-send_all-to-handle-nonblocking-chardev-w.patch
+Patch0405: 0405-char-Equip-the-unix-tcp-backend-to-handle-nonblockin.patch
+Patch0406: 0406-char-Throttle-when-host-connection-is-down.patch
+Patch0407: 0407-virtio-console-Enable-port-throttling-when-chardev-i.patch
+Patch0408: 0408-spice-qemu-char.c-add-throttling.patch
+Patch0409: 0409-spice-qemu-char.c-remove-intermediate-buffer.patch
+Patch0410: 0410-usb-redir-Add-flow-control-support.patch
+Patch0411: 0411-virtio-serial-bus-replay-guest_open-on-migration.patch
+Patch0412: 0412-char-Disable-write-callback-if-throttled-chardev-is-.patch
 
 # Spice features from upstream master: seamless migration & dynamic monitors
-Patch201: 0201-spice-abort-on-invalid-streaming-cmdline-params.patch
-Patch202: 0202-spice-notify-spice-server-on-vm-start-stop.patch
-Patch203: 0203-spice-notify-on-vm-state-change-only-via-spice_serve.patch
-Patch204: 0204-spice-migration-add-QEVENT_SPICE_MIGRATE_COMPLETED.patch
-Patch205: 0205-spice-add-migrated-flag-to-spice-info.patch
-Patch206: 0206-spice-adding-seamless-migration-option-to-the-comman.patch
-Patch207: 0207-spice-increase-the-verbosity-of-spice-section-in-qem.patch
-Patch208: 0208-qxl-update_area_io-guest_bug-on-invalid-parameters.patch
-Patch209: 0209-qxl-disallow-unknown-revisions.patch
-Patch210: 0210-qxl-add-QXL_IO_MONITORS_CONFIG_ASYNC.patch
-Patch211: 0211-configure-print-spice-protocol-and-spice-server-vers.patch
-Patch212: 0212-spice-make-number-of-surfaces-runtime-configurable.patch
-Patch213: 0213-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch
-Patch214: 0214-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch
-Patch215: 0215-spice-switch-to-queue-for-vga-mode-updates.patch
-Patch216: 0216-spice-split-qemu_spice_create_update.patch
-Patch217: 0217-spice-add-screen-mirror.patch
-Patch218: 0218-spice-send-updates-only-for-changed-screen-content.patch
-Patch219: 0219-qxl-dont-update-invalid-area.patch
-Patch220: 0220-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch
-Patch221: 0221-qxl-better-cleanup-for-surface-destroy.patch
-Patch222: 0222-hw-qxl-tracing-fixes.patch
-Patch223: 0223-qxl-add-trace-event-for-QXL_IO_LOG.patch
-Patch224: 0224-hw-qxl-support-client-monitor-configuration-via-devi.patch
-Patch225: 0225-qxl-always-update-displaysurface-on-resize.patch
-Patch226: 0226-qxl-update_area_io-cleanup-invalid-parameters-handli.patch
-Patch227: 0227-qxl-fix-range-check-for-rev3-io-commands.patch
-
-# Ugh, ton of USB bugfixes / preparation patches for usb-redir
-# live-migration which did not make 1.2.0 :|
-# All are in upstream master so can be dropped next qemu release
-Patch0301: 0301-usb-controllers-do-not-need-to-check-for-babble-them.patch
-Patch0302: 0302-usb-core-Don-t-set-packet-state-to-complete-on-a-nak.patch
-Patch0303: 0303-usb-core-Add-a-usb_ep_find_packet_by_id-helper-funct.patch
-Patch0304: 0304-usb-core-Allow-the-first-packet-of-a-pipelined-ep-to.patch
-Patch0305: 0305-Revert-ehci-don-t-flush-cache-on-doorbell-rings.patch
-Patch0306: 0306-ehci-Validate-qh-is-not-changed-unexpectedly-by-the-.patch
-Patch0307: 0307-ehci-Update-copyright-headers-to-reflect-recent-work.patch
-Patch0308: 0308-ehci-Properly-cleanup-packets-on-cancel.patch
-Patch0309: 0309-ehci-Properly-report-completed-but-not-yet-processed.patch
-Patch0310: 0310-ehci-check-for-EHCI_ASYNC_FINISHED-first-in-ehci_fre.patch
-Patch0311: 0311-ehci-trace-guest-bugs.patch
-Patch0312: 0312-ehci-add-doorbell-trace-events.patch
-Patch0313: 0313-ehci-Add-some-additional-ehci_trace_guest_bug-calls.patch
-Patch0314: 0314-ehci-Fix-memory-leak-in-handling-of-NAK-ed-packets.patch
-Patch0315: 0315-ehci-Handle-USB_RET_PROCERR-in-ehci_fill_queue.patch
-Patch0316: 0316-ehci-Correct-a-comment-in-fetchqtd-packet-processing.patch
-Patch0317: 0317-usb-redir-Never-return-USB_RET_NAK-for-async-handled.patch
-Patch0318: 0318-usb-redir-Don-t-delay-handling-of-open-events-to-a-b.patch
-Patch0319: 0319-usb-redir-Get-rid-of-async-struct-get-member.patch
-Patch0320: 0320-usb-redir-Get-rid-of-local-shadow-copy-of-packet-hea.patch
-Patch0321: 0321-usb-redir-Get-rid-of-unused-async-struct-dev-member.patch
-Patch0322: 0322-usb-redir-Move-to-core-packet-id-and-queue-handling.patch
-Patch0323: 0323-usb-redir-Return-babble-when-getting-more-bulk-data-.patch
-Patch0324: 0324-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch
-Patch0325: 0325-usb-redir-Set-ep-max_packet_size-if-available.patch
-Patch0326: 0326-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch
-Patch0327: 0327-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch
-Patch0328: 0328-usb-redir-Enable-pipelining-for-bulk-endpoints.patch
-Patch0329: 0329-Better-name-usb-braille-device.patch
-Patch0330: 0330-usb-audio-fix-usb-version.patch
-Patch0331: 0331-xhci-rip-out-background-transfer-code.patch
-Patch0332: 0332-xhci-drop-buffering.patch
-Patch0333: 0333-xhci-move-device-lookup-into-xhci_setup_packet.patch
-Patch0334: 0334-xhci-implement-mfindex.patch
-Patch0335: 0335-xhci-iso-xfer-support.patch
-Patch0336: 0336-xhci-trace-cc-codes-in-cleartext.patch
-Patch0337: 0337-xhci-add-trace_usb_xhci_ep_set_dequeue.patch
-Patch0338: 0338-xhci-fix-runtime-write-tracepoint.patch
-Patch0339: 0339-xhci-update-register-layout.patch
-Patch0340: 0340-xhci-update-port-handling.patch
-Patch0341: 0341-usb3-superspeed-descriptors.patch
-Patch0342: 0342-usb3-superspeed-endpoint-companion.patch
-Patch0343: 0343-usb3-bos-decriptor.patch
-Patch0344: 0344-usb-storage-usb3-support.patch
-Patch0345: 0345-xhci-fix-cleanup-msi.patch
-Patch0346: 0346-xhci-rework-interrupt-handling.patch
-Patch0347: 0347-xhci-add-msix-support.patch
-Patch0348: 0348-xhci-move-register-update-into-xhci_intr_raise.patch
-Patch0349: 0349-xhci-add-XHCIInterrupter.patch
-Patch0350: 0350-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch
-Patch0351: 0351-xhci-pick-target-interrupter.patch
-Patch0352: 0352-xhci-support-multiple-interrupters.patch
-Patch0353: 0353-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch
-Patch0354: 0354-xhci-allow-bytewise-capability-register-reads.patch
-Patch0355: 0355-usb-host-allow-emulated-non-async-control-requests-w.patch
-Patch0356: 0356-ehci-switch-to-new-style-memory-ops.patch
-Patch0357: 0357-ehci-Fix-interrupts-stopping-when-Interrupt-Threshol.patch
-Patch0358: 0358-ehci-Don-t-process-too-much-frames-in-1-timer-tick-v.patch
-Patch0359: 0359-configure-usbredir-fixes.patch
-Patch0360: 0360-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch
-Patch0361: 0361-ehci-Walk-async-schedule-before-and-after-migration.patch
-Patch0362: 0362-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
-Patch0363: 0363-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
-Patch0364: 0364-usb-redir-Store-max_packet_size-in-endp_data.patch
-Patch0365: 0365-usb-redir-Add-support-for-migration.patch
-Patch0366: 0366-usb-redir-Add-chardev-open-close-debug-logging.patch
-Patch0367: 0367-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch
-Patch0368: 0368-uhci-Don-t-queue-up-packets-after-one-with-the-SPD-f.patch
-# And the last few ehci fixes + the actual usb-redir live migration code
-# Not yet upstream but should get there real soon
-Patch0369: 0369-ehci-Fix-interrupt-packet-MULT-handling.patch
-Patch0370: 0370-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch
-Patch0371: 0371-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch
-Patch0372: 0372-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch
-
-# Revert c3767ed0eb5d0.
-# NOT upstream (hopefully will be soon).
-# See: https://bugzilla.redhat.com/show_bug.cgi?id=853408
-# and: https://lists.gnu.org/archive/html/qemu-devel/2012-09/msg00526.html
-# plus followups.
-Patch0900: 0001-Revert-qemu-char-Re-connect-for-tcp_chr_write-unconn.patch
+Patch0500: 0500-qxl-disallow-unknown-revisions.patch
+Patch0501: 0501-spice-make-number-of-surfaces-runtime-configurable.patch
+Patch0502: 0502-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch
+Patch0503: 0503-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch
+Patch0504: 0504-spice-switch-to-queue-for-vga-mode-updates.patch
+Patch0505: 0505-spice-split-qemu_spice_create_update.patch
+Patch0506: 0506-spice-add-screen-mirror.patch
+Patch0507: 0507-spice-send-updates-only-for-changed-screen-content.patch
+Patch0508: 0508-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch
+Patch0509: 0509-qxl-add-trace-event-for-QXL_IO_LOG.patch
+Patch0510: 0510-hw-qxl-support-client-monitor-configuration-via-devi.patch
+Patch0511: 0511-qxl-always-update-displaysurface-on-resize.patch
+Patch0512: 0512-qxl-update_area_io-cleanup-invalid-parameters-handli.patch
+Patch0513: 0513-qxl-fix-range-check-for-rev3-io-commands.patch
+
+# usb-redir live-migration and misc bits, will be in before 1.3.0
+Patch0600: 0600-usb-redir-Convert-to-new-libusbredirparser-0.5-API.patch
+Patch0601: 0601-usb-redir-Set-ep-max_packet_size-if-available.patch
+Patch0602: 0602-usb-redir-Add-a-usbredir_reject_device-helper-functi.patch
+Patch0603: 0603-usb-redir-Ensure-our-peer-has-the-necessary-caps-whe.patch
+Patch0604: 0604-usb-redir-Enable-pipelining-for-bulk-endpoints.patch
+Patch0605: 0605-xhci-move-device-lookup-into-xhci_setup_packet.patch
+Patch0606: 0606-xhci-implement-mfindex.patch
+Patch0607: 0607-xhci-iso-xfer-support.patch
+Patch0608: 0608-xhci-trace-cc-codes-in-cleartext.patch
+Patch0609: 0609-xhci-add-trace_usb_xhci_ep_set_dequeue.patch
+Patch0610: 0610-xhci-update-register-layout.patch
+Patch0611: 0611-xhci-update-port-handling.patch
+Patch0612: 0612-usb3-superspeed-descriptors.patch
+Patch0613: 0613-usb3-superspeed-endpoint-companion.patch
+Patch0614: 0614-usb3-bos-decriptor.patch
+Patch0615: 0615-usb-storage-usb3-support.patch
+Patch0616: 0616-xhci-fix-cleanup-msi.patch
+Patch0617: 0617-xhci-rework-interrupt-handling.patch
+Patch0618: 0618-xhci-add-msix-support.patch
+Patch0619: 0619-xhci-move-register-update-into-xhci_intr_raise.patch
+Patch0620: 0620-xhci-add-XHCIInterrupter.patch
+Patch0621: 0621-xhci-prepare-xhci_runtime_-read-write-for-multiple-i.patch
+Patch0622: 0622-xhci-pick-target-interrupter.patch
+Patch0623: 0623-xhci-support-multiple-interrupters.patch
+Patch0624: 0624-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch
+Patch0625: 0625-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
+Patch0626: 0626-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
+Patch0627: 0627-usb-redir-Store-max_packet_size-in-endp_data.patch
+Patch0628: 0628-usb-redir-Add-support-for-migration.patch
+Patch0629: 0629-usb-redir-Add-chardev-open-close-debug-logging.patch
+Patch0630: 0630-usb-redir-Revert-usb-redir-part-of-commit-93bfef4c.patch
+Patch0631: 0631-ehci-Fix-interrupt-packet-MULT-handling.patch
+Patch0632: 0632-usb-redir-Adjust-pkg-config-check-for-usbredirparser.patch
+Patch0633: 0633-usb-redir-Change-usbredir_open_chardev-into-usbredir.patch
+Patch0634: 0634-usb-redir-Don-t-make-migration-fail-in-none-seamless.patch
+
+# Non upstream build fix, http://www.spinics.net/lists/kvm/msg80589.html
+Patch0800: 0800-mips-Fix-link-error-with-piix4_pm_init.patch
+# Add ./configure --disable-kvm-options
+# keep: Carrying locally until qemu-kvm is fully merged into qemu.git
+Patch0801: 0801-configure-Add-disable-kvm-options.patch
+
 
 BuildRequires: SDL-devel
 BuildRequires: zlib-devel
@@ -705,125 +888,316 @@ such as kvm_stat.
 %prep
 %setup -q -n qemu-kvm-%{version}
 
-%patch1 -p1
-%patch2 -p1
-
-%patch101 -p1
-%patch102 -p1
-%patch103 -p1
-%patch104 -p1
-%patch105 -p1
-%patch106 -p1
-%patch107 -p1
-%patch108 -p1
-%patch109 -p1
-%patch110 -p1
-%patch111 -p1
-%patch112 -p1
-%patch113 -p1
-
-%patch201 -p1
-%patch202 -p1
-%patch203 -p1
-%patch204 -p1
-%patch205 -p1
-%patch206 -p1
-%patch207 -p1
-%patch208 -p1
-%patch209 -p1
-%patch210 -p1
-%patch211 -p1
-%patch212 -p1
-%patch213 -p1
-%patch214 -p1
-%patch215 -p1
-%patch216 -p1
-%patch217 -p1
-%patch218 -p1
-%patch219 -p1
-%patch220 -p1
-%patch221 -p1
-%patch222 -p1
-%patch223 -p1
-%patch224 -p1
-%patch225 -p1
-%patch226 -p1
-%patch227 -p1
-
-%patch301 -p1
-%patch302 -p1
-%patch303 -p1
-%patch304 -p1
-%patch305 -p1
-%patch306 -p1
-%patch307 -p1
-%patch308 -p1
-%patch309 -p1
-%patch310 -p1
-%patch311 -p1
-%patch312 -p1
-%patch313 -p1
-%patch314 -p1
-%patch315 -p1
-%patch316 -p1
-%patch317 -p1
-%patch318 -p1
-%patch319 -p1
-%patch320 -p1
-%patch321 -p1
-%patch322 -p1
-%patch323 -p1
-%patch324 -p1
-%patch325 -p1
-%patch326 -p1
-%patch327 -p1
-%patch328 -p1
-%patch329 -p1
-%patch330 -p1
-%patch331 -p1
-%patch332 -p1
-%patch333 -p1
-%patch334 -p1
-%patch335 -p1
-%patch336 -p1
-%patch337 -p1
-%patch338 -p1
-%patch339 -p1
-%patch340 -p1
-%patch341 -p1
-%patch342 -p1
-%patch343 -p1
-%patch344 -p1
-%patch345 -p1
-%patch346 -p1
-%patch347 -p1
-%patch348 -p1
-%patch349 -p1
-%patch350 -p1
-%patch351 -p1
-%patch352 -p1
-%patch353 -p1
-%patch354 -p1
-%patch355 -p1
-%patch356 -p1
-%patch357 -p1
-%patch358 -p1
-%patch359 -p1
-%patch360 -p1
-%patch361 -p1
-%patch362 -p1
-%patch363 -p1
-%patch364 -p1
-%patch365 -p1
-%patch366 -p1
-%patch367 -p1
-%patch368 -p1
-%patch369 -p1
-%patch370 -p1
-%patch371 -p1
-%patch372 -p1
-
-%patch900 -p1
+%patch0001 -p1
+%patch0002 -p1
+%patch0003 -p1
+%patch0004 -p1
+%patch0005 -p1
+%patch0006 -p1
+%patch0007 -p1
+%patch0008 -p1
+%patch0009 -p1
+%patch0010 -p1
+%patch0011 -p1
+%patch0012 -p1
+%patch0013 -p1
+%patch0014 -p1
+%patch0015 -p1
+%patch0016 -p1
+%patch0017 -p1
+%patch0018 -p1
+%patch0019 -p1
+%patch0020 -p1
+%patch0021 -p1
+%patch0022 -p1
+%patch0023 -p1
+%patch0024 -p1
+%patch0025 -p1
+%patch0026 -p1
+%patch0027 -p1
+%patch0028 -p1
+%patch0029 -p1
+%patch0030 -p1
+%patch0031 -p1
+%patch0032 -p1
+%patch0033 -p1
+%patch0034 -p1
+%patch0035 -p1
+%patch0036 -p1
+%patch0037 -p1
+%patch0038 -p1
+%patch0039 -p1
+%patch0040 -p1
+%patch0041 -p1
+%patch0042 -p1
+%patch0043 -p1
+%patch0044 -p1
+%patch0045 -p1
+%patch0046 -p1
+%patch0047 -p1
+%patch0048 -p1
+%patch0049 -p1
+%patch0050 -p1
+%patch0051 -p1
+%patch0052 -p1
+%patch0053 -p1
+%patch0054 -p1
+%patch0055 -p1
+%patch0056 -p1
+%patch0057 -p1
+%patch0058 -p1
+%patch0059 -p1
+%patch0060 -p1
+%patch0061 -p1
+%patch0062 -p1
+%patch0063 -p1
+%patch0064 -p1
+%patch0065 -p1
+%patch0066 -p1
+%patch0067 -p1
+%patch0068 -p1
+%patch0069 -p1
+%patch0070 -p1
+%patch0071 -p1
+%patch0072 -p1
+%patch0073 -p1
+%patch0074 -p1
+%patch0075 -p1
+%patch0076 -p1
+%patch0077 -p1
+%patch0078 -p1
+%patch0079 -p1
+%patch0080 -p1
+%patch0081 -p1
+%patch0082 -p1
+%patch0083 -p1
+%patch0084 -p1
+%patch0085 -p1
+%patch0086 -p1
+%patch0087 -p1
+%patch0088 -p1
+%patch0089 -p1
+%patch0090 -p1
+%patch0091 -p1
+%patch0092 -p1
+%patch0093 -p1
+%patch0094 -p1
+%patch0095 -p1
+%patch0096 -p1
+%patch0097 -p1
+%patch0098 -p1
+%patch0099 -p1
+%patch0100 -p1
+%patch0101 -p1
+%patch0102 -p1
+%patch0103 -p1
+%patch0104 -p1
+%patch0105 -p1
+%patch0106 -p1
+%patch0107 -p1
+%patch0108 -p1
+%patch0109 -p1
+%patch0110 -p1
+%patch0111 -p1
+%patch0112 -p1
+%patch0113 -p1
+%patch0114 -p1
+%patch0115 -p1
+%patch0116 -p1
+%patch0117 -p1
+%patch0118 -p1
+%patch0119 -p1
+%patch0120 -p1
+%patch0121 -p1
+%patch0122 -p1
+%patch0123 -p1
+%patch0124 -p1
+%patch0125 -p1
+%patch0126 -p1
+%patch0127 -p1
+%patch0128 -p1
+%patch0129 -p1
+%patch0130 -p1
+%patch0131 -p1
+%patch0132 -p1
+%patch0133 -p1
+%patch0134 -p1
+%patch0135 -p1
+%patch0136 -p1
+%patch0137 -p1
+%patch0138 -p1
+%patch0139 -p1
+%patch0140 -p1
+%patch0141 -p1
+%patch0142 -p1
+%patch0143 -p1
+%patch0144 -p1
+%patch0145 -p1
+%patch0146 -p1
+%patch0147 -p1
+%patch0148 -p1
+%patch0149 -p1
+%patch0150 -p1
+%patch0151 -p1
+%patch0152 -p1
+%patch0153 -p1
+%patch0154 -p1
+%patch0155 -p1
+%patch0156 -p1
+%patch0157 -p1
+%patch0158 -p1
+%patch0159 -p1
+%patch0160 -p1
+%patch0161 -p1
+%patch0162 -p1
+%patch0163 -p1
+%patch0164 -p1
+%patch0165 -p1
+%patch0166 -p1
+%patch0167 -p1
+%patch0168 -p1
+%patch0169 -p1
+%patch0170 -p1
+%patch0171 -p1
+%patch0172 -p1
+%patch0173 -p1
+%patch0174 -p1
+%patch0175 -p1
+%patch0176 -p1
+%patch0177 -p1
+%patch0178 -p1
+%patch0179 -p1
+%patch0180 -p1
+%patch0181 -p1
+%patch0182 -p1
+%patch0183 -p1
+%patch0184 -p1
+%patch0185 -p1
+%patch0186 -p1
+%patch0187 -p1
+%patch0188 -p1
+%patch0189 -p1
+%patch0190 -p1
+%patch0191 -p1
+%patch0192 -p1
+%patch0193 -p1
+%patch0194 -p1
+%patch0195 -p1
+%patch0196 -p1
+%patch0197 -p1
+%patch0198 -p1
+%patch0199 -p1
+%patch0200 -p1
+%patch0201 -p1
+%patch0202 -p1
+%patch0203 -p1
+%patch0204 -p1
+%patch0205 -p1
+%patch0206 -p1
+%patch0207 -p1
+%patch0208 -p1
+%patch0209 -p1
+%patch0210 -p1
+%patch0211 -p1
+%patch0212 -p1
+%patch0213 -p1
+%patch0214 -p1
+%patch0215 -p1
+%patch0216 -p1
+%patch0217 -p1
+%patch0218 -p1
+%patch0219 -p1
+%patch0220 -p1
+%patch0221 -p1
+%patch0222 -p1
+%patch0223 -p1
+%patch0224 -p1
+%patch0225 -p1
+%patch0226 -p1
+%patch0227 -p1
+%patch0228 -p1
+%patch0229 -p1
+%patch0230 -p1
+%patch0231 -p1
+%patch0232 -p1
+%patch0233 -p1
+%patch0234 -p1
+%patch0235 -p1
+%patch0236 -p1
+%patch0237 -p1
+%patch0238 -p1
+%patch0239 -p1
+%patch0240 -p1
+%patch0241 -p1
+%patch0242 -p1
+
+%patch0400 -p1
+%patch0401 -p1
+%patch0402 -p1
+%patch0403 -p1
+%patch0404 -p1
+%patch0405 -p1
+%patch0406 -p1
+%patch0407 -p1
+%patch0408 -p1
+%patch0409 -p1
+%patch0410 -p1
+%patch0411 -p1
+%patch0412 -p1
+
+%patch0500 -p1
+%patch0501 -p1
+%patch0502 -p1
+%patch0503 -p1
+%patch0504 -p1
+%patch0505 -p1
+%patch0506 -p1
+%patch0507 -p1
+%patch0508 -p1
+%patch0509 -p1
+%patch0510 -p1
+%patch0511 -p1
+%patch0512 -p1
+%patch0513 -p1
+
+%patch0600 -p1
+%patch0601 -p1
+%patch0602 -p1
+%patch0603 -p1
+%patch0604 -p1
+%patch0605 -p1
+%patch0606 -p1
+%patch0607 -p1
+%patch0608 -p1
+%patch0609 -p1
+%patch0610 -p1
+%patch0611 -p1
+%patch0612 -p1
+%patch0613 -p1
+%patch0614 -p1
+%patch0615 -p1
+%patch0616 -p1
+%patch0617 -p1
+%patch0618 -p1
+%patch0619 -p1
+%patch0620 -p1
+%patch0621 -p1
+%patch0622 -p1
+%patch0623 -p1
+%patch0624 -p1
+%patch0625 -p1
+%patch0626 -p1
+%patch0627 -p1
+%patch0628 -p1
+%patch0629 -p1
+%patch0630 -p1
+%patch0631 -p1
+%patch0632 -p1
+%patch0633 -p1
+%patch0634 -p1
+
+%patch0800 -p1
+%patch0801 -p1
 
 
 %build
@@ -1416,6 +1790,9 @@ fi
 %{_mandir}/man1/qemu-img.1*
 
 %changelog
+* Sun Oct 28 2012 Cole Robinson <crobinso at redhat.com> - 2:1.2.0-17
+- Pull patches queued for qemu 1.2.1
+
 * Fri Oct 19 2012 Paolo Bonzini <pbonzini at redhat.com> - 2:1.2.0-16
 - add s390x KVM support
 - distribute pre-built firmware or device trees for Alpha, Microblaze, S390


More information about the scm-commits mailing list