almost all tests work
[soc.git] / src / soc / simulator / program.py
1 import tempfile
2 import subprocess
3 import struct
4 import os
5
6 filedir = os.path.dirname(os.path.realpath(__file__))
7 memmap = os.path.join(filedir, "memmap")
8
9 bigendian = True
10 endian_fmt = "elf64-big"
11 obj_fmt = "-be"
12
13
14 class Program:
15 def __init__(self, instructions):
16 if isinstance(instructions, list):
17 instructions = '\n'.join(instructions)
18 self.assembly = instructions + '\n' # plus final newline
19 self._assemble()
20
21 def __enter__(self):
22 return self
23
24 def __exit__(self, type, value, traceback):
25 self.close()
26
27 def _get_binary(self, elffile):
28 self.binfile = tempfile.NamedTemporaryFile(suffix=".bin")
29 args = ["powerpc64-linux-gnu-objcopy",
30 "-O", "binary",
31 "-I", endian_fmt,
32 elffile.name,
33 self.binfile.name]
34 subprocess.check_output(args)
35
36 def _link(self, ofile):
37 with tempfile.NamedTemporaryFile(suffix=".elf") as elffile:
38 args = ["powerpc64-linux-gnu-ld",
39 "-o", elffile.name,
40 "-T", memmap,
41 ofile.name]
42 subprocess.check_output(args)
43 self._get_binary(elffile)
44
45 def _assemble(self):
46 with tempfile.NamedTemporaryFile(suffix=".o") as outfile:
47 args = ["powerpc64-linux-gnu-as",
48 obj_fmt,
49 "-o",
50 outfile.name]
51 p = subprocess.Popen(args, stdin=subprocess.PIPE)
52 p.communicate(self.assembly.encode('utf-8'))
53 assert(p.wait() == 0)
54 self._link(outfile)
55
56 def generate_instructions(self):
57 while True:
58 data = self.binfile.read(4)
59 if not data:
60 break
61 yield struct.unpack('<i', data)[0]
62
63 def reset(self):
64 self.binfile.seek(0)
65
66 def size(self):
67 curpos = self.binfile.tell()
68 self.binfile.seek(0, 2) # Seek to end of file
69 size = self.binfile.tell()
70 self.binfile.seek(curpos, 0)
71 return size
72
73 def close(self):
74 self.binfile.close()