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