1 # Based on GardenSnake - a parser generator demonstration program
2 # GardenSnake was released into the Public Domain by Andrew Dalke.
4 # Portions of this work are derived from Python's Grammar definition
5 # and may be covered under the Python copyright and license
7 # Andrew Dalke / Dalke Scientific Software, LLC
8 # 30 August 2006 / Cape Town, South Africa
10 # Modifications for inclusion in PLY distribution
12 from pprint
import pprint
14 from ply
import lex
, yacc
18 from openpower
.decoder
.power_decoder
import create_pdecode
19 from nmigen
.sim
import Simulator
, Delay
20 from nmigen
import Module
, Signal
22 from openpower
.decoder
.pseudo
.parser
import GardenSnakeCompiler
23 from openpower
.decoder
.selectable_int
import SelectableInt
, selectconcat
24 from openpower
.decoder
.isa
.caller
import GPR
, Mem
25 from openpower
.util
import log
28 ####### Test code #######
33 index <- (RS)[8*i:8*i+7]
34 RA <- [0]*56 || perm[0:7]
39 if index < 64 then index <- 0
50 index <- (RS)[8*i:8*i+7]
55 RA <- [0]*56|| perm[0:7]
62 if (RS)[63-n] = 0b1 then
72 else if a > EXTS(SI) then
81 in_range <- ((x | y) &
83 in_range <- (x + y) - (a + b)
88 src1 <- EXTZ((RA)[56:63])
90 in_range <- src21lo <= src1 & src1 <= src21hi
104 RT <- (RA) + EXTS(SI || [0]*16)
114 RT <- (load_data[56:63] || load_data[48:55]
115 || load_data[40:47] || load_data[32:39]
116 || load_data[24:31] || load_data[16:23]
117 || load_data[8:15] || load_data[0:7])
128 MEM(EA, 1) <- (RS)[56:63]
134 MEM(EA, 4) <- GPR(r)[32:63]
144 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
145 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
149 if RA = 0 then EA <- 0
151 if NB = 0 then n <- 32
159 GPR(r)[i:i+7] <- MEM(EA, 1)
161 if i = 64 then i <- 32
182 RT <- 0x0001_a000_0000_0000
220 prod[0:XLEN-1] <- MULS((RA)[XLEN/2:XLEN-1], (RB)[XLEN/2:XLEN-1])
221 RT[XLEN/2:XLEN-1] <- prod[0:(XLEN/2)-1]
222 RT[0:(XLEN/2)-1] <- undefined(prod[0:(XLEN/2)-1])
253 l
.append(1 if (num
& (1 << i
)) else 0)
258 def get_reg_hex(reg
):
259 return hex(reg
.value
)
262 def convert_to_pure_python(pcode
, helper
=False, filename
="string"):
264 gsc
= GardenSnakeCompiler(form
=None, incl_carry
=False, helper
=helper
)
266 tree
= gsc
.compile(pcode
, mode
="exec", filename
=filename
)
267 tree
= ast
.fix_missing_locations(tree
)
268 return astor
.to_source(tree
)
271 def convert_to_python(pcode
, form
, incl_carry
, helper
=False, filename
="string"):
274 gsc
= GardenSnakeCompiler(form
=form
, incl_carry
=incl_carry
, helper
=helper
)
276 tree
= gsc
.compile(pcode
, mode
="exec", filename
=filename
)
277 tree
= ast
.fix_missing_locations(tree
)
278 regsused
= {'read_regs': gsc
.parser
.read_regs
,
279 'write_regs': gsc
.parser
.write_regs
,
280 'uninit_regs': gsc
.parser
.uninit_regs
,
281 'special_regs': gsc
.parser
.special_regs
,
282 'op_fields': gsc
.parser
.op_fields
}
283 return astor
.to_source(tree
), regsused
286 def check_in_gitignore(output_file
):
287 gitignore_file
= os
.path
.join(os
.path
.dirname(output_file
), ".gitignore")
288 base_name
= os
.path
.basename(output_file
)
289 with
open(gitignore_file
, "r") as f
:
290 for l
in f
.readlines():
292 if "/" + base_name
== l
:
295 if base_name
.endswith(".py"):
297 raise ValueError(f
"generated output file not in .gitignore:\n"
298 f
"output file: {output_file}\n"
299 f
".gitignore file: {gitignore_file}")
304 gsc
= GardenSnakeCompiler(debug
=True)
309 gsc
.gpr
= GPR(None, None, None, gsc
.regfile
)
312 _compile
= gsc
.compile
314 tree
= _compile(code
, mode
="single", filename
="string")
315 tree
= ast
.fix_missing_locations(tree
)
319 log(astor
.dump_tree(tree
))
321 source
= astor
.to_source(tree
)
326 # Set up the GardenSnake run-time environment
329 print("-->", " ".join(map(str, args
)))
331 from openpower
.decoder
.helpers
import (EXTS64
, EXTZ64
, ROTL64
, ROTL32
, MASK
,
332 trunc_div
, trunc_rem
)
338 d
["trunc_div"] = trunc_div
339 d
["trunc_rem"] = trunc_rem
340 d
["SelectableInt"] = SelectableInt
341 d
["concat"] = selectconcat
344 d
["memassign"] = gsc
.mem
.memassign
347 gsc
.gpr
.set_form(form
)
348 getform
= gsc
.parser
.sd
.sigforms
[form
]._asdict
()
349 #print ("getform", form)
350 # for k, f in getform.items():
354 compiled_code
= compile(source
, mode
="exec", filename
="<string>")
358 instruction
= Signal(32)
360 m
.submodules
.decode
= decode
= gsc
.parser
.sd
361 comb
+= decode
.raw_opcode_in
.eq(instruction
)
368 log("0x%x" % (ins
& 0xffffffff))
370 # ask the decoder to decode this binary data (endian'd)
371 yield decode
.bigendian
.eq(0) # little / big?
372 yield instruction
.eq(ins
) # raw binary instr.
375 # uninitialised regs, drop them into dict for function
376 for rname
in gsc
.parser
.uninit_regs
:
377 d
[rname
] = SelectableInt(0, 64) # uninitialised (to zero)
378 log("uninitialised", rname
, hex(d
[rname
].value
))
380 # read regs, drop them into dict for function
381 for rname
in gsc
.parser
.read_regs
:
382 regidx
= yield getattr(decode
.sigforms
['X'], rname
)
383 d
[rname
] = gsc
.gpr
[regidx
] # contents of regfile
384 d
["_%s" % rname
] = regidx
# actual register value
385 log("read reg", rname
, regidx
, hex(d
[rname
].value
))
387 exec(compiled_code
, d
) # code gets executed here in dict "d"
390 log(d
.keys()) # shows the variables that may have been created
392 log(decode
.sigforms
['X'])
393 x
= yield decode
.sigforms
['X'].RS
394 ra
= yield decode
.sigforms
['X'].RA
395 rb
= yield decode
.sigforms
['X'].RB
396 log("RA", ra
, d
['RA'])
397 log("RB", rb
, d
['RB'])
400 for wname
in gsc
.parser
.write_regs
:
403 log("write regs", regidx
, wname
, d
[wname
], reg
)
404 gsc
.gpr
[regidx
] = d
[wname
]
406 sim
.add_process(process
)
407 with sim
.write_vcd("simulator.vcd", "simulator.gtkw",
408 traces
=decode
.ports()):
413 for i
in range(0, len(gsc
.mem
.mem
), 16):
416 hexstr
.append("%02x" % gsc
.mem
.mem
[i
+j
])
417 hexstr
= ' '.join(hexstr
)
418 log("mem %4x" % i
, hexstr
)
421 if __name__
== '__main__':