get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 98609,
    "url": "http://patchwork.dpdk.org/api/patches/98609/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20210910123003.85448-1-cristian.dumitrescu@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20210910123003.85448-1-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20210910123003.85448-1-cristian.dumitrescu@intel.com",
    "date": "2021-09-10T12:29:40",
    "name": "[01/24] pipeline: move data structures to internal header file",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "537451dfa005b163cfef9b7d6f8932747f9e532f",
    "submitter": {
        "id": 19,
        "url": "http://patchwork.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20210910123003.85448-1-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 18838,
            "url": "http://patchwork.dpdk.org/api/series/18838/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=18838",
            "date": "2021-09-10T12:29:44",
            "name": "[01/24] pipeline: move data structures to internal header file",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/18838/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/98609/comments/",
    "check": "warning",
    "checks": "http://patchwork.dpdk.org/api/patches/98609/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id B6DDFA0547;\n\tFri, 10 Sep 2021 14:31:09 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 9462641154;\n\tFri, 10 Sep 2021 14:30:29 +0200 (CEST)",
            "from mga01.intel.com (mga01.intel.com [192.55.52.88])\n by mails.dpdk.org (Postfix) with ESMTP id 6EEF740DDE\n for <dev@dpdk.org>; Fri, 10 Sep 2021 14:30:21 +0200 (CEST)",
            "from orsmga001.jf.intel.com ([10.7.209.18])\n by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 10 Sep 2021 05:30:05 -0700",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com) ([10.237.223.107])\n by orsmga001.jf.intel.com with ESMTP; 10 Sep 2021 05:30:04 -0700"
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6200,9189,10102\"; a=\"243386247\"",
            "E=Sophos;i=\"5.85,282,1624345200\"; d=\"scan'208\";a=\"243386247\"",
            "E=Sophos;i=\"5.85,282,1624345200\"; d=\"scan'208\";a=\"514279673\""
        ],
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Fri, 10 Sep 2021 13:29:40 +0100",
        "Message-Id": "<20210910123003.85448-1-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "Subject": "[dpdk-dev] [PATCH 01/24] pipeline: move data structures to internal\n header file",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Start to consolidate the data structures and inline functions required\nby the pipeline instructions into an internal header file.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\n---\nDepends-on: series-18297 (\"[V4,1/4] table: add support learner tables\")\n\n lib/pipeline/meson.build                 |    4 +\n lib/pipeline/rte_swx_pipeline.c          | 1373 +--------------------\n lib/pipeline/rte_swx_pipeline_internal.h | 1383 ++++++++++++++++++++++\n 3 files changed, 1388 insertions(+), 1372 deletions(-)\n create mode 100644 lib/pipeline/rte_swx_pipeline_internal.h",
    "diff": "diff --git a/lib/pipeline/meson.build b/lib/pipeline/meson.build\nindex 9132bb517a..ec009631bf 100644\n--- a/lib/pipeline/meson.build\n+++ b/lib/pipeline/meson.build\n@@ -18,3 +18,7 @@ headers = files(\n         'rte_swx_ctl.h',\n )\n deps += ['port', 'table', 'meter', 'sched', 'cryptodev']\n+\n+indirect_headers += files(\n+        'rte_swx_pipeline_internal.h',\n+)\ndiff --git a/lib/pipeline/rte_swx_pipeline.c b/lib/pipeline/rte_swx_pipeline.c\nindex f89a134a52..ae9b2056db 100644\n--- a/lib/pipeline/rte_swx_pipeline.c\n+++ b/lib/pipeline/rte_swx_pipeline.c\n@@ -2,24 +2,11 @@\n  * Copyright(c) 2020 Intel Corporation\n  */\n #include <stdlib.h>\n-#include <string.h>\n #include <stdio.h>\n #include <errno.h>\n-#include <inttypes.h>\n-#include <sys/queue.h>\n #include <arpa/inet.h>\n \n-#include <rte_common.h>\n-#include <rte_prefetch.h>\n-#include <rte_byteorder.h>\n-#include <rte_cycles.h>\n-#include <rte_meter.h>\n-\n-#include <rte_swx_table_selector.h>\n-#include <rte_swx_table_learner.h>\n-\n-#include \"rte_swx_pipeline.h\"\n-#include \"rte_swx_ctl.h\"\n+#include \"rte_swx_pipeline_internal.h\"\n \n #define CHECK(condition, err_code)                                             \\\n do {                                                                           \\\n@@ -40,22 +27,9 @@ do {                                                                           \\\n \t       RTE_SWX_INSTRUCTION_SIZE),                                      \\\n \t      err_code)\n \n-#ifndef TRACE_LEVEL\n-#define TRACE_LEVEL 0\n-#endif\n-\n-#if TRACE_LEVEL\n-#define TRACE(...) printf(__VA_ARGS__)\n-#else\n-#define TRACE(...)\n-#endif\n-\n /*\n  * Environment.\n  */\n-#define ntoh64(x) rte_be_to_cpu_64(x)\n-#define hton64(x) rte_cpu_to_be_64(x)\n-\n #ifndef RTE_SWX_PIPELINE_HUGE_PAGES_DISABLE\n \n #include <rte_malloc.h>\n@@ -103,1351 +77,6 @@ env_free(void *start, size_t size)\n \n #endif\n \n-/*\n- * Struct.\n- */\n-struct field {\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tuint32_t n_bits;\n-\tuint32_t offset;\n-\tint var_size;\n-};\n-\n-struct struct_type {\n-\tTAILQ_ENTRY(struct_type) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tstruct field *fields;\n-\tuint32_t n_fields;\n-\tuint32_t n_bits;\n-\tuint32_t n_bits_min;\n-\tint var_size;\n-};\n-\n-TAILQ_HEAD(struct_type_tailq, struct_type);\n-\n-/*\n- * Input port.\n- */\n-struct port_in_type {\n-\tTAILQ_ENTRY(port_in_type) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tstruct rte_swx_port_in_ops ops;\n-};\n-\n-TAILQ_HEAD(port_in_type_tailq, port_in_type);\n-\n-struct port_in {\n-\tTAILQ_ENTRY(port_in) node;\n-\tstruct port_in_type *type;\n-\tvoid *obj;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(port_in_tailq, port_in);\n-\n-struct port_in_runtime {\n-\trte_swx_port_in_pkt_rx_t pkt_rx;\n-\tvoid *obj;\n-};\n-\n-/*\n- * Output port.\n- */\n-struct port_out_type {\n-\tTAILQ_ENTRY(port_out_type) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tstruct rte_swx_port_out_ops ops;\n-};\n-\n-TAILQ_HEAD(port_out_type_tailq, port_out_type);\n-\n-struct port_out {\n-\tTAILQ_ENTRY(port_out) node;\n-\tstruct port_out_type *type;\n-\tvoid *obj;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(port_out_tailq, port_out);\n-\n-struct port_out_runtime {\n-\trte_swx_port_out_pkt_tx_t pkt_tx;\n-\trte_swx_port_out_flush_t flush;\n-\tvoid *obj;\n-};\n-\n-/*\n- * Extern object.\n- */\n-struct extern_type_member_func {\n-\tTAILQ_ENTRY(extern_type_member_func) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\trte_swx_extern_type_member_func_t func;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(extern_type_member_func_tailq, extern_type_member_func);\n-\n-struct extern_type {\n-\tTAILQ_ENTRY(extern_type) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tstruct struct_type *mailbox_struct_type;\n-\trte_swx_extern_type_constructor_t constructor;\n-\trte_swx_extern_type_destructor_t destructor;\n-\tstruct extern_type_member_func_tailq funcs;\n-\tuint32_t n_funcs;\n-};\n-\n-TAILQ_HEAD(extern_type_tailq, extern_type);\n-\n-struct extern_obj {\n-\tTAILQ_ENTRY(extern_obj) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tstruct extern_type *type;\n-\tvoid *obj;\n-\tuint32_t struct_id;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(extern_obj_tailq, extern_obj);\n-\n-#ifndef RTE_SWX_EXTERN_TYPE_MEMBER_FUNCS_MAX\n-#define RTE_SWX_EXTERN_TYPE_MEMBER_FUNCS_MAX 8\n-#endif\n-\n-struct extern_obj_runtime {\n-\tvoid *obj;\n-\tuint8_t *mailbox;\n-\trte_swx_extern_type_member_func_t funcs[RTE_SWX_EXTERN_TYPE_MEMBER_FUNCS_MAX];\n-};\n-\n-/*\n- * Extern function.\n- */\n-struct extern_func {\n-\tTAILQ_ENTRY(extern_func) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tstruct struct_type *mailbox_struct_type;\n-\trte_swx_extern_func_t func;\n-\tuint32_t struct_id;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(extern_func_tailq, extern_func);\n-\n-struct extern_func_runtime {\n-\tuint8_t *mailbox;\n-\trte_swx_extern_func_t func;\n-};\n-\n-/*\n- * Header.\n- */\n-struct header {\n-\tTAILQ_ENTRY(header) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tstruct struct_type *st;\n-\tuint32_t struct_id;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(header_tailq, header);\n-\n-struct header_runtime {\n-\tuint8_t *ptr0;\n-\tuint32_t n_bytes;\n-};\n-\n-struct header_out_runtime {\n-\tuint8_t *ptr0;\n-\tuint8_t *ptr;\n-\tuint32_t n_bytes;\n-};\n-\n-/*\n- * Instruction.\n- */\n-\n-/* Packet headers are always in Network Byte Order (NBO), i.e. big endian.\n- * Packet meta-data fields are always assumed to be in Host Byte Order (HBO).\n- * Table entry fields can be in either NBO or HBO; they are assumed to be in HBO\n- * when transferred to packet meta-data and in NBO when transferred to packet\n- * headers.\n- */\n-\n-/* Notation conventions:\n- *    -Header field: H = h.header.field (dst/src)\n- *    -Meta-data field: M = m.field (dst/src)\n- *    -Extern object mailbox field: E = e.field (dst/src)\n- *    -Extern function mailbox field: F = f.field (dst/src)\n- *    -Table action data field: T = t.field (src only)\n- *    -Immediate value: I = 32-bit unsigned value (src only)\n- */\n-\n-enum instruction_type {\n-\t/* rx m.port_in */\n-\tINSTR_RX,\n-\n-\t/* tx port_out\n-\t * port_out = MI\n-\t */\n-\tINSTR_TX,   /* port_out = M */\n-\tINSTR_TX_I, /* port_out = I */\n-\n-\t/* extract h.header */\n-\tINSTR_HDR_EXTRACT,\n-\tINSTR_HDR_EXTRACT2,\n-\tINSTR_HDR_EXTRACT3,\n-\tINSTR_HDR_EXTRACT4,\n-\tINSTR_HDR_EXTRACT5,\n-\tINSTR_HDR_EXTRACT6,\n-\tINSTR_HDR_EXTRACT7,\n-\tINSTR_HDR_EXTRACT8,\n-\n-\t/* extract h.header m.last_field_size */\n-\tINSTR_HDR_EXTRACT_M,\n-\n-\t/* lookahead h.header */\n-\tINSTR_HDR_LOOKAHEAD,\n-\n-\t/* emit h.header */\n-\tINSTR_HDR_EMIT,\n-\tINSTR_HDR_EMIT_TX,\n-\tINSTR_HDR_EMIT2_TX,\n-\tINSTR_HDR_EMIT3_TX,\n-\tINSTR_HDR_EMIT4_TX,\n-\tINSTR_HDR_EMIT5_TX,\n-\tINSTR_HDR_EMIT6_TX,\n-\tINSTR_HDR_EMIT7_TX,\n-\tINSTR_HDR_EMIT8_TX,\n-\n-\t/* validate h.header */\n-\tINSTR_HDR_VALIDATE,\n-\n-\t/* invalidate h.header */\n-\tINSTR_HDR_INVALIDATE,\n-\n-\t/* mov dst src\n-\t * dst = src\n-\t * dst = HMEF, src = HMEFTI\n-\t */\n-\tINSTR_MOV,    /* dst = MEF, src = MEFT */\n-\tINSTR_MOV_MH, /* dst = MEF, src = H */\n-\tINSTR_MOV_HM, /* dst = H, src = MEFT */\n-\tINSTR_MOV_HH, /* dst = H, src = H */\n-\tINSTR_MOV_I,  /* dst = HMEF, src = I */\n-\n-\t/* dma h.header t.field\n-\t * memcpy(h.header, t.field, sizeof(h.header))\n-\t */\n-\tINSTR_DMA_HT,\n-\tINSTR_DMA_HT2,\n-\tINSTR_DMA_HT3,\n-\tINSTR_DMA_HT4,\n-\tINSTR_DMA_HT5,\n-\tINSTR_DMA_HT6,\n-\tINSTR_DMA_HT7,\n-\tINSTR_DMA_HT8,\n-\n-\t/* add dst src\n-\t * dst += src\n-\t * dst = HMEF, src = HMEFTI\n-\t */\n-\tINSTR_ALU_ADD,    /* dst = MEF, src = MEF */\n-\tINSTR_ALU_ADD_MH, /* dst = MEF, src = H */\n-\tINSTR_ALU_ADD_HM, /* dst = H, src = MEF */\n-\tINSTR_ALU_ADD_HH, /* dst = H, src = H */\n-\tINSTR_ALU_ADD_MI, /* dst = MEF, src = I */\n-\tINSTR_ALU_ADD_HI, /* dst = H, src = I */\n-\n-\t/* sub dst src\n-\t * dst -= src\n-\t * dst = HMEF, src = HMEFTI\n-\t */\n-\tINSTR_ALU_SUB,    /* dst = MEF, src = MEF */\n-\tINSTR_ALU_SUB_MH, /* dst = MEF, src = H */\n-\tINSTR_ALU_SUB_HM, /* dst = H, src = MEF */\n-\tINSTR_ALU_SUB_HH, /* dst = H, src = H */\n-\tINSTR_ALU_SUB_MI, /* dst = MEF, src = I */\n-\tINSTR_ALU_SUB_HI, /* dst = H, src = I */\n-\n-\t/* ckadd dst src\n-\t * dst = dst '+ src[0:1] '+ src[2:3] + ...\n-\t * dst = H, src = {H, h.header}\n-\t */\n-\tINSTR_ALU_CKADD_FIELD,    /* src = H */\n-\tINSTR_ALU_CKADD_STRUCT20, /* src = h.header, with sizeof(header) = 20 */\n-\tINSTR_ALU_CKADD_STRUCT,   /* src = h.hdeader, with any sizeof(header) */\n-\n-\t/* cksub dst src\n-\t * dst = dst '- src\n-\t * dst = H, src = H\n-\t */\n-\tINSTR_ALU_CKSUB_FIELD,\n-\n-\t/* and dst src\n-\t * dst &= src\n-\t * dst = HMEF, src = HMEFTI\n-\t */\n-\tINSTR_ALU_AND,    /* dst = MEF, src = MEFT */\n-\tINSTR_ALU_AND_MH, /* dst = MEF, src = H */\n-\tINSTR_ALU_AND_HM, /* dst = H, src = MEFT */\n-\tINSTR_ALU_AND_HH, /* dst = H, src = H */\n-\tINSTR_ALU_AND_I,  /* dst = HMEF, src = I */\n-\n-\t/* or dst src\n-\t * dst |= src\n-\t * dst = HMEF, src = HMEFTI\n-\t */\n-\tINSTR_ALU_OR,    /* dst = MEF, src = MEFT */\n-\tINSTR_ALU_OR_MH, /* dst = MEF, src = H */\n-\tINSTR_ALU_OR_HM, /* dst = H, src = MEFT */\n-\tINSTR_ALU_OR_HH, /* dst = H, src = H */\n-\tINSTR_ALU_OR_I,  /* dst = HMEF, src = I */\n-\n-\t/* xor dst src\n-\t * dst ^= src\n-\t * dst = HMEF, src = HMEFTI\n-\t */\n-\tINSTR_ALU_XOR,    /* dst = MEF, src = MEFT */\n-\tINSTR_ALU_XOR_MH, /* dst = MEF, src = H */\n-\tINSTR_ALU_XOR_HM, /* dst = H, src = MEFT */\n-\tINSTR_ALU_XOR_HH, /* dst = H, src = H */\n-\tINSTR_ALU_XOR_I,  /* dst = HMEF, src = I */\n-\n-\t/* shl dst src\n-\t * dst <<= src\n-\t * dst = HMEF, src = HMEFTI\n-\t */\n-\tINSTR_ALU_SHL,    /* dst = MEF, src = MEF */\n-\tINSTR_ALU_SHL_MH, /* dst = MEF, src = H */\n-\tINSTR_ALU_SHL_HM, /* dst = H, src = MEF */\n-\tINSTR_ALU_SHL_HH, /* dst = H, src = H */\n-\tINSTR_ALU_SHL_MI, /* dst = MEF, src = I */\n-\tINSTR_ALU_SHL_HI, /* dst = H, src = I */\n-\n-\t/* shr dst src\n-\t * dst >>= src\n-\t * dst = HMEF, src = HMEFTI\n-\t */\n-\tINSTR_ALU_SHR,    /* dst = MEF, src = MEF */\n-\tINSTR_ALU_SHR_MH, /* dst = MEF, src = H */\n-\tINSTR_ALU_SHR_HM, /* dst = H, src = MEF */\n-\tINSTR_ALU_SHR_HH, /* dst = H, src = H */\n-\tINSTR_ALU_SHR_MI, /* dst = MEF, src = I */\n-\tINSTR_ALU_SHR_HI, /* dst = H, src = I */\n-\n-\t/* regprefetch REGARRAY index\n-\t * prefetch REGARRAY[index]\n-\t * index = HMEFTI\n-\t */\n-\tINSTR_REGPREFETCH_RH, /* index = H */\n-\tINSTR_REGPREFETCH_RM, /* index = MEFT */\n-\tINSTR_REGPREFETCH_RI, /* index = I */\n-\n-\t/* regrd dst REGARRAY index\n-\t * dst = REGARRAY[index]\n-\t * dst = HMEF, index = HMEFTI\n-\t */\n-\tINSTR_REGRD_HRH, /* dst = H, index = H */\n-\tINSTR_REGRD_HRM, /* dst = H, index = MEFT */\n-\tINSTR_REGRD_HRI, /* dst = H, index = I */\n-\tINSTR_REGRD_MRH, /* dst = MEF, index = H */\n-\tINSTR_REGRD_MRM, /* dst = MEF, index = MEFT */\n-\tINSTR_REGRD_MRI, /* dst = MEF, index = I */\n-\n-\t/* regwr REGARRAY index src\n-\t * REGARRAY[index] = src\n-\t * index = HMEFTI, src = HMEFTI\n-\t */\n-\tINSTR_REGWR_RHH, /* index = H, src = H */\n-\tINSTR_REGWR_RHM, /* index = H, src = MEFT */\n-\tINSTR_REGWR_RHI, /* index = H, src = I */\n-\tINSTR_REGWR_RMH, /* index = MEFT, src = H */\n-\tINSTR_REGWR_RMM, /* index = MEFT, src = MEFT */\n-\tINSTR_REGWR_RMI, /* index = MEFT, src = I */\n-\tINSTR_REGWR_RIH, /* index = I, src = H */\n-\tINSTR_REGWR_RIM, /* index = I, src = MEFT */\n-\tINSTR_REGWR_RII, /* index = I, src = I */\n-\n-\t/* regadd REGARRAY index src\n-\t * REGARRAY[index] += src\n-\t * index = HMEFTI, src = HMEFTI\n-\t */\n-\tINSTR_REGADD_RHH, /* index = H, src = H */\n-\tINSTR_REGADD_RHM, /* index = H, src = MEFT */\n-\tINSTR_REGADD_RHI, /* index = H, src = I */\n-\tINSTR_REGADD_RMH, /* index = MEFT, src = H */\n-\tINSTR_REGADD_RMM, /* index = MEFT, src = MEFT */\n-\tINSTR_REGADD_RMI, /* index = MEFT, src = I */\n-\tINSTR_REGADD_RIH, /* index = I, src = H */\n-\tINSTR_REGADD_RIM, /* index = I, src = MEFT */\n-\tINSTR_REGADD_RII, /* index = I, src = I */\n-\n-\t/* metprefetch METARRAY index\n-\t * prefetch METARRAY[index]\n-\t * index = HMEFTI\n-\t */\n-\tINSTR_METPREFETCH_H, /* index = H */\n-\tINSTR_METPREFETCH_M, /* index = MEFT */\n-\tINSTR_METPREFETCH_I, /* index = I */\n-\n-\t/* meter METARRAY index length color_in color_out\n-\t * color_out = meter(METARRAY[index], length, color_in)\n-\t * index = HMEFTI, length = HMEFT, color_in = MEFTI, color_out = MEF\n-\t */\n-\tINSTR_METER_HHM, /* index = H, length = H, color_in = MEFT */\n-\tINSTR_METER_HHI, /* index = H, length = H, color_in = I */\n-\tINSTR_METER_HMM, /* index = H, length = MEFT, color_in = MEFT */\n-\tINSTR_METER_HMI, /* index = H, length = MEFT, color_in = I */\n-\tINSTR_METER_MHM, /* index = MEFT, length = H, color_in = MEFT */\n-\tINSTR_METER_MHI, /* index = MEFT, length = H, color_in = I */\n-\tINSTR_METER_MMM, /* index = MEFT, length = MEFT, color_in = MEFT */\n-\tINSTR_METER_MMI, /* index = MEFT, length = MEFT, color_in = I */\n-\tINSTR_METER_IHM, /* index = I, length = H, color_in = MEFT */\n-\tINSTR_METER_IHI, /* index = I, length = H, color_in = I */\n-\tINSTR_METER_IMM, /* index = I, length = MEFT, color_in = MEFT */\n-\tINSTR_METER_IMI, /* index = I, length = MEFT, color_in = I */\n-\n-\t/* table TABLE */\n-\tINSTR_TABLE,\n-\tINSTR_SELECTOR,\n-\tINSTR_LEARNER,\n-\n-\t/* learn LEARNER ACTION_NAME */\n-\tINSTR_LEARNER_LEARN,\n-\n-\t/* forget */\n-\tINSTR_LEARNER_FORGET,\n-\n-\t/* extern e.obj.func */\n-\tINSTR_EXTERN_OBJ,\n-\n-\t/* extern f.func */\n-\tINSTR_EXTERN_FUNC,\n-\n-\t/* jmp LABEL\n-\t * Unconditional jump\n-\t */\n-\tINSTR_JMP,\n-\n-\t/* jmpv LABEL h.header\n-\t * Jump if header is valid\n-\t */\n-\tINSTR_JMP_VALID,\n-\n-\t/* jmpnv LABEL h.header\n-\t * Jump if header is invalid\n-\t */\n-\tINSTR_JMP_INVALID,\n-\n-\t/* jmph LABEL\n-\t * Jump if table lookup hit\n-\t */\n-\tINSTR_JMP_HIT,\n-\n-\t/* jmpnh LABEL\n-\t * Jump if table lookup miss\n-\t */\n-\tINSTR_JMP_MISS,\n-\n-\t/* jmpa LABEL ACTION\n-\t * Jump if action run\n-\t */\n-\tINSTR_JMP_ACTION_HIT,\n-\n-\t/* jmpna LABEL ACTION\n-\t * Jump if action not run\n-\t */\n-\tINSTR_JMP_ACTION_MISS,\n-\n-\t/* jmpeq LABEL a b\n-\t * Jump if a is equal to b\n-\t * a = HMEFT, b = HMEFTI\n-\t */\n-\tINSTR_JMP_EQ,    /* a = MEFT, b = MEFT */\n-\tINSTR_JMP_EQ_MH, /* a = MEFT, b = H */\n-\tINSTR_JMP_EQ_HM, /* a = H, b = MEFT */\n-\tINSTR_JMP_EQ_HH, /* a = H, b = H */\n-\tINSTR_JMP_EQ_I,  /* (a, b) = (MEFT, I) or (a, b) = (H, I) */\n-\n-\t/* jmpneq LABEL a b\n-\t * Jump if a is not equal to b\n-\t * a = HMEFT, b = HMEFTI\n-\t */\n-\tINSTR_JMP_NEQ,    /* a = MEFT, b = MEFT */\n-\tINSTR_JMP_NEQ_MH, /* a = MEFT, b = H */\n-\tINSTR_JMP_NEQ_HM, /* a = H, b = MEFT */\n-\tINSTR_JMP_NEQ_HH, /* a = H, b = H */\n-\tINSTR_JMP_NEQ_I,  /* (a, b) = (MEFT, I) or (a, b) = (H, I) */\n-\n-\t/* jmplt LABEL a b\n-\t * Jump if a is less than b\n-\t * a = HMEFT, b = HMEFTI\n-\t */\n-\tINSTR_JMP_LT,    /* a = MEFT, b = MEFT */\n-\tINSTR_JMP_LT_MH, /* a = MEFT, b = H */\n-\tINSTR_JMP_LT_HM, /* a = H, b = MEFT */\n-\tINSTR_JMP_LT_HH, /* a = H, b = H */\n-\tINSTR_JMP_LT_MI, /* a = MEFT, b = I */\n-\tINSTR_JMP_LT_HI, /* a = H, b = I */\n-\n-\t/* jmpgt LABEL a b\n-\t * Jump if a is greater than b\n-\t * a = HMEFT, b = HMEFTI\n-\t */\n-\tINSTR_JMP_GT,    /* a = MEFT, b = MEFT */\n-\tINSTR_JMP_GT_MH, /* a = MEFT, b = H */\n-\tINSTR_JMP_GT_HM, /* a = H, b = MEFT */\n-\tINSTR_JMP_GT_HH, /* a = H, b = H */\n-\tINSTR_JMP_GT_MI, /* a = MEFT, b = I */\n-\tINSTR_JMP_GT_HI, /* a = H, b = I */\n-\n-\t/* return\n-\t * Return from action\n-\t */\n-\tINSTR_RETURN,\n-};\n-\n-struct instr_operand {\n-\tuint8_t struct_id;\n-\tuint8_t n_bits;\n-\tuint8_t offset;\n-\tuint8_t pad;\n-};\n-\n-struct instr_io {\n-\tstruct {\n-\t\tunion {\n-\t\t\tstruct {\n-\t\t\t\tuint8_t offset;\n-\t\t\t\tuint8_t n_bits;\n-\t\t\t\tuint8_t pad[2];\n-\t\t\t};\n-\n-\t\t\tuint32_t val;\n-\t\t};\n-\t} io;\n-\n-\tstruct {\n-\t\tuint8_t header_id[8];\n-\t\tuint8_t struct_id[8];\n-\t\tuint8_t n_bytes[8];\n-\t} hdr;\n-};\n-\n-struct instr_hdr_validity {\n-\tuint8_t header_id;\n-};\n-\n-struct instr_table {\n-\tuint8_t table_id;\n-};\n-\n-struct instr_learn {\n-\tuint8_t action_id;\n-};\n-\n-struct instr_extern_obj {\n-\tuint8_t ext_obj_id;\n-\tuint8_t func_id;\n-};\n-\n-struct instr_extern_func {\n-\tuint8_t ext_func_id;\n-};\n-\n-struct instr_dst_src {\n-\tstruct instr_operand dst;\n-\tunion {\n-\t\tstruct instr_operand src;\n-\t\tuint64_t src_val;\n-\t};\n-};\n-\n-struct instr_regarray {\n-\tuint8_t regarray_id;\n-\tuint8_t pad[3];\n-\n-\tunion {\n-\t\tstruct instr_operand idx;\n-\t\tuint32_t idx_val;\n-\t};\n-\n-\tunion {\n-\t\tstruct instr_operand dstsrc;\n-\t\tuint64_t dstsrc_val;\n-\t};\n-};\n-\n-struct instr_meter {\n-\tuint8_t metarray_id;\n-\tuint8_t pad[3];\n-\n-\tunion {\n-\t\tstruct instr_operand idx;\n-\t\tuint32_t idx_val;\n-\t};\n-\n-\tstruct instr_operand length;\n-\n-\tunion {\n-\t\tstruct instr_operand color_in;\n-\t\tuint32_t color_in_val;\n-\t};\n-\n-\tstruct instr_operand color_out;\n-};\n-\n-struct instr_dma {\n-\tstruct {\n-\t\tuint8_t header_id[8];\n-\t\tuint8_t struct_id[8];\n-\t} dst;\n-\n-\tstruct {\n-\t\tuint8_t offset[8];\n-\t} src;\n-\n-\tuint16_t n_bytes[8];\n-};\n-\n-struct instr_jmp {\n-\tstruct instruction *ip;\n-\n-\tunion {\n-\t\tstruct instr_operand a;\n-\t\tuint8_t header_id;\n-\t\tuint8_t action_id;\n-\t};\n-\n-\tunion {\n-\t\tstruct instr_operand b;\n-\t\tuint64_t b_val;\n-\t};\n-};\n-\n-struct instruction {\n-\tenum instruction_type type;\n-\tunion {\n-\t\tstruct instr_io io;\n-\t\tstruct instr_hdr_validity valid;\n-\t\tstruct instr_dst_src mov;\n-\t\tstruct instr_regarray regarray;\n-\t\tstruct instr_meter meter;\n-\t\tstruct instr_dma dma;\n-\t\tstruct instr_dst_src alu;\n-\t\tstruct instr_table table;\n-\t\tstruct instr_learn learn;\n-\t\tstruct instr_extern_obj ext_obj;\n-\t\tstruct instr_extern_func ext_func;\n-\t\tstruct instr_jmp jmp;\n-\t};\n-};\n-\n-struct instruction_data {\n-\tchar label[RTE_SWX_NAME_SIZE];\n-\tchar jmp_label[RTE_SWX_NAME_SIZE];\n-\tuint32_t n_users; /* user = jmp instruction to this instruction. */\n-\tint invalid;\n-};\n-\n-/*\n- * Action.\n- */\n-struct action {\n-\tTAILQ_ENTRY(action) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tstruct struct_type *st;\n-\tint *args_endianness; /* 0 = Host Byte Order (HBO); 1 = Network Byte Order (NBO). */\n-\tstruct instruction *instructions;\n-\tuint32_t n_instructions;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(action_tailq, action);\n-\n-/*\n- * Table.\n- */\n-struct table_type {\n-\tTAILQ_ENTRY(table_type) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tenum rte_swx_table_match_type match_type;\n-\tstruct rte_swx_table_ops ops;\n-};\n-\n-TAILQ_HEAD(table_type_tailq, table_type);\n-\n-struct match_field {\n-\tenum rte_swx_table_match_type match_type;\n-\tstruct field *field;\n-};\n-\n-struct table {\n-\tTAILQ_ENTRY(table) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tchar args[RTE_SWX_NAME_SIZE];\n-\tstruct table_type *type; /* NULL when n_fields == 0. */\n-\n-\t/* Match. */\n-\tstruct match_field *fields;\n-\tuint32_t n_fields;\n-\tstruct header *header; /* Only valid when n_fields > 0. */\n-\n-\t/* Action. */\n-\tstruct action **actions;\n-\tstruct action *default_action;\n-\tuint8_t *default_action_data;\n-\tuint32_t n_actions;\n-\tint default_action_is_const;\n-\tuint32_t action_data_size_max;\n-\n-\tuint32_t size;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(table_tailq, table);\n-\n-struct table_runtime {\n-\trte_swx_table_lookup_t func;\n-\tvoid *mailbox;\n-\tuint8_t **key;\n-};\n-\n-struct table_statistics {\n-\tuint64_t n_pkts_hit[2]; /* 0 = Miss, 1 = Hit. */\n-\tuint64_t *n_pkts_action;\n-};\n-\n-/*\n- * Selector.\n- */\n-struct selector {\n-\tTAILQ_ENTRY(selector) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\n-\tstruct field *group_id_field;\n-\tstruct field **selector_fields;\n-\tuint32_t n_selector_fields;\n-\tstruct header *selector_header;\n-\tstruct field *member_id_field;\n-\n-\tuint32_t n_groups_max;\n-\tuint32_t n_members_per_group_max;\n-\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(selector_tailq, selector);\n-\n-struct selector_runtime {\n-\tvoid *mailbox;\n-\tuint8_t **group_id_buffer;\n-\tuint8_t **selector_buffer;\n-\tuint8_t **member_id_buffer;\n-};\n-\n-struct selector_statistics {\n-\tuint64_t n_pkts;\n-};\n-\n-/*\n- * Learner table.\n- */\n-struct learner {\n-\tTAILQ_ENTRY(learner) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\n-\t/* Match. */\n-\tstruct field **fields;\n-\tuint32_t n_fields;\n-\tstruct header *header;\n-\n-\t/* Action. */\n-\tstruct action **actions;\n-\tstruct field **action_arg;\n-\tstruct action *default_action;\n-\tuint8_t *default_action_data;\n-\tuint32_t n_actions;\n-\tint default_action_is_const;\n-\tuint32_t action_data_size_max;\n-\n-\tuint32_t size;\n-\tuint32_t timeout;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(learner_tailq, learner);\n-\n-struct learner_runtime {\n-\tvoid *mailbox;\n-\tuint8_t **key;\n-\tuint8_t **action_data;\n-};\n-\n-struct learner_statistics {\n-\tuint64_t n_pkts_hit[2]; /* 0 = Miss, 1 = Hit. */\n-\tuint64_t n_pkts_learn[2]; /* 0 = Learn OK, 1 = Learn error. */\n-\tuint64_t n_pkts_forget;\n-\tuint64_t *n_pkts_action;\n-};\n-\n-/*\n- * Register array.\n- */\n-struct regarray {\n-\tTAILQ_ENTRY(regarray) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tuint64_t init_val;\n-\tuint32_t size;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(regarray_tailq, regarray);\n-\n-struct regarray_runtime {\n-\tuint64_t *regarray;\n-\tuint32_t size_mask;\n-};\n-\n-/*\n- * Meter array.\n- */\n-struct meter_profile {\n-\tTAILQ_ENTRY(meter_profile) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tstruct rte_meter_trtcm_params params;\n-\tstruct rte_meter_trtcm_profile profile;\n-\tuint32_t n_users;\n-};\n-\n-TAILQ_HEAD(meter_profile_tailq, meter_profile);\n-\n-struct metarray {\n-\tTAILQ_ENTRY(metarray) node;\n-\tchar name[RTE_SWX_NAME_SIZE];\n-\tuint32_t size;\n-\tuint32_t id;\n-};\n-\n-TAILQ_HEAD(metarray_tailq, metarray);\n-\n-struct meter {\n-\tstruct rte_meter_trtcm m;\n-\tstruct meter_profile *profile;\n-\tenum rte_color color_mask;\n-\tuint8_t pad[20];\n-\n-\tuint64_t n_pkts[RTE_COLORS];\n-\tuint64_t n_bytes[RTE_COLORS];\n-};\n-\n-struct metarray_runtime {\n-\tstruct meter *metarray;\n-\tuint32_t size_mask;\n-};\n-\n-/*\n- * Pipeline.\n- */\n-struct thread {\n-\t/* Packet. */\n-\tstruct rte_swx_pkt pkt;\n-\tuint8_t *ptr;\n-\n-\t/* Structures. */\n-\tuint8_t **structs;\n-\n-\t/* Packet headers. */\n-\tstruct header_runtime *headers; /* Extracted or generated headers. */\n-\tstruct header_out_runtime *headers_out; /* Emitted headers. */\n-\tuint8_t *header_storage;\n-\tuint8_t *header_out_storage;\n-\tuint64_t valid_headers;\n-\tuint32_t n_headers_out;\n-\n-\t/* Packet meta-data. */\n-\tuint8_t *metadata;\n-\n-\t/* Tables. */\n-\tstruct table_runtime *tables;\n-\tstruct selector_runtime *selectors;\n-\tstruct learner_runtime *learners;\n-\tstruct rte_swx_table_state *table_state;\n-\tuint64_t action_id;\n-\tint hit; /* 0 = Miss, 1 = Hit. */\n-\tuint32_t learner_id;\n-\tuint64_t time;\n-\n-\t/* Extern objects and functions. */\n-\tstruct extern_obj_runtime *extern_objs;\n-\tstruct extern_func_runtime *extern_funcs;\n-\n-\t/* Instructions. */\n-\tstruct instruction *ip;\n-\tstruct instruction *ret;\n-};\n-\n-#define MASK64_BIT_GET(mask, pos) ((mask) & (1LLU << (pos)))\n-#define MASK64_BIT_SET(mask, pos) ((mask) | (1LLU << (pos)))\n-#define MASK64_BIT_CLR(mask, pos) ((mask) & ~(1LLU << (pos)))\n-\n-#define HEADER_VALID(thread, header_id) \\\n-\tMASK64_BIT_GET((thread)->valid_headers, header_id)\n-\n-#define ALU(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n-\tuint64_t dst = dst64 & dst64_mask;                                     \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];      \\\n-\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];   \\\n-\tuint64_t src64 = *src64_ptr;                                           \\\n-\tuint64_t src64_mask = UINT64_MAX >> (64 - (ip)->alu.src.n_bits);       \\\n-\tuint64_t src = src64 & src64_mask;                                     \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t result = dst operator src;                                    \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | (result & dst64_mask);            \\\n-}\n-\n-#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN\n-\n-#define ALU_MH(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n-\tuint64_t dst = dst64 & dst64_mask;                                     \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];      \\\n-\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];   \\\n-\tuint64_t src64 = *src64_ptr;                                           \\\n-\tuint64_t src = ntoh64(src64) >> (64 - (ip)->alu.src.n_bits);           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t result = dst operator src;                                    \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | (result & dst64_mask);            \\\n-}\n-\n-#define ALU_HM(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n-\tuint64_t dst = ntoh64(dst64) >> (64 - (ip)->alu.dst.n_bits);           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];      \\\n-\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];   \\\n-\tuint64_t src64 = *src64_ptr;                                           \\\n-\tuint64_t src64_mask = UINT64_MAX >> (64 - (ip)->alu.src.n_bits);       \\\n-\tuint64_t src = src64 & src64_mask;                                     \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t result = dst operator src;                                    \\\n-\tresult = hton64(result << (64 - (ip)->alu.dst.n_bits));                \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | result;                           \\\n-}\n-\n-#define ALU_HM_FAST(thread, ip, operator)  \\\n-{                                                                                 \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];         \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];      \\\n-\tuint64_t dst64 = *dst64_ptr;                                              \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);          \\\n-\tuint64_t dst = dst64 & dst64_mask;                                        \\\n-\t\t\t\t\t\t\t\t\t\t  \\\n-\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];         \\\n-\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];      \\\n-\tuint64_t src64 = *src64_ptr;                                              \\\n-\tuint64_t src64_mask = UINT64_MAX >> (64 - (ip)->alu.src.n_bits);          \\\n-\tuint64_t src = hton64(src64 & src64_mask) >> (64 - (ip)->alu.dst.n_bits); \\\n-\t\t\t\t\t\t\t\t\t\t  \\\n-\tuint64_t result = dst operator src;                                       \\\n-\t\t\t\t\t\t\t\t\t\t  \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | result;                              \\\n-}\n-\n-#define ALU_HH(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n-\tuint64_t dst = ntoh64(dst64) >> (64 - (ip)->alu.dst.n_bits);           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];      \\\n-\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];   \\\n-\tuint64_t src64 = *src64_ptr;                                           \\\n-\tuint64_t src = ntoh64(src64) >> (64 - (ip)->alu.src.n_bits);           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t result = dst operator src;                                    \\\n-\tresult = hton64(result << (64 - (ip)->alu.dst.n_bits));                \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | result;                           \\\n-}\n-\n-#define ALU_HH_FAST(thread, ip, operator)  \\\n-{                                                                                             \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];                     \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];                  \\\n-\tuint64_t dst64 = *dst64_ptr;                                                          \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);                      \\\n-\tuint64_t dst = dst64 & dst64_mask;                                                    \\\n-\t\t\t\t\t\t\t\t\t\t\t      \\\n-\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];                     \\\n-\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];                  \\\n-\tuint64_t src64 = *src64_ptr;                                                          \\\n-\tuint64_t src = (src64 << (64 - (ip)->alu.src.n_bits)) >> (64 - (ip)->alu.dst.n_bits); \\\n-\t\t\t\t\t\t\t\t\t\t\t      \\\n-\tuint64_t result = dst operator src;                                                   \\\n-\t\t\t\t\t\t\t\t\t\t\t      \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | result;                                          \\\n-}\n-\n-#else\n-\n-#define ALU_MH ALU\n-#define ALU_HM ALU\n-#define ALU_HM_FAST ALU\n-#define ALU_HH ALU\n-#define ALU_HH_FAST ALU\n-\n-#endif\n-\n-#define ALU_I(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n-\tuint64_t dst = dst64 & dst64_mask;                                     \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t src = (ip)->alu.src_val;                                      \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t result = dst operator src;                                    \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | (result & dst64_mask);            \\\n-}\n-\n-#define ALU_MI ALU_I\n-\n-#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN\n-\n-#define ALU_HI(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n-\tuint64_t dst = ntoh64(dst64) >> (64 - (ip)->alu.dst.n_bits);           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t src = (ip)->alu.src_val;                                      \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t result = dst operator src;                                    \\\n-\tresult = hton64(result << (64 - (ip)->alu.dst.n_bits));                \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | result;                           \\\n-}\n-\n-#else\n-\n-#define ALU_HI ALU_I\n-\n-#endif\n-\n-#define MOV(thread, ip)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->mov.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->mov.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->mov.dst.n_bits);       \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *src_struct = (thread)->structs[(ip)->mov.src.struct_id];      \\\n-\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->mov.src.offset];   \\\n-\tuint64_t src64 = *src64_ptr;                                           \\\n-\tuint64_t src64_mask = UINT64_MAX >> (64 - (ip)->mov.src.n_bits);       \\\n-\tuint64_t src = src64 & src64_mask;                                     \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | (src & dst64_mask);               \\\n-}\n-\n-#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN\n-\n-#define MOV_MH(thread, ip)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->mov.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->mov.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->mov.dst.n_bits);       \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *src_struct = (thread)->structs[(ip)->mov.src.struct_id];      \\\n-\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->mov.src.offset];   \\\n-\tuint64_t src64 = *src64_ptr;                                           \\\n-\tuint64_t src = ntoh64(src64) >> (64 - (ip)->mov.src.n_bits);           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | (src & dst64_mask);               \\\n-}\n-\n-#define MOV_HM(thread, ip)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->mov.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->mov.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->mov.dst.n_bits);       \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *src_struct = (thread)->structs[(ip)->mov.src.struct_id];      \\\n-\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->mov.src.offset];   \\\n-\tuint64_t src64 = *src64_ptr;                                           \\\n-\tuint64_t src64_mask = UINT64_MAX >> (64 - (ip)->mov.src.n_bits);       \\\n-\tuint64_t src = src64 & src64_mask;                                     \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tsrc = hton64(src) >> (64 - (ip)->mov.dst.n_bits);                      \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | src;                              \\\n-}\n-\n-#define MOV_HH(thread, ip)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->mov.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->mov.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->mov.dst.n_bits);       \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *src_struct = (thread)->structs[(ip)->mov.src.struct_id];      \\\n-\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->mov.src.offset];   \\\n-\tuint64_t src64 = *src64_ptr;                                           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t src = src64 << (64 - (ip)->mov.src.n_bits);                   \\\n-\tsrc = src >> (64 - (ip)->mov.dst.n_bits);                              \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | src;                              \\\n-}\n-\n-#else\n-\n-#define MOV_MH MOV\n-#define MOV_HM MOV\n-#define MOV_HH MOV\n-\n-#endif\n-\n-#define MOV_I(thread, ip)  \\\n-{                                                                              \\\n-\tuint8_t *dst_struct = (thread)->structs[(ip)->mov.dst.struct_id];      \\\n-\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->mov.dst.offset];   \\\n-\tuint64_t dst64 = *dst64_ptr;                                           \\\n-\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->mov.dst.n_bits);       \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t src = (ip)->mov.src_val;                                      \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t*dst64_ptr = (dst64 & ~dst64_mask) | (src & dst64_mask);               \\\n-}\n-\n-#define JMP_CMP(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n-\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n-\tuint64_t a64 = *a64_ptr;                                               \\\n-\tuint64_t a64_mask = UINT64_MAX >> (64 - (ip)->jmp.a.n_bits);           \\\n-\tuint64_t a = a64 & a64_mask;                                           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *b_struct = (thread)->structs[(ip)->jmp.b.struct_id];          \\\n-\tuint64_t *b64_ptr = (uint64_t *)&b_struct[(ip)->jmp.b.offset];         \\\n-\tuint64_t b64 = *b64_ptr;                                               \\\n-\tuint64_t b64_mask = UINT64_MAX >> (64 - (ip)->jmp.b.n_bits);           \\\n-\tuint64_t b = b64 & b64_mask;                                           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n-}\n-\n-#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN\n-\n-#define JMP_CMP_MH(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n-\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n-\tuint64_t a64 = *a64_ptr;                                               \\\n-\tuint64_t a64_mask = UINT64_MAX >> (64 - (ip)->jmp.a.n_bits);           \\\n-\tuint64_t a = a64 & a64_mask;                                           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *b_struct = (thread)->structs[(ip)->jmp.b.struct_id];          \\\n-\tuint64_t *b64_ptr = (uint64_t *)&b_struct[(ip)->jmp.b.offset];         \\\n-\tuint64_t b64 = *b64_ptr;                                               \\\n-\tuint64_t b = ntoh64(b64) >> (64 - (ip)->jmp.b.n_bits);                 \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n-}\n-\n-#define JMP_CMP_HM(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n-\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n-\tuint64_t a64 = *a64_ptr;                                               \\\n-\tuint64_t a = ntoh64(a64) >> (64 - (ip)->jmp.a.n_bits);                 \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *b_struct = (thread)->structs[(ip)->jmp.b.struct_id];          \\\n-\tuint64_t *b64_ptr = (uint64_t *)&b_struct[(ip)->jmp.b.offset];         \\\n-\tuint64_t b64 = *b64_ptr;                                               \\\n-\tuint64_t b64_mask = UINT64_MAX >> (64 - (ip)->jmp.b.n_bits);           \\\n-\tuint64_t b = b64 & b64_mask;                                           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n-}\n-\n-#define JMP_CMP_HH(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n-\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n-\tuint64_t a64 = *a64_ptr;                                               \\\n-\tuint64_t a = ntoh64(a64) >> (64 - (ip)->jmp.a.n_bits);                 \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *b_struct = (thread)->structs[(ip)->jmp.b.struct_id];          \\\n-\tuint64_t *b64_ptr = (uint64_t *)&b_struct[(ip)->jmp.b.offset];         \\\n-\tuint64_t b64 = *b64_ptr;                                               \\\n-\tuint64_t b = ntoh64(b64) >> (64 - (ip)->jmp.b.n_bits);                 \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n-}\n-\n-#define JMP_CMP_HH_FAST(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n-\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n-\tuint64_t a64 = *a64_ptr;                                               \\\n-\tuint64_t a = a64 << (64 - (ip)->jmp.a.n_bits);                         \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint8_t *b_struct = (thread)->structs[(ip)->jmp.b.struct_id];          \\\n-\tuint64_t *b64_ptr = (uint64_t *)&b_struct[(ip)->jmp.b.offset];         \\\n-\tuint64_t b64 = *b64_ptr;                                               \\\n-\tuint64_t b = b64 << (64 - (ip)->jmp.b.n_bits);                         \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n-}\n-\n-#else\n-\n-#define JMP_CMP_MH JMP_CMP\n-#define JMP_CMP_HM JMP_CMP\n-#define JMP_CMP_HH JMP_CMP\n-#define JMP_CMP_HH_FAST JMP_CMP\n-\n-#endif\n-\n-#define JMP_CMP_I(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n-\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n-\tuint64_t a64 = *a64_ptr;                                               \\\n-\tuint64_t a64_mask = UINT64_MAX >> (64 - (ip)->jmp.a.n_bits);           \\\n-\tuint64_t a = a64 & a64_mask;                                           \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t b = (ip)->jmp.b_val;                                          \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n-}\n-\n-#define JMP_CMP_MI JMP_CMP_I\n-\n-#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN\n-\n-#define JMP_CMP_HI(thread, ip, operator)  \\\n-{                                                                              \\\n-\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n-\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n-\tuint64_t a64 = *a64_ptr;                                               \\\n-\tuint64_t a = ntoh64(a64) >> (64 - (ip)->jmp.a.n_bits);                 \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t b = (ip)->jmp.b_val;                                          \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n-}\n-\n-#else\n-\n-#define JMP_CMP_HI JMP_CMP_I\n-\n-#endif\n-\n-#define METADATA_READ(thread, offset, n_bits)                                  \\\n-({                                                                             \\\n-\tuint64_t *m64_ptr = (uint64_t *)&(thread)->metadata[offset];           \\\n-\tuint64_t m64 = *m64_ptr;                                               \\\n-\tuint64_t m64_mask = UINT64_MAX >> (64 - (n_bits));                     \\\n-\t(m64 & m64_mask);                                                      \\\n-})\n-\n-#define METADATA_WRITE(thread, offset, n_bits, value)                          \\\n-{                                                                              \\\n-\tuint64_t *m64_ptr = (uint64_t *)&(thread)->metadata[offset];           \\\n-\tuint64_t m64 = *m64_ptr;                                               \\\n-\tuint64_t m64_mask = UINT64_MAX >> (64 - (n_bits));                     \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\tuint64_t m_new = value;                                                \\\n-\t\t\t\t\t\t\t\t\t       \\\n-\t*m64_ptr = (m64 & ~m64_mask) | (m_new & m64_mask);                     \\\n-}\n-\n-#ifndef RTE_SWX_PIPELINE_THREADS_MAX\n-#define RTE_SWX_PIPELINE_THREADS_MAX 16\n-#endif\n-\n-struct rte_swx_pipeline {\n-\tstruct struct_type_tailq struct_types;\n-\tstruct port_in_type_tailq port_in_types;\n-\tstruct port_in_tailq ports_in;\n-\tstruct port_out_type_tailq port_out_types;\n-\tstruct port_out_tailq ports_out;\n-\tstruct extern_type_tailq extern_types;\n-\tstruct extern_obj_tailq extern_objs;\n-\tstruct extern_func_tailq extern_funcs;\n-\tstruct header_tailq headers;\n-\tstruct struct_type *metadata_st;\n-\tuint32_t metadata_struct_id;\n-\tstruct action_tailq actions;\n-\tstruct table_type_tailq table_types;\n-\tstruct table_tailq tables;\n-\tstruct selector_tailq selectors;\n-\tstruct learner_tailq learners;\n-\tstruct regarray_tailq regarrays;\n-\tstruct meter_profile_tailq meter_profiles;\n-\tstruct metarray_tailq metarrays;\n-\n-\tstruct port_in_runtime *in;\n-\tstruct port_out_runtime *out;\n-\tstruct instruction **action_instructions;\n-\tstruct rte_swx_table_state *table_state;\n-\tstruct table_statistics *table_stats;\n-\tstruct selector_statistics *selector_stats;\n-\tstruct learner_statistics *learner_stats;\n-\tstruct regarray_runtime *regarray_runtime;\n-\tstruct metarray_runtime *metarray_runtime;\n-\tstruct instruction *instructions;\n-\tstruct thread threads[RTE_SWX_PIPELINE_THREADS_MAX];\n-\n-\tuint32_t n_structs;\n-\tuint32_t n_ports_in;\n-\tuint32_t n_ports_out;\n-\tuint32_t n_extern_objs;\n-\tuint32_t n_extern_funcs;\n-\tuint32_t n_actions;\n-\tuint32_t n_tables;\n-\tuint32_t n_selectors;\n-\tuint32_t n_learners;\n-\tuint32_t n_regarrays;\n-\tuint32_t n_metarrays;\n-\tuint32_t n_headers;\n-\tuint32_t thread_id;\n-\tuint32_t port_id;\n-\tuint32_t n_instructions;\n-\tint build_done;\n-\tint numa_node;\n-};\n-\n /*\n  * Struct.\n  */\ndiff --git a/lib/pipeline/rte_swx_pipeline_internal.h b/lib/pipeline/rte_swx_pipeline_internal.h\nnew file mode 100644\nindex 0000000000..5d80dd8451\n--- /dev/null\n+++ b/lib/pipeline/rte_swx_pipeline_internal.h\n@@ -0,0 +1,1383 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2021 Intel Corporation\n+ */\n+#ifndef __INCLUDE_RTE_SWX_PIPELINE_INTERNAL_H__\n+#define __INCLUDE_RTE_SWX_PIPELINE_INTERNAL_H__\n+\n+#include <inttypes.h>\n+#include <string.h>\n+#include <sys/queue.h>\n+\n+#include <rte_byteorder.h>\n+#include <rte_common.h>\n+#include <rte_cycles.h>\n+#include <rte_prefetch.h>\n+#include <rte_meter.h>\n+\n+#include <rte_swx_table_selector.h>\n+#include <rte_swx_table_learner.h>\n+#include <rte_swx_pipeline.h>\n+#include <rte_swx_ctl.h>\n+\n+#ifndef TRACE_LEVEL\n+#define TRACE_LEVEL 0\n+#endif\n+\n+#if TRACE_LEVEL\n+#define TRACE(...) printf(__VA_ARGS__)\n+#else\n+#define TRACE(...)\n+#endif\n+\n+/*\n+ * Environment.\n+ */\n+#define ntoh64(x) rte_be_to_cpu_64(x)\n+#define hton64(x) rte_cpu_to_be_64(x)\n+\n+/*\n+ * Struct.\n+ */\n+struct field {\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tuint32_t n_bits;\n+\tuint32_t offset;\n+\tint var_size;\n+};\n+\n+struct struct_type {\n+\tTAILQ_ENTRY(struct_type) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tstruct field *fields;\n+\tuint32_t n_fields;\n+\tuint32_t n_bits;\n+\tuint32_t n_bits_min;\n+\tint var_size;\n+};\n+\n+TAILQ_HEAD(struct_type_tailq, struct_type);\n+\n+/*\n+ * Input port.\n+ */\n+struct port_in_type {\n+\tTAILQ_ENTRY(port_in_type) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tstruct rte_swx_port_in_ops ops;\n+};\n+\n+TAILQ_HEAD(port_in_type_tailq, port_in_type);\n+\n+struct port_in {\n+\tTAILQ_ENTRY(port_in) node;\n+\tstruct port_in_type *type;\n+\tvoid *obj;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(port_in_tailq, port_in);\n+\n+struct port_in_runtime {\n+\trte_swx_port_in_pkt_rx_t pkt_rx;\n+\tvoid *obj;\n+};\n+\n+/*\n+ * Output port.\n+ */\n+struct port_out_type {\n+\tTAILQ_ENTRY(port_out_type) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tstruct rte_swx_port_out_ops ops;\n+};\n+\n+TAILQ_HEAD(port_out_type_tailq, port_out_type);\n+\n+struct port_out {\n+\tTAILQ_ENTRY(port_out) node;\n+\tstruct port_out_type *type;\n+\tvoid *obj;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(port_out_tailq, port_out);\n+\n+struct port_out_runtime {\n+\trte_swx_port_out_pkt_tx_t pkt_tx;\n+\trte_swx_port_out_flush_t flush;\n+\tvoid *obj;\n+};\n+\n+/*\n+ * Extern object.\n+ */\n+struct extern_type_member_func {\n+\tTAILQ_ENTRY(extern_type_member_func) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\trte_swx_extern_type_member_func_t func;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(extern_type_member_func_tailq, extern_type_member_func);\n+\n+struct extern_type {\n+\tTAILQ_ENTRY(extern_type) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tstruct struct_type *mailbox_struct_type;\n+\trte_swx_extern_type_constructor_t constructor;\n+\trte_swx_extern_type_destructor_t destructor;\n+\tstruct extern_type_member_func_tailq funcs;\n+\tuint32_t n_funcs;\n+};\n+\n+TAILQ_HEAD(extern_type_tailq, extern_type);\n+\n+struct extern_obj {\n+\tTAILQ_ENTRY(extern_obj) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tstruct extern_type *type;\n+\tvoid *obj;\n+\tuint32_t struct_id;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(extern_obj_tailq, extern_obj);\n+\n+#ifndef RTE_SWX_EXTERN_TYPE_MEMBER_FUNCS_MAX\n+#define RTE_SWX_EXTERN_TYPE_MEMBER_FUNCS_MAX 8\n+#endif\n+\n+struct extern_obj_runtime {\n+\tvoid *obj;\n+\tuint8_t *mailbox;\n+\trte_swx_extern_type_member_func_t funcs[RTE_SWX_EXTERN_TYPE_MEMBER_FUNCS_MAX];\n+};\n+\n+/*\n+ * Extern function.\n+ */\n+struct extern_func {\n+\tTAILQ_ENTRY(extern_func) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tstruct struct_type *mailbox_struct_type;\n+\trte_swx_extern_func_t func;\n+\tuint32_t struct_id;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(extern_func_tailq, extern_func);\n+\n+struct extern_func_runtime {\n+\tuint8_t *mailbox;\n+\trte_swx_extern_func_t func;\n+};\n+\n+/*\n+ * Header.\n+ */\n+struct header {\n+\tTAILQ_ENTRY(header) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tstruct struct_type *st;\n+\tuint32_t struct_id;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(header_tailq, header);\n+\n+struct header_runtime {\n+\tuint8_t *ptr0;\n+\tuint32_t n_bytes;\n+};\n+\n+struct header_out_runtime {\n+\tuint8_t *ptr0;\n+\tuint8_t *ptr;\n+\tuint32_t n_bytes;\n+};\n+\n+/*\n+ * Instruction.\n+ */\n+\n+/* Packet headers are always in Network Byte Order (NBO), i.e. big endian.\n+ * Packet meta-data fields are always assumed to be in Host Byte Order (HBO).\n+ * Table entry fields can be in either NBO or HBO; they are assumed to be in HBO\n+ * when transferred to packet meta-data and in NBO when transferred to packet\n+ * headers.\n+ */\n+\n+/* Notation conventions:\n+ *    -Header field: H = h.header.field (dst/src)\n+ *    -Meta-data field: M = m.field (dst/src)\n+ *    -Extern object mailbox field: E = e.field (dst/src)\n+ *    -Extern function mailbox field: F = f.field (dst/src)\n+ *    -Table action data field: T = t.field (src only)\n+ *    -Immediate value: I = 32-bit unsigned value (src only)\n+ */\n+\n+enum instruction_type {\n+\t/* rx m.port_in */\n+\tINSTR_RX,\n+\n+\t/* tx port_out\n+\t * port_out = MI\n+\t */\n+\tINSTR_TX,   /* port_out = M */\n+\tINSTR_TX_I, /* port_out = I */\n+\n+\t/* extract h.header */\n+\tINSTR_HDR_EXTRACT,\n+\tINSTR_HDR_EXTRACT2,\n+\tINSTR_HDR_EXTRACT3,\n+\tINSTR_HDR_EXTRACT4,\n+\tINSTR_HDR_EXTRACT5,\n+\tINSTR_HDR_EXTRACT6,\n+\tINSTR_HDR_EXTRACT7,\n+\tINSTR_HDR_EXTRACT8,\n+\n+\t/* extract h.header m.last_field_size */\n+\tINSTR_HDR_EXTRACT_M,\n+\n+\t/* lookahead h.header */\n+\tINSTR_HDR_LOOKAHEAD,\n+\n+\t/* emit h.header */\n+\tINSTR_HDR_EMIT,\n+\tINSTR_HDR_EMIT_TX,\n+\tINSTR_HDR_EMIT2_TX,\n+\tINSTR_HDR_EMIT3_TX,\n+\tINSTR_HDR_EMIT4_TX,\n+\tINSTR_HDR_EMIT5_TX,\n+\tINSTR_HDR_EMIT6_TX,\n+\tINSTR_HDR_EMIT7_TX,\n+\tINSTR_HDR_EMIT8_TX,\n+\n+\t/* validate h.header */\n+\tINSTR_HDR_VALIDATE,\n+\n+\t/* invalidate h.header */\n+\tINSTR_HDR_INVALIDATE,\n+\n+\t/* mov dst src\n+\t * dst = src\n+\t * dst = HMEF, src = HMEFTI\n+\t */\n+\tINSTR_MOV,    /* dst = MEF, src = MEFT */\n+\tINSTR_MOV_MH, /* dst = MEF, src = H */\n+\tINSTR_MOV_HM, /* dst = H, src = MEFT */\n+\tINSTR_MOV_HH, /* dst = H, src = H */\n+\tINSTR_MOV_I,  /* dst = HMEF, src = I */\n+\n+\t/* dma h.header t.field\n+\t * memcpy(h.header, t.field, sizeof(h.header))\n+\t */\n+\tINSTR_DMA_HT,\n+\tINSTR_DMA_HT2,\n+\tINSTR_DMA_HT3,\n+\tINSTR_DMA_HT4,\n+\tINSTR_DMA_HT5,\n+\tINSTR_DMA_HT6,\n+\tINSTR_DMA_HT7,\n+\tINSTR_DMA_HT8,\n+\n+\t/* add dst src\n+\t * dst += src\n+\t * dst = HMEF, src = HMEFTI\n+\t */\n+\tINSTR_ALU_ADD,    /* dst = MEF, src = MEF */\n+\tINSTR_ALU_ADD_MH, /* dst = MEF, src = H */\n+\tINSTR_ALU_ADD_HM, /* dst = H, src = MEF */\n+\tINSTR_ALU_ADD_HH, /* dst = H, src = H */\n+\tINSTR_ALU_ADD_MI, /* dst = MEF, src = I */\n+\tINSTR_ALU_ADD_HI, /* dst = H, src = I */\n+\n+\t/* sub dst src\n+\t * dst -= src\n+\t * dst = HMEF, src = HMEFTI\n+\t */\n+\tINSTR_ALU_SUB,    /* dst = MEF, src = MEF */\n+\tINSTR_ALU_SUB_MH, /* dst = MEF, src = H */\n+\tINSTR_ALU_SUB_HM, /* dst = H, src = MEF */\n+\tINSTR_ALU_SUB_HH, /* dst = H, src = H */\n+\tINSTR_ALU_SUB_MI, /* dst = MEF, src = I */\n+\tINSTR_ALU_SUB_HI, /* dst = H, src = I */\n+\n+\t/* ckadd dst src\n+\t * dst = dst '+ src[0:1] '+ src[2:3] + ...\n+\t * dst = H, src = {H, h.header}\n+\t */\n+\tINSTR_ALU_CKADD_FIELD,    /* src = H */\n+\tINSTR_ALU_CKADD_STRUCT20, /* src = h.header, with sizeof(header) = 20 */\n+\tINSTR_ALU_CKADD_STRUCT,   /* src = h.hdeader, with any sizeof(header) */\n+\n+\t/* cksub dst src\n+\t * dst = dst '- src\n+\t * dst = H, src = H\n+\t */\n+\tINSTR_ALU_CKSUB_FIELD,\n+\n+\t/* and dst src\n+\t * dst &= src\n+\t * dst = HMEF, src = HMEFTI\n+\t */\n+\tINSTR_ALU_AND,    /* dst = MEF, src = MEFT */\n+\tINSTR_ALU_AND_MH, /* dst = MEF, src = H */\n+\tINSTR_ALU_AND_HM, /* dst = H, src = MEFT */\n+\tINSTR_ALU_AND_HH, /* dst = H, src = H */\n+\tINSTR_ALU_AND_I,  /* dst = HMEF, src = I */\n+\n+\t/* or dst src\n+\t * dst |= src\n+\t * dst = HMEF, src = HMEFTI\n+\t */\n+\tINSTR_ALU_OR,    /* dst = MEF, src = MEFT */\n+\tINSTR_ALU_OR_MH, /* dst = MEF, src = H */\n+\tINSTR_ALU_OR_HM, /* dst = H, src = MEFT */\n+\tINSTR_ALU_OR_HH, /* dst = H, src = H */\n+\tINSTR_ALU_OR_I,  /* dst = HMEF, src = I */\n+\n+\t/* xor dst src\n+\t * dst ^= src\n+\t * dst = HMEF, src = HMEFTI\n+\t */\n+\tINSTR_ALU_XOR,    /* dst = MEF, src = MEFT */\n+\tINSTR_ALU_XOR_MH, /* dst = MEF, src = H */\n+\tINSTR_ALU_XOR_HM, /* dst = H, src = MEFT */\n+\tINSTR_ALU_XOR_HH, /* dst = H, src = H */\n+\tINSTR_ALU_XOR_I,  /* dst = HMEF, src = I */\n+\n+\t/* shl dst src\n+\t * dst <<= src\n+\t * dst = HMEF, src = HMEFTI\n+\t */\n+\tINSTR_ALU_SHL,    /* dst = MEF, src = MEF */\n+\tINSTR_ALU_SHL_MH, /* dst = MEF, src = H */\n+\tINSTR_ALU_SHL_HM, /* dst = H, src = MEF */\n+\tINSTR_ALU_SHL_HH, /* dst = H, src = H */\n+\tINSTR_ALU_SHL_MI, /* dst = MEF, src = I */\n+\tINSTR_ALU_SHL_HI, /* dst = H, src = I */\n+\n+\t/* shr dst src\n+\t * dst >>= src\n+\t * dst = HMEF, src = HMEFTI\n+\t */\n+\tINSTR_ALU_SHR,    /* dst = MEF, src = MEF */\n+\tINSTR_ALU_SHR_MH, /* dst = MEF, src = H */\n+\tINSTR_ALU_SHR_HM, /* dst = H, src = MEF */\n+\tINSTR_ALU_SHR_HH, /* dst = H, src = H */\n+\tINSTR_ALU_SHR_MI, /* dst = MEF, src = I */\n+\tINSTR_ALU_SHR_HI, /* dst = H, src = I */\n+\n+\t/* regprefetch REGARRAY index\n+\t * prefetch REGARRAY[index]\n+\t * index = HMEFTI\n+\t */\n+\tINSTR_REGPREFETCH_RH, /* index = H */\n+\tINSTR_REGPREFETCH_RM, /* index = MEFT */\n+\tINSTR_REGPREFETCH_RI, /* index = I */\n+\n+\t/* regrd dst REGARRAY index\n+\t * dst = REGARRAY[index]\n+\t * dst = HMEF, index = HMEFTI\n+\t */\n+\tINSTR_REGRD_HRH, /* dst = H, index = H */\n+\tINSTR_REGRD_HRM, /* dst = H, index = MEFT */\n+\tINSTR_REGRD_HRI, /* dst = H, index = I */\n+\tINSTR_REGRD_MRH, /* dst = MEF, index = H */\n+\tINSTR_REGRD_MRM, /* dst = MEF, index = MEFT */\n+\tINSTR_REGRD_MRI, /* dst = MEF, index = I */\n+\n+\t/* regwr REGARRAY index src\n+\t * REGARRAY[index] = src\n+\t * index = HMEFTI, src = HMEFTI\n+\t */\n+\tINSTR_REGWR_RHH, /* index = H, src = H */\n+\tINSTR_REGWR_RHM, /* index = H, src = MEFT */\n+\tINSTR_REGWR_RHI, /* index = H, src = I */\n+\tINSTR_REGWR_RMH, /* index = MEFT, src = H */\n+\tINSTR_REGWR_RMM, /* index = MEFT, src = MEFT */\n+\tINSTR_REGWR_RMI, /* index = MEFT, src = I */\n+\tINSTR_REGWR_RIH, /* index = I, src = H */\n+\tINSTR_REGWR_RIM, /* index = I, src = MEFT */\n+\tINSTR_REGWR_RII, /* index = I, src = I */\n+\n+\t/* regadd REGARRAY index src\n+\t * REGARRAY[index] += src\n+\t * index = HMEFTI, src = HMEFTI\n+\t */\n+\tINSTR_REGADD_RHH, /* index = H, src = H */\n+\tINSTR_REGADD_RHM, /* index = H, src = MEFT */\n+\tINSTR_REGADD_RHI, /* index = H, src = I */\n+\tINSTR_REGADD_RMH, /* index = MEFT, src = H */\n+\tINSTR_REGADD_RMM, /* index = MEFT, src = MEFT */\n+\tINSTR_REGADD_RMI, /* index = MEFT, src = I */\n+\tINSTR_REGADD_RIH, /* index = I, src = H */\n+\tINSTR_REGADD_RIM, /* index = I, src = MEFT */\n+\tINSTR_REGADD_RII, /* index = I, src = I */\n+\n+\t/* metprefetch METARRAY index\n+\t * prefetch METARRAY[index]\n+\t * index = HMEFTI\n+\t */\n+\tINSTR_METPREFETCH_H, /* index = H */\n+\tINSTR_METPREFETCH_M, /* index = MEFT */\n+\tINSTR_METPREFETCH_I, /* index = I */\n+\n+\t/* meter METARRAY index length color_in color_out\n+\t * color_out = meter(METARRAY[index], length, color_in)\n+\t * index = HMEFTI, length = HMEFT, color_in = MEFTI, color_out = MEF\n+\t */\n+\tINSTR_METER_HHM, /* index = H, length = H, color_in = MEFT */\n+\tINSTR_METER_HHI, /* index = H, length = H, color_in = I */\n+\tINSTR_METER_HMM, /* index = H, length = MEFT, color_in = MEFT */\n+\tINSTR_METER_HMI, /* index = H, length = MEFT, color_in = I */\n+\tINSTR_METER_MHM, /* index = MEFT, length = H, color_in = MEFT */\n+\tINSTR_METER_MHI, /* index = MEFT, length = H, color_in = I */\n+\tINSTR_METER_MMM, /* index = MEFT, length = MEFT, color_in = MEFT */\n+\tINSTR_METER_MMI, /* index = MEFT, length = MEFT, color_in = I */\n+\tINSTR_METER_IHM, /* index = I, length = H, color_in = MEFT */\n+\tINSTR_METER_IHI, /* index = I, length = H, color_in = I */\n+\tINSTR_METER_IMM, /* index = I, length = MEFT, color_in = MEFT */\n+\tINSTR_METER_IMI, /* index = I, length = MEFT, color_in = I */\n+\n+\t/* table TABLE */\n+\tINSTR_TABLE,\n+\tINSTR_SELECTOR,\n+\tINSTR_LEARNER,\n+\n+\t/* learn LEARNER ACTION_NAME */\n+\tINSTR_LEARNER_LEARN,\n+\n+\t/* forget */\n+\tINSTR_LEARNER_FORGET,\n+\n+\t/* extern e.obj.func */\n+\tINSTR_EXTERN_OBJ,\n+\n+\t/* extern f.func */\n+\tINSTR_EXTERN_FUNC,\n+\n+\t/* jmp LABEL\n+\t * Unconditional jump\n+\t */\n+\tINSTR_JMP,\n+\n+\t/* jmpv LABEL h.header\n+\t * Jump if header is valid\n+\t */\n+\tINSTR_JMP_VALID,\n+\n+\t/* jmpnv LABEL h.header\n+\t * Jump if header is invalid\n+\t */\n+\tINSTR_JMP_INVALID,\n+\n+\t/* jmph LABEL\n+\t * Jump if table lookup hit\n+\t */\n+\tINSTR_JMP_HIT,\n+\n+\t/* jmpnh LABEL\n+\t * Jump if table lookup miss\n+\t */\n+\tINSTR_JMP_MISS,\n+\n+\t/* jmpa LABEL ACTION\n+\t * Jump if action run\n+\t */\n+\tINSTR_JMP_ACTION_HIT,\n+\n+\t/* jmpna LABEL ACTION\n+\t * Jump if action not run\n+\t */\n+\tINSTR_JMP_ACTION_MISS,\n+\n+\t/* jmpeq LABEL a b\n+\t * Jump if a is equal to b\n+\t * a = HMEFT, b = HMEFTI\n+\t */\n+\tINSTR_JMP_EQ,    /* a = MEFT, b = MEFT */\n+\tINSTR_JMP_EQ_MH, /* a = MEFT, b = H */\n+\tINSTR_JMP_EQ_HM, /* a = H, b = MEFT */\n+\tINSTR_JMP_EQ_HH, /* a = H, b = H */\n+\tINSTR_JMP_EQ_I,  /* (a, b) = (MEFT, I) or (a, b) = (H, I) */\n+\n+\t/* jmpneq LABEL a b\n+\t * Jump if a is not equal to b\n+\t * a = HMEFT, b = HMEFTI\n+\t */\n+\tINSTR_JMP_NEQ,    /* a = MEFT, b = MEFT */\n+\tINSTR_JMP_NEQ_MH, /* a = MEFT, b = H */\n+\tINSTR_JMP_NEQ_HM, /* a = H, b = MEFT */\n+\tINSTR_JMP_NEQ_HH, /* a = H, b = H */\n+\tINSTR_JMP_NEQ_I,  /* (a, b) = (MEFT, I) or (a, b) = (H, I) */\n+\n+\t/* jmplt LABEL a b\n+\t * Jump if a is less than b\n+\t * a = HMEFT, b = HMEFTI\n+\t */\n+\tINSTR_JMP_LT,    /* a = MEFT, b = MEFT */\n+\tINSTR_JMP_LT_MH, /* a = MEFT, b = H */\n+\tINSTR_JMP_LT_HM, /* a = H, b = MEFT */\n+\tINSTR_JMP_LT_HH, /* a = H, b = H */\n+\tINSTR_JMP_LT_MI, /* a = MEFT, b = I */\n+\tINSTR_JMP_LT_HI, /* a = H, b = I */\n+\n+\t/* jmpgt LABEL a b\n+\t * Jump if a is greater than b\n+\t * a = HMEFT, b = HMEFTI\n+\t */\n+\tINSTR_JMP_GT,    /* a = MEFT, b = MEFT */\n+\tINSTR_JMP_GT_MH, /* a = MEFT, b = H */\n+\tINSTR_JMP_GT_HM, /* a = H, b = MEFT */\n+\tINSTR_JMP_GT_HH, /* a = H, b = H */\n+\tINSTR_JMP_GT_MI, /* a = MEFT, b = I */\n+\tINSTR_JMP_GT_HI, /* a = H, b = I */\n+\n+\t/* return\n+\t * Return from action\n+\t */\n+\tINSTR_RETURN,\n+};\n+\n+struct instr_operand {\n+\tuint8_t struct_id;\n+\tuint8_t n_bits;\n+\tuint8_t offset;\n+\tuint8_t pad;\n+};\n+\n+struct instr_io {\n+\tstruct {\n+\t\tunion {\n+\t\t\tstruct {\n+\t\t\t\tuint8_t offset;\n+\t\t\t\tuint8_t n_bits;\n+\t\t\t\tuint8_t pad[2];\n+\t\t\t};\n+\n+\t\t\tuint32_t val;\n+\t\t};\n+\t} io;\n+\n+\tstruct {\n+\t\tuint8_t header_id[8];\n+\t\tuint8_t struct_id[8];\n+\t\tuint8_t n_bytes[8];\n+\t} hdr;\n+};\n+\n+struct instr_hdr_validity {\n+\tuint8_t header_id;\n+};\n+\n+struct instr_table {\n+\tuint8_t table_id;\n+};\n+\n+struct instr_learn {\n+\tuint8_t action_id;\n+};\n+\n+struct instr_extern_obj {\n+\tuint8_t ext_obj_id;\n+\tuint8_t func_id;\n+};\n+\n+struct instr_extern_func {\n+\tuint8_t ext_func_id;\n+};\n+\n+struct instr_dst_src {\n+\tstruct instr_operand dst;\n+\tunion {\n+\t\tstruct instr_operand src;\n+\t\tuint64_t src_val;\n+\t};\n+};\n+\n+struct instr_regarray {\n+\tuint8_t regarray_id;\n+\tuint8_t pad[3];\n+\n+\tunion {\n+\t\tstruct instr_operand idx;\n+\t\tuint32_t idx_val;\n+\t};\n+\n+\tunion {\n+\t\tstruct instr_operand dstsrc;\n+\t\tuint64_t dstsrc_val;\n+\t};\n+};\n+\n+struct instr_meter {\n+\tuint8_t metarray_id;\n+\tuint8_t pad[3];\n+\n+\tunion {\n+\t\tstruct instr_operand idx;\n+\t\tuint32_t idx_val;\n+\t};\n+\n+\tstruct instr_operand length;\n+\n+\tunion {\n+\t\tstruct instr_operand color_in;\n+\t\tuint32_t color_in_val;\n+\t};\n+\n+\tstruct instr_operand color_out;\n+};\n+\n+struct instr_dma {\n+\tstruct {\n+\t\tuint8_t header_id[8];\n+\t\tuint8_t struct_id[8];\n+\t} dst;\n+\n+\tstruct {\n+\t\tuint8_t offset[8];\n+\t} src;\n+\n+\tuint16_t n_bytes[8];\n+};\n+\n+struct instr_jmp {\n+\tstruct instruction *ip;\n+\n+\tunion {\n+\t\tstruct instr_operand a;\n+\t\tuint8_t header_id;\n+\t\tuint8_t action_id;\n+\t};\n+\n+\tunion {\n+\t\tstruct instr_operand b;\n+\t\tuint64_t b_val;\n+\t};\n+};\n+\n+struct instruction {\n+\tenum instruction_type type;\n+\tunion {\n+\t\tstruct instr_io io;\n+\t\tstruct instr_hdr_validity valid;\n+\t\tstruct instr_dst_src mov;\n+\t\tstruct instr_regarray regarray;\n+\t\tstruct instr_meter meter;\n+\t\tstruct instr_dma dma;\n+\t\tstruct instr_dst_src alu;\n+\t\tstruct instr_table table;\n+\t\tstruct instr_learn learn;\n+\t\tstruct instr_extern_obj ext_obj;\n+\t\tstruct instr_extern_func ext_func;\n+\t\tstruct instr_jmp jmp;\n+\t};\n+};\n+\n+struct instruction_data {\n+\tchar label[RTE_SWX_NAME_SIZE];\n+\tchar jmp_label[RTE_SWX_NAME_SIZE];\n+\tuint32_t n_users; /* user = jmp instruction to this instruction. */\n+\tint invalid;\n+};\n+\n+/*\n+ * Action.\n+ */\n+struct action {\n+\tTAILQ_ENTRY(action) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tstruct struct_type *st;\n+\tint *args_endianness; /* 0 = Host Byte Order (HBO); 1 = Network Byte Order (NBO). */\n+\tstruct instruction *instructions;\n+\tuint32_t n_instructions;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(action_tailq, action);\n+\n+/*\n+ * Table.\n+ */\n+struct table_type {\n+\tTAILQ_ENTRY(table_type) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tenum rte_swx_table_match_type match_type;\n+\tstruct rte_swx_table_ops ops;\n+};\n+\n+TAILQ_HEAD(table_type_tailq, table_type);\n+\n+struct match_field {\n+\tenum rte_swx_table_match_type match_type;\n+\tstruct field *field;\n+};\n+\n+struct table {\n+\tTAILQ_ENTRY(table) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tchar args[RTE_SWX_NAME_SIZE];\n+\tstruct table_type *type; /* NULL when n_fields == 0. */\n+\n+\t/* Match. */\n+\tstruct match_field *fields;\n+\tuint32_t n_fields;\n+\tstruct header *header; /* Only valid when n_fields > 0. */\n+\n+\t/* Action. */\n+\tstruct action **actions;\n+\tstruct action *default_action;\n+\tuint8_t *default_action_data;\n+\tuint32_t n_actions;\n+\tint default_action_is_const;\n+\tuint32_t action_data_size_max;\n+\n+\tuint32_t size;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(table_tailq, table);\n+\n+struct table_runtime {\n+\trte_swx_table_lookup_t func;\n+\tvoid *mailbox;\n+\tuint8_t **key;\n+};\n+\n+struct table_statistics {\n+\tuint64_t n_pkts_hit[2]; /* 0 = Miss, 1 = Hit. */\n+\tuint64_t *n_pkts_action;\n+};\n+\n+/*\n+ * Selector.\n+ */\n+struct selector {\n+\tTAILQ_ENTRY(selector) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\n+\tstruct field *group_id_field;\n+\tstruct field **selector_fields;\n+\tuint32_t n_selector_fields;\n+\tstruct header *selector_header;\n+\tstruct field *member_id_field;\n+\n+\tuint32_t n_groups_max;\n+\tuint32_t n_members_per_group_max;\n+\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(selector_tailq, selector);\n+\n+struct selector_runtime {\n+\tvoid *mailbox;\n+\tuint8_t **group_id_buffer;\n+\tuint8_t **selector_buffer;\n+\tuint8_t **member_id_buffer;\n+};\n+\n+struct selector_statistics {\n+\tuint64_t n_pkts;\n+};\n+\n+/*\n+ * Learner table.\n+ */\n+struct learner {\n+\tTAILQ_ENTRY(learner) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\n+\t/* Match. */\n+\tstruct field **fields;\n+\tuint32_t n_fields;\n+\tstruct header *header;\n+\n+\t/* Action. */\n+\tstruct action **actions;\n+\tstruct field **action_arg;\n+\tstruct action *default_action;\n+\tuint8_t *default_action_data;\n+\tuint32_t n_actions;\n+\tint default_action_is_const;\n+\tuint32_t action_data_size_max;\n+\n+\tuint32_t size;\n+\tuint32_t timeout;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(learner_tailq, learner);\n+\n+struct learner_runtime {\n+\tvoid *mailbox;\n+\tuint8_t **key;\n+\tuint8_t **action_data;\n+};\n+\n+struct learner_statistics {\n+\tuint64_t n_pkts_hit[2]; /* 0 = Miss, 1 = Hit. */\n+\tuint64_t n_pkts_learn[2]; /* 0 = Learn OK, 1 = Learn error. */\n+\tuint64_t n_pkts_forget;\n+\tuint64_t *n_pkts_action;\n+};\n+\n+/*\n+ * Register array.\n+ */\n+struct regarray {\n+\tTAILQ_ENTRY(regarray) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tuint64_t init_val;\n+\tuint32_t size;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(regarray_tailq, regarray);\n+\n+struct regarray_runtime {\n+\tuint64_t *regarray;\n+\tuint32_t size_mask;\n+};\n+\n+/*\n+ * Meter array.\n+ */\n+struct meter_profile {\n+\tTAILQ_ENTRY(meter_profile) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tstruct rte_meter_trtcm_params params;\n+\tstruct rte_meter_trtcm_profile profile;\n+\tuint32_t n_users;\n+};\n+\n+TAILQ_HEAD(meter_profile_tailq, meter_profile);\n+\n+struct metarray {\n+\tTAILQ_ENTRY(metarray) node;\n+\tchar name[RTE_SWX_NAME_SIZE];\n+\tuint32_t size;\n+\tuint32_t id;\n+};\n+\n+TAILQ_HEAD(metarray_tailq, metarray);\n+\n+struct meter {\n+\tstruct rte_meter_trtcm m;\n+\tstruct meter_profile *profile;\n+\tenum rte_color color_mask;\n+\tuint8_t pad[20];\n+\n+\tuint64_t n_pkts[RTE_COLORS];\n+\tuint64_t n_bytes[RTE_COLORS];\n+};\n+\n+struct metarray_runtime {\n+\tstruct meter *metarray;\n+\tuint32_t size_mask;\n+};\n+\n+/*\n+ * Pipeline.\n+ */\n+struct thread {\n+\t/* Packet. */\n+\tstruct rte_swx_pkt pkt;\n+\tuint8_t *ptr;\n+\n+\t/* Structures. */\n+\tuint8_t **structs;\n+\n+\t/* Packet headers. */\n+\tstruct header_runtime *headers; /* Extracted or generated headers. */\n+\tstruct header_out_runtime *headers_out; /* Emitted headers. */\n+\tuint8_t *header_storage;\n+\tuint8_t *header_out_storage;\n+\tuint64_t valid_headers;\n+\tuint32_t n_headers_out;\n+\n+\t/* Packet meta-data. */\n+\tuint8_t *metadata;\n+\n+\t/* Tables. */\n+\tstruct table_runtime *tables;\n+\tstruct selector_runtime *selectors;\n+\tstruct learner_runtime *learners;\n+\tstruct rte_swx_table_state *table_state;\n+\tuint64_t action_id;\n+\tint hit; /* 0 = Miss, 1 = Hit. */\n+\tuint32_t learner_id;\n+\tuint64_t time;\n+\n+\t/* Extern objects and functions. */\n+\tstruct extern_obj_runtime *extern_objs;\n+\tstruct extern_func_runtime *extern_funcs;\n+\n+\t/* Instructions. */\n+\tstruct instruction *ip;\n+\tstruct instruction *ret;\n+};\n+\n+#define MASK64_BIT_GET(mask, pos) ((mask) & (1LLU << (pos)))\n+#define MASK64_BIT_SET(mask, pos) ((mask) | (1LLU << (pos)))\n+#define MASK64_BIT_CLR(mask, pos) ((mask) & ~(1LLU << (pos)))\n+\n+#define HEADER_VALID(thread, header_id) \\\n+\tMASK64_BIT_GET((thread)->valid_headers, header_id)\n+\n+#define ALU(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n+\tuint64_t dst = dst64 & dst64_mask;                                     \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];      \\\n+\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];   \\\n+\tuint64_t src64 = *src64_ptr;                                           \\\n+\tuint64_t src64_mask = UINT64_MAX >> (64 - (ip)->alu.src.n_bits);       \\\n+\tuint64_t src = src64 & src64_mask;                                     \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t result = dst operator src;                                    \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | (result & dst64_mask);            \\\n+}\n+\n+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN\n+\n+#define ALU_MH(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n+\tuint64_t dst = dst64 & dst64_mask;                                     \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];      \\\n+\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];   \\\n+\tuint64_t src64 = *src64_ptr;                                           \\\n+\tuint64_t src = ntoh64(src64) >> (64 - (ip)->alu.src.n_bits);           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t result = dst operator src;                                    \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | (result & dst64_mask);            \\\n+}\n+\n+#define ALU_HM(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n+\tuint64_t dst = ntoh64(dst64) >> (64 - (ip)->alu.dst.n_bits);           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];      \\\n+\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];   \\\n+\tuint64_t src64 = *src64_ptr;                                           \\\n+\tuint64_t src64_mask = UINT64_MAX >> (64 - (ip)->alu.src.n_bits);       \\\n+\tuint64_t src = src64 & src64_mask;                                     \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t result = dst operator src;                                    \\\n+\tresult = hton64(result << (64 - (ip)->alu.dst.n_bits));                \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | result;                           \\\n+}\n+\n+#define ALU_HM_FAST(thread, ip, operator)  \\\n+{                                                                                 \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];         \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];      \\\n+\tuint64_t dst64 = *dst64_ptr;                                              \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);          \\\n+\tuint64_t dst = dst64 & dst64_mask;                                        \\\n+\t\t\t\t\t\t\t\t\t\t  \\\n+\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];         \\\n+\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];      \\\n+\tuint64_t src64 = *src64_ptr;                                              \\\n+\tuint64_t src64_mask = UINT64_MAX >> (64 - (ip)->alu.src.n_bits);          \\\n+\tuint64_t src = hton64(src64 & src64_mask) >> (64 - (ip)->alu.dst.n_bits); \\\n+\t\t\t\t\t\t\t\t\t\t  \\\n+\tuint64_t result = dst operator src;                                       \\\n+\t\t\t\t\t\t\t\t\t\t  \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | result;                              \\\n+}\n+\n+#define ALU_HH(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n+\tuint64_t dst = ntoh64(dst64) >> (64 - (ip)->alu.dst.n_bits);           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];      \\\n+\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];   \\\n+\tuint64_t src64 = *src64_ptr;                                           \\\n+\tuint64_t src = ntoh64(src64) >> (64 - (ip)->alu.src.n_bits);           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t result = dst operator src;                                    \\\n+\tresult = hton64(result << (64 - (ip)->alu.dst.n_bits));                \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | result;                           \\\n+}\n+\n+#define ALU_HH_FAST(thread, ip, operator)  \\\n+{                                                                                             \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];                     \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];                  \\\n+\tuint64_t dst64 = *dst64_ptr;                                                          \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);                      \\\n+\tuint64_t dst = dst64 & dst64_mask;                                                    \\\n+\t\t\t\t\t\t\t\t\t\t\t      \\\n+\tuint8_t *src_struct = (thread)->structs[(ip)->alu.src.struct_id];                     \\\n+\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->alu.src.offset];                  \\\n+\tuint64_t src64 = *src64_ptr;                                                          \\\n+\tuint64_t src = (src64 << (64 - (ip)->alu.src.n_bits)) >> (64 - (ip)->alu.dst.n_bits); \\\n+\t\t\t\t\t\t\t\t\t\t\t      \\\n+\tuint64_t result = dst operator src;                                                   \\\n+\t\t\t\t\t\t\t\t\t\t\t      \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | result;                                          \\\n+}\n+\n+#else\n+\n+#define ALU_MH ALU\n+#define ALU_HM ALU\n+#define ALU_HM_FAST ALU\n+#define ALU_HH ALU\n+#define ALU_HH_FAST ALU\n+\n+#endif\n+\n+#define ALU_I(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n+\tuint64_t dst = dst64 & dst64_mask;                                     \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t src = (ip)->alu.src_val;                                      \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t result = dst operator src;                                    \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | (result & dst64_mask);            \\\n+}\n+\n+#define ALU_MI ALU_I\n+\n+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN\n+\n+#define ALU_HI(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->alu.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->alu.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->alu.dst.n_bits);       \\\n+\tuint64_t dst = ntoh64(dst64) >> (64 - (ip)->alu.dst.n_bits);           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t src = (ip)->alu.src_val;                                      \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t result = dst operator src;                                    \\\n+\tresult = hton64(result << (64 - (ip)->alu.dst.n_bits));                \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | result;                           \\\n+}\n+\n+#else\n+\n+#define ALU_HI ALU_I\n+\n+#endif\n+\n+#define MOV(thread, ip)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->mov.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->mov.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->mov.dst.n_bits);       \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *src_struct = (thread)->structs[(ip)->mov.src.struct_id];      \\\n+\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->mov.src.offset];   \\\n+\tuint64_t src64 = *src64_ptr;                                           \\\n+\tuint64_t src64_mask = UINT64_MAX >> (64 - (ip)->mov.src.n_bits);       \\\n+\tuint64_t src = src64 & src64_mask;                                     \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | (src & dst64_mask);               \\\n+}\n+\n+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN\n+\n+#define MOV_MH(thread, ip)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->mov.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->mov.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->mov.dst.n_bits);       \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *src_struct = (thread)->structs[(ip)->mov.src.struct_id];      \\\n+\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->mov.src.offset];   \\\n+\tuint64_t src64 = *src64_ptr;                                           \\\n+\tuint64_t src = ntoh64(src64) >> (64 - (ip)->mov.src.n_bits);           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | (src & dst64_mask);               \\\n+}\n+\n+#define MOV_HM(thread, ip)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->mov.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->mov.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->mov.dst.n_bits);       \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *src_struct = (thread)->structs[(ip)->mov.src.struct_id];      \\\n+\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->mov.src.offset];   \\\n+\tuint64_t src64 = *src64_ptr;                                           \\\n+\tuint64_t src64_mask = UINT64_MAX >> (64 - (ip)->mov.src.n_bits);       \\\n+\tuint64_t src = src64 & src64_mask;                                     \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tsrc = hton64(src) >> (64 - (ip)->mov.dst.n_bits);                      \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | src;                              \\\n+}\n+\n+#define MOV_HH(thread, ip)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->mov.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->mov.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->mov.dst.n_bits);       \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *src_struct = (thread)->structs[(ip)->mov.src.struct_id];      \\\n+\tuint64_t *src64_ptr = (uint64_t *)&src_struct[(ip)->mov.src.offset];   \\\n+\tuint64_t src64 = *src64_ptr;                                           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t src = src64 << (64 - (ip)->mov.src.n_bits);                   \\\n+\tsrc = src >> (64 - (ip)->mov.dst.n_bits);                              \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | src;                              \\\n+}\n+\n+#else\n+\n+#define MOV_MH MOV\n+#define MOV_HM MOV\n+#define MOV_HH MOV\n+\n+#endif\n+\n+#define MOV_I(thread, ip)  \\\n+{                                                                              \\\n+\tuint8_t *dst_struct = (thread)->structs[(ip)->mov.dst.struct_id];      \\\n+\tuint64_t *dst64_ptr = (uint64_t *)&dst_struct[(ip)->mov.dst.offset];   \\\n+\tuint64_t dst64 = *dst64_ptr;                                           \\\n+\tuint64_t dst64_mask = UINT64_MAX >> (64 - (ip)->mov.dst.n_bits);       \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t src = (ip)->mov.src_val;                                      \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t*dst64_ptr = (dst64 & ~dst64_mask) | (src & dst64_mask);               \\\n+}\n+\n+#define JMP_CMP(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n+\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n+\tuint64_t a64 = *a64_ptr;                                               \\\n+\tuint64_t a64_mask = UINT64_MAX >> (64 - (ip)->jmp.a.n_bits);           \\\n+\tuint64_t a = a64 & a64_mask;                                           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *b_struct = (thread)->structs[(ip)->jmp.b.struct_id];          \\\n+\tuint64_t *b64_ptr = (uint64_t *)&b_struct[(ip)->jmp.b.offset];         \\\n+\tuint64_t b64 = *b64_ptr;                                               \\\n+\tuint64_t b64_mask = UINT64_MAX >> (64 - (ip)->jmp.b.n_bits);           \\\n+\tuint64_t b = b64 & b64_mask;                                           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n+}\n+\n+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN\n+\n+#define JMP_CMP_MH(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n+\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n+\tuint64_t a64 = *a64_ptr;                                               \\\n+\tuint64_t a64_mask = UINT64_MAX >> (64 - (ip)->jmp.a.n_bits);           \\\n+\tuint64_t a = a64 & a64_mask;                                           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *b_struct = (thread)->structs[(ip)->jmp.b.struct_id];          \\\n+\tuint64_t *b64_ptr = (uint64_t *)&b_struct[(ip)->jmp.b.offset];         \\\n+\tuint64_t b64 = *b64_ptr;                                               \\\n+\tuint64_t b = ntoh64(b64) >> (64 - (ip)->jmp.b.n_bits);                 \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n+}\n+\n+#define JMP_CMP_HM(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n+\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n+\tuint64_t a64 = *a64_ptr;                                               \\\n+\tuint64_t a = ntoh64(a64) >> (64 - (ip)->jmp.a.n_bits);                 \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *b_struct = (thread)->structs[(ip)->jmp.b.struct_id];          \\\n+\tuint64_t *b64_ptr = (uint64_t *)&b_struct[(ip)->jmp.b.offset];         \\\n+\tuint64_t b64 = *b64_ptr;                                               \\\n+\tuint64_t b64_mask = UINT64_MAX >> (64 - (ip)->jmp.b.n_bits);           \\\n+\tuint64_t b = b64 & b64_mask;                                           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n+}\n+\n+#define JMP_CMP_HH(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n+\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n+\tuint64_t a64 = *a64_ptr;                                               \\\n+\tuint64_t a = ntoh64(a64) >> (64 - (ip)->jmp.a.n_bits);                 \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *b_struct = (thread)->structs[(ip)->jmp.b.struct_id];          \\\n+\tuint64_t *b64_ptr = (uint64_t *)&b_struct[(ip)->jmp.b.offset];         \\\n+\tuint64_t b64 = *b64_ptr;                                               \\\n+\tuint64_t b = ntoh64(b64) >> (64 - (ip)->jmp.b.n_bits);                 \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n+}\n+\n+#define JMP_CMP_HH_FAST(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n+\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n+\tuint64_t a64 = *a64_ptr;                                               \\\n+\tuint64_t a = a64 << (64 - (ip)->jmp.a.n_bits);                         \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint8_t *b_struct = (thread)->structs[(ip)->jmp.b.struct_id];          \\\n+\tuint64_t *b64_ptr = (uint64_t *)&b_struct[(ip)->jmp.b.offset];         \\\n+\tuint64_t b64 = *b64_ptr;                                               \\\n+\tuint64_t b = b64 << (64 - (ip)->jmp.b.n_bits);                         \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n+}\n+\n+#else\n+\n+#define JMP_CMP_MH JMP_CMP\n+#define JMP_CMP_HM JMP_CMP\n+#define JMP_CMP_HH JMP_CMP\n+#define JMP_CMP_HH_FAST JMP_CMP\n+\n+#endif\n+\n+#define JMP_CMP_I(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n+\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n+\tuint64_t a64 = *a64_ptr;                                               \\\n+\tuint64_t a64_mask = UINT64_MAX >> (64 - (ip)->jmp.a.n_bits);           \\\n+\tuint64_t a = a64 & a64_mask;                                           \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t b = (ip)->jmp.b_val;                                          \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n+}\n+\n+#define JMP_CMP_MI JMP_CMP_I\n+\n+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN\n+\n+#define JMP_CMP_HI(thread, ip, operator)  \\\n+{                                                                              \\\n+\tuint8_t *a_struct = (thread)->structs[(ip)->jmp.a.struct_id];          \\\n+\tuint64_t *a64_ptr = (uint64_t *)&a_struct[(ip)->jmp.a.offset];         \\\n+\tuint64_t a64 = *a64_ptr;                                               \\\n+\tuint64_t a = ntoh64(a64) >> (64 - (ip)->jmp.a.n_bits);                 \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t b = (ip)->jmp.b_val;                                          \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t(thread)->ip = (a operator b) ? (ip)->jmp.ip : ((thread)->ip + 1);     \\\n+}\n+\n+#else\n+\n+#define JMP_CMP_HI JMP_CMP_I\n+\n+#endif\n+\n+#define METADATA_READ(thread, offset, n_bits)                                  \\\n+({                                                                             \\\n+\tuint64_t *m64_ptr = (uint64_t *)&(thread)->metadata[offset];           \\\n+\tuint64_t m64 = *m64_ptr;                                               \\\n+\tuint64_t m64_mask = UINT64_MAX >> (64 - (n_bits));                     \\\n+\t(m64 & m64_mask);                                                      \\\n+})\n+\n+#define METADATA_WRITE(thread, offset, n_bits, value)                          \\\n+{                                                                              \\\n+\tuint64_t *m64_ptr = (uint64_t *)&(thread)->metadata[offset];           \\\n+\tuint64_t m64 = *m64_ptr;                                               \\\n+\tuint64_t m64_mask = UINT64_MAX >> (64 - (n_bits));                     \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\tuint64_t m_new = value;                                                \\\n+\t\t\t\t\t\t\t\t\t       \\\n+\t*m64_ptr = (m64 & ~m64_mask) | (m_new & m64_mask);                     \\\n+}\n+\n+#ifndef RTE_SWX_PIPELINE_THREADS_MAX\n+#define RTE_SWX_PIPELINE_THREADS_MAX 16\n+#endif\n+\n+struct rte_swx_pipeline {\n+\tstruct struct_type_tailq struct_types;\n+\tstruct port_in_type_tailq port_in_types;\n+\tstruct port_in_tailq ports_in;\n+\tstruct port_out_type_tailq port_out_types;\n+\tstruct port_out_tailq ports_out;\n+\tstruct extern_type_tailq extern_types;\n+\tstruct extern_obj_tailq extern_objs;\n+\tstruct extern_func_tailq extern_funcs;\n+\tstruct header_tailq headers;\n+\tstruct struct_type *metadata_st;\n+\tuint32_t metadata_struct_id;\n+\tstruct action_tailq actions;\n+\tstruct table_type_tailq table_types;\n+\tstruct table_tailq tables;\n+\tstruct selector_tailq selectors;\n+\tstruct learner_tailq learners;\n+\tstruct regarray_tailq regarrays;\n+\tstruct meter_profile_tailq meter_profiles;\n+\tstruct metarray_tailq metarrays;\n+\n+\tstruct port_in_runtime *in;\n+\tstruct port_out_runtime *out;\n+\tstruct instruction **action_instructions;\n+\tstruct rte_swx_table_state *table_state;\n+\tstruct table_statistics *table_stats;\n+\tstruct selector_statistics *selector_stats;\n+\tstruct learner_statistics *learner_stats;\n+\tstruct regarray_runtime *regarray_runtime;\n+\tstruct metarray_runtime *metarray_runtime;\n+\tstruct instruction *instructions;\n+\tstruct thread threads[RTE_SWX_PIPELINE_THREADS_MAX];\n+\n+\tuint32_t n_structs;\n+\tuint32_t n_ports_in;\n+\tuint32_t n_ports_out;\n+\tuint32_t n_extern_objs;\n+\tuint32_t n_extern_funcs;\n+\tuint32_t n_actions;\n+\tuint32_t n_tables;\n+\tuint32_t n_selectors;\n+\tuint32_t n_learners;\n+\tuint32_t n_regarrays;\n+\tuint32_t n_metarrays;\n+\tuint32_t n_headers;\n+\tuint32_t thread_id;\n+\tuint32_t port_id;\n+\tuint32_t n_instructions;\n+\tint build_done;\n+\tint numa_node;\n+};\n+\n+#endif\n",
    "prefixes": [
        "01/24"
    ]
}