<commit_before># SPDX-License-Identifier: Apache-2.0
# Copyright 2016 Eotvos Lorand University, Budapest, Hungary

from compiler_common import unique_everseen
from utils.codegen import format_expr, format_type

#[ #include <unistd.h>

#[ #include "dpdk_lib.h"
#[ #include "actions.h"
#[ #include "tables.h"

#[ extern void table_setdefault_promote  (int tableid, uint8_t* value);
#[ extern void exact_add_promote  (int tableid, uint8_t* key, uint8_t* value, bool should_print);
#[ extern void lpm_add_promote    (int tableid, uint8_t* key, uint8_t depth, uint8_t* value, bool should_print);
#[ extern void ternary_add_promote(int tableid, uint8_t* key, uint8_t* mask, uint8_t* value, bool should_print);

#{ #ifdef T4P4S_P4RT
#[     #include "PI/proto/pi_server.h"
#[     #include "p4rt/device_mgr.h"
#[     extern device_mgr_t *dev_mgr_ptr;
#} #endif


for table in hlir.tables:
    #[ extern void table_${table.name}_key(packet_descriptor_t* pd, uint8_t* key); // defined in dataplane.c


max_bytes = max([0] + [t.key_length_bytes for t in hlir.tables])
#[ uint8_t reverse_buffer[$max_bytes];

# Variable width fields are not supported
def get_key_byte_width(k):
    if 'size' in k:
        return (k.size+7)//8

    if k.header.urtype('is_vw', False):
        return 0

    return (k.header.type.size+7)//8


for table in hlir.tables:
    #[ // note: ${table.name}, ${table.matchType.name}, ${table.key_length_bytes}
    #{ void ${table.name}_add(
    for k in table.key.keyElements:
        if 'header' not in k:
            varname = k.expression.path.name
            #[ uint8_t* $varname,
            # ${format_type(k.expression.urtype)} $varname,
            # TODO mask?
        else:
            byte_width = get_key_byte_width(k)
            #[ uint8_t field_${k.header.name}_${k.field_name}[$byte_width],

            # TODO have keys' and tables' matchType the same case (currently: LPM vs lpm)
            if k.matchType == "ternary":
                #[ uint8_t ${k.field_name}_mask[$byte_width],
            if k.matchType == "lpm":
                #[ uint8_t field_${k.header.name}_${k.field_name}_prefix_length,

    #}     ${table.name}_action_t action, bool has_fields)
    #{ {
    #[     uint8_t key[${table.key_length_bytes}];

    byte_idx = 0
    for k in sorted((k for k in table.key.keyElements), key = lambda k: k.match_order):
        byte_width = get_key_byte_width(k)
        target_name = f'{k.expression.path.name}' if 'header' not in k else f'field_{k.header.name}_{k.field_name}'
        #[ memcpy(key+$byte_idx, (uint8_t*)${target_name}, $byte_width);
        byte_idx += byte_width

    if table.matchType.name == "lpm":
        target_name = f'{k.expression.path.name}' if 'header' not in k else f'field_{k.header.name}_{k.field_name}'
        #[ uint8_t prefix_length = 0;
        for k in table.key.keyElements:
            if k.matchType == "exact":
                #[ prefix_length += ${get_key_byte_width(k)};
            if k.matchType == "lpm":
                #[ prefix_length += ${target_name}_prefix_length;
        #[ int c, d;
        #[ for(c = ${byte_idx-1}, d = 0; c >= 0; c--, d++) *(reverse_buffer+d) = *(key+c);
        #[ for(c = 0; c < ${byte_idx}; c++) *(key+c) = *(reverse_buffer+c);
        #[ lpm_add_promote(TABLE_${table.name}, (uint8_t*)key, prefix_length, (uint8_t*)&action, has_fields);

    if table.matchType.name == "exact":
        #[ exact_add_promote(TABLE_${table.name}, (uint8_t*)key, (uint8_t*)&action, has_fields);

    #} }

