@@ -86,7 +86,7 @@ pub(crate) fn emit_expression(
86
86
}
87
87
ExpressionKind :: Call ( call) => match context {
88
88
P4Context :: Control ( c) => {
89
- let ( stmts, blks, value) = emit_call (
89
+ let ( stmts, blks, value) = emit_call_in_control (
90
90
call,
91
91
c,
92
92
hlir,
@@ -191,7 +191,44 @@ pub(crate) fn emit_binary_expr_eq(
191
191
todo ! ( )
192
192
}
193
193
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 (
195
232
call : & p4:: ast:: Call ,
196
233
control : & p4:: ast:: Control ,
197
234
hlir : & Hlir ,
@@ -254,6 +291,88 @@ pub(crate) fn emit_call(
254
291
}
255
292
}
256
293
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
+
257
376
fn emit_apply_call (
258
377
call : & p4:: ast:: Call ,
259
378
control : & p4:: ast:: Control ,
0 commit comments