[debugger] Add enums for register aliases.

Support AVX-512 in the specification by converting to 32 "ZMM"
registers. The existing XMM and YMM registers are left as aliases for
bit ranges.

Change-Id: I0e14f6927b77cccbadee17b6e263473dc923f7c3
diff --git a/src/developer/debug/ipc/records_unittest.cc b/src/developer/debug/ipc/records_unittest.cc
index 3e86d9b..1756870 100644
--- a/src/developer/debug/ipc/records_unittest.cc
+++ b/src/developer/debug/ipc/records_unittest.cc
@@ -51,10 +51,13 @@
   EXPECT_EQ(IDToCat(RegisterID::kARMv8_x27), CategoryType::kGeneral);
   EXPECT_EQ(IDToCat(RegisterID::kARMv8_x28), CategoryType::kGeneral);
   EXPECT_EQ(IDToCat(RegisterID::kARMv8_x29), CategoryType::kGeneral);
+  EXPECT_EQ(IDToCat(RegisterID::kARMv8_x30), CategoryType::kGeneral);  // alias for LR
   EXPECT_EQ(IDToCat(RegisterID::kARMv8_lr), CategoryType::kGeneral);
   EXPECT_EQ(IDToCat(RegisterID::kARMv8_sp), CategoryType::kGeneral);
   EXPECT_EQ(IDToCat(RegisterID::kARMv8_pc), CategoryType::kGeneral);
   EXPECT_EQ(IDToCat(RegisterID::kARMv8_cpsr), CategoryType::kGeneral);
+  EXPECT_EQ(IDToCat(RegisterID::kARMv8_w0), CategoryType::kGeneral);
+  EXPECT_EQ(IDToCat(RegisterID::kARMv8_w29), CategoryType::kGeneral);
 
   // Vector.
   EXPECT_EQ(IDToCat(RegisterID::kARMv8_fpcr), CategoryType::kVector);
@@ -134,6 +137,10 @@
 
   // General.
   EXPECT_EQ(IDToCat(RegisterID::kX64_rax), CategoryType::kGeneral);
+  EXPECT_EQ(IDToCat(RegisterID::kX64_ah), CategoryType::kGeneral);
+  EXPECT_EQ(IDToCat(RegisterID::kX64_al), CategoryType::kGeneral);
+  EXPECT_EQ(IDToCat(RegisterID::kX64_eax), CategoryType::kGeneral);
+  EXPECT_EQ(IDToCat(RegisterID::kX64_ax), CategoryType::kGeneral);
   EXPECT_EQ(IDToCat(RegisterID::kX64_rbx), CategoryType::kGeneral);
   EXPECT_EQ(IDToCat(RegisterID::kX64_rcx), CategoryType::kGeneral);
   EXPECT_EQ(IDToCat(RegisterID::kX64_rdx), CategoryType::kGeneral);
@@ -170,38 +177,14 @@
 
   // Vector.
   EXPECT_EQ(IDToCat(RegisterID::kX64_mxcsr), CategoryType::kVector);
+  EXPECT_EQ(IDToCat(RegisterID::kX64_mm0), CategoryType::kVector);
+  EXPECT_EQ(IDToCat(RegisterID::kX64_mm7), CategoryType::kVector);
   EXPECT_EQ(IDToCat(RegisterID::kX64_xmm0), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm1), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm2), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm3), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm4), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm5), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm6), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm7), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm8), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm9), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm10), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm11), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm12), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm13), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm14), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm15), CategoryType::kVector);
+  EXPECT_EQ(IDToCat(RegisterID::kX64_xmm31), CategoryType::kVector);
   EXPECT_EQ(IDToCat(RegisterID::kX64_ymm0), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm1), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm2), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm3), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm4), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm5), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm6), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm7), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm8), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm9), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm10), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm11), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm12), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm13), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm14), CategoryType::kVector);
-  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm15), CategoryType::kVector);
+  EXPECT_EQ(IDToCat(RegisterID::kX64_ymm31), CategoryType::kVector);
+  EXPECT_EQ(IDToCat(RegisterID::kX64_zmm0), CategoryType::kVector);
+  EXPECT_EQ(IDToCat(RegisterID::kX64_zmm31), CategoryType::kVector);
 
   // Debug.
   EXPECT_EQ(IDToCat(RegisterID::kX64_dr0), CategoryType::kDebug);
@@ -283,38 +266,38 @@
   EXPECT_STREQ("v31", RegisterIDToString(RegisterID::kARMv8_v31));
   EXPECT_STREQ("id_aa64dfr0_el1", RegisterIDToString(RegisterID::kARMv8_id_aa64dfr0_el1));
   EXPECT_STREQ("mdscr_el1", RegisterIDToString(RegisterID::kARMv8_mdscr_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr0_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr0_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr1_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr1_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr2_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr2_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr3_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr3_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr4_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr4_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr5_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr5_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr6_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr6_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr7_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr7_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr8_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr8_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr9_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr9_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr10_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr10_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr11_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr11_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr12_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr12_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr13_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr13_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr14_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr14_el1));