for table in hlir.tables:
    #{ void ${table.name}_add_table_entry(struct p4_ctrl_msg* ctrl_m) {
    for i, k in enumerate(table.key.keyElements):
        target_name = f'{k.expression.path.name}' if 'header' not in k else f'field_{k.header.name}_{k.field_name}'

        if k.matchType.path.name == "exact":
            #[ uint8_t* ${target_name} = (uint8_t*)(((struct p4_field_match_exact*)ctrl_m->field_matches[${i}])->bitmap);
        if k.matchType.path.name == "lpm":
            #[ uint8_t* ${target_name} = (uint8_t*)(((struct p4_field_match_lpm*)ctrl_m->field_matches[${i}])->bitmap);
            #[ uint16_t ${target_name}_prefix_length = ((struct p4_field_match_lpm*)ctrl_m->field_matches[${i}])->prefix_length;
        if k.matchType.path.name == "ternary":
            # TODO are these right?
            #[ uint8_t* ${target_name} = (uint8_t*)(((struct p4_field_match_lpm*)ctrl_m->field_matches[${i}])->bitmap);
            #[ uint16_t ${target_name}_prefix_length = ((struct p4_field_match_lpm*)ctrl_m->field_matches[${i}])->prefix_length;

    for action in table.actions:
        #{ if(strcmp("${action.action_object.canonical_name}", ctrl_m->action_name)==0) {
        #[     ${table.name}_action_t action;
        #[     action.action_id = action_${action.action_object.name};
        for j, p in enumerate(action.action_object.parameters.parameters):
            #[ uint8_t* bitmap_${p.name} = (uint8_t*)((struct p4_action_parameter*)ctrl_m->action_params[$j])->bitmap;
            #[ memcpy(action.${action.action_object.name}_params.${p.name}, bitmap_${p.name}, ${(p.urtype.size+7)//8});

        params = []
        for i, k in enumerate(table.key.keyElements):
            target_name = f'{k.expression.path.name}' if 'header' not in k else f'field_{k.header.name}_{k.field_name}'

            params.append(target_name)
            if k.matchType == "lpm":
                params.append(f"{target_name}_prefix_length")
            if k.matchType == "ternary":
                params.append("0 /* TODO ternary dstPort_mask */")

        has_fields = "false" if len(action.action_object.parameters.parameters) == 0 else "true"
        joined_params = ', '.join(params + ["action", has_fields])<commit_msg>Bug fix - filling LPM table with key + prefix<commit_after># SPDX-License-Identifier: Apache-2.0
# Copyright 2016 Eotvos Lorand University, Budapest, Hungary

from compiler_common import unique_everseen
from utils.codegen import format_expr, format_type

#[ #include <unistd.h>

#[ #include "dpdk_lib.h"
#[ #include "actions.h"
#[ #include "tables.h"

#[ extern void table_setdefault_promote  (int tableid, uint8_t* value);
#[ extern void exact_add_promote  (int tableid, uint8_t* key, uint8_t* value, bool should_print);
#[ extern void lpm_add_promote    (int tableid, uint8_t* key, uint8_t depth, uint8_t* value, bool should_print);
#[ extern void ternary_add_promote(int tableid, uint8_t* key, uint8_t* mask, uint8_t* value, bool should_print);

#{ #ifdef T4P4S_P4RT
#[     #include "PI/proto/pi_server.h"
#[     #include "p4rt/device_mgr.h"
#[     extern device_mgr_t *dev_mgr_ptr;
#} #endif


for table in hlir.tables:
    #[ extern void table_${table.name}_key(packet_descriptor_t* pd, uint8_t* key); // defined in dataplane.c


max_bytes = max([0] + [t.key_length_bytes for t in hlir.tables])
#[ uint8_t reverse_buffer[$max_bytes];

# Variable width fields are not supported
def get_key_byte_width(k):
    if 'size' in k:
        return (k.size+7)//8

    if k.header.urtype('is_vw', False):
        return 0

    return (k.header.type.size+7)//8


