All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg
@ 2017-01-21  8:45 Alessandro Di Federico
  2017-01-21  8:45 ` [Qemu-devel] [RFC PATCH 1/3] Factor out {linux,bsd}-user/qemu.h Alessandro Di Federico
                   ` (4 more replies)
  0 siblings, 5 replies; 15+ messages in thread
From: Alessandro Di Federico @ 2017-01-21  8:45 UTC (permalink / raw)
  To: qemu-devel

This series of patches introduce a set of changes, mainly to the QEMU
build system, to open the way to implementing "libtcg", i.e., using
QEMU's tiny code generator frontends as a library.

For the initial proposal, please see the related discussion:

http://lists.nongnu.org/archive/html/qemu-devel/2016-11/msg04847.html

The idea is to build a PIC version of QEMU embedding only what's
required to use the TCG frontend (typically
target/$arch/translate.c). To achieve this, some functions have been
moved out of translate.c to reduce the coupling with the other object
files.

All the configurations available on Linux and FreeBSD still build fine
(without warnings).

The last commit also introduces the libtcg/ directory and a series of
*-libtcg targets (similar to the *-{bsd,linux}-user) with the bare
minimum skeleton for the actual implementation and some dummy references
to some functions that in my previous implementation of libtcg were
required, to make sure that all the required object files are linked in.

I've verified that all the libtcg-$arch.so libraries have no pending
symbols.

This is the complete list of new targets available:

aarch64-libtcg alpha-libtcg arm-libtcg armeb-libtcg cris-libtcg i386-libtcg m68k-libtcg microblaze-libtcg microblazeel-libtcg mips-libtcg mips64-libtcg mips64el-libtcg mipsel-libtcg mipsn32-libtcg mipsn32el-libtcg or32-libtcg ppc-libtcg ppc64-libtcg ppc64abi32-libtcg ppc64le-libtcg s390x-libtcg sh4-libtcg sh4eb-libtcg sparc-libtcg sparc32plus-libtcg sparc64-libtcg unicore32-libtcg x86_64-libtcg

Bonus: to reduce the coupling among object files I've create a quick &
dirty Python script to create a Graphviz graph of the various
dependencies among the object files. Simply feed it with a set of object
files, change the name of the "entry" object file (currently anything
containing "libtcg") and it will print the .dot file:

    python graph.py *.o > graph.dot
    dot -Tsvg graph.dot > graph.svg

You can find the script here:

https://clearmind.me/downloads/graph.py

Comments are very welcome.

Alessandro Di Federico (3):
  Factor out {linux,bsd}-user/qemu.h
  *-user targets object files decoupling
  Introduce libtcg infrastructure

 Makefile                                |   7 ++
 Makefile.target                         |  40 ++++++-
 bsd-user/qemu.h                         | 193 +-------------------------------
 configure                               |  20 ++++
 crypto/Makefile.objs                    |   2 +-
 default-configs/aarch64-libtcg.mak      |   0
 default-configs/alpha-libtcg.mak        |   0
 default-configs/arm-libtcg.mak          |   0
 default-configs/armeb-libtcg.mak        |   0
 default-configs/cris-libtcg.mak         |   0
 default-configs/i386-libtcg.mak         |   0
 default-configs/m68k-libtcg.mak         |   0
 default-configs/microblaze-libtcg.mak   |   0
 default-configs/microblazeel-libtcg.mak |   0
 default-configs/mips-libtcg.mak         |   0
 default-configs/mips64-libtcg.mak       |   0
 default-configs/mips64el-libtcg.mak     |   0
 default-configs/mipsel-libtcg.mak       |   0
 default-configs/mipsn32-libtcg.mak      |   0
 default-configs/mipsn32el-libtcg.mak    |   0
 default-configs/or32-libtcg.mak         |   0
 default-configs/ppc-libtcg.mak          |   1 +
 default-configs/ppc64-libtcg.mak        |   1 +
 default-configs/ppc64abi32-libtcg.mak   |   1 +
 default-configs/ppc64le-libtcg.mak      |   1 +
 default-configs/s390x-libtcg.mak        |   0
 default-configs/sh4-libtcg.mak          |   0
 default-configs/sh4eb-libtcg.mak        |   0
 default-configs/sparc-libtcg.mak        |   0
 default-configs/sparc32plus-libtcg.mak  |   0
 default-configs/sparc64-libtcg.mak      |   0
 default-configs/unicore32-libtcg.mak    |   0
 default-configs/x86_64-libtcg.mak       |   0
 exec.c                                  |   2 +
 hw/core/Makefile.objs                   |   5 +-
 include/exec/helper-gen.h               |  12 +-
 include/exec/helper-head.h              |   8 ++
 include/exec/helper-tcg.h               |  12 +-
 libtcg/Makefile.objs                    |   1 +
 libtcg/qemu.h                           |   6 +
 libtcg/tcg.c                            |  55 +++++++++
 libtcg/tcg.h                            |   0
 linux-user/qemu.h                       | 176 +----------------------------
 qemu-user-common.h                      | 180 +++++++++++++++++++++++++++++
 target/alpha/Makefile.objs              |   9 +-
 target/arm/Makefile.objs                |  22 +++-
 target/arm/cpu.c                        | 118 +++++++++++++++++++
 target/arm/cpu.h                        |  82 ++++++++++----
 target/arm/helper.c                     |  73 +-----------
 target/arm/translate-a64.c              |  54 ---------
 target/arm/translate.c                  |  97 ++++++----------
 target/arm/translate.h                  |   7 --
 target/cris/Makefile.objs               |  10 +-
 target/i386/Makefile.objs               |  14 ++-
 target/lm32/Makefile.objs               |  12 +-
 target/m68k/Makefile.objs               |   7 +-
 target/m68k/op_helper.c                 |  23 ++++
 target/m68k/translate.c                 |  23 ----
 target/microblaze/Makefile.objs         |  10 +-
 target/mips/Makefile.objs               |  11 +-
 target/mips/op_helper.c                 |   8 --
 target/mips/translate.c                 |   8 ++
 target/moxie/Makefile.objs              |   8 +-
 target/openrisc/Makefile.objs           |  11 +-
 target/ppc/Makefile.objs                |  18 +--
 target/ppc/gdbstub.c                    |  20 ----
 target/ppc/translate.c                  |   2 +
 target/ppc/translate_init.c             |  28 +++++
 target/s390x/Makefile.objs              |  16 ++-
 target/sh4/Makefile.objs                |   8 +-
 target/sparc/Makefile.objs              |  15 ++-
 target/tilegx/Makefile.objs             |   7 +-
 target/tricore/Makefile.objs            |   7 +-
 target/unicore32/Makefile.objs          |   8 +-
 target/unicore32/helper.c               |  68 +++++++++++
 target/unicore32/translate.c            |  68 -----------
 target/xtensa/Makefile.objs             |  14 ++-
 trace/Makefile.objs                     |   2 +-
 translate-all.c                         |   4 +-
 79 files changed, 837 insertions(+), 778 deletions(-)
 create mode 100644 default-configs/aarch64-libtcg.mak
 create mode 100644 default-configs/alpha-libtcg.mak
 create mode 100644 default-configs/arm-libtcg.mak
 create mode 100644 default-configs/armeb-libtcg.mak
 create mode 100644 default-configs/cris-libtcg.mak
 create mode 100644 default-configs/i386-libtcg.mak
 create mode 100644 default-configs/m68k-libtcg.mak
 create mode 100644 default-configs/microblaze-libtcg.mak
 create mode 100644 default-configs/microblazeel-libtcg.mak
 create mode 100644 default-configs/mips-libtcg.mak
 create mode 100644 default-configs/mips64-libtcg.mak
 create mode 100644 default-configs/mips64el-libtcg.mak
 create mode 100644 default-configs/mipsel-libtcg.mak
 create mode 100644 default-configs/mipsn32-libtcg.mak
 create mode 100644 default-configs/mipsn32el-libtcg.mak
 create mode 100644 default-configs/or32-libtcg.mak
 create mode 100644 default-configs/ppc-libtcg.mak
 create mode 100644 default-configs/ppc64-libtcg.mak
 create mode 100644 default-configs/ppc64abi32-libtcg.mak
 create mode 100644 default-configs/ppc64le-libtcg.mak
 create mode 100644 default-configs/s390x-libtcg.mak
 create mode 100644 default-configs/sh4-libtcg.mak
 create mode 100644 default-configs/sh4eb-libtcg.mak
 create mode 100644 default-configs/sparc-libtcg.mak
 create mode 100644 default-configs/sparc32plus-libtcg.mak
 create mode 100644 default-configs/sparc64-libtcg.mak
 create mode 100644 default-configs/unicore32-libtcg.mak
 create mode 100644 default-configs/x86_64-libtcg.mak
 create mode 100644 libtcg/Makefile.objs
 create mode 100644 libtcg/qemu.h
 create mode 100644 libtcg/tcg.c
 create mode 100644 libtcg/tcg.h
 create mode 100644 qemu-user-common.h

-- 
2.11.0

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

* [Qemu-devel] [RFC PATCH 1/3] Factor out {linux,bsd}-user/qemu.h
  2017-01-21  8:45 [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg Alessandro Di Federico
@ 2017-01-21  8:45 ` Alessandro Di Federico
  2017-01-24 10:10   ` [Qemu-devel] [RFC PATCH 1/3] Factor out {linux, bsd}-user/qemu.h Marc-André Lureau
  2017-01-24 11:18   ` Peter Maydell
  2017-01-21  8:45 ` [Qemu-devel] [RFC PATCH 2/3] *-user targets object files decoupling Alessandro Di Federico
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 15+ messages in thread
From: Alessandro Di Federico @ 2017-01-21  8:45 UTC (permalink / raw)
  To: qemu-devel

A quite large part of {linux,bsd}-user/qemu.h is shared, this patch
introduces qemu-user-common.h which factors it out. This shared part is
also the bare minimum required to build a linux-user-like target, and,
in particular, it will be useful for the libtcg targets.
---
 bsd-user/qemu.h    | 193 +----------------------------------------------------
 linux-user/qemu.h  | 176 +-----------------------------------------------
 qemu-user-common.h | 180 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 182 insertions(+), 367 deletions(-)
 create mode 100644 qemu-user-common.h

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 2b2b9184e0..b51319caf0 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -17,10 +17,8 @@
 #ifndef QEMU_H
 #define QEMU_H
 
-
-#include "cpu.h"
+#include "qemu-user-common.h"
 #include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
 
 #undef DEBUG_REMAP
 #ifdef DEBUG_REMAP
@@ -217,195 +215,6 @@ void mmap_fork_end(int child);
 /* main.c */
 extern unsigned long x86_stack_size;
 
-/* user access */
-
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1 /* implies read access */
-
-static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
-{
-    return page_check_range((target_ulong)addr, size,
-                            (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
-}
-
-/* NOTE __get_user and __put_user use host pointers and don't check access. */
-/* These are usually used to access struct data members once the
- * struct has been locked - usually with lock_user_struct().
- */
-#define __put_user(x, hptr)\
-({\
-    int size = sizeof(*hptr);\
-    switch(size) {\
-    case 1:\
-        *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
-        break;\
-    case 2:\
-        *(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\
-        break;\
-    case 4:\
-        *(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\
-        break;\
-    case 8:\
-        *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
-        break;\
-    default:\
-        abort();\
-    }\
-    0;\
-})
-
-#define __get_user(x, hptr) \
-({\
-    int size = sizeof(*hptr);\
-    switch(size) {\
-    case 1:\
-        x = (typeof(*hptr))*(uint8_t *)(hptr);\
-        break;\
-    case 2:\
-        x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\
-        break;\
-    case 4:\
-        x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
-        break;\
-    case 8:\
-        x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
-        break;\
-    default:\
-        /* avoid warning */\
-        x = 0;\
-        abort();\
-    }\
-    0;\
-})
-
-/* put_user()/get_user() take a guest address and check access */
-/* These are usually used to access an atomic data type, such as an int,
- * that has been passed by address.  These internally perform locking
- * and unlocking on the data type.
- */
-#define put_user(x, gaddr, target_type)                                 \
-({                                                                      \
-    abi_ulong __gaddr = (gaddr);                                        \
-    target_type *__hptr;                                                \
-    abi_long __ret;                                                     \
-    if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \
-        __ret = __put_user((x), __hptr);                                \
-        unlock_user(__hptr, __gaddr, sizeof(target_type));              \
-    } else                                                              \
-        __ret = -TARGET_EFAULT;                                         \
-    __ret;                                                              \
-})
-
-#define get_user(x, gaddr, target_type)                                 \
-({                                                                      \
-    abi_ulong __gaddr = (gaddr);                                        \
-    target_type *__hptr;                                                \
-    abi_long __ret;                                                     \
-    if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \
-        __ret = __get_user((x), __hptr);                                \
-        unlock_user(__hptr, __gaddr, 0);                                \
-    } else {                                                            \
-        /* avoid warning */                                             \
-        (x) = 0;                                                        \
-        __ret = -TARGET_EFAULT;                                         \
-    }                                                                   \
-    __ret;                                                              \
-})
-
-#define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
-#define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
-#define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
-#define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
-#define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
-#define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
-#define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
-#define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
-#define put_user_u8(x, gaddr)  put_user((x), (gaddr), uint8_t)
-#define put_user_s8(x, gaddr)  put_user((x), (gaddr), int8_t)
-
-#define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
-#define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
-#define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
-#define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
-#define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
-#define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
-#define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
-#define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
-#define get_user_u8(x, gaddr)  get_user((x), (gaddr), uint8_t)
-#define get_user_s8(x, gaddr)  get_user((x), (gaddr), int8_t)
-
-/* copy_from_user() and copy_to_user() are usually used to copy data
- * buffers between the target and host.  These internally perform
- * locking/unlocking of the memory.
- */
-abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
-abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
-
-/* Functions for accessing guest memory.  The tget and tput functions
-   read/write single values, byteswapping as necessary.  The lock_user function
-   gets a pointer to a contiguous area of guest memory, but does not perform
-   any byteswapping.  lock_user may return either a pointer to the guest
-   memory, or a temporary buffer.  */
-
-/* Lock an area of guest memory into the host.  If copy is true then the
-   host area will have the same contents as the guest.  */
-static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
-{
-    if (!access_ok(type, guest_addr, len))
-        return NULL;
-#ifdef DEBUG_REMAP
-    {
-        void *addr;
-        addr = g_malloc(len);
-        if (copy)
-            memcpy(addr, g2h(guest_addr), len);
-        else
-            memset(addr, 0, len);
-        return addr;
-    }
-#else
-    return g2h(guest_addr);
-#endif
-}
-
-/* Unlock an area of guest memory.  The first LEN bytes must be
-   flushed back to guest memory. host_ptr = NULL is explicitly
-   allowed and does nothing. */
-static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
-                               long len)
-{
-
-#ifdef DEBUG_REMAP
-    if (!host_ptr)
-        return;
-    if (host_ptr == g2h(guest_addr))
-        return;
-    if (len > 0)
-        memcpy(g2h(guest_addr), host_ptr, len);
-    g_free(host_ptr);
-#endif
-}
-
-/* Return the length of a string in target memory or -TARGET_EFAULT if
-   access error. */
-abi_long target_strlen(abi_ulong gaddr);
-
-/* Like lock_user but for null terminated strings.  */
-static inline void *lock_user_string(abi_ulong guest_addr)
-{
-    abi_long len;
-    len = target_strlen(guest_addr);
-    if (len < 0)
-        return NULL;
-    return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
-}
-
-/* Helper macros for locking/unlocking a target struct.  */
-#define lock_user_struct(type, host_ptr, guest_addr, copy)      \
-    (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
-#define unlock_user_struct(host_ptr, guest_addr, copy)          \
-    unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
-
 #if defined(CONFIG_USE_NPTL)
 #include <pthread.h>
 #endif
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index da73a01106..b56abb5942 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -2,9 +2,8 @@
 #define QEMU_H
 
 #include "hostdep.h"
-#include "cpu.h"
+#include "qemu-user-common.h"
 #include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
 
 #undef DEBUG_REMAP
 #ifdef DEBUG_REMAP
@@ -436,179 +435,6 @@ void mmap_fork_end(int child);
 /* main.c */
 extern unsigned long guest_stack_size;
 
-/* user access */
-
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1 /* implies read access */
-
-static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
-{
-    return page_check_range((target_ulong)addr, size,
-                            (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
-}
-
-/* NOTE __get_user and __put_user use host pointers and don't check access.
-   These are usually used to access struct data members once the struct has
-   been locked - usually with lock_user_struct.  */
-
-/* Tricky points:
-   - Use __builtin_choose_expr to avoid type promotion from ?:,
-   - Invalid sizes result in a compile time error stemming from
-     the fact that abort has no parameters.
-   - It's easier to use the endian-specific unaligned load/store
-     functions than host-endian unaligned load/store plus tswapN.  */
-
-#define __put_user_e(x, hptr, e)                                        \
-  (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p,                   \
-   __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p,             \
-   __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p,             \
-   __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort))))   \
-     ((hptr), (x)), (void)0)
-
-#define __get_user_e(x, hptr, e)                                        \
-  ((x) = (typeof(*hptr))(                                               \
-   __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p,                  \
-   __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p,            \
-   __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p,             \
-   __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort))))   \
-     (hptr)), (void)0)
-
-#ifdef TARGET_WORDS_BIGENDIAN
-# define __put_user(x, hptr)  __put_user_e(x, hptr, be)
-# define __get_user(x, hptr)  __get_user_e(x, hptr, be)
-#else
-# define __put_user(x, hptr)  __put_user_e(x, hptr, le)
-# define __get_user(x, hptr)  __get_user_e(x, hptr, le)
-#endif
-
-/* put_user()/get_user() take a guest address and check access */
-/* These are usually used to access an atomic data type, such as an int,
- * that has been passed by address.  These internally perform locking
- * and unlocking on the data type.
- */
-#define put_user(x, gaddr, target_type)					\
-({									\
-    abi_ulong __gaddr = (gaddr);					\
-    target_type *__hptr;						\
-    abi_long __ret = 0;							\
-    if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \
-        __put_user((x), __hptr);				\
-        unlock_user(__hptr, __gaddr, sizeof(target_type));		\
-    } else								\
-        __ret = -TARGET_EFAULT;						\
-    __ret;								\
-})
-
-#define get_user(x, gaddr, target_type)					\
-({									\
-    abi_ulong __gaddr = (gaddr);					\
-    target_type *__hptr;						\
-    abi_long __ret = 0;							\
-    if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \
-        __get_user((x), __hptr);				\
-        unlock_user(__hptr, __gaddr, 0);				\
-    } else {								\
-        /* avoid warning */						\
-        (x) = 0;							\
-        __ret = -TARGET_EFAULT;						\
-    }									\
-    __ret;								\
-})
-
-#define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
-#define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
-#define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
-#define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
-#define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
-#define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
-#define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
-#define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
-#define put_user_u8(x, gaddr)  put_user((x), (gaddr), uint8_t)
-#define put_user_s8(x, gaddr)  put_user((x), (gaddr), int8_t)
-
-#define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
-#define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
-#define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
-#define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
-#define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
-#define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
-#define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
-#define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
-#define get_user_u8(x, gaddr)  get_user((x), (gaddr), uint8_t)
-#define get_user_s8(x, gaddr)  get_user((x), (gaddr), int8_t)
-
-/* copy_from_user() and copy_to_user() are usually used to copy data
- * buffers between the target and host.  These internally perform
- * locking/unlocking of the memory.
- */
-abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
-abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
-
-/* Functions for accessing guest memory.  The tget and tput functions
-   read/write single values, byteswapping as necessary.  The lock_user function
-   gets a pointer to a contiguous area of guest memory, but does not perform
-   any byteswapping.  lock_user may return either a pointer to the guest
-   memory, or a temporary buffer.  */
-
-/* Lock an area of guest memory into the host.  If copy is true then the
-   host area will have the same contents as the guest.  */
-static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
-{
-    if (!access_ok(type, guest_addr, len))
-        return NULL;
-#ifdef DEBUG_REMAP
-    {
-        void *addr;
-        addr = g_malloc(len);
-        if (copy)
-            memcpy(addr, g2h(guest_addr), len);
-        else
-            memset(addr, 0, len);
-        return addr;
-    }
-#else
-    return g2h(guest_addr);
-#endif
-}
-
-/* Unlock an area of guest memory.  The first LEN bytes must be
-   flushed back to guest memory. host_ptr = NULL is explicitly
-   allowed and does nothing. */
-static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
-                               long len)
-{
-
-#ifdef DEBUG_REMAP
-    if (!host_ptr)
-        return;
-    if (host_ptr == g2h(guest_addr))
-        return;
-    if (len > 0)
-        memcpy(g2h(guest_addr), host_ptr, len);
-    g_free(host_ptr);
-#endif
-}
-
-/* Return the length of a string in target memory or -TARGET_EFAULT if
-   access error. */
-abi_long target_strlen(abi_ulong gaddr);
-
-/* Like lock_user but for null terminated strings.  */
-static inline void *lock_user_string(abi_ulong guest_addr)
-{
-    abi_long len;
-    len = target_strlen(guest_addr);
-    if (len < 0)
-        return NULL;
-    return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
-}
-
-/* Helper macros for locking/unlocking a target struct.  */
-#define lock_user_struct(type, host_ptr, guest_addr, copy)	\
-    (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
-#define unlock_user_struct(host_ptr, guest_addr, copy)		\
-    unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
-
 #include <pthread.h>
 
 /* Include target-specific struct and function definitions;
diff --git a/qemu-user-common.h b/qemu-user-common.h
new file mode 100644
index 0000000000..349dd72fff
--- /dev/null
+++ b/qemu-user-common.h
@@ -0,0 +1,180 @@
+#ifndef QEMU_USER_COMMON_H
+#define QEMU_USER_COMMON_H
+
+#include "cpu.h"
+#include "exec/cpu_ldst.h"
+
+/* user access */
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1 /* implies read access */
+
+static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
+{
+    return page_check_range((target_ulong)addr, size,
+                            (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;
+}
+
+/* NOTE __get_user and __put_user use host pointers and don't check access.
+   These are usually used to access struct data members once the struct has
+   been locked - usually with lock_user_struct.  */
+
+/* Tricky points:
+   - Use __builtin_choose_expr to avoid type promotion from ?:,
+   - Invalid sizes result in a compile time error stemming from
+     the fact that abort has no parameters.
+   - It's easier to use the endian-specific unaligned load/store
+     functions than host-endian unaligned load/store plus tswapN.  */
+
+#define __put_user_e(x, hptr, e)                                        \
+  (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p,                   \
+   __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p,             \
+   __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p,             \
+   __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort))))   \
+     ((hptr), (x)), (void)0)
+
+#define __get_user_e(x, hptr, e)                                        \
+  ((x) = (typeof(*hptr))(                                               \
+   __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p,                  \
+   __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p,            \
+   __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p,             \
+   __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort))))   \
+     (hptr)), (void)0)
+
+#ifdef TARGET_WORDS_BIGENDIAN
+# define __put_user(x, hptr)  __put_user_e(x, hptr, be)
+# define __get_user(x, hptr)  __get_user_e(x, hptr, be)
+#else
+# define __put_user(x, hptr)  __put_user_e(x, hptr, le)
+# define __get_user(x, hptr)  __get_user_e(x, hptr, le)
+#endif
+
+/* put_user()/get_user() take a guest address and check access */
+/* These are usually used to access an atomic data type, such as an int,
+ * that has been passed by address.  These internally perform locking
+ * and unlocking on the data type.
+ */
+#define put_user(x, gaddr, target_type)					\
+({									\
+    abi_ulong __gaddr = (gaddr);					\
+    target_type *__hptr;						\
+    abi_long __ret = 0;							\
+    if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \
+        __put_user((x), __hptr);				\
+        unlock_user(__hptr, __gaddr, sizeof(target_type));		\
+    } else								\
+        __ret = -TARGET_EFAULT;						\
+    __ret;								\
+})
+
+#define get_user(x, gaddr, target_type)					\
+({									\
+    abi_ulong __gaddr = (gaddr);					\
+    target_type *__hptr;						\
+    abi_long __ret = 0;							\
+    if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \
+        __get_user((x), __hptr);				\
+        unlock_user(__hptr, __gaddr, 0);				\
+    } else {								\
+        /* avoid warning */						\
+        (x) = 0;							\
+        __ret = -TARGET_EFAULT;						\
+    }									\
+    __ret;								\
+})
+
+#define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
+#define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
+#define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
+#define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
+#define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
+#define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
+#define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
+#define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
+#define put_user_u8(x, gaddr)  put_user((x), (gaddr), uint8_t)
+#define put_user_s8(x, gaddr)  put_user((x), (gaddr), int8_t)
+
+#define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
+#define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
+#define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
+#define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
+#define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
+#define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
+#define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
+#define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
+#define get_user_u8(x, gaddr)  get_user((x), (gaddr), uint8_t)
+#define get_user_s8(x, gaddr)  get_user((x), (gaddr), int8_t)
+
+/* copy_from_user() and copy_to_user() are usually used to copy data
+ * buffers between the target and host.  These internally perform
+ * locking/unlocking of the memory.
+ */
+abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
+abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
+
+/* Functions for accessing guest memory.  The tget and tput functions
+   read/write single values, byteswapping as necessary.  The lock_user function
+   gets a pointer to a contiguous area of guest memory, but does not perform
+   any byteswapping.  lock_user may return either a pointer to the guest
+   memory, or a temporary buffer.  */
+
+/* Lock an area of guest memory into the host.  If copy is true then the
+   host area will have the same contents as the guest.  */
+static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)
+{
+    if (!access_ok(type, guest_addr, len))
+        return NULL;
+#ifdef DEBUG_REMAP
+    {
+        void *addr;
+        addr = g_malloc(len);
+        if (copy)
+            memcpy(addr, g2h(guest_addr), len);
+        else
+            memset(addr, 0, len);
+        return addr;
+    }
+#else
+    return g2h(guest_addr);
+#endif
+}
+
+/* Unlock an area of guest memory.  The first LEN bytes must be
+   flushed back to guest memory. host_ptr = NULL is explicitly
+   allowed and does nothing. */
+static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
+                               long len)
+{
+
+#ifdef DEBUG_REMAP
+    if (!host_ptr)
+        return;
+    if (host_ptr == g2h(guest_addr))
+        return;
+    if (len > 0)
+        memcpy(g2h(guest_addr), host_ptr, len);
+    g_free(host_ptr);
+#endif
+}
+
+/* Return the length of a string in target memory or -TARGET_EFAULT if
+   access error. */
+abi_long target_strlen(abi_ulong gaddr);
+
+/* Like lock_user but for null terminated strings.  */
+static inline void *lock_user_string(abi_ulong guest_addr)
+{
+    abi_long len;
+    len = target_strlen(guest_addr);
+    if (len < 0)
+        return NULL;
+    return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
+}
+
+/* Helper macros for locking/unlocking a target struct.  */
+#define lock_user_struct(type, host_ptr, guest_addr, copy)	\
+    (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
+#define unlock_user_struct(host_ptr, guest_addr, copy)		\
+    unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
+
+#endif /* QEMU_USER_COMMON_H */
-- 
2.11.0

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

* [Qemu-devel] [RFC PATCH 2/3] *-user targets object files decoupling
  2017-01-21  8:45 [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg Alessandro Di Federico
  2017-01-21  8:45 ` [Qemu-devel] [RFC PATCH 1/3] Factor out {linux,bsd}-user/qemu.h Alessandro Di Federico
@ 2017-01-21  8:45 ` Alessandro Di Federico
  2017-01-24 10:09   ` Marc-André Lureau
  2017-01-21  8:46 ` [Qemu-devel] [RFC PATCH 3/3] Introduce libtcg infrastructure Alessandro Di Federico
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 15+ messages in thread
From: Alessandro Di Federico @ 2017-01-21  8:45 UTC (permalink / raw)
  To: qemu-devel

Move some functions around in target/$arch/*.c to reduce the coupling
among the various compilation unit. In particular, we want to make the
various translate.c as much standalone as possible, so that they will be
easily employed by libtcg.
---
 exec.c                       |   2 +
 target/arm/cpu.c             | 118 +++++++++++++++++++++++++++++++++++++++++++
 target/arm/cpu.h             |  82 ++++++++++++++++++++++--------
 target/arm/helper.c          |  73 +-------------------------
 target/arm/translate-a64.c   |  54 --------------------
 target/arm/translate.c       |  97 ++++++++++++-----------------------
 target/arm/translate.h       |   7 ---
 target/m68k/op_helper.c      |  23 +++++++++
 target/m68k/translate.c      |  23 ---------
 target/mips/op_helper.c      |   8 ---
 target/mips/translate.c      |   8 +++
 target/ppc/gdbstub.c         |  20 --------
 target/ppc/translate_init.c  |  20 ++++++++
 target/unicore32/helper.c    |  68 +++++++++++++++++++++++++
 target/unicore32/translate.c |  68 -------------------------
 15 files changed, 333 insertions(+), 338 deletions(-)

diff --git a/exec.c b/exec.c
index 47835c1dc1..66f8187281 100644
--- a/exec.c
+++ b/exec.c
@@ -672,9 +672,11 @@ void cpu_exec_unrealizefn(CPUState *cpu)
     if (cc->vmsd != NULL) {
         vmstate_unregister(NULL, cc->vmsd, cpu);
     }
+#ifndef CONFIG_USER_ONLY
     if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
         vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
     }
+#endif
 }
 
 void cpu_exec_initfn(CPUState *cpu)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index f5cb30af6c..f0af5d5d7d 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -238,6 +238,124 @@ static void arm_cpu_reset(CPUState *s)
     hw_watchpoint_update_all(cpu);
 }
 
+static void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
+                                   fprintf_function cpu_fprintf, int flags)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    uint32_t psr = pstate_read(env);
+    int i;
+    int el = arm_current_el(env);
+    const char *ns_status;
+
+    cpu_fprintf(f, "PC=%016"PRIx64"  SP=%016"PRIx64"\n",
+            env->pc, env->xregs[31]);
+    for (i = 0; i < 31; i++) {
+        cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
+        if ((i % 4) == 3) {
+            cpu_fprintf(f, "\n");
+        } else {
+            cpu_fprintf(f, " ");
+        }
+    }
+
+    if (arm_feature(env, ARM_FEATURE_EL3) && el != 3) {
+        ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
+    } else {
+        ns_status = "";
+    }
+
+    cpu_fprintf(f, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n",
+                psr,
+                psr & PSTATE_N ? 'N' : '-',
+                psr & PSTATE_Z ? 'Z' : '-',
+                psr & PSTATE_C ? 'C' : '-',
+                psr & PSTATE_V ? 'V' : '-',
+                ns_status,
+                el,
+                psr & PSTATE_SP ? 'h' : 't');
+
+    if (flags & CPU_DUMP_FPU) {
+        int numvfpregs = 32;
+        for (i = 0; i < numvfpregs; i += 2) {
+            uint64_t vlo = float64_val(env->vfp.regs[i * 2]);
+            uint64_t vhi = float64_val(env->vfp.regs[(i * 2) + 1]);
+            cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
+                        i, vhi, vlo);
+            vlo = float64_val(env->vfp.regs[(i + 1) * 2]);
+            vhi = float64_val(env->vfp.regs[((i + 1) * 2) + 1]);
+            cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
+                        i + 1, vhi, vlo);
+        }
+        cpu_fprintf(f, "FPCR: %08x  FPSR: %08x\n",
+                    vfp_get_fpcr(env), vfp_get_fpsr(env));
+    }
+}
+
+static const char *cpu_mode_names[16] = {
+  "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
+  "???", "???", "hyp", "und", "???", "???", "???", "sys"
+};
+
+void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                        int flags)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    int i;
+    uint32_t psr;
+    const char *ns_status;
+
+    if (is_a64(env)) {
+        aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
+        return;
+    }
+
+    for(i=0;i<16;i++) {
+        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
+        if ((i % 4) == 3)
+            cpu_fprintf(f, "\n");
+        else
+            cpu_fprintf(f, " ");
+    }
+    psr = cpsr_read(env);
+
+    if (arm_feature(env, ARM_FEATURE_EL3) &&
+        (psr & CPSR_M) != ARM_CPU_MODE_MON) {
+        ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
+    } else {
+        ns_status = "";
+    }
+
+    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
+                psr,
+                psr & (1 << 31) ? 'N' : '-',
+                psr & (1 << 30) ? 'Z' : '-',
+                psr & (1 << 29) ? 'C' : '-',
+                psr & (1 << 28) ? 'V' : '-',
+                psr & CPSR_T ? 'T' : 'A',
+                ns_status,
+                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
+
+    if (flags & CPU_DUMP_FPU) {
+        int numvfpregs = 0;
+        if (arm_feature(env, ARM_FEATURE_VFP)) {
+            numvfpregs += 16;
+        }
+        if (arm_feature(env, ARM_FEATURE_VFP3)) {
+            numvfpregs += 16;
+        }
+        for (i = 0; i < numvfpregs; i++) {
+            uint64_t v = float64_val(env->vfp.regs[i]);
+            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
+                        i * 2, (uint32_t)v,
+                        i * 2 + 1, (uint32_t)(v >> 32),
+                        i, v);
+        }
+        cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
+    }
+}
+
 bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     CPUClass *cc = CPU_GET_CLASS(cs);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ab119e62ab..3d3bf26f4e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1012,7 +1012,6 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
 #define SCR_AARCH64_MASK      (0x3fff & ~SCR_NET)
 
 /* Return the current FPSCR value.  */
-uint32_t vfp_get_fpscr(CPUARMState *env);
 void vfp_set_fpscr(CPUARMState *env, uint32_t val);
 
 /* For A64 the FPSCR is split into two logically distinct registers,
@@ -1021,27 +1020,6 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
  */
 #define FPSR_MASK 0xf800009f
 #define FPCR_MASK 0x07f79f00
-static inline uint32_t vfp_get_fpsr(CPUARMState *env)
-{
-    return vfp_get_fpscr(env) & FPSR_MASK;
-}
-
-static inline void vfp_set_fpsr(CPUARMState *env, uint32_t val)
-{
-    uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPSR_MASK) | (val & FPSR_MASK);
-    vfp_set_fpscr(env, new_fpscr);
-}
-
-static inline uint32_t vfp_get_fpcr(CPUARMState *env)
-{
-    return vfp_get_fpscr(env) & FPCR_MASK;
-}
-
-static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val)
-{
-    uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPCR_MASK) | (val & FPCR_MASK);
-    vfp_set_fpscr(env, new_fpscr);
-}
 
 enum arm_cpu_mode {
   ARM_CPU_MODE_USR = 0x10,
@@ -1128,6 +1106,66 @@ enum arm_features {
     ARM_FEATURE_VBAR, /* has cp15 VBAR */
 };
 
+/* VFP support.  We follow the convention used for VFP instructions:
+   Single precision routines have a "s" suffix, double precision a
+   "d" suffix.  */
+
+/* Convert host exception flags to vfp form.  */
+static inline int vfp_exceptbits_from_host(int host_bits)
+{
+    int target_bits = 0;
+
+    if (host_bits & float_flag_invalid)
+        target_bits |= 1;
+    if (host_bits & float_flag_divbyzero)
+        target_bits |= 2;
+    if (host_bits & float_flag_overflow)
+        target_bits |= 4;
+    if (host_bits & (float_flag_underflow | float_flag_output_denormal))
+        target_bits |= 8;
+    if (host_bits & float_flag_inexact)
+        target_bits |= 0x10;
+    if (host_bits & float_flag_input_denormal)
+        target_bits |= 0x80;
+    return target_bits;
+}
+
+static inline uint32_t vfp_get_fpscr(CPUARMState *env)
+{
+    int i;
+    uint32_t fpscr;
+
+    fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
+            | (env->vfp.vec_len << 16)
+            | (env->vfp.vec_stride << 20);
+    i = get_float_exception_flags(&env->vfp.fp_status);
+    i |= get_float_exception_flags(&env->vfp.standard_fp_status);
+    fpscr |= vfp_exceptbits_from_host(i);
+    return fpscr;
+}
+
+static inline uint32_t vfp_get_fpsr(CPUARMState *env)
+{
+    return vfp_get_fpscr(env) & FPSR_MASK;
+}
+
+static inline void vfp_set_fpsr(CPUARMState *env, uint32_t val)
+{
+    uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPSR_MASK) | (val & FPSR_MASK);
+    vfp_set_fpscr(env, new_fpscr);
+}
+
+static inline uint32_t vfp_get_fpcr(CPUARMState *env)
+{
+    return vfp_get_fpscr(env) & FPCR_MASK;
+}
+
+static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val)
+{
+    uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPCR_MASK) | (val & FPCR_MASK);
+    vfp_set_fpscr(env, new_fpscr);
+}
+
 static inline int arm_feature(CPUARMState *env, int feature)
 {
     return (env->features & (1ULL << feature)) != 0;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8dcabbf576..2ec50b94fc 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5514,11 +5514,6 @@ void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
     }
 }
 