-  EXPECT_STREQ("kARMv8_dbgbcr15_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr15_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr0_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr0_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr1_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr1_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr2_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr2_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr3_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr3_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr4_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr4_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr5_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr5_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr6_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr6_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr7_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr7_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr8_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr8_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr9_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr9_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr10_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr10_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr11_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr11_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr12_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr12_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr13_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr13_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr14_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr14_el1));
-  EXPECT_STREQ("kARMv8_dbgbvr15_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr15_el1));
+  EXPECT_STREQ("dbgbcr0_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr0_el1));
+  EXPECT_STREQ("dbgbcr1_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr1_el1));
+  EXPECT_STREQ("dbgbcr2_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr2_el1));
+  EXPECT_STREQ("dbgbcr3_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr3_el1));
+  EXPECT_STREQ("dbgbcr4_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr4_el1));
+  EXPECT_STREQ("dbgbcr5_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr5_el1));
+  EXPECT_STREQ("dbgbcr6_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr6_el1));
+  EXPECT_STREQ("dbgbcr7_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr7_el1));
+  EXPECT_STREQ("dbgbcr8_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr8_el1));
+  EXPECT_STREQ("dbgbcr9_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr9_el1));
+  EXPECT_STREQ("dbgbcr10_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr10_el1));
+  EXPECT_STREQ("dbgbcr11_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr11_el1));
+  EXPECT_STREQ("dbgbcr12_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr12_el1));
+  EXPECT_STREQ("dbgbcr13_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr13_el1));
+  EXPECT_STREQ("dbgbcr14_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr14_el1));
+  EXPECT_STREQ("dbgbcr15_el1", RegisterIDToString(RegisterID::kARMv8_dbgbcr15_el1));
+  EXPECT_STREQ("dbgbvr0_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr0_el1));
+  EXPECT_STREQ("dbgbvr1_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr1_el1));
+  EXPECT_STREQ("dbgbvr2_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr2_el1));
+  EXPECT_STREQ("dbgbvr3_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr3_el1));
+  EXPECT_STREQ("dbgbvr4_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr4_el1));
+  EXPECT_STREQ("dbgbvr5_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr5_el1));
+  EXPECT_STREQ("dbgbvr6_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr6_el1));
+  EXPECT_STREQ("dbgbvr7_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr7_el1));
+  EXPECT_STREQ("dbgbvr8_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr8_el1));
+  EXPECT_STREQ("dbgbvr9_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr9_el1));
+  EXPECT_STREQ("dbgbvr10_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr10_el1));
+  EXPECT_STREQ("dbgbvr11_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr11_el1));
+  EXPECT_STREQ("dbgbvr12_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr12_el1));
+  EXPECT_STREQ("dbgbvr13_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr13_el1));
+  EXPECT_STREQ("dbgbvr14_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr14_el1));
+  EXPECT_STREQ("dbgbvr15_el1", RegisterIDToString(RegisterID::kARMv8_dbgbvr15_el1));
   EXPECT_STREQ("rax", RegisterIDToString(RegisterID::kX64_rax));
   EXPECT_STREQ("rbx", RegisterIDToString(RegisterID::kX64_rbx));
   EXPECT_STREQ("rcx", RegisterIDToString(RegisterID::kX64_rcx));
@@ -348,38 +331,14 @@
   EXPECT_STREQ("st6", RegisterIDToString(RegisterID::kX64_st6));
   EXPECT_STREQ("st7", RegisterIDToString(RegisterID::kX64_st7));
   EXPECT_STREQ("mxcsr", RegisterIDToString(RegisterID::kX64_mxcsr));
+  EXPECT_STREQ("mm0", RegisterIDToString(RegisterID::kX64_mm0));
+  EXPECT_STREQ("mm7", RegisterIDToString(RegisterID::kX64_mm7));
   EXPECT_STREQ("xmm0", RegisterIDToString(RegisterID::kX64_xmm0));
-  EXPECT_STREQ("xmm1", RegisterIDToString(RegisterID::kX64_xmm1));
-  EXPECT_STREQ("xmm2", RegisterIDToString(RegisterID::kX64_xmm2));
-  EXPECT_STREQ("xmm3", RegisterIDToString(RegisterID::kX64_xmm3));
-  EXPECT_STREQ("xmm4", RegisterIDToString(RegisterID::kX64_xmm4));
-  EXPECT_STREQ("xmm5", RegisterIDToString(RegisterID::kX64_xmm5));
-  EXPECT_STREQ("xmm6", RegisterIDToString(RegisterID::kX64_xmm6));
-  EXPECT_STREQ("xmm7", RegisterIDToString(RegisterID::kX64_xmm7));
-  EXPECT_STREQ("xmm8", RegisterIDToString(RegisterID::kX64_xmm8));
-  EXPECT_STREQ("xmm9", RegisterIDToString(RegisterID::kX64_xmm9));
-  EXPECT_STREQ("xmm10", RegisterIDToString(RegisterID::kX64_xmm10));
-  EXPECT_STREQ("xmm11", RegisterIDToString(RegisterID::kX64_xmm11));
-  EXPECT_STREQ("xmm12", RegisterIDToString(RegisterID::kX64_xmm12));
-  EXPECT_STREQ("xmm13", RegisterIDToString(RegisterID::kX64_xmm13));
-  EXPECT_STREQ("xmm14", RegisterIDToString(RegisterID::kX64_xmm14));
-  EXPECT_STREQ("xmm15", RegisterIDToString(RegisterID::kX64_xmm15));
+  EXPECT_STREQ("xmm31", RegisterIDToString(RegisterID::kX64_xmm31));
   EXPECT_STREQ("ymm0", RegisterIDToString(RegisterID::kX64_ymm0));
-  EXPECT_STREQ("ymm1", RegisterIDToString(RegisterID::kX64_ymm1));
-  EXPECT_STREQ("ymm2", RegisterIDToString(RegisterID::kX64_ymm2));
-  EXPECT_STREQ("ymm3", RegisterIDToString(RegisterID::kX64_ymm3));
-  EXPECT_STREQ("ymm4", RegisterIDToString(RegisterID::kX64_ymm4));
-  EXPECT_STREQ("ymm5", RegisterIDToString(RegisterID::kX64_ymm5));
-  EXPECT_STREQ("ymm6", RegisterIDToString(RegisterID::kX64_ymm6));
-  EXPECT_STREQ("ymm7", RegisterIDToString(RegisterID::kX64_ymm7));
-  EXPECT_STREQ("ymm8", RegisterIDToString(RegisterID::kX64_ymm8));
-  EXPECT_STREQ("ymm9", RegisterIDToString(RegisterID::kX64_ymm9));
-  EXPECT_STREQ("ymm10", RegisterIDToString(RegisterID::kX64_ymm10));
-  EXPECT_STREQ("ymm11", RegisterIDToString(RegisterID::kX64_ymm11));
-  EXPECT_STREQ("ymm12", RegisterIDToString(RegisterID::kX64_ymm12));
-  EXPECT_STREQ("ymm13", RegisterIDToString(RegisterID::kX64_ymm13));
-  EXPECT_STREQ("ymm14", RegisterIDToString(RegisterID::kX64_ymm14));
-  EXPECT_STREQ("ymm15", RegisterIDToString(RegisterID::kX64_ymm15));
+  EXPECT_STREQ("ymm31", RegisterIDToString(RegisterID::kX64_ymm31));
+  EXPECT_STREQ("zmm0", RegisterIDToString(RegisterID::kX64_zmm0));
+  EXPECT_STREQ("zmm31", RegisterIDToString(RegisterID::kX64_zmm31));
   EXPECT_STREQ("dr0", RegisterIDToString(RegisterID::kX64_dr0));
   EXPECT_STREQ("dr1", RegisterIDToString(RegisterID::kX64_dr1));
   EXPECT_STREQ("dr2", RegisterIDToString(RegisterID::kX64_dr2));
diff --git a/src/developer/debug/ipc/register_desc.cc b/src/developer/debug/ipc/register_desc.cc
index b2664b7..832e838 100644
--- a/src/developer/debug/ipc/register_desc.cc
+++ b/src/developer/debug/ipc/register_desc.cc
@@ -13,250 +13,372 @@
 namespace debug_ipc {
 namespace {
 
-struct RegisterInfo {
-  RegisterID id;
-  std::string name;
-  Arch arch;
-};
+// clang-format off
 
+// Canonical registers, these all have a 1:1 mapping between "id" and "name".
 const RegisterInfo kRegisterInfo[] = {
     // ARMv8
-    // -------------------------------------------------------------------
+    // ---------------------------------------------------------------------------------------------
 
     // General purpose.
 
-    {.id = RegisterID::kARMv8_x0, .name = "x0", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x1, .name = "x1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x2, .name = "x2", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x3, .name = "x3", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x4, .name = "x4", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x5, .name = "x5", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x6, .name = "x6", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x7, .name = "x7", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x8, .name = "x8", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x9, .name = "x9", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x10, .name = "x10", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x11, .name = "x11", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x12, .name = "x12", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x13, .name = "x13", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x14, .name = "x14", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x15, .name = "x15", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x16, .name = "x16", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x17, .name = "x17", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x18, .name = "x18", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x19, .name = "x19", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x20, .name = "x20", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x21, .name = "x21", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x22, .name = "x22", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x23, .name = "x23", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x24, .name = "x24", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x25, .name = "x25", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x26, .name = "x26", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x27, .name = "x27", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x28, .name = "x28", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_x29, .name = "x29", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_lr, .name = "lr", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_sp, .name = "sp", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_pc, .name = "pc", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_cpsr, .name = "cpsr", .arch = Arch::kArm64},
+    {.id = RegisterID::kARMv8_x0,  .name = "x0",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x0,  .bits = 64},
+    {.id = RegisterID::kARMv8_x1,  .name = "x1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x1,  .bits = 64},
+    {.id = RegisterID::kARMv8_x2,  .name = "x2",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x2,  .bits = 64},
+    {.id = RegisterID::kARMv8_x3,  .name = "x3",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x3,  .bits = 64},
+    {.id = RegisterID::kARMv8_x4,  .name = "x4",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x4,  .bits = 64},
+    {.id = RegisterID::kARMv8_x5,  .name = "x5",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x5,  .bits = 64},
+    {.id = RegisterID::kARMv8_x6,  .name = "x6",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x6,  .bits = 64},
+    {.id = RegisterID::kARMv8_x7,  .name = "x7",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x7,  .bits = 64},
+    {.id = RegisterID::kARMv8_x8,  .name = "x8",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x8,  .bits = 64},
+    {.id = RegisterID::kARMv8_x9,  .name = "x9",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x9,  .bits = 64},
+    {.id = RegisterID::kARMv8_x10, .name = "x10", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x10, .bits = 64},
+    {.id = RegisterID::kARMv8_x11, .name = "x11", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x11, .bits = 64},
+    {.id = RegisterID::kARMv8_x12, .name = "x12", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x12, .bits = 64},
+    {.id = RegisterID::kARMv8_x13, .name = "x13", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x13, .bits = 64},
+    {.id = RegisterID::kARMv8_x14, .name = "x14", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x14, .bits = 64},
+    {.id = RegisterID::kARMv8_x15, .name = "x15", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x15, .bits = 64},
+    {.id = RegisterID::kARMv8_x16, .name = "x16", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x16, .bits = 64},
+    {.id = RegisterID::kARMv8_x17, .name = "x17", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x17, .bits = 64},
+    {.id = RegisterID::kARMv8_x18, .name = "x18", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x18, .bits = 64},
+    {.id = RegisterID::kARMv8_x19, .name = "x19", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x19, .bits = 64},
+    {.id = RegisterID::kARMv8_x20, .name = "x20", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x20, .bits = 64},
+    {.id = RegisterID::kARMv8_x21, .name = "x21", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x21, .bits = 64},
+    {.id = RegisterID::kARMv8_x22, .name = "x22", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x22, .bits = 64},
+    {.id = RegisterID::kARMv8_x23, .name = "x23", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x23, .bits = 64},
+    {.id = RegisterID::kARMv8_x24, .name = "x24", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x24, .bits = 64},
+    {.id = RegisterID::kARMv8_x25, .name = "x25", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x25, .bits = 64},
+    {.id = RegisterID::kARMv8_x26, .name = "x26", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x26, .bits = 64},
+    {.id = RegisterID::kARMv8_x27, .name = "x27", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x27, .bits = 64},
+    {.id = RegisterID::kARMv8_x28, .name = "x28", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x28, .bits = 64},
+    {.id = RegisterID::kARMv8_x29, .name = "x29", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x29, .bits = 64},
+    {.id = RegisterID::kARMv8_lr,  .name = "lr",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_lr,  .bits = 64},
+    {.id = RegisterID::kARMv8_sp,  .name = "sp",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_sp,  .bits = 64},
+    {.id = RegisterID::kARMv8_pc,  .name = "pc",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_pc,  .bits = 64},
+
+    {.id = RegisterID::kARMv8_cpsr, .name = "cpsr", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_cpsr, .bits = 64},
 
     // FP (none defined for ARM64).
 
     // Vector.
 
-    {.id = RegisterID::kARMv8_fpcr, .name = "fpcr", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_fpsr, .name = "fpsr", .arch = Arch::kArm64},
+    {.id = RegisterID::kARMv8_fpcr, .name = "fpcr", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_fpcr, .bits = 32},
+    {.id = RegisterID::kARMv8_fpsr, .name = "fpsr", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_fpsr, .bits = 32},
 
-    {.id = RegisterID::kARMv8_v0, .name = "v0", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v1, .name = "v1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v2, .name = "v2", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v3, .name = "v3", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v4, .name = "v4", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v5, .name = "v5", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v6, .name = "v6", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v7, .name = "v7", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v8, .name = "v8", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v9, .name = "v9", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v10, .name = "v10", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v11, .name = "v11", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v12, .name = "v12", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v13, .name = "v13", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v14, .name = "v14", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v15, .name = "v15", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v16, .name = "v16", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v17, .name = "v17", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v18, .name = "v18", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v19, .name = "v19", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v20, .name = "v20", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v21, .name = "v21", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v22, .name = "v22", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v23, .name = "v23", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v24, .name = "v24", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v25, .name = "v25", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v26, .name = "v26", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v27, .name = "v27", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v28, .name = "v28", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v29, .name = "v29", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v30, .name = "v30", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_v31, .name = "v31", .arch = Arch::kArm64},
+    {.id = RegisterID::kARMv8_v0,  .name = "v0",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v0,  .bits = 128},
+    {.id = RegisterID::kARMv8_v1,  .name = "v1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v1,  .bits = 128},
+    {.id = RegisterID::kARMv8_v2,  .name = "v2",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v2,  .bits = 128},
+    {.id = RegisterID::kARMv8_v3,  .name = "v3",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v3,  .bits = 128},
+    {.id = RegisterID::kARMv8_v4,  .name = "v4",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v4,  .bits = 128},
+    {.id = RegisterID::kARMv8_v5,  .name = "v5",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v5,  .bits = 128},
+    {.id = RegisterID::kARMv8_v6,  .name = "v6",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v6,  .bits = 128},
+    {.id = RegisterID::kARMv8_v7,  .name = "v7",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v7,  .bits = 128},
+    {.id = RegisterID::kARMv8_v8,  .name = "v8",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v8,  .bits = 128},
+    {.id = RegisterID::kARMv8_v9,  .name = "v9",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v9,  .bits = 128},
+    {.id = RegisterID::kARMv8_v10, .name = "v10", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v10, .bits = 128},
+    {.id = RegisterID::kARMv8_v11, .name = "v11", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v11, .bits = 128},
+    {.id = RegisterID::kARMv8_v12, .name = "v12", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v12, .bits = 128},
+    {.id = RegisterID::kARMv8_v13, .name = "v13", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v13, .bits = 128},
+    {.id = RegisterID::kARMv8_v14, .name = "v14", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v14, .bits = 128},
+    {.id = RegisterID::kARMv8_v15, .name = "v15", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v15, .bits = 128},
+    {.id = RegisterID::kARMv8_v16, .name = "v16", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v16, .bits = 128},
+    {.id = RegisterID::kARMv8_v17, .name = "v17", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v17, .bits = 128},
+    {.id = RegisterID::kARMv8_v18, .name = "v18", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v18, .bits = 128},
+    {.id = RegisterID::kARMv8_v19, .name = "v19", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v19, .bits = 128},
+    {.id = RegisterID::kARMv8_v20, .name = "v20", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v20, .bits = 128},
+    {.id = RegisterID::kARMv8_v21, .name = "v21", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v21, .bits = 128},
+    {.id = RegisterID::kARMv8_v22, .name = "v22", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v22, .bits = 128},
+    {.id = RegisterID::kARMv8_v23, .name = "v23", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v23, .bits = 128},
+    {.id = RegisterID::kARMv8_v24, .name = "v24", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v24, .bits = 128},
+    {.id = RegisterID::kARMv8_v25, .name = "v25", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v25, .bits = 128},
+    {.id = RegisterID::kARMv8_v26, .name = "v26", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v26, .bits = 128},
+    {.id = RegisterID::kARMv8_v27, .name = "v27", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v27, .bits = 128},
+    {.id = RegisterID::kARMv8_v28, .name = "v28", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v28, .bits = 128},
+    {.id = RegisterID::kARMv8_v29, .name = "v29", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v29, .bits = 128},
+    {.id = RegisterID::kARMv8_v30, .name = "v30", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v30, .bits = 128},
+    {.id = RegisterID::kARMv8_v31, .name = "v31", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_v31, .bits = 128},
 
     // Debug.
 
-    {.id = RegisterID::kARMv8_id_aa64dfr0_el1, .name = "id_aa64dfr0_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_mdscr_el1, .name = "mdscr_el1", .arch = Arch::kArm64},
+    {.id = RegisterID::kARMv8_id_aa64dfr0_el1, .name = "id_aa64dfr0_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_id_aa64dfr0_el1, .bits = 64},
+    {.id = RegisterID::kARMv8_mdscr_el1,       .name = "mdscr_el1",       .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_mdscr_el1,       .bits = 64},
 
-    {.id = RegisterID::kARMv8_dbgbcr0_el1, .name = "kARMv8_dbgbcr0_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr1_el1, .name = "kARMv8_dbgbcr1_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr2_el1, .name = "kARMv8_dbgbcr2_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr3_el1, .name = "kARMv8_dbgbcr3_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr4_el1, .name = "kARMv8_dbgbcr4_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr5_el1, .name = "kARMv8_dbgbcr5_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr6_el1, .name = "kARMv8_dbgbcr6_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr7_el1, .name = "kARMv8_dbgbcr7_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr8_el1, .name = "kARMv8_dbgbcr8_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr9_el1, .name = "kARMv8_dbgbcr9_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr10_el1, .name = "kARMv8_dbgbcr10_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr11_el1, .name = "kARMv8_dbgbcr11_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr12_el1, .name = "kARMv8_dbgbcr12_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr13_el1, .name = "kARMv8_dbgbcr13_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr14_el1, .name = "kARMv8_dbgbcr14_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbcr15_el1, .name = "kARMv8_dbgbcr15_el1", .arch = Arch::kArm64},
+    {.id = RegisterID::kARMv8_dbgbcr0_el1,  .name = "dbgbcr0_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr0_el1,  .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr1_el1,  .name = "dbgbcr1_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr1_el1,  .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr2_el1,  .name = "dbgbcr2_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr2_el1,  .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr3_el1,  .name = "dbgbcr3_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr3_el1,  .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr4_el1,  .name = "dbgbcr4_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr4_el1,  .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr5_el1,  .name = "dbgbcr5_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr5_el1,  .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr6_el1,  .name = "dbgbcr6_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr6_el1,  .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr7_el1,  .name = "dbgbcr7_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr7_el1,  .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr8_el1,  .name = "dbgbcr8_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr8_el1,  .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr9_el1,  .name = "dbgbcr9_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr9_el1,  .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr10_el1, .name = "dbgbcr10_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr10_el1, .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr11_el1, .name = "dbgbcr11_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr11_el1, .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr12_el1, .name = "dbgbcr12_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr12_el1, .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr13_el1, .name = "dbgbcr13_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr13_el1, .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr14_el1, .name = "dbgbcr14_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr14_el1, .bits = 32},
+    {.id = RegisterID::kARMv8_dbgbcr15_el1, .name = "dbgbcr15_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbcr15_el1, .bits = 32},
 
-    {.id = RegisterID::kARMv8_dbgbvr0_el1, .name = "kARMv8_dbgbvr0_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr1_el1, .name = "kARMv8_dbgbvr1_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr2_el1, .name = "kARMv8_dbgbvr2_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr3_el1, .name = "kARMv8_dbgbvr3_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr4_el1, .name = "kARMv8_dbgbvr4_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr5_el1, .name = "kARMv8_dbgbvr5_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr6_el1, .name = "kARMv8_dbgbvr6_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr7_el1, .name = "kARMv8_dbgbvr7_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr8_el1, .name = "kARMv8_dbgbvr8_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr9_el1, .name = "kARMv8_dbgbvr9_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr10_el1, .name = "kARMv8_dbgbvr10_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr11_el1, .name = "kARMv8_dbgbvr11_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr12_el1, .name = "kARMv8_dbgbvr12_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr13_el1, .name = "kARMv8_dbgbvr13_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr14_el1, .name = "kARMv8_dbgbvr14_el1", .arch = Arch::kArm64},
-    {.id = RegisterID::kARMv8_dbgbvr15_el1, .name = "kARMv8_dbgbvr15_el1", .arch = Arch::kArm64},
+    {.id = RegisterID::kARMv8_dbgbvr0_el1,  .name = "dbgbvr0_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr0_el1,  .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr1_el1,  .name = "dbgbvr1_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr1_el1,  .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr2_el1,  .name = "dbgbvr2_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr2_el1,  .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr3_el1,  .name = "dbgbvr3_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr3_el1,  .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr4_el1,  .name = "dbgbvr4_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr4_el1,  .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr5_el1,  .name = "dbgbvr5_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr5_el1,  .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr6_el1,  .name = "dbgbvr6_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr6_el1,  .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr7_el1,  .name = "dbgbvr7_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr7_el1,  .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr8_el1,  .name = "dbgbvr8_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr8_el1,  .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr9_el1,  .name = "dbgbvr9_el1",  .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr9_el1,  .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr10_el1, .name = "dbgbvr10_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr10_el1, .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr11_el1, .name = "dbgbvr11_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr11_el1, .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr12_el1, .name = "dbgbvr12_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr12_el1, .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr13_el1, .name = "dbgbvr13_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr13_el1, .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr14_el1, .name = "dbgbvr14_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr14_el1, .bits = 64},
+    {.id = RegisterID::kARMv8_dbgbvr15_el1, .name = "dbgbvr15_el1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_dbgbvr15_el1, .bits = 64},
+
+    // General-purpose aliases.
+
+    // Our canonical name for x30 is "LR".
+    {.id = RegisterID::kARMv8_x30, .name = "x30", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_lr, .bits = 64},
+
+    {.id = RegisterID::kARMv8_w0, .name = "w0", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x0, .bits = 32},
+    {.id = RegisterID::kARMv8_w1, .name = "w1", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x1, .bits = 32},
+    {.id = RegisterID::kARMv8_w2, .name = "w2", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x2, .bits = 32},
+    {.id = RegisterID::kARMv8_w3, .name = "w3", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x3, .bits = 32},
+    {.id = RegisterID::kARMv8_w4, .name = "w4", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x4, .bits = 32},
+    {.id = RegisterID::kARMv8_w5, .name = "w5", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x5, .bits = 32},
+    {.id = RegisterID::kARMv8_w6, .name = "w6", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x6, .bits = 32},
+    {.id = RegisterID::kARMv8_w7, .name = "w7", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x7, .bits = 32},
+    {.id = RegisterID::kARMv8_w8, .name = "w8", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x8, .bits = 32},
+    {.id = RegisterID::kARMv8_w9, .name = "w9", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x9, .bits = 32},
+    {.id = RegisterID::kARMv8_w10, .name = "w10", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x10, .bits = 32},
+    {.id = RegisterID::kARMv8_w11, .name = "w11", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x11, .bits = 32},
+    {.id = RegisterID::kARMv8_w12, .name = "w12", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x12, .bits = 32},
+    {.id = RegisterID::kARMv8_w13, .name = "w13", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x13, .bits = 32},
+    {.id = RegisterID::kARMv8_w14, .name = "w14", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x14, .bits = 32},
+    {.id = RegisterID::kARMv8_w15, .name = "w15", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x15, .bits = 32},
+    {.id = RegisterID::kARMv8_w16, .name = "w16", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x16, .bits = 32},
+    {.id = RegisterID::kARMv8_w17, .name = "w17", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x17, .bits = 32},
+    {.id = RegisterID::kARMv8_w18, .name = "w18", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x18, .bits = 32},
+    {.id = RegisterID::kARMv8_w19, .name = "w19", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x19, .bits = 32},
+    {.id = RegisterID::kARMv8_w20, .name = "w20", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x20, .bits = 32},
+    {.id = RegisterID::kARMv8_w21, .name = "w21", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x21, .bits = 32},
+    {.id = RegisterID::kARMv8_w22, .name = "w22", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x22, .bits = 32},
+    {.id = RegisterID::kARMv8_w23, .name = "w23", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x23, .bits = 32},
+    {.id = RegisterID::kARMv8_w24, .name = "w24", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x24, .bits = 32},
+    {.id = RegisterID::kARMv8_w25, .name = "w25", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x25, .bits = 32},
+    {.id = RegisterID::kARMv8_w26, .name = "w26", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x26, .bits = 32},
+    {.id = RegisterID::kARMv8_w27, .name = "w27", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x27, .bits = 32},
+    {.id = RegisterID::kARMv8_w28, .name = "w28", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x28, .bits = 32},
+    {.id = RegisterID::kARMv8_w29, .name = "w29", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x29, .bits = 32},
+    {.id = RegisterID::kARMv8_w30, .name = "w30", .arch = Arch::kArm64, .canonical_id = RegisterID::kARMv8_x30, .bits = 32},
 
     // x64
-    // ---------------------------------------------------------------------
+    // ---------------------------------------------------------------------------------------------
 
     // General purpose.
 
-    {.id = RegisterID::kX64_rax, .name = "rax", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_rbx, .name = "rbx", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_rcx, .name = "rcx", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_rdx, .name = "rdx", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_rsi, .name = "rsi", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_rdi, .name = "rdi", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_rbp, .name = "rbp", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_rsp, .name = "rsp", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_r8, .name = "r8", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_r9, .name = "r9", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_r10, .name = "r10", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_r11, .name = "r11", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_r12, .name = "r12", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_r13, .name = "r13", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_r14, .name = "r14", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_r15, .name = "r15", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_rip, .name = "rip", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_rflags, .name = "rflags", .arch = Arch::kX64},
+    {.id = RegisterID::kX64_rax, .name = "rax", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rax, .bits = 64},
+    {.id = RegisterID::kX64_rbx, .name = "rbx", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rbx, .bits = 64},
+    {.id = RegisterID::kX64_rcx, .name = "rcx", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rcx, .bits = 64},
+    {.id = RegisterID::kX64_rdx, .name = "rdx", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rdx, .bits = 64},
+    {.id = RegisterID::kX64_rsi, .name = "rsi", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rsi, .bits = 64},
+    {.id = RegisterID::kX64_rdi, .name = "rdi", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rdi, .bits = 64},
+    {.id = RegisterID::kX64_rbp, .name = "rbp", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rbp, .bits = 64},
+    {.id = RegisterID::kX64_rsp, .name = "rsp", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rsp, .bits = 64},
+    {.id = RegisterID::kX64_r8,  .name = "r8",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_r8,  .bits = 64},
+    {.id = RegisterID::kX64_r9,  .name = "r9",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_r9,  .bits = 64},
+    {.id = RegisterID::kX64_r10, .name = "r10", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_r10, .bits = 64},
+    {.id = RegisterID::kX64_r11, .name = "r11", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_r11, .bits = 64},
+    {.id = RegisterID::kX64_r12, .name = "r12", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_r12, .bits = 64},
+    {.id = RegisterID::kX64_r13, .name = "r13", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_r13, .bits = 64},
+    {.id = RegisterID::kX64_r14, .name = "r14", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_r14, .bits = 64},
+    {.id = RegisterID::kX64_r15, .name = "r15", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_r15, .bits = 64},
+    {.id = RegisterID::kX64_rip, .name = "rip", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rip, .bits = 64},
 
+    {.id = RegisterID::kX64_rflags, .name = "rflags", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rflags, .bits = 64},
+
+    // General-purpose aliases.
+
+    {.id = RegisterID::kX64_ah,  .name = "ah",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rax, .bits = 8, .shift = 8},
+    {.id = RegisterID::kX64_al,  .name = "al",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rax, .bits = 8},
+    {.id = RegisterID::kX64_ax,  .name = "ax",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rax, .bits = 16},
+    {.id = RegisterID::kX64_eax, .name = "eax", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rax, .bits = 32},
+
+    {.id = RegisterID::kX64_bh,  .name = "bh",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rbx, .bits = 8, .shift = 8},
+    {.id = RegisterID::kX64_bl,  .name = "bl",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rbx, .bits = 8},
+    {.id = RegisterID::kX64_bx,  .name = "bx",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rbx, .bits = 16},
+    {.id = RegisterID::kX64_ebx, .name = "ebx", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rbx, .bits = 32},
+
+    {.id = RegisterID::kX64_ch,  .name = "ch",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rcx, .bits = 8, .shift = 8},
+    {.id = RegisterID::kX64_cl,  .name = "cl",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rcx, .bits = 8},
+    {.id = RegisterID::kX64_cx,  .name = "cx",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rcx, .bits = 16},
+    {.id = RegisterID::kX64_ecx, .name = "ecx", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rcx, .bits = 32},
+
+    {.id = RegisterID::kX64_dh,  .name = "dh",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rdx, .bits = 8, .shift = 8},
+    {.id = RegisterID::kX64_dl,  .name = "dl",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rdx, .bits = 8},
+    {.id = RegisterID::kX64_dx,  .name = "dx",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rdx, .bits = 16},
+    {.id = RegisterID::kX64_edx, .name = "edx", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rdx, .bits = 32},
+
+    {.id = RegisterID::kX64_si,  .name = "si",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rsi, .bits = 16},
+    {.id = RegisterID::kX64_esi, .name = "esi", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rsi, .bits = 32},
+
+    {.id = RegisterID::kX64_di,  .name = "di",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rdi, .bits = 16},
+    {.id = RegisterID::kX64_edi, .name = "edi", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_rdi, .bits = 32},
+
+    // Note we don't have an entry for bp/ebp, sp/esp, and ip/eip because these are all pointers
+    // and the low bits are more likely to be user error (they wanted the whole thing) and we don't
+    // want to be misleading in those cases.
     // FP.
 
-    {.id = RegisterID::kX64_fcw, .name = "fcw", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_fsw, .name = "fsw", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ftw, .name = "ftw", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_fop, .name = "fop", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_fip, .name = "fip", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_fdp, .name = "fdp", .arch = Arch::kX64},
+    {.id = RegisterID::kX64_fcw, .name = "fcw", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_fcw, .bits = 16},
+    {.id = RegisterID::kX64_fsw, .name = "fsw", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_fsw, .bits = 16},
+    {.id = RegisterID::kX64_ftw, .name = "ftw", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_ftw, .bits = 16},
+    {.id = RegisterID::kX64_fop, .name = "fop", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_fop, .bits = 16},  // 11 valid bits
+    {.id = RegisterID::kX64_fip, .name = "fip", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_fip, .bits = 64},
+    {.id = RegisterID::kX64_fdp, .name = "fdp", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_fdp, .bits = 64},
 
-    {.id = RegisterID::kX64_st0, .name = "st0", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_st1, .name = "st1", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_st2, .name = "st2", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_st3, .name = "st3", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_st4, .name = "st4", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_st5, .name = "st5", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_st6, .name = "st6", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_st7, .name = "st7", .arch = Arch::kX64},
+    {.id = RegisterID::kX64_st0, .name = "st0", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st0, .bits = 80},
+    {.id = RegisterID::kX64_st1, .name = "st1", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st1, .bits = 80},
+    {.id = RegisterID::kX64_st2, .name = "st2", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st2, .bits = 80},
+    {.id = RegisterID::kX64_st3, .name = "st3", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st3, .bits = 80},
+    {.id = RegisterID::kX64_st4, .name = "st4", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st4, .bits = 80},
+    {.id = RegisterID::kX64_st5, .name = "st5", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st5, .bits = 80},
+    {.id = RegisterID::kX64_st6, .name = "st6", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st6, .bits = 80},
+    {.id = RegisterID::kX64_st7, .name = "st7", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st7, .bits = 80},
 
     // Vector.
 
-    {.id = RegisterID::kX64_mxcsr, .name = "mxcsr", .arch = Arch::kX64},
+    {.id = RegisterID::kX64_mxcsr, .name = "mxcsr", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_mxcsr, .bits = 32},
 
-    // SSE/SSE2 (128 bit).
-    {.id = RegisterID::kX64_xmm0, .name = "xmm0", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm1, .name = "xmm1", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm2, .name = "xmm2", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm3, .name = "xmm3", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm4, .name = "xmm4", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm5, .name = "xmm5", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm6, .name = "xmm6", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm7, .name = "xmm7", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm8, .name = "xmm8", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm9, .name = "xmm9", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm10, .name = "xmm10", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm11, .name = "xmm11", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm12, .name = "xmm12", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm13, .name = "xmm13", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm14, .name = "xmm14", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_xmm15, .name = "xmm15", .arch = Arch::kX64},
+    // AVX-512 (our canonical vector register names).
+    {.id = RegisterID::kX64_zmm0,  .name = "zmm0",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm0,  .bits = 512},
+    {.id = RegisterID::kX64_zmm1,  .name = "zmm1",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm1,  .bits = 512},
+    {.id = RegisterID::kX64_zmm2,  .name = "zmm2",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm2,  .bits = 512},
+    {.id = RegisterID::kX64_zmm3,  .name = "zmm3",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm3,  .bits = 512},
+    {.id = RegisterID::kX64_zmm4,  .name = "zmm4",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm4,  .bits = 512},
+    {.id = RegisterID::kX64_zmm5,  .name = "zmm5",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm5,  .bits = 512},
+    {.id = RegisterID::kX64_zmm6,  .name = "zmm6",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm6,  .bits = 512},
+    {.id = RegisterID::kX64_zmm7,  .name = "zmm7",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm7,  .bits = 512},
+    {.id = RegisterID::kX64_zmm8,  .name = "zmm8",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm8,  .bits = 512},
+    {.id = RegisterID::kX64_zmm9,  .name = "zmm9",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm9,  .bits = 512},
+    {.id = RegisterID::kX64_zmm10, .name = "zmm10", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm10, .bits = 512},
+    {.id = RegisterID::kX64_zmm11, .name = "zmm11", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm11, .bits = 512},
+    {.id = RegisterID::kX64_zmm12, .name = "zmm12", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm12, .bits = 512},
+    {.id = RegisterID::kX64_zmm13, .name = "zmm13", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm13, .bits = 512},
+    {.id = RegisterID::kX64_zmm14, .name = "zmm14", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm14, .bits = 512},
+    {.id = RegisterID::kX64_zmm15, .name = "zmm15", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm15, .bits = 512},
+    {.id = RegisterID::kX64_zmm16, .name = "zmm16", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm16, .bits = 512},
+    {.id = RegisterID::kX64_zmm17, .name = "zmm17", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm17, .bits = 512},
+    {.id = RegisterID::kX64_zmm18, .name = "zmm18", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm18, .bits = 512},
+    {.id = RegisterID::kX64_zmm19, .name = "zmm19", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm19, .bits = 512},
+    {.id = RegisterID::kX64_zmm20, .name = "zmm20", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm20, .bits = 512},
+    {.id = RegisterID::kX64_zmm21, .name = "zmm21", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm21, .bits = 512},
+    {.id = RegisterID::kX64_zmm22, .name = "zmm22", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm22, .bits = 512},
+    {.id = RegisterID::kX64_zmm23, .name = "zmm23", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm23, .bits = 512},
+    {.id = RegisterID::kX64_zmm24, .name = "zmm24", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm24, .bits = 512},
+    {.id = RegisterID::kX64_zmm25, .name = "zmm25", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm25, .bits = 512},
+    {.id = RegisterID::kX64_zmm26, .name = "zmm26", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm26, .bits = 512},
+    {.id = RegisterID::kX64_zmm27, .name = "zmm27", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm27, .bits = 512},
+    {.id = RegisterID::kX64_zmm28, .name = "zmm28", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm28, .bits = 512},
+    {.id = RegisterID::kX64_zmm29, .name = "zmm29", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm29, .bits = 512},
+    {.id = RegisterID::kX64_zmm30, .name = "zmm30", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm30, .bits = 512},
+    {.id = RegisterID::kX64_zmm31, .name = "zmm31", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm31, .bits = 512},
 
-    // AVX (256 bit).
-    {.id = RegisterID::kX64_ymm0, .name = "ymm0", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm1, .name = "ymm1", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm2, .name = "ymm2", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm3, .name = "ymm3", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm4, .name = "ymm4", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm5, .name = "ymm5", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm6, .name = "ymm6", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm7, .name = "ymm7", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm8, .name = "ymm8", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm9, .name = "ymm9", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm10, .name = "ymm10", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm11, .name = "ymm11", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm12, .name = "ymm12", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm13, .name = "ymm13", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm14, .name = "ymm14", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_ymm15, .name = "ymm15", .arch = Arch::kX64},
+    // Vector aliases
 
-    // TODO(donosoc): Add support for AVX-512 when zircon supports it.
+    {.id = RegisterID::kX64_xmm0,  .name = "xmm0", .arch = Arch::kX64,  .canonical_id = RegisterID::kX64_zmm0,  .bits = 128},
+    {.id = RegisterID::kX64_xmm1,  .name = "xmm1", .arch = Arch::kX64,  .canonical_id = RegisterID::kX64_zmm1,  .bits = 128},
+    {.id = RegisterID::kX64_xmm2,  .name = "xmm2", .arch = Arch::kX64,  .canonical_id = RegisterID::kX64_zmm2,  .bits = 128},
+    {.id = RegisterID::kX64_xmm3,  .name = "xmm3", .arch = Arch::kX64,  .canonical_id = RegisterID::kX64_zmm3,  .bits = 128},
+    {.id = RegisterID::kX64_xmm4,  .name = "xmm4", .arch = Arch::kX64,  .canonical_id = RegisterID::kX64_zmm4,  .bits = 128},
+    {.id = RegisterID::kX64_xmm5,  .name = "xmm5", .arch = Arch::kX64,  .canonical_id = RegisterID::kX64_zmm5,  .bits = 128},
+    {.id = RegisterID::kX64_xmm6,  .name = "xmm6", .arch = Arch::kX64,  .canonical_id = RegisterID::kX64_zmm6,  .bits = 128},
+    {.id = RegisterID::kX64_xmm7,  .name = "xmm7", .arch = Arch::kX64,  .canonical_id = RegisterID::kX64_zmm7,  .bits = 128},
+    {.id = RegisterID::kX64_xmm8,  .name = "xmm8", .arch = Arch::kX64,  .canonical_id = RegisterID::kX64_zmm8,  .bits = 128},
+    {.id = RegisterID::kX64_xmm9,  .name = "xmm9", .arch = Arch::kX64,  .canonical_id = RegisterID::kX64_zmm9,  .bits = 128},
+    {.id = RegisterID::kX64_xmm10, .name = "xmm10", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm10, .bits = 128},
+    {.id = RegisterID::kX64_xmm11, .name = "xmm11", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm11, .bits = 128},
+    {.id = RegisterID::kX64_xmm12, .name = "xmm12", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm12, .bits = 128},
+    {.id = RegisterID::kX64_xmm13, .name = "xmm13", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm13, .bits = 128},
+    {.id = RegisterID::kX64_xmm14, .name = "xmm14", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm14, .bits = 128},
+    {.id = RegisterID::kX64_xmm15, .name = "xmm15", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm15, .bits = 128},
+    {.id = RegisterID::kX64_xmm16, .name = "xmm16", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm16, .bits = 128},
+    {.id = RegisterID::kX64_xmm17, .name = "xmm17", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm17, .bits = 128},
+    {.id = RegisterID::kX64_xmm18, .name = "xmm18", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm18, .bits = 128},
+    {.id = RegisterID::kX64_xmm19, .name = "xmm19", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm19, .bits = 128},
+    {.id = RegisterID::kX64_xmm20, .name = "xmm20", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm20, .bits = 128},
+    {.id = RegisterID::kX64_xmm21, .name = "xmm21", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm21, .bits = 128},
+    {.id = RegisterID::kX64_xmm22, .name = "xmm22", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm22, .bits = 128},
+    {.id = RegisterID::kX64_xmm23, .name = "xmm23", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm23, .bits = 128},
+    {.id = RegisterID::kX64_xmm24, .name = "xmm24", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm24, .bits = 128},
+    {.id = RegisterID::kX64_xmm25, .name = "xmm25", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm25, .bits = 128},
+    {.id = RegisterID::kX64_xmm26, .name = "xmm26", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm26, .bits = 128},
+    {.id = RegisterID::kX64_xmm27, .name = "xmm27", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm27, .bits = 128},
+    {.id = RegisterID::kX64_xmm28, .name = "xmm28", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm28, .bits = 128},
+    {.id = RegisterID::kX64_xmm29, .name = "xmm29", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm29, .bits = 128},
+    {.id = RegisterID::kX64_xmm30, .name = "xmm30", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm30, .bits = 128},
+    {.id = RegisterID::kX64_xmm31, .name = "xmm31", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm31, .bits = 128},
+
+    {.id = RegisterID::kX64_ymm0,  .name = "ymm0",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm0,  .bits = 256},
+    {.id = RegisterID::kX64_ymm1,  .name = "ymm1",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm1,  .bits = 256},
+    {.id = RegisterID::kX64_ymm2,  .name = "ymm2",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm2,  .bits = 256},
+    {.id = RegisterID::kX64_ymm3,  .name = "ymm3",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm3,  .bits = 256},
+    {.id = RegisterID::kX64_ymm4,  .name = "ymm4",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm4,  .bits = 256},
+    {.id = RegisterID::kX64_ymm5,  .name = "ymm5",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm5,  .bits = 256},
+    {.id = RegisterID::kX64_ymm6,  .name = "ymm6",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm6,  .bits = 256},
+    {.id = RegisterID::kX64_ymm7,  .name = "ymm7",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm7,  .bits = 256},
+    {.id = RegisterID::kX64_ymm8,  .name = "ymm8",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm8,  .bits = 256},
+    {.id = RegisterID::kX64_ymm9,  .name = "ymm9",  .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm9,  .bits = 256},
+    {.id = RegisterID::kX64_ymm10, .name = "ymm10", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm10, .bits = 256},
+    {.id = RegisterID::kX64_ymm11, .name = "ymm11", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm11, .bits = 256},
+    {.id = RegisterID::kX64_ymm12, .name = "ymm12", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm12, .bits = 256},
+    {.id = RegisterID::kX64_ymm13, .name = "ymm13", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm13, .bits = 256},
+    {.id = RegisterID::kX64_ymm14, .name = "ymm14", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm14, .bits = 256},
+    {.id = RegisterID::kX64_ymm15, .name = "ymm15", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm15, .bits = 256},
+    {.id = RegisterID::kX64_ymm16, .name = "ymm16", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm16, .bits = 256},
+    {.id = RegisterID::kX64_ymm17, .name = "ymm17", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm17, .bits = 256},
+    {.id = RegisterID::kX64_ymm18, .name = "ymm18", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm18, .bits = 256},
+    {.id = RegisterID::kX64_ymm19, .name = "ymm19", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm19, .bits = 256},
+    {.id = RegisterID::kX64_ymm20, .name = "ymm20", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm20, .bits = 256},
+    {.id = RegisterID::kX64_ymm21, .name = "ymm21", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm21, .bits = 256},
+    {.id = RegisterID::kX64_ymm22, .name = "ymm22", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm22, .bits = 256},
+    {.id = RegisterID::kX64_ymm23, .name = "ymm23", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm23, .bits = 256},
+    {.id = RegisterID::kX64_ymm24, .name = "ymm24", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm24, .bits = 256},
+    {.id = RegisterID::kX64_ymm25, .name = "ymm25", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm25, .bits = 256},
+    {.id = RegisterID::kX64_ymm26, .name = "ymm26", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm26, .bits = 256},
+    {.id = RegisterID::kX64_ymm27, .name = "ymm27", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm27, .bits = 256},
+    {.id = RegisterID::kX64_ymm28, .name = "ymm28", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm28, .bits = 256},
+    {.id = RegisterID::kX64_ymm29, .name = "ymm29", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm29, .bits = 256},
+    {.id = RegisterID::kX64_ymm30, .name = "ymm30", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm30, .bits = 256},
+    {.id = RegisterID::kX64_ymm31, .name = "ymm31", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_zmm31, .bits = 256},
+
+    // The old-style MMX registers are the low 64-bits of the FP registers.
+    {.id = RegisterID::kX64_mm0, .name = "mm0", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st0, .bits = 64},
+    {.id = RegisterID::kX64_mm1, .name = "mm1", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st1, .bits = 64},
+    {.id = RegisterID::kX64_mm2, .name = "mm2", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st2, .bits = 64},
+    {.id = RegisterID::kX64_mm3, .name = "mm3", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st3, .bits = 64},
+    {.id = RegisterID::kX64_mm4, .name = "mm4", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st4, .bits = 64},
+    {.id = RegisterID::kX64_mm5, .name = "mm5", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st5, .bits = 64},
+    {.id = RegisterID::kX64_mm6, .name = "mm6", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st6, .bits = 64},
+    {.id = RegisterID::kX64_mm7, .name = "mm7", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_st7, .bits = 64},
 
     // Debug.
 
-    {.id = RegisterID::kX64_dr0, .name = "dr0", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_dr1, .name = "dr1", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_dr2, .name = "dr2", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_dr3, .name = "dr3", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_dr6, .name = "dr6", .arch = Arch::kX64},
-    {.id = RegisterID::kX64_dr7, .name = "dr7", .arch = Arch::kX64},
+    {.id = RegisterID::kX64_dr0, .name = "dr0", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_dr0, .bits = 64},
+    {.id = RegisterID::kX64_dr1, .name = "dr1", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_dr1, .bits = 64},
+    {.id = RegisterID::kX64_dr2, .name = "dr2", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_dr2, .bits = 64},
+    {.id = RegisterID::kX64_dr3, .name = "dr3", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_dr3, .bits = 64},
+    {.id = RegisterID::kX64_dr6, .name = "dr6", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_dr6, .bits = 64},
+    {.id = RegisterID::kX64_dr7, .name = "dr7", .arch = Arch::kX64, .canonical_id = RegisterID::kX64_dr7, .bits = 64},
 };
 
-constexpr size_t kRegisterInfoCount = arraysize(kRegisterInfo);
-
-const RegisterInfo* RegisterIDToInfo(RegisterID id) {
-  static std::map<RegisterID, const RegisterInfo*> info_map;
-
-  if (info_map.empty()) {
-    for (size_t i = 0; i < kRegisterInfoCount; i++) {
-      info_map[kRegisterInfo[i].id] = &kRegisterInfo[i];
-    }
-  }
-
-  auto iter = info_map.find(id);
-
-  if (iter != info_map.end()) {
-    return iter->second;
-  }
-
-  return nullptr;
-}
+// clang-format on
 
 RegisterID DWARFToRegisterIDX64(uint32_t dwarf_reg_id) {
-  // TODO: It's possibly more maintainable to capture DWARF IDs in the table
-  // and just have a cached lookup rather than this switch. We wouldn't even
-  // need the arch-specific functions.
+  // TODO: Move the DWARF IDs into the RegisterInfo table and then fill into a map for dynamic
+  // lookup.
 
   // https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
   // Page 62
@@ -321,8 +443,8 @@
 }
 
 RegisterID DWARFToRegisterIDARMv8(uint32_t dwarf_reg_id) {
-  // TODO: See comment in DWARFToRegisterIDX64 about getting rid of these and
-  // just adding the info to the table.
+  // TODO: See comment in DWARFToRegisterIDX64 about getting rid of these and just adding the info
+  // to the table.
 
   // http://infocenter.arm.com/help/topic/com.arm.doc.ecm0665627/abi_sve_aadwarf_100985_0000_00_en.pdf
   // Page 6
@@ -344,6 +466,36 @@
 
 }  // namespace
 
+const RegisterInfo* InfoForRegister(RegisterID id) {
+  static std::map<RegisterID, const RegisterInfo*> info_map;
+
+  if (info_map.empty()) {
+    for (const auto& info : kRegisterInfo)
+      info_map[info.id] = &info;
+  }
+
+  auto iter = info_map.find(id);
+  if (iter != info_map.end())
+    return iter->second;
+
+  return nullptr;
+}
+
+const RegisterInfo* InfoForRegister(Arch arch, const std::string& name) {
+  static std::map<std::pair<Arch, std::string>, const RegisterInfo*> info_map;
+
+  if (info_map.empty()) {
+    for (const auto& info : kRegisterInfo)
+      info_map[std::make_pair(info.arch, std::string(info.name))] = &info;
+  }
+
+  auto iter = info_map.find(std::make_pair(arch, name));
+  if (iter != info_map.end())
+    return iter->second;
+
+  return nullptr;
+}
+
 RegisterID GetSpecialRegisterID(Arch arch, SpecialRegisterType type) {
   switch (arch) {
     case Arch::kX64:
@@ -377,7 +529,7 @@
 }
 
 const char* RegisterIDToString(RegisterID id) {
-  auto info = RegisterIDToInfo(id);
+  auto info = InfoForRegister(id);
 
   if (!info) {
     FXL_NOTREACHED() << "Unknown register requested: " << static_cast<uint32_t>(id);
@@ -393,7 +545,7 @@
   if (id_map.empty()) {
     // We populate the whole map at once, otherwise any time we try to look up
     // an invalid register ID (fairly often) we have to search the whole list.
-    for (size_t i = 0; i < kRegisterInfoCount; i++) {
+    for (size_t i = 0; i < std::size(kRegisterInfo); i++) {
       id_map[kRegisterInfo[i].name] = kRegisterInfo[i].id;
     }
   }
@@ -408,7 +560,7 @@
 }
 
 Arch GetArchForRegisterID(RegisterID id) {
-  auto info = RegisterIDToInfo(id);
+  auto info = InfoForRegister(id);
 
   if (!info) {
     FXL_NOTREACHED() << "Arch for unknown register requested: " << static_cast<uint32_t>(id);
diff --git a/src/developer/debug/ipc/register_desc.h b/src/developer/debug/ipc/register_desc.h
index 944dd08..358e6f2 100644
--- a/src/developer/debug/ipc/register_desc.h
+++ b/src/developer/debug/ipc/register_desc.h
@@ -22,6 +22,26 @@
 
 enum class SpecialRegisterType { kNone, kIP, kSP };
 
+struct RegisterInfo {
+  RegisterID id;
+  std::string name;
+  Arch arch;
+
+  // Some registers refer to a subset of another register, e.g. "al" (low byte of "rax") on X86 or
+  // "w0" (low 32-bits of "x0") on ARM. This ID will be the larger canonical ID. For registers that
+  // are themselves canonical, this will be the same as "id".
+  RegisterID canonical_id;
+
+  // When asking for a name-to-register mapping, sometimes they map to a part of a register. For
+  // example "al" on x64 is the low 8 bits of rax. These will both be 0 for the "canonical" register
+  // record.
+  int bits = 0;
+  int shift = 0;  // How many bits shited to the right is the low bit of the value.
+};
+
+const RegisterInfo* InfoForRegister(RegisterID id);
+const RegisterInfo* InfoForRegister(Arch arch, const std::string& name);
+
 const char* RegisterIDToString(debug_ipc::RegisterID);
 debug_ipc::RegisterID StringToRegisterID(const std::string&);
 
@@ -57,9 +77,9 @@
 constexpr uint32_t kX64FPBegin = 2100;
 constexpr uint32_t kX64FPEnd = 2199;
 constexpr uint32_t kX64VectorBegin = 2200;
-constexpr uint32_t kX64VectorEnd = 2499;
-constexpr uint32_t kX64DebugBegin = 2500;
-constexpr uint32_t kX64DebugEnd = 2599;
+constexpr uint32_t kX64VectorEnd = 2599;
+constexpr uint32_t kX64DebugBegin = 2600;
+constexpr uint32_t kX64DebugEnd = 2699;
 
 enum class RegisterID : uint32_t {
   kUnknown = 0,
@@ -105,6 +125,41 @@
   // accessing the PSTATE. It's functionally equivalent to SPSR_EL1.
   kARMv8_cpsr = 1034,
 
+  // General-purpose aliases (low 32-bits).
+  kARMv8_w0 = 1035,
+  kARMv8_w1 = 1036,
+  kARMv8_w2 = 1037,
+  kARMv8_w3 = 1038,
+  kARMv8_w4 = 1039,
+  kARMv8_w5 = 1040,
+  kARMv8_w6 = 1041,
+  kARMv8_w7 = 1042,
+  kARMv8_w8 = 1043,
+  kARMv8_w9 = 1044,
+  kARMv8_w10 = 1045,
+  kARMv8_w11 = 1046,
+  kARMv8_w12 = 1047,
+  kARMv8_w13 = 1048,
+  kARMv8_w14 = 1049,
+  kARMv8_w15 = 1050,
+  kARMv8_w16 = 1051,
+  kARMv8_w17 = 1052,
+  kARMv8_w18 = 1053,
+  kARMv8_w19 = 1054,
+  kARMv8_w20 = 1055,
+  kARMv8_w21 = 1056,
+  kARMv8_w22 = 1057,
+  kARMv8_w23 = 1058,
+  kARMv8_w24 = 1059,
+  kARMv8_w25 = 1060,
+  kARMv8_w26 = 1061,
+  kARMv8_w27 = 1062,
+  kARMv8_w28 = 1063,
+  kARMv8_w29 = 1064,
+  kARMv8_w30 = 1065,
+
+  kARMv8_x30 = 1066,  // Alias for "LR" above.
+
   // FP (None on ARMv8).
 
   // Vector.
@@ -207,6 +262,34 @@
   kX64_rip = 2016,
   kX64_rflags = 2017,
 
+  // General purpose aliases.
+
+  kX64_ah = 2018,
+  kX64_al = 2019,
+  kX64_ax = 2020,
+  kX64_eax = 2021,
+
+  kX64_bh = 2022,
+  kX64_bl = 2023,
+  kX64_bx = 2024,
+  kX64_ebx = 2025,
+
+  kX64_ch = 2026,
+  kX64_cl = 2027,
+  kX64_cx = 2028,
+  kX64_ecx = 2029,
+
+  kX64_dh = 2030,
+  kX64_dl = 2031,
+  kX64_dx = 2032,
+  kX64_edx = 2033,
+
+  kX64_si = 2034,
+  kX64_esi = 2035,
+
+  kX64_di = 2036,
+  kX64_edi = 2037,
+
   // FP (x87 FPU/MMX).
 
   kX64_fcw = 2100,  // Control word.
@@ -233,54 +316,126 @@
 
   kX64_mxcsr = 2200,  // Control and Status register.
 
-  // SSE/SSE2 (128 bit).
-  kX64_xmm0 = 2300,
-  kX64_xmm1 = 2301,
-  kX64_xmm2 = 2302,
-  kX64_xmm3 = 2303,
-  kX64_xmm4 = 2304,
-  kX64_xmm5 = 2305,
-  kX64_xmm6 = 2306,
-  kX64_xmm7 = 2307,
-  kX64_xmm8 = 2308,
-  kX64_xmm9 = 2309,
-  kX64_xmm10 = 2310,
-  kX64_xmm11 = 2311,
-  kX64_xmm12 = 2312,
-  kX64_xmm13 = 2313,
-  kX64_xmm14 = 2314,
-  kX64_xmm15 = 2315,
+  // SSE/AVX (512 bit, 128- and 256-bit variants will use the low bits of these).
+  kX64_zmm0 = 2400,
+  kX64_zmm1 = 2401,
+  kX64_zmm2 = 2402,
+  kX64_zmm3 = 2403,
+  kX64_zmm4 = 2404,
+  kX64_zmm5 = 2405,
+  kX64_zmm6 = 2406,
+  kX64_zmm7 = 2407,
+  kX64_zmm8 = 2408,
+  kX64_zmm9 = 2409,
+  kX64_zmm10 = 2410,
+  kX64_zmm11 = 2411,
+  kX64_zmm12 = 2412,
+  kX64_zmm13 = 2413,
+  kX64_zmm14 = 2414,
+  kX64_zmm15 = 2415,
+  kX64_zmm16 = 2416,
+  kX64_zmm17 = 2417,
+  kX64_zmm18 = 2418,
+  kX64_zmm19 = 2419,
+  kX64_zmm20 = 2420,
+  kX64_zmm21 = 2421,
+  kX64_zmm22 = 2422,
+  kX64_zmm23 = 2423,
+  kX64_zmm24 = 2424,
+  kX64_zmm25 = 2425,
+  kX64_zmm26 = 2426,
+  kX64_zmm27 = 2427,
+  kX64_zmm28 = 2428,
+  kX64_zmm29 = 2429,
+  kX64_zmm30 = 2430,
+  kX64_zmm31 = 2431,
 
-  // AVX (256 bit).
-  kX64_ymm0 = 2400,
-  kX64_ymm1 = 2401,
-  kX64_ymm2 = 2402,
-  kX64_ymm3 = 2403,
-  kX64_ymm4 = 2404,
-  kX64_ymm5 = 2405,
-  kX64_ymm6 = 2406,
-  kX64_ymm7 = 2407,
-  kX64_ymm8 = 2408,
-  kX64_ymm9 = 2409,
-  kX64_ymm10 = 2410,
-  kX64_ymm11 = 2411,
-  kX64_ymm12 = 2412,
-  kX64_ymm13 = 2413,
-  kX64_ymm14 = 2414,
-  kX64_ymm15 = 2415,
+  // Vector aliases.
+  kX64_xmm0 = 2432,
+  kX64_xmm1 = 2433,
+  kX64_xmm2 = 2434,
+  kX64_xmm3 = 2435,
+  kX64_xmm4 = 2436,
+  kX64_xmm5 = 2437,
+  kX64_xmm6 = 2438,
+  kX64_xmm7 = 2439,
+  kX64_xmm8 = 2440,
+  kX64_xmm9 = 2441,
+  kX64_xmm10 = 2442,
+  kX64_xmm11 = 2443,
+  kX64_xmm12 = 2444,
+  kX64_xmm13 = 2445,
+  kX64_xmm14 = 2446,
+  kX64_xmm15 = 2447,
+  kX64_xmm16 = 2448,
+  kX64_xmm17 = 2449,
+  kX64_xmm18 = 2450,
+  kX64_xmm19 = 2451,
+  kX64_xmm20 = 2452,
+  kX64_xmm21 = 2453,
+  kX64_xmm22 = 2454,
+  kX64_xmm23 = 2455,
+  kX64_xmm24 = 2456,
+  kX64_xmm25 = 2457,
+  kX64_xmm26 = 2458,
+  kX64_xmm27 = 2459,
+  kX64_xmm28 = 2460,
+  kX64_xmm29 = 2461,
+  kX64_xmm30 = 2462,
+  kX64_xmm31 = 2463,
 
-  // TODO(donosoc): Add AVX-512 support.
+  kX64_ymm0 = 2464,
+  kX64_ymm1 = 2465,
+  kX64_ymm2 = 2466,
+  kX64_ymm3 = 2467,
+  kX64_ymm4 = 2468,
+  kX64_ymm5 = 2469,
+  kX64_ymm6 = 2470,
+  kX64_ymm7 = 2471,
+  kX64_ymm8 = 2472,
+  kX64_ymm9 = 2473,
+  kX64_ymm10 = 2474,
+  kX64_ymm11 = 2475,
+  kX64_ymm12 = 2476,
+  kX64_ymm13 = 2477,
+  kX64_ymm14 = 2478,
+  kX64_ymm15 = 2479,
+  kX64_ymm16 = 2480,
+  kX64_ymm17 = 2481,
+  kX64_ymm18 = 2482,
+  kX64_ymm19 = 2483,
+  kX64_ymm20 = 2484,
+  kX64_ymm21 = 2485,
+  kX64_ymm22 = 2486,
+  kX64_ymm23 = 2487,
+  kX64_ymm24 = 2488,
+  kX64_ymm25 = 2489,
+  kX64_ymm26 = 2490,
+  kX64_ymm27 = 2491,
+  kX64_ymm28 = 2492,
+  kX64_ymm29 = 2493,
+  kX64_ymm30 = 2494,
+  kX64_ymm31 = 2495,
+
+  kX64_mm0 = 2496,
+  kX64_mm1 = 2497,
+  kX64_mm2 = 2498,
+  kX64_mm3 = 2499,
+  kX64_mm4 = 2500,
+  kX64_mm5 = 2501,
+  kX64_mm6 = 2502,
+  kX64_mm7 = 2503,
 
   // Debug.
 
-  kX64_dr0 = 2500,
-  kX64_dr1 = 2501,
-  kX64_dr2 = 2502,
-  kX64_dr3 = 2503,
+  kX64_dr0 = 2600,
+  kX64_dr1 = 2601,
+  kX64_dr2 = 2602,
+  kX64_dr3 = 2603,
   // dr4 is reserved.
   // dr5 is reserved.
-  kX64_dr6 = 2506,
-  kX64_dr7 = 2507,
+  kX64_dr6 = 2606,
+  kX64_dr7 = 2607,
 };
 
 }  // namespace debug_ipc
diff --git a/src/developer/debug/zxdb/console/format_register_unittest.cc b/src/developer/debug/zxdb/console/format_register_unittest.cc
index 6097bec..c07f411 100644
--- a/src/developer/debug/zxdb/console/format_register_unittest.cc
+++ b/src/developer/debug/zxdb/console/format_register_unittest.cc
@@ -487,20 +487,18 @@
   err = FormatRegisters(options, filtered_set, &out);
   ASSERT_FALSE(err.has_error()) << err.msg();
 
+  // clang-format off
   EXPECT_EQ(
       "Debug Registers\n"
-      "   kARMv8_dbgbcr0_el1          0x000f2006 E=0, PMC=3, BAS=0, HMC=1, "
-      "SSC=0, LBN=15, BT=0\n"
-      "   kARMv8_dbgbvr0_el1  0xdeadbeefaabbccdd \n"
-      "  kARMv8_dbgbcr15_el1          0x00f0c1e1 E=1, PMC=0, BAS=15, HMC=0, "
-      "SSC=3, LBN=0, BT=15\n"
-      "   kARMv8_dbgbvr0_el1  0xaabbccdd11223344 \n"
-      "      id_aa64dfr0_el1         0xf00f0ff0f DV=15, TV=0, PMUV=15, BRP=16, "
-      "WRP=16, CTX_CMP=1, PMSV=15\n"
-      "            mdscr_el1          0x44009001 SS=1, TDCC=1, KDE=0, HDE=0, "
-      "MDE=1, RAZ/WI=0, TDA=0, INTdis=0, TXU=1, RXO=0, TXfull=0, RXfull=1\n"
+      "      dbgbcr0_el1          0x000f2006 E=0, PMC=3, BAS=0, HMC=1, SSC=0, LBN=15, BT=0\n"
+      "      dbgbvr0_el1  0xdeadbeefaabbccdd \n"
+      "     dbgbcr15_el1          0x00f0c1e1 E=1, PMC=0, BAS=15, HMC=0, SSC=3, LBN=0, BT=15\n"
+      "      dbgbvr0_el1  0xaabbccdd11223344 \n"
+      "  id_aa64dfr0_el1         0xf00f0ff0f DV=15, TV=0, PMUV=15, BRP=16, WRP=16, CTX_CMP=1, PMSV=15\n"
+      "        mdscr_el1          0x44009001 SS=1, TDCC=1, KDE=0, HDE=0, MDE=1, RAZ/WI=0, TDA=0, INTdis=0, TXU=1, RXO=0, TXfull=0, RXfull=1\n"
       "\n",
       out.AsString());
+  // clang-format on
 }
 
 }  // namespace zxdb