pokefmt is a template system to embed Poke code in files.
It copies the content from standard input to standard output and
replaces the Poke code with the result of execution. You can write
Poke code between %{ and }% delimters. To simplify
printing of expressions, pokefmt also supports embedding of
Poke expressions between %( and %) delimiters.
As as example, pokefmt will transform the following text
%{
load riscv;
var a = 1, b = 2;
}%
The encoding of ADD R3, R2, R1 instruction in RISC-V instruction set
is %{printf "0x%u32x", rv32_add (3, 2, 1);}%.
The result of %(a)% + %(b)% is %(a + b)%.
to this text:
The encoding of ADD R3, R2, R1 instruction in RISC-V instruct set is 0x001101b3. The result of 1 + 2 is 3.
You can customize the printer for expressions by re-defining
pokefmt_expr_printer function. For example,
#as: -march=rv32i
#objdump: -dr
%{
load riscv;
fun pokefmt_expr_printer = (any i32) void:
{
printf ("%u32x", i32 as uint<32>);
}
}%
.*:[ ]+file format .*
Disassembly of section .text:
0+000 <target>:
#...
[ ]+40:[ ]+%(+(rv32_auipc :rd 0 :imm 0))%[ ]+auipc[ ]+zero,0x0
%{
/* Change the expression printer to accept RV32_Insn. */
fun pokefmt_expr_printer = (any rv32insn) void:
{
printf ("%u32x", +(rv32insn as RV32_Insn));
}
}%[ ]+44:[ ]+%(rv32_lw :rd 0 :rs1 0 :imm 0)%[ ]+lw[ ]+zero,0\(zero\) # 0 .*
will be transformed to:
#as: -march=rv32i #objdump: -dr .*:[ ]+file format .* Disassembly of section .text: 0+000 <target>: #... [ ]+40:[ ]+00000017[ ]+auipc[ ]+zero,0x0 [ ]+44:[ ]+00002003[ ]+lw[ ]+zero,0\(zero\) # 0 .*