-
Notifications
You must be signed in to change notification settings - Fork 138
/
m0_hash.m0
161 lines (134 loc) · 3.36 KB
/
m0_hash.m0
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
.version 0
.chunk "byte_ops_test"
.constants
0 "1..1\n"
1 "ok 1 hash of jellyfish string is correct\n"
2 "nok 1 hash of jellyfish string is not correct\n"
3 "I wish I were a jellyfish that cannot fall down stairs."
#3 "jellyfish"
4 67827064
5 "step "
6 ": tmp = "
7 "\n"
8 ": hash = "
.metadata
.bytecode
# 'x' => 120
# 'quux' => 3281278855
# 'I wish I were a jellyfish that cannot fall down stairs.' => 67827064
set_imm I0, 0, 1
set_imm S0, 0, 0
deref S0, CONSTS, S0
print_s I0, S0, x
##################################
# calculate the hash of string 3 #
##################################
hash_calc_init:
# set up some constants for debugging output
set_imm S10, 0, 5
deref S10, CONSTS, S10
set_imm S11, 0, 6
deref S11, CONSTS, S11
set_imm S12, 0, 7
deref S12, CONSTS, S12
set_imm S0, 0, 3
deref S0, CONSTS, S0
# I1 = number of bytes in string
set_imm I1, 0, 0
get_word I1, S0, I1
sub_i I1, I1, I0
# I2 = index into string (excluding header)
set_imm I2, 0, 0
# I3 = tmp
set_imm I3, 0, 0
# I4 = current hash value (hash)
set_imm I4, 0, 0
# I5 = temporary register for hash calculations
set_imm I5, 0, 0
#enable debugging output
set_imm I25, 0, 0
# algorithm:
# while (ch = *str++)
# hash = ch + (hash << 6) + (hash << 16) - hash;
hash_loop_start:
# tmp = current character of string
set_imm I3, 0, 8
add_i I3, I3, I2
get_byte I3, S0, I3
# debugging output
goto_if end_debug_1, I25
print_s I0, S10, x
set_imm I10, 0, 1
print_i I0, I10, x
set_imm S11, 0, 6
deref S11, CONSTS, S11
print_s I0, S11, x
print_i I0, I3, x
print_s I0, S12, x
end_debug_1:
# tmp += (hash << 6);
set_imm I5, 0, 6
shl I5, I4, I5
add_i I3, I3, I5
# debugging output
goto_if end_debug_2, I25
print_s I0, S10, x
set_imm I10, 0, 2
print_i I0, I10, x
print_s I0, S11, x
print_i I0, I3, x
print_s I0, S12, x
end_debug_2:
# tmp += (hash << 16);
set_imm I5, 0, 16
shl I5, I4, I5
add_i I3, I3, I5
# debugging output
goto_if end_debug_3, I25
print_s I0, S10, x
set_imm I10, 0, 3
print_i I0, I10, x
print_s I0, S11, x
print_i I0, I3, x
print_s I0, S12, x
end_debug_3:
# hash = tmp - hash;
sub_i I4, I3, I4
# debugging output
goto_if end_debug_4, I25
print_s I0, S10, x
set_imm I10, 0, 4
print_i I0, I10, x
set_imm S11, 0, 8
deref S11, CONSTS, S11
print_s I0, S11, x
print_i I0, I4, x
print_s I0, S12, x
end_debug_4:
# increment the index into the string
set_imm I5, 0, 1
add_i I2, I2, I5
# if we're at the end of the string, break
sub_i I5, I2, I1
goto_if hash_loop_start, I5
goto hash_loop_end, x
hash_loop_end:
# I4 contains the calculated hash
# store known-good hash in I1
set_imm I1, 0, 4
deref I1, CONSTS, I1
sub_i I1, I1, I4
goto_if hash_test_fail, I1
goto hash_test_ok, x
hash_test_fail:
set_imm S0, 0, 2
print_i I0, I4, x
goto print_result, x
hash_test_ok:
set_imm S0, 0, 1
goto print_result, x
print_result:
deref S0, CONSTS, S0
print_s I0, S0, x
# This code isn't really PASM, but the highlighting works well.
# vim: expandtab shiftwidth=4 ft=pasm: