History

Moved the Instruction class into the opcodes module. Moved the read* functions into the new utils module. Created an Instruction subclass for each instruction, placing the corresponding opcode value inside it.

David Boddie committed 9 years ago

Commit b833c111 parent 48fa6014 files · +952 −354Browse files

Unified · Split

4 files
  1. dis.py +3 −177
  2. docs/notes.txt +43 −0
  3. opcodes.py +808 −177
  4. utils.py +98 −0
dis.py+3−177
@@ -18,88 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. · 17 unmodified lines
18from struct import calcsize, pack, unpack18from struct import calcsize, pack, unpack
19 19
20import opcodes20import opcodes
21from utils import _read, read_B, read_C, read_OP, read_F, read_L, read_P, \
22 read_W
21 23
22XMAGIC = 0x0c803024XMAGIC = 0x0c8030
23SMAGIC = 0x0e172225SMAGIC = 0x0e1722
24 26
25def _read(f, format):
26
27 size = calcsize(format)
28 return unpack(format, f.read(size))[0]
29
30def read_B(f):
31 # byte, 8-bit unsigned
32 return unpack(">B", f.read(1))[0]
33
34def read_OP(f):
35
36 s = f.read(1)
37 v = unpack(">B", s)[0]
38
39 encoding = v & 0xc0
40
41 if encoding == 0x80:
42 s += f.read(1)
43 v = unpack(">H", s)[0] & 0x3fff
44 if v >= 0x2000:
45 v = v - 0x4000
46
47 elif encoding == 0xc0:
48 s += f.read(3)
49 v = unpack(">I", s)[0] & 0x3fffffff
50 if v >= 0x20000000:
51 v = v - 0x40000000
52 else:
53 # The top bit is clear, the next-to-top bit can be 0 or 1.
54 # -64 (0xc0) <= original value <= 63 (0x2f)
55 # -64 (0x40) <= encoded value <= 63 (0x2f)
56 if encoding != 0:
57 # The next-to-top bit is set meaning that
58 # -64 <= original value <= -1
59 v = v - 0x80
60
61 return v
62
63def read_W(f):
64 # 32-bit word
65 return unpack(">i", f.read(4))[0]
66
67def read_F(f):
68 # 64-bit float
69 return unpack(">d", f.read(8))[0]
70
71def read_L(f):
72 # 64-bit big integer
73 # Signed or unsigned? Assume signed for now.
74 return unpack(">q", f.read(8))[0]
75
76def read_P(f):
77 # 32-bit pointer
78 return unpack(">I", f.read(4))[0]
79
80def read_C(f):
81 # UTF-8 encoded string
82 s = ""
83 while True:
84 c = f.read(1)
85 if c == "\x00":
86 break
87 s += c
88
89 return s
90
91def read_SO(f):
92
93 return unpack(">H", f.read(2))[0]
94
95def read_SI(f):
96
97 return unpack(">h", f.read(2))[0]
98
99def read_LO(f):
100
101 return unpack(">i", f.read(4))[0]
102
103 27
104class DisError(Exception):28class DisError(Exception):
105 pass29 pass
@@ -167,7 +91,7 @@ class Dis: · 61 unmodified lines
167 i = 091 i = 0
168 92
169 while i < self.code_size:93 while i < self.code_size:
170 self.code.append(Instruction(f))94 self.code.append(opcodes.Instruction().read(f))
171 i += 195 i += 1
172 96
173 def read_types(self, f):97 def read_types(self, f):
@@ -291,104 +215,6 @@ class RuntimeFlag: · 117 unmodified lines
291 return self.value & flags != 0215 return self.value & flags != 0
292 216
293 217
294class Instruction:
295
296 def __init__(self, f):
297
298 self.opcode = read_B(f)
299 self.address_mode = read_B(f)
300
301 middle = self.address_mode & 0xc0
302 self.middle, self.middle_type = self.read_middle_operand(middle, f)
303
304 source = (self.address_mode & 0x38) >> 3
305 self.source, self.source_type = self.read_operand(source, f)
306
307 destination = self.address_mode & 0x07
308 self.destination, self.destination_type = self.read_operand(destination, f)
309
310 def read_operand(self, operand, f):
311
312 # Since we shift the address flags for the source operand, we can
313 # check both source and destination operands using the same values.
314
315 if operand == 0x00:
316 operand = read_OP(f)
317 operand_type = "LO(MP)"
318 elif operand == 0x01:
319 operand = read_OP(f)
320 operand_type = "LO(FP)"
321 elif operand == 0x02:
322 operand = read_OP(f)
323 operand_type = "$OP"
324
325 # No operand for 0x03.
326
327 elif operand == 0x04:
328 operand = (read_OP(f), read_OP(f))
329 operand_type = "SO(SO(MP))"
330 elif operand == 0x05:
331 operand = (read_OP(f), read_OP(f))
332 operand_type = "SO(SO(FP))"
333 else:
334 operand = None
335 operand_type = None
336
337 return operand, operand_type
338
339 def read_middle_operand(self, operand, f):
340
341 # The middle operand bits are not shifted.
342
343 if operand == 0x40:
344 operand = read_OP(f)
345 operand_type = "$SI"
346 elif operand == 0x80:
347 operand = read_OP(f)
348 operand_type = "SO(FP)"
349 elif operand == 0xc0:
350 operand = read_OP(f)
351 operand_type = "SO(MP)"
352 else:
353 operand = None
354 operand_type = None
355
356 return operand, operand_type
357
358 def __repr__(self):
359
360 try:
361 name = opcodes.names[self.opcode]
362 except IndexError:
363 name = hex(self.opcode)
364
365 operands = []
366 comments = []
367
368 for op, optype in (self.source, self.source_type), \
369 (self.middle, self.middle_type), \
370 (self.destination, self.destination_type):
371
372 if optype == "$SI":
373 operands.append("$%x" % op)
374 elif optype == "SO(FP)":
375 operands.append("%i(fp)" % op)
376 elif optype == "SO(MP)":
377 operands.append("%i(mp)" % op)
378 elif optype == "LO(MP)":
379 operands.append("%i(mp)" % op)
380 elif optype == "LO(FP)":
381 operands.append("%i(fp)" % op)
382 elif optype == "$OP":
383 operands.append("$%x" % op)
384 elif optype == "SO(SO(MP))":
385 operands.append("%i(%i(mp))" % op)
386 elif optype == "SO(SO(FP))":
387 operands.append("%i(%i(fp))" % op)
388
389 return name + " " + ", ".join(operands)
390
391
392class Type:218class Type:
393 219
394 def __init__(self, f):220 def __init__(self, f):
docs/notes.txt+43−0
@@ -0,0 +1,43 @@
1Function signatures will be output by the Limbo compiler if you pass it the
2"-D S" debug option.
3
4For example, the Sys->print function has this summary output for it:
5
6 signed Sys->print type fn(s: string, *): int len 6 sig 0xac849033
7
8The type "fn(s: string, *): int" is how the function is declared in the
9module/sys.m file.
10
11Function signatures are generated by the sign function in the limbo/types.c
12file. We add the debug code after the md5 function call:
13
14 md5(sig, sigend, md5sig, nil);
15 if(debug['S']) {
16 print("sign %D len %d\n", d, sigend);
17 print("%s\n", (char*)sig);
18 }
19
20This results in the following additional two debug lines:
21
22 sign Sys->print len 6
23 f*(s)i
24
25The "f*(s)i" string is the function signature that needs to be hashed using the
26MD5 algorithm. Additionally, the following code is used to reduce the hash
27value to four bytes:
28
29 for(i = 0; i < MD5dlen; i += 4)
30 t->sig ^= md5sig[i+0] | (md5sig[i+1]<<8) | (md5sig[i+2]<<16) | (md5sig[i+3]<<24);
31
32We can reproduce this in Python using the md5 module, obtaining the hash value
33then combining each eight digit segment of it using XOR, before reversing the
34endianness of the resulting value:
35
36 import md5
37 h = md5.md5("f*(s)i").hexdigest()
38 l = map(lambda x: int(h[x:x+2], 16), range(0, 32, 2))
39 hd = sum(map(lambda x: reduce(lambda y, z: y ^ z, l[x::4]) << (x * 8), range(4)))
40
41The rtsign and idsign functions in the limbo/types.c file are responsible for
42creating a signature for a function. The sigkind array contains the characters
43used for each type of object that will be serialised.
opcodes.py+808−177
@@ -15,183 +15,11 @@ You should have received a copy of the GNU General Public License · 14 unmodified lines
15along with this program. If not, see <http://www.gnu.org/licenses/>.15along with this program. If not, see <http://www.gnu.org/licenses/>.
16"""16"""
17 17
18nop = 0x0018from utils import read_B, read_OP
19alt = 0x0119
20nbalt = 0x0220# Define string representations of the opcodes.
21goto = 0x0321
22call = 0x0422instruction_names = [
23frame = 0x05
24spawn = 0x06
25runt = 0x07
26load = 0x08
27mcall = 0x09
28mspawn = 0x0a
29mframe = 0x0b
30ret = 0x0c
31jmp = 0x0d
32case = 0x0e
33exit = 0x0f
34new = 0x10
35newa = 0x11
36newcb = 0x12
37newcw = 0x13
38newcf = 0x14
39newcp = 0x15
40newcm = 0x16
41newcmp = 0x17
42send = 0x18
43recv = 0x19
44consb = 0x1a
45consw = 0x1b
46consp = 0x1c
47consf = 0x1d
48consm = 0x1e
49consmp = 0x1f
50headb = 0x20
51headw = 0x21
52headp = 0x22
53headf = 0x23
54headm = 0x24
55headmp = 0x25
56tail = 0x26
57lea = 0x27
58indx = 0x28
59movp = 0x29
60movm = 0x2a
61movmp = 0x2b
62movb = 0x2c
63movw = 0x2d
64movf = 0x2e
65cvtbw = 0x2f
66cvtwb = 0x30
67cvtfw = 0x31
68cvtwf = 0x32
69cvtca = 0x33
70cvtac = 0x34
71cvtwc = 0x35
72cvtcw = 0x36
73cvtfc = 0x37
74cvtcf = 0x38
75addb = 0x39
76addw = 0x3a
77addf = 0x3b
78subb = 0x3c
79subw = 0x3d
80subf = 0x3e
81mulb = 0x3f
82mulw = 0x40
83mulf = 0x41
84divb = 0x42
85divw = 0x43
86divf = 0x44
87modw = 0x45
88modb = 0x46
89andb = 0x47
90andw = 0x48
91orb = 0x49
92orw = 0x4a
93xorb = 0x4b
94xorw = 0x4c
95shlb = 0x4d
96shlw = 0x4e
97shrb = 0x4f
98shrw = 0x50
99insc = 0x51
100indc = 0x52
101addc = 0x53
102lenc = 0x54
103lena = 0x55
104lenl = 0x56
105beqb = 0x57
106bneb = 0x58
107bltb = 0x59
108bleb = 0x5a
109bgtb = 0x5b
110bgeb = 0x5c
111beqw = 0x5d
112bnew = 0x5e
113bltw = 0x5f
114blew = 0x60
115bgtw = 0x61
116bgew = 0x62
117beqf = 0x63
118bnef = 0x64
119bltf = 0x65
120blef = 0x66
121bgtf = 0x67
122bgef = 0x68
123beqc = 0x69
124bnec = 0x6a
125bltc = 0x6b
126blec = 0x6c
127bgtc = 0x6d
128bgec = 0x6e
129slicea = 0x6f
130slicela = 0x70
131slicec = 0x71
132indw = 0x72
133indf = 0x73
134indb = 0x74
135negf = 0x75
136movl = 0x76
137addl = 0x77
138subl = 0x78
139divl = 0x79
140modl = 0x7a
141mull = 0x7b
142andl = 0x7c
143orl = 0x7d
144xorl = 0x7e
145shll = 0x7f
146shrl = 0x80
147bnel = 0x81
148bltl = 0x82
149blel = 0x83
150bgtl = 0x84
151bgel = 0x85
152beql = 0x86
153cvtlf = 0x87
154cvtfl = 0x88
155cvtlw = 0x89
156cvtwl = 0x8a
157cvtlc = 0x8b
158cvtcl = 0x8c
159headl = 0x8d
160consl = 0x8e
161newcl = 0x8f
162casec = 0x90
163indl = 0x91
164movpc = 0x92
165tcmp = 0x93
166mnewz = 0x94
167cvtrf = 0x95
168cvtfr = 0x96
169cvtws = 0x97
170cvtsw = 0x98
171lsrw = 0x99
172lsrl = 0x9a
173eclr = 0x9b
174newz = 0x9c
175newaz = 0x9d
176raise_ = 0x9e
177casel = 0x9f
178mulx = 0xa0
179divx = 0xa1
180cvtxx = 0xa2
181mulx0 = 0xa3
182divx0 = 0xa4
183cvtxx0 = 0xa5
184mulx1 = 0xa6
185divx1 = 0xa7
186cvtxx1 = 0xa8
187cvtfx = 0xa9
188cvtxf = 0xaa
189expw = 0xab
190expl = 0xac
191expf = 0xad
192self = 0xae
193
194names = [
195 "nop", "alt", "nbalt", "goto", "call", "frame", "spawn", "runt",23 "nop", "alt", "nbalt", "goto", "call", "frame", "spawn", "runt",
196 "load", "mcall", "mspawn", "mframe", "ret", "jmp", "case", "exit",24 "load", "mcall", "mspawn", "mframe", "ret", "jmp", "case", "exit",
197 "new", "newa", "newcb", "newcw", "newcf", "newcp", "newcm", "newcmp",25 "new", "newa", "newcb", "newcw", "newcf", "newcp", "newcm", "newcmp",
@@ -215,3 +43,806 @@ names = [ · 17 unmodified lines
215 "mulx", "divx", "cvtxx", "mulx0", "divx0", "cvtxx0", "mulx1", "divx1",43 "mulx", "divx", "cvtxx", "mulx0", "divx0", "cvtxx0", "mulx1", "divx1",
216 "cvtxx1", "cvtfx", "cvtxf", "expw", "expl", "expf", "self"44 "cvtxx1", "cvtfx", "cvtxf", "expw", "expl", "expf", "self"
217 ]45 ]
46
47
48class Instruction:
49
50 def read(self, f):
51
52 self.opcode = read_B(f)
53 self.address_mode = read_B(f)
54
55 middle = self.address_mode & 0xc0
56 self.middle, self.middle_type = self.read_middle_operand(middle, f)
57
58 source = (self.address_mode & 0x38) >> 3
59 self.source, self.source_type = self.read_operand(source, f)
60
61 destination = self.address_mode & 0x07
62 self.destination, self.destination_type = self.read_operand(destination, f)
63
64 return self
65
66 def read_operand(self, operand, f):
67
68 # Since we shift the address flags for the source operand, we can
69 # check both source and destination operands using the same values.
70
71 if operand == 0x00:
72 operand = read_OP(f)
73 operand_type = "LO(MP)"
74 elif operand == 0x01:
75 operand = read_OP(f)
76 operand_type = "LO(FP)"
77 elif operand == 0x02:
78 operand = read_OP(f)
79 operand_type = "$OP"
80
81 # No operand for 0x03.
82
83 elif operand == 0x04:
84 operand = (read_OP(f), read_OP(f))
85 operand_type = "SO(SO(MP))"
86 elif operand == 0x05:
87 operand = (read_OP(f), read_OP(f))
88 operand_type = "SO(SO(FP))"
89 else:
90 operand = None
91 operand_type = None
92
93 return operand, operand_type
94
95 def read_middle_operand(self, operand, f):
96
97 # The middle operand bits are not shifted.
98
99 if operand == 0x40:
100 operand = read_OP(f)
101 operand_type = "$SI"
102 elif operand == 0x80:
103 operand = read_OP(f)
104 operand_type = "SO(FP)"
105 elif operand == 0xc0:
106 operand = read_OP(f)
107 operand_type = "SO(MP)"
108 else:
109 operand = None
110 operand_type = None
111
112 return operand, operand_type
113
114 def __repr__(self):
115
116 try:
117 name = instruction_names[self.opcode]
118 except IndexError:
119 name = hex(self.opcode)
120
121 operands = []
122 comments = []
123
124 for op, optype in (self.source, self.source_type), \
125 (self.middle, self.middle_type), \
126 (self.destination, self.destination_type):
127
128 if optype == "$SI":
129 operands.append("$%x" % op)
130 elif optype == "SO(FP)":
131 operands.append("%i(fp)" % op)
132 elif optype == "SO(MP)":
133 operands.append("%i(mp)" % op)
134 elif optype == "LO(MP)":
135 operands.append("%i(mp)" % op)
136 elif optype == "LO(FP)":
137 operands.append("%i(fp)" % op)
138 elif optype == "$OP":
139 operands.append("$%x" % op)
140 elif optype == "SO(SO(MP))":
141 operands.append("%i(%i(mp))" % op)
142 elif optype == "SO(SO(FP))":
143 operands.append("%i(%i(fp))" % op)
144
145 return name + " " + ", ".join(operands)
146
147
148# Define the instructions and their opcode values.
149
150class nop(Instruction):
151
152 opcode = 0x00
153
154class alt(Instruction):
155
156 opcode = 0x01
157
158class nbalt(Instruction):
159
160 opcode = 0x02
161
162class goto(Instruction):
163
164 opcode = 0x03
165
166class call(Instruction):
167
168 opcode = 0x04
169
170class frame(Instruction):
171
172 opcode = 0x05
173
174class spawn(Instruction):
175
176 opcode = 0x06
177
178class runt(Instruction):
179
180 opcode = 0x07
181
182class load(Instruction):
183
184 opcode = 0x08
185
186class mcall(Instruction):
187
188 opcode = 0x09
189
190class mspawn(Instruction):
191
192 opcode = 0x0a
193
194class mframe(Instruction):
195
196 opcode = 0x0b
197
198class ret(Instruction):
199
200 opcode = 0x0c
201
202class jmp(Instruction):
203
204 opcode = 0x0d
205
206class case(Instruction):
207
208 opcode = 0x0e
209
210class exit(Instruction):
211
212 opcode = 0x0f
213
214class new(Instruction):
215
216 opcode = 0x10
217
218class newa(Instruction):
219
220 opcode = 0x11
221
222class newcb(Instruction):
223
224 opcode = 0x12
225
226class newcw(Instruction):
227
228 opcode = 0x13
229
230class newcf(Instruction):
231
232 opcode = 0x14
233
234class newcp(Instruction):
235
236 opcode = 0x15
237
238class newcm(Instruction):
239
240 opcode = 0x16
241
242class newcmp(Instruction):
243
244 opcode = 0x17
245
246class send(Instruction):
247
248 opcode = 0x18
249
250class recv(Instruction):
251
252 opcode = 0x19
253
254class consb(Instruction):
255
256 opcode = 0x1a
257
258class consw(Instruction):
259
260 opcode = 0x1b
261
262class consp(Instruction):
263
264 opcode = 0x1c
265
266class consf(Instruction):
267
268 opcode = 0x1d
269
270class consm(Instruction):
271
272 opcode = 0x1e
273
274class consmp(Instruction):
275
276 opcode = 0x1f
277
278class headb(Instruction):
279
280 opcode = 0x20
281
282class headw(Instruction):
283
284 opcode = 0x21
285
286class headp(Instruction):
287
288 opcode = 0x22
289
290class headf(Instruction):
291
292 opcode = 0x23
293
294class headm(Instruction):
295
296 opcode = 0x24
297
298class headmp(Instruction):
299
300 opcode = 0x25
301
302class tail(Instruction):
303
304 opcode = 0x26
305
306class lea(Instruction):
307
308 opcode = 0x27
309
310class indx(Instruction):
311
312 opcode = 0x28
313
314class movp(Instruction):
315
316 opcode = 0x29
317
318class movm(Instruction):
319
320 opcode = 0x2a
321
322class movmp(Instruction):
323
324 opcode = 0x2b
325
326class movb(Instruction):
327
328 opcode = 0x2c
329
330class movw(Instruction):
331
332 opcode = 0x2d
333
334class movf(Instruction):
335
336 opcode = 0x2e
337
338class cvtbw(Instruction):
339
340 opcode = 0x2f
341
342class cvtwb(Instruction):
343
344 opcode = 0x30
345
346class cvtfw(Instruction):
347
348 opcode = 0x31
349
350class cvtwf(Instruction):
351
352 opcode = 0x32
353
354class cvtca(Instruction):
355
356 opcode = 0x33
357
358class cvtac(Instruction):
359
360 opcode = 0x34
361
362class cvtwc(Instruction):
363
364 opcode = 0x35
365
366class cvtcw(Instruction):
367
368 opcode = 0x36
369
370class cvtfc(Instruction):
371
372 opcode = 0x37
373
374class cvtcf(Instruction):
375
376 opcode = 0x38
377
378class addb(Instruction):
379
380 opcode = 0x39
381
382class addw(Instruction):
383
384 opcode = 0x3a
385
386class addf(Instruction):
387
388 opcode = 0x3b
389
390class subb(Instruction):
391
392 opcode = 0x3c
393
394class subw(Instruction):
395
396 opcode = 0x3d
397
398class subf(Instruction):
399
400 opcode = 0x3e
401
402class mulb(Instruction):
403
404 opcode = 0x3f
405
406class mulw(Instruction):
407
408 opcode = 0x40
409
410class mulf(Instruction):
411
412 opcode = 0x41
413
414class divb(Instruction):
415
416 opcode = 0x42
417
418class divw(Instruction):
419
420 opcode = 0x43
421
422class divf(Instruction):
423
424 opcode = 0x44
425
426class modw(Instruction):
427
428 opcode = 0x45
429
430class modb(Instruction):
431
432 opcode = 0x46
433
434class andb(Instruction):
435
436 opcode = 0x47
437
438class andw(Instruction):
439
440 opcode = 0x48
441
442class orb(Instruction):
443
444 opcode = 0x49
445
446class orw(Instruction):
447
448 opcode = 0x4a
449
450class xorb(Instruction):
451
452 opcode = 0x4b
453
454class xorw(Instruction):
455
456 opcode = 0x4c
457
458class shlb(Instruction):
459
460 opcode = 0x4d
461
462class shlw(Instruction):
463
464 opcode = 0x4e
465
466class shrb(Instruction):
467
468 opcode = 0x4f
469
470class shrw(Instruction):
471
472 opcode = 0x50
473
474class insc(Instruction):
475
476 opcode = 0x51
477
478class indc(Instruction):
479
480 opcode = 0x52
481
482class addc(Instruction):
483
484 opcode = 0x53
485
486class lenc(Instruction):
487
488 opcode = 0x54
489
490class lena(Instruction):
491
492 opcode = 0x55
493
494class lenl(Instruction):
495
496 opcode = 0x56
497
498class beqb(Instruction):
499
500 opcode = 0x57
501
502class bneb(Instruction):
503
504 opcode = 0x58
505
506class bltb(Instruction):
507
508 opcode = 0x59
509
510class bleb(Instruction):
511
512 opcode = 0x5a
513
514class bgtb(Instruction):
515
516 opcode = 0x5b
517
518class bgeb(Instruction):
519
520 opcode = 0x5c
521
522class beqw(Instruction):
523
524 opcode = 0x5d
525
526class bnew(Instruction):
527
528 opcode = 0x5e
529
530class bltw(Instruction):
531
532 opcode = 0x5f
533
534class blew(Instruction):
535
536 opcode = 0x60
537
538class bgtw(Instruction):
539
540 opcode = 0x61
541
542class bgew(Instruction):
543
544 opcode = 0x62
545
546class beqf(Instruction):
547
548 opcode = 0x63
549
550class bnef(Instruction):
551
552 opcode = 0x64
553
554class bltf(Instruction):
555
556 opcode = 0x65
557
558class blef(Instruction):
559
560 opcode = 0x66
561
562class bgtf(Instruction):
563
564 opcode = 0x67
565
566class bgef(Instruction):
567
568 opcode = 0x68
569
570class beqc(Instruction):
571
572 opcode = 0x69
573
574class bnec(Instruction):
575
576 opcode = 0x6a
577
578class bltc(Instruction):
579
580 opcode = 0x6b
581
582class blec(Instruction):
583
584 opcode = 0x6c
585
586class bgtc(Instruction):
587
588 opcode = 0x6d
589
590class bgec(Instruction):
591
592 opcode = 0x6e
593
594class slicea(Instruction):
595
596 opcode = 0x6f
597
598class slicela(Instruction):
599
600 opcod = 0x70
601
602class slicec(Instruction):
603
604 opcode = 0x71
605
606class indw(Instruction):
607
608 opcode = 0x72
609
610class indf(Instruction):
611
612 opcode = 0x73
613
614class indb(Instruction):
615
616 opcode = 0x74
617
618class negf(Instruction):
619
620 opcode = 0x75
621
622class movl(Instruction):
623
624 opcode = 0x76
625
626class addl(Instruction):
627
628 opcode = 0x77
629
630class subl(Instruction):
631
632 opcode = 0x78
633
634class divl(Instruction):
635
636 opcode = 0x79
637
638class modl(Instruction):
639
640 opcode = 0x7a
641
642class mull(Instruction):
643
644 opcode = 0x7b
645
646class andl(Instruction):
647
648 opcode = 0x7c
649
650class orl(Instruction):
651
652 opcode = 0x7d
653
654class xorl(Instruction):
655
656 opcode = 0x7e
657
658class shll(Instruction):
659
660 opcode = 0x7f
661
662class shrl(Instruction):
663
664 opcode = 0x80
665
666class bnel(Instruction):
667
668 opcode = 0x81
669
670class bltl(Instruction):
671
672 opcode = 0x82
673
674class blel(Instruction):
675
676 opcode = 0x83
677
678class bgtl(Instruction):
679
680 opcode = 0x84
681
682class bgel(Instruction):
683
684 opcode = 0x85
685
686class beql(Instruction):
687
688 opcode = 0x86
689
690class cvtlf(Instruction):
691
692 opcode = 0x87
693
694class cvtfl(Instruction):
695
696 opcode = 0x88
697
698class cvtlw(Instruction):
699
700 opcode = 0x89
701
702class cvtwl(Instruction):
703
704 opcode = 0x8a
705
706class cvtlc(Instruction):
707
708 opcode = 0x8b
709
710class cvtcl(Instruction):
711
712 opcode = 0x8c
713
714class headl(Instruction):
715
716 opcode = 0x8d
717
718class consl(Instruction):
719
720 opcode = 0x8e
721
722class newcl(Instruction):
723
724 opcode = 0x8f
725
726class casec(Instruction):
727
728 opcode = 0x90
729
730class indl(Instruction):
731
732 opcode = 0x91
733
734class movpc(Instruction):
735
736 opcode = 0x92
737
738class tcmp(Instruction):
739
740 opcode = 0x93
741
742class mnewz(Instruction):
743
744 opcode = 0x94
745
746class cvtrf(Instruction):
747
748 opcode = 0x95
749
750class cvtfr(Instruction):
751
752 opcode = 0x96
753
754class cvtws(Instruction):
755
756 opcode = 0x97
757
758class cvtsw(Instruction):
759
760 opcode = 0x98
761
762class lsrw(Instruction):
763
764 opcode = 0x99
765
766class lsrl(Instruction):
767
768 opcode = 0x9a
769
770class eclr(Instruction):
771
772 opcode = 0x9b
773
774class newz(Instruction):
775
776 opcode = 0x9c
777
778class newaz(Instruction):
779
780 opcode = 0x9d
781
782class raise_(Instruction):
783
784 opcode = 0x9e
785
786class casel(Instruction):
787
788 opcode = 0x9f
789
790class mulx(Instruction):
791
792 opcode = 0xa0
793
794class divx(Instruction):
795
796 opcode = 0xa1
797
798class cvtxx(Instruction):
799
800 opcode = 0xa2
801
802class mulx0(Instruction):
803
804 opcode = 0xa3
805
806class divx0(Instruction):
807
808 opcode = 0xa4
809
810class cvtxx0(Instruction):
811
812 opcode = 0xa5
813
814class mulx1(Instruction):
815
816 opcode = 0xa6
817
818class divx1(Instruction):
819
820 opcode = 0xa7
821
822class cvtxx1(Instruction):
823
824 opcode = 0xa8
825
826class cvtfx(Instruction):
827
828 opcode = 0xa9
829
830class cvtxf(Instruction):
831
832 opcode = 0xaa
833
834class expw(Instruction):
835
836 opcode = 0xab
837
838class expl(Instruction):
839
840 opcode = 0xac
841
842class expf(Instruction):
843
844 opcode = 0xad
845
846class self(Instruction):
847
848 opcode = 0xae
utils.py+98−0
@@ -0,0 +1,98 @@
1"""
2Copyright (C) 2017 David Boddie <david@boddie.org.uk>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 3 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16"""
17
18from struct import calcsize, pack, unpack
19
20def _read(f, format):
21
22 size = calcsize(format)
23 return unpack(format, f.read(size))[0]
24
25def read_B(f):
26 # byte, 8-bit unsigned
27 return unpack(">B", f.read(1))[0]
28
29def read_OP(f):
30
31 s = f.read(1)
32 v = unpack(">B", s)[0]
33
34 encoding = v & 0xc0
35
36 if encoding == 0x80:
37 s += f.read(1)
38 v = unpack(">H", s)[0] & 0x3fff
39 if v >= 0x2000:
40 v = v - 0x4000
41
42 elif encoding == 0xc0:
43 s += f.read(3)
44 v = unpack(">I", s)[0] & 0x3fffffff
45 if v >= 0x20000000:
46 v = v - 0x40000000
47 else:
48 # The top bit is clear, the next-to-top bit can be 0 or 1.
49 # -64 (0xc0) <= original value <= 63 (0x2f)
50 # -64 (0x40) <= encoded value <= 63 (0x2f)
51 if encoding != 0:
52 # The next-to-top bit is set meaning that
53 # -64 <= original value <= -1
54 v = v - 0x80
55
56 return v
57
58def read_W(f):
59 # 32-bit word
60 return unpack(">i", f.read(4))[0]
61
62def read_F(f):
63 # 64-bit float
64 return unpack(">d", f.read(8))[0]
65
66def read_L(f):
67 # 64-bit big integer
68 # Signed or unsigned? Assume signed for now.
69 return unpack(">q", f.read(8))[0]
70
71def read_P(f):
72 # 32-bit pointer
73 return unpack(">I", f.read(4))[0]
74
75def read_C(f):
76 # UTF-8 encoded string
77 s = ""
78 while True:
79 c = f.read(1)
80 if c == "\x00":
81 break
82 s += c
83
84 return s
85
86# Currently unused:
87
88def read_SO(f):
89
90 return unpack(">H", f.read(2))[0]
91
92def read_SI(f):
93
94 return unpack(">h", f.read(2))[0]
95
96def read_LO(f):
97
98 return unpack(">i", f.read(4))[0]