Fix pointer authentication modifier source register (#61)

Pointer authentication instructions allow the stack pointer as source for the
modifier, but simulation was using the zero register instead. Fix this and
add a regression test.
diff --git a/src/aarch64/simulator-aarch64.cc b/src/aarch64/simulator-aarch64.cc
index 1830eb4..838c579 100644
--- a/src/aarch64/simulator-aarch64.cc
+++ b/src/aarch64/simulator-aarch64.cc
@@ -5239,18 +5239,18 @@
   unsigned src = instr->GetRn();
 
   switch (instr->Mask(DataProcessing1SourceMask)) {
-#define DEFINE_PAUTH_FUNCS(SUFFIX, KEY, D)          \
-  case PAC##SUFFIX: {                               \
-    uint64_t mod = ReadXRegister(src);              \
-    uint64_t ptr = ReadXRegister(dst);              \
-    WriteXRegister(dst, AddPAC(ptr, mod, KEY, D));  \
-    break;                                          \
-  }                                                 \
-  case AUT##SUFFIX: {                               \
-    uint64_t mod = ReadXRegister(src);              \
-    uint64_t ptr = ReadXRegister(dst);              \
-    WriteXRegister(dst, AuthPAC(ptr, mod, KEY, D)); \
-    break;                                          \
+#define DEFINE_PAUTH_FUNCS(SUFFIX, KEY, D)                  \
+  case PAC##SUFFIX: {                                       \
+    uint64_t mod = ReadXRegister(src, Reg31IsStackPointer); \
+    uint64_t ptr = ReadXRegister(dst);                      \
+    WriteXRegister(dst, AddPAC(ptr, mod, KEY, D));          \
+    break;                                                  \
+  }                                                         \
+  case AUT##SUFFIX: {                                       \
+    uint64_t mod = ReadXRegister(src, Reg31IsStackPointer); \
+    uint64_t ptr = ReadXRegister(dst);                      \
+    WriteXRegister(dst, AuthPAC(ptr, mod, KEY, D));         \
+    break;                                                  \
   }
 
     PAUTH_MODES_REGISTER_CONTEXT(DEFINE_PAUTH_FUNCS)
diff --git a/test/aarch64/test-assembler-aarch64.cc b/test/aarch64/test-assembler-aarch64.cc
index a1543a7..ac701c3 100644
--- a/test/aarch64/test-assembler-aarch64.cc
+++ b/test/aarch64/test-assembler-aarch64.cc
@@ -1916,6 +1916,34 @@
   }
 }
 
+TEST(pac_sp_modifier) {
+  SETUP_WITH_FEATURES(CPUFeatures::kPAuth);
+
+  START();
+
+  __ Mov(x0, 0x0000000012345678);
+  __ Mov(x1, x0);
+  __ Mov(x10, sp);
+
+  // Generate PACs using sp and register containing a copy of sp.
+  __ Pacia(x0, x10);
+  __ Pacia(x1, sp);
+
+  // Authenticate the pointers, exchanging (equal) modifiers.
+  __ Mov(x2, x0);
+  __ Mov(x3, x1);
+  __ Autia(x2, sp);
+  __ Autia(x3, x10);
+
+  END();
+
+  if (CAN_RUN()) {
+    RUN();
+
+    ASSERT_EQUAL_64(x0, x1);
+    ASSERT_EQUAL_64(x2, x3);
+  }
+}
 
 TEST(label) {
   SETUP();