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 #if __mips_isa_rev >= 6
92 mulu $2,$5,$4 // arg1 * arg2, lo
93 muhu $6,$5,$4 // arg1 * arg2, hi
95 multu $5,$4 // arg1 * arg2
99 sw $6,mulu32_high // hi abspeichern // Adressierung?? Deklaration??
105 // extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
107 DECLARE_FUNCTION(copy_loop_up)
108 .ent copy_loop_up // Input in $4,$5,$6, Output in $2
109 colu1: lw $12,($4) // d = *sourceptr
110 addu $4,4 // sourceptr++
111 sw $12,($5) // *destptr = d
112 addu $5,4 // destptr++
115 bnez $6,colu1 // until (count==0)
116 move $2,$5 // destptr
120 // extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
122 DECLARE_FUNCTION(copy_loop_down)
123 .ent copy_loop_down // Input in $4,$5,$6, Output in $2
124 cold1: subu $4,4 // sourceptr--
125 lw $12,($4) // d = *sourceptr
126 subu $5,4 // destptr--
127 sw $12,($5) // *destptr = d
130 bnez $6,cold1 // until (count==0)
131 move $2,$5 // destptr
135 // extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
137 DECLARE_FUNCTION(fill_loop_up)
138 .ent fill_loop_up // Input in $4,$5,$6, Output in $2
139 flu1: sw $6,($4) // *destptr = filler
140 addu $4,4 // destptr++
143 bnez $5,flu1 // until (count==0)
144 move $2,$4 // destptr
148 // extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
150 DECLARE_FUNCTION(fill_loop_down)
151 .ent fill_loop_down // Input in $4,$5,$6, Output in $2
152 fld1: subu $4,4 // destptr--
153 sw $6,($4) // *destptr = filler
156 bnez $5,fld1 // until (count==0)
157 move $2,$4 // destptr
161 // extern uintD* clear_loop_up (uintD* destptr, uintC count);
163 DECLARE_FUNCTION(clear_loop_up)
164 .ent clear_loop_up // Input in $4,$5, Output in $2
165 cllu1: sw $0,($4) // *destptr = 0
166 addu $4,4 // destptr++
169 bnez $5,cllu1 // until (count==0)
170 move $2,$4 // destptr
174 // extern uintD* clear_loop_down (uintD* destptr, uintC count);
176 DECLARE_FUNCTION(clear_loop_down)
177 .ent clear_loop_down // Input in $4,$5, Output in $2
178 clld1: subu $4,4 // destptr--
179 sw $0,($4) // *destptr = 0
182 bnez $5,clld1 // until (count==0)
183 move $2,$4 // destptr
187 // extern boolean test_loop_up (uintD* ptr, uintC count);
189 DECLARE_FUNCTION(test_loop_up)
190 .ent test_loop_up // Input in $4,$5
191 tlu1: lw $12,($4) // x = *ptr
196 bnez $5,tlu1 // until (count==0)
203 // extern boolean test_loop_down (uintD* ptr, uintC count);
205 DECLARE_FUNCTION(test_loop_down)
206 .ent test_loop_down // Input in $4,$5
207 tld1: subu $4,4 // ptr--
208 lw $12,($4) // x = *ptr
212 bnez $5,tld1 // until (count==0)
219 #if CL_DS_BIG_ENDIAN_P
221 // extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
223 DECLARE_FUNCTION(or_loop_up)
224 .ent or_loop_up // Input in $4,$5,$6
225 olu1: lw $12,($4) // x = *xptr
226 lw $13,($5) // y = *yptr
229 sw $12,($4) // *xptr = x
233 bnez $6,olu1 // until (count==0)
239 // extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
241 DECLARE_FUNCTION(xor_loop_up)
242 .ent xor_loop_up // Input in $4,$5,$6
243 xlu1: lw $12,($4) // x = *xptr
244 lw $13,($5) // y = *yptr
246 xor $12,$13 // x ^= y
247 sw $12,($4) // *xptr = x
251 bnez $6,xlu1 // until (count==0)
255 #if CL_DS_BIG_ENDIAN_P
257 // extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
259 DECLARE_FUNCTION(and_loop_up)
260 .ent and_loop_up // Input in $4,$5,$6
261 alu1: lw $12,($4) // x = *xptr
262 lw $13,($5) // y = *yptr
264 and $12,$13 // x &= y
265 sw $12,($4) // *xptr = x
269 bnez $6,alu1 // until (count==0)
273 // extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
275 DECLARE_FUNCTION(eqv_loop_up)
276 .ent eqv_loop_up // Input in $4,$5,$6
277 nxlu1: lw $12,($4) // x = *xptr
278 lw $13,($5) // y = *yptr
280 xor $12,$13 // x ^= y
282 sw $12,($4) // *xptr = x
286 bnez $6,nxlu1 // until (count==0)
290 // extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
292 DECLARE_FUNCTION(nand_loop_up)
293 .ent nand_loop_up // Input in $4,$5,$6
294 nalu1: lw $12,($4) // x = *xptr
295 lw $13,($5) // y = *yptr
297 and $12,$13 // x &= y // Gibt es 'nand $12,$13' ??
299 sw $12,($4) // *xptr = x
303 bnez $6,nalu1 // until (count==0)
307 // extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
309 DECLARE_FUNCTION(nor_loop_up)
310 .ent nor_loop_up // Input in $4,$5,$6
311 nolu1: lw $12,($4) // x = *xptr
312 lw $13,($5) // y = *yptr
314 nor $12,$13 // x = ~(x|y)
315 sw $12,($4) // *xptr = x
319 bnez $6,nolu1 // until (count==0)
323 // extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
325 DECLARE_FUNCTION(andc2_loop_up)
326 .ent andc2_loop_up // Input in $4,$5,$6
327 aclu1: lw $12,($4) // x = *xptr
328 lw $13,($5) // y = *yptr
331 and $12,$13 // x &= y
332 sw $12,($4) // *xptr = x
336 bnez $6,aclu1 // until (count==0)
340 // extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
342 DECLARE_FUNCTION(orc2_loop_up)
343 .ent orc2_loop_up // Input in $4,$5,$6
344 oclu1: lw $12,($4) // x = *xptr
345 lw $13,($5) // y = *yptr
349 sw $12,($4) // *xptr = x
353 bnez $6,oclu1 // until (count==0)
357 // extern void not_loop_up (uintD* xptr, uintC count);
359 DECLARE_FUNCTION(not_loop_up)
360 .ent not_loop_up // Input in $4,$5
361 nlu1: lw $12,($4) // x = *xptr
364 sw $12,($4) // *xptr = x
367 bnez $5,nlu1 // until (count==0)
371 // extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
373 DECLARE_FUNCTION(and_test_loop_up)
374 .ent and_test_loop_up // Input in $4,$5,$6
375 atlu1: lw $12,($4) // x = *xptr
376 lw $13,($5) // y = *yptr
378 and $12,$13 // x &= y
379 bnez $12,atlu3 // if (x) ...
383 bnez $6,atlu1 // until (count==0)
388 .end and_test_loop_up
392 // extern cl_signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
394 DECLARE_FUNCTION(compare_loop_up)
395 .ent compare_loop_up // Input in $4,$5,$6
396 cmlu1: lw $12,($4) // x = *xptr
397 lw $13,($5) // y = *yptr
399 bne $12,$13,cmlu3 // if (!(x==y)) ...
403 bnez $6,cmlu1 // until (count==0)
406 cmlu3: bltu $12,$13,cmlu4 // if (x<y) ...
409 cmlu4: li $2,-1 // -1
413 #if CL_DS_BIG_ENDIAN_P
415 // extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
417 DECLARE_FUNCTION(add_loop_down)
418 .ent add_loop_down // Input in $4,$5,$6,$7, Output in $2
420 subu $4,4 // sourceptr1--
421 subu $5,4 // sourceptr2--
422 lw $12,($4) // source1 = *sourceptr1
423 lw $13,($5) // source2 = *sourceptr2
424 subu $6,4 // destptr--
425 addu $12,$13 // dest = source1 + source2
426 sw $12,($6) // *destptr = dest
427 bltu $12,$13,ald4 // if (dest < source2) [also Carry] ...
431 bnez $7,ald1 // until (count==0)
435 subu $4,4 // sourceptr1--
436 subu $5,4 // sourceptr2--
437 lw $12,($4) // source1 = *sourceptr1
438 lw $13,($5) // source2 = *sourceptr2
439 subu $6,4 // destptr--
440 addu $12,$13 // dest = source1 + source2
442 sw $12,($6) // *destptr = dest
443 bgtu $12,$13,ald2 // if (dest > source2) [also kein Carry] ...
444 ald4: subu $7,1 // count--
445 bnez $7,ald3 // until (count==0)
450 // extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
452 DECLARE_FUNCTION(addto_loop_down)
453 .ent addto_loop_down // Input in $4,$5,$6, Output in $2
455 subu $4,4 // sourceptr--
456 subu $5,4 // destptr--
457 lw $12,($4) // source1 = *sourceptr
458 lw $13,($5) // source2 = *destptr
460 addu $12,$13 // dest = source1 + source2
461 sw $12,($5) // *destptr = dest
462 bltu $12,$13,atld4 // if (dest < source2) [also Carry] ...
464 atld2: bnez $6,atld1 // until (count==0)
468 subu $4,4 // sourceptr--
469 subu $5,4 // destptr--
470 lw $12,($4) // source1 = *sourceptr
471 lw $13,($5) // source2 = *destptr
473 addu $12,$13 // dest = source1 + source2
475 sw $12,($5) // *destptr = dest
476 bgtu $12,$13,atld2 // if (dest > source2) [also kein Carry] ...
477 atld4: bnez $6,atld3 // until (count==0)
482 // extern uintD inc_loop_down (uintD* ptr, uintC count);
484 DECLARE_FUNCTION(inc_loop_down)
485 .ent inc_loop_down // Input in $4,$5, Output in $2
486 ild1: subu $4,4 // ptr--
487 lw $12,($4) // x = *ptr
490 sw $12,($4) // *ptr = x
491 bnez $12,ild3 // if (!(x==0)) ...
493 bnez $5,ild1 // until (count==0)
496 ild3: move $2,$0 // 0
500 // extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
502 DECLARE_FUNCTION(sub_loop_down)
503 .ent sub_loop_down // Input in $4,$5,$6,$7, Output in $2
505 subu $4,4 // sourceptr1--
506 subu $5,4 // sourceptr2--
507 lw $12,($4) // source1 = *sourceptr1
508 lw $13,($5) // source2 = *sourceptr2
509 subu $6,4 // destptr--
510 bltu $12,$13,sld2 // if (source1 < source2) [also Carry] ...
511 subu $12,$13 // dest = source1 - source2
512 sw $12,($6) // *destptr = dest
515 bnez $7,sld1 // until (count==0)
518 sld2: subu $12,$13 // dest = source1 - source2
519 sw $12,($6) // *destptr = dest
521 bnez $7,sld3 // until (count==0)
525 subu $4,4 // sourceptr1--
526 subu $5,4 // sourceptr2--
527 lw $12,($4) // source1 = *sourceptr1
528 lw $13,($5) // source2 = *sourceptr2
529 subu $6,4 // destptr--
530 bgtu $12,$13,sld4 // if (source1 > source2) [also kein Carry] ...
531 subu $12,$13 // dest = source1 - source2
533 sw $12,($6) // *destptr = dest
535 bnez $7,sld3 // until (count==0)
538 sld4: subu $12,$13 // dest = source1 - source2
540 sw $12,($6) // *destptr = dest
542 bnez $7,sld1 // until (count==0)
547 // extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
549 DECLARE_FUNCTION(subx_loop_down)
550 .ent subx_loop_down // Input in $4,$5,$6,$7,$8 Output in $2
555 lw $12,16($sp) // carry
557 bnez $12,sxld5 // !(carry==0) ?
560 subu $4,4 // sourceptr1--
561 subu $5,4 // sourceptr2--
562 lw $12,($4) // source1 = *sourceptr1
563 lw $13,($5) // source2 = *sourceptr2
564 subu $6,4 // destptr--
565 bltu $12,$13,sxld3 // if (source1 < source2) [also Carry] ...
566 subu $12,$13 // dest = source1 - source2
567 sw $12,($6) // *destptr = dest
569 sxld2: bnez $7,sxld1 // until (count==0)
572 sxld3: subu $12,$13 // dest = source1 - source2
573 sw $12,($6) // *destptr = dest
575 bnez $7,sxld4 // until (count==0)
579 subu $4,4 // sourceptr1--
580 subu $5,4 // sourceptr2--
581 lw $12,($4) // source1 = *sourceptr1
582 lw $13,($5) // source2 = *sourceptr2
583 subu $6,4 // destptr--
584 bgtu $12,$13,sxld6 // if (source1 > source2) [also kein Carry] ...
585 subu $12,$13 // dest = source1 - source2
587 sw $12,($6) // *destptr = dest
589 sxld5: bnez $7,sxld4 // until (count==0)
592 sxld6: subu $12,$13 // dest = source1 - source2
594 sw $12,($6) // *destptr = dest
596 bnez $7,sxld1 // until (count==0)
601 // extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
603 DECLARE_FUNCTION(subfrom_loop_down)
604 .ent subfrom_loop_down // Input in $4,$5,$6,$7, Output in $2
606 subu $4,4 // sourceptr--
607 subu $5,4 // destptr--
608 lw $12,($5) // source1 = *destptr
609 lw $13,($4) // source2 = *sourceptr
611 bltu $12,$13,sfld2 // if (source1 < source2) [also Carry] ...
612 subu $12,$13 // dest = source1 - source2
613 sw $12,($5) // *destptr = dest
615 bnez $6,sfld1 // until (count==0)
618 sfld2: subu $12,$13 // dest = source1 - source2
619 sw $12,($5) // *destptr = dest
620 bnez $6,sfld3 // until (count==0)
624 subu $4,4 // sourceptr--
625 subu $5,4 // destptr--
626 lw $12,($5) // source1 = *destptr
627 lw $13,($4) // source2 = *sourceptr
629 bgtu $12,$13,sfld4 // if (source1 > source2) [also kein Carry] ...
630 subu $12,$13 // dest = source1 - source2
632 sw $12,($5) // *destptr = dest
633 bnez $6,sfld3 // until (count==0)
636 sfld4: subu $12,$13 // dest = source1 - source2
638 sw $12,($5) // *destptr = dest
639 bnez $6,sfld1 // until (count==0)
642 .end subfrom_loop_down
644 // extern uintD dec_loop_down (uintD* ptr, uintC count);
646 DECLARE_FUNCTION(dec_loop_down)
647 .ent dec_loop_down // Input in $4,$5, Output in $2
648 dld1: subu $4,4 // ptr--
649 lw $12,($4) // x = *ptr
651 bnez $12,dld3 // if (!(x==0)) ...
653 sw $12,($4) // *ptr = x
655 bnez $5,dld1 // until (count==0)
658 dld3: subu $12,1 // x--;
659 sw $12,($4) // *ptr = x
664 // extern uintD neg_loop_down (uintD* ptr, uintC count);
666 DECLARE_FUNCTION(neg_loop_down)
667 .ent neg_loop_down // Input in $4,$5, Output in $2
668 // erstes Digit /=0 suchen:
669 nld1: subu $4,4 // ptr--
670 lw $12,($4) // x = *ptr
672 bnez $12,nld3 // if (!(x==0)) ...
674 bnez $5,nld1 // until (count==0)
677 nld3: // erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
679 subu $12,$0,$12 // x = -x
680 sw $12,($4) // *ptr = x
681 // alle anderen Digits invertieren:
683 nld4: subu $4,4 // xptr--
684 lw $12,($4) // x = *xptr
687 sw $12,($4) // *xptr = x
688 nld5: bnez $5,nld4 // until (count==0)
695 #if !CL_DS_BIG_ENDIAN_P
697 // extern void or_loop_down (uintD* xptr, uintD* yptr, uintC count);
699 DECLARE_FUNCTION(or_loop_down)
700 .ent or_loop_down // Input in $4,$5,$6
701 old1: subu $4,4 // xptr--
703 lw $12,($4) // x = *xptr
704 lw $13,($5) // y = *yptr
707 sw $12,($4) // *xptr = x
709 bnez $6,old1 // until (count==0)
713 // extern void xor_loop_down (uintD* xptr, uintD* yptr, uintC count);
715 DECLARE_FUNCTION(xor_loop_down)
716 .ent xor_loop_down // Input in $4,$5,$6
717 xld1: subu $4,4 // xptr--
719 lw $12,($4) // x = *xptr
720 lw $13,($5) // y = *yptr
722 xor $12,$13 // x ^= y
723 sw $12,($4) // *xptr = x
725 bnez $6,xld1 // until (count==0)
729 // extern void and_loop_down (uintD* xptr, uintD* yptr, uintC count);
731 DECLARE_FUNCTION(and_loop_down)
732 .ent and_loop_down // Input in $4,$5,$6
733 ald1: subu $4,4 // xptr--
735 lw $12,($4) // x = *xptr
736 lw $13,($5) // y = *yptr
738 and $12,$13 // x &= y
739 sw $12,($4) // *xptr = x
741 bnez $6,ald1 // until (count==0)
745 // extern void eqv_loop_down (uintD* xptr, uintD* yptr, uintC count);
747 DECLARE_FUNCTION(eqv_loop_down)
748 .ent eqv_loop_down // Input in $4,$5,$6
749 nxld1: subu $4,4 // xptr--
751 lw $12,($4) // x = *xptr
752 lw $13,($5) // y = *yptr
754 xor $12,$13 // x ^= y
756 sw $12,($4) // *xptr = x
758 bnez $6,nxld1 // until (count==0)
762 // extern void nand_loop_down (uintD* xptr, uintD* yptr, uintC count);
764 DECLARE_FUNCTION(nand_loop_down)
765 .ent nand_loop_down // Input in $4,$5,$6
766 nald1: subu $4,4 // xptr--
768 lw $12,($4) // x = *xptr
769 lw $13,($5) // y = *yptr
771 and $12,$13 // x &= y // Gibt es 'nand $12,$13' ??
773 sw $12,($4) // *xptr = x
775 bnez $6,nald1 // until (count==0)
779 // extern void nor_loop_down (uintD* xptr, uintD* yptr, uintC count);
781 DECLARE_FUNCTION(nor_loop_down)
782 .ent nor_loop_down // Input in $4,$5,$6
783 nold1: subu $4,4 // xptr--
785 lw $12,($4) // x = *xptr
786 lw $13,($5) // y = *yptr
788 nor $12,$13 // x = ~(x|y)
789 sw $12,($4) // *xptr = x
791 bnez $6,nold1 // until (count==0)
795 // extern void andc2_loop_down (uintD* xptr, uintD* yptr, uintC count);
797 DECLARE_FUNCTION(andc2_loop_down)
798 .ent andc2_loop_down // Input in $4,$5,$6
799 acld1: subu $4,4 // xptr--
801 lw $12,($4) // x = *xptr
802 lw $13,($5) // y = *yptr
805 and $12,$13 // x &= y
806 sw $12,($4) // *xptr = x
808 bnez $6,acld1 // until (count==0)
812 // extern void orc2_loop_down (uintD* xptr, uintD* yptr, uintC count);
814 DECLARE_FUNCTION(orc2_loop_down)
815 .ent orc2_loop_down // Input in $4,$5,$6
816 ocld1: subu $4,4 // xptr--
818 lw $12,($4) // x = *xptr
819 lw $13,($5) // y = *yptr
823 sw $12,($4) // *xptr = x
825 bnez $6,ocld1 // until (count==0)
829 // extern void not_loop_down (uintD* xptr, uintC count);
831 DECLARE_FUNCTION(not_loop_down)
832 .ent not_loop_down // Input in $4,$5
833 nld1: subu $4,4 // xptr--
834 lw $12,($4) // x = *xptr
837 sw $12,($4) // *xptr = x
839 bnez $5,nld1 // until (count==0)
843 // extern boolean and_test_loop_down (uintD* xptr, uintD* yptr, uintC count);
845 DECLARE_FUNCTION(and_test_loop_down)
846 .ent and_test_loop_down // Input in $4,$5,$6
847 atld1: subu $4,4 // xptr--
849 lw $12,($4) // x = *xptr
850 lw $13,($5) // y = *yptr
851 and $12,$13 // x &= y
852 bnez $12,atld3 // if (x) ...
855 bnez $6,atld1 // until (count==0)
860 .end and_test_loop_down
862 // extern cl_signean compare_loop_down (uintD* xptr, uintD* yptr, uintC count);
864 DECLARE_FUNCTION(compare_loop_down)
865 .ent compare_loop_down // Input in $4,$5,$6
866 cmld1: subu $4,4 // xptr--
868 lw $12,($4) // x = *xptr
869 lw $13,($5) // y = *yptr
871 bne $12,$13,cmld3 // if (!(x==y)) ...
873 bnez $6,cmld1 // until (count==0)
876 cmld3: bltu $12,$13,cmld4 // if (x<y) ...
879 cmld4: li $2,-1 // -1
881 .end compare_loop_down
883 // extern uintD add_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
885 DECLARE_FUNCTION(add_loop_up)
886 .ent add_loop_up // Input in $4,$5,$6,$7, Output in $2
888 lw $12,($4) // source1 = *sourceptr1
889 lw $13,($5) // source2 = *sourceptr2
890 addu $4,4 // sourceptr1++
891 addu $5,4 // sourceptr2++
892 addu $12,$13 // dest = source1 + source2
893 sw $12,($6) // *destptr = dest
894 addu $6,4 // destptr++
895 bltu $12,$13,alu4 // if (dest < source2) [also Carry] ...
899 bnez $7,alu1 // until (count==0)
903 lw $12,($4) // source1 = *sourceptr1
904 lw $13,($5) // source2 = *sourceptr2
905 addu $4,4 // sourceptr1++
906 addu $5,4 // sourceptr2++
907 addu $12,$13 // dest = source1 + source2
909 sw $12,($6) // *destptr = dest
910 addu $6,4 // destptr++
911 bgtu $12,$13,alu2 // if (dest > source2) [also kein Carry] ...
912 alu4: subu $7,1 // count--
913 bnez $7,alu3 // until (count==0)
918 // extern uintD addto_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
920 DECLARE_FUNCTION(addto_loop_up)
921 .ent addto_loop_up // Input in $4,$5,$6, Output in $2
923 lw $12,($4) // source1 = *sourceptr
924 lw $13,($5) // source2 = *destptr
925 addu $4,4 // sourceptr++
927 addu $12,$13 // dest = source1 + source2
928 sw $12,($5) // *destptr = dest
929 addu $5,4 // destptr++
930 bltu $12,$13,atlu4 // if (dest < source2) [also Carry] ...
932 atlu2: bnez $6,atlu1 // until (count==0)
936 lw $12,($4) // source1 = *sourceptr
937 lw $13,($5) // source2 = *destptr
938 addu $4,4 // sourceptr++
940 addu $12,$13 // dest = source1 + source2
942 sw $12,($5) // *destptr = dest
943 addu $5,4 // destptr++
944 bgtu $12,$13,atlu2 // if (dest > source2) [also kein Carry] ...
945 atlu4: bnez $6,atlu3 // until (count==0)
950 // extern uintD inc_loop_up (uintD* ptr, uintC count);
952 DECLARE_FUNCTION(inc_loop_up)
953 .ent inc_loop_up // Input in $4,$5, Output in $2
954 ilu1: lw $12,($4) // x = *ptr
957 sw $12,($4) // *ptr = x
959 bnez $12,ilu3 // if (!(x==0)) ...
961 bnez $5,ilu1 // until (count==0)
964 ilu3: move $2,$0 // 0
968 // extern uintD sub_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
970 DECLARE_FUNCTION(sub_loop_up)
971 .ent sub_loop_up // Input in $4,$5,$6,$7, Output in $2
973 lw $12,($4) // source1 = *sourceptr1
974 lw $13,($5) // source2 = *sourceptr2
975 addu $4,4 // sourceptr1++
976 addu $5,4 // sourceptr2++
978 bltu $12,$13,slu2 // if (source1 < source2) [also Carry] ...
979 subu $12,$13 // dest = source1 - source2
980 sw $12,($6) // *destptr = dest
981 addu $6,4 // destptr++
983 bnez $7,slu1 // until (count==0)
986 slu2: subu $12,$13 // dest = source1 - source2
987 sw $12,($6) // *destptr = dest
988 addu $6,4 // destptr++
989 bnez $7,slu3 // until (count==0)
993 lw $12,($4) // source1 = *sourceptr1
994 lw $13,($5) // source2 = *sourceptr2
995 addu $4,4 // sourceptr1++
996 addu $5,4 // sourceptr2++
998 bgtu $12,$13,slu4 // if (source1 > source2) [also kein Carry] ...
999 subu $12,$13 // dest = source1 - source2
1001 sw $12,($6) // *destptr = dest
1002 addu $6,4 // destptr++
1003 bnez $7,slu3 // until (count==0)
1006 slu4: subu $12,$13 // dest = source1 - source2
1008 sw $12,($6) // *destptr = dest
1009 addu $6,4 // destptr++
1010 bnez $7,slu1 // until (count==0)
1015 // extern uintD subx_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
1017 DECLARE_FUNCTION(subx_loop_up)
1018 .ent subx_loop_up // Input in $4,$5,$6,$7,$8, Output in $2
1021 move $12,$8 // carry
1023 lw $12,16($sp) // carry
1025 bnez $12,sxlu5 // !(carry==0) ?
1027 sxlu1: // kein Carry
1028 lw $12,($4) // source1 = *sourceptr1
1029 lw $13,($5) // source2 = *sourceptr2
1030 addu $4,4 // sourceptr1++
1031 addu $5,4 // sourceptr2++
1032 subu $7,1 // count--
1033 bltu $12,$13,sxlu3 // if (source1 < source2) [also Carry] ...
1034 subu $12,$13 // dest = source1 - source2
1035 sw $12,($6) // *destptr = dest
1036 addu $6,4 // destptr++
1037 sxlu2: bnez $7,sxlu1 // until (count==0)
1040 sxlu3: subu $12,$13 // dest = source1 - source2
1041 sw $12,($6) // *destptr = dest
1042 addu $6,4 // destptr++
1043 bnez $7,sxlu4 // until (count==0)
1046 sxlu4: // Hier Carry
1047 lw $12,($4) // source1 = *sourceptr1
1048 lw $13,($5) // source2 = *sourceptr2
1049 addu $4,4 // sourceptr1++
1050 addu $5,4 // sourceptr2++
1051 subu $7,1 // count--
1052 bgtu $12,$13,sxlu6 // if (source1 > source2) [also kein Carry] ...
1053 subu $12,$13 // dest = source1 - source2
1055 sw $12,($6) // *destptr = dest
1056 addu $6,4 // destptr++
1057 sxlu5: bnez $7,sxlu4 // until (count==0)
1060 sxlu6: subu $12,$13 // dest = source1 - source2
1062 sw $12,($6) // *destptr = dest
1063 addu $6,4 // destptr++
1064 bnez $7,sxlu1 // until (count==0)
1069 // extern uintD subfrom_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
1071 DECLARE_FUNCTION(subfrom_loop_up)
1072 .ent subfrom_loop_up // Input in $4,$5,$6,$7, Output in $2
1073 sflu1: // kein Carry
1074 lw $12,($5) // source1 = *destptr
1075 lw $13,($4) // source2 = *sourceptr
1076 addu $4,4 // sourceptr++
1077 subu $6,1 // count--
1078 bltu $12,$13,sflu2 // if (source1 < source2) [also Carry] ...
1079 subu $12,$13 // dest = source1 - source2
1080 sw $12,($5) // *destptr = dest
1081 addu $5,4 // destptr++
1083 bnez $6,sflu1 // until (count==0)
1086 sflu2: subu $12,$13 // dest = source1 - source2
1087 sw $12,($5) // *destptr = dest
1088 addu $5,4 // destptr++
1089 bnez $6,sflu3 // until (count==0)
1092 sflu3: // Hier Carry
1093 lw $12,($5) // source1 = *destptr
1094 lw $13,($4) // source2 = *sourceptr
1095 addu $4,4 // sourceptr++
1096 subu $6,1 // count--
1097 bgtu $12,$13,sflu4 // if (source1 > source2) [also kein Carry] ...
1098 subu $12,$13 // dest = source1 - source2
1100 sw $12,($5) // *destptr = dest
1101 addu $5,4 // destptr++
1102 bnez $6,sflu3 // until (count==0)
1105 sflu4: subu $12,$13 // dest = source1 - source2
1107 sw $12,($5) // *destptr = dest
1108 addu $5,4 // destptr++
1109 bnez $6,sflu1 // until (count==0)
1112 .end subfrom_loop_up
1114 // extern uintD dec_loop_up (uintD* ptr, uintC count);
1116 DECLARE_FUNCTION(dec_loop_up)
1117 .ent dec_loop_up // Input in $4,$5, Output in $2
1118 dlu1: lw $12,($4) // x = *ptr
1119 subu $5,1 // count--
1120 bnez $12,dlu3 // if (!(x==0)) ...
1122 sw $12,($4) // *ptr = x
1125 bnez $5,dlu1 // until (count==0)
1128 dlu3: subu $12,1 // x--;
1129 sw $12,($4) // *ptr = x
1134 // extern uintD neg_loop_up (uintD* ptr, uintC count);
1136 DECLARE_FUNCTION(neg_loop_up)
1137 .ent neg_loop_up // Input in $4,$5, Output in $2
1138 // erstes Digit /=0 suchen:
1139 nlu1: lw $12,($4) // x = *ptr
1140 subu $5,1 // count--
1141 bnez $12,nlu3 // if (!(x==0)) ...
1144 bnez $5,nlu1 // until (count==0)
1147 nlu3: // erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
1148 // 1 Digit negieren:
1149 subu $12,$0,$12 // x = -x
1150 sw $12,($4) // *ptr = x
1151 // alle anderen Digits invertieren:
1153 nlu4: lw $12,($4) // x = *xptr
1154 subu $5,1 // count--
1155 nor $12,$0 // x = ~x
1156 sw $12,($4) // *xptr = x
1157 nlu5: addu $4,4 // xptr++
1158 bnez $5,nlu4 // until (count==0)