summaryrefslogtreecommitdiff
path: root/2018/21_notes.txt
blob: 905f861ea17a922cac2481d067556642668d3dcb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
L0: // r4 <- 123
    // r4 <- 72
    // r4 <- 1
    jmp L1
    // jmp L0
L1: r4 <- 0
L2: r3 <- r4 | 65536
    r4 <- 3730679
L3: // r5 <- r3 & 255
    // r4 <- r4 + (r3 & 255)
    // r4 <- (r4 + (r3 & 255)) & 16777215
    // r4 <- ((r4 + (r3 & 255)) & 16777215) * 65899
    r4 <- (((r4 + (r3 & 255)) & 16777215) * 65899) & 16777215
    // r5 <- 256 > r3
    if (r3 >= 256)
        then jmp L4
        else jmp L8
L4: r5 <- 0
L5: r2 <- r5 + 1
    r2 <- r2 * 256
    // r2 <- r2 > r3
    if (r2 <= r3)
        then jmp L6
        else jmp L7
L6: r5 <- r5 + 1
    jmp L5
L7: r3 <- r5
    jmp L3
L8: // r5 <- r4 == r0
    if (r4 != r0)
        then jmp L2
        [else exit]


            ↓‾‾‾‾‾‾‾‾‾‾‾|
0 → 1 → 2 → 3 → 4 → 5 → 7
        ↑   ↓       ↕
        └── 8       6
            ↓
            *

L5:
loop {
    r2 = (r5 + 1) * 256;
    if r2 > r3 { jmp L7; }
    r5 += 1;
}

L5:
Let x = ceil((r3 + 1) / 256).
Set r5 = x - 1; r2 = x * 256.
Jump to L7.
This takes (x+1)*5+2*x = 7*x+5 instructions.


// --------------------------


L0: jmp L1 [4 instrs]
L1: r4 <- 0
L2: r3 <- r4 | 65536
    r4 <- 3730679
L3: r4 <- (((r4 + (r3 & 0xff)) & 0xffffff) * 65899) & 0xffffff [6 instrs]
    if (r3 >= 256)
        then jmp L4
        else jmp L8
L4: Set r3 = ceil((r3 + 1) / 256) - 1. [7*ceil((r3+1)/256)+6 instrs]
    jmp L3
L8: // r5 <- r4 == r0
    if (r4 != r0)
        then jmp L2
        [else exit]


            ↓‾‾‾|
0 → 1 → 2 → 3 → 4
        ↑   ↓
        └── 8
            ↓
            *


// --------------------------


Earliest exit is if r0 is equal to the value in r4 on the first arrival at L8.


L3:
loop {
    r4 = (((r4 + (r3 & 0xff)) & 0xffffff) * 65899) & 0xffffff  [6 instrs]
    if r3 < 256 { jmp L8 }
    r3 = ceil((r3 + 1) / 256) - 1  [7*ceil((r3+1)/256)+6 instrs]
}

exit at 8
-> r4 == r0 at end of 3, jmp to 8
-> r4 == r0 and r3 < 256 at end of 3
-> r3 < 256 and r0 == (((r4 + (r3 & 255)) & 16777215) * 65899) & 16777215 at start of 3
-> r3 < 256 and r0 == (r4 + r3) * 65899 (mod 2^24) at start of 3