-const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
-{
-    return g_hash_table_lookup(cpregs, &encoded_cp);
-}
-
 void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
 {
@@ -8664,47 +8659,9 @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
     return (a & mask) | (b & ~mask);
 }
 
-/* VFP support.  We follow the convention used for VFP instructions:
-   Single precision routines have a "s" suffix, double precision a
-   "d" suffix.  */
-
-/* Convert host exception flags to vfp form.  */
-static inline int vfp_exceptbits_from_host(int host_bits)
-{
-    int target_bits = 0;
-
-    if (host_bits & float_flag_invalid)
-        target_bits |= 1;
-    if (host_bits & float_flag_divbyzero)
-        target_bits |= 2;
-    if (host_bits & float_flag_overflow)
-        target_bits |= 4;
-    if (host_bits & (float_flag_underflow | float_flag_output_denormal))
-        target_bits |= 8;
-    if (host_bits & float_flag_inexact)
-        target_bits |= 0x10;
-    if (host_bits & float_flag_input_denormal)
-        target_bits |= 0x80;
-    return target_bits;
-}
-
 uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
 {
-    int i;
-    uint32_t fpscr;
-
-    fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
-            | (env->vfp.vec_len << 16)
-            | (env->vfp.vec_stride << 20);
-    i = get_float_exception_flags(&env->vfp.fp_status);
-    i |= get_float_exception_flags(&env->vfp.standard_fp_status);
-    fpscr |= vfp_exceptbits_from_host(i);
-    return fpscr;
-}
-
-uint32_t vfp_get_fpscr(CPUARMState *env)
-{
-    return HELPER(vfp_get_fpscr)(env);
+    return vfp_get_fpscr(env);
 }
 
 /* Convert vfp exception flags to target form.  */
@@ -9577,34 +9534,6 @@ float64 HELPER(rintd)(float64 x, void *fp_status)
     return ret;
 }
 
-/* Convert ARM rounding mode to softfloat */
-int arm_rmode_to_sf(int rmode)
-{
-    switch (rmode) {
-    case FPROUNDING_TIEAWAY:
-        rmode = float_round_ties_away;
-        break;
-    case FPROUNDING_ODD:
-        /* FIXME: add support for TIEAWAY and ODD */
-        qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n",
-                      rmode);
-    case FPROUNDING_TIEEVEN:
-    default:
-        rmode = float_round_nearest_even;
-        break;
-    case FPROUNDING_POSINF:
-        rmode = float_round_up;
-        break;
-    case FPROUNDING_NEGINF:
-        rmode = float_round_down;
-        break;
-    case FPROUNDING_ZERO:
-        rmode = float_round_to_zero;
-        break;
-    }
-    return rmode;
-}
-
 /* CRC helpers.
  * The upper bytes of val (above the number specified by 'bytes') must have
  * been zeroed out by the caller.
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index f673d939e1..56333c6dd5 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -118,60 +118,6 @@ static inline ARMMMUIdx get_a64_user_mem_index(DisasContext *s)
     }
 }
 
-void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
-                            fprintf_function cpu_fprintf, int flags)
-{
-    ARMCPU *cpu = ARM_CPU(cs);
-    CPUARMState *env = &cpu->env;
-    uint32_t psr = pstate_read(env);
-    int i;
-    int el = arm_current_el(env);
-    const char *ns_status;
-
-    cpu_fprintf(f, "PC=%016"PRIx64"  SP=%016"PRIx64"\n",
-            env->pc, env->xregs[31]);
-    for (i = 0; i < 31; i++) {
-        cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
-        if ((i % 4) == 3) {
-            cpu_fprintf(f, "\n");
-        } else {
-            cpu_fprintf(f, " ");
-        }
-    }
-
-    if (arm_feature(env, ARM_FEATURE_EL3) && el != 3) {
-        ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
-    } else {
-        ns_status = "";
-    }
-
-    cpu_fprintf(f, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n",
-                psr,
-                psr & PSTATE_N ? 'N' : '-',
-                psr & PSTATE_Z ? 'Z' : '-',
-                psr & PSTATE_C ? 'C' : '-',
-                psr & PSTATE_V ? 'V' : '-',
-                ns_status,
-                el,
-                psr & PSTATE_SP ? 'h' : 't');
-
-    if (flags & CPU_DUMP_FPU) {
-        int numvfpregs = 32;
-        for (i = 0; i < numvfpregs; i += 2) {
-            uint64_t vlo = float64_val(env->vfp.regs[i * 2]);
-            uint64_t vhi = float64_val(env->vfp.regs[(i * 2) + 1]);
-            cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
-                        i, vhi, vlo);
-            vlo = float64_val(env->vfp.regs[(i + 1) * 2]);
-            vhi = float64_val(env->vfp.regs[((i + 1) * 2) + 1]);
-            cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
-                        i + 1, vhi, vlo);
-        }
-        cpu_fprintf(f, "FPCR: %08x  FPSR: %08x\n",
-                    vfp_get_fpcr(env), vfp_get_fpsr(env));
-    }
-}
-
 void gen_a64_set_pc_im(uint64_t val)
 {
     tcg_gen_movi_i64(cpu_pc, val);
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 0ad9070b45..a82557eb39 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -2971,6 +2971,34 @@ static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
     return 0;
 }
 
+/* Convert ARM rounding mode to softfloat */
+int arm_rmode_to_sf(int rmode)
+{
+    switch (rmode) {
+    case FPROUNDING_TIEAWAY:
+        rmode = float_round_ties_away;
+        break;
+    case FPROUNDING_ODD:
+        /* FIXME: add support for TIEAWAY and ODD */
+        qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n",
+                      rmode);
+    case FPROUNDING_TIEEVEN:
+    default:
+        rmode = float_round_nearest_even;
+        break;
+    case FPROUNDING_POSINF:
+        rmode = float_round_up;
+        break;
+    case FPROUNDING_NEGINF:
+        rmode = float_round_down;
+        break;
+    case FPROUNDING_ZERO:
+        rmode = float_round_to_zero;
+        break;
+    }
+    return rmode;
+}
+
 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
                         int rounding)
 {
@@ -7399,6 +7427,11 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
     return 0;
 }
 
+const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t encoded_cp)
+{
+    return g_hash_table_lookup(cpregs, &encoded_cp);
+}
+
 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
 {
     int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
@@ -11976,70 +12009,6 @@ done_generating:
     tb->icount = num_insns;
 }
 
-static const char *cpu_mode_names[16] = {
-  "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
-  "???", "???", "hyp", "und", "???", "???", "???", "sys"
-};
-
-void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-                        int flags)
-{
-    ARMCPU *cpu = ARM_CPU(cs);
-    CPUARMState *env = &cpu->env;
-    int i;
-    uint32_t psr;
-    const char *ns_status;
-
-    if (is_a64(env)) {
-        aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
-        return;
-    }
-
-    for(i=0;i<16;i++) {
-        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
-        if ((i % 4) == 3)
-            cpu_fprintf(f, "\n");
-        else
-            cpu_fprintf(f, " ");
-    }
-    psr = cpsr_read(env);
-
-    if (arm_feature(env, ARM_FEATURE_EL3) &&
-        (psr & CPSR_M) != ARM_CPU_MODE_MON) {
-        ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
-    } else {
-        ns_status = "";
-    }
-
-    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
-                psr,
-                psr & (1 << 31) ? 'N' : '-',
-                psr & (1 << 30) ? 'Z' : '-',
-                psr & (1 << 29) ? 'C' : '-',
-                psr & (1 << 28) ? 'V' : '-',
-                psr & CPSR_T ? 'T' : 'A',
-                ns_status,
-                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
-
-    if (flags & CPU_DUMP_FPU) {
-        int numvfpregs = 0;
-        if (arm_feature(env, ARM_FEATURE_VFP)) {
-            numvfpregs += 16;
-        }
-        if (arm_feature(env, ARM_FEATURE_VFP3)) {
-            numvfpregs += 16;
-        }
-        for (i = 0; i < numvfpregs; i++) {
-            uint64_t v = float64_val(env->vfp.regs[i]);
-            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
-                        i * 2, (uint32_t)v,
-                        i * 2 + 1, (uint32_t)(v >> 32),
-                        i, v);
-        }
-        cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
-    }
-}
-
 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 285e96f087..6b93b35a3b 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -125,8 +125,6 @@ static inline int default_exception_el(DisasContext *s)
 void a64_translate_init(void);
 void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb);
 void gen_a64_set_pc_im(uint64_t val);
-void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
-                            fprintf_function cpu_fprintf, int flags);
 #else
 static inline void a64_translate_init(void)
 {
@@ -140,11 +138,6 @@ static inline void gen_a64_set_pc_im(uint64_t val)
 {
 }
 
-static inline void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
-                                          fprintf_function cpu_fprintf,
-                                          int flags)
-{
-}
 #endif
 
 void arm_test_cc(DisasCompare *cmp, int cc);
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index e56b815d73..059061e6e8 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -148,6 +148,29 @@ static inline void do_interrupt_m68k_hardirq(CPUM68KState *env)
 }
 #endif
 
