get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.2/patches/811191/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 811191,
    "url": "http://patchwork.ozlabs.org/api/1.2/patches/811191/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20170907224051.21518-2-richard.henderson@linaro.org/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/1.2/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170907224051.21518-2-richard.henderson@linaro.org>",
    "list_archive_url": null,
    "date": "2017-09-07T22:40:29",
    "name": "[PULL,01/23] tcg: Move USE_DIRECT_JUMP discriminator to tcg/cpu/tcg-target.h",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "09d565d1d8f075777a32e5d7720e2a13f5628458",
    "submitter": {
        "id": 72104,
        "url": "http://patchwork.ozlabs.org/api/1.2/people/72104/?format=api",
        "name": "Richard Henderson",
        "email": "richard.henderson@linaro.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20170907224051.21518-2-richard.henderson@linaro.org/mbox/",
    "series": [
        {
            "id": 2073,
            "url": "http://patchwork.ozlabs.org/api/1.2/series/2073/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=2073",
            "date": "2017-09-07T22:40:28",
            "name": "[PULL,01/23] tcg: Move USE_DIRECT_JUMP discriminator to tcg/cpu/tcg-target.h",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/2073/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/811191/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/811191/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=nongnu.org\n\t(client-ip=2001:4830:134:3::11; helo=lists.gnu.org;\n\tenvelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n\treceiver=<UNKNOWN>)",
            "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=linaro.org header.i=@linaro.org\n\theader.b=\"iNLY8+ec\"; dkim-atps=neutral"
        ],
        "Received": [
            "from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11])\n\t(using TLSv1 with cipher AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xpFnP28NRz9sDB\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri,  8 Sep 2017 08:42:01 +1000 (AEST)",
            "from localhost ([::1]:42515 helo=lists.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.71) (envelope-from\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1dq5Ul-00032H-C9\n\tfor incoming@patchwork.ozlabs.org; Thu, 07 Sep 2017 18:41:59 -0400",
            "from eggs.gnu.org ([2001:4830:134:3::10]:51931)\n\tby lists.gnu.org with esmtp (Exim 4.71)\n\t(envelope-from <richard.henderson@linaro.org>) id 1dq5Tr-0002xL-Fj\n\tfor qemu-devel@nongnu.org; Thu, 07 Sep 2017 18:41:09 -0400",
            "from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)\n\t(envelope-from <richard.henderson@linaro.org>) id 1dq5Tl-0007zB-At\n\tfor qemu-devel@nongnu.org; Thu, 07 Sep 2017 18:41:03 -0400",
            "from mail-pg0-x22c.google.com ([2607:f8b0:400e:c05::22c]:36680)\n\tby eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16)\n\t(Exim 4.71) (envelope-from <richard.henderson@linaro.org>)\n\tid 1dq5Tl-0007yM-1K\n\tfor qemu-devel@nongnu.org; Thu, 07 Sep 2017 18:40:57 -0400",
            "by mail-pg0-x22c.google.com with SMTP id m9so1817621pgd.3\n\tfor <qemu-devel@nongnu.org>; Thu, 07 Sep 2017 15:40:56 -0700 (PDT)",
            "from bigtime.twiddle.net (97-126-108-236.tukw.qwest.net.\n\t[97.126.108.236]) by smtp.gmail.com with ESMTPSA id\n\th19sm770678pfh.142.2017.09.07.15.40.53\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tThu, 07 Sep 2017 15:40:54 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=K/R2gnM8fsYbqRdhzqJY4H3SJFOLlrFJBxKGEBBoreY=;\n\tb=iNLY8+ecvky4JB4uUapfm0nOGvOqrFqFAx2w0GuGl28yTD0UGZooGTK1K3sZMCRV3X\n\t6rQwAPex0E7tVwHCq6K/s9nry6y64DTQbl168kUD2rDrpt0s7oodjtaEVj0X845O+yLU\n\tRgEwJAL9UMJe3PQkIj+oOMeWFwCcRlqn+Ypto=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=K/R2gnM8fsYbqRdhzqJY4H3SJFOLlrFJBxKGEBBoreY=;\n\tb=oSKPhGjubDENZCnqNae8X75DNK/lWST76zoadB740SdUwP4FMkfSCgb4xnZ2jGR2c9\n\tK8612Byi9/a2rJrdAED7vGfVfK6GbbfYRibmaQX98NM/hsT3B7G59AQIqOk1C4ZyAt/U\n\tBCcU/qkK2uPq3OSS+H3bZ/jQ9VhISU17eRL/scNrhfWiODd7bfLOvTGY64KxNPhOP0YG\n\tUvSxnEUCfJyUBM32Lsu21ECR075pEROPLuNPrl0ndrcEO7Y54cMrfW+C+L5gK1D1rH6R\n\tNlL7bCRlczhlwCDbZ0yEd/SyY25en/T639w0iTpO+vek2pBJg23FbjJx6G2QJPrHum1K\n\tZr8w==",
        "X-Gm-Message-State": "AHPjjUgbOtoTSJAeQA9UJqQ2U/SHy2oshpliyn9RIB5zVGUR6uT/7pQp\n\tlMABpOKY/ytrNSo8xiGQnw==",
        "X-Google-Smtp-Source": "ADKCNb7Np6c2Ybo7/EeNnjgrPnS3HZH0N9dIeH9x7iRLYC2mjV25hwXIsEx3i7s9zXTOn2MwIZRVBQ==",
        "X-Received": "by 10.98.10.146 with SMTP id 18mr952466pfk.346.1504824055503;\n\tThu, 07 Sep 2017 15:40:55 -0700 (PDT)",
        "From": "Richard Henderson <richard.henderson@linaro.org>",
        "To": "qemu-devel@nongnu.org",
        "Date": "Thu,  7 Sep 2017 15:40:29 -0700",
        "Message-Id": "<20170907224051.21518-2-richard.henderson@linaro.org>",
        "X-Mailer": "git-send-email 2.13.5",
        "In-Reply-To": "<20170907224051.21518-1-richard.henderson@linaro.org>",
        "References": "<20170907224051.21518-1-richard.henderson@linaro.org>",
        "X-detected-operating-system": "by eggs.gnu.org: Genre and OS details not\n\trecognized.",
        "X-Received-From": "2607:f8b0:400e:c05::22c",
        "Subject": "[Qemu-devel] [PULL 01/23] tcg: Move USE_DIRECT_JUMP discriminator\n\tto tcg/cpu/tcg-target.h",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.21",
        "Precedence": "list",
        "List-Id": "<qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.nongnu.org/archive/html/qemu-devel/>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Cc": "peter.maydell@linaro.org, Richard Henderson <rth@twiddle.net>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "\"Qemu-devel\"\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>"
    },
    "content": "From: Richard Henderson <rth@twiddle.net>\n\nReplace the USE_DIRECT_JUMP ifdef with a TCG_TARGET_HAS_direct_jump\nboolean test.  Replace the tb_set_jmp_target1 ifdef with an unconditional\nfunction tb_target_set_jmp_target.\n\nWhile we're touching all backends, add a parameter for tb->tc_ptr;\nwe're going to need it shortly for some backends.\n\nMove tb_set_jmp_target and tb_add_jump from exec-all.h to cpu-exec.c.\n\nThis opens the possibility for TCG_TARGET_HAS_direct_jump to be\na runtime decision -- based on host cpu capabilities, the size of\ncode_gen_buffer, or a future debugging switch.\n\nSigned-off-by: Richard Henderson <rth@twiddle.net>\n---\n include/exec/exec-all.h      | 95 ++------------------------------------------\n tcg/aarch64/tcg-target.h     |  5 ++-\n tcg/arm/tcg-target.h         |  6 ++-\n tcg/i386/tcg-target.h        |  9 +++++\n tcg/mips/tcg-target.h        |  5 ++-\n tcg/ppc/tcg-target.h         |  2 +\n tcg/s390/tcg-target.h        | 10 +++++\n tcg/sparc/tcg-target.h       |  3 ++\n tcg/tcg.h                    |  4 +-\n tcg/tci/tcg-target.h         |  9 +++++\n accel/tcg/cpu-exec.c         | 35 ++++++++++++++++\n accel/tcg/translate-all.c    | 14 +++----\n tcg/aarch64/tcg-target.inc.c | 13 +++---\n tcg/mips/tcg-target.inc.c    |  3 +-\n tcg/ppc/tcg-target.inc.c     |  6 ++-\n tcg/sparc/tcg-target.inc.c   |  3 +-\n 16 files changed, 106 insertions(+), 116 deletions(-)",
    "diff": "diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h\nindex ff8fbe423d..673fc066d0 100644\n--- a/include/exec/exec-all.h\n+++ b/include/exec/exec-all.h\n@@ -301,15 +301,6 @@ static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)\n #define CODE_GEN_AVG_BLOCK_SIZE 150\n #endif\n \n-#if defined(_ARCH_PPC) \\\n-    || defined(__x86_64__) || defined(__i386__) \\\n-    || defined(__sparc__) || defined(__aarch64__) \\\n-    || defined(__s390x__) || defined(__mips__) \\\n-    || defined(CONFIG_TCG_INTERPRETER)\n-/* NOTE: Direct jump patching must be atomic to be thread-safe. */\n-#define USE_DIRECT_JUMP\n-#endif\n-\n struct TranslationBlock {\n     target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS base) */\n     target_ulong cs_base; /* CS base for this block */\n@@ -347,11 +338,8 @@ struct TranslationBlock {\n      */\n     uint16_t jmp_reset_offset[2]; /* offset of original jump target */\n #define TB_JMP_RESET_OFFSET_INVALID 0xffff /* indicates no jump generated */\n-#ifdef USE_DIRECT_JUMP\n-    uint16_t jmp_insn_offset[2]; /* offset of native jump instruction */\n-#else\n-    uintptr_t jmp_target_addr[2]; /* target address for indirect jump */\n-#endif\n+    uintptr_t jmp_target_arg[2];  /* target address or offset */\n+\n     /* Each TB has an assosiated circular list of TBs jumping to this one.\n      * jmp_list_first points to the first TB jumping to this one.\n      * jmp_list_next is used to point to the next TB in a list.\n@@ -373,84 +361,7 @@ void tb_flush(CPUState *cpu);\n void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);\n TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,\n                                    target_ulong cs_base, uint32_t flags);\n-\n-#if defined(USE_DIRECT_JUMP)\n-\n-#if defined(CONFIG_TCG_INTERPRETER)\n-static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)\n-{\n-    /* patch the branch destination */\n-    atomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4));\n-    /* no need to flush icache explicitly */\n-}\n-#elif defined(_ARCH_PPC)\n-void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr);\n-#define tb_set_jmp_target1 ppc_tb_set_jmp_target\n-#elif defined(__i386__) || defined(__x86_64__)\n-static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)\n-{\n-    /* patch the branch destination */\n-    atomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4));\n-    /* no need to flush icache explicitly */\n-}\n-#elif defined(__s390x__)\n-static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)\n-{\n-    /* patch the branch destination */\n-    intptr_t disp = addr - (jmp_addr - 2);\n-    atomic_set((int32_t *)jmp_addr, disp / 2);\n-    /* no need to flush icache explicitly */\n-}\n-#elif defined(__aarch64__)\n-void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr);\n-#define tb_set_jmp_target1 aarch64_tb_set_jmp_target\n-#elif defined(__sparc__) || defined(__mips__)\n-void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);\n-#else\n-#error tb_set_jmp_target1 is missing\n-#endif\n-\n-static inline void tb_set_jmp_target(TranslationBlock *tb,\n-                                     int n, uintptr_t addr)\n-{\n-    uint16_t offset = tb->jmp_insn_offset[n];\n-    tb_set_jmp_target1((uintptr_t)(tb->tc_ptr + offset), addr);\n-}\n-\n-#else\n-\n-/* set the jump target */\n-static inline void tb_set_jmp_target(TranslationBlock *tb,\n-                                     int n, uintptr_t addr)\n-{\n-    tb->jmp_target_addr[n] = addr;\n-}\n-\n-#endif\n-\n-/* Called with tb_lock held.  */\n-static inline void tb_add_jump(TranslationBlock *tb, int n,\n-                               TranslationBlock *tb_next)\n-{\n-    assert(n < ARRAY_SIZE(tb->jmp_list_next));\n-    if (tb->jmp_list_next[n]) {\n-        /* Another thread has already done this while we were\n-         * outside of the lock; nothing to do in this case */\n-        return;\n-    }\n-    qemu_log_mask_and_addr(CPU_LOG_EXEC, tb->pc,\n-                           \"Linking TBs %p [\" TARGET_FMT_lx\n-                           \"] index %d -> %p [\" TARGET_FMT_lx \"]\\n\",\n-                           tb->tc_ptr, tb->pc, n,\n-                           tb_next->tc_ptr, tb_next->pc);\n-\n-    /* patch the native jump address */\n-    tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr);\n-\n-    /* add in TB jmp circular list */\n-    tb->jmp_list_next[n] = tb_next->jmp_list_first;\n-    tb_next->jmp_list_first = (uintptr_t)tb | n;\n-}\n+void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr);\n \n /* GETPC is the true target of the return instruction that we'll execute.  */\n #if defined(CONFIG_TCG_INTERPRETER)\ndiff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h\nindex b41a248bee..719861fe3e 100644\n--- a/tcg/aarch64/tcg-target.h\n+++ b/tcg/aarch64/tcg-target.h\n@@ -111,12 +111,15 @@ typedef enum {\n #define TCG_TARGET_HAS_muls2_i64        0\n #define TCG_TARGET_HAS_muluh_i64        1\n #define TCG_TARGET_HAS_mulsh_i64        1\n+#define TCG_TARGET_HAS_direct_jump      1\n+\n+#define TCG_TARGET_DEFAULT_MO (0)\n \n static inline void flush_icache_range(uintptr_t start, uintptr_t stop)\n {\n     __builtin___clear_cache((char *)start, (char *)stop);\n }\n \n-#define TCG_TARGET_DEFAULT_MO (0)\n+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);\n \n #endif /* AARCH64_TCG_TARGET_H */\ndiff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h\nindex a38be15a39..7117ebf4fc 100644\n--- a/tcg/arm/tcg-target.h\n+++ b/tcg/arm/tcg-target.h\n@@ -124,16 +124,20 @@ extern bool use_idiv_instructions;\n #define TCG_TARGET_HAS_div_i32          use_idiv_instructions\n #define TCG_TARGET_HAS_rem_i32          0\n #define TCG_TARGET_HAS_goto_ptr         1\n+#define TCG_TARGET_HAS_direct_jump      0\n \n enum {\n     TCG_AREG0 = TCG_REG_R6,\n };\n \n+#define TCG_TARGET_DEFAULT_MO (0)\n+\n static inline void flush_icache_range(uintptr_t start, uintptr_t stop)\n {\n     __builtin___clear_cache((char *) start, (char *) stop);\n }\n \n-#define TCG_TARGET_DEFAULT_MO (0)\n+/* not defined -- call should be eliminated at compile time */\n+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);\n \n #endif\ndiff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h\nindex 73a15f7e80..2fd28fa6a5 100644\n--- a/tcg/i386/tcg-target.h\n+++ b/tcg/i386/tcg-target.h\n@@ -108,6 +108,7 @@ extern bool have_popcnt;\n #define TCG_TARGET_HAS_muluh_i32        0\n #define TCG_TARGET_HAS_mulsh_i32        0\n #define TCG_TARGET_HAS_goto_ptr         1\n+#define TCG_TARGET_HAS_direct_jump      1\n \n #if TCG_TARGET_REG_BITS == 64\n #define TCG_TARGET_HAS_extrl_i64_i32    0\n@@ -166,6 +167,14 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop)\n {\n }\n \n+static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,\n+                                            uintptr_t jmp_addr, uintptr_t addr)\n+{\n+    /* patch the branch destination */\n+    atomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4));\n+    /* no need to flush icache explicitly */\n+}\n+\n /* This defines the natural memory order supported by this\n  * architecture before guarantees made by various barrier\n  * instructions.\ndiff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h\nindex e9558d15bc..928a762bd7 100644\n--- a/tcg/mips/tcg-target.h\n+++ b/tcg/mips/tcg-target.h\n@@ -131,6 +131,7 @@ extern bool use_mips32r2_instructions;\n #define TCG_TARGET_HAS_mulsh_i32        1\n #define TCG_TARGET_HAS_bswap32_i32      1\n #define TCG_TARGET_HAS_goto_ptr         1\n+#define TCG_TARGET_HAS_direct_jump      1\n \n #if TCG_TARGET_REG_BITS == 64\n #define TCG_TARGET_HAS_add2_i32         0\n@@ -201,11 +202,13 @@ extern bool use_mips32r2_instructions;\n #include <sys/cachectl.h>\n #endif\n \n+#define TCG_TARGET_DEFAULT_MO (0)\n+\n static inline void flush_icache_range(uintptr_t start, uintptr_t stop)\n {\n     cacheflush ((void *)start, stop-start, ICACHE);\n }\n \n-#define TCG_TARGET_DEFAULT_MO (0)\n+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);\n \n #endif\ndiff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h\nindex 5a092b038a..aa44e715d8 100644\n--- a/tcg/ppc/tcg-target.h\n+++ b/tcg/ppc/tcg-target.h\n@@ -83,6 +83,7 @@ extern bool have_isa_3_00;\n #define TCG_TARGET_HAS_muluh_i32        1\n #define TCG_TARGET_HAS_mulsh_i32        1\n #define TCG_TARGET_HAS_goto_ptr         1\n+#define TCG_TARGET_HAS_direct_jump      1\n \n #if TCG_TARGET_REG_BITS == 64\n #define TCG_TARGET_HAS_add2_i32         0\n@@ -124,6 +125,7 @@ extern bool have_isa_3_00;\n #endif\n \n void flush_icache_range(uintptr_t start, uintptr_t stop);\n+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);\n \n #define TCG_TARGET_DEFAULT_MO (0)\n \ndiff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h\nindex bedda5edf6..31a9eb4ac7 100644\n--- a/tcg/s390/tcg-target.h\n+++ b/tcg/s390/tcg-target.h\n@@ -95,6 +95,7 @@ extern uint64_t s390_facilities;\n #define TCG_TARGET_HAS_extrl_i64_i32  0\n #define TCG_TARGET_HAS_extrh_i64_i32  0\n #define TCG_TARGET_HAS_goto_ptr       1\n+#define TCG_TARGET_HAS_direct_jump    1\n \n #define TCG_TARGET_HAS_div2_i64       1\n #define TCG_TARGET_HAS_rot_i64        1\n@@ -145,4 +146,13 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop)\n {\n }\n \n+static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,\n+                                            uintptr_t jmp_addr, uintptr_t addr)\n+{\n+    /* patch the branch destination */\n+    intptr_t disp = addr - (jmp_addr - 2);\n+    atomic_set((int32_t *)jmp_addr, disp / 2);\n+    /* no need to flush icache explicitly */\n+}\n+\n #endif\ndiff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h\nindex 4515c9ab48..da98743817 100644\n--- a/tcg/sparc/tcg-target.h\n+++ b/tcg/sparc/tcg-target.h\n@@ -124,6 +124,7 @@ extern bool use_vis3_instructions;\n #define TCG_TARGET_HAS_muluh_i32        0\n #define TCG_TARGET_HAS_mulsh_i32        0\n #define TCG_TARGET_HAS_goto_ptr         1\n+#define TCG_TARGET_HAS_direct_jump      1\n \n #define TCG_TARGET_HAS_extrl_i64_i32    1\n #define TCG_TARGET_HAS_extrh_i64_i32    1\n@@ -172,4 +173,6 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop)\n     }\n }\n \n+void tb_target_set_jmp_target(uintptr_t, uintptr_t, uintptr_t);\n+\n #endif\ndiff --git a/tcg/tcg.h b/tcg/tcg.h\nindex 17b7750ee6..46957d9bd7 100644\n--- a/tcg/tcg.h\n+++ b/tcg/tcg.h\n@@ -652,8 +652,8 @@ struct TCGContext {\n     /* goto_tb support */\n     tcg_insn_unit *code_buf;\n     uint16_t *tb_jmp_reset_offset; /* tb->jmp_reset_offset */\n-    uint16_t *tb_jmp_insn_offset; /* tb->jmp_insn_offset if USE_DIRECT_JUMP */\n-    uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_addr if !USE_DIRECT_JUMP */\n+    uintptr_t *tb_jmp_insn_offset; /* tb->jmp_target_arg if direct_jump */\n+    uintptr_t *tb_jmp_target_addr; /* tb->jmp_target_arg if !direct_jump */\n \n     TCGRegSet reserved_regs;\n     intptr_t current_frame_offset;\ndiff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h\nindex 8df628a319..26140d78cb 100644\n--- a/tcg/tci/tcg-target.h\n+++ b/tcg/tci/tcg-target.h\n@@ -86,6 +86,7 @@\n #define TCG_TARGET_HAS_muluh_i32        0\n #define TCG_TARGET_HAS_mulsh_i32        0\n #define TCG_TARGET_HAS_goto_ptr         0\n+#define TCG_TARGET_HAS_direct_jump      1\n \n #if TCG_TARGET_REG_BITS == 64\n #define TCG_TARGET_HAS_extrl_i64_i32    0\n@@ -197,4 +198,12 @@ static inline void flush_icache_range(uintptr_t start, uintptr_t stop)\n    We prefer consistency across hosts on this.  */\n #define TCG_TARGET_DEFAULT_MO  (0)\n \n+static inline void tb_target_set_jmp_target(uintptr_t tc_ptr,\n+                                            uintptr_t jmp_addr, uintptr_t addr)\n+{\n+    /* patch the branch destination */\n+    atomic_set((int32_t *)jmp_addr, addr - (jmp_addr + 4));\n+    /* no need to flush icache explicitly */\n+}\n+\n #endif /* TCG_TARGET_H */\ndiff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c\nindex d84b01d1b8..ff6866624a 100644\n--- a/accel/tcg/cpu-exec.c\n+++ b/accel/tcg/cpu-exec.c\n@@ -329,6 +329,41 @@ TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,\n     return qht_lookup(&tcg_ctx.tb_ctx.htable, tb_cmp, &desc, h);\n }\n \n+void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr)\n+{\n+    if (TCG_TARGET_HAS_direct_jump) {\n+        uintptr_t offset = tb->jmp_target_arg[n];\n+        uintptr_t tc_ptr = (uintptr_t)tb->tc_ptr;\n+        tb_target_set_jmp_target(tc_ptr, tc_ptr + offset, addr);\n+    } else {\n+        tb->jmp_target_arg[n] = addr;\n+    }\n+}\n+\n+/* Called with tb_lock held.  */\n+static inline void tb_add_jump(TranslationBlock *tb, int n,\n+                               TranslationBlock *tb_next)\n+{\n+    assert(n < ARRAY_SIZE(tb->jmp_list_next));\n+    if (tb->jmp_list_next[n]) {\n+        /* Another thread has already done this while we were\n+         * outside of the lock; nothing to do in this case */\n+        return;\n+    }\n+    qemu_log_mask_and_addr(CPU_LOG_EXEC, tb->pc,\n+                           \"Linking TBs %p [\" TARGET_FMT_lx\n+                           \"] index %d -> %p [\" TARGET_FMT_lx \"]\\n\",\n+                           tb->tc_ptr, tb->pc, n,\n+                           tb_next->tc_ptr, tb_next->pc);\n+\n+    /* patch the native jump address */\n+    tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr);\n+\n+    /* add in TB jmp circular list */\n+    tb->jmp_list_next[n] = tb_next->jmp_list_first;\n+    tb_next->jmp_list_first = (uintptr_t)tb | n;\n+}\n+\n static inline TranslationBlock *tb_find(CPUState *cpu,\n                                         TranslationBlock *last_tb,\n                                         int tb_exit)\ndiff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c\nindex 37ecafa931..93a1cf2ba8 100644\n--- a/accel/tcg/translate-all.c\n+++ b/accel/tcg/translate-all.c\n@@ -1289,13 +1289,13 @@ TranslationBlock *tb_gen_code(CPUState *cpu,\n     tb->jmp_reset_offset[0] = TB_JMP_RESET_OFFSET_INVALID;\n     tb->jmp_reset_offset[1] = TB_JMP_RESET_OFFSET_INVALID;\n     tcg_ctx.tb_jmp_reset_offset = tb->jmp_reset_offset;\n-#ifdef USE_DIRECT_JUMP\n-    tcg_ctx.tb_jmp_insn_offset = tb->jmp_insn_offset;\n-    tcg_ctx.tb_jmp_target_addr = NULL;\n-#else\n-    tcg_ctx.tb_jmp_insn_offset = NULL;\n-    tcg_ctx.tb_jmp_target_addr = tb->jmp_target_addr;\n-#endif\n+    if (TCG_TARGET_HAS_direct_jump) {\n+        tcg_ctx.tb_jmp_insn_offset = tb->jmp_target_arg;\n+        tcg_ctx.tb_jmp_target_addr = NULL;\n+    } else {\n+        tcg_ctx.tb_jmp_insn_offset = NULL;\n+        tcg_ctx.tb_jmp_target_addr = tb->jmp_target_arg;\n+    }\n \n #ifdef CONFIG_PROFILER\n     tcg_ctx.tb_count++;\ndiff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c\nindex 04bc369a92..a1e5dd2f03 100644\n--- a/tcg/aarch64/tcg-target.inc.c\n+++ b/tcg/aarch64/tcg-target.inc.c\n@@ -871,9 +871,8 @@ static inline void tcg_out_call(TCGContext *s, tcg_insn_unit *target)\n     }\n }\n \n-#ifdef USE_DIRECT_JUMP\n-\n-void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)\n+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,\n+                              uintptr_t addr)\n {\n     tcg_insn_unit i1, i2;\n     TCGType rt = TCG_TYPE_I64;\n@@ -898,8 +897,6 @@ void aarch64_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)\n     flush_icache_range(jmp_addr, jmp_addr + 8);\n }\n \n-#endif\n-\n static inline void tcg_out_goto_label(TCGContext *s, TCGLabel *l)\n {\n     if (!l->has_value) {\n@@ -1412,7 +1409,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,\n \n     case INDEX_op_goto_tb:\n         if (s->tb_jmp_insn_offset != NULL) {\n-            /* USE_DIRECT_JUMP */\n+            /* TCG_TARGET_HAS_direct_jump */\n             /* Ensure that ADRP+ADD are 8-byte aligned so that an atomic\n                write can be used to patch the target address. */\n             if ((uintptr_t)s->code_ptr & 7) {\n@@ -1420,11 +1417,11 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,\n             }\n             s->tb_jmp_insn_offset[a0] = tcg_current_code_size(s);\n             /* actual branch destination will be patched by\n-               aarch64_tb_set_jmp_target later. */\n+               tb_target_set_jmp_target later. */\n             tcg_out_insn(s, 3406, ADRP, TCG_REG_TMP, 0);\n             tcg_out_insn(s, 3401, ADDI, TCG_TYPE_I64, TCG_REG_TMP, TCG_REG_TMP, 0);\n         } else {\n-            /* !USE_DIRECT_JUMP */\n+            /* !TCG_TARGET_HAS_direct_jump */\n             tcg_debug_assert(s->tb_jmp_target_addr != NULL);\n             intptr_t offset = tcg_pcrel_diff(s, (s->tb_jmp_target_addr + a0)) >> 2;\n             tcg_out_insn(s, 3305, LDR, offset, TCG_REG_TMP);\ndiff --git a/tcg/mips/tcg-target.inc.c b/tcg/mips/tcg-target.inc.c\nindex 1a8169f5fc..04f8c839fe 100644\n--- a/tcg/mips/tcg-target.inc.c\n+++ b/tcg/mips/tcg-target.inc.c\n@@ -2642,7 +2642,8 @@ static void tcg_target_init(TCGContext *s)\n     tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);   /* global pointer */\n }\n \n-void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)\n+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,\n+                              uintptr_t addr)\n {\n     atomic_set((uint32_t *)jmp_addr, deposit32(OPC_J, 0, 26, addr >> 2));\n     flush_icache_range(jmp_addr, jmp_addr + 4);\ndiff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c\nindex 1f690df20d..018c240f6d 100644\n--- a/tcg/ppc/tcg-target.inc.c\n+++ b/tcg/ppc/tcg-target.inc.c\n@@ -1296,7 +1296,8 @@ static void tcg_out_mb(TCGContext *s, TCGArg a0)\n }\n \n #ifdef __powerpc64__\n-void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)\n+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,\n+                              uintptr_t addr)\n {\n     tcg_insn_unit i1, i2;\n     uint64_t pair;\n@@ -1328,7 +1329,8 @@ void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)\n     flush_icache_range(jmp_addr, jmp_addr + 8);\n }\n #else\n-void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr)\n+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,\n+                              uintptr_t addr)\n {\n     intptr_t diff = addr - jmp_addr;\n     tcg_debug_assert(in_range_b(diff));\ndiff --git a/tcg/sparc/tcg-target.inc.c b/tcg/sparc/tcg-target.inc.c\nindex 18afce2f87..06cabbedf5 100644\n--- a/tcg/sparc/tcg-target.inc.c\n+++ b/tcg/sparc/tcg-target.inc.c\n@@ -1708,7 +1708,8 @@ void tcg_register_jit(void *buf, size_t buf_size)\n     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));\n }\n \n-void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)\n+void tb_target_set_jmp_target(uintptr_t tc_ptr, uintptr_t jmp_addr,\n+                              uintptr_t addr)\n {\n     uint32_t *ptr = (uint32_t *)jmp_addr;\n     uintptr_t disp = addr - jmp_addr;\n",
    "prefixes": [
        "PULL",
        "01/23"
    ]
}