xref: /btstack/3rd-party/micro-ecc/scripts/mult_avr.py (revision 6ccd8248590f666db07dd7add13fecb4f5664fb5)
1*6ccd8248SMilanka Ringwald#!/usr/bin/env python3
2af03003cSMatthias Ringwald
3af03003cSMatthias Ringwaldimport sys
4af03003cSMatthias Ringwald
5af03003cSMatthias Ringwaldif len(sys.argv) < 2:
6*6ccd8248SMilanka Ringwald    print("Provide the integer size in bytes")
7af03003cSMatthias Ringwald    sys.exit(1)
8af03003cSMatthias Ringwald
9af03003cSMatthias Ringwaldsize = int(sys.argv[1])
10af03003cSMatthias Ringwald
11af03003cSMatthias Ringwaldfull_rows = size // 10
12af03003cSMatthias Ringwaldinit_size = size % 10
13af03003cSMatthias Ringwald
14af03003cSMatthias Ringwaldif init_size == 0:
15af03003cSMatthias Ringwald    full_rows = full_rows - 1
16af03003cSMatthias Ringwald    init_size = 10
17af03003cSMatthias Ringwald
18af03003cSMatthias Ringwalddef rx(i):
19af03003cSMatthias Ringwald    return i + 2
20af03003cSMatthias Ringwald
21af03003cSMatthias Ringwalddef ry(i):
22af03003cSMatthias Ringwald    return i + 12
23af03003cSMatthias Ringwald
24af03003cSMatthias Ringwalddef emit(line, *args):
25af03003cSMatthias Ringwald    s = '"' + line + r' \n\t"'
26*6ccd8248SMilanka Ringwald    print(s % args)
27af03003cSMatthias Ringwald
28af03003cSMatthias Ringwald#### set up registers
29af03003cSMatthias Ringwaldemit("adiw r30, %s", size - init_size) # move z
30af03003cSMatthias Ringwaldemit("adiw r28, %s", size - init_size) # move y
31af03003cSMatthias Ringwald
32*6ccd8248SMilanka Ringwaldfor i in range(init_size):
33af03003cSMatthias Ringwald    emit("ld r%s, x+", rx(i))
34*6ccd8248SMilanka Ringwaldfor i in range(init_size):
35af03003cSMatthias Ringwald    emit("ld r%s, y+", ry(i))
36af03003cSMatthias Ringwald
37af03003cSMatthias Ringwaldemit("ldi r25, 0")
38*6ccd8248SMilanka Ringwaldprint("")
39af03003cSMatthias Ringwaldif init_size == 1:
40af03003cSMatthias Ringwald    emit("mul r2, r12")
41af03003cSMatthias Ringwald    emit("st z+, r0")
42af03003cSMatthias Ringwald    emit("st z+, r1")
43af03003cSMatthias Ringwaldelse:
44af03003cSMatthias Ringwald    #### first two multiplications of initial block
45af03003cSMatthias Ringwald    emit("ldi r23, 0")
46af03003cSMatthias Ringwald    emit("mul r2, r12")
47af03003cSMatthias Ringwald    emit("st z+, r0")
48af03003cSMatthias Ringwald    emit("mov r22, r1")
49*6ccd8248SMilanka Ringwald    print("")
50af03003cSMatthias Ringwald    emit("ldi r24, 0")
51af03003cSMatthias Ringwald    emit("mul r2, r13")
52af03003cSMatthias Ringwald    emit("add r22, r0")
53af03003cSMatthias Ringwald    emit("adc r23, r1")
54af03003cSMatthias Ringwald    emit("mul r3, r12")
55af03003cSMatthias Ringwald    emit("add r22, r0")
56af03003cSMatthias Ringwald    emit("adc r23, r1")
57af03003cSMatthias Ringwald    emit("adc r24, r25")
58af03003cSMatthias Ringwald    emit("st z+, r22")
59*6ccd8248SMilanka Ringwald    print("")
60af03003cSMatthias Ringwald
61af03003cSMatthias Ringwald    #### rest of initial block, with moving accumulator registers
62af03003cSMatthias Ringwald    acc = [23, 24, 22]
63*6ccd8248SMilanka Ringwald    for r in range(2, init_size):
64af03003cSMatthias Ringwald        emit("ldi r%s, 0", acc[2])
65*6ccd8248SMilanka Ringwald        for i in range(0, r+1):
66af03003cSMatthias Ringwald            emit("mul r%s, r%s", rx(i), ry(r - i))
67af03003cSMatthias Ringwald            emit("add r%s, r0", acc[0])
68af03003cSMatthias Ringwald            emit("adc r%s, r1", acc[1])
69af03003cSMatthias Ringwald            emit("adc r%s, r25", acc[2])
70af03003cSMatthias Ringwald        emit("st z+, r%s", acc[0])
71*6ccd8248SMilanka Ringwald        print("")
72af03003cSMatthias Ringwald        acc = acc[1:] + acc[:1]
73*6ccd8248SMilanka Ringwald    for r in range(1, init_size-1):
74af03003cSMatthias Ringwald        emit("ldi r%s, 0", acc[2])
75*6ccd8248SMilanka Ringwald        for i in range(0, init_size-r):
76af03003cSMatthias Ringwald            emit("mul r%s, r%s", rx(r+i), ry((init_size-1) - i))
77af03003cSMatthias Ringwald            emit("add r%s, r0", acc[0])
78af03003cSMatthias Ringwald            emit("adc r%s, r1", acc[1])
79af03003cSMatthias Ringwald            emit("adc r%s, r25", acc[2])
80af03003cSMatthias Ringwald        emit("st z+, r%s", acc[0])
81*6ccd8248SMilanka Ringwald        print("")
82af03003cSMatthias Ringwald        acc = acc[1:] + acc[:1]
83af03003cSMatthias Ringwald    emit("mul r%s, r%s", rx(init_size-1), ry(init_size-1))
84af03003cSMatthias Ringwald    emit("add r%s, r0", acc[0])
85af03003cSMatthias Ringwald    emit("adc r%s, r1", acc[1])
86af03003cSMatthias Ringwald    emit("st z+, r%s", acc[0])
87af03003cSMatthias Ringwald    emit("st z+, r%s", acc[1])
88*6ccd8248SMilanka Ringwaldprint("")
89af03003cSMatthias Ringwald
90af03003cSMatthias Ringwald#### reset y and z pointers
91af03003cSMatthias Ringwaldemit("sbiw r30, %s", 2 * init_size + 10)
92af03003cSMatthias Ringwaldemit("sbiw r28, %s", init_size + 10)
93af03003cSMatthias Ringwald
94af03003cSMatthias Ringwald#### load y registers
95*6ccd8248SMilanka Ringwaldfor i in range(10):
96af03003cSMatthias Ringwald    emit("ld r%s, y+", ry(i))
97af03003cSMatthias Ringwald
98af03003cSMatthias Ringwald#### load additional x registers
99*6ccd8248SMilanka Ringwaldfor i in range(init_size, 10):
100af03003cSMatthias Ringwald    emit("ld r%s, x+", rx(i))
101*6ccd8248SMilanka Ringwaldprint("")
102af03003cSMatthias Ringwald
103af03003cSMatthias Ringwaldprev_size = init_size
104*6ccd8248SMilanka Ringwaldfor row in range(full_rows):
105af03003cSMatthias Ringwald    #### do x = 0-9, y = 0-9 multiplications
106af03003cSMatthias Ringwald    emit("ldi r23, 0")
107af03003cSMatthias Ringwald    emit("mul r2, r12")
108af03003cSMatthias Ringwald    emit("st z+, r0")
109af03003cSMatthias Ringwald    emit("mov r22, r1")
110*6ccd8248SMilanka Ringwald    print("")
111af03003cSMatthias Ringwald    emit("ldi r24, 0")
112af03003cSMatthias Ringwald    emit("mul r2, r13")
113af03003cSMatthias Ringwald    emit("add r22, r0")
114af03003cSMatthias Ringwald    emit("adc r23, r1")
115af03003cSMatthias Ringwald    emit("mul r3, r12")
116af03003cSMatthias Ringwald    emit("add r22, r0")
117af03003cSMatthias Ringwald    emit("adc r23, r1")
118af03003cSMatthias Ringwald    emit("adc r24, r25")
119af03003cSMatthias Ringwald    emit("st z+, r22")
120*6ccd8248SMilanka Ringwald    print("")
121af03003cSMatthias Ringwald
122af03003cSMatthias Ringwald    acc = [23, 24, 22]
123*6ccd8248SMilanka Ringwald    for r in range(2, 10):
124af03003cSMatthias Ringwald        emit("ldi r%s, 0", acc[2])
125*6ccd8248SMilanka Ringwald        for i in range(0, r+1):
126af03003cSMatthias Ringwald            emit("mul r%s, r%s", rx(i), ry(r - i))
127af03003cSMatthias Ringwald            emit("add r%s, r0", acc[0])
128af03003cSMatthias Ringwald            emit("adc r%s, r1", acc[1])
129af03003cSMatthias Ringwald            emit("adc r%s, r25", acc[2])
130af03003cSMatthias Ringwald        emit("st z+, r%s", acc[0])
131*6ccd8248SMilanka Ringwald        print("")
132af03003cSMatthias Ringwald        acc = acc[1:] + acc[:1]
133af03003cSMatthias Ringwald
134af03003cSMatthias Ringwald    #### now we need to start shifting x and loading from z
135af03003cSMatthias Ringwald    x_regs = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
136*6ccd8248SMilanka Ringwald    for r in range(0, prev_size):
137af03003cSMatthias Ringwald        x_regs = x_regs[1:] + x_regs[:1]
138af03003cSMatthias Ringwald        emit("ld r%s, x+", x_regs[9]) # load next byte of left
139af03003cSMatthias Ringwald        emit("ldi r%s, 0", acc[2])
140*6ccd8248SMilanka Ringwald        for i in range(0, 10):
141af03003cSMatthias Ringwald            emit("mul r%s, r%s", x_regs[i], ry(9 - i))
142af03003cSMatthias Ringwald            emit("add r%s, r0", acc[0])
143af03003cSMatthias Ringwald            emit("adc r%s, r1", acc[1])
144af03003cSMatthias Ringwald            emit("adc r%s, r25", acc[2])
145af03003cSMatthias Ringwald        emit("ld r0, z") # load stored value from initial block, and add to accumulator (note z does not increment)
146af03003cSMatthias Ringwald        emit("add r%s, r0", acc[0])
147af03003cSMatthias Ringwald        emit("adc r%s, r25", acc[1])
148af03003cSMatthias Ringwald        emit("adc r%s, r25", acc[2])
149af03003cSMatthias Ringwald        emit("st z+, r%s", acc[0]) # store next byte (z increments)
150*6ccd8248SMilanka Ringwald        print("")
151af03003cSMatthias Ringwald        acc = acc[1:] + acc[:1]
152af03003cSMatthias Ringwald
153af03003cSMatthias Ringwald    # done shifting x, start shifting y
154af03003cSMatthias Ringwald    y_regs = [12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
155*6ccd8248SMilanka Ringwald    for r in range(0, prev_size):
156af03003cSMatthias Ringwald        y_regs = y_regs[1:] + y_regs[:1]
157af03003cSMatthias Ringwald        emit("ld r%s, y+", y_regs[9]) # load next byte of right
158af03003cSMatthias Ringwald        emit("ldi r%s, 0", acc[2])
159*6ccd8248SMilanka Ringwald        for i in range(0, 10):
160af03003cSMatthias Ringwald            emit("mul r%s, r%s", x_regs[i], y_regs[9 -i])
161af03003cSMatthias Ringwald            emit("add r%s, r0", acc[0])
162af03003cSMatthias Ringwald            emit("adc r%s, r1", acc[1])
163af03003cSMatthias Ringwald            emit("adc r%s, r25", acc[2])
164af03003cSMatthias Ringwald        emit("ld r0, z") # load stored value from initial block, and add to accumulator (note z does not increment)
165af03003cSMatthias Ringwald        emit("add r%s, r0", acc[0])
166af03003cSMatthias Ringwald        emit("adc r%s, r25", acc[1])
167af03003cSMatthias Ringwald        emit("adc r%s, r25", acc[2])
168af03003cSMatthias Ringwald        emit("st z+, r%s", acc[0]) # store next byte (z increments)
169*6ccd8248SMilanka Ringwald        print("")
170af03003cSMatthias Ringwald        acc = acc[1:] + acc[:1]
171af03003cSMatthias Ringwald
172af03003cSMatthias Ringwald    # done both shifts, do remaining corner
173*6ccd8248SMilanka Ringwald    for r in range(1, 9):
174af03003cSMatthias Ringwald        emit("ldi r%s, 0", acc[2])
175*6ccd8248SMilanka Ringwald        for i in range(0, 10-r):
176af03003cSMatthias Ringwald            emit("mul r%s, r%s", x_regs[r+i], y_regs[9 - i])
177af03003cSMatthias Ringwald            emit("add r%s, r0", acc[0])
178af03003cSMatthias Ringwald            emit("adc r%s, r1", acc[1])
179af03003cSMatthias Ringwald            emit("adc r%s, r25", acc[2])
180af03003cSMatthias Ringwald        emit("st z+, r%s", acc[0])
181*6ccd8248SMilanka Ringwald        print("")
182af03003cSMatthias Ringwald        acc = acc[1:] + acc[:1]
183af03003cSMatthias Ringwald    emit("mul r%s, r%s", x_regs[9], y_regs[9])
184af03003cSMatthias Ringwald    emit("add r%s, r0", acc[0])
185af03003cSMatthias Ringwald    emit("adc r%s, r1", acc[1])
186af03003cSMatthias Ringwald    emit("st z+, r%s", acc[0])
187af03003cSMatthias Ringwald    emit("st z+, r%s", acc[1])
188*6ccd8248SMilanka Ringwald    print("")
189af03003cSMatthias Ringwald
190af03003cSMatthias Ringwald    prev_size = prev_size + 10
191af03003cSMatthias Ringwald    if row < full_rows - 1:
192af03003cSMatthias Ringwald        #### reset x, y and z pointers
193af03003cSMatthias Ringwald        emit("sbiw r30, %s", 2 * prev_size + 10)
194af03003cSMatthias Ringwald        emit("sbiw r28, %s", prev_size + 10)
195af03003cSMatthias Ringwald        emit("sbiw r26, %s", prev_size)
196af03003cSMatthias Ringwald
197af03003cSMatthias Ringwald        #### load x and y registers
198*6ccd8248SMilanka Ringwald        for i in range(10):
199af03003cSMatthias Ringwald            emit("ld r%s, x+", rx(i))
200af03003cSMatthias Ringwald            emit("ld r%s, y+", ry(i))
201*6ccd8248SMilanka Ringwald        print("")
202af03003cSMatthias Ringwald
203af03003cSMatthias Ringwaldemit("eor r1, r1")
204