+void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
+{
+    M68kCPU *cpu = M68K_CPU(cs);
+    CPUM68KState *env = &cpu->env;
+    int i;
+    uint16_t sr;
+    CPU_DoubleU u;
+    for (i = 0; i < 8; i++)
+      {
+        u.d = env->fregs[i];
+        cpu_fprintf(f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
+                    i, env->dregs[i], i, env->aregs[i],
+                    i, u.l.upper, u.l.lower, *(double *)&u.d);
+      }
+    cpu_fprintf (f, "PC = %08x   ", env->pc);
+    sr = env->sr | cpu_m68k_get_ccr(env);
+    cpu_fprintf(f, "SR = %04x %c%c%c%c%c ", sr, (sr & CCF_X) ? 'X' : '-',
+                (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
+                (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
+    cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
+}
+
 bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     M68kCPU *cpu = M68K_CPU(cs);
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 53293173c5..e0d055c3fe 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4725,29 +4725,6 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
     tb->icount = num_insns;
 }
 
-void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
-                         int flags)
-{
-    M68kCPU *cpu = M68K_CPU(cs);
-    CPUM68KState *env = &cpu->env;
-    int i;
-    uint16_t sr;
-    CPU_DoubleU u;
-    for (i = 0; i < 8; i++)
-      {
-        u.d = env->fregs[i];
-        cpu_fprintf(f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
-                    i, env->dregs[i], i, env->aregs[i],
-                    i, u.l.upper, u.l.lower, *(double *)&u.d);
-      }
-    cpu_fprintf (f, "PC = %08x   ", env->pc);
-    sr = env->sr | cpu_m68k_get_ccr(env);
-    cpu_fprintf(f, "SR = %04x %c%c%c%c%c ", sr, (sr & CCF_X) ? 'X' : '-',
-                (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
-                (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
-    cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
-}
-
 void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 7af4c2f084..4965b912ef 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -2454,14 +2454,6 @@ void mips_cpu_unassigned_access(CPUState *cs, hwaddr addr,
 #define FP_TO_INT32_OVERFLOW 0x7fffffff
 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
 
-/* convert MIPS rounding mode in FCR31 to IEEE library */
-unsigned int ieee_rm[] = {
-    float_round_nearest_even,
-    float_round_to_zero,
-    float_round_up,
-    float_round_down
-};
-
 target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
 {
     target_ulong arg1 = 0;
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 57b824ff2d..697b2a2079 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -36,6 +36,14 @@
 #include "trace-tcg.h"
 #include "exec/log.h"
 
+/* convert MIPS rounding mode in FCR31 to IEEE library */
+unsigned int ieee_rm[] = {
+    float_round_nearest_even,
+    float_round_to_zero,
+    float_round_up,
+    float_round_down
+};
+
 #define MIPS_DEBUG_DISAS 0
 
 /* MIPS major opcodes */
diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c
index 7a338136a8..4f74946ec9 100644
--- a/target/ppc/gdbstub.c
+++ b/target/ppc/gdbstub.c
@@ -84,26 +84,6 @@ static int ppc_gdb_register_len(int n)
     }
 }
 
-/* We need to present the registers to gdb in the "current" memory ordering.
-   For user-only mode we get this for free; TARGET_WORDS_BIGENDIAN is set to
-   the proper ordering for the binary, and cannot be changed.
-   For system mode, TARGET_WORDS_BIGENDIAN is always set, and we must check
-   the current mode of the chip to see if we're running in little-endian.  */
-void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
-{
-#ifndef CONFIG_USER_ONLY
-    if (!msr_le) {
-        /* do nothing */
-    } else if (len == 4) {
-        bswap32s((uint32_t *)mem_buf);
-    } else if (len == 8) {
-        bswap64s((uint64_t *)mem_buf);
-    } else {
-        g_assert_not_reached();
-    }
-#endif
-}
-
 /* Old gdb always expects FP registers.  Newer (xml-aware) gdb only
  * expects whatever the target description contains.  Due to a
  * historical mishap the FP registers appear in between core integer
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 626e03186c..74e3339bd8 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -9462,6 +9462,26 @@ static bool avr_need_swap(CPUPPCState *env)
 #endif
 }
 
+/* We need to present the registers to gdb in the "current" memory ordering.
+   For user-only mode we get this for free; TARGET_WORDS_BIGENDIAN is set to
+   the proper ordering for the binary, and cannot be changed.
+   For system mode, TARGET_WORDS_BIGENDIAN is always set, and we must check
+   the current mode of the chip to see if we're running in little-endian.  */
+void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
+{
+#ifndef CONFIG_USER_ONLY
+    if (!msr_le) {
+        /* do nothing */
+    } else if (len == 4) {
+        bswap32s((uint32_t *)mem_buf);
+    } else if (len == 8) {
+        bswap64s((uint64_t *)mem_buf);
+    } else {
+        g_assert_not_reached();
+    }
+#endif
+}
+
 static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 {
     if (n < 32) {
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
index d603bde237..42e753a5ea 100644
--- a/target/unicore32/helper.c
+++ b/target/unicore32/helper.c
@@ -247,6 +247,74 @@ int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr address,
 }
 #endif
 
+static const char *cpu_mode_names[16] = {
+    "USER", "REAL", "INTR", "PRIV", "UM14", "UM15", "UM16", "TRAP",
+    "UM18", "UM19", "UM1A", "EXTN", "UM1C", "UM1D", "UM1E", "SUSR"
+};
+
+#undef UCF64_DUMP_STATE
+#ifdef UCF64_DUMP_STATE
+static void cpu_dump_state_ucf64(CPUUniCore32State *env, FILE *f,
+        fprintf_function cpu_fprintf, int flags)
+{
+    int i;
+    union {
+        uint32_t i;
+        float s;
+    } s0, s1;
+    CPU_DoubleU d;
+    /* ??? This assumes float64 and double have the same layout.
+       Oh well, it's only debug dumps.  */
+    union {
+        float64 f64;
+        double d;
+    } d0;
+
+    for (i = 0; i < 16; i++) {
+        d.d = env->ucf64.regs[i];
+        s0.i = d.l.lower;
+        s1.i = d.l.upper;
+        d0.f64 = d.d;
+        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g)",
+                    i * 2, (int)s0.i, s0.s,
+                    i * 2 + 1, (int)s1.i, s1.s);
+        cpu_fprintf(f, " d%02d=%" PRIx64 "(%8g)\n",
+                    i, (uint64_t)d0.f64, d0.d);
+    }
+    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
+}
+#else
+#define cpu_dump_state_ucf64(env, file, pr, flags)      do { } while (0)
+#endif
+
+void uc32_cpu_dump_state(CPUState *cs, FILE *f,
+                         fprintf_function cpu_fprintf, int flags)
+{
+    UniCore32CPU *cpu = UNICORE32_CPU(cs);
+    CPUUniCore32State *env = &cpu->env;
+    int i;
+    uint32_t psr;
+
+    for (i = 0; i < 32; i++) {
+        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
+        if ((i % 4) == 3) {
+            cpu_fprintf(f, "\n");
+        } else {
+            cpu_fprintf(f, " ");
+        }
+    }
+    psr = cpu_asr_read(env);
+    cpu_fprintf(f, "PSR=%08x %c%c%c%c %s\n",
+                psr,
+                psr & (1 << 31) ? 'N' : '-',
+                psr & (1 << 30) ? 'Z' : '-',
+                psr & (1 << 29) ? 'C' : '-',
+                psr & (1 << 28) ? 'V' : '-',
+                cpu_mode_names[psr & 0xf]);
+
+    cpu_dump_state_ucf64(env, f, cpu_fprintf, flags);
+}
+
 bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c
index 514d460408..92300671a7 100644
--- a/target/unicore32/translate.c
+++ b/target/unicore32/translate.c
@@ -2036,74 +2036,6 @@ done_generating:
     tb->icount = num_insns;
 }
 
-static const char *cpu_mode_names[16] = {
-    "USER", "REAL", "INTR", "PRIV", "UM14", "UM15", "UM16", "TRAP",
-    "UM18", "UM19", "UM1A", "EXTN", "UM1C", "UM1D", "UM1E", "SUSR"
-};
-
-#undef UCF64_DUMP_STATE
-#ifdef UCF64_DUMP_STATE
-static void cpu_dump_state_ucf64(CPUUniCore32State *env, FILE *f,
-        fprintf_function cpu_fprintf, int flags)
-{
-    int i;
-    union {
-        uint32_t i;
-        float s;
-    } s0, s1;
-    CPU_DoubleU d;
-    /* ??? This assumes float64 and double have the same layout.
-       Oh well, it's only debug dumps.  */
-    union {
-        float64 f64;
-        double d;
-    } d0;
-
-    for (i = 0; i < 16; i++) {
-        d.d = env->ucf64.regs[i];
-        s0.i = d.l.lower;
-        s1.i = d.l.upper;
-        d0.f64 = d.d;
-        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g)",
-                    i * 2, (int)s0.i, s0.s,
-                    i * 2 + 1, (int)s1.i, s1.s);
-        cpu_fprintf(f, " d%02d=%" PRIx64 "(%8g)\n",
-                    i, (uint64_t)d0.f64, d0.d);
-    }
-    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
-}
-#else
-#define cpu_dump_state_ucf64(env, file, pr, flags)      do { } while (0)
-#endif
-
-void uc32_cpu_dump_state(CPUState *cs, FILE *f,
-                         fprintf_function cpu_fprintf, int flags)
-{
-    UniCore32CPU *cpu = UNICORE32_CPU(cs);
-    CPUUniCore32State *env = &cpu->env;
-    int i;
-    uint32_t psr;
-
-    for (i = 0; i < 32; i++) {
-        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
-        if ((i % 4) == 3) {
-            cpu_fprintf(f, "\n");
-        } else {
-            cpu_fprintf(f, " ");
-        }
-    }
-    psr = cpu_asr_read(env);
-    cpu_fprintf(f, "PSR=%08x %c%c%c%c %s\n",
-                psr,
-                psr & (1 << 31) ? 'N' : '-',
-                psr & (1 << 30) ? 'Z' : '-',
-                psr & (1 << 29) ? 'C' : '-',
-                psr & (1 << 28) ? 'V' : '-',
-                cpu_mode_names[psr & 0xf]);
-
-    cpu_dump_state_ucf64(env, f, cpu_fprintf, flags);
-}
-
 void restore_state_to_opc(CPUUniCore32State *env, TranslationBlock *tb,
                           target_ulong *data)
 {
-- 
2.11.0

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

* [Qemu-devel] [RFC PATCH 3/3] Introduce libtcg infrastructure
  2017-01-21  8:45 [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg Alessandro Di Federico
  2017-01-21  8:45 ` [Qemu-devel] [RFC PATCH 1/3] Factor out {linux,bsd}-user/qemu.h Alessandro Di Federico
  2017-01-21  8:45 ` [Qemu-devel] [RFC PATCH 2/3] *-user targets object files decoupling Alessandro Di Federico
@ 2017-01-21  8:46 ` Alessandro Di Federico
  2017-01-24 10:08   ` Marc-André Lureau
  2017-01-21  9:01 ` [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg no-reply
  2017-02-07 11:40 ` Peter Maydell
  4 siblings, 1 reply; 15+ messages in thread
From: Alessandro Di Federico @ 2017-01-21  8:46 UTC (permalink / raw)
  To: qemu-devel

[This is a draft patch is for review purposes only]

* Extend the build system to build libtcg-$arch.so dynamic libraries.
* Introduce --enable-libtcg and --disable-libtcg the *-libtcg target,
  similar to *-linux-user and *-bsd-user, since it enables
  CONFIG_USER_ONLY, but uses only the TCG frontends (in particular the
  various /target/$arch/translate.c).
* If there's at least a *-libtcg, compile everything as position
  independent code.
* In case we're building libtcg, install the output binary in the
  $PREFIX/lib directory instead of $PREFIX/bin.
* Reduce the number of object files linked into libtcg-$arch.so to the
  minimum.
* Install the tcg.h header to use libtcg.
* Create libtcg/, with a draft function referencing the functions that
  libtcg would use.
---
 Makefile                                |  7 +++++
 Makefile.target                         | 40 +++++++++++++++++++++---
 configure                               | 20 ++++++++++++
 crypto/Makefile.objs                    |  2 +-
 default-configs/aarch64-libtcg.mak      |  0
 default-configs/alpha-libtcg.mak        |  0
 default-configs/arm-libtcg.mak          |  0
 default-configs/armeb-libtcg.mak        |  0
 default-configs/cris-libtcg.mak         |  0
 default-configs/i386-libtcg.mak         |  0
 default-configs/m68k-libtcg.mak         |  0
 default-configs/microblaze-libtcg.mak   |  0
 default-configs/microblazeel-libtcg.mak |  0
 default-configs/mips-libtcg.mak         |  0
 default-configs/mips64-libtcg.mak       |  0
 default-configs/mips64el-libtcg.mak     |  0
 default-configs/mipsel-libtcg.mak       |  0
 default-configs/mipsn32-libtcg.mak      |  0
 default-configs/mipsn32el-libtcg.mak    |  0
 default-configs/or32-libtcg.mak         |  0
 default-configs/ppc-libtcg.mak          |  1 +
 default-configs/ppc64-libtcg.mak        |  1 +
 default-configs/ppc64abi32-libtcg.mak   |  1 +
 default-configs/ppc64le-libtcg.mak      |  1 +
 default-configs/s390x-libtcg.mak        |  0
 default-configs/sh4-libtcg.mak          |  0
 default-configs/sh4eb-libtcg.mak        |  0
 default-configs/sparc-libtcg.mak        |  0
 default-configs/sparc32plus-libtcg.mak  |  0
 default-configs/sparc64-libtcg.mak      |  0
 default-configs/unicore32-libtcg.mak    |  0
 default-configs/x86_64-libtcg.mak       |  0
 hw/core/Makefile.objs                   |  5 ++-
 include/exec/helper-gen.h               | 12 +++----
 include/exec/helper-head.h              |  8 +++++
 include/exec/helper-tcg.h               | 12 +++----
 libtcg/Makefile.objs                    |  1 +
 libtcg/qemu.h                           |  6 ++++
 libtcg/tcg.c                            | 55 +++++++++++++++++++++++++++++++++
 libtcg/tcg.h                            |  0
 target/alpha/Makefile.objs              |  9 ++++--
 target/arm/Makefile.objs                | 22 +++++++++----
 target/cris/Makefile.objs               | 10 ++++--
 target/i386/Makefile.objs               | 14 ++++++---
 target/lm32/Makefile.objs               | 12 +++++--
 target/m68k/Makefile.objs               |  7 ++++-
 target/microblaze/Makefile.objs         | 10 ++++--
 target/mips/Makefile.objs               | 11 +++++--
 target/moxie/Makefile.objs              |  8 ++++-
 target/openrisc/Makefile.objs           | 11 +++++--
 target/ppc/Makefile.objs                | 18 +++++------
 target/ppc/translate.c                  |  2 ++
 target/ppc/translate_init.c             |  8 +++++
 target/s390x/Makefile.objs              | 16 +++++++---
 target/sh4/Makefile.objs                |  8 ++++-
 target/sparc/Makefile.objs              | 15 ++++++---
 target/tilegx/Makefile.objs             |  7 ++++-
 target/tricore/Makefile.objs            |  7 ++++-
 target/unicore32/Makefile.objs          |  8 +++--
 target/xtensa/Makefile.objs             | 14 ++++++---
 trace/Makefile.objs                     |  2 +-
 translate-all.c                         |  4 ++-
 62 files changed, 322 insertions(+), 73 deletions(-)
 create mode 100644 default-configs/aarch64-libtcg.mak
 create mode 100644 default-configs/alpha-libtcg.mak
 create mode 100644 default-configs/arm-libtcg.mak
 create mode 100644 default-configs/armeb-libtcg.mak
 create mode 100644 default-configs/cris-libtcg.mak
 create mode 100644 default-configs/i386-libtcg.mak
 create mode 100644 default-configs/m68k-libtcg.mak
 create mode 100644 default-configs/microblaze-libtcg.mak
 create mode 100644 default-configs/microblazeel-libtcg.mak
 create mode 100644 default-configs/mips-libtcg.mak
 create mode 100644 default-configs/mips64-libtcg.mak
 create mode 100644 default-configs/mips64el-libtcg.mak
 create mode 100644 default-configs/mipsel-libtcg.mak
 create mode 100644 default-configs/mipsn32-libtcg.mak
 create mode 100644 default-configs/mipsn32el-libtcg.mak
 create mode 100644 default-configs/or32-libtcg.mak
 create mode 100644 default-configs/ppc-libtcg.mak
 create mode 100644 default-configs/ppc64-libtcg.mak
 create mode 100644 default-configs/ppc64abi32-libtcg.mak
 create mode 100644 default-configs/ppc64le-libtcg.mak
 create mode 100644 default-configs/s390x-libtcg.mak
 create mode 100644 default-configs/sh4-libtcg.mak
 create mode 100644 default-configs/sh4eb-libtcg.mak
 create mode 100644 default-configs/sparc-libtcg.mak
 create mode 100644 default-configs/sparc32plus-libtcg.mak
 create mode 100644 default-configs/sparc64-libtcg.mak
 create mode 100644 default-configs/unicore32-libtcg.mak
 create mode 100644 default-configs/x86_64-libtcg.mak
 create mode 100644 libtcg/Makefile.objs
 create mode 100644 libtcg/qemu.h
 create mode 100644 libtcg/tcg.c
 create mode 100644 libtcg/tcg.h

diff --git a/Makefile b/Makefile
index 1a8bfb225c..0e6925e04f 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,14 @@ endif
 
 CONFIG_SOFTMMU := $(if $(filter %-softmmu,$(TARGET_DIRS)),y)
 CONFIG_USER_ONLY := $(if $(filter %-user,$(TARGET_DIRS)),y)
+CONFIG_LIBTCG := $(if $(filter %-libtcg,$(TARGET_DIRS)),y)
 CONFIG_ALL=y
+
+# If there's at least a *-libtcg target we need to build everything with -fPIC
+ifeq ($(CONFIG_LIBTCG),y)
+QEMU_CFLAGS+=-fPIC
+endif
+
 -include config-all-devices.mak
 -include config-all-disas.mak
 
diff --git a/Makefile.target b/Makefile.target
index 8ae82cb311..6e3df541e0 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -15,10 +15,23 @@ QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target/$(TARGET_BASE_ARCH) -DNEED_CPU_H
 
 QEMU_CFLAGS+=-I$(SRC_PATH)/include
 
+# By default install in bindir
+PROGS_INSTALL_DIR := $(bindir)
+
 ifdef CONFIG_USER_ONLY
+ifdef CONFIG_LIBTCG
+# libtcg
+QEMU_PROG=libtcg-$(TARGET_NAME)$(DSOSUF)
+QEMU_PROG_BUILD = $(QEMU_PROG)
+QEMU_CFLAGS+=-fPIC
+
+# Change the install directory
+PROGS_INSTALL_DIR := $(libdir)
+else
 # user emulator name
 QEMU_PROG=qemu-$(TARGET_NAME)
 QEMU_PROG_BUILD = $(QEMU_PROG)
+endif
 else
 # system emulator name
 QEMU_PROG=qemu-system-$(TARGET_NAME)$(EXESUF)
@@ -85,17 +98,20 @@ all: $(PROGS) stap
 
 #########################################################
 # cpu emulator library
-obj-y = exec.o translate-all.o cpu-exec.o
+obj-y = exec.o translate-all.o
+ifndef CONFIG_LIBTCG
+obj-y += cpu-exec.o
+obj-y += tcg-runtime.o
+obj-y += fpu/softfloat.o
+endif
 obj-y += translate-common.o
 obj-y += cpu-exec-common.o
 obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
 obj-y += tcg/tcg-common.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
-obj-y += fpu/softfloat.o
 obj-y += target/$(TARGET_BASE_ARCH)/
 obj-y += disas.o
-obj-y += tcg-runtime.o
 obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
 
@@ -133,6 +149,19 @@ obj-y += gdbstub.o user-exec.o
 endif #CONFIG_BSD_USER
 
 #########################################################
+# libtcg target
+
+ifdef CONFIG_LIBTCG
+
+QEMU_CFLAGS+=-I$(SRC_PATH)/libtcg
+
+obj-y += libtcg/
+
+QEMU_LDFLAGS+=-shared
+
+endif #CONFIG_LIBTCG
+
+#########################################################
 # System emulator target
 ifdef CONFIG_SOFTMMU
 obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
@@ -220,8 +249,11 @@ ifdef CONFIG_TRACE_SYSTEMTAP
 endif
 
 install: all
+ifdef CONFIG_LIBTINYCODE
+	$(INSTALL_DATA) $(SRC_PATH)/tcg/tcg-opc.h $(SRC_PATH)/libtcg/tcg.h "$(DESTDIR)$(includedir)"
+endif
 ifneq ($(PROGS),)
-	$(call install-prog,$(PROGS),$(DESTDIR)$(bindir))
+	$(call install-prog,$(PROGS),$(DESTDIR)$(PROGS_INSTALL_DIR))
 endif
 ifdef CONFIG_TRACE_SYSTEMTAP
 	$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)/../systemtap/tapset"
diff --git a/configure b/configure
index 86f5214dd0..352a74cec8 100755
--- a/configure
+++ b/configure
@@ -265,6 +265,7 @@ cocoa="no"
 softmmu="yes"
 linux_user="no"
 bsd_user="no"
+libtcg="no"
 aix="no"
 blobs="yes"
 pkgversion=""
@@ -676,6 +677,7 @@ Haiku)
   audio_possible_drivers="oss alsa sdl pa"
   linux="yes"
   linux_user="yes"
+  libtcg="yes"
   kvm="yes"
   vhost_net="yes"
   vhost_scsi="yes"
@@ -969,6 +971,10 @@ for opt do
   ;;
   --enable-bsd-user) bsd_user="yes"
   ;;
+  --disable-libtcg) libtcg="no"
+  ;;
+  --enable-libtcg) libtcg="yes"
+  ;;
   --enable-pie) pie="yes"
   ;;
   --disable-pie) pie="no"
@@ -1245,6 +1251,7 @@ EXTRA_CFLAGS="$CPU_CFLAGS $EXTRA_CFLAGS"
 if [ "$ARCH" = "unknown" ]; then
   bsd_user="no"
   linux_user="no"
+  libtcg="no"
 fi
 
 default_target_list=""
@@ -1260,6 +1267,9 @@ fi
 if [ "$bsd_user" = "yes" ]; then
     mak_wilds="${mak_wilds} $source_path/default-configs/*-bsd-user.mak"
 fi
+if [ "$libtcg" = "yes" ]; then
+    mak_wilds="${mak_wilds} $source_path/default-configs/*-libtcg.mak"
+fi
 
 for config in $mak_wilds; do
     default_target_list="${default_target_list} $(basename "$config" .mak)"
@@ -1401,6 +1411,7 @@ disabled with --disable-FEATURE, default is enabled if available:
   tcmalloc        tcmalloc support
   jemalloc        jemalloc support
   replication     replication support
+  libtcg          standalone TCG library
 
 NOTE: The object files are built at the place where configure is launched
 EOF
@@ -5112,6 +5123,7 @@ echo "tcmalloc support  $tcmalloc"
 echo "jemalloc support  $jemalloc"
 echo "avx2 optimization $avx2_opt"
 echo "replication support $replication"
+echo "libtcg enabled    $libtcg"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -5853,6 +5865,7 @@ target_softmmu="no"
 target_user_only="no"
 target_linux_user="no"
 target_bsd_user="no"
+target_libtcg="no"
 case "$target" in
   ${target_name}-softmmu)
     target_softmmu="yes"
@@ -5871,6 +5884,10 @@ case "$target" in
     target_user_only="yes"
     target_bsd_user="yes"
     ;;
+  ${target_name}-libtcg)
+    target_user_only="yes"
+    target_libtcg="yes"
+    ;;
   *)
     error_exit "Target '$target' not recognised"
     exit 1
@@ -6063,6 +6080,9 @@ fi
 if test "$target_linux_user" = "yes" ; then
   echo "CONFIG_LINUX_USER=y" >> $config_target_mak
 fi
+if test "$target_libtcg" = "yes" ; then
+  echo "CONFIG_LIBTCG=y" >> $config_target_mak
+fi
 list=""
 if test ! -z "$gdb_xml_files" ; then
   for x in $gdb_xml_files; do
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index 1f749f2087..2f654db9af 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -7,7 +7,7 @@ crypto-obj-y += hmac.o
 crypto-obj-$(CONFIG_NETTLE) += hmac-nettle.o
 crypto-obj-$(CONFIG_GCRYPT_HMAC) += hmac-gcrypt.o
 crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT_HMAC),n,y)) += hmac-glib.o
-crypto-obj-y += aes.o
+crypto-obj-$(call lnot,$(CONFIG_LIBTCG)) += aes.o
 crypto-obj-y += desrfb.o
 crypto-obj-y += cipher.o
 crypto-obj-y += tlscreds.o
diff --git a/default-configs/aarch64-libtcg.mak b/default-configs/aarch64-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/alpha-libtcg.mak b/default-configs/alpha-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/arm-libtcg.mak b/default-configs/arm-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/armeb-libtcg.mak b/default-configs/armeb-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/cris-libtcg.mak b/default-configs/cris-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/i386-libtcg.mak b/default-configs/i386-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/m68k-libtcg.mak b/default-configs/m68k-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/microblaze-libtcg.mak b/default-configs/microblaze-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/microblazeel-libtcg.mak b/default-configs/microblazeel-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/mips-libtcg.mak b/default-configs/mips-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/mips64-libtcg.mak b/default-configs/mips64-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/mips64el-libtcg.mak b/default-configs/mips64el-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/mipsel-libtcg.mak b/default-configs/mipsel-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/mipsn32-libtcg.mak b/default-configs/mipsn32-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/mipsn32el-libtcg.mak b/default-configs/mipsn32el-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/or32-libtcg.mak b/default-configs/or32-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/ppc-libtcg.mak b/default-configs/ppc-libtcg.mak
new file mode 100644
index 0000000000..7235c56d55
--- /dev/null
+++ b/default-configs/ppc-libtcg.mak
@@ -0,0 +1 @@
+CONFIG_LIBDECNUMBER=y
diff --git a/default-configs/ppc64-libtcg.mak b/default-configs/ppc64-libtcg.mak
new file mode 100644
index 0000000000..7235c56d55
--- /dev/null
+++ b/default-configs/ppc64-libtcg.mak
@@ -0,0 +1 @@
+CONFIG_LIBDECNUMBER=y
diff --git a/default-configs/ppc64abi32-libtcg.mak b/default-configs/ppc64abi32-libtcg.mak
new file mode 100644
index 0000000000..7235c56d55
--- /dev/null
+++ b/default-configs/ppc64abi32-libtcg.mak
@@ -0,0 +1 @@
+CONFIG_LIBDECNUMBER=y
diff --git a/default-configs/ppc64le-libtcg.mak b/default-configs/ppc64le-libtcg.mak
new file mode 100644
index 0000000000..7235c56d55
--- /dev/null
+++ b/default-configs/ppc64le-libtcg.mak
@@ -0,0 +1 @@
+CONFIG_LIBDECNUMBER=y
diff --git a/default-configs/s390x-libtcg.mak b/default-configs/s390x-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/sh4-libtcg.mak b/default-configs/sh4-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/sh4eb-libtcg.mak b/default-configs/sh4eb-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/sparc-libtcg.mak b/default-configs/sparc-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/sparc32plus-libtcg.mak b/default-configs/sparc32plus-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/sparc64-libtcg.mak b/default-configs/sparc64-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/unicore32-libtcg.mak b/default-configs/unicore32-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/default-configs/x86_64-libtcg.mak b/default-configs/x86_64-libtcg.mak
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index a4c94e522d..a58d7c404c 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -1,11 +1,14 @@
 # core qdev-related obj files, also used by *-user:
-common-obj-y += qdev.o qdev-properties.o
+common-obj-y += qdev-properties.o
+#ifndef CONFIG_LIBTCG
+common-obj-y += qdev.o
 common-obj-y += bus.o
 common-obj-y += fw-path-provider.o
 # irq.o needed for qdev GPIO handling:
 common-obj-y += irq.o
 common-obj-y += hotplug.o
 obj-y += nmi.o
+#endif
 
 common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
 common-obj-$(CONFIG_XILINX_AXI) += stream.o
diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
index 8239ffc77c..ac290180b3 100644
--- a/include/exec/helper-gen.h
+++ b/include/exec/helper-gen.h
@@ -9,7 +9,7 @@
 #define DEF_HELPER_FLAGS_0(name, flags, ret)                            \
 static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret))        \
 {                                                                       \
-  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 0, NULL);       \
+  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 0, NULL);   \
 }
 
 #define DEF_HELPER_FLAGS_1(name, flags, ret, t1)                        \
@@ -17,7 +17,7 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret)          \
     dh_arg_decl(t1, 1))                                                 \
 {                                                                       \
   TCGArg args[1] = { dh_arg(t1, 1) };                                   \
-  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 1, args);       \
+  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 1, args);   \
 }
 
 #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2)                    \
@@ -25,7 +25,7 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret)          \
     dh_arg_decl(t1, 1), dh_arg_decl(t2, 2))                             \
 {                                                                       \
   TCGArg args[2] = { dh_arg(t1, 1), dh_arg(t2, 2) };                    \
-  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 2, args);       \
+  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 2, args);   \
 }
 
 #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3)                \
@@ -33,7 +33,7 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret)          \
     dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3))         \
 {                                                                       \
   TCGArg args[3] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3) };     \
-  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 3, args);       \
+  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 3, args);   \
 }
 
 #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4)            \
@@ -43,7 +43,7 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret)          \
 {                                                                       \
   TCGArg args[4] = { dh_arg(t1, 1), dh_arg(t2, 2),                      \
                      dh_arg(t3, 3), dh_arg(t4, 4) };                    \
-  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 4, args);       \
+  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 4, args);   \
 }
 
 #define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5)        \
@@ -53,7 +53,7 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret)          \
 {                                                                       \
   TCGArg args[5] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3),       \
                      dh_arg(t4, 4), dh_arg(t5, 5) };                    \
-  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 5, args);       \
+  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 5, args);   \
 }
 
 #include "helper.h"
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
index 1cfc43b9ff..fa68de92db 100644
--- a/include/exec/helper-head.h
+++ b/include/exec/helper-head.h
@@ -20,6 +20,14 @@
 
 #define HELPER(name) glue(helper_, name)
 
+/* In libtcg we don't want helpers, therefore we leave these fields empty so
+   that we don't needlessly introduce a dependency towards the helper. */
+#ifdef CONFIG_LIBTCG
+# define HELPER_REF(helper) (0)
+#else
+# define HELPER_REF(helper) (HELPER(helper))
+#endif
+
 #define GET_TCGV_i32 GET_TCGV_I32
 #define GET_TCGV_i64 GET_TCGV_I64
 #define GET_TCGV_ptr GET_TCGV_PTR
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
index bb9287727c..ebc7b45d1a 100644
--- a/include/exec/helper-tcg.h
+++ b/include/exec/helper-tcg.h
@@ -7,30 +7,30 @@
 #include "exec/helper-head.h"
 
 #define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
-  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
+  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
     .sizemask = dh_sizemask(ret, 0) },
 
 #define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \
-  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
+  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
     .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) },
 
 #define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \
-  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
+  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
     .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
     | dh_sizemask(t2, 2) },
 
 #define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \
-  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
+  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
     .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
     | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) },
 
 #define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \
-  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
+  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
     .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
     | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) },
 
 #define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \
-  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
+  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
     .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
     | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
     | dh_sizemask(t5, 5) },
diff --git a/libtcg/Makefile.objs b/libtcg/Makefile.objs
new file mode 100644
index 0000000000..a1e7720ce3
--- /dev/null
+++ b/libtcg/Makefile.objs
@@ -0,0 +1 @@
+obj-y += tcg.o
diff --git a/libtcg/qemu.h b/libtcg/qemu.h
new file mode 100644
index 0000000000..cc2131493a
--- /dev/null
+++ b/libtcg/qemu.h
@@ -0,0 +1,6 @@
+#ifndef QEMU_H
+#define QEMU_H
+
+#include "qemu-user-common.h"
+
+#endif /* QEMU_H */
diff --git a/libtcg/tcg.c b/libtcg/tcg.c
new file mode 100644
index 0000000000..f1ce37c77b
--- /dev/null
+++ b/libtcg/tcg.c
@@ -0,0 +1,55 @@
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "exec/exec-all.h"
+#include "qemu/cutils.h"
+
+unsigned long guest_base;
+int singlestep;
+
+void mmap_lock(void)
+{
+    abort();
+}
+
+void mmap_unlock(void)
+{
+    abort();
+}
+
+bool qemu_cpu_is_self(CPUState *cpu)
+{
+    abort();
+}
+
+void qemu_cpu_kick(CPUState *cpu)
+{
+    abort();
+}
+
+#include "disas/disas.h"
+#include "cpu.h"
+
+void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
+                  tb_page_addr_t phys_page2);
+
+void test(void);
+void test(void) {
+  void *x = target_disas;
+  x = &guest_base;
+  x = &tcg_exec_init;
+  x = &module_call_init;
+  // cpu_init("");
+#ifdef TARGET_X86_64
+  X86_CPU(cpu_generic_init(TYPE_X86_CPU, ""));
+#endif
+  x = &cpu_reset;
+  x = &qemu_set_log;
+  x = &g_hash_table_foreach;
+  x = &get_page_addr_code;
+  x = &tcg_func_start;
+  x = &gen_intermediate_code;
+  x = &tb_link_page;
+  // x = &target_mmap;
+  x = &cpu_get_tb_cpu_state;
+  (void) x;
+}
diff --git a/libtcg/tcg.h b/libtcg/tcg.h
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/target/alpha/Makefile.objs b/target/alpha/Makefile.objs
index 63664629f6..5ee1bacf27 100644
--- a/target/alpha/Makefile.objs
+++ b/target/alpha/Makefile.objs
@@ -1,4 +1,9 @@
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += machine.o
-obj-y += translate.o helper.o cpu.o
-obj-y += int_helper.o fpu_helper.o vax_helper.o sys_helper.o mem_helper.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o int_helper.o fpu_helper.o vax_helper.o sys_helper.o mem_helper.o
 obj-y += gdbstub.o
