Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/include/lldb/Target/RegisterFlags.h
Line
Count
Source
1
//===-- RegisterFlags.h -----------------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLDB_TARGET_REGISTERFLAGS_H
10
#define LLDB_TARGET_REGISTERFLAGS_H
11
12
#include "lldb/Utility/Log.h"
13
14
namespace lldb_private {
15
16
class RegisterFlags {
17
public:
18
  class Field {
19
  public:
20
    Field(std::string name, unsigned start, unsigned end)
21
284
        : m_name(std::move(name)), m_start(start), m_end(end) {
22
284
      assert(m_start <= m_end && "Start bit must be <= end bit.");
23
284
    }
24
25
    /// Get size of the field in bits. Will always be at least 1.
26
306
    unsigned GetSizeInBits() const { return m_end - m_start + 1; }
27
28
    /// A mask that covers all bits of the field.
29
72
    uint64_t GetMask() const {
30
72
      return (((uint64_t)1 << (GetSizeInBits())) - 1) << m_start;
31
72
    }
32
33
    /// Extract value of the field from a whole register value.
34
69
    uint64_t GetValue(uint64_t register_value) const {
35
69
      return (register_value & GetMask()) >> m_start;
36
69
    }
37
38
93
    const std::string &GetName() const { return m_name; }
39
2.01k
    unsigned GetStart() const { return m_start; }
40
608
    unsigned GetEnd() const { return m_end; }
41
    bool Overlaps(const Field &other) const;
42
    void log(Log *log) const;
43
44
    /// Return the number of bits between this field and the other, that are not
45
    /// covered by either field.
46
    unsigned PaddingDistance(const Field &other) const;
47
48
601
    bool operator<(const Field &rhs) const {
49
601
      return GetStart() < rhs.GetStart();
50
601
    }
51
52
    bool operator==(const Field &rhs) const {
53
      return (m_name == rhs.m_name) && (m_start == rhs.m_start) &&
54
             (m_end == rhs.m_end);
55
    }
56
57
  private:
58
    std::string m_name;
59
    /// Start/end bit positions. Where start N, end N means a single bit
60
    /// field at position N. We expect that start <= end. Bit positions begin
61
    /// at 0.
62
    /// Start is the LSB, end is the MSB.
63
    unsigned m_start;
64
    unsigned m_end;
65
  };
66
67
  /// This assumes that:
68
  /// * There is at least one field.
69
  /// * The fields are sorted in descending order.
70
  /// Gaps are allowed, they will be filled with anonymous padding fields.
71
  RegisterFlags(std::string id, unsigned size,
72
                const std::vector<Field> &fields);
73
74
  // Reverse the order of the fields, keeping their values the same.
75
  // For example a field from bit 31 to 30 with value 0b10 will become bits
76
  // 1 to 0, with the same 0b10 value.
77
  // Use this when you are going to show the register using a bitfield struct
78
  // type. If that struct expects MSB first and you are on little endian where
79
  // LSB would be first, this corrects that (and vice versa for big endian).
80
24
  template <typename T> T ReverseFieldOrder(T value) const {
81
24
    T ret = 0;
82
24
    unsigned shift = 0;
83
60
    for (auto field : GetFields()) {
84
60
      ret |= field.GetValue(value) << shift;
85
60
      shift += field.GetSizeInBits();
86
60
    }
87
88
24
    return ret;
89
24
  }
unsigned int lldb_private::RegisterFlags::ReverseFieldOrder<unsigned int>(unsigned int) const
Line
Count
Source
80
19
  template <typename T> T ReverseFieldOrder(T value) const {
81
19
    T ret = 0;
82
19
    unsigned shift = 0;
83
49
    for (auto field : GetFields()) {
84
49
      ret |= field.GetValue(value) << shift;
85
49
      shift += field.GetSizeInBits();
86
49
    }
87
88
19
    return ret;
89
19
  }
unsigned long long lldb_private::RegisterFlags::ReverseFieldOrder<unsigned long long>(unsigned long long) const
Line
Count
Source
80
5
  template <typename T> T ReverseFieldOrder(T value) const {
81
5
    T ret = 0;
82
5
    unsigned shift = 0;
83
11
    for (auto field : GetFields()) {
84
11
      ret |= field.GetValue(value) << shift;
85
11
      shift += field.GetSizeInBits();
86
11
    }
87
88
5
    return ret;
89
5
  }
90
91
57
  const std::vector<Field> &GetFields() const { return m_fields; }
92
1
  const std::string &GetID() const { return m_id; }
93
55
  unsigned GetSize() const { return m_size; }
94
  void log(Log *log) const;
95
96
  /// Produce a text table showing the layout of all the fields. Unnamed/padding
97
  /// fields will be included, with only their positions shown.
98
  /// max_width will be the width in characters of the terminal you are
99
  /// going to print the table to. If the table would exceed this width, it will
100
  /// be split into many tables as needed.
101
  std::string AsTable(uint32_t max_width) const;
102
103
private:
104
  const std::string m_id;
105
  /// Size in bytes
106
  const unsigned m_size;
107
  std::vector<Field> m_fields;
108
};
109
110
} // namespace lldb_private
111
112
#endif // LLDB_TARGET_REGISTERFLAGS_H