for table in hlir.tables:
    #[ // note: ${table.name}, ${table.matchType.name}, ${table.key_length_bytes}
    #{ void ${table.name}_add(
    for k in table.key.keyElements:
        if 'header' not in k:
            varname = k.expression.path.name
            #[ uint8_t* $varname,
            # ${format_type(k.expression.urtype)} $varname,
            # TODO mask?
        else:
            byte_width = get_key_byte_width(k)
            #[ uint8_t field_${k.header.name}_${k.field_name}[$byte_width],
            #[ /* ${dir(k.matchType)} */
            # TODO have keys' and tables' matchType the same case (currently: LPM vs lpm)
            if k.matchType.path.name == "ternary": # TODO: LS Check!
                #[ uint8_t ${k.field_name}_mask[$byte_width],
            if k.matchType.path.name == "lpm": # TODO: LS Check!
                #[ uint8_t field_${k.header.name}_${k.field_name}_prefix_length,

    #}     ${table.name}_action_t action, bool has_fields)
    #{ {
    #[     uint8_t key[${table.key_length_bytes}];

    byte_idx = 0
    for k in sorted((k for k in table.key.keyElements), key = lambda k: k.match_order):
        byte_width = get_key_byte_width(k)
        target_name = f'{k.expression.path.name}' if 'header' not in k else f'field_{k.header.name}_{k.field_name}'
        #[ memcpy(key+$byte_idx, (uint8_t*)${target_name}, $byte_width);
        byte_idx += byte_width

    if table.matchType.name == "lpm":
        target_name = f'{k.expression.path.name}' if 'header' not in k else f'field_{k.header.name}_{k.field_name}'
        #[ uint8_t prefix_length = 0;
        for k in table.key.keyElements:
            if k.matchType.path.name == "exact": # TODO: LS Check!
                #[ prefix_length += ${get_key_byte_width(k)};
            if k.matchType.path.name == "lpm": # TODO: LS Check!
                #[ prefix_length += ${target_name}_prefix_length;
        #[ int c, d;
        #[ for(c = ${byte_idx-1}, d = 0; c >= 0; c--, d++) *(reverse_buffer+d) = *(key+c);
        #[ for(c = 0; c < ${byte_idx}; c++) *(key+c) = *(reverse_buffer+c);
        #[ lpm_add_promote(TABLE_${table.name}, (uint8_t*)key, prefix_length, (uint8_t*)&action, has_fields);

    if table.matchType.name == "exact":
        #[ exact_add_promote(TABLE_${table.name}, (uint8_t*)key, (uint8_t*)&action, has_fields);

    #} }

for table in hlir.tables:
    #{ void ${table.name}_add_table_entry(struct p4_ctrl_msg* ctrl_m) {
    for i, k in enumerate(table.key.keyElements):
        target_name = f'{k.expression.path.name}' if 'header' not in k else f'field_{k.header.name}_{k.field_name}'

        if k.matchType.path.name == "exact":
            #[ uint8_t* ${target_name} = (uint8_t*)(((struct p4_field_match_exact*)ctrl_m->field_matches[${i}])->bitmap);
        if k.matchType.path.name == "lpm":
            #[ uint8_t* ${target_name} = (uint8_t*)(((struct p4_field_match_lpm*)ctrl_m->field_matches[${i}])->bitmap);
            #[ uint16_t ${target_name}_prefix_length = ((struct p4_field_match_lpm*)ctrl_m->field_matches[${i}])->prefix_length;
        if k.matchType.path.name == "ternary":
            # TODO are these right?
            #[ uint8_t* ${target_name} = (uint8_t*)(((struct p4_field_match_lpm*)ctrl_m->field_matches[${i}])->bitmap);
            #[ uint16_t ${target_name}_prefix_length = ((struct p4_field_match_lpm*)ctrl_m->field_matches[${i}])->prefix_length;

    for action in table.actions:
        #{ if(strcmp("${action.action_object.canonical_name}", ctrl_m->action_name)==0) {
        #[     ${table.name}_action_t action;
        #[     action.action_id = action_${action.action_object.name};
        for j, p in enumerate(action.action_object.parameters.parameters):
            #[ uint8_t* bitmap_${p.name} = (uint8_t*)((struct p4_action_parameter*)ctrl_m->action_params[$j])->bitmap;
            #[ memcpy(action.${action.action_object.name}_params.${p.name}, bitmap_${p.name}, ${(p.urtype.size+7)//8});

        params = []
        for i, k in enumerate(table.key.keyElements):
            target_name = f'{k.expression.path.name}' if 'header' not in k else f'field_{k.header.name}_{k.field_name}'

            params.append(target_name)
            if k.matchType.path.name == "lpm":
                params.append(f"{target_name}_prefix_length")
            if k.matchType.path.name == "ternary":
                params.append("0 /* TODO ternary dstPort_mask */")

        has_fields = "false" if len(action.action_object.parameters.parameters) == 0 else "true"
        joined_params = ', '.join(params + ["action", has_fields])
{'fraction_non_alphanumeric': 0.15615358244772026, 'fraction_numerical': 0.011655810764484058, 'mean_word_length': 3.145293072824156, 'pattern_counts': {'":': 22, '<': 7, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1349803', 'n_tokens_mistral': 4126, 'n_tokens_neox': 4140, 'n_words': 799}