def set_table_key_attrs(hlir, table): for k in table.key.keyElements: match_name = k.matchType.path.name k.match_order = table_key_match_order.index(match_name) kx = k.expression if 'expr' not in kx: k.size = kx.urtype.size # TODO remove? # the key element is a local variable in a control # locs = table.control.controlLocals # locvar = locs.get(kx.path.name) # k.size = locvar.urtype.size continue kxx = kx.expr k.field_name = kx.member hdrname = None if kxx.node_type == 'Member': hdrname = kxx.member if hdrname is None and (fld := hlir.allmetas.urtype.fields.get( k.field_name)): # TODO .hdr_ref is already set in some cases, but not all kxx.hdr_ref = hlir.allmetas k.header = hlir.allmetas k.header_name = 'all_metadatas' k.size = fld.size else: # supposing that kx is of form '<header_name>.<name>' if kxx.node_type == 'PathExpression': k.header_name = kxx.hdr_ref.name # supposing that kx is of form 'hdr.<header_name>.<name>' elif kxx.node_type == 'Member': k.header_name = kxx.member elif kxx.node_type == 'ArrayIndex': idx = kxx.right.value k.header_name = f'{kxx.left.member}_{idx}' else: addWarning("Table key analysis", f"Header not found for key in table {table.name}") continue k.header = hlir.header_instances.get(k.header_name) fld = k.header.urtype.fields.get(k.field_name) k.size = fld.urtype.size
return is_underscore_header, hdr, hdrt for s in parser.states: if not s.is_reachable: continue 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
#[ debug(" %%%%%%%% Parser state $$[parserstate]{s.name}\n"); for component in s.components: if 'call' not in component: #[ ${format_statement(component, parser)} continue if component.call != 'extract_header': continue arg0 = component.methodCall.arguments['Argument'][0] hdr = get_hdrinst(arg0, component) if hdr is None: hdrt = arg0.expression.hdr_ref.urtype if hdrt.size % 8 != 0: addWarning('extracting underscore header', f'Extracting non-byte-aligned header type {hdrt.name}/{hdrt.size}b as noname header') size = (hdrt.size+7)//8 #[ // extracting to underscore argument, $size bytes (${hdrt.size} bits) #[ debug(" :: Extracting " T4LIT(${hdrt.name},header) "/" T4LIT($size) " as " T4LIT(noname header,header) "\n"); #[ pd->extract_ptr += $size; #[ pd->is_emit_reordering = true; // a noname header cannot be emitted else: #[ int offset_${hdr.name} = parser_extract_${hdr.name}(STDPARAMS_IN); #{ if (unlikely(offset_${hdr.name}) < 0) { #[ drop_packet(STDPARAMS_IN); #[ return; #} } #[ if 'selectExpression' not in s:
#{ table_entry_${table.name}_t initial_default = { #[ .action = { action_${table.default_action.expression.method.action_ref.name} }, #[ .is_entry_valid = VALID_TABLE_ENTRY, #} }; #[ table_setdefault_promote(TABLE_${table.name}, (uint8_t *)&initial_default); #} } #} } for table in hlir.tables: if 'entries' not in table: 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
#{ if (unlikely(!is_header_valid(HDR(${hi_name}), pd))) { #{ #ifdef T4P4S_DEBUG #[ debug(" " T4LIT(!!!!,error) " " T4LIT(Lookup on invalid header,error) " " T4LIT(${hi_name},header) "." T4LIT(${f.field_name},field) ", " T4LIT(it will contain an unspecified value,warning) "\n"); #} #endif #[ return; #} } 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: # f is a control local if f.size <= 32 or f.size % 8 == 0: byte_width = (f.size+7)//8 fld_name = f.expression.path.name #[ memcpy(key, &((control_locals_${table.control.name}_t*) pd->control_locals)->${fld_name}, ${byte_width}); #[ key += ${byte_width}; else: addWarning("table key computation", f"Skipping unsupported key component {f.expression.path.name} ({f.size} bits): it is over 32 bits long and not byte aligned") if table.matchType.name == "lpm": #[ key -= ${table.key_length_bytes}; #} } ################################################################################
def check_resolved(node): if 'name' in node: addWarning('resolving type', f'Type name {node.name} could not be resolved') else: addWarning('resolving type', f'Type {node} could not be resolved')
method = mcall.methodCall.method mname = method.expr.path.name mprefix = 'tbl_' if mname.startswith(mprefix) and (action := actions.get( mname[len(mprefix):])) is not None: if (tbl := ctl.tables.get(f'{mprefix}{action.name}')) is not None: replace_short_name(tbl, prefix) else: return replace_short_name(action, prefix) elif (mcall := comp).node_type == 'EmptyStatement': pass else: addWarning('Improving action names', f'Unexpected statement node type {comp.node_type}') def attrs_improve_action_names(hlir): for ctl in hlir.controls: improve_action_names(ctl, ctl, ctl.actions, '') def attrs_improve_localvar_names(hlir): for ctl in hlir.controls: shorten_locvar_names(ctl.controlLocals['Declaration_Variable']) for parser in hlir.parsers: shorten_locvar_names(parser.parserLocals['Declaration_Variable'])