1 // Externe Routinen zu ARILEV1.D
3 // Endianness: irrelevant
4 // Compiler: GNU-C oder ...
5 // Parameter-Übergabe: in Registern $4,$5,$6,$7, und auf dem Stack 16($sp),...
6 // Rückgabewert: in Register $2
7 // Einstellungen: intCsize=32, intDsize=32.
8 // Besonderheiten: Nach jedem Ladebefehl ein Wartetakt nötig, bevor der
9 // geholte Wert benutzt werden darf.
11 // When this file is compiled into a shared library, ELF linkers need to
12 // know which symbols are functions.
13 #if defined(__GNU__) || defined(__NetBSD__)
14 #define DECLARE_FUNCTION(name) .type name,@function
16 #define DECLARE_FUNCTION(name)
26 .globl clear_loop_down
30 .globl compare_loop_up
31 #if CL_DS_BIG_ENDIAN_P
40 .globl and_test_loop_up
42 .globl addto_loop_down
46 .globl subfrom_loop_down
56 .globl andc2_loop_down
59 .globl and_test_loop_down
60 .globl compare_loop_down
66 .globl subfrom_loop_up
71 #ifndef __GNUC__ /* mit GNU-C machen wir mulu32() als Macro, der inline multipliziert */
73 // extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
74 // 2^32*hi+lo := arg1*arg2.
77 DECLARE_FUNCTION(mulu32_)
78 .ent mulu32_ // Input in $4,$5, Output in $2,mulu32_high
80 multu $5,$4 // arg1 * arg2
83 sw $6,mulu32_high // hi abspeichern // Adressierung?? Deklaration??
89 // extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
91 DECLARE_FUNCTION(copy_loop_up)
92 .ent copy_loop_up // Input in $4,$5,$6, Output in $2
93 colu1: lw $12,($4) // d = *sourceptr
94 addu $4,4 // sourceptr++
95 sw $12,($5) // *destptr = d
96 addu $5,4 // destptr++
99 bnez $6,colu1 // until (count==0)
100 move $2,$5 // destptr
104 // extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
106 DECLARE_FUNCTION(copy_loop_down)
107 .ent copy_loop_down // Input in $4,$5,$6, Output in $2
108 cold1: subu $4,4 // sourceptr--
109 lw $12,($4) // d = *sourceptr
110 subu $5,4 // destptr--
111 sw $12,($5) // *destptr = d
114 bnez $6,cold1 // until (count==0)
115 move $2,$5 // destptr
119 // extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
121 DECLARE_FUNCTION(fill_loop_up)
122 .ent fill_loop_up // Input in $4,$5,$6, Output in $2
123 flu1: sw $6,($4) // *destptr = filler
124 addu $4,4 // destptr++
127 bnez $5,flu1 // until (count==0)
128 move $2,$4 // destptr
132 // extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
134 DECLARE_FUNCTION(fill_loop_down)
135 .ent fill_loop_down // Input in $4,$5,$6, Output in $2
136 fld1: subu $4,4 // destptr--
137 sw $6,($4) // *destptr = filler
140 bnez $5,fld1 // until (count==0)
141 move $2,$4 // destptr
145 // extern uintD* clear_loop_up (uintD* destptr, uintC count);
147 DECLARE_FUNCTION(clear_loop_up)
148 .ent clear_loop_up // Input in $4,$5, Output in $2
149 cllu1: sw $0,($4) // *destptr = 0
150 addu $4,4 // destptr++
153 bnez $5,cllu1 // until (count==0)
154 move $2,$4 // destptr
158 // extern uintD* clear_loop_down (uintD* destptr, uintC count);
160 DECLARE_FUNCTION(clear_loop_down)
161 .ent clear_loop_down // Input in $4,$5, Output in $2
162 clld1: subu $4,4 // destptr--
163 sw $0,($4) // *destptr = 0
166 bnez $5,clld1 // until (count==0)
167 move $2,$4 // destptr
171 // extern boolean test_loop_up (uintD* ptr, uintC count);
173 DECLARE_FUNCTION(test_loop_up)
174 .ent test_loop_up // Input in $4,$5
175 tlu1: lw $12,($4) // x = *ptr
180 bnez $5,tlu1 // until (count==0)
187 // extern boolean test_loop_down (uintD* ptr, uintC count);
189 DECLARE_FUNCTION(test_loop_down)
190 .ent test_loop_down // Input in $4,$5
191 tld1: subu $4,4 // ptr--
192 lw $12,($4) // x = *ptr
196 bnez $5,tld1 // until (count==0)
203 #if CL_DS_BIG_ENDIAN_P
205 // extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
207 DECLARE_FUNCTION(or_loop_up)
208 .ent or_loop_up // Input in $4,$5,$6
209 olu1: lw $12,($4) // x = *xptr
210 lw $13,($5) // y = *yptr
213 sw $12,($4) // *xptr = x
217 bnez $6,olu1 // until (count==0)
223 // extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
225 DECLARE_FUNCTION(xor_loop_up)
226 .ent xor_loop_up // Input in $4,$5,$6
227 xlu1: lw $12,($4) // x = *xptr
228 lw $13,($5) // y = *yptr
230 xor $12,$13 // x ^= y
231 sw $12,($4) // *xptr = x
235 bnez $6,xlu1 // until (count==0)
239 #if CL_DS_BIG_ENDIAN_P
241 // extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
243 DECLARE_FUNCTION(and_loop_up)
244 .ent and_loop_up // Input in $4,$5,$6
245 alu1: lw $12,($4) // x = *xptr
246 lw $13,($5) // y = *yptr
248 and $12,$13 // x &= y
249 sw $12,($4) // *xptr = x
253 bnez $6,alu1 // until (count==0)
257 // extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
259 DECLARE_FUNCTION(eqv_loop_up)
260 .ent eqv_loop_up // Input in $4,$5,$6
261 nxlu1: lw $12,($4) // x = *xptr
262 lw $13,($5) // y = *yptr
264 xor $12,$13 // x ^= y
266 sw $12,($4) // *xptr = x
270 bnez $6,nxlu1 // until (count==0)
274 // extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
276 DECLARE_FUNCTION(nand_loop_up)
277 .ent nand_loop_up // Input in $4,$5,$6
278 nalu1: lw $12,($4) // x = *xptr
279 lw $13,($5) // y = *yptr
281 and $12,$13 // x &= y // Gibt es 'nand $12,$13' ??
283 sw $12,($4) // *xptr = x
287 bnez $6,nalu1 // until (count==0)
291 // extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
293 DECLARE_FUNCTION(nor_loop_up)
294 .ent nor_loop_up // Input in $4,$5,$6
295 nolu1: lw $12,($4) // x = *xptr
296 lw $13,($5) // y = *yptr
298 nor $12,$13 // x = ~(x|y)
299 sw $12,($4) // *xptr = x
303 bnez $6,nolu1 // until (count==0)
307 // extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
309 DECLARE_FUNCTION(andc2_loop_up)
310 .ent andc2_loop_up // Input in $4,$5,$6
311 aclu1: lw $12,($4) // x = *xptr
312 lw $13,($5) // y = *yptr
315 and $12,$13 // x &= y
316 sw $12,($4) // *xptr = x
320 bnez $6,aclu1 // until (count==0)
324 // extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
326 DECLARE_FUNCTION(orc2_loop_up)
327 .ent orc2_loop_up // Input in $4,$5,$6
328 oclu1: lw $12,($4) // x = *xptr
329 lw $13,($5) // y = *yptr
333 sw $12,($4) // *xptr = x
337 bnez $6,oclu1 // until (count==0)
341 // extern void not_loop_up (uintD* xptr, uintC count);
343 DECLARE_FUNCTION(not_loop_up)
344 .ent not_loop_up // Input in $4,$5
345 nlu1: lw $12,($4) // x = *xptr
348 sw $12,($4) // *xptr = x
351 bnez $5,nlu1 // until (count==0)
355 // extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
357 DECLARE_FUNCTION(and_test_loop_up)
358 .ent and_test_loop_up // Input in $4,$5,$6
359 atlu1: lw $12,($4) // x = *xptr
360 lw $13,($5) // y = *yptr
362 and $12,$13 // x &= y
363 bnez $12,atlu3 // if (x) ...
367 bnez $6,atlu1 // until (count==0)
372 .end and_test_loop_up
376 // extern cl_signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
378 DECLARE_FUNCTION(compare_loop_up)
379 .ent compare_loop_up // Input in $4,$5,$6
380 cmlu1: lw $12,($4) // x = *xptr
381 lw $13,($5) // y = *yptr
383 bne $12,$13,cmlu3 // if (!(x==y)) ...
387 bnez $6,cmlu1 // until (count==0)
390 cmlu3: bltu $12,$13,cmlu4 // if (x<y) ...
393 cmlu4: li $2,-1 // -1
397 #if CL_DS_BIG_ENDIAN_P
399 // extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
401 DECLARE_FUNCTION(add_loop_down)
402 .ent add_loop_down // Input in $4,$5,$6,$7, Output in $2
404 subu $4,4 // sourceptr1--
405 subu $5,4 // sourceptr2--
406 lw $12,($4) // source1 = *sourceptr1
407 lw $13,($5) // source2 = *sourceptr2
408 subu $6,4 // destptr--
409 addu $12,$13 // dest = source1 + source2
410 sw $12,($6) // *destptr = dest
411 bltu $12,$13,ald4 // if (dest < source2) [also Carry] ...
415 bnez $7,ald1 // until (count==0)
419 subu $4,4 // sourceptr1--
420 subu $5,4 // sourceptr2--
421 lw $12,($4) // source1 = *sourceptr1
422 lw $13,($5) // source2 = *sourceptr2
423 subu $6,4 // destptr--
424 addu $12,$13 // dest = source1 + source2
426 sw $12,($6) // *destptr = dest
427 bgtu $12,$13,ald2 // if (dest > source2) [also kein Carry] ...
428 ald4: subu $7,1 // count--
429 bnez $7,ald3 // until (count==0)
434 // extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
436 DECLARE_FUNCTION(addto_loop_down)
437 .ent addto_loop_down // Input in $4,$5,$6, Output in $2
439 subu $4,4 // sourceptr--
440 subu $5,4 // destptr--
441 lw $12,($4) // source1 = *sourceptr
442 lw $13,($5) // source2 = *destptr
444 addu $12,$13 // dest = source1 + source2
445 sw $12,($5) // *destptr = dest
446 bltu $12,$13,atld4 // if (dest < source2) [also Carry] ...
448 atld2: bnez $6,atld1 // until (count==0)
452 subu $4,4 // sourceptr--
453 subu $5,4 // destptr--
454 lw $12,($4) // source1 = *sourceptr
455 lw $13,($5) // source2 = *destptr
457 addu $12,$13 // dest = source1 + source2
459 sw $12,($5) // *destptr = dest
460 bgtu $12,$13,atld2 // if (dest > source2) [also kein Carry] ...
461 atld4: bnez $6,atld3 // until (count==0)
466 // extern uintD inc_loop_down (uintD* ptr, uintC count);
468 DECLARE_FUNCTION(inc_loop_down)
469 .ent inc_loop_down // Input in $4,$5, Output in $2
470 ild1: subu $4,4 // ptr--
471 lw $12,($4) // x = *ptr
474 sw $12,($4) // *ptr = x
475 bnez $12,ild3 // if (!(x==0)) ...
477 bnez $5,ild1 // until (count==0)
480 ild3: move $2,$0 // 0
484 // extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
486 DECLARE_FUNCTION(sub_loop_down)
487 .ent sub_loop_down // Input in $4,$5,$6,$7, Output in $2
489 subu $4,4 // sourceptr1--
490 subu $5,4 // sourceptr2--
491 lw $12,($4) // source1 = *sourceptr1
492 lw $13,($5) // source2 = *sourceptr2
493 subu $6,4 // destptr--
494 bltu $12,$13,sld2 // if (source1 < source2) [also Carry] ...
495 subu $12,$13 // dest = source1 - source2
496 sw $12,($6) // *destptr = dest
499 bnez $7,sld1 // until (count==0)
502 sld2: subu $12,$13 // dest = source1 - source2
503 sw $12,($6) // *destptr = dest
505 bnez $7,sld3 // until (count==0)
509 subu $4,4 // sourceptr1--
510 subu $5,4 // sourceptr2--
511 lw $12,($4) // source1 = *sourceptr1
512 lw $13,($5) // source2 = *sourceptr2
513 subu $6,4 // destptr--
514 bgtu $12,$13,sld4 // if (source1 > source2) [also kein Carry] ...
515 subu $12,$13 // dest = source1 - source2
517 sw $12,($6) // *destptr = dest
519 bnez $7,sld3 // until (count==0)
522 sld4: subu $12,$13 // dest = source1 - source2
524 sw $12,($6) // *destptr = dest
526 bnez $7,sld1 // until (count==0)
531 // extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
533 DECLARE_FUNCTION(subx_loop_down)
534 .ent subx_loop_down // Input in $4,$5,$6,$7, Output in $2
536 lw $12,16($sp) // carry
537 bnez $12,sxld5 // !(carry==0) ?
540 subu $4,4 // sourceptr1--
541 subu $5,4 // sourceptr2--
542 lw $12,($4) // source1 = *sourceptr1
543 lw $13,($5) // source2 = *sourceptr2
544 subu $6,4 // destptr--
545 bltu $12,$13,sxld3 // if (source1 < source2) [also Carry] ...
546 subu $12,$13 // dest = source1 - source2
547 sw $12,($6) // *destptr = dest
549 sxld2: bnez $7,sxld1 // until (count==0)
552 sxld3: subu $12,$13 // dest = source1 - source2
553 sw $12,($6) // *destptr = dest
555 bnez $7,sxld4 // until (count==0)
559 subu $4,4 // sourceptr1--
560 subu $5,4 // sourceptr2--
561 lw $12,($4) // source1 = *sourceptr1
562 lw $13,($5) // source2 = *sourceptr2
563 subu $6,4 // destptr--
564 bgtu $12,$13,sxld6 // if (source1 > source2) [also kein Carry] ...
565 subu $12,$13 // dest = source1 - source2
567 sw $12,($6) // *destptr = dest
569 sxld5: bnez $7,sxld4 // until (count==0)
572 sxld6: subu $12,$13 // dest = source1 - source2
574 sw $12,($6) // *destptr = dest
576 bnez $7,sxld1 // until (count==0)
581 // extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
583 DECLARE_FUNCTION(subfrom_loop_down)
584 .ent subfrom_loop_down // Input in $4,$5,$6,$7, Output in $2
586 subu $4,4 // sourceptr--
587 subu $5,4 // destptr--
588 lw $12,($5) // source1 = *destptr
589 lw $13,($4) // source2 = *sourceptr
591 bltu $12,$13,sfld2 // if (source1 < source2) [also Carry] ...
592 subu $12,$13 // dest = source1 - source2
593 sw $12,($5) // *destptr = dest
595 bnez $6,sfld1 // until (count==0)
598 sfld2: subu $12,$13 // dest = source1 - source2
599 sw $12,($5) // *destptr = dest
600 bnez $6,sfld3 // until (count==0)
604 subu $4,4 // sourceptr--
605 subu $5,4 // destptr--
606 lw $12,($5) // source1 = *destptr
607 lw $13,($4) // source2 = *sourceptr
609 bgtu $12,$13,sfld4 // if (source1 > source2) [also kein Carry] ...
610 subu $12,$13 // dest = source1 - source2
612 sw $12,($5) // *destptr = dest
613 bnez $6,sfld3 // until (count==0)
616 sfld4: subu $12,$13 // dest = source1 - source2
618 sw $12,($5) // *destptr = dest
619 bnez $6,sfld1 // until (count==0)
622 .end subfrom_loop_down
624 // extern uintD dec_loop_down (uintD* ptr, uintC count);
626 DECLARE_FUNCTION(dec_loop_down)
627 .ent dec_loop_down // Input in $4,$5, Output in $2
628 dld1: subu $4,4 // ptr--
629 lw $12,($4) // x = *ptr
631 bnez $12,dld3 // if (!(x==0)) ...
633 sw $12,($4) // *ptr = x
635 bnez $5,dld1 // until (count==0)
638 dld3: subu $12,1 // x--;
639 sw $12,($4) // *ptr = x
644 // extern uintD neg_loop_down (uintD* ptr, uintC count);
646 DECLARE_FUNCTION(neg_loop_down)
647 .ent neg_loop_down // Input in $4,$5, Output in $2
648 // erstes Digit /=0 suchen:
649 nld1: subu $4,4 // ptr--
650 lw $12,($4) // x = *ptr
652 bnez $12,nld3 // if (!(x==0)) ...
654 bnez $5,nld1 // until (count==0)
657 nld3: // erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
659 subu $12,$0,$12 // x = -x
660 sw $12,($4) // *ptr = x
661 // alle anderen Digits invertieren:
663 nld4: subu $4,4 // xptr--
664 lw $12,($4) // x = *xptr
667 sw $12,($4) // *xptr = x
668 nld5: bnez $5,nld4 // until (count==0)
675 #if !CL_DS_BIG_ENDIAN_P
677 // extern void or_loop_down (uintD* xptr, uintD* yptr, uintC count);
679 DECLARE_FUNCTION(or_loop_down)
680 .ent or_loop_down // Input in $4,$5,$6
681 old1: subu $4,4 // xptr--
683 lw $12,($4) // x = *xptr
684 lw $13,($5) // y = *yptr
687 sw $12,($4) // *xptr = x
689 bnez $6,old1 // until (count==0)
693 // extern void xor_loop_down (uintD* xptr, uintD* yptr, uintC count);
695 DECLARE_FUNCTION(xor_loop_down)
696 .ent xor_loop_down // Input in $4,$5,$6
697 xld1: subu $4,4 // xptr--
699 lw $12,($4) // x = *xptr
700 lw $13,($5) // y = *yptr
702 xor $12,$13 // x ^= y
703 sw $12,($4) // *xptr = x
705 bnez $6,xld1 // until (count==0)
709 // extern void and_loop_down (uintD* xptr, uintD* yptr, uintC count);
711 DECLARE_FUNCTION(and_loop_down)
712 .ent and_loop_down // Input in $4,$5,$6
713 ald1: subu $4,4 // xptr--
715 lw $12,($4) // x = *xptr
716 lw $13,($5) // y = *yptr
718 and $12,$13 // x &= y
719 sw $12,($4) // *xptr = x
721 bnez $6,ald1 // until (count==0)
725 // extern void eqv_loop_down (uintD* xptr, uintD* yptr, uintC count);
727 DECLARE_FUNCTION(eqv_loop_down)
728 .ent eqv_loop_down // Input in $4,$5,$6
729 nxld1: subu $4,4 // xptr--
731 lw $12,($4) // x = *xptr
732 lw $13,($5) // y = *yptr
734 xor $12,$13 // x ^= y
736 sw $12,($4) // *xptr = x
738 bnez $6,nxld1 // until (count==0)
742 // extern void nand_loop_down (uintD* xptr, uintD* yptr, uintC count);
744 DECLARE_FUNCTION(nand_loop_down)
745 .ent nand_loop_down // Input in $4,$5,$6
746 nald1: subu $4,4 // xptr--
748 lw $12,($4) // x = *xptr
749 lw $13,($5) // y = *yptr
751 and $12,$13 // x &= y // Gibt es 'nand $12,$13' ??
753 sw $12,($4) // *xptr = x
755 bnez $6,nald1 // until (count==0)
759 // extern void nor_loop_down (uintD* xptr, uintD* yptr, uintC count);
761 DECLARE_FUNCTION(nor_loop_down)
762 .ent nor_loop_down // Input in $4,$5,$6
763 nold1: subu $4,4 // xptr--
765 lw $12,($4) // x = *xptr
766 lw $13,($5) // y = *yptr
768 nor $12,$13 // x = ~(x|y)
769 sw $12,($4) // *xptr = x
771 bnez $6,nold1 // until (count==0)
775 // extern void andc2_loop_down (uintD* xptr, uintD* yptr, uintC count);
777 DECLARE_FUNCTION(andc2_loop_down)
778 .ent andc2_loop_down // Input in $4,$5,$6
779 acld1: subu $4,4 // xptr--
781 lw $12,($4) // x = *xptr
782 lw $13,($5) // y = *yptr
785 and $12,$13 // x &= y
786 sw $12,($4) // *xptr = x
788 bnez $6,acld1 // until (count==0)
792 // extern void orc2_loop_down (uintD* xptr, uintD* yptr, uintC count);
794 DECLARE_FUNCTION(orc2_loop_down)
795 .ent orc2_loop_down // Input in $4,$5,$6
796 ocld1: subu $4,4 // xptr--
798 lw $12,($4) // x = *xptr
799 lw $13,($5) // y = *yptr
803 sw $12,($4) // *xptr = x
805 bnez $6,ocld1 // until (count==0)
809 // extern void not_loop_down (uintD* xptr, uintC count);
811 DECLARE_FUNCTION(not_loop_down)
812 .ent not_loop_down // Input in $4,$5
813 nld1: subu $4,4 // xptr--
814 lw $12,($4) // x = *xptr
817 sw $12,($4) // *xptr = x
819 bnez $5,nld1 // until (count==0)
823 // extern boolean and_test_loop_down (uintD* xptr, uintD* yptr, uintC count);
825 DECLARE_FUNCTION(and_test_loop_down)
826 .ent and_test_loop_down // Input in $4,$5,$6
827 atld1: subu $4,4 // xptr--
829 lw $12,($4) // x = *xptr
830 lw $13,($5) // y = *yptr
831 and $12,$13 // x &= y
832 bnez $12,atld3 // if (x) ...
835 bnez $6,atld1 // until (count==0)
840 .end and_test_loop_down
842 // extern cl_signean compare_loop_down (uintD* xptr, uintD* yptr, uintC count);
844 DECLARE_FUNCTION(compare_loop_down)
845 .ent compare_loop_down // Input in $4,$5,$6
846 cmld1: subu $4,4 // xptr--
848 lw $12,($4) // x = *xptr
849 lw $13,($5) // y = *yptr
851 bne $12,$13,cmld3 // if (!(x==y)) ...
853 bnez $6,cmld1 // until (count==0)
856 cmld3: bltu $12,$13,cmld4 // if (x<y) ...
859 cmld4: li $2,-1 // -1
861 .end compare_loop_down
863 // extern uintD add_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
865 DECLARE_FUNCTION(add_loop_up)
866 .ent add_loop_up // Input in $4,$5,$6,$7, Output in $2
868 lw $12,($4) // source1 = *sourceptr1
869 lw $13,($5) // source2 = *sourceptr2
870 addu $4,4 // sourceptr1++
871 addu $5,4 // sourceptr2++
872 addu $12,$13 // dest = source1 + source2
873 sw $12,($6) // *destptr = dest
874 addu $6,4 // destptr++
875 bltu $12,$13,alu4 // if (dest < source2) [also Carry] ...
879 bnez $7,alu1 // until (count==0)
883 lw $12,($4) // source1 = *sourceptr1
884 lw $13,($5) // source2 = *sourceptr2
885 addu $4,4 // sourceptr1++
886 addu $5,4 // sourceptr2++
887 addu $12,$13 // dest = source1 + source2
889 sw $12,($6) // *destptr = dest
890 addu $6,4 // destptr++
891 bgtu $12,$13,alu2 // if (dest > source2) [also kein Carry] ...
892 alu4: subu $7,1 // count--
893 bnez $7,alu3 // until (count==0)
898 // extern uintD addto_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
900 DECLARE_FUNCTION(addto_loop_up)
901 .ent addto_loop_up // Input in $4,$5,$6, Output in $2
903 lw $12,($4) // source1 = *sourceptr
904 lw $13,($5) // source2 = *destptr
905 addu $4,4 // sourceptr++
907 addu $12,$13 // dest = source1 + source2
908 sw $12,($5) // *destptr = dest
909 addu $5,4 // destptr++
910 bltu $12,$13,atlu4 // if (dest < source2) [also Carry] ...
912 atlu2: bnez $6,atlu1 // until (count==0)
916 lw $12,($4) // source1 = *sourceptr
917 lw $13,($5) // source2 = *destptr
918 addu $4,4 // sourceptr++
920 addu $12,$13 // dest = source1 + source2
922 sw $12,($5) // *destptr = dest
923 addu $5,4 // destptr++
924 bgtu $12,$13,atlu2 // if (dest > source2) [also kein Carry] ...
925 atlu4: bnez $6,atlu3 // until (count==0)
930 // extern uintD inc_loop_up (uintD* ptr, uintC count);
932 DECLARE_FUNCTION(inc_loop_up)
933 .ent inc_loop_up // Input in $4,$5, Output in $2
934 ilu1: lw $12,($4) // x = *ptr
937 sw $12,($4) // *ptr = x
939 bnez $12,ilu3 // if (!(x==0)) ...
941 bnez $5,ilu1 // until (count==0)
944 ilu3: move $2,$0 // 0
948 // extern uintD sub_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
950 DECLARE_FUNCTION(sub_loop_up)
951 .ent sub_loop_up // Input in $4,$5,$6,$7, Output in $2
953 lw $12,($4) // source1 = *sourceptr1
954 lw $13,($5) // source2 = *sourceptr2
955 addu $4,4 // sourceptr1++
956 addu $5,4 // sourceptr2++
958 bltu $12,$13,slu2 // if (source1 < source2) [also Carry] ...
959 subu $12,$13 // dest = source1 - source2
960 sw $12,($6) // *destptr = dest
961 addu $6,4 // destptr++
963 bnez $7,slu1 // until (count==0)
966 slu2: subu $12,$13 // dest = source1 - source2
967 sw $12,($6) // *destptr = dest
968 addu $6,4 // destptr++
969 bnez $7,slu3 // until (count==0)
973 lw $12,($4) // source1 = *sourceptr1
974 lw $13,($5) // source2 = *sourceptr2
975 addu $4,4 // sourceptr1++
976 addu $5,4 // sourceptr2++
978 bgtu $12,$13,slu4 // if (source1 > source2) [also kein Carry] ...
979 subu $12,$13 // dest = source1 - source2
981 sw $12,($6) // *destptr = dest
982 addu $6,4 // destptr++
983 bnez $7,slu3 // until (count==0)
986 slu4: subu $12,$13 // dest = source1 - source2
988 sw $12,($6) // *destptr = dest
989 addu $6,4 // destptr++
990 bnez $7,slu1 // until (count==0)
995 // extern uintD subx_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
997 DECLARE_FUNCTION(subx_loop_up)
998 .ent subx_loop_up // Input in $4,$5,$6,$7, Output in $2
1000 lw $12,16($sp) // carry
1001 bnez $12,sxlu5 // !(carry==0) ?
1003 sxlu1: // kein Carry
1004 lw $12,($4) // source1 = *sourceptr1
1005 lw $13,($5) // source2 = *sourceptr2
1006 addu $4,4 // sourceptr1++
1007 addu $5,4 // sourceptr2++
1008 subu $7,1 // count--
1009 bltu $12,$13,sxlu3 // if (source1 < source2) [also Carry] ...
1010 subu $12,$13 // dest = source1 - source2
1011 sw $12,($6) // *destptr = dest
1012 addu $6,4 // destptr++
1013 sxlu2: bnez $7,sxlu1 // until (count==0)
1016 sxlu3: subu $12,$13 // dest = source1 - source2
1017 sw $12,($6) // *destptr = dest
1018 addu $6,4 // destptr++
1019 bnez $7,sxlu4 // until (count==0)
1022 sxlu4: // Hier Carry
1023 lw $12,($4) // source1 = *sourceptr1
1024 lw $13,($5) // source2 = *sourceptr2
1025 addu $4,4 // sourceptr1++
1026 addu $5,4 // sourceptr2++
1027 subu $7,1 // count--
1028 bgtu $12,$13,sxlu6 // if (source1 > source2) [also kein Carry] ...
1029 subu $12,$13 // dest = source1 - source2
1031 sw $12,($6) // *destptr = dest
1032 addu $6,4 // destptr++
1033 sxlu5: bnez $7,sxlu4 // until (count==0)
1036 sxlu6: subu $12,$13 // dest = source1 - source2
1038 sw $12,($6) // *destptr = dest
1039 addu $6,4 // destptr++
1040 bnez $7,sxlu1 // until (count==0)
1045 // extern uintD subfrom_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
1047 DECLARE_FUNCTION(subfrom_loop_up)
1048 .ent subfrom_loop_up // Input in $4,$5,$6,$7, Output in $2
1049 sflu1: // kein Carry
1050 lw $12,($5) // source1 = *destptr
1051 lw $13,($4) // source2 = *sourceptr
1052 addu $4,4 // sourceptr++
1053 subu $6,1 // count--
1054 bltu $12,$13,sflu2 // if (source1 < source2) [also Carry] ...
1055 subu $12,$13 // dest = source1 - source2
1056 sw $12,($5) // *destptr = dest
1057 addu $5,4 // destptr++
1059 bnez $6,sflu1 // until (count==0)
1062 sflu2: subu $12,$13 // dest = source1 - source2
1063 sw $12,($5) // *destptr = dest
1064 addu $5,4 // destptr++
1065 bnez $6,sflu3 // until (count==0)
1068 sflu3: // Hier Carry
1069 lw $12,($5) // source1 = *destptr
1070 lw $13,($4) // source2 = *sourceptr
1071 addu $4,4 // sourceptr++
1072 subu $6,1 // count--
1073 bgtu $12,$13,sflu4 // if (source1 > source2) [also kein Carry] ...
1074 subu $12,$13 // dest = source1 - source2
1076 sw $12,($5) // *destptr = dest
1077 addu $5,4 // destptr++
1078 bnez $6,sflu3 // until (count==0)
1081 sflu4: subu $12,$13 // dest = source1 - source2
1083 sw $12,($5) // *destptr = dest
1084 addu $5,4 // destptr++
1085 bnez $6,sflu1 // until (count==0)
1088 .end subfrom_loop_up
1090 // extern uintD dec_loop_up (uintD* ptr, uintC count);
1092 DECLARE_FUNCTION(dec_loop_up)
1093 .ent dec_loop_up // Input in $4,$5, Output in $2
1094 dlu1: lw $12,($4) // x = *ptr
1095 subu $5,1 // count--
1096 bnez $12,dlu3 // if (!(x==0)) ...
1098 sw $12,($4) // *ptr = x
1101 bnez $5,dlu1 // until (count==0)
1104 dlu3: subu $12,1 // x--;
1105 sw $12,($4) // *ptr = x
1110 // extern uintD neg_loop_up (uintD* ptr, uintC count);
1112 DECLARE_FUNCTION(neg_loop_up)
1113 .ent neg_loop_up // Input in $4,$5, Output in $2
1114 // erstes Digit /=0 suchen:
1115 nlu1: lw $12,($4) // x = *ptr
1116 subu $5,1 // count--
1117 bnez $12,nlu3 // if (!(x==0)) ...
1120 bnez $5,nlu1 // until (count==0)
1123 nlu3: // erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
1124 // 1 Digit negieren:
1125 subu $12,$0,$12 // x = -x
1126 sw $12,($4) // *ptr = x
1127 // alle anderen Digits invertieren:
1129 nlu4: lw $12,($4) // x = *xptr
1130 subu $5,1 // count--
1131 nor $12,$0 // x = ~x
1132 sw $12,($4) // *xptr = x
1133 nlu5: addu $4,4 // xptr++
1134 bnez $5,nlu4 // until (count==0)