History

Annotated the test further. Added more information to the string representation of Type objects. Fixed the order of the offsets in the string representation of offsets in double indirect operands. Updated the notes.

David Boddie committed 9 years ago

Commit a8c27d91 parent de9ef054 files · +63 −20Browse files

Unified · Split

4 files
  1. Tests/count.py +42 −16
  2. dis.py +2 −2
  3. docs/notes.txt +17 −0
  4. opcodes.py +2 −2
Tests/count.py+42−16
@@ -5,6 +5,7 @@ import sys · 4 unmodified lines
55 import dis
66 import opcodes
77 from opcodes import Imm, LOfp, LOmp, NoOp, SOfp, SOmp, SOSOfp, SOSOmp
8+from utils import hash_signature
89
910 if __name__ == "__main__":
1011
@@ -19,28 +20,53 @@ if __name__ == "__main__": · 8 unmodified lines
1920 d.entry_pc = 0
2021 d.entry_type = 2 # refers to Type 2
2122
23+ # implement count;
24+ #
25+ # include "sys.m";
26+ # include "draw.m";
27+ #
28+ # count: module
29+ # {
30+ # init: fn(ctxt: ref Draw->Context, args: list of string);
31+ # };
32+ #
33+ # init(ctxt: ref Draw->Context, args: list of string)
34+ # {
35+ # sys := load Sys Sys->PATH;
36+ # sys->print("Counting...\n");
37+ # for (i := 0; i < 20; i++)
38+ # sys->print("%d\n", i);
39+ # }
40+
2241 d.code = [
23− opcodes.load(LOmp(0), Imm(0), LOfp(44)),
24− opcodes.frame(Imm(1), LOfp(52)),
25− opcodes.movp(LOmp(8), SOSOfp(52, 32)),
26− opcodes.lea(LOfp(48), SOSOfp(52, 16)),
27− opcodes.mcall(LOfp(52), Imm(0), LOfp(44)),
28− opcodes.movw(Imm(0), LOfp(40)),
29− opcodes.blew(Imm(0x14), SOfp(40), Imm(0xe)),
30− opcodes.frame(Imm(1), LOfp(48)),
31− opcodes.movp(LOmp(4), SOSOfp(48, 32)),
42+ opcodes.load(LOmp(0), Imm(0), LOfp(44)), # "$Sys", ldt[0] -> module
43+
44+ opcodes.frame(Imm(1), LOfp(52)), # types[1] -> new_frame1 (ptr)
45+ opcodes.movp(LOmp(8), SOSOfp(52, 32)), # "Counting..." ->
46+ opcodes.lea(LOfp(48), SOSOfp(52, 16)), #
47+ opcodes.mcall(LOfp(52), Imm(0), LOfp(44)), # new_frame1, ldt[0], module
48+
49+ opcodes.movw(Imm(0), LOfp(40)), # 0 -> i (int)
50+ opcodes.blew(Imm(0x14), SOfp(40), Imm(0xe)),# 0x6: if 20 <= i branch to 0xe
51+
52+ opcodes.frame(Imm(1), LOfp(48)), # types[1] -> new_frame2 (ptr)
53+ opcodes.movp(LOmp(4), SOSOfp(48, 32)), # "%d\n" ->
3254 opcodes.movw(LOfp(40), SOSOfp(48, 36)),
33− opcodes.lea(LOfp(52), SOSOfp(48, 16)),
34− opcodes.mcall(LOfp(48), Imm(0), LOfp(44)),
35− opcodes.addw(Imm(1), NoOp(), LOfp(40)),
36− opcodes.jmp(Imm(6)),
37− opcodes.ret()
55+ opcodes.lea(LOfp(52), SOSOfp(48, 16)), # new_frame1 ->
56+ opcodes.mcall(LOfp(48), Imm(0), LOfp(44)), # new_frame2, ldt[0]
57+
58+ opcodes.addw(Imm(1), NoOp(), LOfp(40)), # 1 + [i] -> i
59+ opcodes.jmp(Imm(6)), # jump to 0x6
60+ opcodes.ret() # 0xe: return
3861 ]
3962
4063 d.types = [
4164 dis.Type(0, 16, 1, "\xf0"),
4265 dis.Type(1, 40, 2, "\x00\x80"),
43− dis.Type(2, 56, 2, "\x00\xd0") # stack frame type, entry type
66+ # Type 2 is the stack frame type (see below), entry type (see above),
67+ # 56 bytes (14 words) in size:
68+ # pointer bitmap: 0 0 0 0 0 0 0 0 | 1 1 0 1 0 0 [0 0]
69+ dis.Type(2, 56, 2, "\x00\xd0")
4470 ]
4571
4672 d.data = {
@@ -53,7 +79,7 @@ if __name__ == "__main__": · 6 unmodified lines
5379 d.module_name = "count"
5480 d.link = [dis.Link(0, 2, 0x4244b354, "init")] # refers to Type 2
5581 d.initialised_globals = 1
56− d.ldt = [[dis.LDT(0xac849033, "print")]]
82+ d.ldt = [[dis.LDT(hash_signature("f*(s)i"), "print")]]
5783 d.path = sys.argv[0]
5884
5985 d.write(open(sys.argv[1], "w"))
dis.py+2−2
@@ -349,8 +349,8 @@ class Type: · 348 unmodified lines
349349
350350 def __repr__(self):
351351
352− return "Type(desc=%i, size=%i, ptrs=%i)" % (self.desc_number,
353− self.size, self.number_ptrs)
352+ return "Type(desc=%i, size=%i, ptrs=%i, array=%s)" % (self.desc_number,
353+ self.size, self.number_ptrs, repr(self.array))
354354
355355 def is_pointer(self, address):
356356
docs/notes.txt+17−0
@@ -1,7 +1,13 @@
1+Opcode definitions
2+------------------
3+
14 Opcodes are defined in include/isa.h, limbo/optab.c and libinterp/xec.c.
25
36 consc is documented but does not exist in the opcode definitions.
47
8+Function signatures
9+-------------------
10+
511 Function signatures will be output by the Limbo compiler if you pass it the
612 "-D S" debug option.
713
@@ -45,3 +51,14 @@ endianness of the resulting value: · 37 unmodified lines
4551 The rtsign and idsign functions in the limbo/types.c file are responsible for
4652 creating a signature for a function. The sigkind array contains the characters
4753 used for each type of object that will be serialised.
54+
55+Operands
56+--------
57+
58+The double indirect operands SO(SO(fp)) and SO(SO(mp)) are represented by two
59+offsets in the encoded instruction. The first represents the "inner" offset,
60+the second the "outer" offset. For example:
61+
62+ 10(20(fp)) is represented as 20, 10 in the instruction.
63+
64+This was discovered by running the Limbo compiler with the -S option.
opcodes.py+2−2
@@ -158,7 +158,7 @@ class Operand: · 157 unmodified lines
158158 write_OP(f, self.value)
159159
160160 class Immediate(Operand):
161− str_pattern = "$%x"
161+ str_pattern = "$0x%x"
162162 middle_address_mode = 0x40
163163 address_mode = 0x02
164164
@@ -193,7 +193,7 @@ class DoubleShortOffset(Operand): · 28 unmodified lines
193193 self.annotation = annotation
194194
195195 def __str__(self):
196− return self.str_pattern % (self.offset0, self.offset1)
196+ return self.str_pattern % (self.offset1, self.offset0)
197197
198198 def write(self, f):
199199 write_OP(f, self.offset0 & 0xffff)