[intrinsics] Add additional metadata to types

This prepares for changes to AsmCallInfo coming in a following CL.

Bug: 295189784
Test: mm && berberis_host_tests
Change-Id: I567b2c7a380bdd2f1ed7da1fe4fe7df860313d35
diff --git a/backend/include/berberis/backend/x86_64/machine_ir.h b/backend/include/berberis/backend/x86_64/machine_ir.h
index 3b529f4..490575d 100644
--- a/backend/include/berberis/backend/x86_64/machine_ir.h
+++ b/backend/include/berberis/backend/x86_64/machine_ir.h
@@ -110,8 +110,27 @@
   kEight,
 };
 
+#include "machine_reg_class_x86_64-inl.h"  // NOLINT generated file!
+
 class MachineInsnX86_64 : public MachineInsn {
  public:
+  static constexpr const auto kEAX = x86_64::kEAX;
+  static constexpr const auto kRAX = x86_64::kRAX;
+  static constexpr const auto kCL = x86_64::kCL;
+  static constexpr const auto kECX = x86_64::kECX;
+  static constexpr const auto kRCX = x86_64::kRCX;
+  static constexpr const auto kEDX = x86_64::kEDX;
+  static constexpr const auto kRDX = x86_64::kRDX;
+  static constexpr const auto kGeneralReg8 = x86_64::kGeneralReg8;
+  static constexpr const auto kGeneralReg16 = x86_64::kGeneralReg16;
+  static constexpr const auto kGeneralReg32 = x86_64::kGeneralReg32;
+  static constexpr const auto kGeneralReg64 = x86_64::kGeneralReg64;
+  static constexpr const auto kFpReg32 = x86_64::kFpReg32;
+  static constexpr const auto kFpReg64 = x86_64::kFpReg64;
+  static constexpr const auto kVecReg128 = x86_64::kVecReg128;
+  static constexpr const auto kXmmReg = x86_64::kXmmReg;
+  static constexpr const auto kFLAGS = x86_64::kFLAGS;
+
   ~MachineInsnX86_64() override {
     // No code here - will never be called!
   }
@@ -245,8 +264,6 @@
   };
 };
 
-#include "machine_reg_class_x86_64-inl.h"  // NOLINT generated file!
-
 // This template is syntax sugar to group memory instructions with
 // different addressing modes.
 template <typename Absolute_, typename BaseDisp_, typename IndexDisp_, typename BaseIndexDisp_>
diff --git a/intrinsics/common_to_x86/include/berberis/intrinsics/common_to_x86/intrinsics_bindings.h b/intrinsics/common_to_x86/include/berberis/intrinsics/common_to_x86/intrinsics_bindings.h
index 67917e5..6659930 100644
--- a/intrinsics/common_to_x86/include/berberis/intrinsics/common_to_x86/intrinsics_bindings.h
+++ b/intrinsics/common_to_x86/include/berberis/intrinsics/common_to_x86/intrinsics_bindings.h
@@ -21,6 +21,7 @@
 
 #include <cstdint>
 
+#include "berberis/base/dependent_false.h"
 #include "berberis/intrinsics/intrinsics_args.h"
 #include "berberis/intrinsics/type_traits.h"
 
@@ -78,6 +79,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = true;
   static constexpr char kAsRegister = 'a';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kEAX;
 };
 
 class RAX {
@@ -86,6 +89,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = true;
   static constexpr char kAsRegister = 'a';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kRAX;
 };
 
 class CL {
@@ -94,6 +99,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = true;
   static constexpr char kAsRegister = 'c';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kCL;
 };
 
 class CX {
@@ -110,6 +117,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = true;
   static constexpr char kAsRegister = 'c';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kECX;
 };
 
 class RCX {
@@ -118,6 +127,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = true;
   static constexpr char kAsRegister = 'c';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kRCX;
 };
 
 class DL {
@@ -142,6 +153,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = true;
   static constexpr char kAsRegister = 'd';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kEDX;
 };
 
 class RDX {
@@ -150,6 +163,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = true;
   static constexpr char kAsRegister = 'd';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kRDX;
 };
 
 class GeneralReg8 {
@@ -158,6 +173,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = false;
   static constexpr char kAsRegister = 'q';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kGeneralReg8;
 };
 
 class GeneralReg16 {
@@ -166,6 +183,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = false;
   static constexpr char kAsRegister = 'r';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kGeneralReg16;
 };
 
 class GeneralReg32 {
@@ -174,6 +193,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = false;
   static constexpr char kAsRegister = 'r';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kGeneralReg32;
 };
 
 class GeneralReg64 {
@@ -182,6 +203,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = false;
   static constexpr char kAsRegister = 'r';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kGeneralReg64;
 };
 
 class FLAGS {
@@ -189,6 +212,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = true;
   static constexpr char kAsRegister = 0;
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kFLAGS;
 };
 
 class FpReg32 {
@@ -197,6 +222,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = false;
   static constexpr char kAsRegister = 'x';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kFpReg32;
 };
 
 class FpReg64 {
@@ -205,6 +232,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = false;
   static constexpr char kAsRegister = 'x';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kFpReg64;
 };
 
 class VecReg128 {
@@ -213,6 +242,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = false;
   static constexpr char kAsRegister = 'x';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kVecReg128;
 };
 
 class XmmReg {
@@ -221,6 +252,8 @@
   static constexpr bool kIsImmediate = false;
   static constexpr bool kIsImplicitReg = false;
   static constexpr char kAsRegister = 'x';
+  template <typename MachineInsnArch>
+  static constexpr auto kRegClass = MachineInsnArch::kXmmReg;
 };
 
 class Mem8 {
@@ -251,12 +284,31 @@
   static constexpr char kAsRegister = 'm';
 };
 
