Merge "Implement JEBS opcode using opcode 20 and R=1" into main am: f3a9084122

Original change: https://android-review.googlesource.com/c/platform/packages/modules/NetworkStack/+/2896804

Change-Id: I873ca2ee4238a49ceb35097e8e7c668274096dcc
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/src/android/net/apf/ApfGenerator.java b/src/android/net/apf/ApfGenerator.java
index c6ff441..1c08228 100644
--- a/src/android/net/apf/ApfGenerator.java
+++ b/src/android/net/apf/ApfGenerator.java
@@ -902,8 +902,9 @@
     }
 
     /**
-     * Add an instruction to the end of the program to jump to {@code target} if the bytes of the
+     * Add an instruction to the end of the program to jump to {@code tgt} if the bytes of the
      * packet at an offset specified by {@code register} don't match {@code bytes}
+     * R=0 means check for not equal
      */
     public ApfGenerator addJumpIfBytesAtR0NotEqual(byte[] bytes, String tgt) {
         return append(new Instruction(Opcodes.JNEBS).addUnsigned(
@@ -911,6 +912,18 @@
     }
 
     /**
+     * Add an instruction to the end of the program to jump to {@code tgt} if the bytes of the
+     * packet at an offset specified by {@code register} match {@code bytes}
+     * R=1 means check for equal.
+     */
+    public ApfGenerator addJumpIfBytesAtR0Equal(byte[] bytes, String tgt)
+            throws IllegalInstructionException {
+        requireApfVersion(MIN_APF_VERSION_IN_DEV);
+        return append(new Instruction(Opcodes.JNEBS, R1).addUnsigned(
+                bytes.length).setTargetLabel(tgt).setBytesImm(bytes));
+    }
+
+    /**
      * Add an instruction to the end of the program to load memory slot {@code slot} into
      * {@code register}.
      */
diff --git a/tests/unit/src/android/net/apf/ApfV5Test.kt b/tests/unit/src/android/net/apf/ApfV5Test.kt
index 1977a6c..dc8b7b6 100644
--- a/tests/unit/src/android/net/apf/ApfV5Test.kt
+++ b/tests/unit/src/android/net/apf/ApfV5Test.kt
@@ -59,6 +59,8 @@
         assertFailsWith<IllegalInstructionException> { gen.addDataCopyFromR0LenR1() }
         assertFailsWith<IllegalInstructionException> { gen.addPacketCopyFromR0(10) }
         assertFailsWith<IllegalInstructionException> { gen.addDataCopyFromR0(10) }
+        assertFailsWith<IllegalInstructionException> {
+            gen.addJumpIfBytesAtR0Equal(byteArrayOf('a'.code.toByte()), ApfGenerator.DROP_LABEL) }
     }
 
     @Test
@@ -245,6 +247,13 @@
 //        assertContentEquals(arrayOf(
 //                "       0: dcopy [r1+0], 5",
 //                "       4: pcopy [r0+1000], 255"), ApfJniUtils.disassembleApf(program))
+
+        gen = ApfGenerator(ApfGenerator.MIN_APF_VERSION_IN_DEV)
+        gen.addJumpIfBytesAtR0Equal(byteArrayOf('a'.code.toByte()), ApfGenerator.DROP_LABEL)
+        program = gen.generate()
+        assertContentEquals(
+                byteArrayOf(encodeInstruction(opcode = 20, immLength = 1, register = 1),
+                        1, 1, 'a'.code.toByte()), program)
     }
 
     private fun encodeInstruction(opcode: Int, immLength: Int, register: Int): Byte {