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