@@ -86,7 +86,7 @@ pub(crate) fn emit_expression(
8686 }
8787 ExpressionKind :: Call ( call) => match context {
8888 P4Context :: Control ( c) => {
89- let ( stmts, blks, value) = emit_call (
89+ let ( stmts, blks, value) = emit_call_in_control (
9090 call,
9191 c,
9292 hlir,
@@ -191,7 +191,44 @@ pub(crate) fn emit_binary_expr_eq(
191191 todo ! ( )
192192}
193193
194- pub ( crate ) fn emit_call (
194+ pub ( crate ) fn emit_call_in_parser (
195+ call : & p4:: ast:: Call ,
196+ parser : & p4:: ast:: Parser ,
197+ hlir : & Hlir ,
198+ ast : & p4:: ast:: AST ,
199+ ra : & mut RegisterAllocator ,
200+ afa : & mut AsyncFlagAllocator ,
201+ names : & HashMap < String , NameInfo > ,
202+ table_context : & mut TableContext ,
203+ ) -> Result <
204+ (
205+ Vec < Statement > ,
206+ Vec < htq:: ast:: StatementBlock > ,
207+ Option < ExpressionValue > ,
208+ ) ,
209+ CodegenError ,
210+ > {
211+ match call. lval . leaf ( ) {
212+ "extract" => {
213+ let ( stmts, result) = emit_extract_call (
214+ call,
215+ parser,
216+ hlir,
217+ ast,
218+ ra,
219+ afa,
220+ names,
221+ table_context,
222+ ) ?;
223+ Ok ( ( stmts, Vec :: default ( ) , result) )
224+ }
225+ x => {
226+ todo ! ( "unhandled parser function: {x:#?}" ) ;
227+ }
228+ }
229+ }
230+
231+ pub ( crate ) fn emit_call_in_control (
195232 call : & p4:: ast:: Call ,
196233 control : & p4:: ast:: Control ,
197234 hlir : & Hlir ,
@@ -254,6 +291,88 @@ pub(crate) fn emit_call(
254291 }
255292}
256293
294+ fn emit_extract_call (
295+ call : & p4:: ast:: Call ,
296+ parser : & p4:: ast:: Parser ,
297+ _hlir : & Hlir ,
298+ ast : & p4:: ast:: AST ,
299+ ra : & mut RegisterAllocator ,
300+ _afa : & mut AsyncFlagAllocator ,
301+ names : & HashMap < String , NameInfo > ,
302+ _table_context : & mut TableContext ,
303+ ) -> Result < ( Vec < Statement > , Option < ExpressionValue > ) , CodegenError > {
304+ let src = & parser. parameters [ 1 ] . name ;
305+ let source = ra. get ( src) . ok_or ( CodegenError :: NoRegisterForParameter (
306+ src. to_owned ( ) ,
307+ ra. clone ( ) ,
308+ ) ) ?;
309+
310+ let tgt = call
311+ . args
312+ . first ( )
313+ . ok_or ( CodegenError :: NotEnoughArgs ( call. lval . clone ( ) ) ) ?;
314+ let tgt = match & tgt. kind {
315+ ExpressionKind :: Lvalue ( lval) => lval,
316+ _ => return Err ( CodegenError :: ExpectedLvalue ( tgt. as_ref ( ) . clone ( ) ) ) ,
317+ } ;
318+ let target = ra
319+ . get ( tgt. root ( ) )
320+ . ok_or ( CodegenError :: RegisterDoesNotExistForLval ( tgt. clone ( ) ) ) ?;
321+ let output = ra. alloc ( & tgt. root ( ) ) ;
322+
323+ let info = names
324+ . get ( tgt. root ( ) )
325+ . ok_or ( CodegenError :: HeaderDeclNotFound ( tgt. clone ( ) ) ) ?;
326+
327+ let typename = match & info. ty {
328+ p4:: ast:: Type :: UserDefined ( name, _) => name. clone ( ) ,
329+ _ => return Err ( CodegenError :: ExpectedHeaderType ( tgt. clone ( ) ) ) ,
330+ } ;
331+
332+ let offset = if let Some ( hdr) = ast. get_header ( & typename) {
333+ hdr. index_of ( tgt. leaf ( ) )
334+ . ok_or ( CodegenError :: MemberOffsetNotFound ( tgt. clone ( ) ) ) ?
335+ } else {
336+ let st = ast. get_struct ( & typename) . ok_or (
337+ CodegenError :: HeaderDefnNotFound ( typename. clone ( ) , tgt. clone ( ) ) ,
338+ ) ?;
339+ st. index_of ( tgt. leaf ( ) )
340+ . ok_or ( CodegenError :: MemberOffsetNotFound ( tgt. clone ( ) ) ) ?
341+ } ;
342+
343+ let sz = type_size ( & info. ty , ast) ;
344+
345+ let offset_reg =
346+ ra. get ( "offset" )
347+ . ok_or ( CodegenError :: NoRegisterForParameter (
348+ String :: from ( "offset" ) ,
349+ ra. clone ( ) ,
350+ ) ) ?;
351+
352+ let extract_stmt = htq:: ast:: Extract {
353+ output,
354+ target,
355+ target_offset : Value :: number ( offset as i128 ) ,
356+ source,
357+ source_offset : Value :: reg ( offset_reg. clone ( ) ) , //TODO
358+ } ;
359+
360+ let add_offset_stmt = htq:: ast:: Add {
361+ target : ra. alloc ( & offset_reg. 0 ) ,
362+ typ : Type :: Unsigned ( 32 ) ,
363+ source_a : Value :: reg ( offset_reg) ,
364+ source_b : Value :: number ( sz as i128 ) ,
365+ } ;
366+
367+ Ok ( (
368+ vec ! [
369+ Statement :: Extract ( extract_stmt) ,
370+ Statement :: Add ( add_offset_stmt) ,
371+ ] ,
372+ None ,
373+ ) )
374+ }
375+
257376fn emit_apply_call (
258377 call : & p4:: ast:: Call ,
259378 control : & p4:: ast:: Control ,
0 commit comments