1 # Reads OpenPOWER ISA pages from http://libre-riscv.org/openpower/isa
2 """OpenPOWER ISA page parser
4 returns an OrderedDict of namedtuple "Ops" containing details of all
5 instructions listed in markdown files.
7 format must be strictly as follows (no optional sections) including whitespace:
15 if L = 0 then a <- [0]*32 || (RA)[32:63]
16 b <- [0]*32 || (RB)[32:63]
19 if a <u b then c <- 0b100
20 else if a >u b then c <- 0b010
22 CR[4*BF+32:4*BF+35] <- c || XER[SO]
24 Special Registers Altered:
35 * instruction registerlist
36 * instruction registerlist
38 4-space-indented pseudo-code
39 4-space-indented pseudo-code
41 Special Registers Altered:
42 4-space-indented register description
48 from collections
import namedtuple
, OrderedDict
52 op
= namedtuple("Ops", ("desc", "form", "opcode", "regs", "pcode", "sregs"))
55 fdir
= os
.path
.abspath(os
.path
.dirname(__file__
))
56 fdir
= os
.path
.split(fdir
)[0]
57 fdir
= os
.path
.split(fdir
)[0]
58 fdir
= os
.path
.split(fdir
)[0]
59 fdir
= os
.path
.split(fdir
)[0]
60 return os
.path
.join(fdir
, "libreriscv", "openpower", "isa")
65 self
.instr
= OrderedDict()
67 for pth
in os
.listdir(os
.path
.join(get_isa_dir())):
68 print (get_isa_dir(), pth
)
69 assert pth
.endswith(".mdwn"), "only %s in isa dir" % pth
72 def read_file(self
, fname
):
73 fname
= os
.path
.join(get_isa_dir(), fname
)
74 with
open(fname
) as f
:
78 l
= lines
.pop(0).rstrip() # get first line
82 assert l
.startswith('#'), ("# not found in line %s" % l
)
83 d
['desc'] = l
[1:].strip()
86 l
= lines
.pop(0).strip()
88 assert len(l
) == 0, ("blank line not found %s" % l
)
91 l
= lines
.pop(0).strip()
92 assert l
.endswith('-Form'), ("line with -Form expected %s" % l
)
93 d
['form'] = l
.split('-')[0]
96 l
= lines
.pop(0).strip()
97 assert len(l
) == 0, ("blank line not found %s" % l
)
102 l
= lines
.pop(0).strip()
103 if len(l
) == 0: break
104 assert l
.startswith('*'), ("* not found in line %s" % l
)
105 l
= l
[1:].split(' ') # lose star
106 l
= filter(lambda x
: len(x
) != 0, l
) # strip blanks
113 l
= lines
.pop(0).rstrip()
114 if len(l
) == 0: break
115 assert l
.startswith(' '), ("4spcs not found in line %s" % l
)
116 l
= l
[4:] # lose 4 spaces
120 # "Special Registers Altered" expected
121 l
= lines
.pop(0).rstrip()
122 assert l
.startswith("Special"), ("special not found %s" % l
)
124 # whitespace expected
125 l
= lines
.pop(0).strip()
126 assert len(l
) == 0, ("blank line not found %s" % l
)
131 l
= lines
.pop(0).rstrip()
132 if len(l
) == 0: break
133 assert l
.startswith(' '), ("4spcs not found in line %s" % l
)
134 l
= l
[4:] # lose 4 spaces
142 # expect and drop whitespace
144 l
= lines
.pop(0).rstrip()
145 if len(l
) != 0: break
147 def add_op(self
, o
, d
):
148 opcode
, regs
= o
[0], o
[1:]
151 op
['opcode'] = opcode
152 self
.instr
[opcode
] = op
154 # create list of instructions by form
156 fl
= self
.forms
.get(form
, [])
157 self
.forms
[form
] = fl
+ [opcode
]
159 def pprint_ops(self
):
160 for k
, v
in self
.instr
.items():
161 print ("# %s %s" % (v
['opcode'], v
['desc']))
162 print ("Form: %s Regs: %s" % (v
['form'], v
['regs']))
163 print ('\n'.join(map(lambda x
: " %s" % x
, v
['pcode'])))
165 print ('\n'.join(map(lambda x
: " %s" % x
, v
['sregs'])))
167 for k
, v
in isa
.forms
.items():
170 if __name__
== '__main__':