+endif
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
index 847fb52ee0..75a6fc637a 100644
--- a/target/arm/Makefile.objs
+++ b/target/arm/Makefile.objs
@@ -1,12 +1,22 @@
-obj-y += arm-semi.o
+obj-y += translate.o
+obj-$(TARGET_AARCH64) += translate-a64.o
+
 obj-$(CONFIG_SOFTMMU) += machine.o psci.o arch_dump.o monitor.o
+obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
 obj-$(CONFIG_KVM) += kvm.o
 obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
 obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-$(TARGET_AARCH64) += cpu64.o
+
+obj-y += helper.o op_helper.o neon_helper.o iwmmxt_helper.o crypto_helper.o
+obj-$(TARGET_AARCH64) += helper-a64.o
+
+obj-y += arm-semi.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += neon_helper.o iwmmxt_helper.o
+
 obj-y += gdbstub.o
-obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
-obj-y += crypto_helper.o
-obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
+obj-$(TARGET_AARCH64) += gdbstub64.o
+endif
diff --git a/target/cris/Makefile.objs b/target/cris/Makefile.objs
index 7779227fc4..1270edca79 100644
--- a/target/cris/Makefile.objs
+++ b/target/cris/Makefile.objs
@@ -1,3 +1,9 @@
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += gdbstub.o
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += mmu.o machine.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o op_helper.o
+obj-y += gdbstub.o
+endif
diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
index b223d7932b..6653f1c9dd 100644
--- a/target/i386/Makefile.objs
+++ b/target/i386/Makefile.objs
@@ -1,7 +1,13 @@
-obj-y += translate.o helper.o cpu.o bpt_helper.o
-obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o
-obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o mpx_helper.o
-obj-y += gdbstub.o
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o
 obj-$(CONFIG_KVM) += kvm.o hyperv.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o bpt_helper.o int_helper.o misc_helper.o mem_helper.o \
+         excp_helper.o fpu_helper.o cc_helper.o svm_helper.o smm_helper.o \
+         seg_helper.o mpx_helper.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
+obj-y += gdbstub.o
+endif
diff --git a/target/lm32/Makefile.objs b/target/lm32/Makefile.objs
index c3e1bd6bd6..737a6b252d 100644
--- a/target/lm32/Makefile.objs
+++ b/target/lm32/Makefile.objs
@@ -1,4 +1,10 @@
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += gdbstub.o
-obj-y += lm32-semi.o
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += machine.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o op_helper.o
+obj-y += lm32-semi.o
+obj-y += gdbstub.o
+endif
diff --git a/target/m68k/Makefile.objs b/target/m68k/Makefile.objs
index 02cf616a78..9f1bd5de59 100644
--- a/target/m68k/Makefile.objs
+++ b/target/m68k/Makefile.objs
@@ -1,3 +1,8 @@
+obj-y += translate.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o op_helper.o
 obj-y += m68k-semi.o
-obj-y += translate.o op_helper.o helper.o cpu.o
 obj-y += gdbstub.o
+endif
diff --git a/target/microblaze/Makefile.objs b/target/microblaze/Makefile.objs
index f3d7b44c89..898ddbcb0e 100644
--- a/target/microblaze/Makefile.objs
+++ b/target/microblaze/Makefile.objs
@@ -1,3 +1,9 @@
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += gdbstub.o
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += mmu.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o op_helper.o
+obj-y += gdbstub.o
+endif
diff --git a/target/mips/Makefile.objs b/target/mips/Makefile.objs
index bc5ed8511f..d7eae8b9c5 100644
--- a/target/mips/Makefile.objs
+++ b/target/mips/Makefile.objs
@@ -1,4 +1,11 @@
-obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o
-obj-y += gdbstub.o msa_helper.o mips-semi.o
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += machine.o
 obj-$(CONFIG_KVM) += kvm.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += dsp_helper.o op_helper.o lmi_helper.o helper.o msa_helper.o
+obj-y += mips-semi.o
+obj-y += gdbstub.o
+endif
diff --git a/target/moxie/Makefile.objs b/target/moxie/Makefile.objs
index 6381d4d636..5afe63852d 100644
--- a/target/moxie/Makefile.objs
+++ b/target/moxie/Makefile.objs
@@ -1,2 +1,8 @@
-obj-y += translate.o helper.o machine.o cpu.o machine.o
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += mmu.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o machine.o
+obj-y += helper.o
+endif
diff --git a/target/openrisc/Makefile.objs b/target/openrisc/Makefile.objs
index 397d01650e..ea466e9224 100644
--- a/target/openrisc/Makefile.objs
+++ b/target/openrisc/Makefile.objs
@@ -1,5 +1,10 @@
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += machine.o
-obj-y += cpu.o exception.o interrupt.o mmu.o translate.o
-obj-y += exception_helper.o fpu_helper.o int_helper.o \
-         interrupt_helper.o mmu_helper.o sys_helper.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o exception.o interrupt.o mmu.o
+obj-y += exception_helper.o fpu_helper.o int_helper.o interrupt_helper.o \
+         mmu_helper.o sys_helper.o
 obj-y += gdbstub.o
+endif
diff --git a/target/ppc/Makefile.objs b/target/ppc/Makefile.objs
index e667e69701..0b179acd0e 100644
--- a/target/ppc/Makefile.objs
+++ b/target/ppc/Makefile.objs
@@ -1,17 +1,17 @@
-obj-y += cpu-models.o
 obj-y += translate.o
+obj-y += cpu-models.o
+
 ifeq ($(CONFIG_SOFTMMU),y)
-obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o
+obj-y += machine.o mmu-hash32.o monitor.o
+obj-y += mmu_helper.o
 obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o
 endif
+
 obj-$(CONFIG_KVM) += kvm.o
 obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
-obj-y += dfp_helper.o
-obj-y += excp_helper.o
-obj-y += fpu_helper.o
-obj-y += int_helper.o
-obj-y += timebase_helper.o
-obj-y += misc_helper.o
-obj-y += mem_helper.o
+
+ifndef CONFIG_LIBTCG
+obj-y += int_helper.o dfp_helper.o timebase_helper.o mem_helper.o misc_helper.o fpu_helper.o excp_helper.o
 obj-$(CONFIG_USER_ONLY) += user_only_helper.o
 obj-y += gdbstub.o
+endif
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 59e9552d2b..bc9363e9e2 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -6766,6 +6766,7 @@ GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \
 #include "helper_regs.h"
 #include "translate_init.c"
 
+#ifndef CONFIG_LIBTCG
 /*****************************************************************************/
 /* Misc PowerPC helpers */
 void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
@@ -6932,6 +6933,7 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
 #undef RGPL
 #undef RFPL
 }
+#endif
 
 void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
                              fprintf_function cpu_fprintf, int flags)
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 74e3339bd8..7919ebe700 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -9453,6 +9453,7 @@ static void dump_ppc_insns (CPUPPCState *env)
 }
 #endif
 
+#ifndef CONFIG_LIBTCG
 static bool avr_need_swap(CPUPPCState *env)
 {
 #ifdef HOST_WORDS_BIGENDIAN
@@ -9638,6 +9639,7 @@ static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
     }
     return 0;
 }
+#endif
 
 static int ppc_fixup_cpu(PowerPCCPU *cpu)
 {
@@ -9740,6 +9742,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
     }
     init_ppc_proc(cpu);
 
+#ifndef CONFIG_LIBTCG
     if (pcc->insns_flags & PPC_FLOAT) {
         gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
                                  33, "power-fpu.xml", 0);
@@ -9756,6 +9759,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
         gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
                                  32, "power-vsx.xml", 0);
     }
+#endif
 
     qemu_init_vcpu(cs);
 
@@ -10564,11 +10568,14 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
 
     cc->class_by_name = ppc_cpu_class_by_name;
     cc->has_work = ppc_cpu_has_work;
+#ifndef CONFIG_LIBTCG
     cc->do_interrupt = ppc_cpu_do_interrupt;
     cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
     cc->dump_state = ppc_cpu_dump_state;
+#endif
     cc->dump_statistics = ppc_cpu_dump_statistics;
     cc->set_pc = ppc_cpu_set_pc;
+#ifndef CONFIG_LIBTCG
     cc->gdb_read_register = ppc_cpu_gdb_read_register;
     cc->gdb_write_register = ppc_cpu_gdb_write_register;
 #ifdef CONFIG_USER_ONLY
@@ -10580,6 +10587,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
     cc->write_elf64_note = ppc64_cpu_write_elf64_note;
 #endif
 #endif
+#endif
     cc->cpu_exec_enter = ppc_cpu_exec_enter;
 
     cc->gdb_num_core_regs = 71;
diff --git a/target/s390x/Makefile.objs b/target/s390x/Makefile.objs
index c573633bd1..97986fca4e 100644
--- a/target/s390x/Makefile.objs
+++ b/target/s390x/Makefile.objs
@@ -1,9 +1,17 @@
-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-y += gdbstub.o cpu_models.o cpu_features.o
-obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
+obj-y += translate.o
+
+obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o
+obj-$(CONFIG_SOFTMMU) += mmu_helper.o
 obj-$(CONFIG_KVM) += kvm.o
 
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o interrupt.o
+obj-y += helper.o int_helper.o fpu_helper.o cc_helper.o mem_helper.o \
+         misc_helper.o
+obj-y += cpu_models.o cpu_features.o
+obj-y += gdbstub.o
+endif
+
 # build and run feature list generator
 feat-src = $(SRC_PATH)/target/$(TARGET_BASE_ARCH)/
 feat-dst = $(BUILD_DIR)/$(TARGET_DIR)
diff --git a/target/sh4/Makefile.objs b/target/sh4/Makefile.objs
index 2c25d96e65..cfbc95fd46 100644
--- a/target/sh4/Makefile.objs
+++ b/target/sh4/Makefile.objs
@@ -1,3 +1,9 @@
-obj-y += translate.o op_helper.o helper.o cpu.o
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += monitor.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o op_helper.o
 obj-y += gdbstub.o
+endif
diff --git a/target/sparc/Makefile.objs b/target/sparc/Makefile.objs
index ec905698c5..fa824d541c 100644
--- a/target/sparc/Makefile.objs
+++ b/target/sparc/Makefile.objs
@@ -1,7 +1,14 @@
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += machine.o monitor.o
-obj-y += translate.o helper.o cpu.o
-obj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+
+obj-y += helper.o 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-$(TARGET_SPARC64) += int64_helper.o vis_helper.o
+
 obj-y += gdbstub.o
+endif
diff --git a/target/tilegx/Makefile.objs b/target/tilegx/Makefile.objs
index 0db778f407..ddf2e41c51 100644
--- a/target/tilegx/Makefile.objs
+++ b/target/tilegx/Makefile.objs
@@ -1 +1,6 @@
-obj-y += cpu.o translate.o helper.o simd_helper.o
+obj-y += translate.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o simd_helper.o
+endif
diff --git a/target/tricore/Makefile.objs b/target/tricore/Makefile.objs
index 7a05670718..9b12c51db0 100644
--- a/target/tricore/Makefile.objs
+++ b/target/tricore/Makefile.objs
@@ -1 +1,6 @@
-obj-y += translate.o helper.o cpu.o op_helper.o fpu_helper.o
+obj-y += translate.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o op_helper.o fpu_helper.o
+endif
diff --git a/target/unicore32/Makefile.objs b/target/unicore32/Makefile.objs
index 6b41b1e9ef..c936429f94 100644
--- a/target/unicore32/Makefile.objs
+++ b/target/unicore32/Makefile.objs
@@ -1,4 +1,8 @@
-obj-y += translate.o op_helper.o helper.o cpu.o
-obj-y += ucf64_helper.o
+obj-y += translate.o
 
 obj-$(CONFIG_SOFTMMU) += softmmu.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o op_helper.o ucf64_helper.o
+endif
diff --git a/target/xtensa/Makefile.objs b/target/xtensa/Makefile.objs
index 481de91973..393a12caea 100644
--- a/target/xtensa/Makefile.objs
+++ b/target/xtensa/Makefile.objs
@@ -1,7 +1,11 @@
-obj-y += xtensa-semi.o
-obj-y += core-dc232b.o
-obj-y += core-dc233c.o
-obj-y += core-fsf.o
+obj-y += translate.o
+
 obj-$(CONFIG_SOFTMMU) += monitor.o
-obj-y += translate.o op_helper.o helper.o cpu.o
+
+ifndef CONFIG_LIBTCG
+obj-y += cpu.o
+obj-y += helper.o op_helper.o
+obj-y += xtensa-semi.o
+obj-y += core-dc232b.o core-dc233c.o core-fsf.o
 obj-y += gdbstub.o
+endif
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index 1e1ce7479d..a6874d769b 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -118,7 +118,7 @@ $(obj)/generated-helpers.c-timestamp: $(BUILD_DIR)/trace-events-all $(BUILD_DIR)
 
 $(obj)/generated-helpers.o: $(obj)/generated-helpers.c
 
-target-obj-y += generated-helpers.o
+target-obj-$(call lnot,$(CONFIG_LIBTCG)) += generated-helpers.o
 
 
 $(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
diff --git a/translate-all.c b/translate-all.c
index 20262938bb..c952271651 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -1239,7 +1239,9 @@ static inline void tb_alloc_page(TranslationBlock *tb,
  *
  * Called with mmap_lock held for user-mode emulation.
  */
-static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
+void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
+                  tb_page_addr_t phys_page2);
+void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
                          tb_page_addr_t phys_page2)
 {
     uint32_t h;
-- 
2.11.0

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

* Re: [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg
  2017-01-21  8:45 [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg Alessandro Di Federico
                   ` (2 preceding siblings ...)
  2017-01-21  8:46 ` [Qemu-devel] [RFC PATCH 3/3] Introduce libtcg infrastructure Alessandro Di Federico
@ 2017-01-21  9:01 ` no-reply
  2017-02-07 11:40 ` Peter Maydell
  4 siblings, 0 replies; 15+ messages in thread
From: no-reply @ 2017-01-21  9:01 UTC (permalink / raw)
  To: ale+qemu; +Cc: famz, qemu-devel

Hi,

Your series seems to have some coding style problems. See output below for
more information:

Subject: [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg
Message-id: 20170121084600.5860-1-ale+qemu@clearmind.me
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
4be8b33 Introduce libtcg infrastructure
1264cba *-user targets object files decoupling
5130643 Factor out {linux,bsd}-user/qemu.h

=== OUTPUT BEGIN ===
Checking PATCH 1/3: Factor out {linux,bsd}-user/qemu.h...
ERROR: line over 90 characters
#439: FILE: qemu-user-common.h:15:
+                            (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0;

ERROR: code indent should never use tabs
#481: FILE: qemu-user-common.h:57:
+#define put_user(x, gaddr, target_type)^I^I^I^I^I\$

ERROR: code indent should never use tabs
#482: FILE: qemu-user-common.h:58:
+({^I^I^I^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#483: FILE: qemu-user-common.h:59:
+    abi_ulong __gaddr = (gaddr);^I^I^I^I^I\$

ERROR: code indent should never use tabs
#484: FILE: qemu-user-common.h:60:
+    target_type *__hptr;^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#485: FILE: qemu-user-common.h:61:
+    abi_long __ret = 0;^I^I^I^I^I^I^I\$

ERROR: do not use assignment in if condition
#486: FILE: qemu-user-common.h:62:
+    if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \

ERROR: braces {} are necessary for all arms of this statement
#486: FILE: qemu-user-common.h:62:
+    if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type), 0))) { \
[...]
+    } else								\
[...]

ERROR: code indent should never use tabs
#487: FILE: qemu-user-common.h:63:
+        __put_user((x), __hptr);^I^I^I^I\$

ERROR: code indent should never use tabs
#488: FILE: qemu-user-common.h:64:
+        unlock_user(__hptr, __gaddr, sizeof(target_type));^I^I\$

ERROR: code indent should never use tabs
#489: FILE: qemu-user-common.h:65:
+    } else^I^I^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#490: FILE: qemu-user-common.h:66:
+        __ret = -TARGET_EFAULT;^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#491: FILE: qemu-user-common.h:67:
+    __ret;^I^I^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#494: FILE: qemu-user-common.h:70:
+#define get_user(x, gaddr, target_type)^I^I^I^I^I\$

ERROR: code indent should never use tabs
#495: FILE: qemu-user-common.h:71:
+({^I^I^I^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#496: FILE: qemu-user-common.h:72:
+    abi_ulong __gaddr = (gaddr);^I^I^I^I^I\$

ERROR: code indent should never use tabs
#497: FILE: qemu-user-common.h:73:
+    target_type *__hptr;^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#498: FILE: qemu-user-common.h:74:
+    abi_long __ret = 0;^I^I^I^I^I^I^I\$

ERROR: do not use assignment in if condition
#499: FILE: qemu-user-common.h:75:
+    if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type), 1))) { \

ERROR: code indent should never use tabs
#500: FILE: qemu-user-common.h:76:
+        __get_user((x), __hptr);^I^I^I^I\$

ERROR: code indent should never use tabs
#501: FILE: qemu-user-common.h:77:
+        unlock_user(__hptr, __gaddr, 0);^I^I^I^I\$

ERROR: code indent should never use tabs
#502: FILE: qemu-user-common.h:78:
+    } else {^I^I^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#503: FILE: qemu-user-common.h:79:
+        /* avoid warning */^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#504: FILE: qemu-user-common.h:80:
+        (x) = 0;^I^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#505: FILE: qemu-user-common.h:81:
+        __ret = -TARGET_EFAULT;^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#506: FILE: qemu-user-common.h:82:
+    }^I^I^I^I^I^I^I^I^I\$

ERROR: code indent should never use tabs
#507: FILE: qemu-user-common.h:83:
+    __ret;^I^I^I^I^I^I^I^I\$

WARNING: line over 80 characters
#547: FILE: qemu-user-common.h:123:
+static inline void *lock_user(int type, abi_ulong guest_addr, long len, int copy)

ERROR: braces {} are necessary for all arms of this statement
#549: FILE: qemu-user-common.h:125:
+    if (!access_ok(type, guest_addr, len))
[...]

ERROR: braces {} are necessary for all arms of this statement
#555: FILE: qemu-user-common.h:131:
+        if (copy)
[...]
+        else
[...]

ERROR: braces {} are necessary for all arms of this statement
#574: FILE: qemu-user-common.h:150:
+    if (!host_ptr)
[...]

ERROR: braces {} are necessary for all arms of this statement
#576: FILE: qemu-user-common.h:152:
+    if (host_ptr == g2h(guest_addr))
[...]

ERROR: braces {} are necessary for all arms of this statement
#578: FILE: qemu-user-common.h:154:
+    if (len > 0)
[...]

ERROR: braces {} are necessary for all arms of this statement
#593: FILE: qemu-user-common.h:169:
+    if (len < 0)
[...]

ERROR: code indent should never use tabs
#599: FILE: qemu-user-common.h:175:
+#define lock_user_struct(type, host_ptr, guest_addr, copy)^I\$

ERROR: code indent should never use tabs
#601: FILE: qemu-user-common.h:177:
+#define unlock_user_struct(host_ptr, guest_addr, copy)^I^I\$

ERROR: Missing Signed-off-by: line(s)

