Make *ie and *ip registers 64 bit CSRs.

Fixes an issue in a test where a shift of 32 was performed on a
32 bit quantity (undefined behavior in C++)

PiperOrigin-RevId: 823071750
Change-Id: I56afa96530b536d273aa7c8dd2e4e80fe9112c5f
diff --git a/riscv/riscv_xip_xie.cc b/riscv/riscv_xip_xie.cc
index 608c7c1..9c92d9a 100644
--- a/riscv/riscv_xip_xie.cc
+++ b/riscv/riscv_xip_xie.cc
@@ -24,78 +24,77 @@
 namespace riscv {
 
 // Machine Interrupt Pending methods.
-RiscVMIp::RiscVMIp(uint32_t initial_value, ArchState* state)
-    : RiscVSimpleCsr<uint32_t>("mip", RiscVCsrEnum::kMIp, initial_value,
+RiscVMIp::RiscVMIp(uint64_t initial_value, ArchState* state)
+    : RiscVSimpleCsr<uint64_t>("mip", RiscVCsrEnum::kMIp, initial_value,
                                kReadMask, kWriteMask, state) {}
-void RiscVMIp::Set(uint32_t value) {
-  this->RiscVSimpleCsr<uint32_t>::Set(value);
+void RiscVMIp::Set(uint64_t value) {
+  this->RiscVSimpleCsr<uint64_t>::Set(value);
   if (value != 0) {
     state()->CheckForInterrupt();
   }
 }
 
-void RiscVMIp::Set(uint64_t value) { Set(static_cast<uint32_t>(value)); }
+void RiscVMIp::Set(uint32_t value) { Set(static_cast<uint64_t>(value)); }
 
-uint32_t RiscVMIp::GetUint32() {
-  return this->RiscVSimpleCsr<uint32_t>::GetUint32() | ext_seip_;
+uint32_t RiscVMIp::GetUint32() { return static_cast<uint32_t>(GetUint64()); }
+
+uint64_t RiscVMIp::GetUint64() {
+  return this->RiscVSimpleCsr<uint64_t>::GetUint64() | ext_seip_;
 }
 
-uint64_t RiscVMIp::GetUint64() { return GetUint32(); }
-
 // Supervisor Interrupt Pending methods.
 RiscVSIp::RiscVSIp(RiscVMIp* mip, RiscVCsrInterface* mideleg, ArchState* state)
-    : RiscVSimpleCsr<uint32_t>("sip", RiscVCsrEnum::kSIp, kReadMask, kWriteMask,
+    : RiscVSimpleCsr<uint64_t>("sip", RiscVCsrEnum::kSIp, kReadMask, kWriteMask,
                                state),
       mip_(mip),
       mideleg_(mideleg) {}
 
-void RiscVSIp::Set(uint32_t value) {
-  auto wmask = write_mask() | mideleg_->GetUint32();
-  mip_->Set((mip_->GetUint32() & wmask) | (value & wmask));
+void RiscVSIp::Set(uint64_t value) {
+  auto wmask = write_mask() | mideleg_->GetUint64();
+  mip_->Set((mip_->GetUint64() & wmask) | (value & wmask));
 }
 
-void RiscVSIp::Set(uint64_t value) { Set(static_cast<uint32_t>(value)); }
+void RiscVSIp::Set(uint32_t value) { Set(static_cast<uint64_t>(value)); }
 
 // Machine Interrupt Enable methods.
-RiscVMIe::RiscVMIe(uint32_t initial_value, ArchState* state)
-    : RiscVSimpleCsr<uint32_t>("mie", RiscVCsrEnum::kMIe, initial_value,
+RiscVMIe::RiscVMIe(uint64_t initial_value, ArchState* state)
+    : RiscVSimpleCsr<uint64_t>("mie", RiscVCsrEnum::kMIe, initial_value,
                                kReadMask, kWriteMask, state) {}
-void RiscVMIe::Set(uint32_t value) {
-  this->RiscVSimpleCsr<uint32_t>::Set(value);
+
+void RiscVMIe::Set(uint32_t value) { Set(static_cast<uint64_t>(value)); }
+
+void RiscVMIe::Set(uint64_t value) {
+  this->RiscVSimpleCsr<uint64_t>::Set(value);
   if (value != 0) {
     state()->CheckForInterrupt();
   }
 }
 
-uint32_t RiscVSIp::GetUint32() {
-  return mip_->GetUint32() & (mideleg_->GetUint32() | read_mask());
+uint64_t RiscVSIp::GetUint64() {
+  return mip_->GetUint64() & (mideleg_->GetUint64() | read_mask());
 }
 
-uint64_t RiscVSIp::GetUint64() { return GetUint32(); }
-
-void RiscVMIe::Set(uint64_t value) {
-  this->RiscVSimpleCsr<uint32_t>::Set(value);
-}
+uint32_t RiscVSIp::GetUint32() { return static_cast<uint32_t>(GetUint64()); }
 
 // Supervisor Interrupt Enable methods.
 RiscVSIe::RiscVSIe(RiscVMIe* mie, RiscVCsrInterface* mideleg, ArchState* state)
-    : RiscVSimpleCsr<uint32_t>("sie", RiscVCsrEnum::kSIe, kReadMask, kWriteMask,
+    : RiscVSimpleCsr<uint64_t>("sie", RiscVCsrEnum::kSIe, kReadMask, kWriteMask,
                                state),
       mie_(mie),
       mideleg_(mideleg) {}
 
-void RiscVSIe::Set(uint32_t value) {
-  auto wmask = write_mask() | mideleg_->GetUint32();
-  mie_->Set((mie_->GetUint32() & wmask) | (value & wmask));
+void RiscVSIe::Set(uint64_t value) {
+  auto wmask = write_mask() | mideleg_->GetUint64();
+  mie_->Set((mie_->GetUint64() & wmask) | (value & wmask));
 }
 
-void RiscVSIe::Set(uint64_t value) { Set(static_cast<uint32_t>(value)); }
+void RiscVSIe::Set(uint32_t value) { Set(static_cast<uint64_t>(value)); }
 
-uint32_t RiscVSIe::GetUint32() {
-  return mie_->GetUint32() & (mideleg_->GetUint32() | read_mask());
+uint64_t RiscVSIe::GetUint64() {
+  return mie_->GetUint64() & (mideleg_->GetUint64() | read_mask());
 }
 
-uint64_t RiscVSIe::GetUint64() { return GetUint32(); }
+uint32_t RiscVSIe::GetUint32() { return static_cast<uint32_t>(GetUint64()); }
 
 }  // namespace riscv
 }  // namespace sim
diff --git a/riscv/riscv_xip_xie.h b/riscv/riscv_xip_xie.h
index 66b7b1e..5a23a74 100644
--- a/riscv/riscv_xip_xie.h
+++ b/riscv/riscv_xip_xie.h
@@ -34,24 +34,24 @@
 class MipExternalWriteInterface {
  public:
   virtual ~MipExternalWriteInterface() = default;
-  virtual void set_meip(uint32_t value) = 0;
-  virtual void set_mtip(uint32_t value) = 0;
-  virtual void set_msip(uint32_t value) = 0;
-  virtual void set_ext_seip(uint32_t value) = 0;
+  virtual void set_meip(uint64_t value) = 0;
+  virtual void set_mtip(uint64_t value) = 0;
+  virtual void set_msip(uint64_t value) = 0;
+  virtual void set_ext_seip(uint64_t value) = 0;
 };
 
 // xip - x mode interrupt pending registers.
 
 class RiscVMIp : public MipExternalWriteInterface,
-                 public RiscVSimpleCsr<uint32_t> {
+                 public RiscVSimpleCsr<uint64_t> {
  public:
   // Read and Write masks.
-  static constexpr uint32_t kReadMask = 0b1011'1011'1011;
-  static constexpr uint32_t kWriteMask = 0b0011'0011'1011;
+  static constexpr uint64_t kReadMask = 0b1011'1011'1011;
+  static constexpr uint64_t kWriteMask = 0b0011'0011'1011;
 
   // Disable default constructor.
   RiscVMIp() = delete;
-  RiscVMIp(uint32_t initial_value, ArchState* state);
+  RiscVMIp(uint64_t initial_value, ArchState* state);
   ~RiscVMIp() override = default;
 
   // RiscVSimpleCsr method overrides.
@@ -64,55 +64,55 @@
   bool meip() { return GetterHelper<11, 0b1>(); }
   bool seip() { return (GetterHelper<9, 0b1>()) || (ext_seip_ != 0); }
   bool ueip() { return GetterHelper<8, 0b1>(); }
-  void set_meip(uint32_t value) override { SetterHelper<11, 0b1>(value); }
-  void set_seip(uint32_t value) { SetterHelper<9, 0b1>(value); }
-  void set_ext_seip(uint32_t value) override { ext_seip_ = (value != 0) << 9; }
-  void set_ueip(uint32_t value) { SetterHelper<8, 0b1>(value); }
+  void set_meip(uint64_t value) override { SetterHelper<11, 0b1>(value); }
+  void set_seip(uint64_t value) { SetterHelper<9, 0b1>(value); }
+  void set_ext_seip(uint64_t value) override { ext_seip_ = (value != 0) << 9; }
+  void set_ueip(uint64_t value) { SetterHelper<8, 0b1>(value); }
 
   // X timer interrupt pending.
   bool mtip() { return GetterHelper<7, 0b1>(); }
   bool stip() { return GetterHelper<5, 0b1>(); }
   bool utip() { return GetterHelper<4, 0b1>(); }
-  void set_mtip(uint32_t value) override { SetterHelper<7, 0b1>(value); }
-  void set_stip(uint32_t value) { SetterHelper<5, 0b1>(value); }
-  void set_utip(uint32_t value) { SetterHelper<4, 0b1>(value); }
+  void set_mtip(uint64_t value) override { SetterHelper<7, 0b1>(value); }
+  void set_stip(uint64_t value) { SetterHelper<5, 0b1>(value); }
+  void set_utip(uint64_t value) { SetterHelper<4, 0b1>(value); }
 
   // X software interrupt pending.
   bool msip() { return GetterHelper<3, 0b1>(); }
   bool ssip() { return GetterHelper<1, 0b1>(); }
   bool usip() { return GetterHelper<0, 0b1>(); }
-  void set_msip(uint32_t value) override { SetterHelper<3, 0b1>(value); }
-  void set_ssip(uint32_t value) { SetterHelper<1, 0b1>(value); }
-  void set_usip(uint32_t value) { SetterHelper<0, 0b1>(value); }
+  void set_msip(uint64_t value) override { SetterHelper<3, 0b1>(value); }
+  void set_ssip(uint64_t value) { SetterHelper<1, 0b1>(value); }
+  void set_usip(uint64_t value) { SetterHelper<0, 0b1>(value); }
 
  private:
   // Template function to help implement the getters.
-  template <int Shift, uint32_t BitMask>
+  template <int Shift, uint64_t BitMask>
   inline int GetterHelper() {
-    return (GetUint32() >> Shift) & BitMask;
+    return (GetUint64() >> Shift) & BitMask;
   }
   // Template function to help implement the setters.
-  template <int Shift, uint32_t BitMask>
-  inline void SetterHelper(uint32_t value) {
+  template <int Shift, uint64_t BitMask>
+  inline void SetterHelper(uint64_t value) {
     uint64_t bit_value = value & BitMask;
     uint64_t new_value =
         (GetUint64() & ~(BitMask << Shift)) | (bit_value << Shift);
     Set(new_value);
   }
-  uint32_t ext_seip_ = 0;
+  uint64_t ext_seip_ = 0;
 };
 
 // The supervisor mode sip is an interface to mip. The visibility of mip bits
 // depends on the value of mideleg. Delegated interrupts bits are readable and
 // writable in sip as they would be in mip.
-class RiscVSIp : public RiscVSimpleCsr<uint32_t> {
+class RiscVSIp : public RiscVSimpleCsr<uint64_t> {
  public:
   // Read and Write masks.
-  static constexpr uint32_t kReadMask = 0b1011'1011'1011;
-  static constexpr uint32_t kWriteMask = 0b0011'0011'0011;
-  static constexpr uint32_t kMBitMask = 0b1000'1000'1000;
-  static constexpr uint32_t kSBitMask = 0b0010'0010'0010;
-  static constexpr uint32_t kUBitMask = 0b0001'0001'0001;
+  static constexpr uint64_t kReadMask = 0b1011'1011'1011;
+  static constexpr uint64_t kWriteMask = 0b0011'0011'0011;
+  static constexpr uint64_t kMBitMask = 0b1000'1000'1000;
+  static constexpr uint64_t kSBitMask = 0b0010'0010'0010;
+  static constexpr uint64_t kUBitMask = 0b0001'0001'0001;
 
   // Disable default constructor.
   RiscVSIp() = delete;
@@ -127,34 +127,34 @@
 
   // X external interrupt pending.
   bool meip() {
-    return mip_->meip() && (mideleg_->AsUint32() & 0b1000'0000'0000) != 0;
+    return mip_->meip() && (mideleg_->AsUint64() & 0b1000'0000'0000) != 0;
   }
   bool seip() { return mip_->seip(); }
   bool ueip() { return mip_->ueip(); }
   void set_meip(uint32_t value) {
-    if ((mideleg_->AsUint32() & 0b1000'0000'0000) != 0) mip_->set_meip(value);
+    if ((mideleg_->AsUint64() & 0b1000'0000'0000) != 0) mip_->set_meip(value);
   }
   void set_seip(uint32_t value) { mip_->set_seip(value); }
   void set_ueip(uint32_t value) { mip_->set_ueip(value); }
 
   // X timer interrupt pending.
   bool mtip() {
-    return mip_->mtip() && (mideleg_->AsUint32() & 0b1000'0000) != 0;
+    return mip_->mtip() && (mideleg_->AsUint64() & 0b1000'0000) != 0;
   }
   bool stip() { return mip_->stip(); }
   bool utip() { return mip_->utip(); }
   void set_mtip(uint32_t value) {
-    if ((mideleg_->AsUint32() & 0b1000'0000) != 0) mip_->set_mtip(value);
+    if ((mideleg_->AsUint64() & 0b1000'0000) != 0) mip_->set_mtip(value);
   }
   void set_stip(uint32_t value) { mip_->set_stip(value); }
   void set_utip(uint32_t value) { mip_->set_utip(value); }
 
   // X software interrupt pending.
-  bool msip() { return mip_->msip() && (mideleg_->AsUint32() & 0b1000) != 0; }
+  bool msip() { return mip_->msip() && (mideleg_->AsUint64() & 0b1000) != 0; }
   bool ssip() { return mip_->ssip(); }
   bool usip() { return mip_->usip(); }
   void set_msip(uint32_t value) {
-    if ((mideleg_->AsUint32() & 0b1000) != 0) mip_->set_msip(value);
+    if ((mideleg_->AsUint64() & 0b1000) != 0) mip_->set_msip(value);
   }
   void set_ssip(uint32_t value) { mip_->set_ssip(value); }
   void set_usip(uint32_t value) { mip_->set_usip(value); }
@@ -166,15 +166,15 @@
 
 // xie - x mode interrupt enable registers.
 
-class RiscVMIe : public RiscVSimpleCsr<uint32_t> {
+class RiscVMIe : public RiscVSimpleCsr<uint64_t> {
  public:
   // Read and Write masks.
-  static constexpr uint32_t kReadMask = 0b1011'1011'1011;
-  static constexpr uint32_t kWriteMask = 0b1011'1011'1011;
+  static constexpr uint64_t kReadMask = 0b1011'1011'1011;
+  static constexpr uint64_t kWriteMask = 0b1011'1011'1011;
 
   // Disable default constructor.
   RiscVMIe() = delete;
-  RiscVMIe(uint32_t initial_value, ArchState* state);
+  RiscVMIe(uint64_t initial_value, ArchState* state);
   ~RiscVMIe() override = default;
 
   // RiscVSimpleCsr method overrides.
@@ -185,35 +185,35 @@
   bool meie() { return GetterHelper<11, 0b1>(); }
   bool seie() { return GetterHelper<9, 0b1>(); }
   bool ueie() { return GetterHelper<8, 0b1>(); }
-  void set_meie(uint32_t value) { SetterHelper<11, 0b1>(value); }
-  void set_seie(uint32_t value) { SetterHelper<9, 0b1>(value); }
-  void set_ueie(uint32_t value) { SetterHelper<8, 0b1>(value); }
+  void set_meie(uint64_t value) { SetterHelper<11, 0b1>(value); }
+  void set_seie(uint64_t value) { SetterHelper<9, 0b1>(value); }
+  void set_ueie(uint64_t value) { SetterHelper<8, 0b1>(value); }
 
   // X timer interrupt pending.
   bool mtie() { return GetterHelper<7, 0b1>(); }
   bool stie() { return GetterHelper<5, 0b1>(); }
   bool utie() { return GetterHelper<4, 0b1>(); }
-  void set_mtie(uint32_t value) { SetterHelper<7, 0b1>(value); }
-  void set_stie(uint32_t value) { SetterHelper<5, 0b1>(value); }
-  void set_utie(uint32_t value) { SetterHelper<4, 0b1>(value); }
+  void set_mtie(uint64_t value) { SetterHelper<7, 0b1>(value); }
+  void set_stie(uint64_t value) { SetterHelper<5, 0b1>(value); }
+  void set_utie(uint64_t value) { SetterHelper<4, 0b1>(value); }
 
   // X software interrupt pending.
   bool msie() { return GetterHelper<3, 0b1>(); }
   bool ssie() { return GetterHelper<1, 0b1>(); }
   bool usie() { return GetterHelper<0, 0b1>(); }
-  void set_msie(uint32_t value) { SetterHelper<3, 0b1>(value); }
-  void set_ssie(uint32_t value) { SetterHelper<1, 0b1>(value); }
-  void set_usie(uint32_t value) { SetterHelper<0, 0b1>(value); }
+  void set_msie(uint64_t value) { SetterHelper<3, 0b1>(value); }
+  void set_ssie(uint64_t value) { SetterHelper<1, 0b1>(value); }
+  void set_usie(uint64_t value) { SetterHelper<0, 0b1>(value); }
 
  private:
   // Template function to help implement the getters.
-  template <int Shift, uint32_t BitMask>
+  template <int Shift, uint64_t BitMask>
   inline int GetterHelper() {
-    return (GetUint32() >> Shift) & BitMask;
+    return (GetUint64() >> Shift) & BitMask;
   }
   // Template function to help implement the setters.
-  template <int Shift, uint32_t BitMask>
-  inline void SetterHelper(uint32_t value) {
+  template <int Shift, uint64_t BitMask>
+  inline void SetterHelper(uint64_t value) {
     uint64_t bit_value = value & BitMask;
     uint64_t new_value =
         (GetUint64() & ~(BitMask << Shift)) | (bit_value << Shift);
@@ -222,11 +222,11 @@
 };
 
 // The supervisor sie is an interface to the mie.
-class RiscVSIe : public RiscVSimpleCsr<uint32_t> {
+class RiscVSIe : public RiscVSimpleCsr<uint64_t> {
  public:
   // Read and Write masks.
-  static constexpr uint32_t kReadMask = 0b1011'1011'1011;
-  static constexpr uint32_t kWriteMask = 0b1011'1011'1011;
+  static constexpr uint64_t kReadMask = 0b1011'1011'1011;
+  static constexpr uint64_t kWriteMask = 0b1011'1011'1011;
 
   // Disable default constructor.
   RiscVSIe() = delete;
@@ -241,37 +241,37 @@
 
   // X external interrupt pending.
   bool meie() {
-    return mie_->meie() && (mideleg_->AsUint32() & 0b1000'0000'0000) != 0;
+    return mie_->meie() && (mideleg_->AsUint64() & 0b1000'0000'0000) != 0;
   }
   bool seie() { return mie_->seie(); }
   bool ueie() { return mie_->ueie(); }
-  void set_meie(uint32_t value) {
-    if ((mideleg_->AsUint32() & 0b1000'0000'0000) != 0) mie_->set_meie(value);
+  void set_meie(uint64_t value) {
+    if ((mideleg_->AsUint64() & 0b1000'0000'0000) != 0) mie_->set_meie(value);
   }
-  void set_seie(uint32_t value) { mie_->set_seie(value); }
-  void set_ueie(uint32_t value) { mie_->set_ueie(value); }
+  void set_seie(uint64_t value) { mie_->set_seie(value); }
+  void set_ueie(uint64_t value) { mie_->set_ueie(value); }
 
   // X timer interrupt pending.
   bool mtie() {
-    return mie_->mtie() && (mideleg_->AsUint32() & 0b1000'0000) != 0;
+    return mie_->mtie() && (mideleg_->AsUint64() & 0b1000'0000) != 0;
   }
   bool stie() { return mie_->stie(); }
   bool utie() { return mie_->utie(); }
-  void set_mtie(uint32_t value) {
-    if ((mideleg_->AsUint32() & 0b1000'0000) != 0) mie_->set_mtie(value);
+  void set_mtie(uint64_t value) {
+    if ((mideleg_->AsUint64() & 0b1000'0000) != 0) mie_->set_mtie(value);
   }
-  void set_stie(uint32_t value) { mie_->set_stie(value); }
-  void set_utie(uint32_t value) { mie_->set_utie(value); }
+  void set_stie(uint64_t value) { mie_->set_stie(value); }
+  void set_utie(uint64_t value) { mie_->set_utie(value); }
 
   // X software interrupt pending.
-  bool msie() { return mie_->msie() && (mideleg_->AsUint32() & 0b1000) != 0; }
+  bool msie() { return mie_->msie() && (mideleg_->AsUint64() & 0b1000) != 0; }
   bool ssie() { return mie_->ssie(); }
   bool usie() { return mie_->usie(); }
-  void set_msie(uint32_t value) {
-    if ((mideleg_->AsUint32() & 0b1000) != 0) mie_->set_msie(value);
+  void set_msie(uint64_t value) {
+    if ((mideleg_->AsUint64() & 0b1000) != 0) mie_->set_msie(value);
   }
-  void set_ssie(uint32_t value) { mie_->set_ssie(value); }
-  void set_usie(uint32_t value) { mie_->set_usie(value); }
+  void set_ssie(uint64_t value) { mie_->set_ssie(value); }
+  void set_usie(uint64_t value) { mie_->set_usie(value); }
 
  private:
   RiscVMIe* mie_;
diff --git a/riscv/test/riscv32_bitmanip_instructions_test.cc b/riscv/test/riscv32_bitmanip_instructions_test.cc
index a7737b0..a679ba3 100644
--- a/riscv/test/riscv32_bitmanip_instructions_test.cc
+++ b/riscv/test/riscv32_bitmanip_instructions_test.cc
@@ -538,7 +538,7 @@
     T val1 = absl::Uniform(absl::IntervalClosed, bitgen_,
                            std::numeric_limits<T>::min(),
                            std::numeric_limits<T>::max());
-    T val2 = absl::Uniform(absl::IntervalClosed, bitgen_, 0, 32);
+    T val2 = absl::Uniform(absl::IntervalClosed, bitgen_, 0, 31);
     SetRegisterValues<uint32_t>({{kX1, val1}, {kX2, val2}});
     instruction_->Execute(nullptr);
     EXPECT_EQ(GetRegisterValue<uint32_t>(kX3), val1 | (1 << val2));