1 // Externe Routinen zu ARILEV1.D
2 // Prozessor: 80386 im native mode
3 // Assembler-Syntax: GNU oder SUN, Moves von links nach rechts
4 // Compiler: GNU-C oder SUN-C
5 // Parameter-Übergabe: auf dem Stack 4(%esp),8(%esp),...
6 // Register: %eax,%edx,%ecx dürfen stets verändert werden, alles andere retten.
7 // Ergebnis-Übergabe: in %eax
8 // Einstellungen: intCsize=32, intDsize=32.
10 // Bruno Haible 14.8.1992
11 // Zum Teil abgeschrieben von Bernhard Degels "v-i386.s"
14 #if defined(__STDC__) || defined (__cplusplus)
15 #define C(entrypoint) _##entrypoint
17 #define C(entrypoint) _/**/entrypoint
20 #define C(entrypoint) entrypoint
23 #if defined(__STDC__) || defined (__cplusplus)
24 #define L(label) L##label
26 #define L(label) L/**/label
29 #if defined(__STDC__) || defined (__cplusplus)
30 #define L(label) .L##label
32 #define L(label) .L/**/label
35 #if defined(ASM_UNDERSCORE) || defined(COHERENT) /* defined(__EMX__) || defined(__GO32__) || defined(linux) || defined(__386BSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(COHERENT) || ... */
36 // GNU-Assembler oder MWC-Assembler
39 #else /* defined(sun) || ... */
40 // SUN-Assembler oder Consensys-Assembler
41 #define jecxz orl %ecx,%ecx ; jz
45 // Direction-Flag ist defaultmäßig gelöscht
51 // Wir gehen auf Nummer sicher.
57 // Direction-Flag darf nach Belieben modifiziert werden
63 // Alignment. Note that some assemblers need ".align 3,0x90" whereas other
64 // assemblers don't like this syntax. So we put in the "nop"s by hand.
65 #if defined(ASM_UNDERSCORE) && !(defined(__CYGWIN32__) || defined(__MINGW32__))
66 // BSD syntax assembler
67 #define ALIGN .align 3
69 // ELF syntax assembler
70 #define ALIGN .align 8
72 // When this file is compiled into a shared library, ELF linkers need to
73 // know which symbols are functions.
74 #if defined(__svr4__) || defined(__ELF__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__ROSE__) || defined(_SEQUENT_) || defined(DGUX) || defined(_SCO_COFF) || defined(_SCO_ELF)
75 #define DECLARE_FUNCTION(name) .type C(name),@function
77 #define DECLARE_FUNCTION(name)
82 .globl C(copy_loop_up)
83 .globl C(copy_loop_down)
84 .globl C(fill_loop_up)
85 .globl C(fill_loop_down)
86 .globl C(clear_loop_up)
87 .globl C(clear_loop_down)
88 .globl C(test_loop_up)
89 .globl C(test_loop_down)
91 .globl C(compare_loop_up)
92 .globl C(shiftleftcopy_loop_up)
93 .globl C(shiftxor_loop_up)
94 #if CL_DS_BIG_ENDIAN_P
98 .globl C(nand_loop_up)
100 .globl C(andc2_loop_up)
101 .globl C(orc2_loop_up)
102 .globl C(not_loop_up)
103 .globl C(and_test_loop_up)
104 .globl C(add_loop_down)
105 .globl C(addto_loop_down)
106 .globl C(inc_loop_down)
107 .globl C(sub_loop_down)
108 .globl C(subx_loop_down)
109 .globl C(subfrom_loop_down)
110 .globl C(dec_loop_down)
111 .globl C(neg_loop_down)
112 .globl C(shift1left_loop_down)
113 .globl C(shiftleft_loop_down)
114 .globl C(shiftleftcopy_loop_down)
115 .globl C(shift1right_loop_up)
116 .globl C(shiftright_loop_up)
117 .globl C(shiftrightsigned_loop_up)
118 .globl C(shiftrightcopy_loop_up)
119 .globl C(mulusmall_loop_down)
120 .globl C(mulu_loop_down)
121 .globl C(muluadd_loop_down)
122 .globl C(mulusub_loop_down)
123 .globl C(divu_loop_up)
124 .globl C(divucopy_loop_up)
126 .globl C(or_loop_down)
127 .globl C(xor_loop_down)
128 .globl C(and_loop_down)
129 .globl C(eqv_loop_down)
130 .globl C(nand_loop_down)
131 .globl C(nor_loop_down)
132 .globl C(andc2_loop_down)
133 .globl C(orc2_loop_down)
134 .globl C(not_loop_down)
135 .globl C(and_test_loop_down)
136 .globl C(compare_loop_down)
137 .globl C(add_loop_up)
138 .globl C(addto_loop_up)
139 .globl C(inc_loop_up)
140 .globl C(sub_loop_up)
141 .globl C(subx_loop_up)
142 .globl C(subfrom_loop_up)
143 .globl C(dec_loop_up)
144 .globl C(neg_loop_up)
145 .globl C(shift1left_loop_up)
146 .globl C(shiftleft_loop_up)
147 .globl C(shift1right_loop_down)
148 .globl C(shiftright_loop_down)
149 .globl C(shiftrightsigned_loop_down)
150 .globl C(shiftrightcopy_loop_down)
151 .globl C(mulusmall_loop_up)
152 .globl C(mulu_loop_up)
153 .globl C(muluadd_loop_up)
154 .globl C(mulusub_loop_up)
155 .globl C(divu_loop_down)
156 .globl C(divucopy_loop_down)
159 #ifndef __GNUC__ /* mit GNU-C machen wir mulu32() als Macro, der inline multipliziert */
161 // extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
162 // 2^32*hi+lo := arg1*arg2.
165 DECLARE_FUNCTION(mulu32_)
167 movl 4(%esp),%eax // arg1
168 mull 8(%esp) // %edx|%eax := arg1 * arg2
169 movl %edx,C(mulu32_high) // %edx = hi abspeichern
170 ret // %eax = lo als Ergebnis
174 #ifndef __GNUC__ /* mit GNU-C machen wir divu_6432_3232() als Macro, der inline dividiert */
176 // extern struct { uint32 q; uint32 r; } divu_6432_3232_ (uint32 xhi, uint32 xlo, uint32 y);
177 // x = 2^32*xhi+xlo = q*y+r schreiben. Sei bekannt, daß 0 <= x < 2^32*y .
178 .globl C(divu_6432_3232_)
180 DECLARE_FUNCTION(divu_6432_3232_)
184 divl 12(%esp) // x = %edx|%eax durch dividieren
185 movl %edx,C(divu_32_rest) // Rest %edx = r abspeichern
186 ret // Quotient %eax = q als Ergebnis
190 // extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
192 DECLARE_FUNCTION(copy_loop_up)
194 movl %edi,%edx // %edi retten
195 movl %esi,%eax // %esi retten
196 movl 4(%esp),%esi // %esi = sourceptr
197 movl 8(%esp),%edi // %edi = destptr
198 movl 12(%esp),%ecx // %ecx = count
201 movsl // %ecx mal aufwärts (%edi) := (%esi)
203 movl %eax,%esi // %esi zurück
204 movl %edi,%eax // %edi als Ergebnis
205 movl %edx,%edi // %edi zurück
208 // extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
210 DECLARE_FUNCTION(copy_loop_down)
212 movl %edi,%edx // %edi retten
213 movl %esi,%eax // %esi retten
214 movl 4(%esp),%esi // %esi = sourceptr
215 movl 8(%esp),%edi // %edi = destptr
216 movl 12(%esp),%ecx // %ecx = count
221 movsl // %ecx mal abwärts (%edi) := (%esi)
223 movl %eax,%esi // %esi zurück
224 leal 4(%edi),%eax // %edi als Ergebnis
225 movl %edx,%edi // %edi zurück
228 // extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
230 DECLARE_FUNCTION(fill_loop_up)
232 movl %edi,%edx // %edi retten
233 movl 4(%esp),%edi // %edi = destptr
234 movl 8(%esp),%ecx // %ecx = count
235 movl 12(%esp),%eax // %eax = filler
238 stosl // %ecx mal aufwärts (%edi) := %eax
240 movl %edi,%eax // %edi als Ergebnis
241 movl %edx,%edi // %edi zurück
244 // extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
246 DECLARE_FUNCTION(fill_loop_down)
248 movl %edi,%edx // %edi retten
249 movl 4(%esp),%edi // %edi = destptr
250 movl 8(%esp),%ecx // %ecx = count
251 movl 12(%esp),%eax // %eax = filler
255 stosl // %ecx mal abwärts (%edi) := %eax
257 leal 4(%edi),%eax // %edi als Ergebnis
258 movl %edx,%edi // %edi zurück
261 // extern uintD* clear_loop_up (uintD* destptr, uintC count);
263 DECLARE_FUNCTION(clear_loop_up)
265 movl %edi,%edx // %edi retten
266 movl 4(%esp),%edi // %edi = destptr
267 movl 8(%esp),%ecx // %ecx = count
268 xorl %eax,%eax // %eax = 0
271 stosl // %ecx mal aufwärts (%edi) := %eax
273 movl %edi,%eax // %edi als Ergebnis
274 movl %edx,%edi // %edi zurück
277 // extern uintD* clear_loop_down (uintD* destptr, uintC count);
279 DECLARE_FUNCTION(clear_loop_down)
281 movl %edi,%edx // %edi retten
282 movl 4(%esp),%edi // %edi = destptr
283 movl 8(%esp),%ecx // %ecx = count
285 xorl %eax,%eax // %eax = 0
288 stosl // %ecx mal abwärts (%edi) := %eax
290 leal 4(%edi),%eax // %edi als Ergebnis
291 movl %edx,%edi // %edi zurück
294 // extern boolean test_loop_up (uintD* ptr, uintC count);
296 DECLARE_FUNCTION(test_loop_up)
298 movl %edi,%edx // %edi retten
299 movl 4(%esp),%edi // %edi = ptr
300 movl 8(%esp),%ecx // %ecx = count
301 xorl %eax,%eax // %eax = 0
303 repz // Falls %ecx > 0:
304 scasl // %ecx mal aufwärts (%edi) testen
305 // und weiterschleifen, falls Z, d.h. (%edi)=0.
307 // Noch ist %eax = 0.
308 jz L(tlu1) // alles =0 -> Ergebnis 0
309 incl %eax // Ergebnis 1
310 L(tlu1:) movl %edx,%edi // %edi zurück
313 // extern boolean test_loop_down (uintD* ptr, uintC count);
315 DECLARE_FUNCTION(test_loop_down)
317 movl %edi,%edx // %edi retten
318 movl 4(%esp),%edi // %edi = ptr
319 movl 8(%esp),%ecx // %ecx = count
320 xorl %eax,%eax // %eax = 0
323 repz // Falls %ecx > 0:
324 scasl // %ecx mal aufwärts (%edi) testen
325 // und weiterschleifen, falls Z, d.h. (%edi)=0.
327 // Noch ist %eax = 0.
328 jz L(tld1) // alles =0 -> Ergebnis 0
329 incl %eax // Ergebnis 1
330 L(tld1:) movl %edx,%edi // %edi zurück
333 #if CL_DS_BIG_ENDIAN_P
335 // extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
337 DECLARE_FUNCTION(or_loop_up)
339 pushl %esi // %esi retten
340 movl 8(%esp),%edx // %edx = xptr
341 movl 12(%esp),%esi // %esi = yptr
342 movl 16(%esp),%ecx // %ecx = count
344 jecxz L(olu2) // %ecx = 0 ?
345 L(olu1:) movl (%edx,%esi),%eax // *yptr
346 orl %eax,(%edx) // *xptr |= ...
347 leal 4(%edx),%edx // xptr++, yptr++
350 L(olu2:) popl %esi // %esi zurück
355 // extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
357 DECLARE_FUNCTION(xor_loop_up)
359 pushl %esi // %esi retten
360 movl 8(%esp),%edx // %edx = xptr
361 movl 12(%esp),%esi // %esi = yptr
362 movl 16(%esp),%ecx // %ecx = count
364 jecxz L(xlu2) // %ecx = 0 ?
365 L(xlu1:) movl (%edx,%esi),%eax // *yptr
366 xorl %eax,(%edx) // *xptr ^= ...
367 leal 4(%edx),%edx // xptr++, yptr++
370 L(xlu2:) popl %esi // %esi zurück
373 #if CL_DS_BIG_ENDIAN_P
375 // extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
377 DECLARE_FUNCTION(and_loop_up)
379 pushl %esi // %esi retten
380 movl 8(%esp),%edx // %edx = xptr
381 movl 12(%esp),%esi // %esi = yptr
382 movl 16(%esp),%ecx // %ecx = count
384 jecxz L(alu2) // %ecx = 0 ?
385 L(alu1:) movl (%edx,%esi),%eax // *yptr
386 andl %eax,(%edx) // *xptr &= ...
387 leal 4(%edx),%edx // xptr++, yptr++
390 L(alu2:) popl %esi // %esi zurück
393 // extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
395 DECLARE_FUNCTION(eqv_loop_up)
397 pushl %esi // %esi retten
398 movl 8(%esp),%edx // %edx = xptr
399 movl 12(%esp),%esi // %esi = yptr
400 movl 16(%esp),%ecx // %ecx = count
402 jecxz L(elu2) // %ecx = 0 ?
403 L(elu1:) movl (%edx),%eax // *xptr
404 xorl (%edx,%esi),%eax // ^ *yptr
406 movl %eax,(%edx) // =: *xptr
407 leal 4(%edx),%edx // xptr++, yptr++
410 L(elu2:) popl %esi // %esi zurück
413 // extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
415 DECLARE_FUNCTION(nand_loop_up)
417 pushl %esi // %esi retten
418 movl 8(%esp),%edx // %edx = xptr
419 movl 12(%esp),%esi // %esi = yptr
420 movl 16(%esp),%ecx // %ecx = count
422 jecxz L(nalu2) // %ecx = 0 ?
423 L(nalu1:) movl (%edx),%eax // *xptr
424 andl (%edx,%esi),%eax // & *yptr
426 movl %eax,(%edx) // =: *xptr
427 leal 4(%edx),%edx // xptr++, yptr++
430 L(nalu2:) popl %esi // %esi zurück
433 // extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
435 DECLARE_FUNCTION(nor_loop_up)
437 pushl %esi // %esi retten
438 movl 8(%esp),%edx // %edx = xptr
439 movl 12(%esp),%esi // %esi = yptr
440 movl 16(%esp),%ecx // %ecx = count
442 jecxz L(nolu2) // %ecx = 0 ?
443 L(nolu1:) movl (%edx),%eax // *xptr
444 orl (%edx,%esi),%eax // | *yptr
446 movl %eax,(%edx) // =: *xptr
447 leal 4(%edx),%edx // xptr++, yptr++
450 L(nolu2:) popl %esi // %esi zurück
453 // extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
455 DECLARE_FUNCTION(andc2_loop_up)
457 pushl %esi // %esi retten
458 movl 8(%esp),%edx // %edx = xptr
459 movl 12(%esp),%esi // %esi = yptr
460 movl 16(%esp),%ecx // %ecx = count
462 jecxz L(aclu2) // %ecx = 0 ?
463 L(aclu1:) movl (%edx,%esi),%eax // *yptr
465 andl %eax,(%edx) // *xptr &= ...
466 leal 4(%edx),%edx // xptr++, yptr++
469 L(aclu2:) popl %esi // %esi zurück
472 // extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
474 DECLARE_FUNCTION(orc2_loop_up)
476 pushl %esi // %esi retten
477 movl 8(%esp),%edx // %edx = xptr
478 movl 12(%esp),%esi // %esi = yptr
479 movl 16(%esp),%ecx // %ecx = count
481 jecxz L(oclu2) // %ecx = 0 ?
482 L(oclu1:) movl (%edx,%esi),%eax // *yptr
484 orl %eax,(%edx) // *xptr |= ...
485 leal 4(%edx),%edx // xptr++, yptr++
488 L(oclu2:) popl %esi // %esi zurück
491 // extern void not_loop_up (uintD* xptr, uintC count);
493 DECLARE_FUNCTION(not_loop_up)
495 movl 4(%esp),%edx // %edx = xptr
496 movl 8(%esp),%ecx // %ecx = count
497 jecxz L(nlu2) // %ecx = 0 ?
498 nop ; nop ; nop ; nop ; nop ; nop
499 L(nlu1:) notl (%edx) // ~= *xptr
500 leal 4(%edx),%edx // xptr++
505 // extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
507 DECLARE_FUNCTION(and_test_loop_up)
509 pushl %esi // %esi retten
510 movl 8(%esp),%edx // %edx = xptr
511 movl 12(%esp),%esi // %esi = yptr
512 movl 16(%esp),%ecx // %ecx = count
513 jecxz L(atlu2) // %ecx = 0 ?
515 L(atlu1:) movl (%edx,%esi),%eax // *yptr
516 andl (%edx),%eax // *xptr & ...
518 leal 4(%edx),%edx // xptr++, yptr++
521 L(atlu2:) xorl %eax,%eax // Ergebnis 0
522 popl %esi // %esi zurück
524 L(atlu3:) movl $1,%eax // Ergebnis 1 (nicht irgendwas /=0 !)
525 popl %esi // %esi zurück
530 // extern cl_signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
532 DECLARE_FUNCTION(compare_loop_up)
534 movl %esi,%edx // %esi retten
535 movl %edi,%eax // %edi retten
536 movl 4(%esp),%esi // %esi = xptr
537 movl 8(%esp),%edi // %edi = yptr
538 movl 12(%esp),%ecx // %ecx = count
539 cmpl %ecx,%ecx // initialize flags for the case %ecx is 0
541 repz // Falls %ecx > 0:
542 cmpsl // %ecx mal aufwärts (%edi) und (%esi) vergleichen
543 // und weiterschleifen, falls Z, d.h. (%edi)=(%esi).
545 // Flags -> Ergebnis:
546 // Z,NC -> bis zum Schluß (%esi)-(%edi) = 0 -> x=y -> Ergebnis 0
547 // NZ,C -> schließlich (%esi)-(%edi) < 0 -> x<y -> Ergebnis -1
548 // NZ,NC -> schließlich (%esi)-(%edi) > 0 -> x>y -> Ergebnis +1
549 movl %eax,%edi // %edi zurück
550 movl %edx,%esi // %esi zurück
551 jbe L(cmlu1) // "be" = Z oder C
552 movl $1,%eax // Ergebnis +1
554 L(cmlu1:) sbbl %eax,%eax // Ergebnis -1 (falls C) oder 0 (falls NC)
557 #if CL_DS_BIG_ENDIAN_P
559 // extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
561 DECLARE_FUNCTION(add_loop_down)
563 pushl %esi // %esi retten
564 pushl %edi // %edi retten
565 movl 12(%esp),%edx // %edx = sourceptr1
566 movl 16(%esp),%esi // %esi = sourceptr2
567 movl 20(%esp),%edi // %edi = destptr
568 movl 24(%esp),%ecx // %ecx = count
571 orl %ecx,%ecx // %ecx = 0 ?, Carry löschen
573 L(ald1:) leal -4(%edi),%edi // sourceptr1--, sourceptr2--, destptr--
574 movl (%edx,%edi),%eax // *sourceptr1
575 adcl (%esi,%edi),%eax // + *sourceptr2 + carry
576 movl %eax,(%edi) // =: *destptr, neuen Carry behalten
579 L(ald2:) sbbl %eax,%eax // Ergebnis := - Carry
580 popl %edi // %edi zurück
581 popl %esi // %esi zurück
584 // extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
586 DECLARE_FUNCTION(addto_loop_down)
588 pushl %edi // %edi retten
589 movl 8(%esp),%edx // %edx = sourceptr
590 movl 12(%esp),%edi // %edi = destptr
591 movl 16(%esp),%ecx // %ecx = count
593 orl %ecx,%ecx // %ecx = 0 ?, Carry löschen
595 L(atld1:) leal -4(%edi),%edi // sourceptr--, destptr--
596 movl (%edx,%edi),%eax // *sourceptr
597 adcl %eax,(%edi) // + *destptr + carry =: *destptr, neuer Carry
600 L(atld2:) sbbl %eax,%eax // Ergebnis := - Carry
601 popl %edi // %edi zurück
604 // extern uintD inc_loop_down (uintD* ptr, uintC count);
606 DECLARE_FUNCTION(inc_loop_down)
608 movl 4(%esp),%edx // %edx = ptr
609 movl 8(%esp),%ecx // %ecx = count
610 jecxz L(ild2) // %ecx = 0 ?
611 L(ild1:) leal -4(%edx),%edx
612 addl $1,(%edx) // (*ptr)++
613 jnc L(ild3) // kein Carry -> fertig
616 L(ild2:) movl $1,%eax // Ergebnis := 1
618 L(ild3:) xorl %eax,%eax // Ergebnis := 0
621 // extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
623 DECLARE_FUNCTION(sub_loop_down)
625 pushl %esi // %esi retten
626 pushl %edi // %edi retten
627 movl 12(%esp),%edx // %edx = sourceptr1
628 movl 16(%esp),%esi // %esi = sourceptr2
629 movl 20(%esp),%edi // %edi = destptr
630 movl 24(%esp),%ecx // %ecx = count
633 orl %ecx,%ecx // %ecx = 0 ?, Carry löschen
635 L(sld1:) leal -4(%edi),%edi // sourceptr1--, sourceptr2--, destptr--
636 movl (%edx,%edi),%eax // *sourceptr1
637 sbbl (%esi,%edi),%eax // - *sourceptr2 - carry
638 movl %eax,(%edi) // =: *destptr, neuen Carry behalten
641 L(sld2:) sbbl %eax,%eax // Ergebnis := - Carry
642 popl %edi // %edi zurück
643 popl %esi // %esi zurück
646 // extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
648 DECLARE_FUNCTION(subx_loop_down)
650 pushl %esi // %esi retten
651 pushl %edi // %edi retten
652 movl 12(%esp),%edx // %edx = sourceptr1
653 movl 16(%esp),%esi // %esi = sourceptr2
654 movl 20(%esp),%edi // %edi = destptr
655 movl 24(%esp),%ecx // %ecx = count
656 jecxz L(sxld2) // %ecx = 0 ?
659 movl 28(%esp),%eax // carry, 0 oder -1
660 addl %eax,%eax // Bit 31 davon in den Carry
662 L(sxld1:) leal -4(%edi),%edi // sourceptr1--, sourceptr2--, destptr--
663 movl (%edx,%edi),%eax // *sourceptr1
664 sbbl (%esi,%edi),%eax // - *sourceptr2 - carry
665 movl %eax,(%edi) // =: *destptr, neuen Carry behalten
668 sbbl %eax,%eax // Ergebnis := - Carry
669 popl %edi // %edi zurück
670 popl %esi // %esi zurück
672 L(sxld2:) movl 28(%esp),%eax // Ergebnis := carry
673 popl %edi // %edi zurück
674 popl %esi // %esi zurück
677 // extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
679 DECLARE_FUNCTION(subfrom_loop_down)
680 C(subfrom_loop_down:)
681 pushl %edi // %edi retten
682 movl 8(%esp),%edx // %edx = sourceptr
683 movl 12(%esp),%edi // %edi = destptr
684 movl 16(%esp),%ecx // %ecx = count
686 orl %ecx,%ecx // %ecx = 0 ?, Carry löschen
688 L(sfld1:) leal -4(%edi),%edi // sourceptr--, destptr--
689 movl (%edx,%edi),%eax // *sourceptr
690 sbbl %eax,(%edi) // *destptr - *sourceptr - carry =: *destptr, neuer Carry
693 L(sfld2:) sbbl %eax,%eax // Ergebnis := - Carry
694 popl %edi // %edi zurück
697 // extern uintD dec_loop_down (uintD* ptr, uintC count);
699 DECLARE_FUNCTION(dec_loop_down)
701 movl 4(%esp),%edx // %edx = ptr
702 movl 8(%esp),%ecx // %ecx = count
703 jecxz L(dld2) // %ecx = 0 ?
704 L(dld1:) leal -4(%edx),%edx
705 subl $1,(%edx) // (*ptr)--
706 jnc L(dld3) // kein Carry -> fertig
709 L(dld2:) movl $-1,%eax // Ergebnis := -1
711 L(dld3:) xorl %eax,%eax // Ergebnis := 0
714 // extern uintD neg_loop_down (uintD* ptr, uintC count);
716 DECLARE_FUNCTION(neg_loop_down)
718 movl 4(%esp),%edx // %edx = ptr
719 movl 8(%esp),%ecx // %ecx = count
720 // erstes Digit /=0 suchen:
721 jecxz L(nld2) // %ecx = 0 ?
722 L(nld1:) leal -4(%edx),%edx
727 L(nld2:) xorl %eax,%eax // Ergebnis := 0
729 nop ; nop ; nop ; nop ; nop ; nop
730 L(nld3:) // erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
731 // alle anderen Digits invertieren:
734 L(nld4:) leal -4(%edx),%edx
738 L(nld5:) movl $-1,%eax // Ergebnis := -1
741 // extern uintD shift1left_loop_down (uintD* ptr, uintC count);
743 DECLARE_FUNCTION(shift1left_loop_down)
744 C(shift1left_loop_down:)
745 movl 4(%esp),%edx // %edx = ptr
746 movl 8(%esp),%ecx // %ecx = count
747 orl %ecx,%ecx // %ecx = 0 ?, Carry löschen
749 nop ; nop ; nop ; nop
750 L(s1lld1:) leal -4(%edx),%edx // ptr--
751 rcll $1,(%edx) // *ptr und Carry um 1 Bit links rotieren
754 L(s1lld2:) sbbl %eax,%eax // Ergebnis := - Carry
757 // extern uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
759 DECLARE_FUNCTION(shiftleft_loop_down)
760 C(shiftleft_loop_down:)
761 pushl %edi // %edi retten
762 pushl %ebx // %ebx retten
763 movl 12(%esp),%edi // %edi = ptr
764 movl 16(%esp),%edx // %edx = count
765 movb 20(%esp),%cl // %cl = i
766 orl %edx,%edx // count = 0 ?
768 // erstes Digit shiften:
770 movl (%edi),%eax // Digit in %eax halten
771 movl %eax,%ebx // und in %ebx rechnen:
772 shll %cl,%ebx // um i Bits links shiften
773 orl 24(%esp),%ebx // und die unteren i Bits eintragen
774 movl %ebx,(%edi) // und wieder ablegen
775 // Letztes Digit in %eax.
778 nop ; nop ; nop ; nop
779 L(slld1:) // weiteres Digit shiften:
782 shldl shcl %eax,(%edi) // (%edi) um %cl=i Bits links shiften, %eax von rechts reinshiften
783 // Letztes Digit in %ebx.
786 // weiteres Digit shiften:
789 shldl shcl %ebx,(%edi) // (%edi) um %cl=i Bits links shiften, %ebx von rechts reinshiften
790 // Letztes Digit in %eax.
793 L(slld2:) movl %eax,%ebx
794 L(slld3:) xorl %eax,%eax // %eax := 0
795 shldl shcl %ebx,%eax // %eax := höchste %cl=i Bits von %ebx
796 popl %ebx // %ebx zurück
797 popl %edi // %edi zurück
799 L(slld4:) movl 24(%esp),%eax // %eax := carry
800 popl %ebx // %ebx zurück
801 popl %edi // %edi zurück
804 // extern uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
806 DECLARE_FUNCTION(shiftleftcopy_loop_down)
807 C(shiftleftcopy_loop_down:)
808 pushl %esi // %esi retten
809 pushl %edi // %edi retten
810 pushl %ebx // %ebx retten
811 movl 16(%esp),%esi // %esi = sourceptr
812 movl 20(%esp),%edi // %edi = destptr
813 movl 24(%esp),%edx // count
814 movb 28(%esp),%cl // i
815 orl %edx,%edx // count = 0 ?
818 // erstes Digit shiften:
819 leal -4(%edi),%edi // sourceptr--, destptr--
820 movl (%edi,%esi),%ebx // *sourceptr in %ebx halten
821 movl %ebx,%eax // und in %eax rechnen:
822 shll %cl,%eax // um i Bits links shiften, rechts Nullen rein
823 movl %eax,(%edi) // und als *destptr ablegen
824 // Letztes Digit in %ebx.
828 L(slcld1:) // weiteres Digit shiften:
829 leal -4(%edi),%edi // sourceptr--, destptr--
830 movl (%edi,%esi),%eax // nächstes Digit nach %eax
831 shrdl shcl %eax,%ebx // %ebx um %cl=32-i Bits rechts shiften, %eax von links reinshiften
832 movl %ebx,(%edi) // %ebx als *destptr ablegen
833 // Letztes Digit in %eax.
836 // weiteres Digit shiften:
837 leal -4(%edi),%edi // sourceptr--, destptr--
838 movl (%edi,%esi),%ebx // nächstes Digit nach %ebx
839 shrdl shcl %ebx,%eax // %eax um %cl=32-i Bits rechts shiften, %ebx von links reinshiften
840 movl %eax,(%edi) // %eax als *destptr ablegen
841 // Letztes Digit in %ebx.
844 L(slcld2:) movl %ebx,%eax
845 L(slcld3:) shrl %cl,%eax // %eax um 32-i Bits nach rechts shiften
846 popl %ebx // %ebx zurück
847 popl %edi // %edi zurück
848 popl %esi // %esi zurück
850 L(slcld4:) xorl %eax,%eax // %eax := 0
851 popl %ebx // %ebx zurück
852 popl %edi // %edi zurück
853 popl %esi // %esi zurück
856 // extern uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
858 DECLARE_FUNCTION(shift1right_loop_up)
859 C(shift1right_loop_up:)
860 movl 4(%esp),%edx // %edx = ptr
861 movl 8(%esp),%ecx // %ecx = count
862 movl 12(%esp),%eax // %eax = carry (0 oder -1)
863 jecxz L(s1rld3) // %ecx = 0 ?
864 addl %eax,%eax // Carry := Bit 31 von carry
865 L(s1rld1:) rcrl $1,(%edx) // *ptr und Carry um 1 Bit rechts rotieren
866 leal 4(%edx),%edx // ptr++
869 L(s1rld2:) sbbl %eax,%eax // Ergebnis := - Carry
872 // extern uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
874 DECLARE_FUNCTION(shiftright_loop_up)
875 C(shiftright_loop_up:)
876 pushl %edi // %edi retten
877 pushl %ebx // %ebx retten
878 movl 12(%esp),%edi // %edi = ptr
879 movl 16(%esp),%edx // %edx = count
880 movb 20(%esp),%cl // %cl = i
881 orl %edx,%edx // count = 0 ?
883 // erstes Digit shiften:
884 movl (%edi),%eax // Digit in %eax halten
885 movl %eax,%ebx // und in %ebx rechnen:
886 shrl %cl,%ebx // um i Bits rechts shiften
887 movl %ebx,(%edi) // und wieder ablegen
888 // Letztes Digit in %eax.
892 L(srlu1:) // weiteres Digit shiften:
895 shrdl shcl %eax,(%edi) // (%edi) um %cl=i Bits rechts shiften, %eax von links reinshiften
896 // Letztes Digit in %ebx.
899 // weiteres Digit shiften:
902 shrdl shcl %ebx,(%edi) // (%edi) um %cl=i Bits rechts shiften, %ebx von links reinshiften
903 // Letztes Digit in %eax.
906 L(srlu2:) movl %eax,%ebx
907 L(srlu3:) xorl %eax,%eax // %eax := 0
908 shrdl shcl %ebx,%eax // %eax := niedrigste %cl=i Bits von %ebx, als Bits 31..32-i
909 popl %ebx // %ebx zurück
910 popl %edi // %edi zurück
912 L(srlu4:) xorl %eax,%eax // %eax := 0
913 popl %ebx // %ebx zurück
914 popl %edi // %edi zurück
917 // extern uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
919 DECLARE_FUNCTION(shiftrightsigned_loop_up)
920 C(shiftrightsigned_loop_up:)
921 pushl %edi // %edi retten
922 pushl %ebx // %ebx retten
923 movl 12(%esp),%edi // %edi = ptr
924 movl 16(%esp),%edx // %edx = count
925 movb 20(%esp),%cl // %cl = i
926 // erstes Digit shiften:
927 movl (%edi),%eax // Digit in %eax halten
928 movl %eax,%ebx // und in %ebx rechnen:
929 sarl %cl,%ebx // um i Bits rechts shiften, Vorzeichen vervielfachen
930 movl %ebx,(%edi) // und wieder ablegen
931 // Letztes Digit in %eax.
934 L(srslu1:) // weiteres Digit shiften:
937 shrdl shcl %eax,(%edi) // (%edi) um %cl=i Bits rechts shiften, %eax von links reinshiften
938 // Letztes Digit in %ebx.
941 // weiteres Digit shiften:
944 shrdl shcl %ebx,(%edi) // (%edi) um %cl=i Bits rechts shiften, %ebx von links reinshiften
945 // Letztes Digit in %eax.
948 L(srslu2:) movl %eax,%ebx
949 L(srslu3:) xorl %eax,%eax // %eax := 0
950 shrdl shcl %ebx,%eax // %eax := niedrigste %cl=i Bits von %ebx, als Bits 31..32-i
951 popl %ebx // %ebx zurück
952 popl %edi // %edi zurück
955 // extern uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
957 DECLARE_FUNCTION(shiftrightcopy_loop_up)
958 C(shiftrightcopy_loop_up:)
959 pushl %esi // %esi retten
960 pushl %edi // %edi retten
961 pushl %ebx // %ebx retten
962 movl 16(%esp),%esi // %esi = sourceptr
963 movl 20(%esp),%edi // %edi = destptr
964 movl 24(%esp),%edx // count
965 movb 28(%esp),%cl // i
967 movl 32(%esp),%eax // %eax = carry
968 orl %edx,%edx // count = 0 ?
971 // erstes Digit shiften:
972 movl (%edi,%esi),%ebx // *sourceptr in %ebx halten
973 shldl shcl %ebx,%eax // carry um %cl=32-i Bits links shiften, dabei *sourceptr rein
974 movl %eax,(%edi) // und als *destptr ablegen
975 // Letztes Digit in %ebx.
978 L(srcld1:) // weiteres Digit shiften:
979 leal 4(%edi),%edi // sourceptr++, destptr++
980 movl (%edi,%esi),%eax // nächstes Digit nach %eax
981 shldl shcl %eax,%ebx // %ebx um %cl=32-i Bits links shiften, %eax von rechts reinshiften
982 movl %ebx,(%edi) // %ebx als *destptr ablegen
983 // Letztes Digit in %eax.
986 // weiteres Digit shiften:
987 leal 4(%edi),%edi // sourceptr++, destptr++
988 movl (%edi,%esi),%ebx // nächstes Digit nach %ebx
989 shldl shcl %ebx,%eax // %eax um %cl=32-i Bits links shiften, %ebx von rechts reinshiften
990 movl %eax,(%edi) // %eax als *destptr ablegen
991 // Letztes Digit in %ebx.
994 L(srcld2:) movl %ebx,%eax
995 L(srcld3:) shll %cl,%eax // %eax um 32-i Bits nach links shiften
996 popl %ebx // %ebx zurück
997 popl %edi // %edi zurück
998 popl %esi // %esi zurück
1001 // extern uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
1003 DECLARE_FUNCTION(mulusmall_loop_down)
1004 C(mulusmall_loop_down:)
1005 pushl %ebp // %ebp retten
1006 pushl %edi // %edi retten
1007 pushl %ebx // %ebx retten
1008 movl 16(%esp),%ebx // %ebx = digit
1009 movl 20(%esp),%edi // %edi = ptr
1010 movl 24(%esp),%ecx // %ecx = len
1011 movl 28(%esp),%ebp // %ebp = carry := newdigit
1013 negl %eax // %eax = -len
1015 leal -4(%edi,%eax,4),%edi // %edi = &ptr[-1-len]
1017 L(msld1:) movl (%edi,%ecx,4),%eax // *ptr
1018 mull %ebx // %edx|%eax := digit * *ptr
1019 addl %ebp,%eax // carry und Low-Teil des Produktes addieren
1021 adcl %edx,%ebp // Übertrag zum High-Teil %edx dazu, gibt neuen carry
1022 movl %eax,(%edi,%ecx,4) // Low-Teil als *ptr ablegen
1023 decl %ecx // count--, ptr--
1025 L(msld2:) movl %ebp,%eax // Ergebnis := letzter Übertrag
1026 popl %ebx // %ebx zurück
1027 popl %edi // %edi zurück
1028 popl %ebp // %ebp zurück
1031 // extern void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1033 DECLARE_FUNCTION(mulu_loop_down)
1035 pushl %ebp // %ebp retten
1036 pushl %edi // %edi retten
1037 pushl %esi // %esi retten
1038 pushl %ebx // %ebx retten
1039 movl 20(%esp),%ebx // %ebx = digit
1040 movl 24(%esp),%esi // %esi = sourceptr
1041 movl 28(%esp),%edi // %edi = destptr
1042 movl 32(%esp),%ecx // %ecx = len
1044 notl %eax // %eax = -1-len
1045 leal (%esi,%eax,4),%esi // %esi = &sourceptr[-1-len]
1046 leal (%edi,%eax,4),%edi // %edi = &destptr[-1-len]
1047 xorl %ebp,%ebp // %epb = carry := 0
1048 L(muld1:) movl (%esi,%ecx,4),%eax // *sourceptr
1049 mull %ebx // %edx|%eax := digit * *sourceptr
1050 addl %ebp,%eax // carry und Low-Teil des Produktes addieren
1052 adcl %edx,%ebp // Übertrag zum High-Teil %edx dazu, gibt neuen carry
1053 movl %eax,(%edi,%ecx,4) // Low-Teil als *destptr ablegen
1054 decl %ecx // count--, sourceptr--, destptr--
1056 movl %ebp,(%edi) // letzten Übertrag ablegen
1057 popl %ebx // %ebx zurück
1058 popl %esi // %esi zurück
1059 popl %edi // %edi zurück
1060 popl %ebp // %ebp zurück
1063 // extern uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1065 DECLARE_FUNCTION(muluadd_loop_down)
1066 C(muluadd_loop_down:)
1067 pushl %ebp // %ebp retten
1068 pushl %edi // %edi retten
1069 pushl %esi // %esi retten
1070 pushl %ebx // %ebx retten
1071 movl 20(%esp),%ebx // %ebx = digit
1072 movl 24(%esp),%esi // %esi = sourceptr
1073 movl 28(%esp),%edi // %edi = destptr
1074 movl 32(%esp),%ecx // %ecx = len
1076 notl %eax // %eax = -1-len
1077 leal (%esi,%eax,4),%esi // %esi = &sourceptr[-1-len]
1078 leal (%edi,%eax,4),%edi // %edi = &destptr[-1-len]
1079 xorl %ebp,%ebp // %epb = carry := 0
1080 L(muald1:) movl (%esi,%ecx,4),%eax // *sourceptr
1081 mull %ebx // %edx|%eax := digit * *sourceptr
1082 addl %ebp,%eax // carry und Low-Teil des Produktes addieren
1084 adcl %ebp,%edx // Übertrag zum High-Teil %edx dazu
1085 addl %eax,(%edi,%ecx,4) // Low-Teil zu *destptr addieren
1086 adcl %edx,%ebp // zweiten Übertrag zu %edx addieren, gibt neuen carry
1087 decl %ecx // count--, sourceptr--, destptr--
1089 movl %ebp,%eax // Ergebnis := letzter Übertrag
1090 popl %ebx // %ebx zurück
1091 popl %esi // %esi zurück
1092 popl %edi // %edi zurück
1093 popl %ebp // %ebp zurück
1096 // extern uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1098 DECLARE_FUNCTION(mulusub_loop_down)
1099 C(mulusub_loop_down:)
1100 pushl %ebp // %ebp retten
1101 pushl %edi // %edi retten
1102 pushl %esi // %esi retten
1103 pushl %ebx // %ebx retten
1104 movl 20(%esp),%ebx // %ebx = digit
1105 movl 24(%esp),%esi // %esi = sourceptr
1106 movl 28(%esp),%edi // %edi = destptr
1107 movl 32(%esp),%ecx // %ecx = len
1109 notl %eax // %eax = -1-len
1110 leal (%esi,%eax,4),%esi // %esi = &sourceptr[-1-len]
1111 leal (%edi,%eax,4),%edi // %edi = &destptr[-1-len]
1112 xorl %ebp,%ebp // %epb = carry := 0
1113 L(musld1:) movl (%esi,%ecx,4),%eax // *sourceptr
1114 mull %ebx // %edx|%eax := digit * *sourceptr
1115 addl %ebp,%eax // carry und Low-Teil des Produktes addieren
1117 adcl %ebp,%edx // Übertrag zum High-Teil %edx dazu
1118 subl %eax,(%edi,%ecx,4) // Low-Teil von *destptr subtrahieren
1119 adcl %edx,%ebp // zweiten Übertrag zu %edx addieren, gibt neuen carry
1120 decl %ecx // count--, sourceptr--, destptr--
1122 movl %ebp,%eax // Ergebnis := letzter Übertrag
1123 popl %ebx // %ebx zurück
1124 popl %esi // %esi zurück
1125 popl %edi // %edi zurück
1126 popl %ebp // %ebp zurück
1129 // extern uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
1131 DECLARE_FUNCTION(divu_loop_up)
1133 pushl %edi // %edi retten
1134 pushl %ebx // %ebx retten
1135 movl 12(%esp),%ebx // %ebx = digit
1136 movl 16(%esp),%edi // %edi = ptr
1137 movl 20(%esp),%ecx // %ecx = len
1138 xorl %edx,%edx // %edx = Rest := 0
1139 jecxz L(dlu2) // %ecx = 0 ?
1140 L(dlu1:) movl (%edi),%eax // nächstes Digit *ptr
1141 divl %ebx // Division von %edx|%eax durch %ebx
1142 movl %eax,(%edi) // Quotient %eax ablegen, Rest in %edx behalten
1143 leal 4(%edi),%edi // ptr++
1146 L(dlu2:) movl %edx,%eax // Ergebnis := letzter Rest
1147 popl %ebx // %ebx zurück
1148 popl %edi // %edi zurück
1151 // extern uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1153 DECLARE_FUNCTION(divucopy_loop_up)
1154 C(divucopy_loop_up:)
1155 pushl %edi // %edi retten
1156 pushl %esi // %esi retten
1157 pushl %ebx // %ebx retten
1158 movl 16(%esp),%ebx // %ebx = digit
1159 movl 20(%esp),%esi // %esi = sourceptr
1160 movl 24(%esp),%edi // %edi = destptr
1161 movl 28(%esp),%ecx // %ecx = len
1162 xorl %edx,%edx // %edx = Rest := 0
1163 jecxz L(dclu2) // %ecx = 0 ?
1165 L(dclu1:) movl (%esi,%edi),%eax // nächstes Digit *ptr
1166 divl %ebx // Division von %edx|%eax durch %ebx
1167 movl %eax,(%edi) // Quotient %eax ablegen, Rest in %edx behalten
1168 leal 4(%edi),%edi // sourceptr++, destptr++
1171 L(dclu2:) movl %edx,%eax // Ergebnis := letzter Rest
1172 popl %ebx // %ebx zurück
1173 popl %esi // %esi zurück
1174 popl %edi // %edi zurück
1179 #if !CL_DS_BIG_ENDIAN_P
1181 // extern void or_loop_down (uintD* xptr, uintD* yptr, uintC count);
1183 DECLARE_FUNCTION(or_loop_down)
1185 pushl %esi // %esi retten
1186 movl 8(%esp),%edx // %edx = xptr
1187 movl 12(%esp),%esi // %esi = yptr
1188 movl 16(%esp),%ecx // %ecx = count
1190 jecxz L(old2) // %ecx = 0 ?
1191 L(old1:) leal -4(%edx),%edx // xptr--, yptr--
1192 movl (%edx,%esi),%eax // *yptr
1193 orl %eax,(%edx) // *xptr |= ...
1196 L(old2:) popl %esi // %esi zurück
1199 // extern void xor_loop_down (uintD* xptr, uintD* yptr, uintC count);
1201 DECLARE_FUNCTION(xor_loop_down)
1203 pushl %esi // %esi retten
1204 movl 8(%esp),%edx // %edx = xptr
1205 movl 12(%esp),%esi // %esi = yptr
1206 movl 16(%esp),%ecx // %ecx = count
1208 jecxz L(xld2) // %ecx = 0 ?
1209 L(xld1:) leal -4(%edx),%edx // xptr--, yptr--
1210 movl (%edx,%esi),%eax // *yptr
1211 xorl %eax,(%edx) // *xptr ^= ...
1214 L(xld2:) popl %esi // %esi zurück
1217 // extern void and_loop_down (uintD* xptr, uintD* yptr, uintC count);
1219 DECLARE_FUNCTION(and_loop_down)
1221 pushl %esi // %esi retten
1222 movl 8(%esp),%edx // %edx = xptr
1223 movl 12(%esp),%esi // %esi = yptr
1224 movl 16(%esp),%ecx // %ecx = count
1226 jecxz L(ald2) // %ecx = 0 ?
1227 L(ald1:) leal -4(%edx),%edx // xptr--, yptr--
1228 movl (%edx,%esi),%eax // *yptr
1229 andl %eax,(%edx) // *xptr &= ...
1232 L(ald2:) popl %esi // %esi zurück
1235 // extern void eqv_loop_down (uintD* xptr, uintD* yptr, uintC count);
1237 DECLARE_FUNCTION(eqv_loop_down)
1239 pushl %esi // %esi retten
1240 movl 8(%esp),%edx // %edx = xptr
1241 movl 12(%esp),%esi // %esi = yptr
1242 movl 16(%esp),%ecx // %ecx = count
1244 jecxz L(eld2) // %ecx = 0 ?
1245 L(eld1:) leal -4(%edx),%edx // xptr--, yptr--
1246 movl (%edx),%eax // *xptr
1247 xorl (%edx,%esi),%eax // ^ *yptr
1249 movl %eax,(%edx) // =: *xptr
1252 L(eld2:) popl %esi // %esi zurück
1255 // extern void nand_loop_down (uintD* xptr, uintD* yptr, uintC count);
1257 DECLARE_FUNCTION(nand_loop_down)
1259 pushl %esi // %esi retten
1260 movl 8(%esp),%edx // %edx = xptr
1261 movl 12(%esp),%esi // %esi = yptr
1262 movl 16(%esp),%ecx // %ecx = count
1264 jecxz L(nald2) // %ecx = 0 ?
1265 L(nald1:) leal -4(%edx),%edx // xptr--, yptr--
1266 movl (%edx),%eax // *xptr
1267 andl (%edx,%esi),%eax // & *yptr
1269 movl %eax,(%edx) // =: *xptr
1272 L(nald2:) popl %esi // %esi zurück
1275 // extern void nor_loop_down (uintD* xptr, uintD* yptr, uintC count);
1277 DECLARE_FUNCTION(nor_loop_down)
1279 pushl %esi // %esi retten
1280 movl 8(%esp),%edx // %edx = xptr
1281 movl 12(%esp),%esi // %esi = yptr
1282 movl 16(%esp),%ecx // %ecx = count
1284 jecxz L(nold2) // %ecx = 0 ?
1285 L(nold1:) leal -4(%edx),%edx // xptr--, yptr--
1286 movl (%edx),%eax // *xptr
1287 orl (%edx,%esi),%eax // | *yptr
1289 movl %eax,(%edx) // =: *xptr
1292 L(nold2:) popl %esi // %esi zurück
1295 // extern void andc2_loop_down (uintD* xptr, uintD* yptr, uintC count);
1297 DECLARE_FUNCTION(andc2_loop_down)
1299 pushl %esi // %esi retten
1300 movl 8(%esp),%edx // %edx = xptr
1301 movl 12(%esp),%esi // %esi = yptr
1302 movl 16(%esp),%ecx // %ecx = count
1304 jecxz L(acld2) // %ecx = 0 ?
1305 L(acld1:) leal -4(%edx),%edx // xptr--, yptr--
1306 movl (%edx,%esi),%eax // *yptr
1307 notl %eax // ~ *yptr
1308 andl %eax,(%edx) // *xptr &= ...
1311 L(acld2:) popl %esi // %esi zurück
1314 // extern void orc2_loop_down (uintD* xptr, uintD* yptr, uintC count);
1316 DECLARE_FUNCTION(orc2_loop_down)
1318 pushl %esi // %esi retten
1319 movl 8(%esp),%edx // %edx = xptr
1320 movl 12(%esp),%esi // %esi = yptr
1321 movl 16(%esp),%ecx // %ecx = count
1323 jecxz L(ocld2) // %ecx = 0 ?
1324 L(ocld1:) leal -4(%edx),%edx // xptr--, yptr--
1325 movl (%edx,%esi),%eax // *yptr
1326 notl %eax // ~ *yptr
1327 orl %eax,(%edx) // *xptr |= ...
1330 L(ocld2:) popl %esi // %esi zurück
1333 // extern void not_loop_down (uintD* xptr, uintC count);
1335 DECLARE_FUNCTION(not_loop_down)
1337 movl 4(%esp),%edx // %edx = xptr
1338 movl 8(%esp),%ecx // %ecx = count
1339 jecxz L(nld2) // %ecx = 0 ?
1340 nop ; nop ; nop ; nop ; nop ; nop
1341 L(nld1:) leal -4(%edx),%edx // xptr--
1342 notl (%edx) // ~= *xptr
1347 // extern boolean and_test_loop_down (uintD* xptr, uintD* yptr, uintC count);
1349 DECLARE_FUNCTION(and_test_loop_down)
1350 C(and_test_loop_down:)
1351 pushl %esi // %esi retten
1352 movl 8(%esp),%edx // %edx = xptr
1353 movl 12(%esp),%esi // %esi = yptr
1354 movl 16(%esp),%ecx // %ecx = count
1355 jecxz L(atld2) // %ecx = 0 ?
1357 L(atld1:) leal -4(%edx),%edx // xptr--, yptr--
1358 movl (%edx,%esi),%eax // *yptr
1359 andl (%edx),%eax // *xptr & ...
1363 L(atld2:) xorl %eax,%eax // Ergebnis 0
1364 popl %esi // %esi zurück
1366 L(atld3:) movl $1,%eax // Ergebnis 1 (nicht irgendwas /=0 !)
1367 popl %esi // %esi zurück
1370 // extern cl_signean compare_loop_down (uintD* xptr, uintD* yptr, uintC count);
1372 DECLARE_FUNCTION(compare_loop_down)
1373 C(compare_loop_down:)
1374 movl %esi,%edx // %esi retten
1375 movl %edi,%eax // %edi retten
1376 movl 4(%esp),%esi // %esi = xptr
1377 movl 8(%esp),%edi // %edi = yptr
1378 movl 12(%esp),%ecx // %ecx = count
1381 cmpl %ecx,%ecx // initialize flags for the case %ecx is 0
1383 repz // Falls %ecx > 0:
1384 cmpsl // %ecx mal aufwärts (%edi) und (%esi) vergleichen
1385 // und weiterschleifen, falls Z, d.h. (%edi)=(%esi).
1387 // Flags -> Ergebnis:
1388 // Z,NC -> bis zum Schluß (%esi)-(%edi) = 0 -> x=y -> Ergebnis 0
1389 // NZ,C -> schließlich (%esi)-(%edi) < 0 -> x<y -> Ergebnis -1
1390 // NZ,NC -> schließlich (%esi)-(%edi) > 0 -> x>y -> Ergebnis +1
1391 movl %eax,%edi // %edi zurück
1392 movl %edx,%esi // %esi zurück
1393 jbe L(cmld1) // "be" = Z oder C
1394 movl $1,%eax // Ergebnis +1
1396 L(cmld1:) sbbl %eax,%eax // Ergebnis -1 (falls C) oder 0 (falls NC)
1399 // extern uintD add_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
1401 DECLARE_FUNCTION(add_loop_up)
1403 pushl %esi // %esi retten
1404 pushl %edi // %edi retten
1405 movl 12(%esp),%edx // %edx = sourceptr1
1406 movl 16(%esp),%esi // %esi = sourceptr2
1407 movl 20(%esp),%edi // %edi = destptr
1408 movl 24(%esp),%ecx // %ecx = count
1411 orl %ecx,%ecx // %ecx = 0 ?, Carry löschen
1413 L(alu1:) movl (%edx,%edi),%eax // *sourceptr1
1414 adcl (%esi,%edi),%eax // + *sourceptr2 + carry
1415 movl %eax,(%edi) // =: *destptr, neuen Carry behalten
1416 leal 4(%edi),%edi // sourceptr1++, sourceptr2++, destptr++
1419 L(alu2:) sbbl %eax,%eax // Ergebnis := - Carry
1420 popl %edi // %edi zurück
1421 popl %esi // %esi zurück
1424 // extern uintD addto_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
1426 DECLARE_FUNCTION(addto_loop_up)
1428 pushl %edi // %edi retten
1429 movl 8(%esp),%edx // %edx = sourceptr
1430 movl 12(%esp),%edi // %edi = destptr
1431 movl 16(%esp),%ecx // %ecx = count
1433 orl %ecx,%ecx // %ecx = 0 ?, Carry löschen
1435 L(atlu1:) movl (%edx,%edi),%eax // *sourceptr
1436 adcl %eax,(%edi) // + *destptr + carry =: *destptr, neuer Carry
1437 leal 4(%edi),%edi // sourceptr++, destptr++
1440 L(atlu2:) sbbl %eax,%eax // Ergebnis := - Carry
1441 popl %edi // %edi zurück
1444 // extern uintD inc_loop_up (uintD* ptr, uintC count);
1446 DECLARE_FUNCTION(inc_loop_up)
1448 movl 4(%esp),%edx // %edx = ptr
1449 movl 8(%esp),%ecx // %ecx = count
1450 jecxz L(ilu2) // %ecx = 0 ?
1451 L(ilu1:) addl $1,(%edx) // (*ptr)++
1452 jnc L(ilu3) // kein Carry -> fertig
1456 L(ilu2:) movl $1,%eax // Ergebnis := 1
1458 L(ilu3:) xorl %eax,%eax // Ergebnis := 0
1461 // extern uintD sub_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
1463 DECLARE_FUNCTION(sub_loop_up)
1465 pushl %esi // %esi retten
1466 pushl %edi // %edi retten
1467 movl 12(%esp),%edx // %edx = sourceptr1
1468 movl 16(%esp),%esi // %esi = sourceptr2
1469 movl 20(%esp),%edi // %edi = destptr
1470 movl 24(%esp),%ecx // %ecx = count
1473 orl %ecx,%ecx // %ecx = 0 ?, Carry löschen
1475 L(slu1:) movl (%edx,%edi),%eax // *sourceptr1
1476 sbbl (%esi,%edi),%eax // - *sourceptr2 - carry
1477 movl %eax,(%edi) // =: *destptr, neuen Carry behalten
1478 leal 4(%edi),%edi // sourceptr1++, sourceptr2++, destptr++
1481 L(slu2:) sbbl %eax,%eax // Ergebnis := - Carry
1482 popl %edi // %edi zurück
1483 popl %esi // %esi zurück
1486 // extern uintD subx_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
1488 DECLARE_FUNCTION(subx_loop_up)
1490 pushl %esi // %esi retten
1491 pushl %edi // %edi retten
1492 movl 12(%esp),%edx // %edx = sourceptr1
1493 movl 16(%esp),%esi // %esi = sourceptr2
1494 movl 20(%esp),%edi // %edi = destptr
1495 movl 24(%esp),%ecx // %ecx = count
1496 jecxz L(sxlu2) // %ecx = 0 ?
1499 movl 28(%esp),%eax // carry, 0 oder -1
1500 addl %eax,%eax // Bit 31 davon in den Carry
1502 L(sxlu1:) movl (%edx,%edi),%eax // *sourceptr1
1503 sbbl (%esi,%edi),%eax // - *sourceptr2 - carry
1504 movl %eax,(%edi) // =: *destptr, neuen Carry behalten
1505 leal 4(%edi),%edi // sourceptr1++, sourceptr2++, destptr++
1508 sbbl %eax,%eax // Ergebnis := - Carry
1509 popl %edi // %edi zurück
1510 popl %esi // %esi zurück
1512 L(sxlu2:) movl 28(%esp),%eax // Ergebnis := carry
1513 popl %edi // %edi zurück
1514 popl %esi // %esi zurück
1517 // extern uintD subfrom_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
1519 DECLARE_FUNCTION(subfrom_loop_up)
1521 pushl %edi // %edi retten
1522 movl 8(%esp),%edx // %edx = sourceptr
1523 movl 12(%esp),%edi // %edi = destptr
1524 movl 16(%esp),%ecx // %ecx = count
1526 orl %ecx,%ecx // %ecx = 0 ?, Carry löschen
1528 L(sflu1:) movl (%edx,%edi),%eax // *sourceptr
1529 sbbl %eax,(%edi) // *destptr - *sourceptr - carry =: *destptr, neuer Carry
1530 leal 4(%edi),%edi // sourceptr++, destptr++
1533 L(sflu2:) sbbl %eax,%eax // Ergebnis := - Carry
1534 popl %edi // %edi zurück
1537 // extern uintD dec_loop_up (uintD* ptr, uintC count);
1539 DECLARE_FUNCTION(dec_loop_up)
1541 movl 4(%esp),%edx // %edx = ptr
1542 movl 8(%esp),%ecx // %ecx = count
1543 jecxz L(dlu2) // %ecx = 0 ?
1544 L(dlu1:) subl $1,(%edx) // (*ptr)--
1545 jnc L(dlu3) // kein Carry -> fertig
1549 L(dlu2:) movl $-1,%eax // Ergebnis := -1
1551 L(dlu3:) xorl %eax,%eax // Ergebnis := 0
1554 // extern uintD neg_loop_up (uintD* ptr, uintC count);
1556 DECLARE_FUNCTION(neg_loop_up)
1558 movl 4(%esp),%edx // %edx = ptr
1559 movl 8(%esp),%ecx // %ecx = count
1560 // erstes Digit /=0 suchen:
1561 jecxz L(nlu2) // %ecx = 0 ?
1562 L(nlu1:) negl (%edx)
1567 L(nlu2:) xorl %eax,%eax // Ergebnis := 0
1569 nop ; nop ; nop ; nop ; nop ; nop
1570 L(nlu3:) // erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
1571 // alle anderen Digits invertieren:
1574 L(nlu4:) leal 4(%edx),%edx
1578 L(nlu5:) movl $-1,%eax // Ergebnis := -1
1581 // extern uintD shift1left_loop_up (uintD* ptr, uintC count);
1583 DECLARE_FUNCTION(shift1left_loop_up)
1584 C(shift1left_loop_up:)
1585 movl 4(%esp),%edx // %edx = ptr
1586 movl 8(%esp),%ecx // %ecx = count
1587 orl %ecx,%ecx // %ecx = 0 ?, Carry löschen
1589 nop ; nop ; nop ; nop
1590 L(s1llu1:) rcll $1,(%edx) // *ptr und Carry um 1 Bit links rotieren
1591 leal 4(%edx),%edx // ptr++
1594 L(s1llu2:) sbbl %eax,%eax // Ergebnis := - Carry
1597 // extern uintD shiftleft_loop_up (uintD* ptr, uintC count, uintC i, uintD carry);
1599 DECLARE_FUNCTION(shiftleft_loop_up)
1600 C(shiftleft_loop_up:)
1601 pushl %edi // %edi retten
1602 pushl %ebx // %ebx retten
1603 movl 12(%esp),%edi // %edi = ptr
1604 movl 16(%esp),%edx // %edx = count
1605 movb 20(%esp),%cl // %cl = i
1606 orl %edx,%edx // count = 0 ?
1608 // erstes Digit shiften:
1609 movl (%edi),%eax // Digit in %eax halten
1610 movl %eax,%ebx // und in %ebx rechnen:
1611 shll %cl,%ebx // um i Bits links shiften
1612 orl 24(%esp),%ebx // und die unteren i Bits eintragen
1613 movl %ebx,(%edi) // und wieder ablegen
1615 // Letztes Digit in %eax.
1618 nop ; nop ; nop ; nop
1619 L(sllu1:) // weiteres Digit shiften:
1621 shldl shcl %eax,(%edi) // (%edi) um %cl=i Bits links shiften, %eax von rechts reinshiften
1623 // Letztes Digit in %ebx.
1626 // weiteres Digit shiften:
1628 shldl shcl %ebx,(%edi) // (%edi) um %cl=i Bits links shiften, %ebx von rechts reinshiften
1630 // Letztes Digit in %eax.
1633 L(sllu2:) movl %eax,%ebx
1634 L(sllu3:) xorl %eax,%eax // %eax := 0
1635 shldl shcl %ebx,%eax // %eax := höchste %cl=i Bits von %ebx
1636 popl %ebx // %ebx zurück
1637 popl %edi // %edi zurück
1639 L(sllu4:) movl 24(%esp),%eax // %eax := carry
1640 popl %ebx // %ebx zurück
1641 popl %edi // %edi zurück
1646 // extern uintD shiftleftcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
1648 DECLARE_FUNCTION(shiftleftcopy_loop_up)
1649 C(shiftleftcopy_loop_up:)
1650 pushl %esi // %esi retten
1651 pushl %edi // %edi retten
1652 pushl %ebx // %ebx retten
1653 movl 16(%esp),%esi // %esi = sourceptr
1654 movl 20(%esp),%edi // %edi = destptr
1655 movl 24(%esp),%edx // count
1656 movb 28(%esp),%cl // i
1657 orl %edx,%edx // count = 0 ?
1660 // erstes Digit shiften:
1661 movl (%edi,%esi),%ebx // *sourceptr in %ebx halten
1662 movl %ebx,%eax // und in %eax rechnen:
1663 shll %cl,%eax // um i Bits links shiften, rechts Nullen rein
1664 movl %eax,(%edi) // und als *destptr ablegen
1665 leal 4(%edi),%edi // sourceptr++, destptr++
1666 // Letztes Digit in %ebx.
1670 L(slclu1:) // weiteres Digit shiften:
1671 movl (%edi,%esi),%eax // nächstes Digit nach %eax
1672 shrdl shcl %eax,%ebx // %ebx um %cl=32-i Bits rechts shiften, %eax von links reinshiften
1673 movl %ebx,(%edi) // %ebx als *destptr ablegen
1674 leal 4(%edi),%edi // sourceptr++, destptr++
1675 // Letztes Digit in %eax.
1678 // weiteres Digit shiften:
1679 movl (%edi,%esi),%ebx // nächstes Digit nach %ebx
1680 shrdl shcl %ebx,%eax // %eax um %cl=32-i Bits rechts shiften, %ebx von links reinshiften
1681 movl %eax,(%edi) // %eax als *destptr ablegen
1682 leal 4(%edi),%edi // sourceptr++, destptr++
1683 // Letztes Digit in %ebx.
1686 L(slclu2:) movl %ebx,%eax
1687 L(slclu3:) shrl %cl,%eax // %eax um 32-i Bits nach rechts shiften
1688 popl %ebx // %ebx zurück
1689 popl %edi // %edi zurück
1690 popl %esi // %esi zurück
1692 L(slclu4:) xorl %eax,%eax // %eax := 0
1693 popl %ebx // %ebx zurück
1694 popl %edi // %edi zurück
1695 popl %esi // %esi zurück
1698 #if !CL_DS_BIG_ENDIAN_P
1700 // extern uintD shift1right_loop_down (uintD* ptr, uintC count, uintD carry);
1702 DECLARE_FUNCTION(shift1right_loop_down)
1703 C(shift1right_loop_down:)
1704 movl 4(%esp),%edx // %edx = ptr
1705 movl 8(%esp),%ecx // %ecx = count
1706 movl 12(%esp),%eax // %eax = carry (0 oder -1)
1707 jecxz L(s1rlu3) // %ecx = 0 ?
1708 addl %eax,%eax // Carry := Bit 31 von carry
1709 L(s1rlu1:) leal -4(%edx),%edx // ptr--
1710 rcrl $1,(%edx) // *ptr und Carry um 1 Bit rechts rotieren
1713 L(s1rlu2:) sbbl %eax,%eax // Ergebnis := - Carry
1716 // extern uintD shiftright_loop_down (uintD* ptr, uintC count, uintC i);
1718 DECLARE_FUNCTION(shiftright_loop_down)
1719 C(shiftright_loop_down:)
1720 pushl %edi // %edi retten
1721 pushl %ebx // %ebx retten
1722 movl 12(%esp),%edi // %edi = ptr
1723 movl 16(%esp),%edx // %edx = count
1724 movb 20(%esp),%cl // %cl = i
1725 orl %edx,%edx // count = 0 ?
1727 // erstes Digit shiften:
1729 movl (%edi),%eax // Digit in %eax halten
1730 movl %eax,%ebx // und in %ebx rechnen:
1731 shrl %cl,%ebx // um i Bits rechts shiften
1732 movl %ebx,(%edi) // und wieder ablegen
1733 // Letztes Digit in %eax.
1736 L(srld1:) // weiteres Digit shiften:
1739 shrdl shcl %eax,(%edi) // (%edi) um %cl=i Bits rechts shiften, %eax von links reinshiften
1740 // Letztes Digit in %ebx.
1743 // weiteres Digit shiften:
1746 shrdl shcl %ebx,(%edi) // (%edi) um %cl=i Bits rechts shiften, %ebx von links reinshiften
1747 // Letztes Digit in %eax.
1750 L(srld2:) movl %eax,%ebx
1751 L(srld3:) xorl %eax,%eax // %eax := 0
1752 shrdl shcl %ebx,%eax // %eax := niedrigste %cl=i Bits von %ebx, als Bits 31..32-i
1753 popl %ebx // %ebx zurück
1754 popl %edi // %edi zurück
1756 L(srld4:) xorl %eax,%eax // %eax := 0
1757 popl %ebx // %ebx zurück
1758 popl %edi // %edi zurück
1761 // extern uintD shiftrightsigned_loop_down (uintD* ptr, uintC count, uintC i);
1763 DECLARE_FUNCTION(shiftrightsigned_loop_down)
1764 C(shiftrightsigned_loop_down:)
1765 pushl %edi // %edi retten
1766 pushl %ebx // %ebx retten
1767 movl 12(%esp),%edi // %edi = ptr
1768 movl 16(%esp),%edx // %edx = count
1769 movb 20(%esp),%cl // %cl = i
1770 // erstes Digit shiften:
1772 movl (%edi),%eax // Digit in %eax halten
1773 movl %eax,%ebx // und in %ebx rechnen:
1774 sarl %cl,%ebx // um i Bits rechts shiften, Vorzeichen vervielfachen
1775 movl %ebx,(%edi) // und wieder ablegen
1776 // Letztes Digit in %eax.
1779 nop ; nop ; nop ; nop
1780 L(srsld1:) // weiteres Digit shiften:
1783 shrdl shcl %eax,(%edi) // (%edi) um %cl=i Bits rechts shiften, %eax von links reinshiften
1784 // Letztes Digit in %ebx.
1787 // weiteres Digit shiften:
1790 shrdl shcl %ebx,(%edi) // (%edi) um %cl=i Bits rechts shiften, %ebx von links reinshiften
1791 // Letztes Digit in %eax.
1794 L(srsld2:) movl %eax,%ebx
1795 L(srsld3:) xorl %eax,%eax // %eax := 0
1796 shrdl shcl %ebx,%eax // %eax := niedrigste %cl=i Bits von %ebx, als Bits 31..32-i
1797 popl %ebx // %ebx zurück
1798 popl %edi // %edi zurück
1801 // extern uintD shiftrightcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
1803 DECLARE_FUNCTION(shiftrightcopy_loop_down)
1804 C(shiftrightcopy_loop_down:)
1805 pushl %esi // %esi retten
1806 pushl %edi // %edi retten
1807 pushl %ebx // %ebx retten
1808 movl 16(%esp),%esi // %esi = sourceptr
1809 movl 20(%esp),%edi // %edi = destptr
1810 movl 24(%esp),%edx // count
1811 movb 28(%esp),%cl // i
1813 movl 32(%esp),%eax // %eax = carry
1814 orl %edx,%edx // count = 0 ?
1817 // erstes Digit shiften:
1818 leal -4(%edi),%edi // sourceptr--, destptr--
1819 movl (%edi,%esi),%ebx // *sourceptr in %ebx halten
1820 shldl shcl %ebx,%eax // carry um %cl=32-i Bits links shiften, dabei *sourceptr rein
1821 movl %eax,(%edi) // und als *destptr ablegen
1822 // Letztes Digit in %ebx.
1826 L(srclu1:) // weiteres Digit shiften:
1827 leal -4(%edi),%edi // sourceptr--, destptr--
1828 movl (%edi,%esi),%eax // nächstes Digit nach %eax
1829 shldl shcl %eax,%ebx // %ebx um %cl=32-i Bits links shiften, %eax von rechts reinshiften
1830 movl %ebx,(%edi) // %ebx als *destptr ablegen
1831 // Letztes Digit in %eax.
1834 // weiteres Digit shiften:
1835 leal -4(%edi),%edi // sourceptr--, destptr--
1836 movl (%edi,%esi),%ebx // nächstes Digit nach %ebx
1837 shldl shcl %ebx,%eax // %eax um %cl=32-i Bits links shiften, %ebx von rechts reinshiften
1838 movl %eax,(%edi) // %eax als *destptr ablegen
1839 // Letztes Digit in %ebx.
1842 L(srclu2:) movl %ebx,%eax
1843 L(srclu3:) shll %cl,%eax // %eax um 32-i Bits nach links shiften
1844 popl %ebx // %ebx zurück
1845 popl %edi // %edi zurück
1846 popl %esi // %esi zurück
1849 // extern uintD mulusmall_loop_up (uintD digit, uintD* ptr, uintC len, uintD newdigit);
1851 DECLARE_FUNCTION(mulusmall_loop_up)
1852 C(mulusmall_loop_up:)
1853 pushl %ebp // %ebp retten
1854 pushl %edi // %edi retten
1855 pushl %ebx // %ebx retten
1856 movl 16(%esp),%ebx // %ebx = digit
1857 movl 20(%esp),%edi // %edi = ptr
1858 movl 24(%esp),%ecx // %ecx = len
1859 movl 28(%esp),%ebp // %ebp = carry := newdigit
1860 leal (%edi,%ecx,4),%edi // %edi = &ptr[len]
1861 negl %ecx // %ecx = -count
1863 L(mslu1:) movl (%edi,%ecx,4),%eax // *ptr
1864 mull %ebx // %edx|%eax := digit * *ptr
1865 addl %ebp,%eax // carry und Low-Teil des Produktes addieren
1867 adcl %edx,%ebp // Übertrag zum High-Teil %edx dazu, gibt neuen carry
1868 movl %eax,(%edi,%ecx,4) // Low-Teil als *ptr ablegen
1869 incl %ecx // count--, ptr++
1871 L(mslu2:) movl %ebp,%eax // Ergebnis := letzter Übertrag
1872 popl %ebx // %ebx zurück
1873 popl %edi // %edi zurück
1874 popl %ebp // %ebp zurück
1877 // extern void mulu_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1879 DECLARE_FUNCTION(mulu_loop_up)
1881 pushl %ebp // %ebp retten
1882 pushl %edi // %edi retten
1883 pushl %esi // %esi retten
1884 pushl %ebx // %ebx retten
1885 movl 20(%esp),%ebx // %ebx = digit
1886 movl 24(%esp),%esi // %esi = sourceptr
1887 movl 28(%esp),%edi // %edi = destptr
1888 movl 32(%esp),%ecx // %ecx = len
1889 leal (%esi,%ecx,4),%esi // %esi = &sourceptr[len]
1890 leal (%edi,%ecx,4),%edi // %edi = &destptr[len]
1891 negl %ecx // %ecx = -count
1892 xorl %ebp,%ebp // %epb = carry := 0
1894 L(mulu1:) movl (%esi,%ecx,4),%eax // *sourceptr
1895 mull %ebx // %edx|%eax := digit * *sourceptr
1896 addl %ebp,%eax // carry und Low-Teil des Produktes addieren
1898 adcl %edx,%ebp // Übertrag zum High-Teil %edx dazu, gibt neuen carry
1899 movl %eax,(%edi,%ecx,4) // Low-Teil als *destptr ablegen
1900 incl %ecx // count--, sourceptr++, destptr++
1902 movl %ebp,(%edi) // letzten Übertrag ablegen
1903 popl %ebx // %ebx zurück
1904 popl %esi // %esi zurück
1905 popl %edi // %edi zurück
1906 popl %ebp // %ebp zurück
1909 // extern uintD muluadd_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1911 DECLARE_FUNCTION(muluadd_loop_up)
1913 pushl %ebp // %ebp retten
1914 pushl %edi // %edi retten
1915 pushl %esi // %esi retten
1916 pushl %ebx // %ebx retten
1917 movl 20(%esp),%ebx // %ebx = digit
1918 movl 24(%esp),%esi // %esi = sourceptr
1919 movl 28(%esp),%edi // %edi = destptr
1920 movl 32(%esp),%ecx // %ecx = len
1921 leal (%esi,%ecx,4),%esi // %esi = &sourceptr[len]
1922 leal (%edi,%ecx,4),%edi // %edi = &destptr[len]
1923 negl %ecx // %ecx = -count
1924 xorl %ebp,%ebp // %epb = carry := 0
1926 L(mualu1:) movl (%esi,%ecx,4),%eax // *sourceptr
1927 mull %ebx // %edx|%eax := digit * *sourceptr
1928 addl %ebp,%eax // carry und Low-Teil des Produktes addieren
1930 adcl %ebp,%edx // Übertrag zum High-Teil %edx dazu
1931 addl %eax,(%edi,%ecx,4) // Low-Teil zu *destptr addieren
1932 adcl %edx,%ebp // zweiten Übertrag zu %edx addieren, gibt neuen carry
1933 incl %ecx // count--, sourceptr++, destptr++
1935 movl %ebp,%eax // Ergebnis := letzter Übertrag
1936 popl %ebx // %ebx zurück
1937 popl %esi // %esi zurück
1938 popl %edi // %edi zurück
1939 popl %ebp // %ebp zurück
1942 // extern uintD mulusub_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1944 DECLARE_FUNCTION(mulusub_loop_up)
1946 pushl %ebp // %ebp retten
1947 pushl %edi // %edi retten
1948 pushl %esi // %esi retten
1949 pushl %ebx // %ebx retten
1950 movl 20(%esp),%ebx // %ebx = digit
1951 movl 24(%esp),%esi // %esi = sourceptr
1952 movl 28(%esp),%edi // %edi = destptr
1953 movl 32(%esp),%ecx // %ecx = len
1954 leal (%esi,%ecx,4),%esi // %esi = &sourceptr[len]
1955 leal (%edi,%ecx,4),%edi // %edi = &destptr[len]
1956 negl %ecx // %ecx = -count
1957 xorl %ebp,%ebp // %epb = carry := 0
1959 L(muslu1:) movl (%esi,%ecx,4),%eax // *sourceptr
1960 mull %ebx // %edx|%eax := digit * *sourceptr
1961 addl %ebp,%eax // carry und Low-Teil des Produktes addieren
1963 adcl %ebp,%edx // Übertrag zum High-Teil %edx dazu
1964 subl %eax,(%edi,%ecx,4) // Low-Teil von *destptr subtrahieren
1965 adcl %edx,%ebp // zweiten Übertrag zu %edx addieren, gibt neuen carry
1966 incl %ecx // count--, sourceptr++, destptr++
1968 movl %ebp,%eax // Ergebnis := letzter Übertrag
1969 popl %ebx // %ebx zurück
1970 popl %esi // %esi zurück
1971 popl %edi // %edi zurück
1972 popl %ebp // %ebp zurück
1975 // extern uintD divu_loop_down (uintD digit, uintD* ptr, uintC len);
1977 DECLARE_FUNCTION(divu_loop_down)
1979 pushl %edi // %edi retten
1980 pushl %ebx // %ebx retten
1981 movl 12(%esp),%ebx // %ebx = digit
1982 movl 16(%esp),%edi // %edi = ptr
1983 movl 20(%esp),%ecx // %ecx = len
1984 xorl %edx,%edx // %edx = Rest := 0
1985 jecxz L(dld2) // %ecx = 0 ?
1986 L(dld1:) leal -4(%edi),%edi // ptr--
1987 movl (%edi),%eax // nächstes Digit *ptr
1988 divl %ebx // Division von %edx|%eax durch %ebx
1989 movl %eax,(%edi) // Quotient %eax ablegen, Rest in %edx behalten
1992 L(dld2:) movl %edx,%eax // Ergebnis := letzter Rest
1993 popl %ebx // %ebx zurück
1994 popl %edi // %edi zurück
1997 // extern uintD divucopy_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1999 DECLARE_FUNCTION(divucopy_loop_down)
2000 C(divucopy_loop_down:)
2001 pushl %edi // %edi retten
2002 pushl %esi // %esi retten
2003 pushl %ebx // %ebx retten
2004 movl 16(%esp),%ebx // %ebx = digit
2005 movl 20(%esp),%esi // %esi = sourceptr
2006 movl 24(%esp),%edi // %edi = destptr
2007 movl 28(%esp),%ecx // %ecx = len
2008 xorl %edx,%edx // %edx = Rest := 0
2009 jecxz L(dcld2) // %ecx = 0 ?
2011 L(dcld1:) leal -4(%edi),%edi // sourceptr--, destptr--
2012 movl (%esi,%edi),%eax // nächstes Digit *ptr
2013 divl %ebx // Division von %edx|%eax durch %ebx
2014 movl %eax,(%edi) // Quotient %eax ablegen, Rest in %edx behalten
2017 L(dcld2:) movl %edx,%eax // Ergebnis := letzter Rest
2018 popl %ebx // %ebx zurück
2019 popl %esi // %esi zurück
2020 popl %edi // %edi zurück
2025 // extern void shiftxor_loop_up (uintD* xptr, const uintD* yptr, uintC count, uintC i);
2027 DECLARE_FUNCTION(shiftxor_loop_up)
2028 C(shiftxor_loop_up:)
2029 pushl %esi // %esi retten
2030 pushl %edi // %edi retten
2031 pushl %ebx // %ebx retten
2032 movl 16(%esp),%esi // %esi = xptr
2033 movl 20(%esp),%edi // %edi = yptr
2034 movl 24(%esp),%edx // count
2035 movb 28(%esp),%cl // i
2036 orl %edx,%edx // count = 0 ?
2039 // erstes Digit shiften:
2040 movl (%esi,%edi),%ebx // *yptr in %ebx halten
2041 movl %ebx,%eax // und in %eax rechnen:
2042 shll %cl,%eax // um i Bits links shiften, rechts Nullen rein
2043 xorl %eax,(%esi) // und mit *xptr verknüpfen und ablegen
2044 leal 4(%esi),%esi // sourceptr++, destptr++
2045 // Letztes Digit in %ebx.
2049 L(shxlu1:) // weiteres Digit shiften:
2050 movl (%esi,%edi),%eax // nächstes Digit nach %eax
2051 shrdl shcl %eax,%ebx // %ebx um %cl=32-i Bits rechts shiften, %eax von links reinshiften
2052 xorl %ebx,(%esi) // %ebx mit *xptr verknüpfen und ablegen
2053 leal 4(%esi),%esi // xptr++, yptr++
2054 // Letztes Digit in %eax.
2057 // weiteres Digit shiften:
2058 movl (%esi,%edi),%ebx // nächstes Digit nach %ebx
2059 shrdl shcl %ebx,%eax // %eax um %cl=32-i Bits rechts shiften, %ebx von links reinshiften
2060 xorl %eax,(%esi) // %eax mit *xptr verknüpfen und ablegen
2061 leal 4(%esi),%esi // xptr++, yptr++
2062 // Letztes Digit in %ebx.
2065 L(shxlu2:) movl %ebx,%eax
2066 L(shxlu3:) shrl %cl,%eax // %eax um 32-i Bits nach rechts shiften
2067 xorl %eax,(%esi) // und mit *xptr verknüpfen und ablegen
2068 L(shxlu4:) popl %ebx // %ebx zurück
2069 popl %edi // %edi zurück
2070 popl %esi // %esi zurück