total: 36 errors, 1 warnings, 575 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 2/3: *-user targets object files decoupling...
ERROR: spaces required around that '=' (ctx:VxV)
#109: FILE: target/arm/cpu.c:313:
+    for(i=0;i<16;i++) {
          ^

ERROR: space required after that ';' (ctx:VxV)
#109: FILE: target/arm/cpu.c:313:
+    for(i=0;i<16;i++) {
            ^

ERROR: spaces required around that '<' (ctx:VxV)
#109: FILE: target/arm/cpu.c:313:
+    for(i=0;i<16;i++) {
              ^

ERROR: space required after that ';' (ctx:VxV)
#109: FILE: target/arm/cpu.c:313:
+    for(i=0;i<16;i++) {
                 ^

ERROR: space required before the open parenthesis '('
#109: FILE: target/arm/cpu.c:313:
+    for(i=0;i<16;i++) {

ERROR: braces {} are necessary for all arms of this statement
#111: FILE: target/arm/cpu.c:315:
+        if ((i % 4) == 3)
[...]
+        else
[...]

ERROR: braces {} are necessary for all arms of this statement
#210: FILE: target/arm/cpu.h:1130:
+    if (host_bits & float_flag_invalid)
[...]

ERROR: braces {} are necessary for all arms of this statement
#212: FILE: target/arm/cpu.h:1132:
+    if (host_bits & float_flag_divbyzero)
[...]

ERROR: braces {} are necessary for all arms of this statement
#214: FILE: target/arm/cpu.h:1134:
+    if (host_bits & float_flag_overflow)
[...]

ERROR: braces {} are necessary for all arms of this statement
#216: FILE: target/arm/cpu.h:1136:
+    if (host_bits & (float_flag_underflow | float_flag_output_denormal))
[...]

ERROR: braces {} are necessary for all arms of this statement
#218: FILE: target/arm/cpu.h:1138:
+    if (host_bits & float_flag_inexact)
[...]

ERROR: braces {} are necessary for all arms of this statement
#220: FILE: target/arm/cpu.h:1140:
+    if (host_bits & float_flag_input_denormal)
[...]

ERROR: that open brace { should be on the previous line
#592: FILE: target/m68k/op_helper.c:159:
+    for (i = 0; i < 8; i++)
+      {

ERROR: space prohibited between function name and open parenthesis '('
#599: FILE: target/m68k/op_helper.c:166:
+    cpu_fprintf (f, "PC = %08x   ", env->pc);

ERROR: space prohibited between function name and open parenthesis '('
#604: FILE: target/m68k/op_helper.c:171:
+    cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);

ERROR: Missing Signed-off-by: line(s)

total: 16 errors, 0 warnings, 808 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 3/3: Introduce libtcg infrastructure...
ERROR: externs should be avoided in .c files
#529: FILE: libtcg/tcg.c:32:
+void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,

ERROR: externs should be avoided in .c files
#532: FILE: libtcg/tcg.c:35:
+void test(void);

ERROR: open brace '{' following function declarations go on the next line
#533: FILE: libtcg/tcg.c:36:
+void test(void) {

ERROR: do not use C99 // comments
#538: FILE: libtcg/tcg.c:41:
+  // cpu_init("");

ERROR: do not use C99 // comments
#549: FILE: libtcg/tcg.c:52:
+  // x = &target_mmap;

ERROR: externs should be avoided in .c files
#997: FILE: translate-all.c:1242:
+void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,

ERROR: Missing Signed-off-by: line(s)

total: 7 errors, 0 warnings, 689 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [RFC PATCH 3/3] Introduce libtcg infrastructure
  2017-01-21  8:46 ` [Qemu-devel] [RFC PATCH 3/3] Introduce libtcg infrastructure Alessandro Di Federico
@ 2017-01-24 10:08   ` Marc-André Lureau
  2017-01-25  7:37     ` Alessandro Di Federico
  0 siblings, 1 reply; 15+ messages in thread
From: Marc-André Lureau @ 2017-01-24 10:08 UTC (permalink / raw)
  To: Alessandro Di Federico, qemu-devel

Hi

On Sat, Jan 21, 2017 at 12:46 PM Alessandro Di Federico <
ale+qemu@clearmind.me> wrote:

> [This is a draft patch is for review purposes only]
>
> * Extend the build system to build libtcg-$arch.so dynamic libraries.
>

It would be nice to link qemu-user with it, it could be done later.

* Introduce --enable-libtcg and --disable-libtcg the *-libtcg target,
>   similar to *-linux-user and *-bsd-user, since it enables
>   CONFIG_USER_ONLY, but uses only the TCG frontends (in particular the
>   various /target/$arch/translate.c).
> * If there's at least a *-libtcg, compile everything as position
>   independent code.
>

why not limit it to libtcg code?


> * In case we're building libtcg, install the output binary in the
>   $PREFIX/lib directory instead of $PREFIX/bin.
>

If it's installed globally, I think we have to deal with versioning, common
prefix, and list of visible symbols.

* Reduce the number of object files linked into libtcg-$arch.so to the
>   minimum.
> * Install the tcg.h header to use libtcg.
> * Create libtcg/, with a draft function referencing the functions that
>   libtcg would use.
>

What's the plan with this tcg.c? Shouldn't the functions be stubs or
library user callbacks?

What is test() doing?

Please add a libtcg test under tests/ (even minimal, like a basic
translate/dump).


---
>  Makefile                                |  7 +++++
>  Makefile.target                         | 40 +++++++++++++++++++++---
>  configure                               | 20 ++++++++++++
>  crypto/Makefile.objs                    |  2 +-
>  default-configs/aarch64-libtcg.mak      |  0
>  default-configs/alpha-libtcg.mak        |  0
>  default-configs/arm-libtcg.mak          |  0
>  default-configs/armeb-libtcg.mak        |  0
>  default-configs/cris-libtcg.mak         |  0
>  default-configs/i386-libtcg.mak         |  0
>  default-configs/m68k-libtcg.mak         |  0
>  default-configs/microblaze-libtcg.mak   |  0
>  default-configs/microblazeel-libtcg.mak |  0
>  default-configs/mips-libtcg.mak         |  0
>  default-configs/mips64-libtcg.mak       |  0
>  default-configs/mips64el-libtcg.mak     |  0
>  default-configs/mipsel-libtcg.mak       |  0
>  default-configs/mipsn32-libtcg.mak      |  0
>  default-configs/mipsn32el-libtcg.mak    |  0
>  default-configs/or32-libtcg.mak         |  0
>  default-configs/ppc-libtcg.mak          |  1 +
>  default-configs/ppc64-libtcg.mak        |  1 +
>  default-configs/ppc64abi32-libtcg.mak   |  1 +
>  default-configs/ppc64le-libtcg.mak      |  1 +
>  default-configs/s390x-libtcg.mak        |  0
>  default-configs/sh4-libtcg.mak          |  0
>  default-configs/sh4eb-libtcg.mak        |  0
>  default-configs/sparc-libtcg.mak        |  0
>  default-configs/sparc32plus-libtcg.mak  |  0
>  default-configs/sparc64-libtcg.mak      |  0
>  default-configs/unicore32-libtcg.mak    |  0
>  default-configs/x86_64-libtcg.mak       |  0
>  hw/core/Makefile.objs                   |  5 ++-
>  include/exec/helper-gen.h               | 12 +++----
>  include/exec/helper-head.h              |  8 +++++
>  include/exec/helper-tcg.h               | 12 +++----
>  libtcg/Makefile.objs                    |  1 +
>  libtcg/qemu.h                           |  6 ++++
>  libtcg/tcg.c                            | 55
> +++++++++++++++++++++++++++++++++
>  libtcg/tcg.h                            |  0
>  target/alpha/Makefile.objs              |  9 ++++--
>  target/arm/Makefile.objs                | 22 +++++++++----
>  target/cris/Makefile.objs               | 10 ++++--
>  target/i386/Makefile.objs               | 14 ++++++---
>  target/lm32/Makefile.objs               | 12 +++++--
>  target/m68k/Makefile.objs               |  7 ++++-
>  target/microblaze/Makefile.objs         | 10 ++++--
>  target/mips/Makefile.objs               | 11 +++++--
>  target/moxie/Makefile.objs              |  8 ++++-
>  target/openrisc/Makefile.objs           | 11 +++++--
>  target/ppc/Makefile.objs                | 18 +++++------
>  target/ppc/translate.c                  |  2 ++
>  target/ppc/translate_init.c             |  8 +++++
>  target/s390x/Makefile.objs              | 16 +++++++---
>  target/sh4/Makefile.objs                |  8 ++++-
>  target/sparc/Makefile.objs              | 15 ++++++---
>  target/tilegx/Makefile.objs             |  7 ++++-
>  target/tricore/Makefile.objs            |  7 ++++-
>  target/unicore32/Makefile.objs          |  8 +++--
>  target/xtensa/Makefile.objs             | 14 ++++++---
>  trace/Makefile.objs                     |  2 +-
>  translate-all.c                         |  4 ++-
>  62 files changed, 322 insertions(+), 73 deletions(-)
>  create mode 100644 default-configs/aarch64-libtcg.mak
>  create mode 100644 default-configs/alpha-libtcg.mak
>  create mode 100644 default-configs/arm-libtcg.mak
>  create mode 100644 default-configs/armeb-libtcg.mak
>  create mode 100644 default-configs/cris-libtcg.mak
>  create mode 100644 default-configs/i386-libtcg.mak
>  create mode 100644 default-configs/m68k-libtcg.mak
>  create mode 100644 default-configs/microblaze-libtcg.mak
>  create mode 100644 default-configs/microblazeel-libtcg.mak
>  create mode 100644 default-configs/mips-libtcg.mak
>  create mode 100644 default-configs/mips64-libtcg.mak
>  create mode 100644 default-configs/mips64el-libtcg.mak
>  create mode 100644 default-configs/mipsel-libtcg.mak
>  create mode 100644 default-configs/mipsn32-libtcg.mak
>  create mode 100644 default-configs/mipsn32el-libtcg.mak
>  create mode 100644 default-configs/or32-libtcg.mak
>  create mode 100644 default-configs/ppc-libtcg.mak
>  create mode 100644 default-configs/ppc64-libtcg.mak
>  create mode 100644 default-configs/ppc64abi32-libtcg.mak
>  create mode 100644 default-configs/ppc64le-libtcg.mak
>  create mode 100644 default-configs/s390x-libtcg.mak
>  create mode 100644 default-configs/sh4-libtcg.mak
>  create mode 100644 default-configs/sh4eb-libtcg.mak
>  create mode 100644 default-configs/sparc-libtcg.mak
>  create mode 100644 default-configs/sparc32plus-libtcg.mak
>  create mode 100644 default-configs/sparc64-libtcg.mak
>  create mode 100644 default-configs/unicore32-libtcg.mak
>  create mode 100644 default-configs/x86_64-libtcg.mak
>  create mode 100644 libtcg/Makefile.objs
>  create mode 100644 libtcg/qemu.h
>  create mode 100644 libtcg/tcg.c
>  create mode 100644 libtcg/tcg.h
>
> diff --git a/Makefile b/Makefile
> index 1a8bfb225c..0e6925e04f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -26,7 +26,14 @@ endif
>
>  CONFIG_SOFTMMU := $(if $(filter %-softmmu,$(TARGET_DIRS)),y)
>  CONFIG_USER_ONLY := $(if $(filter %-user,$(TARGET_DIRS)),y)
> +CONFIG_LIBTCG := $(if $(filter %-libtcg,$(TARGET_DIRS)),y)
>  CONFIG_ALL=y
> +
> +# If there's at least a *-libtcg target we need to build everything with
> -fPIC
> +ifeq ($(CONFIG_LIBTCG),y)
> +QEMU_CFLAGS+=-fPIC
> +endif
> +
>  -include config-all-devices.mak
>  -include config-all-disas.mak
>
> diff --git a/Makefile.target b/Makefile.target
> index 8ae82cb311..6e3df541e0 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -15,10 +15,23 @@ QEMU_CFLAGS += -I..
> -I$(SRC_PATH)/target/$(TARGET_BASE_ARCH) -DNEED_CPU_H
>
>  QEMU_CFLAGS+=-I$(SRC_PATH)/include
>
> +# By default install in bindir
> +PROGS_INSTALL_DIR := $(bindir)
> +
>  ifdef CONFIG_USER_ONLY
> +ifdef CONFIG_LIBTCG
> +# libtcg
> +QEMU_PROG=libtcg-$(TARGET_NAME)$(DSOSUF)
> +QEMU_PROG_BUILD = $(QEMU_PROG)
> +QEMU_CFLAGS+=-fPIC
> +
> +# Change the install directory
> +PROGS_INSTALL_DIR := $(libdir)
>

okay, we may want to rename it to something like QEMU_BUILD perhaps


> +else
>  # user emulator name
>  QEMU_PROG=qemu-$(TARGET_NAME)
>  QEMU_PROG_BUILD = $(QEMU_PROG)
> +endif
>  else
>  # system emulator name
>  QEMU_PROG=qemu-system-$(TARGET_NAME)$(EXESUF)
> @@ -85,17 +98,20 @@ all: $(PROGS) stap
>
>  #########################################################
>  # cpu emulator library
> -obj-y = exec.o translate-all.o cpu-exec.o
> +obj-y = exec.o translate-all.o
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu-exec.o
> +obj-y += tcg-runtime.o
> +obj-y += fpu/softfloat.o
> +endif
>  obj-y += translate-common.o
>  obj-y += cpu-exec-common.o
>  obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
>  obj-$(CONFIG_TCG_INTERPRETER) += tci.o
>  obj-y += tcg/tcg-common.o
>  obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
> -obj-y += fpu/softfloat.o
>  obj-y += target/$(TARGET_BASE_ARCH)/
>  obj-y += disas.o
> -obj-y += tcg-runtime.o
>  obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
>  obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
>
> @@ -133,6 +149,19 @@ obj-y += gdbstub.o user-exec.o
>  endif #CONFIG_BSD_USER
>
>  #########################################################
> +# libtcg target
> +
> +ifdef CONFIG_LIBTCG
> +
> +QEMU_CFLAGS+=-I$(SRC_PATH)/libtcg
> +
> +obj-y += libtcg/
> +
> +QEMU_LDFLAGS+=-shared
> +
> +endif #CONFIG_LIBTCG
> +
> +#########################################################
>  # System emulator target
>  ifdef CONFIG_SOFTMMU
>  obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o
> @@ -220,8 +249,11 @@ ifdef CONFIG_TRACE_SYSTEMTAP
>  endif
>
>  install: all
> +ifdef CONFIG_LIBTINYCODE
> +       $(INSTALL_DATA) $(SRC_PATH)/tcg/tcg-opc.h $(SRC_PATH)/libtcg/tcg.h
> "$(DESTDIR)$(includedir)"
> +endif
>

LIBTINYCODE/LIBTCG?


>  ifneq ($(PROGS),)
> -       $(call install-prog,$(PROGS),$(DESTDIR)$(bindir))
> +       $(call install-prog,$(PROGS),$(DESTDIR)$(PROGS_INSTALL_DIR))
>  endif
>  ifdef CONFIG_TRACE_SYSTEMTAP
>         $(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)/../systemtap/tapset"
> diff --git a/configure b/configure
> index 86f5214dd0..352a74cec8 100755
> --- a/configure
> +++ b/configure
> @@ -265,6 +265,7 @@ cocoa="no"
>  softmmu="yes"
>  linux_user="no"
>  bsd_user="no"
> +libtcg="no"
>  aix="no"
>  blobs="yes"
>  pkgversion=""
> @@ -676,6 +677,7 @@ Haiku)
>    audio_possible_drivers="oss alsa sdl pa"
>    linux="yes"
>    linux_user="yes"
> +  libtcg="yes"
>    kvm="yes"
>    vhost_net="yes"
>    vhost_scsi="yes"
> @@ -969,6 +971,10 @@ for opt do
>    ;;
>    --enable-bsd-user) bsd_user="yes"
>    ;;
> +  --disable-libtcg) libtcg="no"
> +  ;;
> +  --enable-libtcg) libtcg="yes"
> +  ;;
>    --enable-pie) pie="yes"
>    ;;
>    --disable-pie) pie="no"
> @@ -1245,6 +1251,7 @@ EXTRA_CFLAGS="$CPU_CFLAGS $EXTRA_CFLAGS"
>  if [ "$ARCH" = "unknown" ]; then
>    bsd_user="no"
>    linux_user="no"
> +  libtcg="no"
>  fi
>
>  default_target_list=""
> @@ -1260,6 +1267,9 @@ fi
>  if [ "$bsd_user" = "yes" ]; then
>      mak_wilds="${mak_wilds} $source_path/default-configs/*-bsd-user.mak"
>  fi
> +if [ "$libtcg" = "yes" ]; then
> +    mak_wilds="${mak_wilds} $source_path/default-configs/*-libtcg.mak"
> +fi
>
>  for config in $mak_wilds; do
>      default_target_list="${default_target_list} $(basename "$config"
> .mak)"
> @@ -1401,6 +1411,7 @@ disabled with --disable-FEATURE, default is enabled
> if available:
>    tcmalloc        tcmalloc support
>    jemalloc        jemalloc support
>    replication     replication support
> +  libtcg          standalone TCG library
>
>  NOTE: The object files are built at the place where configure is launched
>  EOF
> @@ -5112,6 +5123,7 @@ echo "tcmalloc support  $tcmalloc"
>  echo "jemalloc support  $jemalloc"
>  echo "avx2 optimization $avx2_opt"
>  echo "replication support $replication"
> +echo "libtcg enabled    $libtcg"
>
>  if test "$sdl_too_old" = "yes"; then
>  echo "-> Your SDL version is too old - please upgrade to have SDL support"
> @@ -5853,6 +5865,7 @@ target_softmmu="no"
>  target_user_only="no"
>  target_linux_user="no"
>  target_bsd_user="no"
> +target_libtcg="no"
>  case "$target" in
>    ${target_name}-softmmu)
>      target_softmmu="yes"
> @@ -5871,6 +5884,10 @@ case "$target" in
>      target_user_only="yes"
>      target_bsd_user="yes"
>      ;;
> +  ${target_name}-libtcg)
> +    target_user_only="yes"
> +    target_libtcg="yes"
> +    ;;
>    *)
>      error_exit "Target '$target' not recognised"
>      exit 1
> @@ -6063,6 +6080,9 @@ fi
>  if test "$target_linux_user" = "yes" ; then
>    echo "CONFIG_LINUX_USER=y" >> $config_target_mak
>  fi
> +if test "$target_libtcg" = "yes" ; then
> +  echo "CONFIG_LIBTCG=y" >> $config_target_mak
> +fi
>  list=""
>  if test ! -z "$gdb_xml_files" ; then
>    for x in $gdb_xml_files; do
> diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
> index 1f749f2087..2f654db9af 100644
> --- a/crypto/Makefile.objs
> +++ b/crypto/Makefile.objs
> @@ -7,7 +7,7 @@ crypto-obj-y += hmac.o
>  crypto-obj-$(CONFIG_NETTLE) += hmac-nettle.o
>  crypto-obj-$(CONFIG_GCRYPT_HMAC) += hmac-gcrypt.o
>  crypto-obj-$(if $(CONFIG_NETTLE),n,$(if $(CONFIG_GCRYPT_HMAC),n,y)) +=
> hmac-glib.o
> -crypto-obj-y += aes.o
> +crypto-obj-$(call lnot,$(CONFIG_LIBTCG)) += aes.o
>

why that change?


>  crypto-obj-y += desrfb.o
>  crypto-obj-y += cipher.o
>  crypto-obj-y += tlscreds.o
> diff --git a/default-configs/aarch64-libtcg.mak
> b/default-configs/aarch64-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/alpha-libtcg.mak
> b/default-configs/alpha-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/arm-libtcg.mak
> b/default-configs/arm-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/armeb-libtcg.mak
> b/default-configs/armeb-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/cris-libtcg.mak
> b/default-configs/cris-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/i386-libtcg.mak
> b/default-configs/i386-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/m68k-libtcg.mak
> b/default-configs/m68k-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/microblaze-libtcg.mak
> b/default-configs/microblaze-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/microblazeel-libtcg.mak
> b/default-configs/microblazeel-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/mips-libtcg.mak
> b/default-configs/mips-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/mips64-libtcg.mak
> b/default-configs/mips64-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/mips64el-libtcg.mak
> b/default-configs/mips64el-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/mipsel-libtcg.mak
> b/default-configs/mipsel-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/mipsn32-libtcg.mak
> b/default-configs/mipsn32-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/mipsn32el-libtcg.mak
> b/default-configs/mipsn32el-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/or32-libtcg.mak
> b/default-configs/or32-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/ppc-libtcg.mak
> b/default-configs/ppc-libtcg.mak
> new file mode 100644
> index 0000000000..7235c56d55
> --- /dev/null
> +++ b/default-configs/ppc-libtcg.mak
> @@ -0,0 +1 @@
> +CONFIG_LIBDECNUMBER=y
> diff --git a/default-configs/ppc64-libtcg.mak
> b/default-configs/ppc64-libtcg.mak
> new file mode 100644
> index 0000000000..7235c56d55
> --- /dev/null
> +++ b/default-configs/ppc64-libtcg.mak
> @@ -0,0 +1 @@
> +CONFIG_LIBDECNUMBER=y
> diff --git a/default-configs/ppc64abi32-libtcg.mak
> b/default-configs/ppc64abi32-libtcg.mak
> new file mode 100644
> index 0000000000..7235c56d55
> --- /dev/null
> +++ b/default-configs/ppc64abi32-libtcg.mak
> @@ -0,0 +1 @@
> +CONFIG_LIBDECNUMBER=y
> diff --git a/default-configs/ppc64le-libtcg.mak
> b/default-configs/ppc64le-libtcg.mak
> new file mode 100644
> index 0000000000..7235c56d55
> --- /dev/null
> +++ b/default-configs/ppc64le-libtcg.mak
> @@ -0,0 +1 @@
> +CONFIG_LIBDECNUMBER=y
> diff --git a/default-configs/s390x-libtcg.mak
> b/default-configs/s390x-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/sh4-libtcg.mak
> b/default-configs/sh4-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/sh4eb-libtcg.mak
> b/default-configs/sh4eb-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/sparc-libtcg.mak
> b/default-configs/sparc-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/sparc32plus-libtcg.mak
> b/default-configs/sparc32plus-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/sparc64-libtcg.mak
> b/default-configs/sparc64-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/unicore32-libtcg.mak
> b/default-configs/unicore32-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/default-configs/x86_64-libtcg.mak
> b/default-configs/x86_64-libtcg.mak
> new file mode 100644
> index 0000000000..e69de29bb2
> diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
> index a4c94e522d..a58d7c404c 100644
> --- a/hw/core/Makefile.objs
> +++ b/hw/core/Makefile.objs
> @@ -1,11 +1,14 @@
>  # core qdev-related obj files, also used by *-user:
> -common-obj-y += qdev.o qdev-properties.o
> +common-obj-y += qdev-properties.o
> +#ifndef CONFIG_LIBTCG
> +common-obj-y += qdev.o
>  common-obj-y += bus.o
>  common-obj-y += fw-path-provider.o
>  # irq.o needed for qdev GPIO handling:
>  common-obj-y += irq.o
>  common-obj-y += hotplug.o
>  obj-y += nmi.o
> +#endif
>
>  common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
>  common-obj-$(CONFIG_XILINX_AXI) += stream.o
> diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
> index 8239ffc77c..ac290180b3 100644
> --- a/include/exec/helper-gen.h
> +++ b/include/exec/helper-gen.h
> @@ -9,7 +9,7 @@
>  #define DEF_HELPER_FLAGS_0(name, flags, ret)                            \
>  static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret))        \
>  {                                                                       \
> -  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 0, NULL);       \
> +  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 0, NULL);   \
>  }
>
>  #define DEF_HELPER_FLAGS_1(name, flags, ret, t1)                        \
> @@ -17,7 +17,7 @@ static inline void glue(gen_helper_,
> name)(dh_retvar_decl(ret)          \
>      dh_arg_decl(t1, 1))                                                 \
>  {                                                                       \
>    TCGArg args[1] = { dh_arg(t1, 1) };                                   \
> -  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 1, args);       \
> +  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 1, args);   \
>  }
>
>  #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2)                    \
> @@ -25,7 +25,7 @@ static inline void glue(gen_helper_,
> name)(dh_retvar_decl(ret)          \
>      dh_arg_decl(t1, 1), dh_arg_decl(t2, 2))                             \
>  {                                                                       \
>    TCGArg args[2] = { dh_arg(t1, 1), dh_arg(t2, 2) };                    \
> -  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 2, args);       \
> +  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 2, args);   \
>  }
>
>  #define DEF_HELPER_FLAGS_3(name, flags, ret, t1, t2, t3)                \
> @@ -33,7 +33,7 @@ static inline void glue(gen_helper_,
> name)(dh_retvar_decl(ret)          \
>      dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3))         \
>  {                                                                       \
>    TCGArg args[3] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3) };     \
> -  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 3, args);       \
> +  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 3, args);   \
>  }
>
>  #define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4)            \
> @@ -43,7 +43,7 @@ static inline void glue(gen_helper_,
> name)(dh_retvar_decl(ret)          \
>  {                                                                       \
>    TCGArg args[4] = { dh_arg(t1, 1), dh_arg(t2, 2),                      \
>                       dh_arg(t3, 3), dh_arg(t4, 4) };                    \
> -  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 4, args);       \
> +  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 4, args);   \
>  }
>
>  #define DEF_HELPER_FLAGS_5(name, flags, ret, t1, t2, t3, t4, t5)        \
> @@ -53,7 +53,7 @@ static inline void glue(gen_helper_,
> name)(dh_retvar_decl(ret)          \
>  {                                                                       \
>    TCGArg args[5] = { dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3),       \
>                       dh_arg(t4, 4), dh_arg(t5, 5) };                    \
> -  tcg_gen_callN(&tcg_ctx, HELPER(name), dh_retvar(ret), 5, args);       \
> +  tcg_gen_callN(&tcg_ctx, HELPER_REF(name), dh_retvar(ret), 5, args);   \
>  }
>
>  #include "helper.h"
> diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
> index 1cfc43b9ff..fa68de92db 100644
> --- a/include/exec/helper-head.h
> +++ b/include/exec/helper-head.h
> @@ -20,6 +20,14 @@
>
>  #define HELPER(name) glue(helper_, name)
>
> +/* In libtcg we don't want helpers, therefore we leave these fields empty
> so
> +   that we don't needlessly introduce a dependency towards the helper. */
> +#ifdef CONFIG_LIBTCG
> +# define HELPER_REF(helper) (0)
> +#else
> +# define HELPER_REF(helper) (HELPER(helper))
> +#endif
> +
>  #define GET_TCGV_i32 GET_TCGV_I32
>  #define GET_TCGV_i64 GET_TCGV_I64
>  #define GET_TCGV_ptr GET_TCGV_PTR
> diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
> index bb9287727c..ebc7b45d1a 100644
> --- a/include/exec/helper-tcg.h
> +++ b/include/exec/helper-tcg.h
> @@ -7,30 +7,30 @@
>  #include "exec/helper-head.h"
>
>  #define DEF_HELPER_FLAGS_0(NAME, FLAGS, ret) \
> -  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
> +  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
>      .sizemask = dh_sizemask(ret, 0) },
>
>  #define DEF_HELPER_FLAGS_1(NAME, FLAGS, ret, t1) \
> -  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
> +  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
>      .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) },
>
>  #define DEF_HELPER_FLAGS_2(NAME, FLAGS, ret, t1, t2) \
> -  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
> +  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
>      .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
>      | dh_sizemask(t2, 2) },
>
>  #define DEF_HELPER_FLAGS_3(NAME, FLAGS, ret, t1, t2, t3) \
> -  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
> +  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
>      .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
>      | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) },
>
>  #define DEF_HELPER_FLAGS_4(NAME, FLAGS, ret, t1, t2, t3, t4) \
> -  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
> +  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
>      .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
>      | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) },
>
>  #define DEF_HELPER_FLAGS_5(NAME, FLAGS, ret, t1, t2, t3, t4, t5) \
> -  { .func = HELPER(NAME), .name = #NAME, .flags = FLAGS, \
> +  { .func = HELPER_REF(NAME), .name = #NAME, .flags = FLAGS, \
>      .sizemask = dh_sizemask(ret, 0) | dh_sizemask(t1, 1) \
>      | dh_sizemask(t2, 2) | dh_sizemask(t3, 3) | dh_sizemask(t4, 4) \
>      | dh_sizemask(t5, 5) },
> diff --git a/libtcg/Makefile.objs b/libtcg/Makefile.objs
> new file mode 100644
> index 0000000000..a1e7720ce3
> --- /dev/null
> +++ b/libtcg/Makefile.objs
> @@ -0,0 +1 @@
> +obj-y += tcg.o
> diff --git a/libtcg/qemu.h b/libtcg/qemu.h
> new file mode 100644
> index 0000000000..cc2131493a
> --- /dev/null
> +++ b/libtcg/qemu.h
> @@ -0,0 +1,6 @@
> +#ifndef QEMU_H
> +#define QEMU_H
> +
> +#include "qemu-user-common.h"
> +
> +#endif /* QEMU_H */
> diff --git a/libtcg/tcg.c b/libtcg/tcg.c
> new file mode 100644
> index 0000000000..f1ce37c77b
> --- /dev/null
> +++ b/libtcg/tcg.c
> @@ -0,0 +1,55 @@
> +#include "qemu/osdep.h"
> +#include "qemu.h"
> +#include "exec/exec-all.h"
> +#include "qemu/cutils.h"
> +
> +unsigned long guest_base;
> +int singlestep;
> +
> +void mmap_lock(void)
> +{
> +    abort();
> +}
> +
> +void mmap_unlock(void)
> +{
> +    abort();
> +}
> +
> +bool qemu_cpu_is_self(CPUState *cpu)
> +{
> +    abort();
> +}
> +
> +void qemu_cpu_kick(CPUState *cpu)
> +{
> +    abort();
> +}
> +
> +#include "disas/disas.h"
> +#include "cpu.h"
> +
> +void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
> +                  tb_page_addr_t phys_page2);
> +
> +void test(void);
> +void test(void) {
> +  void *x = target_disas;
> +  x = &guest_base;
> +  x = &tcg_exec_init;
> +  x = &module_call_init;
> +  // cpu_init("");
> +#ifdef TARGET_X86_64
> +  X86_CPU(cpu_generic_init(TYPE_X86_CPU, ""));
> +#endif
> +  x = &cpu_reset;
> +  x = &qemu_set_log;
> +  x = &g_hash_table_foreach;
> +  x = &get_page_addr_code;
> +  x = &tcg_func_start;
> +  x = &gen_intermediate_code;
> +  x = &tb_link_page;
> +  // x = &target_mmap;
> +  x = &cpu_get_tb_cpu_state;
> +  (void) x;
> +}
> diff --git a/libtcg/tcg.h b/libtcg/tcg.h
> new file mode 100644
> index 0000000000..e69de29bb2
>

What is this empty file for?


> diff --git a/target/alpha/Makefile.objs b/target/alpha/Makefile.objs
> index 63664629f6..5ee1bacf27 100644
> --- a/target/alpha/Makefile.objs
> +++ b/target/alpha/Makefile.objs
> @@ -1,4 +1,9 @@
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += machine.o
> -obj-y += translate.o helper.o cpu.o
> -obj-y += int_helper.o fpu_helper.o vax_helper.o sys_helper.o mem_helper.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o int_helper.o fpu_helper.o vax_helper.o sys_helper.o
> mem_helper.o
>  obj-y += gdbstub.o
> +endif
> diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
> index 847fb52ee0..75a6fc637a 100644
> --- a/target/arm/Makefile.objs
> +++ b/target/arm/Makefile.objs
> @@ -1,12 +1,22 @@
> -obj-y += arm-semi.o
> +obj-y += translate.o
> +obj-$(TARGET_AARCH64) += translate-a64.o
> +
>  obj-$(CONFIG_SOFTMMU) += machine.o psci.o arch_dump.o monitor.o
> +obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
>  obj-$(CONFIG_KVM) += kvm.o
>  obj-$(call land,$(CONFIG_KVM),$(call lnot,$(TARGET_AARCH64))) += kvm32.o
>  obj-$(call land,$(CONFIG_KVM),$(TARGET_AARCH64)) += kvm64.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-$(TARGET_AARCH64) += cpu64.o
> +
> +obj-y += helper.o op_helper.o neon_helper.o iwmmxt_helper.o
> crypto_helper.o
> +obj-$(TARGET_AARCH64) += helper-a64.o
> +
> +obj-y += arm-semi.o
>  obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
> -obj-y += translate.o op_helper.o helper.o cpu.o
> -obj-y += neon_helper.o iwmmxt_helper.o
> +
>  obj-y += gdbstub.o
> -obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
> -obj-y += crypto_helper.o
> -obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
> +obj-$(TARGET_AARCH64) += gdbstub64.o
> +endif
> diff --git a/target/cris/Makefile.objs b/target/cris/Makefile.objs
> index 7779227fc4..1270edca79 100644
> --- a/target/cris/Makefile.objs
> +++ b/target/cris/Makefile.objs
> @@ -1,3 +1,9 @@
> -obj-y += translate.o op_helper.o helper.o cpu.o
> -obj-y += gdbstub.o
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += mmu.o machine.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o op_helper.o
> +obj-y += gdbstub.o
> +endif
> diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs
> index b223d7932b..6653f1c9dd 100644
> --- a/target/i386/Makefile.objs
> +++ b/target/i386/Makefile.objs
> @@ -1,7 +1,13 @@
> -obj-y += translate.o helper.o cpu.o bpt_helper.o
> -obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o
> -obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o mpx_helper.o
> -obj-y += gdbstub.o
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
> monitor.o
>  obj-$(CONFIG_KVM) += kvm.o hyperv.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o bpt_helper.o int_helper.o misc_helper.o mem_helper.o \
> +         excp_helper.o fpu_helper.o cc_helper.o svm_helper.o smm_helper.o
> \
> +         seg_helper.o mpx_helper.o
>  obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
> +obj-y += gdbstub.o
> +endif
> diff --git a/target/lm32/Makefile.objs b/target/lm32/Makefile.objs
> index c3e1bd6bd6..737a6b252d 100644
> --- a/target/lm32/Makefile.objs
> +++ b/target/lm32/Makefile.objs
> @@ -1,4 +1,10 @@
> -obj-y += translate.o op_helper.o helper.o cpu.o
> -obj-y += gdbstub.o
> -obj-y += lm32-semi.o
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += machine.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o op_helper.o
> +obj-y += lm32-semi.o
> +obj-y += gdbstub.o
> +endif
> diff --git a/target/m68k/Makefile.objs b/target/m68k/Makefile.objs
> index 02cf616a78..9f1bd5de59 100644
> --- a/target/m68k/Makefile.objs
> +++ b/target/m68k/Makefile.objs
> @@ -1,3 +1,8 @@
> +obj-y += translate.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o op_helper.o
>  obj-y += m68k-semi.o
> -obj-y += translate.o op_helper.o helper.o cpu.o
>  obj-y += gdbstub.o
> +endif
> diff --git a/target/microblaze/Makefile.objs
> b/target/microblaze/Makefile.objs
> index f3d7b44c89..898ddbcb0e 100644
> --- a/target/microblaze/Makefile.objs
> +++ b/target/microblaze/Makefile.objs
> @@ -1,3 +1,9 @@
> -obj-y += translate.o op_helper.o helper.o cpu.o
> -obj-y += gdbstub.o
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += mmu.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o op_helper.o
> +obj-y += gdbstub.o
> +endif
> diff --git a/target/mips/Makefile.objs b/target/mips/Makefile.objs
> index bc5ed8511f..d7eae8b9c5 100644
> --- a/target/mips/Makefile.objs
> +++ b/target/mips/Makefile.objs
> @@ -1,4 +1,11 @@
> -obj-y += translate.o dsp_helper.o op_helper.o lmi_helper.o helper.o cpu.o
> -obj-y += gdbstub.o msa_helper.o mips-semi.o
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += machine.o
>  obj-$(CONFIG_KVM) += kvm.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += dsp_helper.o op_helper.o lmi_helper.o helper.o msa_helper.o
> +obj-y += mips-semi.o
> +obj-y += gdbstub.o
> +endif
> diff --git a/target/moxie/Makefile.objs b/target/moxie/Makefile.objs
> index 6381d4d636..5afe63852d 100644
> --- a/target/moxie/Makefile.objs
> +++ b/target/moxie/Makefile.objs
> @@ -1,2 +1,8 @@
> -obj-y += translate.o helper.o machine.o cpu.o machine.o
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += mmu.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o machine.o
> +obj-y += helper.o
> +endif
> diff --git a/target/openrisc/Makefile.objs b/target/openrisc/Makefile.objs
> index 397d01650e..ea466e9224 100644
> --- a/target/openrisc/Makefile.objs
> +++ b/target/openrisc/Makefile.objs
> @@ -1,5 +1,10 @@
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += machine.o
> -obj-y += cpu.o exception.o interrupt.o mmu.o translate.o
> -obj-y += exception_helper.o fpu_helper.o int_helper.o \
> -         interrupt_helper.o mmu_helper.o sys_helper.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o exception.o interrupt.o mmu.o
> +obj-y += exception_helper.o fpu_helper.o int_helper.o interrupt_helper.o \
> +         mmu_helper.o sys_helper.o
>  obj-y += gdbstub.o
> +endif
> diff --git a/target/ppc/Makefile.objs b/target/ppc/Makefile.objs
> index e667e69701..0b179acd0e 100644
> --- a/target/ppc/Makefile.objs
> +++ b/target/ppc/Makefile.objs
> @@ -1,17 +1,17 @@
> -obj-y += cpu-models.o
>  obj-y += translate.o
> +obj-y += cpu-models.o
> +
>  ifeq ($(CONFIG_SOFTMMU),y)
> -obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o
> +obj-y += machine.o mmu-hash32.o monitor.o
> +obj-y += mmu_helper.o
>  obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o
>  endif
> +
>  obj-$(CONFIG_KVM) += kvm.o
>  obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
> -obj-y += dfp_helper.o
> -obj-y += excp_helper.o
> -obj-y += fpu_helper.o
> -obj-y += int_helper.o
> -obj-y += timebase_helper.o
> -obj-y += misc_helper.o
> -obj-y += mem_helper.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += int_helper.o dfp_helper.o timebase_helper.o mem_helper.o
> misc_helper.o fpu_helper.o excp_helper.o
>  obj-$(CONFIG_USER_ONLY) += user_only_helper.o
>  obj-y += gdbstub.o
> +endif
> diff --git a/target/ppc/translate.c b/target/ppc/translate.c
> index 59e9552d2b..bc9363e9e2 100644
> --- a/target/ppc/translate.c
> +++ b/target/ppc/translate.c
> @@ -6766,6 +6766,7 @@ GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E,
> 0x1F, 0x03FFF800, \
>  #include "helper_regs.h"
>  #include "translate_init.c"
>
> +#ifndef CONFIG_LIBTCG
>
>  /*****************************************************************************/
>  /* Misc PowerPC helpers */
>  void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function
> cpu_fprintf,
> @@ -6932,6 +6933,7 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f,
> fprintf_function cpu_fprintf,
>  #undef RGPL
>  #undef RFPL
>  }
> +#endif
>
>  void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
>                               fprintf_function cpu_fprintf, int flags)
> diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
> index 74e3339bd8..7919ebe700 100644
> --- a/target/ppc/translate_init.c
> +++ b/target/ppc/translate_init.c
> @@ -9453,6 +9453,7 @@ static void dump_ppc_insns (CPUPPCState *env)
>  }
>  #endif
>
> +#ifndef CONFIG_LIBTCG
>  static bool avr_need_swap(CPUPPCState *env)
>  {
>  #ifdef HOST_WORDS_BIGENDIAN
> @@ -9638,6 +9639,7 @@ static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t
> *mem_buf, int n)
>      }
>      return 0;
>  }
> +#endif
>
>  static int ppc_fixup_cpu(PowerPCCPU *cpu)
>  {
> @@ -9740,6 +9742,7 @@ static void ppc_cpu_realizefn(DeviceState *dev,
> Error **errp)
>      }
>      init_ppc_proc(cpu);
>
> +#ifndef CONFIG_LIBTCG
>      if (pcc->insns_flags & PPC_FLOAT) {
>          gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
>                                   33, "power-fpu.xml", 0);
> @@ -9756,6 +9759,7 @@ static void ppc_cpu_realizefn(DeviceState *dev,
> Error **errp)
>          gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
>                                   32, "power-vsx.xml", 0);
>      }
> +#endif
>
>      qemu_init_vcpu(cs);
>
> @@ -10564,11 +10568,14 @@ static void ppc_cpu_class_init(ObjectClass *oc,
> void *data)
>
>      cc->class_by_name = ppc_cpu_class_by_name;
>      cc->has_work = ppc_cpu_has_work;
> +#ifndef CONFIG_LIBTCG
>      cc->do_interrupt = ppc_cpu_do_interrupt;
>      cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
>      cc->dump_state = ppc_cpu_dump_state;
> +#endif
>      cc->dump_statistics = ppc_cpu_dump_statistics;
>      cc->set_pc = ppc_cpu_set_pc;
> +#ifndef CONFIG_LIBTCG
>      cc->gdb_read_register = ppc_cpu_gdb_read_register;
>      cc->gdb_write_register = ppc_cpu_gdb_write_register;
>  #ifdef CONFIG_USER_ONLY
> @@ -10580,6 +10587,7 @@ static void ppc_cpu_class_init(ObjectClass *oc,
> void *data)
>      cc->write_elf64_note = ppc64_cpu_write_elf64_note;
>  #endif
>  #endif
> +#endif
>      cc->cpu_exec_enter = ppc_cpu_exec_enter;
>
>      cc->gdb_num_core_regs = 71;
> diff --git a/target/s390x/Makefile.objs b/target/s390x/Makefile.objs
> index c573633bd1..97986fca4e 100644
> --- a/target/s390x/Makefile.objs
> +++ b/target/s390x/Makefile.objs
> @@ -1,9 +1,17 @@
> -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-y += gdbstub.o cpu_models.o cpu_features.o
> -obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o mmu_helper.o
> +obj-y += translate.o
> +
> +obj-$(CONFIG_SOFTMMU) += machine.o ioinst.o arch_dump.o
> +obj-$(CONFIG_SOFTMMU) += mmu_helper.o
>  obj-$(CONFIG_KVM) += kvm.o
>
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o interrupt.o
> +obj-y += helper.o int_helper.o fpu_helper.o cc_helper.o mem_helper.o \
> +         misc_helper.o
> +obj-y += cpu_models.o cpu_features.o
> +obj-y += gdbstub.o
> +endif
> +
>  # build and run feature list generator
>  feat-src = $(SRC_PATH)/target/$(TARGET_BASE_ARCH)/
>  feat-dst = $(BUILD_DIR)/$(TARGET_DIR)
> diff --git a/target/sh4/Makefile.objs b/target/sh4/Makefile.objs
> index 2c25d96e65..cfbc95fd46 100644
> --- a/target/sh4/Makefile.objs
> +++ b/target/sh4/Makefile.objs
> @@ -1,3 +1,9 @@
> -obj-y += translate.o op_helper.o helper.o cpu.o
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += monitor.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o op_helper.o
>  obj-y += gdbstub.o
> +endif
> diff --git a/target/sparc/Makefile.objs b/target/sparc/Makefile.objs
> index ec905698c5..fa824d541c 100644
> --- a/target/sparc/Makefile.objs
> +++ b/target/sparc/Makefile.objs
> @@ -1,7 +1,14 @@
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += machine.o monitor.o
> -obj-y += translate.o helper.o cpu.o
> -obj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +
> +obj-y += helper.o 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-$(TARGET_SPARC64) += int64_helper.o vis_helper.o
> +
>  obj-y += gdbstub.o
> +endif
> diff --git a/target/tilegx/Makefile.objs b/target/tilegx/Makefile.objs
> index 0db778f407..ddf2e41c51 100644
> --- a/target/tilegx/Makefile.objs
> +++ b/target/tilegx/Makefile.objs
> @@ -1 +1,6 @@
> -obj-y += cpu.o translate.o helper.o simd_helper.o
> +obj-y += translate.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o simd_helper.o
> +endif
> diff --git a/target/tricore/Makefile.objs b/target/tricore/Makefile.objs
> index 7a05670718..9b12c51db0 100644
> --- a/target/tricore/Makefile.objs
> +++ b/target/tricore/Makefile.objs
> @@ -1 +1,6 @@
> -obj-y += translate.o helper.o cpu.o op_helper.o fpu_helper.o
> +obj-y += translate.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o op_helper.o fpu_helper.o
> +endif
> diff --git a/target/unicore32/Makefile.objs
> b/target/unicore32/Makefile.objs
> index 6b41b1e9ef..c936429f94 100644
> --- a/target/unicore32/Makefile.objs
> +++ b/target/unicore32/Makefile.objs
> @@ -1,4 +1,8 @@
> -obj-y += translate.o op_helper.o helper.o cpu.o
> -obj-y += ucf64_helper.o
> +obj-y += translate.o
>
>  obj-$(CONFIG_SOFTMMU) += softmmu.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o op_helper.o ucf64_helper.o
> +endif
> diff --git a/target/xtensa/Makefile.objs b/target/xtensa/Makefile.objs
> index 481de91973..393a12caea 100644
> --- a/target/xtensa/Makefile.objs
> +++ b/target/xtensa/Makefile.objs
> @@ -1,7 +1,11 @@
> -obj-y += xtensa-semi.o
> -obj-y += core-dc232b.o
> -obj-y += core-dc233c.o
> -obj-y += core-fsf.o
> +obj-y += translate.o
> +
>  obj-$(CONFIG_SOFTMMU) += monitor.o
> -obj-y += translate.o op_helper.o helper.o cpu.o
> +
> +ifndef CONFIG_LIBTCG
> +obj-y += cpu.o
> +obj-y += helper.o op_helper.o
> +obj-y += xtensa-semi.o
> +obj-y += core-dc232b.o core-dc233c.o core-fsf.o
>  obj-y += gdbstub.o
> +endif
> diff --git a/trace/Makefile.objs b/trace/Makefile.objs
> index 1e1ce7479d..a6874d769b 100644
> --- a/trace/Makefile.objs
> +++ b/trace/Makefile.objs
> @@ -118,7 +118,7 @@ $(obj)/generated-helpers.c-timestamp:
> $(BUILD_DIR)/trace-events-all $(BUILD_DIR)
>
>  $(obj)/generated-helpers.o: $(obj)/generated-helpers.c
>
> -target-obj-y += generated-helpers.o
> +target-obj-$(call lnot,$(CONFIG_LIBTCG)) += generated-helpers.o
>
>
>  $(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
> diff --git a/translate-all.c b/translate-all.c
> index 20262938bb..c952271651 100644
> --- a/translate-all.c
> +++ b/translate-all.c
> @@ -1239,7 +1239,9 @@ static inline void tb_alloc_page(TranslationBlock
> *tb,
>   *
>   * Called with mmap_lock held for user-mode emulation.
>   */
> -static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
> +void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
> +                  tb_page_addr_t phys_page2);
> +void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
>                           tb_page_addr_t phys_page2)
>  {
>      uint32_t h;
> --
> 2.11.0
>
>
> --
Marc-André Lureau

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

* Re: [Qemu-devel] [RFC PATCH 2/3] *-user targets object files decoupling
  2017-01-21  8:45 ` [Qemu-devel] [RFC PATCH 2/3] *-user targets object files decoupling Alessandro Di Federico
@ 2017-01-24 10:09   ` Marc-André Lureau
  2017-01-25  7:38     ` Alessandro Di Federico
  0 siblings, 1 reply; 15+ messages in thread
From: Marc-André Lureau @ 2017-01-24 10:09 UTC (permalink / raw)
  To: Alessandro Di Federico, qemu-devel

On Sat, Jan 21, 2017 at 12:49 PM Alessandro Di Federico <
ale+qemu@clearmind.me> wrote:

Move some functions around in target/$arch/*.c to reduce the coupling
among the various compilation unit. In particular, we want to make the
various translate.c as much standalone as possible, so that they will be
easily employed by libtcg.
---
 exec.c                       |   2 +
 target/arm/cpu.c             | 118
+++++++++++++++++++++++++++++++++++++++++++
 target/arm/cpu.h             |  82 ++++++++++++++++++++++--------
 target/arm/helper.c          |  73 +-------------------------
 target/arm/translate-a64.c   |  54 --------------------
 target/arm/translate.c       |  97 ++++++++++++-----------------------
 target/arm/translate.h       |   7 ---
 target/m68k/op_helper.c      |  23 +++++++++
 target/m68k/translate.c      |  23 ---------
 target/mips/op_helper.c      |   8 ---
 target/mips/translate.c      |   8 +++
 target/ppc/gdbstub.c         |  20 --------
 target/ppc/translate_init.c  |  20 ++++++++
 target/unicore32/helper.c    |  68 +++++++++++++++++++++++++
 target/unicore32/translate.c |  68 -------------------------
 15 files changed, 333 insertions(+), 338 deletions(-)

diff --git a/exec.c b/exec.c
index 47835c1dc1..66f8187281 100644
--- a/exec.c
+++ b/exec.c
@@ -672,9 +672,11 @@ void cpu_exec_unrealizefn(CPUState *cpu)
     if (cc->vmsd != NULL) {
         vmstate_unregister(NULL, cc->vmsd, cpu);
     }
+#ifndef CONFIG_USER_ONLY
     if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
         vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
     }
+#endif


Shouldn't this #ifndef block also include the vmsd vmstate_unregister()
above? That would be matching cpu_exec_realizefn() #ifndef.

 }

 void cpu_exec_initfn(CPUState *cpu)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index f5cb30af6c..f0af5d5d7d 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -238,6 +238,124 @@ static void arm_cpu_reset(CPUState *s)
     hw_watchpoint_update_all(cpu);
 }

+static void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
+                                   fprintf_function cpu_fprintf, int flags)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    uint32_t psr = pstate_read(env);
+    int i;
+    int el = arm_current_el(env);
+    const char *ns_status;
+
+    cpu_fprintf(f, "PC=%016"PRIx64"  SP=%016"PRIx64"\n",
+            env->pc, env->xregs[31]);
+    for (i = 0; i < 31; i++) {
+        cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
+        if ((i % 4) == 3) {
+            cpu_fprintf(f, "\n");
+        } else {
+            cpu_fprintf(f, " ");
+        }
+    }
+
+    if (arm_feature(env, ARM_FEATURE_EL3) && el != 3) {
+        ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
+    } else {
+        ns_status = "";
+    }
+
+    cpu_fprintf(f, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n",
+                psr,
+                psr & PSTATE_N ? 'N' : '-',
+                psr & PSTATE_Z ? 'Z' : '-',
+                psr & PSTATE_C ? 'C' : '-',
+                psr & PSTATE_V ? 'V' : '-',
+                ns_status,
+                el,
+                psr & PSTATE_SP ? 'h' : 't');
+
+    if (flags & CPU_DUMP_FPU) {
+        int numvfpregs = 32;
+        for (i = 0; i < numvfpregs; i += 2) {
+            uint64_t vlo = float64_val(env->vfp.regs[i * 2]);
+            uint64_t vhi = float64_val(env->vfp.regs[(i * 2) + 1]);
+            cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
+                        i, vhi, vlo);
+            vlo = float64_val(env->vfp.regs[(i + 1) * 2]);
+            vhi = float64_val(env->vfp.regs[((i + 1) * 2) + 1]);
+            cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
+                        i + 1, vhi, vlo);
+        }
+        cpu_fprintf(f, "FPCR: %08x  FPSR: %08x\n",
+                    vfp_get_fpcr(env), vfp_get_fpsr(env));
+    }
+}
+
+static const char *cpu_mode_names[16] = {
+  "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
+  "???", "???", "hyp", "und", "???", "???", "???", "sys"
+};
+
+void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function
cpu_fprintf,
+                        int flags)
+{
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    int i;
+    uint32_t psr;
+    const char *ns_status;
+
+    if (is_a64(env)) {
+        aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
+        return;
+    }
+
+    for(i=0;i<16;i++) {
+        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
+        if ((i % 4) == 3)
+            cpu_fprintf(f, "\n");
+        else
+            cpu_fprintf(f, " ");
+    }
+    psr = cpsr_read(env);
+
+    if (arm_feature(env, ARM_FEATURE_EL3) &&
+        (psr & CPSR_M) != ARM_CPU_MODE_MON) {
+        ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
+    } else {
+        ns_status = "";
+    }
+
+    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
+                psr,
+                psr & (1 << 31) ? 'N' : '-',
+                psr & (1 << 30) ? 'Z' : '-',
+                psr & (1 << 29) ? 'C' : '-',
+                psr & (1 << 28) ? 'V' : '-',
+                psr & CPSR_T ? 'T' : 'A',
+                ns_status,
+                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
+
+    if (flags & CPU_DUMP_FPU) {
+        int numvfpregs = 0;
+        if (arm_feature(env, ARM_FEATURE_VFP)) {
+            numvfpregs += 16;
+        }
+        if (arm_feature(env, ARM_FEATURE_VFP3)) {
+            numvfpregs += 16;
+        }
+        for (i = 0; i < numvfpregs; i++) {
+            uint64_t v = float64_val(env->vfp.regs[i]);
+            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
+                        i * 2, (uint32_t)v,
+                        i * 2 + 1, (uint32_t)(v >> 32),
+                        i, v);
+        }
+        cpu_fprintf(f, "FPSCR: %08x\n",
(int)env->vfp.xregs[ARM_VFP_FPSCR]);
+    }
+}
+
 bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     CPUClass *cc = CPU_GET_CLASS(cs);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index ab119e62ab..3d3bf26f4e 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1012,7 +1012,6 @@ static inline void xpsr_write(CPUARMState *env,
uint32_t val, uint32_t mask)
 #define SCR_AARCH64_MASK      (0x3fff & ~SCR_NET)

 /* Return the current FPSCR value.  */
-uint32_t vfp_get_fpscr(CPUARMState *env);
 void vfp_set_fpscr(CPUARMState *env, uint32_t val);

 /* For A64 the FPSCR is split into two logically distinct registers,
@@ -1021,27 +1020,6 @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
  */
 #define FPSR_MASK 0xf800009f
 #define FPCR_MASK 0x07f79f00
-static inline uint32_t vfp_get_fpsr(CPUARMState *env)
-{
-    return vfp_get_fpscr(env) & FPSR_MASK;
-}
-
-static inline void vfp_set_fpsr(CPUARMState *env, uint32_t val)
-{
-    uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPSR_MASK) | (val &
FPSR_MASK);
-    vfp_set_fpscr(env, new_fpscr);
-}
-
-static inline uint32_t vfp_get_fpcr(CPUARMState *env)
-{
-    return vfp_get_fpscr(env) & FPCR_MASK;
-}
-
-static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val)
-{
-    uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPCR_MASK) | (val &
FPCR_MASK);
-    vfp_set_fpscr(env, new_fpscr);
-}

 enum arm_cpu_mode {
   ARM_CPU_MODE_USR = 0x10,
@@ -1128,6 +1106,66 @@ enum arm_features {
     ARM_FEATURE_VBAR, /* has cp15 VBAR */
 };

+/* VFP support.  We follow the convention used for VFP instructions:
+   Single precision routines have a "s" suffix, double precision a
+   "d" suffix.  */
+
+/* Convert host exception flags to vfp form.  */
+static inline int vfp_exceptbits_from_host(int host_bits)
+{
+    int target_bits = 0;
+
+    if (host_bits & float_flag_invalid)
+        target_bits |= 1;
+    if (host_bits & float_flag_divbyzero)
+        target_bits |= 2;
+    if (host_bits & float_flag_overflow)
+        target_bits |= 4;
+    if (host_bits & (float_flag_underflow | float_flag_output_denormal))
+        target_bits |= 8;
+    if (host_bits & float_flag_inexact)
+        target_bits |= 0x10;
+    if (host_bits & float_flag_input_denormal)
+        target_bits |= 0x80;
+    return target_bits;
+}
+
+static inline uint32_t vfp_get_fpscr(CPUARMState *env)
+{
+    int i;
+    uint32_t fpscr;
+
+    fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
+            | (env->vfp.vec_len << 16)
+            | (env->vfp.vec_stride << 20);
+    i = get_float_exception_flags(&env->vfp.fp_status);
+    i |= get_float_exception_flags(&env->vfp.standard_fp_status);
+    fpscr |= vfp_exceptbits_from_host(i);
+    return fpscr;
+}
+
+static inline uint32_t vfp_get_fpsr(CPUARMState *env)
+{
+    return vfp_get_fpscr(env) & FPSR_MASK;
+}
+
+static inline void vfp_set_fpsr(CPUARMState *env, uint32_t val)
+{
+    uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPSR_MASK) | (val &
FPSR_MASK);
+    vfp_set_fpscr(env, new_fpscr);
+}
+
+static inline uint32_t vfp_get_fpcr(CPUARMState *env)
+{
+    return vfp_get_fpscr(env) & FPCR_MASK;
+}
+
+static inline void vfp_set_fpcr(CPUARMState *env, uint32_t val)
+{
+    uint32_t new_fpscr = (vfp_get_fpscr(env) & ~FPCR_MASK) | (val &
FPCR_MASK);
+    vfp_set_fpscr(env, new_fpscr);
+}
+
 static inline int arm_feature(CPUARMState *env, int feature)
 {
     return (env->features & (1ULL << feature)) != 0;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 8dcabbf576..2ec50b94fc 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -5514,11 +5514,6 @@ void define_arm_cp_regs_with_opaque(ARMCPU *cpu,
     }
 }

-const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t
encoded_cp)
-{
-    return g_hash_table_lookup(cpregs, &encoded_cp);
-}
-
 void arm_cp_write_ignore(CPUARMState *env, const ARMCPRegInfo *ri,
                          uint64_t value)
 {
@@ -8664,47 +8659,9 @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t
a, uint32_t b)
     return (a & mask) | (b & ~mask);
 }

-/* VFP support.  We follow the convention used for VFP instructions:
-   Single precision routines have a "s" suffix, double precision a
-   "d" suffix.  */
-
-/* Convert host exception flags to vfp form.  */
-static inline int vfp_exceptbits_from_host(int host_bits)
-{
-    int target_bits = 0;
-
-    if (host_bits & float_flag_invalid)
-        target_bits |= 1;
-    if (host_bits & float_flag_divbyzero)
-        target_bits |= 2;
-    if (host_bits & float_flag_overflow)
-        target_bits |= 4;
-    if (host_bits & (float_flag_underflow | float_flag_output_denormal))
-        target_bits |= 8;
-    if (host_bits & float_flag_inexact)
-        target_bits |= 0x10;
-    if (host_bits & float_flag_input_denormal)
-        target_bits |= 0x80;
-    return target_bits;
-}
-
 uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
 {
-    int i;
-    uint32_t fpscr;
-
-    fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
-            | (env->vfp.vec_len << 16)
-            | (env->vfp.vec_stride << 20);
-    i = get_float_exception_flags(&env->vfp.fp_status);
-    i |= get_float_exception_flags(&env->vfp.standard_fp_status);
-    fpscr |= vfp_exceptbits_from_host(i);
-    return fpscr;
-}
-
-uint32_t vfp_get_fpscr(CPUARMState *env)
-{
-    return HELPER(vfp_get_fpscr)(env);
+    return vfp_get_fpscr(env);
 }

 /* Convert vfp exception flags to target form.  */
@@ -9577,34 +9534,6 @@ float64 HELPER(rintd)(float64 x, void *fp_status)
     return ret;
 }

-/* Convert ARM rounding mode to softfloat */
-int arm_rmode_to_sf(int rmode)
-{
-    switch (rmode) {
-    case FPROUNDING_TIEAWAY:
-        rmode = float_round_ties_away;
-        break;
-    case FPROUNDING_ODD:
-        /* FIXME: add support for TIEAWAY and ODD */
-        qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n",
-                      rmode);
-    case FPROUNDING_TIEEVEN:
-    default:
-        rmode = float_round_nearest_even;
-        break;
-    case FPROUNDING_POSINF:
-        rmode = float_round_up;
-        break;
-    case FPROUNDING_NEGINF:
-        rmode = float_round_down;
-        break;
-    case FPROUNDING_ZERO:
-        rmode = float_round_to_zero;
-        break;
-    }
-    return rmode;
-}
-
 /* CRC helpers.
  * The upper bytes of val (above the number specified by 'bytes') must have
  * been zeroed out by the caller.
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index f673d939e1..56333c6dd5 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -118,60 +118,6 @@ static inline ARMMMUIdx
get_a64_user_mem_index(DisasContext *s)
     }
 }

-void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
-                            fprintf_function cpu_fprintf, int flags)
-{
-    ARMCPU *cpu = ARM_CPU(cs);
-    CPUARMState *env = &cpu->env;
-    uint32_t psr = pstate_read(env);
-    int i;
-    int el = arm_current_el(env);
-    const char *ns_status;
-
-    cpu_fprintf(f, "PC=%016"PRIx64"  SP=%016"PRIx64"\n",
-            env->pc, env->xregs[31]);
-    for (i = 0; i < 31; i++) {
-        cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
-        if ((i % 4) == 3) {
-            cpu_fprintf(f, "\n");
-        } else {
-            cpu_fprintf(f, " ");
-        }
-    }
-
-    if (arm_feature(env, ARM_FEATURE_EL3) && el != 3) {
-        ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
-    } else {
-        ns_status = "";
-    }
-
-    cpu_fprintf(f, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n",
-                psr,
-                psr & PSTATE_N ? 'N' : '-',
-                psr & PSTATE_Z ? 'Z' : '-',
-                psr & PSTATE_C ? 'C' : '-',
-                psr & PSTATE_V ? 'V' : '-',
-                ns_status,
-                el,
-                psr & PSTATE_SP ? 'h' : 't');
-
-    if (flags & CPU_DUMP_FPU) {
-        int numvfpregs = 32;
-        for (i = 0; i < numvfpregs; i += 2) {
-            uint64_t vlo = float64_val(env->vfp.regs[i * 2]);
-            uint64_t vhi = float64_val(env->vfp.regs[(i * 2) + 1]);
-            cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
-                        i, vhi, vlo);
-            vlo = float64_val(env->vfp.regs[(i + 1) * 2]);
-            vhi = float64_val(env->vfp.regs[((i + 1) * 2) + 1]);
-            cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
-                        i + 1, vhi, vlo);
-        }
-        cpu_fprintf(f, "FPCR: %08x  FPSR: %08x\n",
-                    vfp_get_fpcr(env), vfp_get_fpsr(env));
-    }
-}
-
 void gen_a64_set_pc_im(uint64_t val)
 {
     tcg_gen_movi_i64(cpu_pc, val);
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 0ad9070b45..a82557eb39 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -2971,6 +2971,34 @@ static int handle_vminmaxnm(uint32_t insn, uint32_t
rd, uint32_t rn,
     return 0;
 }

+/* Convert ARM rounding mode to softfloat */
+int arm_rmode_to_sf(int rmode)
+{
+    switch (rmode) {
+    case FPROUNDING_TIEAWAY:
+        rmode = float_round_ties_away;
+        break;
+    case FPROUNDING_ODD:
+        /* FIXME: add support for TIEAWAY and ODD */
+        qemu_log_mask(LOG_UNIMP, "arm: unimplemented rounding mode: %d\n",
+                      rmode);
+    case FPROUNDING_TIEEVEN:
+    default:
+        rmode = float_round_nearest_even;
+        break;
+    case FPROUNDING_POSINF:
+        rmode = float_round_up;
+        break;
+    case FPROUNDING_NEGINF:
+        rmode = float_round_down;
+        break;
+    case FPROUNDING_ZERO:
+        rmode = float_round_to_zero;
+        break;
+    }
+    return rmode;
+}
+
 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t
