Implement cmp (immediate) for aarch64 assembler

PiperOrigin-RevId: 424125523
diff --git a/src/jit/aarch64-assembler.cc b/src/jit/aarch64-assembler.cc
index d42be55..ef3b3ae 100644
--- a/src/jit/aarch64-assembler.cc
+++ b/src/jit/aarch64-assembler.cc
@@ -215,6 +215,14 @@
   return branch_to_label(0x14000000, BranchType::kUnconditional, l);
 }
 
+Assembler& Assembler::cmp(XRegister xn, uint16_t imm12) {
+  if (imm12 > kUint12Max) {
+    error_ = Error::kInvalidOperand;
+    return *this;
+  }
+  return emit32(0xF100001F | imm12 << 10 | rn(xn));
+}
+
 Assembler& Assembler::ldp(XRegister xt1, XRegister xt2, MemOperand xn) {
   if (!imm7_offset_valid(xn.offset, xt1)) {
     error_ = Error::kInvalidOperand;
diff --git a/src/xnnpack/aarch64-assembler.h b/src/xnnpack/aarch64-assembler.h
index 58cf396..63f6821 100644
--- a/src/xnnpack/aarch64-assembler.h
+++ b/src/xnnpack/aarch64-assembler.h
@@ -322,6 +322,7 @@
   Assembler& b_hs(Label& l) { return b(kHS, l); }
   Assembler& b_lo(Label& l) { return b(kLO, l); }
   Assembler& b_ne(Label& l) { return b(kNE, l); }
+  Assembler& cmp(XRegister xn, uint16_t imm12);
   Assembler& ldp(XRegister xt1, XRegister xt2, MemOperand xn);
   Assembler& ldp(XRegister xt1, XRegister xt2, MemOperand xn, int32_t imm);
   Assembler& ldr(XRegister xt, MemOperand xn);
diff --git a/test/aarch64-assembler.cc b/test/aarch64-assembler.cc
index ecbfbda..fdc6798 100644
--- a/test/aarch64-assembler.cc
+++ b/test/aarch64-assembler.cc
@@ -29,6 +29,9 @@
   CHECK_ENCODING(0x913FFC41, a.add(x1, x2, 4095));
   EXPECT_ERROR(Error::kInvalidOperand, a.add(x1, x2, 4096));
 
+  CHECK_ENCODING(0xF100081F, a.cmp(x0, 2));
+  EXPECT_ERROR(Error::kInvalidOperand, a.cmp(x0, 4096));
+
   CHECK_ENCODING(0xA9403FEE, a.ldp(x14, x15, mem[sp]));
   CHECK_ENCODING(0xA8C13FEE, a.ldp(x14, x15, mem[sp], 16));
   CHECK_ENCODING(0xA9413FEE, a.ldp(x14, x15, mem[sp, 16]));