sorting out bigendian/littleendian including in qemu
[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 import sys
12
13 filedir = os.path.dirname(os.path.realpath(__file__))
14 memmap = os.path.join(filedir, "memmap")
15
16
17 class Program:
18 def __init__(self, instructions, bigendian):
19 self.bigendian = bigendian
20 if self.bigendian:
21 self.endian_fmt = "elf64-big"
22 self.obj_fmt = "-be"
23 self.ld_fmt = "-EB"
24 else:
25 self.ld_fmt = "-EL"
26 self.endian_fmt = "elf64-little"
27 self.obj_fmt = "-le"
28
29 if isinstance(instructions, str): # filename
30 self.binfile = open(instructions, "rb")
31 self.assembly = '' # noo disassemble number fiiive
32 print ("program", self.binfile)
33 else:
34 if isinstance(instructions, list):
35 instructions = '\n'.join(instructions)
36 self.assembly = instructions + '\n' # plus final newline
37 self._assemble()
38 self._instructions = list(self._get_instructions())
39
40 def __enter__(self):
41 return self
42
43 def __exit__(self, type, value, traceback):
44 self.close()
45
46 def _get_binary(self, elffile):
47 self.binfile = tempfile.NamedTemporaryFile(suffix=".bin")
48 args = ["powerpc64-linux-gnu-objcopy",
49 "-O", "binary",
50 "-I", self.endian_fmt,
51 elffile.name,
52 self.binfile.name]
53 subprocess.check_output(args)
54
55 def _link(self, ofile):
56 with tempfile.NamedTemporaryFile(suffix=".elf") as elffile:
57 args = ["powerpc64-linux-gnu-ld",
58 self.ld_fmt,
59 "-o", elffile.name,
60 "-T", memmap,
61 ofile.name]
62 subprocess.check_output(args)
63 self._get_binary(elffile)
64
65 def _assemble(self):
66 with tempfile.NamedTemporaryFile(suffix=".o") as outfile:
67 args = ["powerpc64-linux-gnu-as",
68 '-mpower9',
69 self.obj_fmt,
70 "-o",
71 outfile.name]
72 p = subprocess.Popen(args, stdin=subprocess.PIPE)
73 p.communicate(self.assembly.encode('utf-8'))
74 if p.wait() != 0:
75 print("Error in program:")
76 print(self.assembly)
77 sys.exit(1)
78 self._link(outfile)
79
80 def _get_instructions(self):
81 while True:
82 data = self.binfile.read(4)
83 if not data:
84 break
85 yield struct.unpack('<i', data)[0]
86
87 def generate_instructions(self):
88 yield from self._instructions
89
90 def reset(self):
91 self.binfile.seek(0)
92
93 def size(self):
94 curpos = self.binfile.tell()
95 self.binfile.seek(0, 2) # Seek to end of file
96 size = self.binfile.tell()
97 self.binfile.seek(curpos, 0)
98 return size
99
100 def close(self):
101 self.binfile.close()