Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:58

0001 //===-- RegisterValue.h -----------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_UTILITY_REGISTERVALUE_H
0010 #define LLDB_UTILITY_REGISTERVALUE_H
0011 
0012 #include "lldb/Utility/Endian.h"
0013 #include "lldb/Utility/Scalar.h"
0014 #include "lldb/Utility/Status.h"
0015 #include "lldb/lldb-enumerations.h"
0016 #include "lldb/lldb-types.h"
0017 #include "llvm/ADT/APInt.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include <cstdint>
0021 #include <cstring>
0022 #include <utility>
0023 
0024 namespace lldb_private {
0025 class DataExtractor;
0026 class Stream;
0027 struct RegisterInfo;
0028 
0029 class RegisterValue {
0030 public:
0031   enum {
0032     // What we can reasonably put on the stack, big enough to support up to 256
0033     // byte AArch64 SVE.
0034     kTypicalRegisterByteSize = 256u,
0035     // Anything else we'll heap allocate storage for it.
0036     // 256x256 to support 256 byte AArch64 SME's array storage (ZA) register.
0037     // Which is a square of vector length x vector length.
0038     kMaxRegisterByteSize = 256u * 256u,
0039   };
0040 
0041   typedef llvm::SmallVector<uint8_t, kTypicalRegisterByteSize> BytesContainer;
0042 
0043   enum Type {
0044     eTypeInvalid,
0045     eTypeUInt8,
0046     eTypeUInt16,
0047     eTypeUInt32,
0048     eTypeUInt64,
0049     eTypeUInt128,
0050     eTypeFloat,
0051     eTypeDouble,
0052     eTypeLongDouble,
0053     eTypeBytes
0054   };
0055 
0056   RegisterValue() : m_scalar(static_cast<unsigned long>(0)) {}
0057 
0058   explicit RegisterValue(uint8_t inst) : m_type(eTypeUInt8) { m_scalar = inst; }
0059 
0060   explicit RegisterValue(uint16_t inst) : m_type(eTypeUInt16) {
0061     m_scalar = inst;
0062   }
0063 
0064   explicit RegisterValue(uint32_t inst) : m_type(eTypeUInt32) {
0065     m_scalar = inst;
0066   }
0067 
0068   explicit RegisterValue(uint64_t inst) : m_type(eTypeUInt64) {
0069     m_scalar = inst;
0070   }
0071 
0072   explicit RegisterValue(llvm::APInt inst) : m_type(eTypeUInt128) {
0073     m_scalar = llvm::APInt(std::move(inst));
0074   }
0075 
0076   explicit RegisterValue(float value) : m_type(eTypeFloat) { m_scalar = value; }
0077 
0078   explicit RegisterValue(double value) : m_type(eTypeDouble) {
0079     m_scalar = value;
0080   }
0081 
0082   explicit RegisterValue(long double value) : m_type(eTypeLongDouble) {
0083     m_scalar = value;
0084   }
0085 
0086   explicit RegisterValue(llvm::ArrayRef<uint8_t> bytes,
0087                          lldb::ByteOrder byte_order) {
0088     SetBytes(bytes.data(), bytes.size(), byte_order);
0089   }
0090 
0091   RegisterValue::Type GetType() const { return m_type; }
0092 
0093   bool CopyValue(const RegisterValue &rhs);
0094 
0095   void SetType(RegisterValue::Type type) { m_type = type; }
0096 
0097   RegisterValue::Type SetType(const RegisterInfo &reg_info);
0098 
0099   bool GetData(DataExtractor &data) const;
0100 
0101   // Copy the register value from this object into a buffer in "dst" and obey
0102   // the "dst_byte_order" when copying the data. Also watch out in case
0103   // "dst_len" is longer or shorter than the register value described by
0104   // "reg_info" and only copy the least significant bytes of the register
0105   // value, or pad the destination with zeroes if the register byte size is
0106   // shorter that "dst_len" (all while correctly abiding the "dst_byte_order").
0107   // Returns the number of bytes copied into "dst".
0108   uint32_t GetAsMemoryData(const RegisterInfo &reg_info, void *dst,
0109                            uint32_t dst_len, lldb::ByteOrder dst_byte_order,
0110                            Status &error) const;
0111 
0112   uint32_t SetFromMemoryData(const RegisterInfo &reg_info, const void *src,
0113                              uint32_t src_len, lldb::ByteOrder src_byte_order,
0114                              Status &error);
0115 
0116   bool GetScalarValue(Scalar &scalar) const;
0117 
0118   uint8_t GetAsUInt8(uint8_t fail_value = UINT8_MAX,
0119                      bool *success_ptr = nullptr) const {
0120     if (m_type == eTypeUInt8) {
0121       if (success_ptr)
0122         *success_ptr = true;
0123       return m_scalar.UChar(fail_value);
0124     }
0125     if (success_ptr)
0126       *success_ptr = true;
0127     return fail_value;
0128   }
0129 
0130   uint16_t GetAsUInt16(uint16_t fail_value = UINT16_MAX,
0131                        bool *success_ptr = nullptr) const;
0132 
0133   uint32_t GetAsUInt32(uint32_t fail_value = UINT32_MAX,
0134                        bool *success_ptr = nullptr) const;
0135 
0136   uint64_t GetAsUInt64(uint64_t fail_value = UINT64_MAX,
0137                        bool *success_ptr = nullptr) const;
0138 
0139   llvm::APInt GetAsUInt128(const llvm::APInt &fail_value,
0140                            bool *success_ptr = nullptr) const;
0141 
0142   float GetAsFloat(float fail_value = 0.0f, bool *success_ptr = nullptr) const;
0143 
0144   double GetAsDouble(double fail_value = 0.0,
0145                      bool *success_ptr = nullptr) const;
0146 
0147   long double GetAsLongDouble(long double fail_value = 0.0,
0148                               bool *success_ptr = nullptr) const;
0149 
0150   void SetValueToInvalid() { m_type = eTypeInvalid; }
0151 
0152   bool ClearBit(uint32_t bit);
0153 
0154   bool SetBit(uint32_t bit);
0155 
0156   bool operator==(const RegisterValue &rhs) const;
0157 
0158   bool operator!=(const RegisterValue &rhs) const;
0159 
0160   void operator=(uint8_t uint) {
0161     m_type = eTypeUInt8;
0162     m_scalar = uint;
0163   }
0164 
0165   void operator=(uint16_t uint) {
0166     m_type = eTypeUInt16;
0167     m_scalar = uint;
0168   }
0169 
0170   void operator=(uint32_t uint) {
0171     m_type = eTypeUInt32;
0172     m_scalar = uint;
0173   }
0174 
0175   void operator=(uint64_t uint) {
0176     m_type = eTypeUInt64;
0177     m_scalar = uint;
0178   }
0179 
0180   void operator=(llvm::APInt uint) {
0181     m_type = eTypeUInt128;
0182     m_scalar = llvm::APInt(std::move(uint));
0183   }
0184 
0185   void operator=(float f) {
0186     m_type = eTypeFloat;
0187     m_scalar = f;
0188   }
0189 
0190   void operator=(double f) {
0191     m_type = eTypeDouble;
0192     m_scalar = f;
0193   }
0194 
0195   void operator=(long double f) {
0196     m_type = eTypeLongDouble;
0197     m_scalar = f;
0198   }
0199 
0200   void SetUInt8(uint8_t uint) {
0201     m_type = eTypeUInt8;
0202     m_scalar = uint;
0203   }
0204 
0205   void SetUInt16(uint16_t uint) {
0206     m_type = eTypeUInt16;
0207     m_scalar = uint;
0208   }
0209 
0210   void SetUInt32(uint32_t uint, Type t = eTypeUInt32) {
0211     m_type = t;
0212     m_scalar = uint;
0213   }
0214 
0215   void SetUInt64(uint64_t uint, Type t = eTypeUInt64) {
0216     m_type = t;
0217     m_scalar = uint;
0218   }
0219 
0220   void SetUInt128(llvm::APInt uint) {
0221     m_type = eTypeUInt128;
0222     m_scalar = std::move(uint);
0223   }
0224 
0225   bool SetUInt(uint64_t uint, uint32_t byte_size);
0226 
0227   void SetFloat(float f) {
0228     m_type = eTypeFloat;
0229     m_scalar = f;
0230   }
0231 
0232   void SetDouble(double f) {
0233     m_type = eTypeDouble;
0234     m_scalar = f;
0235   }
0236 
0237   void SetLongDouble(long double f) {
0238     m_type = eTypeLongDouble;
0239     m_scalar = f;
0240   }
0241 
0242   void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order);
0243 
0244   bool SignExtend(uint32_t sign_bitpos);
0245 
0246   Status SetValueFromString(const RegisterInfo *reg_info,
0247                             llvm::StringRef value_str);
0248   Status SetValueFromString(const RegisterInfo *reg_info,
0249                             const char *value_str) = delete;
0250 
0251   Status SetValueFromData(const RegisterInfo &reg_info, DataExtractor &data,
0252                           lldb::offset_t offset, bool partial_data_ok);
0253 
0254   const void *GetBytes() const;
0255 
0256   lldb::ByteOrder GetByteOrder() const {
0257     if (m_type == eTypeBytes)
0258       return buffer.byte_order;
0259     return endian::InlHostByteOrder();
0260   }
0261 
0262   uint32_t GetByteSize() const;
0263 
0264   void Clear();
0265 
0266 protected:
0267   RegisterValue::Type m_type = eTypeInvalid;
0268   Scalar m_scalar;
0269 
0270   struct RegisterValueBuffer {
0271     // Start at max stack storage size. Move to the heap for anything larger.
0272     RegisterValueBuffer() : bytes(kTypicalRegisterByteSize) {}
0273 
0274     mutable BytesContainer bytes;
0275     lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
0276   } buffer;
0277 };
0278 
0279 } // namespace lldb_private
0280 
0281 #endif // LLDB_UTILITY_REGISTERVALUE_H