xref: /llvm-project/lldb/examples/customization/bin-utils/binutils.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"Collection of tools for displaying bit representation of numbers." ""
2
3
4def binary(n, width=None):
5    """
6    Return a list of (0|1)'s for the binary representation of n where n >= 0.
7    If you specify a width, it must be > 0, otherwise it is ignored.  The list
8    could be padded with 0 bits if width is specified.
9    """
10    l = []
11    if width and width <= 0:
12        width = None
13    while n > 0:
14        l.append(1 if n & 1 else 0)
15        n = n >> 1
16
17    if width:
18        for i in range(width - len(l)):
19            l.append(0)
20
21    l.reverse()
22    return l
23
24
25def twos_complement(n, width):
26    """
27    Return a list of (0|1)'s for the binary representation of a width-bit two's
28    complement numeral system of an integer n which may be negative.
29    """
30    val = 2 ** (width - 1)
31    if n >= 0:
32        if n > (val - 1):
33            return None
34        # It is safe to represent n with width-bits.
35        return binary(n, width)
36
37    if n < 0:
38        if abs(n) > val:
39            return None
40        # It is safe to represent n (a negative int) with width-bits.
41        return binary(val * 2 - abs(n))
42
43
44# print binary(0xABCD)
45# [1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1]
46# print binary(0x1F, 8)
47# [0, 0, 0, 1, 1, 1, 1, 1]
48# print twos_complement(-5, 4)
49# [1, 0, 1, 1]
50# print twos_complement(7, 4)
51# [0, 1, 1, 1]
52# print binary(7)
53# [1, 1, 1]
54# print twos_complement(-5, 64)
55# [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1]
56
57
58def positions(width):
59    """Helper function returning a list describing the bit positions.
60    Bit positions greater than 99 are truncated to 2 digits, for example,
61    100 -> 00 and 127 -> 27."""
62    return ["{0:2}".format(i)[-2:] for i in reversed(range(width))]
63
64
65def utob(debugger, command_line, result, dict):
66    """Convert the unsigned integer to print its binary representation.
67    args[0] (mandatory) is the unsigned integer to be converted
68    args[1] (optional) is the bit width of the binary representation
69    args[2] (optional) if specified, turns on verbose printing"""
70    args = command_line.split()
71    try:
72        n = int(args[0], 0)
73        width = None
74        if len(args) > 1:
75            width = int(args[1], 0)
76            if width < 0:
77                width = 0
78    except:
79        print(utob.__doc__)
80        return
81
82    if len(args) > 2:
83        verbose = True
84    else:
85        verbose = False
86
87    bits = binary(n, width)
88    if not bits:
89        print("insufficient width value: %d" % width)
90        return
91    if verbose and width > 0:
92        pos = positions(width)
93        print(" " + " ".join(pos))
94    print(" %s" % str(bits))
95
96
97def itob(debugger, command_line, result, dict):
98    """Convert the integer to print its two's complement representation.
99    args[0] (mandatory) is the integer to be converted
100    args[1] (mandatory) is the bit width of the two's complement representation
101    args[2] (optional) if specified, turns on verbose printing"""
102    args = command_line.split()
103    try:
104        n = int(args[0], 0)
105        width = int(args[1], 0)
106        if width < 0:
107            width = 0
108    except:
109        print(itob.__doc__)
110        return
111
112    if len(args) > 2:
113        verbose = True
114    else:
115        verbose = False
116
117    bits = twos_complement(n, width)
118    if not bits:
119        print("insufficient width value: %d" % width)
120        return
121    if verbose and width > 0:
122        pos = positions(width)
123        print(" " + " ".join(pos))
124    print(" %s" % str(bits))
125