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 @@
1+Opcodes are defined in include/isa.h, limbo/optab.c and libinterp/xec.c.
2+
3+consc is documented but does not exist in the opcode definitions.
4+
15 Function signatures will be output by the Limbo compiler if you pass it the
26 "-D S" debug option.
37
opcodes.py+345−723
@@ -15,7 +15,11 @@ You should have received a copy of the GNU General Public License · 14 unmodified lines
1515 along with this program. If not, see <http://www.gnu.org/licenses/>.
1616 """
1717
18−from utils import read_B, read_OP
18+# 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+
22+from utils import read_B, read_OP, write_B, write_OP
1923
2024 # Define string representations of the opcodes.
2125
@@ -47,69 +51,81 @@ instruction_names = [ · 25 unmodified lines
4751
4852 class Instruction:
4953
54+ def __init__(self):
55+
56+ self.source = NoOperand()
57+ self.middle = NoOperand()
58+ self.destination = NoOperand()
59+ self.set_address_mode()
60+
5061 def read(self, f):
5162
5263 self.opcode = read_B(f)
5364 self.address_mode = read_B(f)
5465
5566 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)
5768
5869 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)
6071
6172 destination = self.address_mode & 0x07
62− self.destination, self.destination_type = self.read_operand(destination, f)
73+ self.destination = self.read_operand(destination, f)
6374
6475 return self
6576
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+
6683 def read_operand(self, operand, f):
6784
6885 # Since we shift the address flags for the source operand, we can
6986 # check both source and destination operands using the same values.
7087
7188 if operand == 0x00:
72− operand = read_OP(f)
73− operand_type = "LO(MP)"
89+ operand = LongOffsetMP(read_OP(f), "LO(MP)")
7490 elif operand == 0x01:
75− operand = read_OP(f)
76− operand_type = "LO(FP)"
91+ operand = LongOffsetFP(read_OP(f), "LO(FP)")
7792 elif operand == 0x02:
78− operand = read_OP(f)
79− operand_type = "$OP"
93+ operand = Immediate(read_OP(f), "$OP")
8094
8195 # No operand for 0x03.
8296
8397 elif operand == 0x04:
84− operand = (read_OP(f), read_OP(f))
85− operand_type = "SO(SO(MP))"
98+ operand = DoubleShortOffsetMP((read_OP(f), read_OP(f)), "SO(SO(MP))")
8699 elif operand == 0x05:
87− operand = (read_OP(f), read_OP(f))
88− operand_type = "SO(SO(FP))"
100+ operand = DoubleShortOffsetFP((read_OP(f), read_OP(f)), "SO(SO(FP))")
89101 else:
90− operand = None
91− operand_type = None
102+ operand = NoOperand()
92103
93− return operand, operand_type
104+ return operand
94105
95106 def read_middle_operand(self, operand, f):
96107
97108 # The middle operand bits are not shifted.
98109
99110 if operand == 0x40:
100− operand = read_OP(f)
101− operand_type = "$SI"
111+ operand = Immediate(read_OP(f), "$SI")
102112 elif operand == 0x80:
103− operand = read_OP(f)
104− operand_type = "SO(FP)"
113+ operand = ShortOffsetFP(read_OP(f), "SO(FP)")
105114 elif operand == 0xc0:
106− operand = read_OP(f)
107− operand_type = "SO(MP)"
115+ operand = ShortOffsetMP(read_OP(f), "SO(MP)")
108116 else:
109− operand = None
110− operand_type = None
117+ operand = NoOperand()
111118
112− return operand, operand_type
119+ 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)
113129
114130 def __repr__(self):
115131
@@ -119,730 +135,336 @@ class Instruction: · 3 unmodified lines
119135 name = hex(self.opcode)
120136
121137 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):
127138
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)
139+ for operand in self.source, self.middle, self.destination:
140+ s = str(operand)
141+ if s:
142+ operands.append(s)
144143
145144 return name + " " + ", ".join(operands)
146145
147146
148−# Define the instructions and their opcode values.
149−
150−class nop(Instruction):
151−
152− opcode = 0x00
153−
154−class alt(Instruction):
155−
156− opcode = 0x01
157−
158−class nbalt(Instruction):
159−
160− opcode = 0x02
161−
162−class goto(Instruction):
163−
164− opcode = 0x03
165−
166−class call(Instruction):
167−
168− opcode = 0x04
169−
170−class frame(Instruction):
171−
172− opcode = 0x05
173−
174−class spawn(Instruction):
175−
176− opcode = 0x06
177−
178−class runt(Instruction):
179−
180− opcode = 0x07
181−
182−class load(Instruction):
183−
184− opcode = 0x08
185−
186−class mcall(Instruction):
187−
188− opcode = 0x09
189−
190−class mspawn(Instruction):
191−
192− opcode = 0x0a
193−
194−class mframe(Instruction):
195−
196− opcode = 0x0b
197−
198−class ret(Instruction):
199−
200− opcode = 0x0c
201−
202−class jmp(Instruction):
203−
204− opcode = 0x0d
205−
206−class case(Instruction):
207−
208− opcode = 0x0e
209−
210−class exit(Instruction):
211−
212− opcode = 0x0f
213−
214−class new(Instruction):
215−
216− opcode = 0x10
217−
218−class newa(Instruction):
219−
220− opcode = 0x11
221−
222−class newcb(Instruction):
223−
224− opcode = 0x12
225−
226−class newcw(Instruction):
227−
228− opcode = 0x13
229−
230−class newcf(Instruction):
231−
232− opcode = 0x14
233−
234−class newcp(Instruction):
235−
236− opcode = 0x15
237−
238−class newcm(Instruction):
239−
240− opcode = 0x16
241−
242−class newcmp(Instruction):
243−
244− opcode = 0x17
245−
246−class send(Instruction):
247−
248− opcode = 0x18
249−
250−class recv(Instruction):
251−
252− opcode = 0x19
253−
254−class consb(Instruction):
255−
256− opcode = 0x1a
257−
258−class consw(Instruction):
259−
260− opcode = 0x1b
261−
262−class consp(Instruction):
263−
264− opcode = 0x1c
265−
266−class consf(Instruction):
267−
268− opcode = 0x1d
269−
270−class consm(Instruction):
271−
272− opcode = 0x1e
273−
274−class consmp(Instruction):
275−
276− opcode = 0x1f
277−
278−class headb(Instruction):
279−
280− opcode = 0x20
281−
282−class headw(Instruction):
283−
284− opcode = 0x21
285−
286−class headp(Instruction):
287−
288− opcode = 0x22
289−
290−class headf(Instruction):
291−
292− opcode = 0x23
293−
294−class headm(Instruction):
295−
296− opcode = 0x24
297−
298−class headmp(Instruction):
299−
300− opcode = 0x25
301−
302−class tail(Instruction):
303−
304− opcode = 0x26
305−
306−class lea(Instruction):
307−
308− opcode = 0x27
309−
310−class indx(Instruction):
311−
312− opcode = 0x28
313−
314−class movp(Instruction):
315−
316− opcode = 0x29
317−
318−class movm(Instruction):
319−
320− opcode = 0x2a
321−
322−class movmp(Instruction):
323−
324− opcode = 0x2b
325−
326−class movb(Instruction):
327−
328− opcode = 0x2c
329−
330−class movw(Instruction):
331−
332− opcode = 0x2d
333−
334−class movf(Instruction):
335−
336− opcode = 0x2e
337−
338−class cvtbw(Instruction):
339−
340− opcode = 0x2f
341−
342−class cvtwb(Instruction):
343−
344− opcode = 0x30
345−
346−class cvtfw(Instruction):
347−
348− opcode = 0x31
349−
350−class cvtwf(Instruction):
351−
352− opcode = 0x32
353−
354−class cvtca(Instruction):
355−
356− opcode = 0x33
357−
358−class cvtac(Instruction):
359−
360− opcode = 0x34
361−
362−class cvtwc(Instruction):
363−
364− opcode = 0x35
365−
366−class cvtcw(Instruction):
367−
368− opcode = 0x36
369−
370−class cvtfc(Instruction):
371−
372− opcode = 0x37
373−
374−class cvtcf(Instruction):
375−
376− opcode = 0x38
377−
378−class addb(Instruction):
379−
380− opcode = 0x39
381−
382−class addw(Instruction):
383−
384− opcode = 0x3a
385−
386−class addf(Instruction):
387−
388− opcode = 0x3b
389−
390−class subb(Instruction):
391−
392− opcode = 0x3c
393−
394−class subw(Instruction):
395−
396− opcode = 0x3d
397−
398−class subf(Instruction):
399−
400− opcode = 0x3e
401−
402−class mulb(Instruction):
403−
404− opcode = 0x3f
405−
406−class mulw(Instruction):
407−
408− opcode = 0x40
409−
410−class mulf(Instruction):
411−
412− opcode = 0x41
413−
414−class divb(Instruction):
415−
416− opcode = 0x42
417−
418−class divw(Instruction):
419−
420− opcode = 0x43
421−
422−class divf(Instruction):
423−
424− opcode = 0x44
425−
426−class modw(Instruction):
427−
428− opcode = 0x45
429−
430−class modb(Instruction):
431−
432− opcode = 0x46
433−
434−class andb(Instruction):
435−
436− opcode = 0x47
437−
438−class andw(Instruction):
439−
440− opcode = 0x48
441−
442−class orb(Instruction):
443−
444− opcode = 0x49
445−
446−class orw(Instruction):
447−
448− opcode = 0x4a
449−
450−class xorb(Instruction):
451−
452− opcode = 0x4b
453−
454−class xorw(Instruction):
455−
456− opcode = 0x4c
457−
458−class shlb(Instruction):
459−
460− opcode = 0x4d
461−
462−class shlw(Instruction):
463−
464− opcode = 0x4e
465−
466−class shrb(Instruction):
467−
468− opcode = 0x4f
469−
470−class shrw(Instruction):
471−
472− opcode = 0x50
473−
474−class insc(Instruction):
475−
476− opcode = 0x51
477−
478−class indc(Instruction):
479−
480− opcode = 0x52
147+# Define the argument types.
481148
482−class addc(Instruction):
149+class NoOperand:
483150
484− opcode = 0x53
485−
486−class lenc(Instruction):
487−
488− opcode = 0x54
489−
490−class lena(Instruction):
491−
492− opcode = 0x55
493−
494−class lenl(Instruction):
495−
496− opcode = 0x56
497−
498−class beqb(Instruction):
499−
500− opcode = 0x57
501−
502−class bneb(Instruction):
503−
504− opcode = 0x58
505−
506−class bltb(Instruction):
507−
508− opcode = 0x59
509−
510−class bleb(Instruction):
511−
512− opcode = 0x5a
513−
514−class bgtb(Instruction):
515−
516− opcode = 0x5b
517−
518−class bgeb(Instruction):
519−
520− opcode = 0x5c
521−
522−class beqw(Instruction):
523−
524− opcode = 0x5d
525−
526−class bnew(Instruction):
527−
528− opcode = 0x5e
529−
530−class bltw(Instruction):
531−
532− opcode = 0x5f
533−
534−class blew(Instruction):
535−
536− opcode = 0x60
537−
538−class bgtw(Instruction):
539−
540− opcode = 0x61
541−
542−class bgew(Instruction):
543−
544− opcode = 0x62
545−
546−class beqf(Instruction):
547−
548− opcode = 0x63
549−
550−class bnef(Instruction):
551−
552− opcode = 0x64
553−
554−class bltf(Instruction):
555−
556− opcode = 0x65
557−
558−class blef(Instruction):
559−
560− opcode = 0x66
561−
562−class bgtf(Instruction):
563−
564− opcode = 0x67
565−
566−class bgef(Instruction):
567−
568− opcode = 0x68
569−
570−class beqc(Instruction):
571−
572− opcode = 0x69
573−
574−class bnec(Instruction):
575−
576− opcode = 0x6a
577−
578−class bltc(Instruction):
579−
580− opcode = 0x6b
581−
582−class blec(Instruction):
583−
584− opcode = 0x6c
585−
586−class bgtc(Instruction):
587−
588− opcode = 0x6d
589−
590−class bgec(Instruction):
591−
592− opcode = 0x6e
593−
594−class slicea(Instruction):
595−
596− opcode = 0x6f
597−
598−class slicela(Instruction):
599−
600− opcod = 0x70
601−
602−class slicec(Instruction):
603−
604− opcode = 0x71
605−
606−class indw(Instruction):
607−
608− opcode = 0x72
609−
610−class indf(Instruction):
611−
612− opcode = 0x73
613−
614−class indb(Instruction):
615−
616− opcode = 0x74
617−
618−class negf(Instruction):
619−
620− opcode = 0x75
621−
622−class movl(Instruction):
623−
624− opcode = 0x76
625−
626−class addl(Instruction):
627−
628− opcode = 0x77
629−
630−class subl(Instruction):
631−
632− opcode = 0x78
633−
634−class divl(Instruction):
635−
636− opcode = 0x79
637−
638−class modl(Instruction):
639−
640− opcode = 0x7a
641−
642−class mull(Instruction):
643−
644− opcode = 0x7b
645−
646−class andl(Instruction):
647−
648− opcode = 0x7c
649−
650−class orl(Instruction):
651−
652− opcode = 0x7d
653−
654−class xorl(Instruction):
655−
656− opcode = 0x7e
657−
658−class shll(Instruction):
659−
660− opcode = 0x7f
661−
662−class shrl(Instruction):
663−
664− opcode = 0x80
665−
666−class bnel(Instruction):
667−
668− opcode = 0x81
669−
670−class bltl(Instruction):
671−
672− opcode = 0x82
673−
674−class blel(Instruction):
675−
676− opcode = 0x83
677−
678−class bgtl(Instruction):
679−
680− opcode = 0x84
681−
682−class bgel(Instruction):
683−
684− opcode = 0x85
685−
686−class beql(Instruction):
687−
688− opcode = 0x86
689−
690−class cvtlf(Instruction):
691−
692− opcode = 0x87
693−
694−class cvtfl(Instruction):
695−
696− opcode = 0x88
697−
698−class cvtlw(Instruction):
699−
700− opcode = 0x89
701−
702−class cvtwl(Instruction):
703−
704− opcode = 0x8a
705−
706−class cvtlc(Instruction):
707−
708− opcode = 0x8b
709−
710−class cvtcl(Instruction):
711−
712− opcode = 0x8c
713−
714−class headl(Instruction):
715−
716− opcode = 0x8d
717−
718−class consl(Instruction):
719−
720− opcode = 0x8e
721−
722−class newcl(Instruction):
723−
724− opcode = 0x8f
725−
726−class casec(Instruction):
727−
728− opcode = 0x90
729−
730−class indl(Instruction):
731−
732− opcode = 0x91
733−
734−class movpc(Instruction):
735−
736− opcode = 0x92
737−
738−class tcmp(Instruction):
739−
740− opcode = 0x93
741−
742−class mnewz(Instruction):
743−
744− opcode = 0x94
745−
746−class cvtrf(Instruction):
747−
748− opcode = 0x95
749−
750−class cvtfr(Instruction):
751−
752− opcode = 0x96
753−
754−class cvtws(Instruction):
755−
756− opcode = 0x97
757−
758−class cvtsw(Instruction):
759−
760− opcode = 0x98
761−
762−class lsrw(Instruction):
763−
764− opcode = 0x99
765−
766−class lsrl(Instruction):
767−
768− opcode = 0x9a
769−
770−class eclr(Instruction):
771−
772− opcode = 0x9b
773−
774−class newz(Instruction):
775−
776− opcode = 0x9c
777−
778−class newaz(Instruction):
779−
780− opcode = 0x9d
781−
782−class raise_(Instruction):
783−
784− opcode = 0x9e
785−
786−class casel(Instruction):
787−
788− opcode = 0x9f
789−
790−class mulx(Instruction):
791−
792− opcode = 0xa0
793−
794−class divx(Instruction):
795−
796− opcode = 0xa1
797−
798−class cvtxx(Instruction):
799−
800− opcode = 0xa2
801−
802−class mulx0(Instruction):
151+ middle_address_mode = 0x00
152+ address_mode = 0x03
153+
154+ def write(self, f):
155+ pass
156+
157+ def __str__(self):
158+ return ""
803159
804− opcode = 0xa3
160+class Operand:
805161
806−class 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)
807172
808− opcode = 0xa4
173+class Immediate(Operand):
174+ str_pattern = "$%x"
175+ middle_address_mode = 0x40
176+ address_mode = 0x02
809177
810−class cvtxx0(Instruction):
178+class LongOffset(Operand):
179+ pass
811180
812− opcode = 0xa5
181+class LongOffsetMP(LongOffset):
182+ str_pattern = "%i(mp)"
183+ address_mode = 0x00
813184
814−class mulx1(Instruction):
185+class LongOffsetFP(LongOffset):
186+ str_pattern = "%i(fp)"
187+ address_mode = 0x01
815188
816− opcode = 0xa6
189+class ShortOffset(Operand):
190+ pass
817191
818−class divx1(Instruction):
192+class ShortOffsetMP(ShortOffset):
193+ str_pattern = "%i(mp)"
194+ middle_address_mode = 0xc0
819195
820− opcode = 0xa7
196+class ShortOffsetFP(ShortOffset):
197+ str_pattern = "%i(fp)"
198+ middle_address_mode = 0x80
821199
822−class cvtxx1(Instruction):
200+class DoubleShortOffset(Operand):
823201
824− opcode = 0xa8
202+ def write(self, f):
203+ write_OP(f, self.value[0] & 0xffff)
204+ write_OP(f, self.value[1] & 0xffff)
825205
826−class cvtfx(Instruction):
206+class DoubleShortOffsetMP(Operand):
207+ str_pattern = "%i(%i(mp))"
208+ address_mode = 0x04
827209
828− opcode = 0xa9
210+class DoubleShortOffsetFP(Operand):
211+ str_pattern = "%i(%i(fp))"
212+ address_mode = 0x05
829213
830−class cvtxf(Instruction):
831214
832− opcode = 0xaa
215+# Define the instructions and their opcode values.
833216
834−class expw(Instruction):
217+class 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()
835225
836− opcode = 0xab
226+class 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()
837234
838−class expl(Instruction):
235+class 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()
839243
840− opcode = 0xac
244+class Src_Src_Dst(Instruction):
841245
842−class 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()
843252
844− opcode = 0xad
253+class Src_Src_src(Instruction):
845254
846−class 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()
847261
848− opcode = 0xae
262+class 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
272+class addx(Src_Src_Dst): pass
273+class andx(Src_Src_Dst): pass
274+class beqx(Src_Src_Dst): pass
275+class bgex(Src_Src_Dst): pass
276+class bgtx(Src_Src_Dst): pass
277+class blex(Src_Src_Dst): pass
278+class bltx(Src_Src_Dst): pass
279+class bnex(Src_Src_Dst): pass
280+class consx(Src_Dst): pass
281+class divx_(Src_Src_Dst): pass
282+class headx(Src_Dst): pass
283+class indx_(Src_Src_Dst): pass
284+class lsrx(Src_Src_Dst): pass
285+class modx(Src_Src_Dst): pass
286+class movx(Src_Dst): pass
287+class mulx_(Src_Src_Dst): pass
288+class newcx(Dst): pass
289+class orx(Src_Src_Dst): pass
290+class shlx(Src_Src_Dst): pass
291+class shrx(Src_Src_Dst): pass
292+class subx(Src_Src_Dst): pass
293+class xorx(Src_Src_Dst): pass
294+
295+# Individual definitions (marked with the file in libinterp with information)
296+class addb(addx): opcode = 0x39
297+class addc(addx): opcode = 0x53
298+class addf(addx): opcode = 0x3b
299+class addl(addx): opcode = 0x77
300+class addw(addx): opcode = 0x3a
301+class alt(Src_Dst): opcode = 0x01
302+class andb(andx): opcode = 0x47
303+class andl(andx): opcode = 0x7c
304+class andw(andx): opcode = 0x48
305+class beqb(beqx): opcode = 0x57
306+class beqc(beqx): opcode = 0x69
307+class beqf(beqx): opcode = 0x63
308+class beql(beqx): opcode = 0x86
309+class beqw(beqx): opcode = 0x5d
310+class bgeb(bgex): opcode = 0x5c
311+class bgec(bgex): opcode = 0x6e
312+class bgef(bgex): opcode = 0x68
313+class bgel(bgex): opcode = 0x85
314+class bgew(bgex): opcode = 0x62
315+class bgtb(bgtx): opcode = 0x5b
316+class bgtc(bgtx): opcode = 0x6d
317+class bgtf(bgtx): opcode = 0x67
318+class bgtl(bgtx): opcode = 0x84
319+class bgtw(bgtx): opcode = 0x61
320+class bleb(blex): opcode = 0x5a
321+class blec(blex): opcode = 0x6c
322+class blef(blex): opcode = 0x66
323+class blel(blex): opcode = 0x83
324+class blew(blex): opcode = 0x60
325+class bltb(bltx): opcode = 0x59
326+class bltc(bltx): opcode = 0x6b
327+class bltf(bltx): opcode = 0x65
328+class bltl(bltx): opcode = 0x82
329+class bltw(bltx): opcode = 0x5f
330+class bneb(bnex): opcode = 0x58
331+class bnec(bnex): opcode = 0x6a
332+class bnef(bnex): opcode = 0x64
333+class bnel(bnex): opcode = 0x81
334+class bnew(bnex): opcode = 0x5e
335+class call(Src_Dst): opcode = 0x04
336+class case(Src_Dst): opcode = 0x0e
337+class casec(Src_Dst): opcode = 0x90
338+class casel(Src_Dst): opcode = 0x9f ### check syntax
339+class consb(consx): opcode = 0x1a
340+class consf(consx): opcode = 0x1d
341+class consl(consx): opcode = 0x8e
342+class consm(consx): opcode = 0x1e
343+class consmp(consx): opcode = 0x1f
344+class consp(consx): opcode = 0x1c
345+class consw(consx): opcode = 0x1b
346+class cvtac(Src_Dst): opcode = 0x34
347+class cvtbw(Src_Dst): opcode = 0x2f
348+class cvtca(Src_Dst): opcode = 0x33
349+class cvtcf(Src_Dst): opcode = 0x38
350+class cvtcl(Src_Dst): opcode = 0x8c
351+class cvtcw(Src_Dst): opcode = 0x36
352+class cvtfc(Src_Dst): opcode = 0x37
353+class cvtfl(Src_Dst): opcode = 0x88
354+class cvtfr(Src_Dst): opcode = 0x96
355+class cvtfw(Src_Dst): opcode = 0x31
356+class cvtfx(Src_Dst): opcode = 0xa9
357+class cvtlc(Src_Dst): opcode = 0x8b
358+class cvtlf(Src_Dst): opcode = 0x87
359+class cvtlw(Src_Dst): opcode = 0x89
360+class cvtrf(Src_Dst): opcode = 0x95
361+class cvtsw(Src_Dst): opcode = 0x98 # short to word (xec.c)
362+class cvtwb(Src_Dst): opcode = 0x30 # word to byte (xec.c)
363+class cvtwc(Src_Dst): opcode = 0x35 # word to char array (string.c)
364+class cvtwf(Src_Dst): opcode = 0x32 # word to float (xec.c)
365+class cvtwl(Src_Dst): opcode = 0x8a # word to long (xec.c)
366+class cvtws(Src_Dst): opcode = 0x97 # word to short (xec.c)
367+class cvtxf(Src_Src_Dst): opcode = 0xaa # word * float -> float (xec.c)
368+class cvtxx0(Src_Src_Dst): opcode = 0xa5 ### word ? word -> word (xec.c)
369+class cvtxx1(Src_Src_Dst): opcode = 0xa8 ### word ? word -> word (xec.c)
370+class cvtxx(Src_Src_Dst): opcode = 0xa2 ### word ? word -> word (xec.c)
371+class divb(divx_): opcode = 0x42
372+class divf(divx_): opcode = 0x44
373+class divl(divx_): opcode = 0x79
374+class divw(divx_): opcode = 0x43
375+class divx0(divx_): opcode = 0xa4 # (xec.c)
376+class divx1(divx_): opcode = 0xa7 # (xec.c)
377+class divx(divx_): opcode = 0xa1 # (xec.c)
378+class eclr(Instruction): opcode = 0x9b # unused
379+class exit(Instruction): opcode = 0x0f
380+class expf(Src_Src_Dst): opcode = 0xad # word word -> float (xec.c)
381+class expl(Src_Src_Dst): opcode = 0xac # word long -> long (xec.c)
382+class expw(Src_Src_Dst): opcode = 0xab # word word -> word (xec.c)
383+class frame(Src_Src): opcode = 0x05
384+class goto(Src_Dst): opcode = 0x03
385+class headb(headx): opcode = 0x20
386+class headf(headx): opcode = 0x23
387+class headl(headx): opcode = 0x8d
388+class headm(headx): opcode = 0x24
389+class headmp(headx): opcode = 0x25
390+class headp(headx): opcode = 0x22
391+class headw(headx): opcode = 0x21
392+class indb(indx_): opcode = 0x74
393+class indc(Src_Src_Dst): opcode = 0x52
394+class indf(indx_): opcode = 0x73
395+class indl(indx_): opcode = 0x91
396+class indw(indx_): opcode = 0x72
397+class indx(Src_Src_Dst): opcode = 0x28
398+class insc(Src_Src_Dst): opcode = 0x51
399+class jmp(Dst): opcode = 0x0d
400+class lea(Src_Dst): opcode = 0x27
401+class lena(Src_Dst): opcode = 0x55
402+class lenc(Src_Dst): opcode = 0x54
403+class lenl(Src_Dst): opcode = 0x56
404+class load(Src_Src_Dst): opcode = 0x08
405+class lsrl(lsrx): opcode = 0x9a
406+class lsrw(lsrx): opcode = 0x99
407+class mcall(Src_Src_src): opcode = 0x09
408+class mframe(Src_Src_Dst): opcode = 0x0b
409+class mnewz(Src_Src_Dst): opcode = 0x94
410+class modb(modx): opcode = 0x46
411+class modl(modx): opcode = 0x7a
412+class modw(modx): opcode = 0x45
413+class movb(movx): opcode = 0x2c
414+class movf(movx): opcode = 0x2e
415+class movl(movx): opcode = 0x76
416+class movm(Src_Src_Dst): opcode = 0x2a
417+class movmp(Src_Src_Dst): opcode = 0x2b
418+class movpc(Src_Dst): opcode = 0x92
419+class movp(Src_Dst): opcode = 0x29
420+class movw(movx): opcode = 0x2d
421+class mspawn(Src_Src_src): opcode = 0x0a
422+class mulb(mulx_): opcode = 0x3f
423+class mulf(mulx_): opcode = 0x41
424+class mull(mulx_): opcode = 0x7b
425+class mulw(mulx_): opcode = 0x40
426+class mulx0(mulx_): opcode = 0xa3 ### word * word -> word (xec.c)
427+class mulx1(mulx_): opcode = 0xa6 ### word * word -> word (xec.c)
428+class mulx(mulx_): opcode = 0xa0 ### word * word -> word (xec.c)
429+class nbalt(Src_Dst): opcode = 0x02
430+class negf(Src_Dst): opcode = 0x75
431+class new(Src_Dst): opcode = 0x10
432+class newa(Src_Src_Dst): opcode = 0x11
433+class newaz(Src_Src_Dst): opcode = 0x9d
434+class newcb(newcx): opcode = 0x12
435+class newcf(newcx): opcode = 0x14
436+class newcl(newcx): opcode = 0x8f
437+class newcm(newcx): opcode = 0x16
438+class newcmp(newcx): opcode = 0x17
439+class newcp(newcx): opcode = 0x15
440+class newcw(newcx): opcode = 0x13
441+class newz(Src_Dst): opcode = 0x9c
442+class nop(Instruction): opcode = 0x00
443+class orb(orx): opcode = 0x49
444+class orl(orx): opcode = 0x7d
445+class orw(orx): opcode = 0x4a
446+class raise_(Src): opcode = 0x9e ### type (xec.c)
447+class recv(Src_Dst): opcode = 0x19
448+class ret(Instruction): opcode = 0x0c
449+class runt(Instruction): opcode = 0x07 ### no operands (xec.c)
450+class self(Instruction): opcode = 0xae ### no operands? (xec.c)
451+class send(Src_Dst): opcode = 0x18
452+class shlb(shlx): opcode = 0x4d
453+class shll(shlx): opcode = 0x7f
454+class shlw(shlx): opcode = 0x4e
455+class shrb(shrx): opcode = 0x4f
456+class shrl(shrx): opcode = 0x80
457+class shrw(shrx): opcode = 0x50
458+class slicea(Src_Src_Dst): opcode = 0x6f
459+class slicec(Src_Src_Dst): opcode = 0x71
460+class slicela(Src_Src_Dst): opcode = 0x70
461+class spawn(Src_Dst): opcode = 0x06
462+class subb(subx): opcode = 0x3c
463+class subf(subx): opcode = 0x3e
464+class subl(subx): opcode = 0x78
465+class subw(subx): opcode = 0x3d
466+class tail(Src_Dst): opcode = 0x26
467+class tcmp(Src_Dst): opcode = 0x93
468+class xorb(xorx): opcode = 0x4b
469+class xorl(xorx): opcode = 0x7e
470+class 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
1515 along with this program. If not, see <http://www.gnu.org/licenses/>.
1616 """
1717
18+import md5
1819 from struct import calcsize, pack, unpack
1920
2021 def _read(f, format):
@@ -83,6 +84,71 @@ def read_C(f): · 62 unmodified lines
8384
8485 return s
8586
87+def _write(f, format, value):
88+
89+ f.write(pack(format, value))
90+
91+def write_B(f, value):
92+ # byte, 8-bit unsigned
93+ f.write(pack(">B", value))
94+
95+def 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+
109+def write_W(f, value):
110+ # 32-bit word
111+ f.write(pack(">i", value))
112+
113+def write_F(f, value):
114+ # 64-bit float
115+ f.write(pack(">d", value))
116+
117+def write_L(f, value):
118+ # 64-bit big integer
119+ # Signed or unsigned? Assume signed for now.
120+ f.write(pack(">q", value))
121+
122+def write_P(f, value):
123+ # 32-bit pointer
124+ f.write(pack(">I", value))
125+
126+def write_C(f, value):
127+ # UTF-8 encoded string
128+ f.write(value)
129+ f.write("\x00")
130+
131+# Higher level data handling
132+
133+def 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+
86152 # Currently unused:
87153
88154 def read_SO(f):