summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Żenczykowski <maze@google.com>2024-03-19 00:07:48 -0700
committerMaciej Żenczykowski <maze@google.com>2024-03-19 00:17:21 -0700
commit7fd6014f4ece11c043322600e5e8cb0e02d09c81 (patch)
tree72ba0638722e71dd522cca48981a236a6f1d4589
parent9026ee0f35310db82d1478a10af2e811525e317d (diff)
downloadapf-7fd6014f4ece11c043322600e5e8cb0e02d09c81.tar.gz
v5: implement 'jbseq' (ie. 'jbsne' with R=1)
After: text data bss dec hex filename 3888 0 0 3888 f30 apf_interpreter.arm.o text data bss dec hex filename 4901 0 0 4901 1325 apf_interpreter.x86.o Test: TreeHugger Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: I3ec724bc090af4b3fcb0a37692365dc4750c87b0
-rw-r--r--v5/apf.h1
-rw-r--r--v5/apf_interpreter.c6
-rw-r--r--v5/apf_interpreter_source.c5
3 files changed, 8 insertions, 4 deletions
diff --git a/v5/apf.h b/v5/apf.h
index e2ab495..69fd941 100644
--- a/v5/apf.h
+++ b/v5/apf.h
@@ -185,6 +185,7 @@ typedef union {
#define JLT_OPCODE 18 // Compare less than and branch, e.g. "jlt R0,5,label"
#define JSET_OPCODE 19 // Compare any bits set and branch, e.g. "jset R0,5,label"
#define JBSMATCH_OPCODE 20 // Compare byte sequence [R=0 not] equal, e.g. "jbsne R0,2,label,0x1122"
+ // NOTE: Only APFv6+ implements R=1 'jbseq' version
#define EXT_OPCODE 21 // Immediate value is one of *_EXT_OPCODE
#define LDDW_OPCODE 22 // Load 4 bytes from data address (register + signed imm): "lddw R0, [5+R1]"
#define STDW_OPCODE 23 // Store 4 bytes to data address (register + signed imm): "stdw R0, [5+R1]"
diff --git a/v5/apf_interpreter.c b/v5/apf_interpreter.c
index 00576f8..dd3850a 100644
--- a/v5/apf_interpreter.c
+++ b/v5/apf_interpreter.c
@@ -257,6 +257,7 @@ typedef union {
#define JLT_OPCODE 18 /* Compare less than and branch, e.g. "jlt R0,5,label" */
#define JSET_OPCODE 19 /* Compare any bits set and branch, e.g. "jset R0,5,label" */
#define JBSMATCH_OPCODE 20 /* Compare byte sequence [R=0 not] equal, e.g. "jbsne R0,2,label,0x1122" */
+ /* NOTE: Only APFv6+ implements R=1 'jbseq' version */
#define EXT_OPCODE 21 /* Immediate value is one of *_EXT_OPCODE */
#define LDDW_OPCODE 22 /* Load 4 bytes from data address (register + signed imm): "lddw R0, [5+R1]" */
#define STDW_OPCODE 23 /* Store 4 bytes to data address (register + signed imm): "stdw R0, [5+R1]" */
@@ -800,16 +801,17 @@ static int do_apf_run(apf_context* ctx) {
/* imm is jump target offset. */
/* REG is offset of packet bytes to compare. */
if (cmp_imm > 0xFFFF) return PASS_PACKET;
+ Boolean do_jump = !reg_num;
/* 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;
+ do_jump ^= !memcmp(ctx->program + ctx->pc, ctx->packet + REG, cmp_imm);
/* skip past comparison bytes */
ctx->pc += cmp_imm;
+ if (do_jump) ctx->pc += imm;
break;
}
/* There is a difference in APFv4 and APFv6 arithmetic behaviour! */
diff --git a/v5/apf_interpreter_source.c b/v5/apf_interpreter_source.c
index 5246451..25df6fa 100644
--- a/v5/apf_interpreter_source.c
+++ b/v5/apf_interpreter_source.c
@@ -267,16 +267,17 @@ static int do_apf_run(apf_context* ctx) {
// imm is jump target offset.
// REG is offset of packet bytes to compare.
if (cmp_imm > 0xFFFF) return PASS_PACKET;
+ bool do_jump = !reg_num;
// 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;
+ do_jump ^= !memcmp(ctx->program + ctx->pc, ctx->packet + REG, cmp_imm);
// skip past comparison bytes
ctx->pc += cmp_imm;
+ if (do_jump) ctx->pc += imm;
break;
}
// There is a difference in APFv4 and APFv6 arithmetic behaviour!