diff options
author | Maciej Żenczykowski <maze@google.com> | 2024-03-18 23:31:09 -0700 |
---|---|---|
committer | Maciej Żenczykowski <maze@google.com> | 2024-03-19 06:59:48 +0000 |
commit | 8fed45be8461369c7aafa777521f62700cb23593 (patch) | |
tree | 2ea1951025009ad3fd4993cbf9ecf2d75c28bc33 | |
parent | 3f3ab633aa85d7775507681c50ed3415e3bc8722 (diff) | |
download | apf-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.c | 47 | ||||
-rw-r--r-- | v5/apf_interpreter_source.c | 47 |
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) |