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