summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Żenczykowski <maze@google.com>2024-03-18 23:31:09 -0700
committerMaciej Żenczykowski <maze@google.com>2024-03-19 06:59:48 +0000
commit8fed45be8461369c7aafa777521f62700cb23593 (patch)
tree2ea1951025009ad3fd4993cbf9ecf2d75c28bc33
parent3f3ab633aa85d7775507681c50ed3415e3bc8722 (diff)
downloadapf-8fed45be8461369c7aafa777521f62700cb23593.tar.gz
v5: simplify: move JBSMATCH_OPCODE block outside nested switch
Before: text data bss dec hex filename 3884 0 0 3884 f2c apf_interpreter.arm.o text data bss dec hex filename 4822 0 0 4822 12d6 apf_interpreter.x86.o After: text data bss dec hex filename 3912 0 0 3912 f48 apf_interpreter.arm.o text data bss dec hex filename 4829 0 0 4829 12dd apf_interpreter.x86.o Test: TreeHugger Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: Ib1901d09182297e6feeadb83f01dbe0be17b636d
-rw-r--r--v5/apf_interpreter.c47
-rw-r--r--v5/apf_interpreter_source.c47
2 files changed, 54 insertions, 40 deletions
diff --git a/v5/apf_interpreter.c b/v5/apf_interpreter.c
index 1b03c50..f3b6726 100644
--- a/v5/apf_interpreter.c
+++ b/v5/apf_interpreter.c
@@ -769,8 +769,7 @@ static int do_apf_run(apf_context* ctx) {
case JNE_OPCODE:
case JGT_OPCODE:
case JLT_OPCODE:
- case JSET_OPCODE:
- case JBSMATCH_OPCODE: {
+ case JSET_OPCODE: {
/* Load second immediate field. */
u32 cmp_imm = 0;
if (reg_num == 1) {
@@ -785,27 +784,35 @@ static int do_apf_run(apf_context* ctx) {
case JGT_OPCODE: if (ctx->R[0] > cmp_imm) ctx->pc += imm; break;
case JLT_OPCODE: if (ctx->R[0] < cmp_imm) ctx->pc += imm; break;
case JSET_OPCODE: if (ctx->R[0] & cmp_imm) ctx->pc += imm; break;
- case JBSMATCH_OPCODE: {
- /* cmp_imm is size in bytes of data to compare. */
- /* pc is offset of program bytes to compare. */
- /* imm is jump target offset. */
- /* REG is offset of packet bytes to compare. */
- if (len_field > 2) return PASS_PACKET; /* guarantees cmp_imm <= 0xFFFF */
- /* pc < program_len < ram_len < 2GiB, thus pc + cmp_imm cannot wrap */
- if (!IN_RAM_BOUNDS(ctx->pc + cmp_imm - 1)) return PASS_PACKET;
- ASSERT_IN_PACKET_BOUNDS(REG);
- const u32 last_packet_offs = REG + cmp_imm - 1;
- ASSERT_RETURN(last_packet_offs >= REG);
- ASSERT_IN_PACKET_BOUNDS(last_packet_offs);
- if (memcmp(ctx->program + ctx->pc, ctx->packet + REG, cmp_imm))
- ctx->pc += imm;
- /* skip past comparison bytes */
- ctx->pc += cmp_imm;
- break;
- }
}
break;
}
+ case JBSMATCH_OPCODE: {
+ /* Load second immediate field. */
+ u32 cmp_imm = 0;
+ if (reg_num == 1) {
+ cmp_imm = ctx->R[1];
+ } else if (len_field != 0) {
+ u32 cmp_imm_len = 1 << (len_field - 1);
+ cmp_imm = decode_imm(ctx, cmp_imm_len); /* 2nd imm, at worst 8 bytes past prog_len */
+ }
+ /* cmp_imm is size in bytes of data to compare. */
+ /* pc is offset of program bytes to compare. */
+ /* imm is jump target offset. */
+ /* REG is offset of packet bytes to compare. */
+ if (len_field > 2) return PASS_PACKET; /* guarantees cmp_imm <= 0xFFFF */
+ /* pc < program_len < ram_len < 2GiB, thus pc + cmp_imm cannot wrap */
+ if (!IN_RAM_BOUNDS(ctx->pc + cmp_imm - 1)) return PASS_PACKET;
+ ASSERT_IN_PACKET_BOUNDS(REG);
+ const u32 last_packet_offs = REG + cmp_imm - 1;
+ ASSERT_RETURN(last_packet_offs >= REG);
+ ASSERT_IN_PACKET_BOUNDS(last_packet_offs);
+ if (memcmp(ctx->program + ctx->pc, ctx->packet + REG, cmp_imm))
+ ctx->pc += imm;
+ /* skip past comparison bytes */
+ ctx->pc += cmp_imm;
+ break;
+ }
/* There is a difference in APFv4 and APFv6 arithmetic behaviour! */
/* APFv4: R[0] op= Rbit ? R[1] : imm; (and it thus doesn't make sense to have R=1 && len_field>0) */
/* APFv6+: REG op= len_field ? imm : OTHER_REG; (note: this is *DIFFERENT* with R=1 len_field==0) */
diff --git a/v5/apf_interpreter_source.c b/v5/apf_interpreter_source.c
index c0552e7..5b8b4cc 100644
--- a/v5/apf_interpreter_source.c
+++ b/v5/apf_interpreter_source.c
@@ -236,8 +236,7 @@ static int do_apf_run(apf_context* ctx) {
case JNE_OPCODE:
case JGT_OPCODE:
case JLT_OPCODE:
- case JSET_OPCODE:
- case JBSMATCH_OPCODE: {
+ case JSET_OPCODE: {
// Load second immediate field.
u32 cmp_imm = 0;
if (reg_num == 1) {
@@ -252,27 +251,35 @@ static int do_apf_run(apf_context* ctx) {
case JGT_OPCODE: if (ctx->R[0] > cmp_imm) ctx->pc += imm; break;
case JLT_OPCODE: if (ctx->R[0] < cmp_imm) ctx->pc += imm; break;
case JSET_OPCODE: if (ctx->R[0] & cmp_imm) ctx->pc += imm; break;
- case JBSMATCH_OPCODE: {
- // cmp_imm is size in bytes of data to compare.
- // pc is offset of program bytes to compare.
- // imm is jump target offset.
- // REG is offset of packet bytes to compare.
- if (len_field > 2) return PASS_PACKET; // guarantees cmp_imm <= 0xFFFF
- // pc < program_len < ram_len < 2GiB, thus pc + cmp_imm cannot wrap
- if (!IN_RAM_BOUNDS(ctx->pc + cmp_imm - 1)) return PASS_PACKET;
- ASSERT_IN_PACKET_BOUNDS(REG);
- const u32 last_packet_offs = REG + cmp_imm - 1;
- ASSERT_RETURN(last_packet_offs >= REG);
- ASSERT_IN_PACKET_BOUNDS(last_packet_offs);
- if (memcmp(ctx->program + ctx->pc, ctx->packet + REG, cmp_imm))
- ctx->pc += imm;
- // skip past comparison bytes
- ctx->pc += cmp_imm;
- break;
- }
}
break;
}
+ case JBSMATCH_OPCODE: {
+ // Load second immediate field.
+ u32 cmp_imm = 0;
+ if (reg_num == 1) {
+ cmp_imm = ctx->R[1];
+ } else if (len_field != 0) {
+ u32 cmp_imm_len = 1 << (len_field - 1);
+ cmp_imm = decode_imm(ctx, cmp_imm_len); // 2nd imm, at worst 8 bytes past prog_len
+ }
+ // cmp_imm is size in bytes of data to compare.
+ // pc is offset of program bytes to compare.
+ // imm is jump target offset.
+ // REG is offset of packet bytes to compare.
+ if (len_field > 2) return PASS_PACKET; // guarantees cmp_imm <= 0xFFFF
+ // pc < program_len < ram_len < 2GiB, thus pc + cmp_imm cannot wrap
+ if (!IN_RAM_BOUNDS(ctx->pc + cmp_imm - 1)) return PASS_PACKET;
+ ASSERT_IN_PACKET_BOUNDS(REG);
+ const u32 last_packet_offs = REG + cmp_imm - 1;
+ ASSERT_RETURN(last_packet_offs >= REG);
+ ASSERT_IN_PACKET_BOUNDS(last_packet_offs);
+ if (memcmp(ctx->program + ctx->pc, ctx->packet + REG, cmp_imm))
+ ctx->pc += imm;
+ // skip past comparison bytes
+ ctx->pc += cmp_imm;
+ break;
+ }
// There is a difference in APFv4 and APFv6 arithmetic behaviour!
// APFv4: R[0] op= Rbit ? R[1] : imm; (and it thus doesn't make sense to have R=1 && len_field>0)
// APFv6+: REG op= len_field ? imm : OTHER_REG; (note: this is *DIFFERENT* with R=1 len_field==0)