1 // Externe Routinen zu ARILEV1.D
3 // Endianness: irrelevant
4 // Compiler: GNU-C oder ...
6 // o32: in Registern $4,$5,$6,$7, und auf dem Stack 16($sp),...
7 // n32: in Registern $4,$5,$6,$7,$8,$9,$10,$11, und auf dem Stack 4($sp),...
8 // Rückgabewert: in Register $2
9 // Einstellungen: intCsize=32, intDsize=32.
10 // Besonderheiten: Nach jedem Ladebefehl ein Wartetakt nötig, bevor der
11 // geholte Wert benutzt werden darf.
13 // Strictly speaking, the MIPS ABI (-32 or -n32) is independent from the CPU
14 // identification (-mips[12] or -mips[34]). But -n32 is commonly used together
15 // with -mips3, and it's easier to test the CPU identification.
22 // When this file is compiled into a shared library, ELF linkers need to
23 // know which symbols are functions.
24 #if defined(__GNU__) || defined(__NetBSD__)
25 #define DECLARE_FUNCTION(name) .type name,@function
27 #define DECLARE_FUNCTION(name)
37 .globl clear_loop_down
41 .globl compare_loop_up
42 #if CL_DS_BIG_ENDIAN_P
51 .globl and_test_loop_up
53 .globl addto_loop_down
57 .globl subfrom_loop_down
67 .globl andc2_loop_down
70 .globl and_test_loop_down
71 .globl compare_loop_down
77 .globl subfrom_loop_up
82 #ifndef __GNUC__ /* mit GNU-C machen wir mulu32() als Macro, der inline multipliziert */
84 // extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
85 // 2^32*hi+lo := arg1*arg2.
88 DECLARE_FUNCTION(mulu32_)
89 .ent mulu32_ // Input in $4,$5, Output in $2,mulu32_high
91 multu $5,$4 // arg1 * arg2
94 sw $6,mulu32_high // hi abspeichern // Adressierung?? Deklaration??
100 // extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
102 DECLARE_FUNCTION(copy_loop_up)
103 .ent copy_loop_up // Input in $4,$5,$6, Output in $2
104 colu1: lw $12,($4) // d = *sourceptr
105 addu $4,4 // sourceptr++
106 sw $12,($5) // *destptr = d
107 addu $5,4 // destptr++
110 bnez $6,colu1 // until (count==0)
111 move $2,$5 // destptr
115 // extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
117 DECLARE_FUNCTION(copy_loop_down)
118 .ent copy_loop_down // Input in $4,$5,$6, Output in $2
119 cold1: subu $4,4 // sourceptr--
120 lw $12,($4) // d = *sourceptr
121 subu $5,4 // destptr--
122 sw $12,($5) // *destptr = d
125 bnez $6,cold1 // until (count==0)
126 move $2,$5 // destptr
130 // extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
132 DECLARE_FUNCTION(fill_loop_up)
133 .ent fill_loop_up // Input in $4,$5,$6, Output in $2
134 flu1: sw $6,($4) // *destptr = filler
135 addu $4,4 // destptr++
138 bnez $5,flu1 // until (count==0)
139 move $2,$4 // destptr
143 // extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
145 DECLARE_FUNCTION(fill_loop_down)
146 .ent fill_loop_down // Input in $4,$5,$6, Output in $2
147 fld1: subu $4,4 // destptr--
148 sw $6,($4) // *destptr = filler
151 bnez $5,fld1 // until (count==0)
152 move $2,$4 // destptr
156 // extern uintD* clear_loop_up (uintD* destptr, uintC count);
158 DECLARE_FUNCTION(clear_loop_up)
159 .ent clear_loop_up // Input in $4,$5, Output in $2
160 cllu1: sw $0,($4) // *destptr = 0
161 addu $4,4 // destptr++
164 bnez $5,cllu1 // until (count==0)
165 move $2,$4 // destptr
169 // extern uintD* clear_loop_down (uintD* destptr, uintC count);
171 DECLARE_FUNCTION(clear_loop_down)
172 .ent clear_loop_down // Input in $4,$5, Output in $2
173 clld1: subu $4,4 // destptr--
174 sw $0,($4) // *destptr = 0
177 bnez $5,clld1 // until (count==0)
178 move $2,$4 // destptr
182 // extern boolean test_loop_up (uintD* ptr, uintC count);
184 DECLARE_FUNCTION(test_loop_up)
185 .ent test_loop_up // Input in $4,$5
186 tlu1: lw $12,($4) // x = *ptr
191 bnez $5,tlu1 // until (count==0)
198 // extern boolean test_loop_down (uintD* ptr, uintC count);
200 DECLARE_FUNCTION(test_loop_down)
201 .ent test_loop_down // Input in $4,$5
202 tld1: subu $4,4 // ptr--
203 lw $12,($4) // x = *ptr
207 bnez $5,tld1 // until (count==0)
214 #if CL_DS_BIG_ENDIAN_P
216 // extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
218 DECLARE_FUNCTION(or_loop_up)
219 .ent or_loop_up // Input in $4,$5,$6
220 olu1: lw $12,($4) // x = *xptr
221 lw $13,($5) // y = *yptr
224 sw $12,($4) // *xptr = x
228 bnez $6,olu1 // until (count==0)
234 // extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
236 DECLARE_FUNCTION(xor_loop_up)
237 .ent xor_loop_up // Input in $4,$5,$6
238 xlu1: lw $12,($4) // x = *xptr
239 lw $13,($5) // y = *yptr
241 xor $12,$13 // x ^= y
242 sw $12,($4) // *xptr = x
246 bnez $6,xlu1 // until (count==0)
250 #if CL_DS_BIG_ENDIAN_P
252 // extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
254 DECLARE_FUNCTION(and_loop_up)
255 .ent and_loop_up // Input in $4,$5,$6
256 alu1: lw $12,($4) // x = *xptr
257 lw $13,($5) // y = *yptr
259 and $12,$13 // x &= y
260 sw $12,($4) // *xptr = x
264 bnez $6,alu1 // until (count==0)
268 // extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
270 DECLARE_FUNCTION(eqv_loop_up)
271 .ent eqv_loop_up // Input in $4,$5,$6
272 nxlu1: lw $12,($4) // x = *xptr
273 lw $13,($5) // y = *yptr
275 xor $12,$13 // x ^= y
277 sw $12,($4) // *xptr = x
281 bnez $6,nxlu1 // until (count==0)
285 // extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
287 DECLARE_FUNCTION(nand_loop_up)
288 .ent nand_loop_up // Input in $4,$5,$6
289 nalu1: lw $12,($4) // x = *xptr
290 lw $13,($5) // y = *yptr
292 and $12,$13 // x &= y // Gibt es 'nand $12,$13' ??
294 sw $12,($4) // *xptr = x
298 bnez $6,nalu1 // until (count==0)
302 // extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
304 DECLARE_FUNCTION(nor_loop_up)
305 .ent nor_loop_up // Input in $4,$5,$6
306 nolu1: lw $12,($4) // x = *xptr
307 lw $13,($5) // y = *yptr
309 nor $12,$13 // x = ~(x|y)
310 sw $12,($4) // *xptr = x
314 bnez $6,nolu1 // until (count==0)
318 // extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
320 DECLARE_FUNCTION(andc2_loop_up)
321 .ent andc2_loop_up // Input in $4,$5,$6
322 aclu1: lw $12,($4) // x = *xptr
323 lw $13,($5) // y = *yptr
326 and $12,$13 // x &= y
327 sw $12,($4) // *xptr = x
331 bnez $6,aclu1 // until (count==0)
335 // extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
337 DECLARE_FUNCTION(orc2_loop_up)
338 .ent orc2_loop_up // Input in $4,$5,$6
339 oclu1: lw $12,($4) // x = *xptr
340 lw $13,($5) // y = *yptr
344 sw $12,($4) // *xptr = x
348 bnez $6,oclu1 // until (count==0)
352 // extern void not_loop_up (uintD* xptr, uintC count);
354 DECLARE_FUNCTION(not_loop_up)
355 .ent not_loop_up // Input in $4,$5
356 nlu1: lw $12,($4) // x = *xptr
359 sw $12,($4) // *xptr = x
362 bnez $5,nlu1 // until (count==0)
366 // extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
368 DECLARE_FUNCTION(and_test_loop_up)
369 .ent and_test_loop_up // Input in $4,$5,$6
370 atlu1: lw $12,($4) // x = *xptr
371 lw $13,($5) // y = *yptr
373 and $12,$13 // x &= y
374 bnez $12,atlu3 // if (x) ...
378 bnez $6,atlu1 // until (count==0)
383 .end and_test_loop_up
387 // extern cl_signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
389 DECLARE_FUNCTION(compare_loop_up)
390 .ent compare_loop_up // Input in $4,$5,$6
391 cmlu1: lw $12,($4) // x = *xptr
392 lw $13,($5) // y = *yptr
394 bne $12,$13,cmlu3 // if (!(x==y)) ...
398 bnez $6,cmlu1 // until (count==0)
401 cmlu3: bltu $12,$13,cmlu4 // if (x<y) ...
404 cmlu4: li $2,-1 // -1
408 #if CL_DS_BIG_ENDIAN_P
410 // extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
412 DECLARE_FUNCTION(add_loop_down)
413 .ent add_loop_down // Input in $4,$5,$6,$7, Output in $2
415 subu $4,4 // sourceptr1--
416 subu $5,4 // sourceptr2--
417 lw $12,($4) // source1 = *sourceptr1
418 lw $13,($5) // source2 = *sourceptr2
419 subu $6,4 // destptr--
420 addu $12,$13 // dest = source1 + source2
421 sw $12,($6) // *destptr = dest
422 bltu $12,$13,ald4 // if (dest < source2) [also Carry] ...
426 bnez $7,ald1 // until (count==0)
430 subu $4,4 // sourceptr1--
431 subu $5,4 // sourceptr2--
432 lw $12,($4) // source1 = *sourceptr1
433 lw $13,($5) // source2 = *sourceptr2
434 subu $6,4 // destptr--
435 addu $12,$13 // dest = source1 + source2
437 sw $12,($6) // *destptr = dest
438 bgtu $12,$13,ald2 // if (dest > source2) [also kein Carry] ...
439 ald4: subu $7,1 // count--
440 bnez $7,ald3 // until (count==0)
445 // extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
447 DECLARE_FUNCTION(addto_loop_down)
448 .ent addto_loop_down // Input in $4,$5,$6, Output in $2
450 subu $4,4 // sourceptr--
451 subu $5,4 // destptr--
452 lw $12,($4) // source1 = *sourceptr
453 lw $13,($5) // source2 = *destptr
455 addu $12,$13 // dest = source1 + source2
456 sw $12,($5) // *destptr = dest
457 bltu $12,$13,atld4 // if (dest < source2) [also Carry] ...
459 atld2: bnez $6,atld1 // until (count==0)
463 subu $4,4 // sourceptr--
464 subu $5,4 // destptr--
465 lw $12,($4) // source1 = *sourceptr
466 lw $13,($5) // source2 = *destptr
468 addu $12,$13 // dest = source1 + source2
470 sw $12,($5) // *destptr = dest
471 bgtu $12,$13,atld2 // if (dest > source2) [also kein Carry] ...
472 atld4: bnez $6,atld3 // until (count==0)
477 // extern uintD inc_loop_down (uintD* ptr, uintC count);
479 DECLARE_FUNCTION(inc_loop_down)
480 .ent inc_loop_down // Input in $4,$5, Output in $2
481 ild1: subu $4,4 // ptr--
482 lw $12,($4) // x = *ptr
485 sw $12,($4) // *ptr = x
486 bnez $12,ild3 // if (!(x==0)) ...
488 bnez $5,ild1 // until (count==0)
491 ild3: move $2,$0 // 0
495 // extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
497 DECLARE_FUNCTION(sub_loop_down)
498 .ent sub_loop_down // Input in $4,$5,$6,$7, Output in $2
500 subu $4,4 // sourceptr1--
501 subu $5,4 // sourceptr2--
502 lw $12,($4) // source1 = *sourceptr1
503 lw $13,($5) // source2 = *sourceptr2
504 subu $6,4 // destptr--
505 bltu $12,$13,sld2 // if (source1 < source2) [also Carry] ...
506 subu $12,$13 // dest = source1 - source2
507 sw $12,($6) // *destptr = dest
510 bnez $7,sld1 // until (count==0)
513 sld2: subu $12,$13 // dest = source1 - source2
514 sw $12,($6) // *destptr = dest
516 bnez $7,sld3 // until (count==0)
520 subu $4,4 // sourceptr1--
521 subu $5,4 // sourceptr2--
522 lw $12,($4) // source1 = *sourceptr1
523 lw $13,($5) // source2 = *sourceptr2
524 subu $6,4 // destptr--
525 bgtu $12,$13,sld4 // if (source1 > source2) [also kein Carry] ...
526 subu $12,$13 // dest = source1 - source2
528 sw $12,($6) // *destptr = dest
530 bnez $7,sld3 // until (count==0)
533 sld4: subu $12,$13 // dest = source1 - source2
535 sw $12,($6) // *destptr = dest
537 bnez $7,sld1 // until (count==0)
542 // extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
544 DECLARE_FUNCTION(subx_loop_down)
545 .ent subx_loop_down // Input in $4,$5,$6,$7,$8 Output in $2
550 lw $12,16($sp) // carry
552 bnez $12,sxld5 // !(carry==0) ?
555 subu $4,4 // sourceptr1--
556 subu $5,4 // sourceptr2--
557 lw $12,($4) // source1 = *sourceptr1
558 lw $13,($5) // source2 = *sourceptr2
559 subu $6,4 // destptr--
560 bltu $12,$13,sxld3 // if (source1 < source2) [also Carry] ...
561 subu $12,$13 // dest = source1 - source2
562 sw $12,($6) // *destptr = dest
564 sxld2: bnez $7,sxld1 // until (count==0)
567 sxld3: subu $12,$13 // dest = source1 - source2
568 sw $12,($6) // *destptr = dest
570 bnez $7,sxld4 // until (count==0)
574 subu $4,4 // sourceptr1--
575 subu $5,4 // sourceptr2--
576 lw $12,($4) // source1 = *sourceptr1
577 lw $13,($5) // source2 = *sourceptr2
578 subu $6,4 // destptr--
579 bgtu $12,$13,sxld6 // if (source1 > source2) [also kein Carry] ...
580 subu $12,$13 // dest = source1 - source2
582 sw $12,($6) // *destptr = dest
584 sxld5: bnez $7,sxld4 // until (count==0)
587 sxld6: subu $12,$13 // dest = source1 - source2
589 sw $12,($6) // *destptr = dest
591 bnez $7,sxld1 // until (count==0)
596 // extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
598 DECLARE_FUNCTION(subfrom_loop_down)
599 .ent subfrom_loop_down // Input in $4,$5,$6,$7, Output in $2
601 subu $4,4 // sourceptr--
602 subu $5,4 // destptr--
603 lw $12,($5) // source1 = *destptr
604 lw $13,($4) // source2 = *sourceptr
606 bltu $12,$13,sfld2 // if (source1 < source2) [also Carry] ...
607 subu $12,$13 // dest = source1 - source2
608 sw $12,($5) // *destptr = dest
610 bnez $6,sfld1 // until (count==0)
613 sfld2: subu $12,$13 // dest = source1 - source2
614 sw $12,($5) // *destptr = dest
615 bnez $6,sfld3 // until (count==0)
619 subu $4,4 // sourceptr--
620 subu $5,4 // destptr--
621 lw $12,($5) // source1 = *destptr
622 lw $13,($4) // source2 = *sourceptr
624 bgtu $12,$13,sfld4 // if (source1 > source2) [also kein Carry] ...
625 subu $12,$13 // dest = source1 - source2
627 sw $12,($5) // *destptr = dest
628 bnez $6,sfld3 // until (count==0)
631 sfld4: subu $12,$13 // dest = source1 - source2
633 sw $12,($5) // *destptr = dest
634 bnez $6,sfld1 // until (count==0)
637 .end subfrom_loop_down
639 // extern uintD dec_loop_down (uintD* ptr, uintC count);
641 DECLARE_FUNCTION(dec_loop_down)
642 .ent dec_loop_down // Input in $4,$5, Output in $2
643 dld1: subu $4,4 // ptr--
644 lw $12,($4) // x = *ptr
646 bnez $12,dld3 // if (!(x==0)) ...
648 sw $12,($4) // *ptr = x
650 bnez $5,dld1 // until (count==0)
653 dld3: subu $12,1 // x--;
654 sw $12,($4) // *ptr = x
659 // extern uintD neg_loop_down (uintD* ptr, uintC count);
661 DECLARE_FUNCTION(neg_loop_down)
662 .ent neg_loop_down // Input in $4,$5, Output in $2
663 // erstes Digit /=0 suchen:
664 nld1: subu $4,4 // ptr--
665 lw $12,($4) // x = *ptr
667 bnez $12,nld3 // if (!(x==0)) ...
669 bnez $5,nld1 // until (count==0)
672 nld3: // erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
674 subu $12,$0,$12 // x = -x
675 sw $12,($4) // *ptr = x
676 // alle anderen Digits invertieren:
678 nld4: subu $4,4 // xptr--
679 lw $12,($4) // x = *xptr
682 sw $12,($4) // *xptr = x
683 nld5: bnez $5,nld4 // until (count==0)
690 #if !CL_DS_BIG_ENDIAN_P
692 // extern void or_loop_down (uintD* xptr, uintD* yptr, uintC count);
694 DECLARE_FUNCTION(or_loop_down)
695 .ent or_loop_down // Input in $4,$5,$6
696 old1: subu $4,4 // xptr--
698 lw $12,($4) // x = *xptr
699 lw $13,($5) // y = *yptr
702 sw $12,($4) // *xptr = x
704 bnez $6,old1 // until (count==0)
708 // extern void xor_loop_down (uintD* xptr, uintD* yptr, uintC count);
710 DECLARE_FUNCTION(xor_loop_down)
711 .ent xor_loop_down // Input in $4,$5,$6
712 xld1: subu $4,4 // xptr--
714 lw $12,($4) // x = *xptr
715 lw $13,($5) // y = *yptr
717 xor $12,$13 // x ^= y
718 sw $12,($4) // *xptr = x
720 bnez $6,xld1 // until (count==0)
724 // extern void and_loop_down (uintD* xptr, uintD* yptr, uintC count);
726 DECLARE_FUNCTION(and_loop_down)
727 .ent and_loop_down // Input in $4,$5,$6
728 ald1: subu $4,4 // xptr--
730 lw $12,($4) // x = *xptr
731 lw $13,($5) // y = *yptr
733 and $12,$13 // x &= y
734 sw $12,($4) // *xptr = x
736 bnez $6,ald1 // until (count==0)
740 // extern void eqv_loop_down (uintD* xptr, uintD* yptr, uintC count);
742 DECLARE_FUNCTION(eqv_loop_down)
743 .ent eqv_loop_down // Input in $4,$5,$6
744 nxld1: subu $4,4 // xptr--
746 lw $12,($4) // x = *xptr
747 lw $13,($5) // y = *yptr
749 xor $12,$13 // x ^= y
751 sw $12,($4) // *xptr = x
753 bnez $6,nxld1 // until (count==0)
757 // extern void nand_loop_down (uintD* xptr, uintD* yptr, uintC count);
759 DECLARE_FUNCTION(nand_loop_down)
760 .ent nand_loop_down // Input in $4,$5,$6
761 nald1: subu $4,4 // xptr--
763 lw $12,($4) // x = *xptr
764 lw $13,($5) // y = *yptr
766 and $12,$13 // x &= y // Gibt es 'nand $12,$13' ??
768 sw $12,($4) // *xptr = x
770 bnez $6,nald1 // until (count==0)
774 // extern void nor_loop_down (uintD* xptr, uintD* yptr, uintC count);
776 DECLARE_FUNCTION(nor_loop_down)
777 .ent nor_loop_down // Input in $4,$5,$6
778 nold1: subu $4,4 // xptr--
780 lw $12,($4) // x = *xptr
781 lw $13,($5) // y = *yptr
783 nor $12,$13 // x = ~(x|y)
784 sw $12,($4) // *xptr = x
786 bnez $6,nold1 // until (count==0)
790 // extern void andc2_loop_down (uintD* xptr, uintD* yptr, uintC count);
792 DECLARE_FUNCTION(andc2_loop_down)
793 .ent andc2_loop_down // Input in $4,$5,$6
794 acld1: subu $4,4 // xptr--
796 lw $12,($4) // x = *xptr
797 lw $13,($5) // y = *yptr
800 and $12,$13 // x &= y
801 sw $12,($4) // *xptr = x
803 bnez $6,acld1 // until (count==0)
807 // extern void orc2_loop_down (uintD* xptr, uintD* yptr, uintC count);
809 DECLARE_FUNCTION(orc2_loop_down)
810 .ent orc2_loop_down // Input in $4,$5,$6
811 ocld1: subu $4,4 // xptr--
813 lw $12,($4) // x = *xptr
814 lw $13,($5) // y = *yptr
818 sw $12,($4) // *xptr = x
820 bnez $6,ocld1 // until (count==0)
824 // extern void not_loop_down (uintD* xptr, uintC count);
826 DECLARE_FUNCTION(not_loop_down)
827 .ent not_loop_down // Input in $4,$5
828 nld1: subu $4,4 // xptr--
829 lw $12,($4) // x = *xptr
832 sw $12,($4) // *xptr = x
834 bnez $5,nld1 // until (count==0)
838 // extern boolean and_test_loop_down (uintD* xptr, uintD* yptr, uintC count);
840 DECLARE_FUNCTION(and_test_loop_down)
841 .ent and_test_loop_down // Input in $4,$5,$6
842 atld1: subu $4,4 // xptr--
844 lw $12,($4) // x = *xptr
845 lw $13,($5) // y = *yptr
846 and $12,$13 // x &= y
847 bnez $12,atld3 // if (x) ...
850 bnez $6,atld1 // until (count==0)
855 .end and_test_loop_down
857 // extern cl_signean compare_loop_down (uintD* xptr, uintD* yptr, uintC count);
859 DECLARE_FUNCTION(compare_loop_down)
860 .ent compare_loop_down // Input in $4,$5,$6
861 cmld1: subu $4,4 // xptr--
863 lw $12,($4) // x = *xptr
864 lw $13,($5) // y = *yptr
866 bne $12,$13,cmld3 // if (!(x==y)) ...
868 bnez $6,cmld1 // until (count==0)
871 cmld3: bltu $12,$13,cmld4 // if (x<y) ...
874 cmld4: li $2,-1 // -1
876 .end compare_loop_down
878 // extern uintD add_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
880 DECLARE_FUNCTION(add_loop_up)
881 .ent add_loop_up // Input in $4,$5,$6,$7, Output in $2
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
888 sw $12,($6) // *destptr = dest
889 addu $6,4 // destptr++
890 bltu $12,$13,alu4 // if (dest < source2) [also Carry] ...
894 bnez $7,alu1 // until (count==0)
898 lw $12,($4) // source1 = *sourceptr1
899 lw $13,($5) // source2 = *sourceptr2
900 addu $4,4 // sourceptr1++
901 addu $5,4 // sourceptr2++
902 addu $12,$13 // dest = source1 + source2
904 sw $12,($6) // *destptr = dest
905 addu $6,4 // destptr++
906 bgtu $12,$13,alu2 // if (dest > source2) [also kein Carry] ...
907 alu4: subu $7,1 // count--
908 bnez $7,alu3 // until (count==0)
913 // extern uintD addto_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
915 DECLARE_FUNCTION(addto_loop_up)
916 .ent addto_loop_up // Input in $4,$5,$6, Output in $2
918 lw $12,($4) // source1 = *sourceptr
919 lw $13,($5) // source2 = *destptr
920 addu $4,4 // sourceptr++
922 addu $12,$13 // dest = source1 + source2
923 sw $12,($5) // *destptr = dest
924 addu $5,4 // destptr++
925 bltu $12,$13,atlu4 // if (dest < source2) [also Carry] ...
927 atlu2: bnez $6,atlu1 // until (count==0)
931 lw $12,($4) // source1 = *sourceptr
932 lw $13,($5) // source2 = *destptr
933 addu $4,4 // sourceptr++
935 addu $12,$13 // dest = source1 + source2
937 sw $12,($5) // *destptr = dest
938 addu $5,4 // destptr++
939 bgtu $12,$13,atlu2 // if (dest > source2) [also kein Carry] ...
940 atlu4: bnez $6,atlu3 // until (count==0)
945 // extern uintD inc_loop_up (uintD* ptr, uintC count);
947 DECLARE_FUNCTION(inc_loop_up)
948 .ent inc_loop_up // Input in $4,$5, Output in $2
949 ilu1: lw $12,($4) // x = *ptr
952 sw $12,($4) // *ptr = x
954 bnez $12,ilu3 // if (!(x==0)) ...
956 bnez $5,ilu1 // until (count==0)
959 ilu3: move $2,$0 // 0
963 // extern uintD sub_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
965 DECLARE_FUNCTION(sub_loop_up)
966 .ent sub_loop_up // Input in $4,$5,$6,$7, Output in $2
968 lw $12,($4) // source1 = *sourceptr1
969 lw $13,($5) // source2 = *sourceptr2
970 addu $4,4 // sourceptr1++
971 addu $5,4 // sourceptr2++
973 bltu $12,$13,slu2 // if (source1 < source2) [also Carry] ...
974 subu $12,$13 // dest = source1 - source2
975 sw $12,($6) // *destptr = dest
976 addu $6,4 // destptr++
978 bnez $7,slu1 // until (count==0)
981 slu2: subu $12,$13 // dest = source1 - source2
982 sw $12,($6) // *destptr = dest
983 addu $6,4 // destptr++
984 bnez $7,slu3 // until (count==0)
988 lw $12,($4) // source1 = *sourceptr1
989 lw $13,($5) // source2 = *sourceptr2
990 addu $4,4 // sourceptr1++
991 addu $5,4 // sourceptr2++
993 bgtu $12,$13,slu4 // if (source1 > source2) [also kein Carry] ...
994 subu $12,$13 // dest = source1 - source2
996 sw $12,($6) // *destptr = dest
997 addu $6,4 // destptr++
998 bnez $7,slu3 // until (count==0)
1001 slu4: subu $12,$13 // dest = source1 - source2
1003 sw $12,($6) // *destptr = dest
1004 addu $6,4 // destptr++
1005 bnez $7,slu1 // until (count==0)
1010 // extern uintD subx_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
1012 DECLARE_FUNCTION(subx_loop_up)
1013 .ent subx_loop_up // Input in $4,$5,$6,$7,$8, Output in $2
1016 move $12,$8 // carry
1018 lw $12,16($sp) // carry
1020 bnez $12,sxlu5 // !(carry==0) ?
1022 sxlu1: // kein 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 bltu $12,$13,sxlu3 // if (source1 < source2) [also Carry] ...
1029 subu $12,$13 // dest = source1 - source2
1030 sw $12,($6) // *destptr = dest
1031 addu $6,4 // destptr++
1032 sxlu2: bnez $7,sxlu1 // until (count==0)
1035 sxlu3: subu $12,$13 // dest = source1 - source2
1036 sw $12,($6) // *destptr = dest
1037 addu $6,4 // destptr++
1038 bnez $7,sxlu4 // until (count==0)
1041 sxlu4: // Hier Carry
1042 lw $12,($4) // source1 = *sourceptr1
1043 lw $13,($5) // source2 = *sourceptr2
1044 addu $4,4 // sourceptr1++
1045 addu $5,4 // sourceptr2++
1046 subu $7,1 // count--
1047 bgtu $12,$13,sxlu6 // if (source1 > source2) [also kein Carry] ...
1048 subu $12,$13 // dest = source1 - source2
1050 sw $12,($6) // *destptr = dest
1051 addu $6,4 // destptr++
1052 sxlu5: bnez $7,sxlu4 // until (count==0)
1055 sxlu6: subu $12,$13 // dest = source1 - source2
1057 sw $12,($6) // *destptr = dest
1058 addu $6,4 // destptr++
1059 bnez $7,sxlu1 // until (count==0)
1064 // extern uintD subfrom_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
1066 DECLARE_FUNCTION(subfrom_loop_up)
1067 .ent subfrom_loop_up // Input in $4,$5,$6,$7, Output in $2
1068 sflu1: // kein Carry
1069 lw $12,($5) // source1 = *destptr
1070 lw $13,($4) // source2 = *sourceptr
1071 addu $4,4 // sourceptr++
1072 subu $6,1 // count--
1073 bltu $12,$13,sflu2 // if (source1 < source2) [also Carry] ...
1074 subu $12,$13 // dest = source1 - source2
1075 sw $12,($5) // *destptr = dest
1076 addu $5,4 // destptr++
1078 bnez $6,sflu1 // until (count==0)
1081 sflu2: subu $12,$13 // dest = source1 - source2
1082 sw $12,($5) // *destptr = dest
1083 addu $5,4 // destptr++
1084 bnez $6,sflu3 // until (count==0)
1087 sflu3: // Hier Carry
1088 lw $12,($5) // source1 = *destptr
1089 lw $13,($4) // source2 = *sourceptr
1090 addu $4,4 // sourceptr++
1091 subu $6,1 // count--
1092 bgtu $12,$13,sflu4 // if (source1 > source2) [also kein Carry] ...
1093 subu $12,$13 // dest = source1 - source2
1095 sw $12,($5) // *destptr = dest
1096 addu $5,4 // destptr++
1097 bnez $6,sflu3 // until (count==0)
1100 sflu4: subu $12,$13 // dest = source1 - source2
1102 sw $12,($5) // *destptr = dest
1103 addu $5,4 // destptr++
1104 bnez $6,sflu1 // until (count==0)
1107 .end subfrom_loop_up
1109 // extern uintD dec_loop_up (uintD* ptr, uintC count);
1111 DECLARE_FUNCTION(dec_loop_up)
1112 .ent dec_loop_up // Input in $4,$5, Output in $2
1113 dlu1: lw $12,($4) // x = *ptr
1114 subu $5,1 // count--
1115 bnez $12,dlu3 // if (!(x==0)) ...
1117 sw $12,($4) // *ptr = x
1120 bnez $5,dlu1 // until (count==0)
1123 dlu3: subu $12,1 // x--;
1124 sw $12,($4) // *ptr = x
1129 // extern uintD neg_loop_up (uintD* ptr, uintC count);
1131 DECLARE_FUNCTION(neg_loop_up)
1132 .ent neg_loop_up // Input in $4,$5, Output in $2
1133 // erstes Digit /=0 suchen:
1134 nlu1: lw $12,($4) // x = *ptr
1135 subu $5,1 // count--
1136 bnez $12,nlu3 // if (!(x==0)) ...
1139 bnez $5,nlu1 // until (count==0)
1142 nlu3: // erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
1143 // 1 Digit negieren:
1144 subu $12,$0,$12 // x = -x
1145 sw $12,($4) // *ptr = x
1146 // alle anderen Digits invertieren:
1148 nlu4: lw $12,($4) // x = *xptr
1149 subu $5,1 // count--
1150 nor $12,$0 // x = ~x
1151 sw $12,($4) // *xptr = x
1152 nlu5: addu $4,4 // xptr++
1153 bnez $5,nlu4 // until (count==0)