dp,
                         int rounding)
 {
@@ -7399,6 +7427,11 @@ static int disas_neon_data_insn(DisasContext *s,
uint32_t insn)
     return 0;
 }

+const ARMCPRegInfo *get_arm_cp_reginfo(GHashTable *cpregs, uint32_t
encoded_cp)
+{
+    return g_hash_table_lookup(cpregs, &encoded_cp);
+}
+
 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
 {
     int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
@@ -11976,70 +12009,6 @@ done_generating:
     tb->icount = num_insns;
 }

-static const char *cpu_mode_names[16] = {
-  "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
-  "???", "???", "hyp", "und", "???", "???", "???", "sys"
-};
-
-void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function
cpu_fprintf,
-                        int flags)
-{
-    ARMCPU *cpu = ARM_CPU(cs);
-    CPUARMState *env = &cpu->env;
-    int i;
-    uint32_t psr;
-    const char *ns_status;
-
-    if (is_a64(env)) {
-        aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
-        return;
-    }
-
-    for(i=0;i<16;i++) {
-        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
-        if ((i % 4) == 3)
-            cpu_fprintf(f, "\n");
-        else
-            cpu_fprintf(f, " ");
-    }
-    psr = cpsr_read(env);
-
-    if (arm_feature(env, ARM_FEATURE_EL3) &&
-        (psr & CPSR_M) != ARM_CPU_MODE_MON) {
-        ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
-    } else {
-        ns_status = "";
-    }
-
-    cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
-                psr,
-                psr & (1 << 31) ? 'N' : '-',
-                psr & (1 << 30) ? 'Z' : '-',
-                psr & (1 << 29) ? 'C' : '-',
-                psr & (1 << 28) ? 'V' : '-',
-                psr & CPSR_T ? 'T' : 'A',
-                ns_status,
-                cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
-
-    if (flags & CPU_DUMP_FPU) {
-        int numvfpregs = 0;
-        if (arm_feature(env, ARM_FEATURE_VFP)) {
-            numvfpregs += 16;
-        }
-        if (arm_feature(env, ARM_FEATURE_VFP3)) {
-            numvfpregs += 16;
-        }
-        for (i = 0; i < numvfpregs; i++) {
-            uint64_t v = float64_val(env->vfp.regs[i]);
-            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
-                        i * 2, (uint32_t)v,
-                        i * 2 + 1, (uint32_t)(v >> 32),
-                        i, v);
-        }
-        cpu_fprintf(f, "FPSCR: %08x\n",
(int)env->vfp.xregs[ARM_VFP_FPSCR]);
-    }
-}
-
 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
