History

Reorganised the way instructions are represented, including mechanism for serialising them to files. Added functions for writing values of different types to files.

David Boddie committed 9 years ago

Commit b2622161 parent b833c113 files · +415 −723Browse files

Unified · Split

3 files
  1. docs/notes.txt +4 −0
  2. opcodes.py +345 −723
  3. utils.py +66 −0
docs/notes.txt+4−0
@@ -1,3 +1,7 @@
1Opcodes are defined in include/isa.h, limbo/optab.c and libinterp/xec.c.
2
3consc is documented but does not exist in the opcode definitions.
4
1Function signatures will be output by the Limbo compiler if you pass it the5Function signatures will be output by the Limbo compiler if you pass it the
2"-D S" debug option.6"-D S" debug option.
3 7
opcodes.py+345−723
@@ -15,7 +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
18from utils import read_B, read_OP18# See http://inferno-os.org/inferno/papers/dis.html or
19# http://doc.cat-v.org/inferno/4th_edition/dis_VM_specification
20# for information.
21
22from utils import read_B, read_OP, write_B, write_OP
19 23
20# Define string representations of the opcodes.24# Define string representations of the opcodes.
21 25
@@ -47,69 +51,81 @@ instruction_names = [ · 25 unmodified lines
47 51
48class Instruction:52class Instruction:
49 53
54 def __init__(self):
55
56 self.source = NoOperand()
57 self.middle = NoOperand()
58 self.destination = NoOperand()
59 self.set_address_mode()
60
50 def read(self, f):61 def read(self, f):
51 62
52 self.opcode = read_B(f)63 self.opcode = read_B(f)
53 self.address_mode = read_B(f)64 self.address_mode = read_B(f)
54 65
55 middle = self.address_mode & 0xc066 middle = self.address_mode & 0xc0
56 self.middle, self.middle_type = self.read_middle_operand(middle, f)67 self.middle = self.read_middle_operand(middle, f)
57 68
58 source = (self.address_mode & 0x38) >> 369 source = (self.address_mode & 0x38) >> 3
59 self.source, self.source_type = self.read_operand(source, f)70 self.source = self.read_operand(source, f)
60 71
61 destination = self.address_mode & 0x0772 destination = self.address_mode & 0x07
62 self.destination, self.destination_type = self.read_operand(destination, f)73 self.destination = self.read_operand(destination, f)
63 74
64 return self75 return self
65 76
77 def set_address_mode(self):
78
79 self.address_mode = self.middle.middle_address_mode | \
80 (self.source.address_mode << 3) | \
81 self.destination.address_mode
82
66 def read_operand(self, operand, f):83 def read_operand(self, operand, f):
67 84
68 # Since we shift the address flags for the source operand, we can85 # Since we shift the address flags for the source operand, we can
69 # check both source and destination operands using the same values.86 # check both source and destination operands using the same values.
70 87
71 if operand == 0x00:88 if operand == 0x00:
72 operand = read_OP(f)89 operand = LongOffsetMP(read_OP(f), "LO(MP)")
73 operand_type = "LO(MP)"
74 elif operand == 0x01:90 elif operand == 0x01:
75 operand = read_OP(f)91 operand = LongOffsetFP(read_OP(f), "LO(FP)")
76 operand_type = "LO(FP)"
77 elif operand == 0x02:92 elif operand == 0x02:
78 operand = read_OP(f)93 operand = Immediate(read_OP(f), "$OP")
79 operand_type = "$OP"
80 94
81 # No operand for 0x03.95 # No operand for 0x03.
82 96
83 elif operand == 0x04:97 elif operand == 0x04:
84 operand = (read_OP(f), read_OP(f))98 operand = DoubleShortOffsetMP((read_OP(f), read_OP(f)), "SO(SO(MP))")
85 operand_type = "SO(SO(MP))"
86 elif operand == 0x05:99 elif operand == 0x05:
87 operand = (read_OP(f), read_OP(f))100 operand = DoubleShortOffsetFP((read_OP(f), read_OP(f)), "SO(SO(FP))")
88 operand_type = "SO(SO(FP))"
89 else:101 else:
90 operand = None102 operand = NoOperand()
91 operand_type = None
92 103
93 return operand, operand_type104 return operand
94 105
95 def read_middle_operand(self, operand, f):106 def read_middle_operand(self, operand, f):
96 107
97 # The middle operand bits are not shifted.108 # The middle operand bits are not shifted.
98 109
99 if operand == 0x40:110 if operand == 0x40:
100 operand = read_OP(f)111 operand = Immediate(read_OP(f), "$SI")
101 operand_type = "$SI"
102 elif operand == 0x80:112 elif operand == 0x80:
103 operand = read_OP(f)113 operand = ShortOffsetFP(read_OP(f), "SO(FP)")
104 operand_type = "SO(FP)"
105 elif operand == 0xc0:114 elif operand == 0xc0:
106 operand = read_OP(f)115 operand = ShortOffsetMP(read_OP(f), "SO(MP)")
107 operand_type = "SO(MP)"
108 else:116 else:
109 operand = None117 operand = NoOperand()
110 operand_type = None
111 118
112 return operand, operand_type119 return operand
120
121 def write(self, f):
122
123 write_B(f, self.opcode)
124 write_B(f, self.address_mode)
125
126 self.middle.write(f)
127 self.source.write(f)
128 self.destination.write(f)
113 129
114 def __repr__(self):130 def __repr__(self):
115 131
@@ -119,730 +135,336 @@ class Instruction: · 3 unmodified lines
119 name = hex(self.opcode)135 name = hex(self.opcode)
120 136
121 operands = []137 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 138
128 if optype == "$SI":139 for operand in self.source, self.middle, self.destination:
129 operands.append("$%x" % op)140 s = str(operand)
130 elif optype == "SO(FP)":141 if s:
131 operands.append("%i(fp)" % op)142 operands.append(s)
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 143
145 return name + " " + ", ".join(operands)144 return name + " " + ", ".join(operands)
146 145
147 146
148# Define the instructions and their opcode values.147# Define the argument types.
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 148
482class addc(Instruction):149class NoOperand:
483 150
484 opcode = 0x53151 middle_address_mode = 0x00
485 152 address_mode = 0x03
486class lenc(Instruction):153
487 154 def write(self, f):
488 opcode = 0x54155 pass
489 156
490class lena(Instruction):157 def __str__(self):
491 158 return ""
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 159
804 opcode = 0xa3160class Operand:
805 161
806class divx0(Instruction):162 def __init__(self, value, annotation = None):
163
164 self.value = value
165 self.annotation = annotation
166
167 def __str__(self):
168 return self.str_pattern % self.value
169
170 def write(self, f):
171 write_OP(f, self.value)
807 172
808 opcode = 0xa4173class Immediate(Operand):
174 str_pattern = "$%x"
175 middle_address_mode = 0x40
176 address_mode = 0x02
809 177
810class cvtxx0(Instruction):178class LongOffset(Operand):
179 pass
811 180
812 opcode = 0xa5181class LongOffsetMP(LongOffset):
182 str_pattern = "%i(mp)"
183 address_mode = 0x00
813 184
814class mulx1(Instruction):185class LongOffsetFP(LongOffset):
186 str_pattern = "%i(fp)"
187 address_mode = 0x01
815 188
816 opcode = 0xa6189class ShortOffset(Operand):
190 pass
817 191
818class divx1(Instruction):192class ShortOffsetMP(ShortOffset):
193 str_pattern = "%i(mp)"
194 middle_address_mode = 0xc0
819 195
820 opcode = 0xa7196class ShortOffsetFP(ShortOffset):
197 str_pattern = "%i(fp)"
198 middle_address_mode = 0x80
821 199
822class cvtxx1(Instruction):200class DoubleShortOffset(Operand):
823 201
824 opcode = 0xa8202 def write(self, f):
203 write_OP(f, self.value[0] & 0xffff)
204 write_OP(f, self.value[1] & 0xffff)
825 205
826class cvtfx(Instruction):206class DoubleShortOffsetMP(Operand):
207 str_pattern = "%i(%i(mp))"
208 address_mode = 0x04
827 209
828 opcode = 0xa9210class DoubleShortOffsetFP(Operand):
211 str_pattern = "%i(%i(fp))"
212 address_mode = 0x05
829 213
830class cvtxf(Instruction):
831 214
832 opcode = 0xaa215# Define the instructions and their opcode values.
833 216
834class expw(Instruction):217class Src(Instruction):
218
219 def __init__(self, src):
220
221 self.source = src
222 self.middle = NoOperand()
223 self.destination = NoOperand()
224 self.set_address_mode()
835 225
836 opcode = 0xab226class Src_Dst(Instruction):
227
228 def __init__(self, src, dst):
229
230 self.source = src
231 self.middle = NoOperand()
232 self.destination = dst
233 self.set_address_mode()
837 234
838class expl(Instruction):235class Src_Src(Instruction):
236
237 def __init__(self, src1, src2):
238
239 self.source = src1
240 self.middle = src2
241 self.destination = NoOperand()
242 self.set_address_mode()
839 243
840 opcode = 0xac244class Src_Src_Dst(Instruction):
841 245
842class expf(Instruction):246 def __init__(self, src1, src2, dst):
247
248 self.source = src1
249 self.middle = src2
250 self.destination = dst
251 self.set_address_mode()
843 252
844 opcode = 0xad253class Src_Src_src(Instruction):
845 254
846class self(Instruction):255 def __init__(self, src1, src2, src3):
256
257 self.source = src1
258 self.middle = src2
259 self.destination = src3
260 self.set_address_mode()
847 261
848 opcode = 0xae262class Dst(Instruction):
263
264 def __init__(self, dst):
265
266 self.source = NoOperand()
267 self.middle = NoOperand()
268 self.destination = dst
269 self.set_address_mode()
270
271# Groups of instructions
272class addx(Src_Src_Dst): pass
273class andx(Src_Src_Dst): pass
274class beqx(Src_Src_Dst): pass
275class bgex(Src_Src_Dst): pass
276class bgtx(Src_Src_Dst): pass
277class blex(Src_Src_Dst): pass
278class bltx(Src_Src_Dst): pass
279class bnex(Src_Src_Dst): pass
280class consx(Src_Dst): pass
281class divx_(Src_Src_Dst): pass
282class headx(Src_Dst): pass
283class indx_(Src_Src_Dst): pass
284class lsrx(Src_Src_Dst): pass
285class modx(Src_Src_Dst): pass
286class movx(Src_Dst): pass
287class mulx_(Src_Src_Dst): pass
288class newcx(Dst): pass
289class orx(Src_Src_Dst): pass
290class shlx(Src_Src_Dst): pass
291class shrx(Src_Src_Dst): pass
292class subx(Src_Src_Dst): pass
293class xorx(Src_Src_Dst): pass
294
295# Individual definitions (marked with the file in libinterp with information)
296class addb(addx): opcode = 0x39
297class addc(addx): opcode = 0x53
298class addf(addx): opcode = 0x3b
299class addl(addx): opcode = 0x77
300class addw(addx): opcode = 0x3a
301class alt(Src_Dst): opcode = 0x01
302class andb(andx): opcode = 0x47
303class andl(andx): opcode = 0x7c
304class andw(andx): opcode = 0x48
305class beqb(beqx): opcode = 0x57
306class beqc(beqx): opcode = 0x69
307class beqf(beqx): opcode = 0x63
308class beql(beqx): opcode = 0x86
309class beqw(beqx): opcode = 0x5d
310class bgeb(bgex): opcode = 0x5c
311class bgec(bgex): opcode = 0x6e
312class bgef(bgex): opcode = 0x68
313class bgel(bgex): opcode = 0x85
314class bgew(bgex): opcode = 0x62
315class bgtb(bgtx): opcode = 0x5b
316class bgtc(bgtx): opcode = 0x6d
317class bgtf(bgtx): opcode = 0x67
318class bgtl(bgtx): opcode = 0x84
319class bgtw(bgtx): opcode = 0x61
320class bleb(blex): opcode = 0x5a
321class blec(blex): opcode = 0x6c
322class blef(blex): opcode = 0x66
323class blel(blex): opcode = 0x83
324class blew(blex): opcode = 0x60
325class bltb(bltx): opcode = 0x59
326class bltc(bltx): opcode = 0x6b
327class bltf(bltx): opcode = 0x65
328class bltl(bltx): opcode = 0x82
329class bltw(bltx): opcode = 0x5f
330class bneb(bnex): opcode = 0x58
331class bnec(bnex): opcode = 0x6a
332class bnef(bnex): opcode = 0x64
333class bnel(bnex): opcode = 0x81
334class bnew(bnex): opcode = 0x5e
335class call(Src_Dst): opcode = 0x04
336class case(Src_Dst): opcode = 0x0e
337class casec(Src_Dst): opcode = 0x90
338class casel(Src_Dst): opcode = 0x9f ### check syntax
339class consb(consx): opcode = 0x1a
340class consf(consx): opcode = 0x1d
341class consl(consx): opcode = 0x8e
342class consm(consx): opcode = 0x1e
343class consmp(consx): opcode = 0x1f
344class consp(consx): opcode = 0x1c
345class consw(consx): opcode = 0x1b
346class cvtac(Src_Dst): opcode = 0x34
347class cvtbw(Src_Dst): opcode = 0x2f
348class cvtca(Src_Dst): opcode = 0x33
349class cvtcf(Src_Dst): opcode = 0x38
350class cvtcl(Src_Dst): opcode = 0x8c
351class cvtcw(Src_Dst): opcode = 0x36
352class cvtfc(Src_Dst): opcode = 0x37
353class cvtfl(Src_Dst): opcode = 0x88
354class cvtfr(Src_Dst): opcode = 0x96
355class cvtfw(Src_Dst): opcode = 0x31
356class cvtfx(Src_Dst): opcode = 0xa9
357class cvtlc(Src_Dst): opcode = 0x8b
358class cvtlf(Src_Dst): opcode = 0x87
359class cvtlw(Src_Dst): opcode = 0x89
360class cvtrf(Src_Dst): opcode = 0x95
361class cvtsw(Src_Dst): opcode = 0x98 # short to word (xec.c)
362class cvtwb(Src_Dst): opcode = 0x30 # word to byte (xec.c)
363class cvtwc(Src_Dst): opcode = 0x35 # word to char array (string.c)
364class cvtwf(Src_Dst): opcode = 0x32 # word to float (xec.c)
365class cvtwl(Src_Dst): opcode = 0x8a # word to long (xec.c)
366class cvtws(Src_Dst): opcode = 0x97 # word to short (xec.c)
367class cvtxf(Src_Src_Dst): opcode = 0xaa # word * float -> float (xec.c)
368class cvtxx0(Src_Src_Dst): opcode = 0xa5 ### word ? word -> word (xec.c)
369class cvtxx1(Src_Src_Dst): opcode = 0xa8 ### word ? word -> word (xec.c)
370class cvtxx(Src_Src_Dst): opcode = 0xa2 ### word ? word -> word (xec.c)
371class divb(divx_): opcode = 0x42
372class divf(divx_): opcode = 0x44
373class divl(divx_): opcode = 0x79
374class divw(divx_): opcode = 0x43
375class divx0(divx_): opcode = 0xa4 # (xec.c)
376class divx1(divx_): opcode = 0xa7 # (xec.c)
377class divx(divx_): opcode = 0xa1 # (xec.c)
378class eclr(Instruction): opcode = 0x9b # unused
379class exit(Instruction): opcode = 0x0f
380class expf(Src_Src_Dst): opcode = 0xad # word word -> float (xec.c)
381class expl(Src_Src_Dst): opcode = 0xac # word long -> long (xec.c)
382class expw(Src_Src_Dst): opcode = 0xab # word word -> word (xec.c)
383class frame(Src_Src): opcode = 0x05
384class goto(Src_Dst): opcode = 0x03
385class headb(headx): opcode = 0x20
386class headf(headx): opcode = 0x23
387class headl(headx): opcode = 0x8d
388class headm(headx): opcode = 0x24
389class headmp(headx): opcode = 0x25
390class headp(headx): opcode = 0x22
391class headw(headx): opcode = 0x21
392class indb(indx_): opcode = 0x74
393class indc(Src_Src_Dst): opcode = 0x52
394class indf(indx_): opcode = 0x73
395class indl(indx_): opcode = 0x91
396class indw(indx_): opcode = 0x72
397class indx(Src_Src_Dst): opcode = 0x28
398class insc(Src_Src_Dst): opcode = 0x51
399class jmp(Dst): opcode = 0x0d
400class lea(Src_Dst): opcode = 0x27
401class lena(Src_Dst): opcode = 0x55
402class lenc(Src_Dst): opcode = 0x54
403class lenl(Src_Dst): opcode = 0x56
404class load(Src_Src_Dst): opcode = 0x08
405class lsrl(lsrx): opcode = 0x9a
406class lsrw(lsrx): opcode = 0x99
407class mcall(Src_Src_src): opcode = 0x09
408class mframe(Src_Src_Dst): opcode = 0x0b
409class mnewz(Src_Src_Dst): opcode = 0x94
410class modb(modx): opcode = 0x46
411class modl(modx): opcode = 0x7a
412class modw(modx): opcode = 0x45
413class movb(movx): opcode = 0x2c
414class movf(movx): opcode = 0x2e
415class movl(movx): opcode = 0x76
416class movm(Src_Src_Dst): opcode = 0x2a
417class movmp(Src_Src_Dst): opcode = 0x2b
418class movpc(Src_Dst): opcode = 0x92
419class movp(Src_Dst): opcode = 0x29
420class movw(movx): opcode = 0x2d
421class mspawn(Src_Src_src): opcode = 0x0a
422class mulb(mulx_): opcode = 0x3f
423class mulf(mulx_): opcode = 0x41
424class mull(mulx_): opcode = 0x7b
425class mulw(mulx_): opcode = 0x40
426class mulx0(mulx_): opcode = 0xa3 ### word * word -> word (xec.c)
427class mulx1(mulx_): opcode = 0xa6 ### word * word -> word (xec.c)
428class mulx(mulx_): opcode = 0xa0 ### word * word -> word (xec.c)
429class nbalt(Src_Dst): opcode = 0x02
430class negf(Src_Dst): opcode = 0x75
431class new(Src_Dst): opcode = 0x10
432class newa(Src_Src_Dst): opcode = 0x11
433class newaz(Src_Src_Dst): opcode = 0x9d
434class newcb(newcx): opcode = 0x12
435class newcf(newcx): opcode = 0x14
436class newcl(newcx): opcode = 0x8f
437class newcm(newcx): opcode = 0x16
438class newcmp(newcx): opcode = 0x17
439class newcp(newcx): opcode = 0x15
440class newcw(newcx): opcode = 0x13
441class newz(Src_Dst): opcode = 0x9c
442class nop(Instruction): opcode = 0x00
443class orb(orx): opcode = 0x49
444class orl(orx): opcode = 0x7d
445class orw(orx): opcode = 0x4a
446class raise_(Src): opcode = 0x9e ### type (xec.c)
447class recv(Src_Dst): opcode = 0x19
448class ret(Instruction): opcode = 0x0c
449class runt(Instruction): opcode = 0x07 ### no operands (xec.c)
450class self(Instruction): opcode = 0xae ### no operands? (xec.c)
451class send(Src_Dst): opcode = 0x18
452class shlb(shlx): opcode = 0x4d
453class shll(shlx): opcode = 0x7f
454class shlw(shlx): opcode = 0x4e
455class shrb(shrx): opcode = 0x4f
456class shrl(shrx): opcode = 0x80
457class shrw(shrx): opcode = 0x50
458class slicea(Src_Src_Dst): opcode = 0x6f
459class slicec(Src_Src_Dst): opcode = 0x71
460class slicela(Src_Src_Dst): opcode = 0x70
461class spawn(Src_Dst): opcode = 0x06
462class subb(subx): opcode = 0x3c
463class subf(subx): opcode = 0x3e
464class subl(subx): opcode = 0x78
465class subw(subx): opcode = 0x3d
466class tail(Src_Dst): opcode = 0x26
467class tcmp(Src_Dst): opcode = 0x93
468class xorb(xorx): opcode = 0x4b
469class xorl(xorx): opcode = 0x7e
470class xorw(xorx): opcode = 0x4c
utils.py+66−0
@@ -15,6 +15,7 @@ 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
18import md5
18from struct import calcsize, pack, unpack19from struct import calcsize, pack, unpack
19 20
20def _read(f, format):21def _read(f, format):
@@ -83,6 +84,71 @@ def read_C(f): · 62 unmodified lines
83 84
84 return s85 return s
85 86
87def _write(f, format, value):
88
89 f.write(pack(format, value))
90
91def write_B(f, value):
92 # byte, 8-bit unsigned
93 f.write(pack(">B", value))
94
95def write_OP(f, value):
96
97 if -64 <= value <= 63:
98 f.write(pack(">B", value))
99
100 elif -8192 <= value <= 8191:
101 f.write(pack(">H", (value & 0x3fff) | 0x8000))
102
103 elif -0x20000000 <= value <= 0x1f000000:
104 f.write(pack(">I", (value & 0x3fffffff) | 0xc0000000))
105
106 else:
107 raise ValueError("Cannot encode %i as an OP." % value)
108
109def write_W(f, value):
110 # 32-bit word
111 f.write(pack(">i", value))
112
113def write_F(f, value):
114 # 64-bit float
115 f.write(pack(">d", value))
116
117def write_L(f, value):
118 # 64-bit big integer
119 # Signed or unsigned? Assume signed for now.
120 f.write(pack(">q", value))
121
122def write_P(f, value):
123 # 32-bit pointer
124 f.write(pack(">I", value))
125
126def write_C(f, value):
127 # UTF-8 encoded string
128 f.write(value)
129 f.write("\x00")
130
131# Higher level data handling
132
133def hash_signature(function_signature):
134
135 h = md5.md5(function_signature).hexdigest()
136
137 # Convert each pair of hexadecimal digits to a byte value, resulting in
138 # sixteen values.
139 l = map(lambda x: int(h[x:x+2], 16), range(0, 32, 2))
140
141 # Considering each four bytes as part of a word, combine each byte with the
142 # corresponding byte in the other three words using the XOR operator,
143 # shifting each value so that they can be combined using addition later.
144 values = []
145 for i in range(4):
146 values.append(reduce(lambda x, y: x ^ y, l[i::4]) << (i * 8))
147
148 # Sum the values to produce a 32-bit value.
149 return sum(values)
150
151
86# Currently unused:152# Currently unused:
87 153
88def read_SO(f):154def read_SO(f):