-// Tag classes. They are never instantioned, only used as tags to pass information about bindings.
+// // Tag classes. They are never instantioned, only used as tags to pass information about
+// bindings.
 class Def;
 class DefEarlyClobber;
 class Use;
 class UseDef;
 
+template <typename Tag, typename MachineRegKind>
+constexpr auto ToRegKind() {
+  if constexpr (std::is_same_v<Tag, Def>) {
+    return MachineRegKind::kDef;
+  } else if constexpr (std::is_same_v<Tag, DefEarlyClobber>) {
+    return MachineRegKind::kDefEarlyClobber;
+  } else if constexpr (std::is_same_v<Tag, Use>) {
+    return MachineRegKind::kUse;
+  } else if constexpr (std::is_same_v<Tag, UseDef>) {
+    return MachineRegKind::kUseDef;
+  } else {
+    static_assert(kDependentTypeFalse<Tag>);
+  }
+}
+
+template <typename Tag, typename MachineRegKind>
+inline constexpr auto kRegKind = ToRegKind<Tag, MachineRegKind>();
+
 enum CPUIDRestriction : int {
   kNoCPUIDRestriction = 0,
   kHas3DNOW,
diff --git a/intrinsics/include/berberis/intrinsics/intrinsics_args.h b/intrinsics/include/berberis/intrinsics/intrinsics_args.h
index db7dabb..1f3ce6a 100644
--- a/intrinsics/include/berberis/intrinsics/intrinsics_args.h
+++ b/intrinsics/include/berberis/intrinsics/intrinsics_args.h
@@ -148,63 +148,87 @@
 template <int N, typename RegisterClassType, typename UsageType>
 class ArgTraits<InArg<N, RegisterClassType, UsageType>> {
  public:
+  using Class = RegisterClassType;
   using RegisterClass = RegisterClassType;
   using Usage = UsageType;
+  template <typename MachineReg>
+  using BuilderArg = MachineReg;
   static constexpr ArgInfo arg_info{.arg_type = ArgInfo::IN_ARG, .from = N};
 };
 
 template <int N, typename RegisterClassType, typename UsageType>
 class ArgTraits<OutArg<N, RegisterClassType, UsageType>> {
  public:
+  using Class = RegisterClassType;
   using RegisterClass = RegisterClassType;
   using Usage = UsageType;
+  template <typename MachineReg>
+  using BuilderArg = MachineReg;
   static constexpr ArgInfo arg_info{.arg_type = ArgInfo::OUT_ARG, .to = N};
 };
 
 template <int N, typename RegisterClassType, typename UsageType>
 class ArgTraits<OutTmpArg<N, RegisterClassType, UsageType>> {
  public:
+  using Class = RegisterClassType;
   using RegisterClass = RegisterClassType;
   using Usage = UsageType;
+  template <typename MachineReg>
+  using BuilderArg = MachineReg;
   static constexpr ArgInfo arg_info{.arg_type = ArgInfo::OUT_TMP_ARG, .to = N};
 };
 
 template <int N, int M, typename RegisterClassType, typename UsageType>
 class ArgTraits<InOutArg<N, M, RegisterClassType, UsageType>> {
  public:
+  using Class = RegisterClassType;
   using RegisterClass = RegisterClassType;
   using Usage = UsageType;
+  template <typename MachineReg>
+  using BuilderArg = MachineReg;
   static constexpr ArgInfo arg_info{.arg_type = ArgInfo::IN_OUT_ARG, .from = N, .to = M};
 };
 
 template <int N, int M, typename RegisterClassType, typename UsageType>
 class ArgTraits<InOutTmpArg<N, M, RegisterClassType, UsageType>> {
  public:
+  using Class = RegisterClassType;
   using RegisterClass = RegisterClassType;
   using Usage = UsageType;
+  template <typename MachineReg>
+  using BuilderArg = MachineReg;
   static constexpr ArgInfo arg_info{.arg_type = ArgInfo::IN_OUT_TMP_ARG, .from = N, .to = M};
 };
 
 template <int N, typename RegisterClassType, typename UsageType>
 class ArgTraits<InTmpArg<N, RegisterClassType, UsageType>> {
  public:
+  using Class = RegisterClassType;
   using RegisterClass = RegisterClassType;
   using Usage = UsageType;
+  template <typename MachineReg>
+  using BuilderArg = MachineReg;
   static constexpr ArgInfo arg_info{.arg_type = ArgInfo::IN_TMP_ARG, .from = N};
 };
 
 template <int N, typename ImmType, typename ImmediateClassType>
 class ArgTraits<ImmArg<N, ImmType, ImmediateClassType>> {
  public:
+  using Class = ImmediateClassType;
   using ImmediateClass = ImmediateClassType;
+  template <typename>
+  using BuilderArg = ImmType;
   static constexpr ArgInfo arg_info{.arg_type = ArgInfo::IMM_ARG, .from = N};
 };
 
 template <typename RegisterClassType, typename UsageType>
 class ArgTraits<TmpArg<RegisterClassType, UsageType>> {
  public:
+  using Class = RegisterClassType;
   using RegisterClass = RegisterClassType;
   using Usage = UsageType;
+  template <typename MachineReg>
+  using BuilderArg = MachineReg;
   static constexpr ArgInfo arg_info{.arg_type = ArgInfo::TMP_ARG};
 };