arnaucube
arnaucube/circomPublic Self-hosted repository
circom/c/buildasm/mul.asm.ejs
c/buildasm/mul.asm.ejsRaw
  1<% function mulS1S2() { %>
  2        xor    rax, rax
  3        mov    eax, r8d
  4        imul   r9d
  5        jo     mul_manageOverflow   ; rsi already is the 64bits result
  6
  7        mov    [rdi], rax       ; not necessary to adjust so just save and return
  8
  9mul_manageOverflow:                 ; Do the operation in 64 bits
 10        push   rsi
 11        movsx  rax, r8d
 12        movsx  rcx, r9d
 13        imul   rcx
 14        mov    rsi, rax
 15        call   rawCopyS2L
 16        pop    rsi
 17<% } %>
 18
 19<% function mulL1S2(t) { %>
 20        push rsi
 21        add rsi, 8
 22        movsx rdx, r9d
 23        add rdi, 8
 24        cmp rdx, 0
 25        <% const rawPositiveLabel = global.tmpLabel() %>
 26        jns <%= rawPositiveLabel %>
 27        neg rdx
 28        call rawMontgomeryMul1
 29        mov rsi, rdi
 30        call rawNegL
 31        sub rdi, 8
 32        pop rsi
 33        <% const done = global.tmpLabel() %>
 34        jmp <%= done %>
 35<%= rawPositiveLabel %>:
 36        call rawMontgomeryMul1
 37        sub rdi, 8
 38        pop rsi
 39<%= done %>:
 40
 41<% } %>
 42
 43<% function mulS1L2() { %>
 44        push rsi
 45        lea rsi, [rdx + 8]
 46        movsx rdx, r8d
 47        add rdi, 8
 48        cmp rdx, 0
 49        <% const rawPositiveLabel = global.tmpLabel() %>
 50        jns <%= rawPositiveLabel %>
 51        neg rdx
 52        call rawMontgomeryMul1
 53        mov rsi, rdi
 54        call rawNegL
 55        sub rdi, 8
 56        pop rsi
 57        <% const done = global.tmpLabel() %>
 58        jmp <%= done %>
 59<%= rawPositiveLabel %>:
 60        call rawMontgomeryMul1
 61        sub rdi, 8
 62        pop rsi
 63<%= done %>:
 64
 65<% } %>
 66
 67<% function mulL1L2() { %>
 68        add rdi, 8
 69        add rsi, 8
 70        add rdx, 8
 71        call rawMontgomeryMul
 72        sub rdi, 8
 73        sub rsi, 8
 74<% } %>
 75
 76<% function mulR3() { %>
 77        push rsi
 78        add rdi, 8
 79        mov rsi, rdi
 80        lea rdx, [R3]
 81        call rawMontgomeryMul
 82        sub rdi, 8
 83        pop rsi
 84<% } %>
 85
 86
 87;;;;;;;;;;;;;;;;;;;;;;
 88; mul
 89;;;;;;;;;;;;;;;;;;;;;;
 90; Multiplies two elements of any kind
 91; Params:
 92;   rsi <= Pointer to element 1
 93;   rdx <= Pointer to element 2
 94;   rdi <= Pointer to result
 95;   [rdi] = [rsi] * [rdi]
 96; Modified Registers:
 97;    r8, r9, 10, r11, rax, rcx
 98;;;;;;;;;;;;;;;;;;;;;;
 99<%=name%>_mul:
100        mov    r8, [rsi]
101        mov    r9, [rdx]
102        bt     r8, 63          ; Check if is short first operand
103        jc     mul_l1
104        bt     r9, 63          ; Check if is short second operand
105        jc     mul_s1l2
106
107mul_s1s2:                       ; Both operands are short
108<%=     mulS1S2()       %>
109        ret
110
111mul_l1:
112        bt     r9, 63          ; Check if is short second operand
113        jc     mul_l1l2
114
115;;;;;;;;
116mul_l1s2:
117        bt     r8, 62          ; check if montgomery first
118        jc     mul_l1ms2
119mul_l1ns2:
120        bt     r9, 62          ; check if montgomery first
121        jc     mul_l1ns2m
122mul_l1ns2n:
123<%=     global.setTypeDest("0xC0"); %>
124<%=     mulL1S2()       %>
125<%=     mulR3()         %>
126        ret
127
128
129mul_l1ns2m:
130<%=     global.setTypeDest("0x80"); %>
131<%=     mulL1L2()       %>
132        ret
133
134
135mul_l1ms2:
136        bt     r9, 62          ; check if montgomery second
137        jc     mul_l1ms2m
138mul_l1ms2n:
139<%=     global.setTypeDest("0x80"); %>
140<%=     mulL1S2()       %>
141        ret
142
143mul_l1ms2m:
144<%=     global.setTypeDest("0xC0"); %>
145<%=     mulL1L2()         %>
146        ret
147
148
149;;;;;;;;
150mul_s1l2:
151        bt     r8, 62          ; check if montgomery first
152        jc     mul_s1ml2
153mul_s1nl2:
154        bt     r9, 62          ; check if montgomery first
155        jc     mul_s1nl2m
156mul_s1nl2n:
157<%=     global.setTypeDest("0xC0"); %>
158<%=     mulS1L2()       %>
159<%=     mulR3()         %>
160        ret
161
162mul_s1nl2m:
163<%=     global.setTypeDest("0x80"); %>
164<%=     mulS1L2(); %>
165        ret
166
167mul_s1ml2:
168        bt     r9, 62          ; check if montgomery first
169        jc     mul_s1ml2m
170mul_s1ml2n:
171<%=     global.setTypeDest("0x80"); %>
172<%=     mulL1L2()         %>
173        ret
174
175mul_s1ml2m:
176<%=     global.setTypeDest("0xC0"); %>
177<%=     mulL1L2()         %>
178        ret
179
180;;;;
181mul_l1l2:
182        bt     r8, 62          ; check if montgomery first
183        jc     mul_l1ml2
184mul_l1nl2:
185        bt     r9, 62          ; check if montgomery second
186        jc     mul_l1nl2m
187mul_l1nl2n:
188<%=     global.setTypeDest("0xC0"); %>
189<%=     mulL1L2()         %>
190<%=     mulR3()         %>
191        ret
192
193mul_l1nl2m:
194<%=     global.setTypeDest("0x80"); %>
195<%=     mulL1L2()         %>
196        ret
197
198mul_l1ml2:
199        bt     r9, 62          ; check if montgomery seconf
200        jc     mul_l1ml2m
201mul_l1ml2n:
202<%=     global.setTypeDest("0x80"); %>
203<%=     mulL1L2()         %>
204        ret
205
206mul_l1ml2m:
207<%=     global.setTypeDest("0xC0"); %>
208<%=     mulL1L2()         %>
209        ret
210
211