Skip to content

Commit f0d0c24

Browse files
committed
more pblock/call/control-flow plumbing
1 parent 36234af commit f0d0c24

2 files changed

Lines changed: 86 additions & 15 deletions

File tree

codegen/htq/src/expression.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ fn emit_extern_call(
561561
fn emit_indirect_action_call(
562562
call: &p4::ast::Call,
563563
_hlir: &Hlir,
564-
_ast: &p4::ast::AST,
564+
ast: &p4::ast::AST,
565565
context: &P4Context<'_>,
566566
ra: &mut RegisterAllocator,
567567
_names: &HashMap<String, NameInfo>,
@@ -603,6 +603,7 @@ fn emit_indirect_action_call(
603603
)?);
604604
block_params.push(block_ra.alloc(&p.name));
605605
}
606+
block_params.push(info.args.clone());
606607

607608
let control_param_values = control_params
608609
.iter()
@@ -616,21 +617,45 @@ fn emit_indirect_action_call(
616617
.map(Value::reg)
617618
.collect::<Vec<_>>();
618619

620+
let mut block_args = control_param_values.clone();
621+
block_args.push(Value::reg(info.args.clone()));
622+
619623
for (i, a) in info.table.actions.iter().enumerate() {
624+
// make a clean lbock for each action
625+
let mut block_ra = block_ra.clone();
626+
let mut block_param_values = block_param_values.clone();
627+
// pop the args off, we're going to break it up into components
628+
block_param_values.pop();
629+
620630
let action_decl = info.control.get_action(&a.name).ok_or(
621631
CodegenError::ActionNotFound(a.clone(), info.control.clone()),
622632
)?;
623633
let mut control_out_params = Vec::default();
624634
let mut out_params = Vec::default();
635+
let mut stmts = Vec::default();
636+
637+
let mut action_params = Vec::default();
638+
639+
let mut offset = 0;
640+
let key = info.args.clone();
625641
for x in &action_decl.parameters {
626642
if x.direction.is_out() {
627-
out_params.push(ra.get(&x.name).ok_or(
628-
CodegenError::NoRegisterForParameter(
629-
x.name.clone(),
630-
ra.clone(),
631-
),
632-
)?)
643+
out_params.push(block_ra.alloc(&x.name));
633644
}
645+
646+
let action_param_reg = block_ra.alloc(&format!("{}_arg", &x.name));
647+
let sz = type_size(&x.ty, ast);
648+
action_params.push(action_param_reg.clone());
649+
stmts.push(Statement::Load(htq::ast::Load {
650+
target: action_param_reg.clone(),
651+
typ: Type::Bitfield(sz),
652+
source: key.clone(),
653+
offset: Value::number(offset),
654+
}));
655+
656+
block_param_values.push(Value::reg(action_param_reg.clone()));
657+
658+
offset += sz as i128;
634659
}
635660
for x in &info.control.parameters {
636661
if x.ty.is_lookup_result() {
@@ -646,9 +671,9 @@ fn emit_indirect_action_call(
646671
source: info.variant.clone(),
647672
predicate: Value::number(i as i128),
648673
label: a.name.clone(),
649-
args: control_param_values.clone(),
674+
args: block_args.clone(),
650675
}));
651-
let mut stmts = Vec::default();
676+
652677
stmts.push(Statement::Call(htq::ast::Call {
653678
fname: format!("{}_{}", info.control.name, a.name.clone()),
654679
args: block_param_values.clone(),

codegen/htq/src/statement.rs

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,60 @@ fn emit_if_block(
9595
) -> Result<
9696
(Vec<htq::ast::Statement>, Vec<htq::ast::StatementBlock>),
9797
CodegenError,
98+
> {
99+
let (mut statements, mut blocks) = emit_conditional_block(
100+
hlir,
101+
ast,
102+
context,
103+
names,
104+
&iblk.predicate,
105+
&iblk.block,
106+
ra,
107+
afa,
108+
psub,
109+
table_context,
110+
)?;
111+
112+
for elif in &iblk.else_ifs {
113+
let (stmts, blks) = emit_conditional_block(
114+
hlir,
115+
ast,
116+
context,
117+
names,
118+
&elif.predicate,
119+
&elif.block,
120+
ra,
121+
afa,
122+
psub,
123+
table_context,
124+
)?;
125+
statements.extend(stmts);
126+
blocks.extend(blks);
127+
}
128+
129+
Ok((statements, blocks))
130+
}
131+
132+
fn emit_conditional_block(
133+
hlir: &Hlir,
134+
ast: &p4::ast::AST,
135+
context: &P4Context<'_>,
136+
names: &mut HashMap<String, NameInfo>,
137+
predicate: &p4::ast::Expression,
138+
block: &p4::ast::StatementBlock,
139+
ra: &mut RegisterAllocator,
140+
afa: &mut AsyncFlagAllocator,
141+
psub: &mut HashMap<ControlParameter, Vec<Register>>,
142+
table_context: &mut TableContext,
143+
) -> Result<
144+
(Vec<htq::ast::Statement>, Vec<htq::ast::StatementBlock>),
145+
CodegenError,
98146
> {
99147
let mut result = Vec::default();
100148
let mut blocks = Vec::default();
101149

102150
let (source, predicate) =
103-
if let ExpressionKind::Binary(lhs, BinOp::Eq, rhs) =
104-
&iblk.predicate.kind
105-
{
151+
if let ExpressionKind::Binary(lhs, BinOp::Eq, rhs) = &predicate.kind {
106152
let (source_statements, blks, source) =
107153
emit_single_valued_expression(
108154
lhs.as_ref(),
@@ -135,7 +181,7 @@ fn emit_if_block(
135181
} else {
136182
let (predicate_statements, blks, source) =
137183
emit_single_valued_expression(
138-
iblk.predicate.as_ref(),
184+
predicate,
139185
hlir,
140186
ast,
141187
context,
@@ -169,7 +215,7 @@ fn emit_if_block(
169215
statements: Vec::default(),
170216
};
171217

172-
for stmt in &iblk.block.statements {
218+
for stmt in &block.statements {
173219
// TODO nested if blocks
174220
let (stmts, blks) = emit_statement(
175221
stmt,
@@ -195,7 +241,7 @@ fn emit_if_block(
195241
out_params.push(block_ra.get(&x.name).ok_or(
196242
CodegenError::NoRegisterForParameter(
197243
x.name.clone(),
198-
ra.clone(),
244+
block_ra.clone(),
199245
),
200246
)?);
201247
}

0 commit comments

Comments
 (0)