diff --git a/target/arm/translate.h b/target/arm/translate.h
index 285e96f087..6b93b35a3b 100644
--- a/target/arm/translate.h
+++ b/target/arm/translate.h
@@ -125,8 +125,6 @@ static inline int default_exception_el(DisasContext *s)
 void a64_translate_init(void);
 void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb);
 void gen_a64_set_pc_im(uint64_t val);
-void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
-                            fprintf_function cpu_fprintf, int flags);
 #else
 static inline void a64_translate_init(void)
 {
@@ -140,11 +138,6 @@ static inline void gen_a64_set_pc_im(uint64_t val)
 {
 }

-static inline void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
-                                          fprintf_function cpu_fprintf,
-                                          int flags)
-{
-}
 #endif

 void arm_test_cc(DisasCompare *cmp, int cc);
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index e56b815d73..059061e6e8 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -148,6 +148,29 @@ static inline void
do_interrupt_m68k_hardirq(CPUM68KState *env)
 }
 #endif

+void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function
cpu_fprintf,
+                         int flags)
+{
+    M68kCPU *cpu = M68K_CPU(cs);
+    CPUM68KState *env = &cpu->env;
+    int i;
+    uint16_t sr;
+    CPU_DoubleU u;
+    for (i = 0; i < 8; i++)
+      {
+        u.d = env->fregs[i];
+        cpu_fprintf(f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
+                    i, env->dregs[i], i, env->aregs[i],
+                    i, u.l.upper, u.l.lower, *(double *)&u.d);
+      }
+    cpu_fprintf (f, "PC = %08x   ", env->pc);
+    sr = env->sr | cpu_m68k_get_ccr(env);
+    cpu_fprintf(f, "SR = %04x %c%c%c%c%c ", sr, (sr & CCF_X) ? 'X' : '-',
+                (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
+                (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
+    cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
+}
+
 bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     M68kCPU *cpu = M68K_CPU(cs);
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 53293173c5..e0d055c3fe 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -4725,29 +4725,6 @@ void gen_intermediate_code(CPUM68KState *env,
TranslationBlock *tb)
     tb->icount = num_insns;
 }

-void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function
cpu_fprintf,
-                         int flags)
-{
-    M68kCPU *cpu = M68K_CPU(cs);
-    CPUM68KState *env = &cpu->env;
-    int i;
-    uint16_t sr;
-    CPU_DoubleU u;
-    for (i = 0; i < 8; i++)
-      {
-        u.d = env->fregs[i];
-        cpu_fprintf(f, "D%d = %08x   A%d = %08x   F%d = %08x%08x (%12g)\n",
-                    i, env->dregs[i], i, env->aregs[i],
-                    i, u.l.upper, u.l.lower, *(double *)&u.d);
-      }
-    cpu_fprintf (f, "PC = %08x   ", env->pc);
-    sr = env->sr | cpu_m68k_get_ccr(env);
-    cpu_fprintf(f, "SR = %04x %c%c%c%c%c ", sr, (sr & CCF_X) ? 'X' : '-',
-                (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-',
-                (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-');
-    cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
-}
-
 void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb,
                           target_ulong *data)
 {
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index 7af4c2f084..4965b912ef 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -2454,14 +2454,6 @@ void mips_cpu_unassigned_access(CPUState *cs, hwaddr
addr,
 #define FP_TO_INT32_OVERFLOW 0x7fffffff
 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL

-/* convert MIPS rounding mode in FCR31 to IEEE library */
-unsigned int ieee_rm[] = {
-    float_round_nearest_even,
-    float_round_to_zero,
-    float_round_up,
-    float_round_down
-};
-
 target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
 {
     target_ulong arg1 = 0;
diff --git a/target/mips/translate.c b/target/mips/translate.c
index 57b824ff2d..697b2a2079 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -36,6 +36,14 @@
 #include "trace-tcg.h"
 #include "exec/log.h"

+/* convert MIPS rounding mode in FCR31 to IEEE library */
+unsigned int ieee_rm[] = {
+    float_round_nearest_even,
+    float_round_to_zero,
+    float_round_up,
+    float_round_down
+};
+
 #define MIPS_DEBUG_DISAS 0

 /* MIPS major opcodes */
diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c
index 7a338136a8..4f74946ec9 100644
--- a/target/ppc/gdbstub.c
+++ b/target/ppc/gdbstub.c
@@ -84,26 +84,6 @@ static int ppc_gdb_register_len(int n)
     }
 }

-/* We need to present the registers to gdb in the "current" memory
ordering.
-   For user-only mode we get this for free; TARGET_WORDS_BIGENDIAN is set
to
-   the proper ordering for the binary, and cannot be changed.
-   For system mode, TARGET_WORDS_BIGENDIAN is always set, and we must check
-   the current mode of the chip to see if we're running in little-endian.
*/
-void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
-{
-#ifndef CONFIG_USER_ONLY
-    if (!msr_le) {
-        /* do nothing */
-    } else if (len == 4) {
-        bswap32s((uint32_t *)mem_buf);
-    } else if (len == 8) {
-        bswap64s((uint64_t *)mem_buf);
-    } else {
-        g_assert_not_reached();
-    }
-#endif
-}
-
 /* Old gdb always expects FP registers.  Newer (xml-aware) gdb only
  * expects whatever the target description contains.  Due to a
  * historical mishap the FP registers appear in between core integer
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 626e03186c..74e3339bd8 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -9462,6 +9462,26 @@ static bool avr_need_swap(CPUPPCState *env)
 #endif
 }

+/* We need to present the registers to gdb in the "current" memory
ordering.
+   For user-only mode we get this for free; TARGET_WORDS_BIGENDIAN is set
to
+   the proper ordering for the binary, and cannot be changed.
+   For system mode, TARGET_WORDS_BIGENDIAN is always set, and we must check
+   the current mode of the chip to see if we're running in little-endian.
*/
+void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
+{
+#ifndef CONFIG_USER_ONLY
+    if (!msr_le) {
+        /* do nothing */
+    } else if (len == 4) {
+        bswap32s((uint32_t *)mem_buf);
+    } else if (len == 8) {
+        bswap64s((uint64_t *)mem_buf);
+    } else {
+        g_assert_not_reached();
+    }
+#endif
+}
+
 static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
 {
     if (n < 32) {
diff --git a/target/unicore32/helper.c b/target/unicore32/helper.c
index d603bde237..42e753a5ea 100644
--- a/target/unicore32/helper.c
+++ b/target/unicore32/helper.c
@@ -247,6 +247,74 @@ int uc32_cpu_handle_mmu_fault(CPUState *cs, vaddr
address,
 }
 #endif

+static const char *cpu_mode_names[16] = {
+    "USER", "REAL", "INTR", "PRIV", "UM14", "UM15", "UM16", "TRAP",
+    "UM18", "UM19", "UM1A", "EXTN", "UM1C", "UM1D", "UM1E", "SUSR"
+};
+
+#undef UCF64_DUMP_STATE
+#ifdef UCF64_DUMP_STATE
+static void cpu_dump_state_ucf64(CPUUniCore32State *env, FILE *f,
+        fprintf_function cpu_fprintf, int flags)
+{
+    int i;
+    union {
+        uint32_t i;
+        float s;
+    } s0, s1;
+    CPU_DoubleU d;
+    /* ??? This assumes float64 and double have the same layout.
+       Oh well, it's only debug dumps.  */
+    union {
+        float64 f64;
+        double d;
+    } d0;
+
+    for (i = 0; i < 16; i++) {
+        d.d = env->ucf64.regs[i];
+        s0.i = d.l.lower;
+        s1.i = d.l.upper;
+        d0.f64 = d.d;
+        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g)",
+                    i * 2, (int)s0.i, s0.s,
+                    i * 2 + 1, (int)s1.i, s1.s);
+        cpu_fprintf(f, " d%02d=%" PRIx64 "(%8g)\n",
+                    i, (uint64_t)d0.f64, d0.d);
+    }
+    cpu_fprintf(f, "FPSCR: %08x\n",
(int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
+}
+#else
+#define cpu_dump_state_ucf64(env, file, pr, flags)      do { } while (0)
+#endif
+
+void uc32_cpu_dump_state(CPUState *cs, FILE *f,
+                         fprintf_function cpu_fprintf, int flags)
+{
+    UniCore32CPU *cpu = UNICORE32_CPU(cs);
+    CPUUniCore32State *env = &cpu->env;
+    int i;
+    uint32_t psr;
+
+    for (i = 0; i < 32; i++) {
+        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
+        if ((i % 4) == 3) {
+            cpu_fprintf(f, "\n");
+        } else {
+            cpu_fprintf(f, " ");
+        }
+    }
+    psr = cpu_asr_read(env);
+    cpu_fprintf(f, "PSR=%08x %c%c%c%c %s\n",
+                psr,
+                psr & (1 << 31) ? 'N' : '-',
+                psr & (1 << 30) ? 'Z' : '-',
+                psr & (1 << 29) ? 'C' : '-',
+                psr & (1 << 28) ? 'V' : '-',
+                cpu_mode_names[psr & 0xf]);
+
+    cpu_dump_state_ucf64(env, f, cpu_fprintf, flags);
+}
+
 bool uc32_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
     if (interrupt_request & CPU_INTERRUPT_HARD) {
diff --git a/target/unicore32/translate.c b/target/unicore32/translate.c
index 514d460408..92300671a7 100644
--- a/target/unicore32/translate.c
+++ b/target/unicore32/translate.c
@@ -2036,74 +2036,6 @@ done_generating:
     tb->icount = num_insns;
 }

-static const char *cpu_mode_names[16] = {
-    "USER", "REAL", "INTR", "PRIV", "UM14", "UM15", "UM16", "TRAP",
-    "UM18", "UM19", "UM1A", "EXTN", "UM1C", "UM1D", "UM1E", "SUSR"
-};
-
-#undef UCF64_DUMP_STATE
-#ifdef UCF64_DUMP_STATE
-static void cpu_dump_state_ucf64(CPUUniCore32State *env, FILE *f,
-        fprintf_function cpu_fprintf, int flags)
-{
-    int i;
-    union {
-        uint32_t i;
-        float s;
-    } s0, s1;
-    CPU_DoubleU d;
-    /* ??? This assumes float64 and double have the same layout.
-       Oh well, it's only debug dumps.  */
-    union {
-        float64 f64;
-        double d;
-    } d0;
-
-    for (i = 0; i < 16; i++) {
-        d.d = env->ucf64.regs[i];
-        s0.i = d.l.lower;
-        s1.i = d.l.upper;
-        d0.f64 = d.d;
-        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g)",
-                    i * 2, (int)s0.i, s0.s,
-                    i * 2 + 1, (int)s1.i, s1.s);
-        cpu_fprintf(f, " d%02d=%" PRIx64 "(%8g)\n",
-                    i, (uint64_t)d0.f64, d0.d);
-    }
-    cpu_fprintf(f, "FPSCR: %08x\n",
(int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
-}
-#else
-#define cpu_dump_state_ucf64(env, file, pr, flags)      do { } while (0)
-#endif
-
-void uc32_cpu_dump_state(CPUState *cs, FILE *f,
-                         fprintf_function cpu_fprintf, int flags)
-{
-    UniCore32CPU *cpu = UNICORE32_CPU(cs);
-    CPUUniCore32State *env = &cpu->env;
-    int i;
-    uint32_t psr;
-
-    for (i = 0; i < 32; i++) {
-        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
-        if ((i % 4) == 3) {
-            cpu_fprintf(f, "\n");
-        } else {
-            cpu_fprintf(f, " ");
-        }
-    }
-    psr = cpu_asr_read(env);
-    cpu_fprintf(f, "PSR=%08x %c%c%c%c %s\n",
-                psr,
-                psr & (1 << 31) ? 'N' : '-',
-                psr & (1 << 30) ? 'Z' : '-',
-                psr & (1 << 29) ? 'C' : '-',
-                psr & (1 << 28) ? 'V' : '-',
-                cpu_mode_names[psr & 0xf]);
-
-    cpu_dump_state_ucf64(env, f, cpu_fprintf, flags);
-}
-
 void restore_state_to_opc(CPUUniCore32State *env, TranslationBlock *tb,
                           target_ulong *data)
 {
--
2.11.0


-- 
Marc-André Lureau

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

* Re: [Qemu-devel] [RFC PATCH 1/3] Factor out {linux, bsd}-user/qemu.h
  2017-01-21  8:45 ` [Qemu-devel] [RFC PATCH 1/3] Factor out {linux,bsd}-user/qemu.h Alessandro Di Federico
@ 2017-01-24 10:10   ` Marc-André Lureau
  2017-01-25  7:37     ` Alessandro Di Federico
  2017-01-24 11:18   ` Peter Maydell
  1 sibling, 1 reply; 15+ messages in thread
From: Marc-André Lureau @ 2017-01-24 10:10 UTC (permalink / raw)
  To: Alessandro Di Federico, qemu-devel

Hi

On Sat, Jan 21, 2017 at 12:46 PM Alessandro Di Federico <
ale+qemu@clearmind.me> wrote:

A quite large part of {linux,bsd}-user/qemu.h is shared, this patch
introduces qemu-user-common.h which factors it out. This shared part is
also the bare minimum required to build a linux-user-like target, and,
in particular, it will be useful for the libtcg targets.


Looks good. Probably worth to mention that the main difference is in commit
658f2dc970996d547a641b5685e384ebe6f2648e not being applied to bsd-user.

---
 bsd-user/qemu.h    | 193
+----------------------------------------------------
 linux-user/qemu.h  | 176 +-----------------------------------------------
 qemu-user-common.h | 180 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 182 insertions(+), 367 deletions(-)
 create mode 100644 qemu-user-common.h

diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 2b2b9184e0..b51319caf0 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -17,10 +17,8 @@
 #ifndef QEMU_H
 #define QEMU_H

-
-#include "cpu.h"
+#include "qemu-user-common.h"
 #include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"

 #undef DEBUG_REMAP
 #ifdef DEBUG_REMAP
@@ -217,195 +215,6 @@ void mmap_fork_end(int child);
 /* main.c */
 extern unsigned long x86_stack_size;

-/* user access */
-
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1 /* implies read access */
-
-static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
-{
-    return page_check_range((target_ulong)addr, size,
-                            (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ
| PAGE_WRITE)) == 0;
-}
-
-/* NOTE __get_user and __put_user use host pointers and don't check
access. */
-/* These are usually used to access struct data members once the
- * struct has been locked - usually with lock_user_struct().
- */
-#define __put_user(x, hptr)\
-({\
-    int size = sizeof(*hptr);\
-    switch(size) {\
-    case 1:\
-        *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
-        break;\
-    case 2:\
-        *(uint16_t *)(hptr) = tswap16((typeof(*hptr))(x));\
-        break;\
-    case 4:\
-        *(uint32_t *)(hptr) = tswap32((typeof(*hptr))(x));\
-        break;\
-    case 8:\
-        *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
-        break;\
-    default:\
-        abort();\
-    }\
-    0;\
-})
-
-#define __get_user(x, hptr) \
-({\
-    int size = sizeof(*hptr);\
-    switch(size) {\
-    case 1:\
-        x = (typeof(*hptr))*(uint8_t *)(hptr);\
-        break;\
-    case 2:\
-        x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\
-        break;\
-    case 4:\
-        x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
-        break;\
-    case 8:\
-        x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
-        break;\
-    default:\
-        /* avoid warning */\
-        x = 0;\
-        abort();\
-    }\
-    0;\
-})
-
-/* put_user()/get_user() take a guest address and check access */
-/* These are usually used to access an atomic data type, such as an int,
- * that has been passed by address.  These internally perform locking
- * and unlocking on the data type.
- */
-#define put_user(x, gaddr, target_type)                                 \
-({                                                                      \
-    abi_ulong __gaddr = (gaddr);                                        \
-    target_type *__hptr;                                                \
-    abi_long __ret;                                                     \
-    if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type),
0))) { \
-        __ret = __put_user((x), __hptr);                                \
-        unlock_user(__hptr, __gaddr, sizeof(target_type));              \
-    } else                                                              \
-        __ret = -TARGET_EFAULT;                                         \
-    __ret;                                                              \
-})
-
-#define get_user(x, gaddr, target_type)                                 \
-({                                                                      \
-    abi_ulong __gaddr = (gaddr);                                        \
-    target_type *__hptr;                                                \
-    abi_long __ret;                                                     \
-    if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type),
1))) { \
-        __ret = __get_user((x), __hptr);                                \
-        unlock_user(__hptr, __gaddr, 0);                                \
-    } else {                                                            \
-        /* avoid warning */                                             \
-        (x) = 0;                                                        \
-        __ret = -TARGET_EFAULT;                                         \
-    }                                                                   \
-    __ret;                                                              \
-})
-
-#define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
-#define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
-#define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
-#define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
-#define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
-#define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
-#define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
-#define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
-#define put_user_u8(x, gaddr)  put_user((x), (gaddr), uint8_t)
-#define put_user_s8(x, gaddr)  put_user((x), (gaddr), int8_t)
-
-#define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
-#define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
-#define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
-#define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
-#define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
-#define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
-#define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
-#define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
-#define get_user_u8(x, gaddr)  get_user((x), (gaddr), uint8_t)
-#define get_user_s8(x, gaddr)  get_user((x), (gaddr), int8_t)
-
-/* copy_from_user() and copy_to_user() are usually used to copy data
- * buffers between the target and host.  These internally perform
- * locking/unlocking of the memory.
- */
-abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
-abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
-
-/* Functions for accessing guest memory.  The tget and tput functions
-   read/write single values, byteswapping as necessary.  The lock_user
function
-   gets a pointer to a contiguous area of guest memory, but does not
perform
-   any byteswapping.  lock_user may return either a pointer to the guest
-   memory, or a temporary buffer.  */
-
-/* Lock an area of guest memory into the host.  If copy is true then the
-   host area will have the same contents as the guest.  */
-static inline void *lock_user(int type, abi_ulong guest_addr, long len,
int copy)
-{
-    if (!access_ok(type, guest_addr, len))
-        return NULL;
-#ifdef DEBUG_REMAP
-    {
-        void *addr;
-        addr = g_malloc(len);
-        if (copy)
-            memcpy(addr, g2h(guest_addr), len);
-        else
-            memset(addr, 0, len);
-        return addr;
-    }
-#else
-    return g2h(guest_addr);
-#endif
-}
-
-/* Unlock an area of guest memory.  The first LEN bytes must be
-   flushed back to guest memory. host_ptr = NULL is explicitly
-   allowed and does nothing. */
-static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
-                               long len)
-{
-
-#ifdef DEBUG_REMAP
-    if (!host_ptr)
-        return;
-    if (host_ptr == g2h(guest_addr))
-        return;
-    if (len > 0)
-        memcpy(g2h(guest_addr), host_ptr, len);
-    g_free(host_ptr);
-#endif
-}
-
-/* Return the length of a string in target memory or -TARGET_EFAULT if
-   access error. */
-abi_long target_strlen(abi_ulong gaddr);
-
-/* Like lock_user but for null terminated strings.  */
-static inline void *lock_user_string(abi_ulong guest_addr)
-{
-    abi_long len;
-    len = target_strlen(guest_addr);
-    if (len < 0)
-        return NULL;
-    return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
-}
-
-/* Helper macros for locking/unlocking a target struct.  */
-#define lock_user_struct(type, host_ptr, guest_addr, copy)      \
-    (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
-#define unlock_user_struct(host_ptr, guest_addr, copy)          \
-    unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
-
 #if defined(CONFIG_USE_NPTL)
 #include <pthread.h>
 #endif
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index da73a01106..b56abb5942 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -2,9 +2,8 @@
 #define QEMU_H

 #include "hostdep.h"
-#include "cpu.h"
+#include "qemu-user-common.h"
 #include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"

 #undef DEBUG_REMAP
 #ifdef DEBUG_REMAP
@@ -436,179 +435,6 @@ void mmap_fork_end(int child);
 /* main.c */
 extern unsigned long guest_stack_size;

-/* user access */
-
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1 /* implies read access */
-
-static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
-{
-    return page_check_range((target_ulong)addr, size,
-                            (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ
| PAGE_WRITE)) == 0;
-}
-
-/* NOTE __get_user and __put_user use host pointers and don't check access.
-   These are usually used to access struct data members once the struct has
-   been locked - usually with lock_user_struct.  */
-
-/* Tricky points:
-   - Use __builtin_choose_expr to avoid type promotion from ?:,
-   - Invalid sizes result in a compile time error stemming from
-     the fact that abort has no parameters.
-   - It's easier to use the endian-specific unaligned load/store
-     functions than host-endian unaligned load/store plus tswapN.  */
-
-#define __put_user_e(x, hptr, e)                                        \
-  (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p,                   \
-   __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p,             \
-   __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p,             \
-   __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort))))   \
-     ((hptr), (x)), (void)0)
-
-#define __get_user_e(x, hptr, e)                                        \
-  ((x) = (typeof(*hptr))(                                               \
-   __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p,                  \
-   __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p,            \
-   __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p,             \
-   __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort))))   \
-     (hptr)), (void)0)
-
-#ifdef TARGET_WORDS_BIGENDIAN
-# define __put_user(x, hptr)  __put_user_e(x, hptr, be)
-# define __get_user(x, hptr)  __get_user_e(x, hptr, be)
-#else
-# define __put_user(x, hptr)  __put_user_e(x, hptr, le)
-# define __get_user(x, hptr)  __get_user_e(x, hptr, le)
-#endif
-
-/* put_user()/get_user() take a guest address and check access */
-/* These are usually used to access an atomic data type, such as an int,
- * that has been passed by address.  These internally perform locking
- * and unlocking on the data type.
- */
-#define put_user(x, gaddr, target_type)
    \
