def gen_fill_key_component_slice(ke): src = generate_var_name('slice') slice_expr = gen_format_slice(ke) #= compiler_common.pre_statement_buffer #[ ${format_type(ke.e0.type)} $src = ${slice_expr}; #= compiler_common.post_statement_buffer compiler_common.pre_statement_buffer = "" compiler_common.post_statement_buffer = ""
for idx, component in enumerate(s.components): #{ static void ${state_component_name(s, idx, component)}(STDPARAMS) { #[ uint32_t res32; (void)res32; #[ parser_state_t* local_vars = pstate; if 'call' in component: if component.call != 'extract_header': addWarning('invoking state component', f'Unknown state component call of type {component.call}') continue is_underscore_header, hdr, hdrt = component_extract_info(component) # TODO remove? args = component.methodCall.arguments var = generate_var_name('vwlen') if len(args) == 1: #[ int $var = 0; else: bexpr = format_expr(args[1].expression) prebuf, postbuf = statement_buffer_value() #[ $prebuf #[ int $var = ${bexpr}; #[ $postbuf #[ int offset_${hdr.name} = parser_extract_${hdr.name}($var, STDPARAMS_IN); #{ if (unlikely(offset_${hdr.name}) < 0) { #[ drop_packet(STDPARAMS_IN); #[ debug(" " T4LIT(XX,status) " " T4LIT(Dropping packet,status) "\n"); #[ return; #} }
def make_var(key, ksize): name, hex_content = make_const(key._left) const_var = generate_var_name(f"const{ksize}", name) return const_var, hex_content
continue #{ void init_table_const_entries_${table.name}() { for entry in table.entries.entries: if any((component.urtype.node_type == 'Type_Dontcare' for component in entry.keys.components)): addWarning("adding const entry", f"Underscore entry for const entry for table {table.name} not supported yet") continue utils.codegen.pre_statement_buffer = "" action_id = entry.action.method.path.name key_total_size = (sum((key._left.urtype.size for key in entry.keys.components))+7) // 8 # note: _left is for lpm and ternary that may have a mask key_var = generate_var_name("key", f"{table.name}__{action_id}") action_var = generate_var_name("action", f"{table.name}__{action_id}") params = entry.action.method.type.parameters.parameters args = entry.action.arguments #[ ${utils.codegen.pre_statement_buffer} #[ uint8_t ${key_var}[${key_total_size}]; def make_var(key, ksize): name, hex_content = make_const(key._left) const_var = generate_var_name(f"const{ksize}", name) return const_var, hex_content keys = entry.keys.components
#} } if f.size <= 32: #[ EXTRACT_INT32_BITS_PACKET(pd, HDR(${hi_name}), FLD(${f.header.name},${f.field_name}), *(uint32_t*)key); #[ key += sizeof(uint32_t); elif f.size > 32 and f.size % 8 == 0: byte_width = (f.size+7)//8 #[ EXTRACT_BYTEBUF_PACKET(pd, HDR(${hi_name}), FLD(${f.header.name},${f.field_name}), key); #[ key += ${byte_width}; else: addWarning("table key computation", f"Skipping unsupported field {f.id} ({f.size} bits): it is over 32 bits long and not byte aligned") else: fx = f.expression if fx.node_type == 'MethodCallExpression': byte_width = (fx.urtype.size + 7) // 8 var = generate_var_name(f'mcall_{fx.method.member}') #[ ${format_type(fx.type)} $var = ${format_expr(fx)}; #[ memcpy(key, &$var, ${byte_width}); elif f.size <= 32 or f.size % 8 == 0: if fx.node_type == 'Slice': high = fx.e1.value low = fx.e2.value bit_width = high - low + 1 byte_width = (bit_width+7) // 8 bit_offset = fx.e0.urtype.size - high - 1 byte_offset = (bit_offset+7) // 8 is_byte_aligned = bit_width % 8 == 0 hdrname, fldname = get_hdrfld_name(fx.e0)