You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

317 lines
7.2 KiB

  1. <% function subS1S2() { %>
  2. xor rdx, rdx
  3. mov edx, eax
  4. sub edx, ecx
  5. jo sub_manageOverflow ; rsi already is the 64bits result
  6. mov [rdi], rdx ; not necessary to adjust so just save and return
  7. ret
  8. sub_manageOverflow: ; Do the operation in 64 bits
  9. push rsi
  10. movsx rsi, eax
  11. movsx rdx, ecx
  12. sub rsi, rdx
  13. call rawCopyS2L
  14. pop rsi
  15. ret
  16. <% } %>
  17. <% function subL1S2(t) { %>
  18. add rsi, 8
  19. movsx rdx, ecx
  20. add rdi, 8
  21. cmp rdx, 0
  22. <% const rawSubLabel = global.tmpLabel() %>
  23. jns <%= rawSubLabel %>
  24. neg rdx
  25. call rawAddLS
  26. sub rdi, 8
  27. sub rsi, 8
  28. ret
  29. <%= rawSubLabel %>:
  30. call rawSubLS
  31. sub rdi, 8
  32. sub rsi, 8
  33. ret
  34. <% } %>
  35. <% function subS1L2(t) { %>
  36. cmp eax, 0
  37. <% const s1NegLabel = global.tmpLabel() %>
  38. js <%= s1NegLabel %>
  39. ; First Operand is positive
  40. push rsi
  41. add rdi, 8
  42. movsx rsi, eax
  43. add rdx, 8
  44. call rawSubSL
  45. sub rdi, 8
  46. pop rsi
  47. ret
  48. <%= s1NegLabel %>: ; First operand is negative
  49. push rsi
  50. lea rsi, [rdx + 8]
  51. movsx rdx, eax
  52. add rdi, 8
  53. neg rdx
  54. call rawNegLS
  55. sub rdi, 8
  56. pop rsi
  57. ret
  58. <% } %>
  59. <% function subL1L2(t) { %>
  60. add rdi, 8
  61. add rsi, 8
  62. add rdx, 8
  63. call rawSubLL
  64. sub rdi, 8
  65. sub rsi, 8
  66. ret
  67. <% } %>
  68. ;;;;;;;;;;;;;;;;;;;;;;
  69. ; sub
  70. ;;;;;;;;;;;;;;;;;;;;;;
  71. ; Substracts two elements of any kind
  72. ; Params:
  73. ; rsi <= Pointer to element 1
  74. ; rdx <= Pointer to element 2
  75. ; rdi <= Pointer to result
  76. ; Modified Registers:
  77. ; r8, r9, 10, r11, rax, rcx
  78. ;;;;;;;;;;;;;;;;;;;;;;
  79. <%=name%>_sub:
  80. mov rax, [rsi]
  81. mov rcx, [rdx]
  82. bt rax, 63 ; Check if is long first operand
  83. jc sub_l1
  84. bt rcx, 63 ; Check if is long second operand
  85. jc sub_s1l2
  86. sub_s1s2: ; Both operands are short
  87. <%= subS1S2() %>
  88. sub_l1:
  89. bt rcx, 63 ; Check if is short second operand
  90. jc sub_l1l2
  91. ;;;;;;;;
  92. sub_l1s2:
  93. bt rax, 62 ; check if montgomery first
  94. jc sub_l1ms2
  95. sub_l1ns2:
  96. <%= global.setTypeDest("0x80"); %>
  97. <%= subL1S2(); %>
  98. sub_l1ms2:
  99. bt rcx, 62 ; check if montgomery second
  100. jc sub_l1ms2m
  101. sub_l1ms2n:
  102. <%= global.setTypeDest("0xC0"); %>
  103. <%= global.toMont_b() %>
  104. <%= subL1L2() %>
  105. sub_l1ms2m:
  106. <%= global.setTypeDest("0xC0"); %>
  107. <%= subL1L2() %>
  108. ;;;;;;;;
  109. sub_s1l2:
  110. bt rcx, 62 ; check if montgomery first
  111. jc sub_s1l2m
  112. sub_s1l2n:
  113. <%= global.setTypeDest("0x80"); %>
  114. <%= subS1L2(); %>
  115. sub_s1l2m:
  116. bt rax, 62 ; check if montgomery second
  117. jc sub_s1ml2m
  118. sub_s1nl2m:
  119. <%= global.setTypeDest("0xC0"); %>
  120. <%= global.toMont_a() %>
  121. <%= subL1L2() %>
  122. sub_s1ml2m:
  123. <%= global.setTypeDest("0xC0"); %>
  124. <%= subL1L2() %>
  125. ;;;;
  126. sub_l1l2:
  127. bt rax, 62 ; check if montgomery first
  128. jc sub_l1ml2
  129. sub_l1nl2:
  130. bt rcx, 62 ; check if montgomery second
  131. jc sub_l1nl2m
  132. sub_l1nl2n:
  133. <%= global.setTypeDest("0x80"); %>
  134. <%= subL1L2() %>
  135. sub_l1nl2m:
  136. <%= global.setTypeDest("0xC0"); %>
  137. <%= global.toMont_a(); %>
  138. <%= subL1L2() %>
  139. sub_l1ml2:
  140. bt rcx, 62 ; check if montgomery seconf
  141. jc sub_l1ml2m
  142. sub_l1ml2n:
  143. <%= global.setTypeDest("0xC0"); %>
  144. <%= global.toMont_b(); %>
  145. <%= subL1L2() %>
  146. sub_l1ml2m:
  147. <%= global.setTypeDest("0xC0"); %>
  148. <%= subL1L2() %>
  149. ;;;;;;;;;;;;;;;;;;;;;;
  150. ; rawSubLS
  151. ;;;;;;;;;;;;;;;;;;;;;;
  152. ; Substracts a short element from the long element
  153. ; Params:
  154. ; rdi <= Pointer to the long data of result
  155. ; rsi <= Pointer to the long data of element 1 where will be substracted
  156. ; rdx <= Value to be substracted
  157. ; [rdi] = [rsi] - rdx
  158. ; Modified Registers:
  159. ; rax
  160. ;;;;;;;;;;;;;;;;;;;;;;
  161. rawSubLS:
  162. ; Substract first digit
  163. mov rax, [rsi]
  164. sub rax, rdx
  165. mov [rdi] ,rax
  166. mov rdx, 0
  167. <% for (let i=1; i<n64; i++) { %>
  168. mov rax, [rsi + <%=i*8%>]
  169. sbb rax, rdx
  170. mov [rdi + <%=i*8%>], rax
  171. <% } %>
  172. jnc rawSubLS_done ; if overflow, add q
  173. ; Add q
  174. rawSubLS_aq:
  175. <% for (let i=0; i<n64; i++) { %>
  176. mov rax, [q + <%=i*8%>]
  177. <%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
  178. <% } %>
  179. rawSubLS_done:
  180. ret
  181. ;;;;;;;;;;;;;;;;;;;;;;
  182. ; rawSubSL
  183. ;;;;;;;;;;;;;;;;;;;;;;
  184. ; Substracts a long element from a short element
  185. ; Params:
  186. ; rdi <= Pointer to the long data of result
  187. ; rsi <= Value from where will bo substracted
  188. ; rdx <= Pointer to long of the value to be substracted
  189. ;
  190. ; [rdi] = rsi - [rdx]
  191. ; Modified Registers:
  192. ; rax
  193. ;;;;;;;;;;;;;;;;;;;;;;
  194. rawSubSL:
  195. ; Substract first digit
  196. sub rsi, [rdx]
  197. mov [rdi] ,rsi
  198. <% for (let i=1; i<n64; i++) { %>
  199. mov rax, 0
  200. sbb rax, [rdx + <%=i*8%>]
  201. mov [rdi + <%=i*8%>], rax
  202. <% } %>
  203. jnc rawSubSL_done ; if overflow, add q
  204. ; Add q
  205. rawSubSL_aq:
  206. <% for (let i=0; i<n64; i++) { %>
  207. mov rax, [q + <%=i*8%>]
  208. <%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
  209. <% } %>
  210. rawSubSL_done:
  211. ret
  212. ;;;;;;;;;;;;;;;;;;;;;;
  213. ; rawSubLL
  214. ;;;;;;;;;;;;;;;;;;;;;;
  215. ; Substracts a long element from a short element
  216. ; Params:
  217. ; rdi <= Pointer to the long data of result
  218. ; rsi <= Pointer to long from where substracted
  219. ; rdx <= Pointer to long of the value to be substracted
  220. ;
  221. ; [rdi] = [rsi] - [rdx]
  222. ; Modified Registers:
  223. ; rax
  224. ;;;;;;;;;;;;;;;;;;;;;;
  225. rawSubLL:
  226. ; Substract first digit
  227. <% for (let i=0; i<n64; i++) { %>
  228. mov rax, [rsi + <%=i*8%>]
  229. <%= i==0 ? "sub" : "sbb" %> rax, [rdx + <%=i*8%>]
  230. mov [rdi + <%=i*8%>], rax
  231. <% } %>
  232. jnc rawSubLL_done ; if overflow, add q
  233. ; Add q
  234. rawSubLL_aq:
  235. <% for (let i=0; i<n64; i++) { %>
  236. mov rax, [q + <%=i*8%>]
  237. <%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
  238. <% } %>
  239. rawSubLL_done:
  240. ret
  241. ;;;;;;;;;;;;;;;;;;;;;;
  242. ; rawNegLS
  243. ;;;;;;;;;;;;;;;;;;;;;;
  244. ; Substracts a long element and a short element form 0
  245. ; Params:
  246. ; rdi <= Pointer to the long data of result
  247. ; rsi <= Pointer to long from where substracted
  248. ; rdx <= short value to be substracted too
  249. ;
  250. ; [rdi] = -[rsi] - rdx
  251. ; Modified Registers:
  252. ; rax
  253. ;;;;;;;;;;;;;;;;;;;;;;
  254. rawNegLS:
  255. mov rax, [q]
  256. sub rax, rdx
  257. mov [rdi], rax
  258. <% for (let i=1; i<n64; i++) { %>
  259. mov rax, [q + <%=i*8%> ]
  260. sbb rax, 0
  261. mov [rdi + <%=i*8%>], rax
  262. <% } %>
  263. setc dl
  264. <% for (let i=0; i<n64; i++) { %>
  265. mov rax, [rdi + <%=i*8%> ]
  266. <%= i==0 ? "sub" : "sbb" %> rax, [rsi + <%=i*8%>]
  267. mov [rdi + <%=i*8%>], rax
  268. <% } %>
  269. setc dh
  270. or dl, dh
  271. jz rawNegSL_done
  272. ; it is a negative value, so add q
  273. <% for (let i=0; i<n64; i++) { %>
  274. mov rax, [q + <%=i*8%>]
  275. <%= i==0 ? "add" : "adc" %> [rdi + <%=i*8%>], rax
  276. <% } %>
  277. rawNegSL_done:
  278. ret