-({                                                                     \
-    abi_ulong __gaddr = (gaddr);                                       \
-    target_type *__hptr;                                               \
-    abi_long __ret = 0;
    \
-    if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type),
0))) { \
-        __put_user((x), __hptr);                               \
-        unlock_user(__hptr, __gaddr, sizeof(target_type));             \
-    } else                                                             \
-        __ret = -TARGET_EFAULT;
    \
-    __ret;                                                             \
-})
-
-#define get_user(x, gaddr, target_type)
    \
-({                                                                     \
-    abi_ulong __gaddr = (gaddr);                                       \
-    target_type *__hptr;                                               \
-    abi_long __ret = 0;
    \
-    if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type),
1))) { \
-        __get_user((x), __hptr);                               \
-        unlock_user(__hptr, __gaddr, 0);                               \
-    } else {                                                           \
-        /* avoid warning */                                            \
-        (x) = 0;                                                       \
-        __ret = -TARGET_EFAULT;
    \
-    }                                                                  \
-    __ret;                                                             \
-})
-
-#define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
-#define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
-#define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
-#define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
-#define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
-#define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
-#define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
-#define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
-#define put_user_u8(x, gaddr)  put_user((x), (gaddr), uint8_t)
-#define put_user_s8(x, gaddr)  put_user((x), (gaddr), int8_t)
-
-#define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
-#define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
-#define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
-#define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
-#define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
-#define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
-#define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
-#define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
-#define get_user_u8(x, gaddr)  get_user((x), (gaddr), uint8_t)
-#define get_user_s8(x, gaddr)  get_user((x), (gaddr), int8_t)
-
-/* copy_from_user() and copy_to_user() are usually used to copy data
- * buffers between the target and host.  These internally perform
- * locking/unlocking of the memory.
- */
-abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
-abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
-
-/* Functions for accessing guest memory.  The tget and tput functions
-   read/write single values, byteswapping as necessary.  The lock_user
function
-   gets a pointer to a contiguous area of guest memory, but does not
perform
-   any byteswapping.  lock_user may return either a pointer to the guest
-   memory, or a temporary buffer.  */
-
-/* Lock an area of guest memory into the host.  If copy is true then the
-   host area will have the same contents as the guest.  */
-static inline void *lock_user(int type, abi_ulong guest_addr, long len,
int copy)
-{
-    if (!access_ok(type, guest_addr, len))
-        return NULL;
-#ifdef DEBUG_REMAP
-    {
-        void *addr;
-        addr = g_malloc(len);
-        if (copy)
-            memcpy(addr, g2h(guest_addr), len);
-        else
-            memset(addr, 0, len);
-        return addr;
-    }
-#else
-    return g2h(guest_addr);
-#endif
-}
-
-/* Unlock an area of guest memory.  The first LEN bytes must be
-   flushed back to guest memory. host_ptr = NULL is explicitly
-   allowed and does nothing. */
-static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
-                               long len)
-{
-
-#ifdef DEBUG_REMAP
-    if (!host_ptr)
-        return;
-    if (host_ptr == g2h(guest_addr))
-        return;
-    if (len > 0)
-        memcpy(g2h(guest_addr), host_ptr, len);
-    g_free(host_ptr);
-#endif
-}
-
-/* Return the length of a string in target memory or -TARGET_EFAULT if
-   access error. */
-abi_long target_strlen(abi_ulong gaddr);
-
-/* Like lock_user but for null terminated strings.  */
-static inline void *lock_user_string(abi_ulong guest_addr)
-{
-    abi_long len;
-    len = target_strlen(guest_addr);
-    if (len < 0)
-        return NULL;
-    return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
-}
-
-/* Helper macros for locking/unlocking a target struct.  */
-#define lock_user_struct(type, host_ptr, guest_addr, copy)     \
-    (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
-#define unlock_user_struct(host_ptr, guest_addr, copy)         \
-    unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
-
 #include <pthread.h>

 /* Include target-specific struct and function definitions;
diff --git a/qemu-user-common.h b/qemu-user-common.h
new file mode 100644
index 0000000000..349dd72fff
--- /dev/null
+++ b/qemu-user-common.h
@@ -0,0 +1,180 @@
+#ifndef QEMU_USER_COMMON_H
+#define QEMU_USER_COMMON_H
+
+#include "cpu.h"
+#include "exec/cpu_ldst.h"
+
+/* user access */
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1 /* implies read access */
+
+static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
+{
+    return page_check_range((target_ulong)addr, size,
+                            (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ
| PAGE_WRITE)) == 0;
+}
+
+/* NOTE __get_user and __put_user use host pointers and don't check access.
+   These are usually used to access struct data members once the struct has
+   been locked - usually with lock_user_struct.  */
+
+/* Tricky points:
+   - Use __builtin_choose_expr to avoid type promotion from ?:,
+   - Invalid sizes result in a compile time error stemming from
+     the fact that abort has no parameters.
+   - It's easier to use the endian-specific unaligned load/store
+     functions than host-endian unaligned load/store plus tswapN.  */
+
+#define __put_user_e(x, hptr, e)                                        \
+  (__builtin_choose_expr(sizeof(*(hptr)) == 1, stb_p,                   \
+   __builtin_choose_expr(sizeof(*(hptr)) == 2, stw_##e##_p,             \
+   __builtin_choose_expr(sizeof(*(hptr)) == 4, stl_##e##_p,             \
+   __builtin_choose_expr(sizeof(*(hptr)) == 8, stq_##e##_p, abort))))   \
+     ((hptr), (x)), (void)0)
+
+#define __get_user_e(x, hptr, e)                                        \
+  ((x) = (typeof(*hptr))(                                               \
+   __builtin_choose_expr(sizeof(*(hptr)) == 1, ldub_p,                  \
+   __builtin_choose_expr(sizeof(*(hptr)) == 2, lduw_##e##_p,            \
+   __builtin_choose_expr(sizeof(*(hptr)) == 4, ldl_##e##_p,             \
+   __builtin_choose_expr(sizeof(*(hptr)) == 8, ldq_##e##_p, abort))))   \
+     (hptr)), (void)0)
+
+#ifdef TARGET_WORDS_BIGENDIAN
+# define __put_user(x, hptr)  __put_user_e(x, hptr, be)
+# define __get_user(x, hptr)  __get_user_e(x, hptr, be)
+#else
+# define __put_user(x, hptr)  __put_user_e(x, hptr, le)
+# define __get_user(x, hptr)  __get_user_e(x, hptr, le)
+#endif
+
+/* put_user()/get_user() take a guest address and check access */
+/* These are usually used to access an atomic data type, such as an int,
+ * that has been passed by address.  These internally perform locking
+ * and unlocking on the data type.
+ */
+#define put_user(x, gaddr, target_type)
    \
+({                                                                     \
+    abi_ulong __gaddr = (gaddr);                                       \
+    target_type *__hptr;                                               \
+    abi_long __ret = 0;
    \
+    if ((__hptr = lock_user(VERIFY_WRITE, __gaddr, sizeof(target_type),
0))) { \
+        __put_user((x), __hptr);                               \
+        unlock_user(__hptr, __gaddr, sizeof(target_type));             \
+    } else                                                             \
+        __ret = -TARGET_EFAULT;
    \
+    __ret;                                                             \
+})
+
+#define get_user(x, gaddr, target_type)
    \
+({                                                                     \
+    abi_ulong __gaddr = (gaddr);                                       \
+    target_type *__hptr;                                               \
+    abi_long __ret = 0;
    \
+    if ((__hptr = lock_user(VERIFY_READ, __gaddr, sizeof(target_type),
1))) { \
+        __get_user((x), __hptr);                               \
+        unlock_user(__hptr, __gaddr, 0);                               \
+    } else {                                                           \
+        /* avoid warning */                                            \
+        (x) = 0;                                                       \
+        __ret = -TARGET_EFAULT;
    \
+    }                                                                  \
+    __ret;                                                             \
+})
+
+#define put_user_ual(x, gaddr) put_user((x), (gaddr), abi_ulong)
+#define put_user_sal(x, gaddr) put_user((x), (gaddr), abi_long)
+#define put_user_u64(x, gaddr) put_user((x), (gaddr), uint64_t)
+#define put_user_s64(x, gaddr) put_user((x), (gaddr), int64_t)
+#define put_user_u32(x, gaddr) put_user((x), (gaddr), uint32_t)
+#define put_user_s32(x, gaddr) put_user((x), (gaddr), int32_t)
+#define put_user_u16(x, gaddr) put_user((x), (gaddr), uint16_t)
+#define put_user_s16(x, gaddr) put_user((x), (gaddr), int16_t)
+#define put_user_u8(x, gaddr)  put_user((x), (gaddr), uint8_t)
+#define put_user_s8(x, gaddr)  put_user((x), (gaddr), int8_t)
+
+#define get_user_ual(x, gaddr) get_user((x), (gaddr), abi_ulong)
+#define get_user_sal(x, gaddr) get_user((x), (gaddr), abi_long)
+#define get_user_u64(x, gaddr) get_user((x), (gaddr), uint64_t)
+#define get_user_s64(x, gaddr) get_user((x), (gaddr), int64_t)
+#define get_user_u32(x, gaddr) get_user((x), (gaddr), uint32_t)
+#define get_user_s32(x, gaddr) get_user((x), (gaddr), int32_t)
+#define get_user_u16(x, gaddr) get_user((x), (gaddr), uint16_t)
+#define get_user_s16(x, gaddr) get_user((x), (gaddr), int16_t)
+#define get_user_u8(x, gaddr)  get_user((x), (gaddr), uint8_t)
+#define get_user_s8(x, gaddr)  get_user((x), (gaddr), int8_t)
+
+/* copy_from_user() and copy_to_user() are usually used to copy data
+ * buffers between the target and host.  These internally perform
+ * locking/unlocking of the memory.
+ */
+abi_long copy_from_user(void *hptr, abi_ulong gaddr, size_t len);
+abi_long copy_to_user(abi_ulong gaddr, void *hptr, size_t len);
+
+/* Functions for accessing guest memory.  The tget and tput functions
+   read/write single values, byteswapping as necessary.  The lock_user
function
+   gets a pointer to a contiguous area of guest memory, but does not
perform
+   any byteswapping.  lock_user may return either a pointer to the guest
+   memory, or a temporary buffer.  */
+
+/* Lock an area of guest memory into the host.  If copy is true then the
+   host area will have the same contents as the guest.  */
+static inline void *lock_user(int type, abi_ulong guest_addr, long len,
int copy)
+{
+    if (!access_ok(type, guest_addr, len))
+        return NULL;
+#ifdef DEBUG_REMAP
+    {
+        void *addr;
+        addr = g_malloc(len);
+        if (copy)
+            memcpy(addr, g2h(guest_addr), len);
+        else
+            memset(addr, 0, len);
+        return addr;
+    }
+#else
+    return g2h(guest_addr);
+#endif
+}
+
+/* Unlock an area of guest memory.  The first LEN bytes must be
+   flushed back to guest memory. host_ptr = NULL is explicitly
+   allowed and does nothing. */
+static inline void unlock_user(void *host_ptr, abi_ulong guest_addr,
+                               long len)
+{
+
+#ifdef DEBUG_REMAP
+    if (!host_ptr)
+        return;
+    if (host_ptr == g2h(guest_addr))
+        return;
+    if (len > 0)
+        memcpy(g2h(guest_addr), host_ptr, len);
+    g_free(host_ptr);
+#endif
+}
+
+/* Return the length of a string in target memory or -TARGET_EFAULT if
+   access error. */
+abi_long target_strlen(abi_ulong gaddr);
+
+/* Like lock_user but for null terminated strings.  */
+static inline void *lock_user_string(abi_ulong guest_addr)
+{
+    abi_long len;
+    len = target_strlen(guest_addr);
+    if (len < 0)
+        return NULL;
+    return lock_user(VERIFY_READ, guest_addr, (long)(len + 1), 1);
+}
+
+/* Helper macros for locking/unlocking a target struct.  */
+#define lock_user_struct(type, host_ptr, guest_addr, copy)     \
+    (host_ptr = lock_user(type, guest_addr, sizeof(*host_ptr), copy))
+#define unlock_user_struct(host_ptr, guest_addr, copy)         \
+    unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
+
+#endif /* QEMU_USER_COMMON_H */
--
2.11.0


-- 
Marc-André Lureau

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

* Re: [Qemu-devel] [RFC PATCH 1/3] Factor out {linux, bsd}-user/qemu.h
  2017-01-21  8:45 ` [Qemu-devel] [RFC PATCH 1/3] Factor out {linux,bsd}-user/qemu.h Alessandro Di Federico
  2017-01-24 10:10   ` [Qemu-devel] [RFC PATCH 1/3] Factor out {linux, bsd}-user/qemu.h Marc-André Lureau
@ 2017-01-24 11:18   ` Peter Maydell
  2017-01-25  7:38     ` Alessandro Di Federico
  1 sibling, 1 reply; 15+ messages in thread
From: Peter Maydell @ 2017-01-24 11:18 UTC (permalink / raw)
  To: Alessandro Di Federico; +Cc: QEMU Developers

On 21 January 2017 at 08:45, Alessandro Di Federico
<ale+qemu@clearmind.me> wrote:
> A quite large part of {linux,bsd}-user/qemu.h is shared, this patch
> introduces qemu-user-common.h which factors it out. This shared part is
> also the bare minimum required to build a linux-user-like target, and,
> in particular, it will be useful for the libtcg targets.
> ---
>  bsd-user/qemu.h    | 193 +----------------------------------------------------
>  linux-user/qemu.h  | 176 +-----------------------------------------------
>  qemu-user-common.h | 180 +++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 182 insertions(+), 367 deletions(-)
>  create mode 100644 qemu-user-common.h

So my issue with this is that currently linux-user is pretty
well maintained and tested, but bsd-user is basically unmaintained
and not even compile tested. So it's convenient to have bsd-user
code be basically its own distinct standalone thing, because
then when we fix linux-user we don't have to care too much
about whether bsd-user might be accidentally broken by our
changes.

If we had more active testing of bsd-user I'd be a bit keener
about removing some of the code duplication.

thanks
-- PMM

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

* Re: [Qemu-devel] [RFC PATCH 1/3] Factor out {linux, bsd}-user/qemu.h
  2017-01-24 10:10   ` [Qemu-devel] [RFC PATCH 1/3] Factor out {linux, bsd}-user/qemu.h Marc-André Lureau
@ 2017-01-25  7:37     ` Alessandro Di Federico
  0 siblings, 0 replies; 15+ messages in thread
From: Alessandro Di Federico @ 2017-01-25  7:37 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

On Tue, 24 Jan 2017 10:10:08 +0000
Marc-André Lureau <marcandre.lureau@gmail.com> wrote:

> 
> Looks good. Probably worth to mention that the main difference is in
> commit 658f2dc970996d547a641b5685e384ebe6f2648e not being applied to
> bsd-user.
> 

Yeah, I'll rebase my next patches on master.

My only doubt about this patch was whether the linux-* and bsd-*
implementations of put_user are equivalent. The linux one seems more
optimized, but they look equivalent to me.

--
Alessandro Di Federico
PhD student at Politecnico di Milano

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

* Re: [Qemu-devel] [RFC PATCH 3/3] Introduce libtcg infrastructure
  2017-01-24 10:08   ` Marc-André Lureau
@ 2017-01-25  7:37     ` Alessandro Di Federico
  0 siblings, 0 replies; 15+ messages in thread
From: Alessandro Di Federico @ 2017-01-25  7:37 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

On Tue, 24 Jan 2017 10:08:56 +0000
Marc-André Lureau <marcandre.lureau@gmail.com> wrote:

>
> > * If there's at least a *-libtcg, compile everything as position
> >   independent code.
> 
> why not limit it to libtcg code?
> 

At least we have to enable it on "common" object files (those compiled
only once, independently from the current target), therefore I see
little benefit in compiling without PIC other object files.
I also think it might be a good idea to switch to PIE executables
altogether.

> 
> > * In case we're building libtcg, install the output binary in the
> >   $PREFIX/lib directory instead of $PREFIX/bin.
> >  
> 
> If it's installed globally, I think we have to deal with versioning,
> common prefix, and list of visible symbols.
> 

Yeah, for symbol visibility I was thinking to force all the symbols to
be hidden except for those in tcg.c, which would have a `tcg_` prefix.
I didn't think about versioning yet.

> 
> What's the plan with this tcg.c? Shouldn't the functions be stubs or
> library user callbacks?
> 
> What is test() doing?
> 
> Please add a libtcg test under tests/ (even minimal, like a basic
> translate/dump).
> 

This patch was to get a first round of opinions. The test function was
only supposed to reference some functions I know I'll use to make sure
that I'm linking in all the required object files.
In the next set of patches I'll provide something that actually does
something.

> 
> >
> >  ifdef CONFIG_USER_ONLY
> > +ifdef CONFIG_LIBTCG
> > +# libtcg
> > +QEMU_PROG=libtcg-$(TARGET_NAME)$(DSOSUF)
> > +QEMU_PROG_BUILD = $(QEMU_PROG)
> > +QEMU_CFLAGS+=-fPIC
> > +
> > +# Change the install directory
> > +PROGS_INSTALL_DIR := $(libdir)
> >  
> 
> okay, we may want to rename it to something like QEMU_BUILD perhaps
> 

You mean the QEMU_PROG_BUILD? ACK.

>
> >  install: all
> > +ifdef CONFIG_LIBTINYCODE
> > +       $(INSTALL_DATA) $(SRC_PATH)/tcg/tcg-opc.h
> > $(SRC_PATH)/libtcg/tcg.h "$(DESTDIR)$(includedir)"
> > +endif
> >  
> 
> LIBTINYCODE/LIBTCG?
> 

Leftover from my internal version.

>
> > -crypto-obj-y += aes.o
> > +crypto-obj-$(call lnot,$(CONFIG_LIBTCG)) += aes.o
> >  
> 
> why that change?
> 

aes.o was being linked in, but we don't use it in LIBTCG. Maybe this
should be fixed in an higher level.

> 
> > diff --git a/libtcg/tcg.h b/libtcg/tcg.h
> > new file mode 100644
> > index 0000000000..e69de29bb2
> >  
> 
> What is this empty file for?
> 

Just a placeholder for the header file to install. This patch goal was
to show all the changes to the build system.

Thanks for the comments.

--
Alessandro Di Federico
PhD student at Politecnico di Milano

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

* Re: [Qemu-devel] [RFC PATCH 2/3] *-user targets object files decoupling
  2017-01-24 10:09   ` Marc-André Lureau
@ 2017-01-25  7:38     ` Alessandro Di Federico
  0 siblings, 0 replies; 15+ messages in thread
From: Alessandro Di Federico @ 2017-01-25  7:38 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: qemu-devel

On Tue, 24 Jan 2017 10:09:25 +0000
Marc-André Lureau <marcandre.lureau@gmail.com> wrote:

>
> diff --git a/exec.c b/exec.c
> index 47835c1dc1..66f8187281 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -672,9 +672,11 @@ void cpu_exec_unrealizefn(CPUState *cpu)
>      if (cc->vmsd != NULL) {
>          vmstate_unregister(NULL, cc->vmsd, cpu);
>      }
> +#ifndef CONFIG_USER_ONLY
>      if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
>          vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
>      }
> +#endif
> 
> 
> Shouldn't this #ifndef block also include the vmsd
> vmstate_unregister() above? That would be matching
> cpu_exec_realizefn() #ifndef.
> 

IIRC the idea here was to break a depency introduced by
"vmstate_cpu_common".
I'll include the previous if statement in the `ifndef`.

Let me know if I missed a comment on this patch.

--
Alessandro Di Federico
PhD student at Politecnico di Milano

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

* Re: [Qemu-devel] [RFC PATCH 1/3] Factor out {linux, bsd}-user/qemu.h
  2017-01-24 11:18   ` Peter Maydell
@ 2017-01-25  7:38     ` Alessandro Di Federico
  2017-02-07 17:25       ` Peter Maydell
  0 siblings, 1 reply; 15+ messages in thread
From: Alessandro Di Federico @ 2017-01-25  7:38 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

On Tue, 24 Jan 2017 11:18:07 +0000
Peter Maydell <peter.maydell@linaro.org> wrote:

> So my issue with this is that currently linux-user is pretty
> well maintained and tested, but bsd-user is basically unmaintained
> and not even compile tested. 

I can say it compiles. I've tried to build it on FreeBSD 11. Didn't
tested it though.

> So it's convenient to have bsd-user code be basically its own
> distinct standalone thing, because then when we fix linux-user we
> don't have to care too much about whether bsd-user might be
> accidentally broken by our changes.
> 
> If we had more active testing of bsd-user I'd be a bit keener
> about removing some of the code duplication.

Currently, the code looks exactly the same to me. If we don't factor it
out I'll have to make a third copy of it for libtcg, which is kinda
annoying. I'm factoring out only a portion of the header, which
probably doesn't change that much. If in the future there's some change
we're not sure about we can keep it in the non-factored out part.

I'll check if qemu-user for BSD has something in the testsuite.

--
Alessandro Di Federico
PhD student at Politecnico di Milano

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

* Re: [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg
  2017-01-21  8:45 [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg Alessandro Di Federico
                   ` (3 preceding siblings ...)
  2017-01-21  9:01 ` [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg no-reply
@ 2017-02-07 11:40 ` Peter Maydell
  4 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2017-02-07 11:40 UTC (permalink / raw)
  To: Alessandro Di Federico; +Cc: QEMU Developers

On 21 January 2017 at 08:45, Alessandro Di Federico
<ale+qemu@clearmind.me> wrote:
> This series of patches introduce a set of changes, mainly to the QEMU
> build system, to open the way to implementing "libtcg", i.e., using
> QEMU's tiny code generator frontends as a library.
>
> For the initial proposal, please see the related discussion:
>
> http://lists.nongnu.org/archive/html/qemu-devel/2016-11/msg04847.html
>
> The idea is to build a PIC version of QEMU embedding only what's
> required to use the TCG frontend (typically
> target/$arch/translate.c). To achieve this, some functions have been
> moved out of translate.c to reduce the coupling with the other object
> files.
>
> All the configurations available on Linux and FreeBSD still build fine
> (without warnings).
>
> The last commit also introduces the libtcg/ directory and a series of
> *-libtcg targets (similar to the *-{bsd,linux}-user) with the bare
> minimum skeleton for the actual implementation and some dummy references
> to some functions that in my previous implementation of libtcg were
> required, to make sure that all the required object files are linked in.

So I guess my question here is: how are we defining the boundary
between libtcg and everything else? How do we disentangle or
abstract away cleanly the parts of a guest CPU frontend that are
annoyingly tightly coupled to the rest of the system model? Some
examples:
 * CPU instructions for reading timers (either cycle counts,
   or real-time timers)
 * CPU instructions that need to update interrupt controller
   state (the ARM M profile CPUs have a bunch of these, as
   do GICv3 ARM CPUs)
 * CPUs where some CPU state is accessed via memory mapped
   registers (again, M profile CPUs have a lot of that)

I think this is overall a good idea but I think I'll find it
easier to review if I have a more solid idea of the design
principles and where we're trying to draw dividing lines
in the tricky cases.

thanks
-- PMM

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

* Re: [Qemu-devel] [RFC PATCH 1/3] Factor out {linux, bsd}-user/qemu.h
  2017-01-25  7:38     ` Alessandro Di Federico
@ 2017-02-07 17:25       ` Peter Maydell
  0 siblings, 0 replies; 15+ messages in thread
From: Peter Maydell @ 2017-02-07 17:25 UTC (permalink / raw)
  To: Alessandro Di Federico; +Cc: QEMU Developers

On 25 January 2017 at 07:38, Alessandro Di Federico
<ale+qemu@clearmind.me> wrote:
> On Tue, 24 Jan 2017 11:18:07 +0000
> Peter Maydell <peter.maydell@linaro.org> wrote:
>> If we had more active testing of bsd-user I'd be a bit keener
>> about removing some of the code duplication.
>
> Currently, the code looks exactly the same to me. If we don't factor it
> out I'll have to make a third copy of it for libtcg, which is kinda
> annoying. I'm factoring out only a portion of the header, which
> probably doesn't change that much. If in the future there's some change
> we're not sure about we can keep it in the non-factored out part.

OK, fair enough.

Regarding whether the linux-* and bsd-* put_user are equivalent,
they should be; it's just that bsd-* doesn't get fixes that
we make to linux-* because it's unmaintained code.

thanks
-- PMM

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

end of thread, other threads:[~2017-02-07 17:25 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-21  8:45 [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg Alessandro Di Federico
2017-01-21  8:45 ` [Qemu-devel] [RFC PATCH 1/3] Factor out {linux,bsd}-user/qemu.h Alessandro Di Federico
2017-01-24 10:10   ` [Qemu-devel] [RFC PATCH 1/3] Factor out {linux, bsd}-user/qemu.h Marc-André Lureau
2017-01-25  7:37     ` Alessandro Di Federico
2017-01-24 11:18   ` Peter Maydell
2017-01-25  7:38     ` Alessandro Di Federico
2017-02-07 17:25       ` Peter Maydell
2017-01-21  8:45 ` [Qemu-devel] [RFC PATCH 2/3] *-user targets object files decoupling Alessandro Di Federico
2017-01-24 10:09   ` Marc-André Lureau
2017-01-25  7:38     ` Alessandro Di Federico
2017-01-21  8:46 ` [Qemu-devel] [RFC PATCH 3/3] Introduce libtcg infrastructure Alessandro Di Federico
2017-01-24 10:08   ` Marc-André Lureau
2017-01-25  7:37     ` Alessandro Di Federico
2017-01-21  9:01 ` [Qemu-devel] [RFC PATCH 0/3] Preparing the build system for libtcg no-reply
2017-02-07 11:40 ` Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.