home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / arimips.d < prev    next >
Encoding:
Text File  |  1994-12-12  |  23.1 KB  |  602 lines

  1. # Externe Routinen zu ARILEV1.D
  2. # Prozessor: MIPS
  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.
  10.  
  11. #ifdef INCLUDED_FROM_C
  12.  
  13.   #define COPY_LOOPS
  14.   #define FILL_LOOPS
  15.   #define CLEAR_LOOPS
  16.   #define LOG_LOOPS
  17.   #define TEST_LOOPS
  18.   #define ADDSUB_LOOPS
  19.  
  20. #else
  21.  
  22.         .text
  23.  
  24.         .globl copy_loop_up
  25.         .globl copy_loop_down
  26.         .globl fill_loop_up
  27.         .globl fill_loop_down
  28.         .globl clear_loop_up
  29.         .globl clear_loop_down
  30.         .globl or_loop_up
  31.         .globl xor_loop_up
  32.         .globl and_loop_up
  33.         .globl eqv_loop_up
  34.         .globl nand_loop_up
  35.         .globl nor_loop_up
  36.         .globl andc2_loop_up
  37.         .globl orc2_loop_up
  38.         .globl not_loop_up
  39.         .globl and_test_loop_up
  40.         .globl test_loop_up
  41.         .globl compare_loop_up
  42.         .globl add_loop_down
  43.         .globl addto_loop_down
  44.         .globl inc_loop_down
  45.         .globl sub_loop_down
  46.         .globl subx_loop_down
  47.         .globl subfrom_loop_down
  48.         .globl dec_loop_down
  49.         .globl neg_loop_down
  50.  
  51. #ifndef __GNUC__ /* mit GNU-C machen wir mulu32() als Macro, der inline multipliziert */
  52.  
  53. # extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
  54. # 2^32*hi+lo := arg1*arg2.
  55.         .globl mulu32_
  56.         .align 2
  57.         .ent mulu32_ # Input in $4,$5, Output in $2,mulu32_high
  58. mulu32_:
  59.         multu $5,$4             # arg1 * arg2
  60.         mfhi $6                 # hi
  61.         mflo $2                 # lo
  62.         sw $6,mulu32_high       # hi abspeichern # Adressierung?? Deklaration??
  63.         j $31                   # return
  64.         .end mulu32_
  65.  
  66. #endif
  67.  
  68. # extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
  69.         .align 2
  70.         .ent copy_loop_up # Input in $4,$5,$6, Output in $2
  71. colu1:    lw $12,($4)           # d = *sourceptr
  72.           addu $4,4             # sourceptr++
  73.           sw $12,($5)           # *destptr = d
  74.           addu $5,4             # destptr++
  75.           subu $6,1             # count--
  76. copy_loop_up:
  77.           bnez $6,colu1         # until (count==0)
  78.         move $2,$5              # destptr
  79.         j $31                   # return
  80.         .end copy_loop_up
  81.  
  82. # extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  83.         .align 2
  84.         .ent copy_loop_down # Input in $4,$5,$6, Output in $2
  85. cold1:    subu $4,4             # sourceptr--
  86.           lw $12,($4)           # d = *sourceptr
  87.           subu $5,4             # destptr--
  88.           sw $12,($5)           # *destptr = d
  89.           subu $6,1             # count--
  90. copy_loop_down:
  91.           bnez $6,cold1         # until (count==0)
  92.         move $2,$5              # destptr
  93.         j $31                   # return
  94.         .end copy_loop_down
  95.  
  96. # extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
  97.         .align 2
  98.         .ent fill_loop_up # Input in $4,$5,$6, Output in $2
  99. flu1:     sw $6,($4)            # *destptr = filler
  100.           addu $4,4             # destptr++
  101.           subu $5,1             # count--
  102. fill_loop_up:
  103.           bnez $5,flu1          # until (count==0)
  104.         move $2,$4              # destptr
  105.         j $31                   # return
  106.         .end fill_loop_up
  107.  
  108. # extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
  109.         .align 2
  110.         .ent fill_loop_down # Input in $4,$5,$6, Output in $2
  111. fld1:     subu $4,4             # destptr--
  112.           sw $6,($4)            # *destptr = filler
  113.           subu $5,1             # count--
  114. fill_loop_down:
  115.           bnez $5,fld1          # until (count==0)
  116.         move $2,$4              # destptr
  117.         j $31                   # return
  118.         .end fill_loop_down
  119.  
  120. # extern uintD* clear_loop_up (uintD* destptr, uintC count);
  121.         .align 2
  122.         .ent clear_loop_up # Input in $4,$5, Output in $2
  123. cllu1:    sw $0,($4)            # *destptr = 0
  124.           addu $4,4             # destptr++
  125.           subu $5,1             # count--
  126. clear_loop_up:
  127.           bnez $5,cllu1         # until (count==0)
  128.         move $2,$4              # destptr
  129.         j $31                   # return
  130.         .end clear_loop_up
  131.  
  132. # extern uintD* clear_loop_down (uintD* destptr, uintC count);
  133.         .align 2
  134.         .ent clear_loop_down # Input in $4,$5, Output in $2
  135. clld1:    subu $4,4             # destptr--
  136.           sw $0,($4)            # *destptr = 0
  137.           subu $5,1             # count--
  138. clear_loop_down:
  139.           bnez $5,clld1         # until (count==0)
  140.         move $2,$4              # destptr
  141.         j $31                   # return
  142.         .end clear_loop_down
  143.  
  144. # extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
  145.         .align 2
  146.         .ent or_loop_up # Input in $4,$5,$6
  147. olu1:     lw $12,($4)           # x = *xptr
  148.           lw $13,($5)           # y = *yptr
  149.           addu $5,4             # yptr++
  150.           or $12,$13            # x |= y
  151.           sw $12,($4)           # *xptr = x
  152.           addu $4,4             # xptr++
  153.           subu $6,1             # count--
  154. or_loop_up:
  155.           bnez $6,olu1          # until (count==0)
  156.         j $31                   # return
  157.         .end or_loop_up
  158.  
  159. # extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  160.         .align 2
  161.         .ent xor_loop_up # Input in $4,$5,$6
  162. xlu1:     lw $12,($4)           # x = *xptr
  163.           lw $13,($5)           # y = *yptr
  164.           addu $5,4             # yptr++
  165.           xor $12,$13           # x ^= y
  166.           sw $12,($4)           # *xptr = x
  167.           addu $4,4             # xptr++
  168.           subu $6,1             # count--
  169. xor_loop_up:
  170.           bnez $6,xlu1          # until (count==0)
  171.         j $31                   # return
  172.         .end xor_loop_up
  173.  
  174. # extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
  175.         .align 2
  176.         .ent and_loop_up # Input in $4,$5,$6
  177. alu1:     lw $12,($4)           # x = *xptr
  178.           lw $13,($5)           # y = *yptr
  179.           addu $5,4             # yptr++
  180.           and $12,$13           # x &= y
  181.           sw $12,($4)           # *xptr = x
  182.           addu $4,4             # xptr++
  183.           subu $6,1             # count--
  184. and_loop_up:
  185.           bnez $6,alu1          # until (count==0)
  186.         j $31                   # return
  187.         .end and_loop_up
  188.  
  189. # extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
  190.         .align 2
  191.         .ent eqv_loop_up # Input in $4,$5,$6
  192. nxlu1:    lw $12,($4)           # x = *xptr
  193.           lw $13,($5)           # y = *yptr
  194.           addu $5,4             # yptr++
  195.           xor $12,$13           # x ^= y
  196.           nor $12,$0            # x = ~x
  197.           sw $12,($4)           # *xptr = x
  198.           addu $4,4             # xptr++
  199.           subu $6,1             # count--
  200. eqv_loop_up:
  201.           bnez $6,nxlu1         # until (count==0)
  202.         j $31                   # return
  203.         .end eqv_loop_up
  204.  
  205. # extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
  206.         .align 2
  207.         .ent nand_loop_up # Input in $4,$5,$6
  208. nalu1:    lw $12,($4)           # x = *xptr
  209.           lw $13,($5)           # y = *yptr
  210.           addu $5,4             # yptr++
  211.           and $12,$13           # x &= y        # Gibt es 'nand $12,$13' ??
  212.           nor $12,$0            # x = ~x
  213.           sw $12,($4)           # *xptr = x
  214.           addu $4,4             # xptr++
  215.           subu $6,1             # count--
  216. nand_loop_up:
  217.           bnez $6,nalu1         # until (count==0)
  218.         j $31                   # return
  219.         .end nand_loop_up
  220.  
  221. # extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  222.         .align 2
  223.         .ent nor_loop_up # Input in $4,$5,$6
  224. nolu1:    lw $12,($4)           # x = *xptr
  225.           lw $13,($5)           # y = *yptr
  226.           addu $5,4             # yptr++
  227.           nor $12,$13           # x = ~(x|y)
  228.           sw $12,($4)           # *xptr = x
  229.           addu $4,4             # xptr++
  230.           subu $6,1             # count--
  231. nor_loop_up:
  232.           bnez $6,nolu1         # until (count==0)
  233.         j $31                   # return
  234.         .end nor_loop_up
  235.  
  236. # extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  237.         .align 2
  238.         .ent andc2_loop_up # Input in $4,$5,$6
  239. aclu1:    lw $12,($4)           # x = *xptr
  240.           lw $13,($5)           # y = *yptr
  241.           addu $5,4             # yptr++
  242.           nor $13,$0            # y = ~y
  243.           and $12,$13           # x &= y
  244.           sw $12,($4)           # *xptr = x
  245.           addu $4,4             # xptr++
  246.           subu $6,1             # count--
  247. andc2_loop_up:
  248.           bnez $6,aclu1         # until (count==0)
  249.         j $31                   # return
  250.         .end andc2_loop_up
  251.  
  252. # extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  253.         .align 2
  254.         .ent orc2_loop_up # Input in $4,$5,$6
  255. oclu1:    lw $12,($4)           # x = *xptr
  256.           lw $13,($5)           # y = *yptr
  257.           addu $5,4             # yptr++
  258.           nor $13,$0            # y = ~y
  259.           or $12,$13            # x |= y
  260.           sw $12,($4)           # *xptr = x
  261.           addu $4,4             # xptr++
  262.           subu $6,1             # count--
  263. orc2_loop_up:
  264.           bnez $6,oclu1         # until (count==0)
  265.         j $31                   # return
  266.         .end orc2_loop_up
  267.  
  268. # extern void not_loop_up (uintD* xptr, uintC count);
  269.         .align 2
  270.         .ent not_loop_up # Input in $4,$5
  271. nlu1:     lw $12,($4)           # x = *xptr
  272.           subu $5,1             # count--
  273.           nor $12,$0            # x = ~x
  274.           sw $12,($4)           # *xptr = x
  275.           addu $4,4             # xptr++
  276. not_loop_up:
  277.           bnez $5,nlu1          # until (count==0)
  278.         j $31                   # return
  279.         .end not_loop_up
  280.  
  281. # extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
  282.         .align 2
  283.         .ent and_test_loop_up # Input in $4,$5,$6
  284. atlu1:    lw $12,($4)           # x = *xptr
  285.           lw $13,($5)           # y = *yptr
  286.           addu $5,4             # yptr++
  287.           and $12,$13           # x &= y
  288.           bnez $12,atlu3        # if (x) ...
  289.           addu $4,4             # xptr++
  290.           subu $6,1             # count--
  291. and_test_loop_up:
  292.           bnez $6,atlu1         # until (count==0)
  293.         move $2,$0              # 0
  294.         j $31                   # return
  295. atlu3:  li $2,1                 # 1
  296.         j $31                   # return
  297.         .end and_test_loop_up
  298.  
  299. # extern boolean test_loop_up (uintD* ptr, uintC count);
  300.         .align 2
  301.         .ent test_loop_up # Input in $4,$5
  302. tlu1:     lw $12,($4)           # x = *ptr
  303.           addu $4,4             # ptr++
  304.           bnez $12,tlu3
  305.           subu $5,1             # count--
  306. test_loop_up:
  307.           bnez $5,tlu1          # until (count==0)
  308.         move $2,$0              # 0
  309.         j $31                   # return
  310. tlu3:   li $2,1                 # 1
  311.         j $31                   # return
  312.         .end test_loop_up
  313.  
  314. # extern signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
  315.         .align 2
  316.         .ent compare_loop_up # Input in $4,$5,$6
  317. cmlu1:    lw $12,($4)           # x = *xptr
  318.           lw $13,($5)           # y = *yptr
  319.           addu $5,4             # yptr++
  320.           bne $12,$13,cmlu3     # if (!(x==y)) ...
  321.           addu $4,4             # xptr++
  322.           subu $6,1             # count--
  323. compare_loop_up:
  324.           bnez $6,cmlu1         # until (count==0)
  325.         move $2,$0              # 0
  326.         j $31                   # return
  327. cmlu3:  bltu $12,$13,cmlu4      # if (x<y) ...
  328.         li $2,1                 # 1
  329.         j $31                   # return
  330. cmlu4:  li $2,-1                # -1
  331.         j $31                   # return
  332.         .end compare_loop_up
  333.  
  334. # extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  335.         .align 2
  336.         .ent add_loop_down # Input in $4,$5,$6,$7, Output in $2
  337. ald1:     # kein Carry
  338.           subu $4,4             # sourceptr1--
  339.           subu $5,4             # sourceptr2--
  340.           lw $12,($4)           # source1 = *sourceptr1
  341.           lw $13,($5)           # source2 = *sourceptr2
  342.           subu $6,4             # destptr--
  343.           addu $12,$13          # dest = source1 + source2
  344.           sw $12,($6)           # *destptr = dest
  345.           bltu $12,$13,ald4     # if (dest < source2) [also Carry] ...
  346. ald2:
  347.           subu $7,1             # count--
  348. add_loop_down:
  349.           bnez $7,ald1          # until (count==0)
  350.         move $2,$0              # 0
  351.         j $31                   # return
  352. ald3:   # Hier Carry
  353.           subu $4,4             # sourceptr1--
  354.           subu $5,4             # sourceptr2--
  355.           lw $12,($4)           # source1 = *sourceptr1
  356.           lw $13,($5)           # source2 = *sourceptr2
  357.           subu $6,4             # destptr--
  358.           addu $12,$13          # dest = source1 + source2
  359.           addu $12,1            #        + 1
  360.           sw $12,($6)           # *destptr = dest
  361.           bgtu $12,$13,ald2     # if (dest > source2) [also kein Carry] ...
  362. ald4:     subu $7,1             # count--
  363.           bnez $7,ald3          # until (count==0)
  364.         li $2,1                 # 1
  365.         j $31                   # return
  366.         .end add_loop_down
  367.  
  368. # extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  369.         .align 2
  370.         .ent addto_loop_down # Input in $4,$5,$6, Output in $2
  371. atld1:    # kein Carry
  372.           subu $4,4             # sourceptr--
  373.           subu $5,4             # destptr--
  374.           lw $12,($4)           # source1 = *sourceptr
  375.           lw $13,($5)           # source2 = *destptr
  376.           subu $6,1             # count--
  377.           addu $12,$13          # dest = source1 + source2
  378.           sw $12,($5)           # *destptr = dest
  379.           bltu $12,$13,atld4    # if (dest < source2) [also Carry] ...
  380. addto_loop_down:
  381. atld2:    bnez $6,atld1         # until (count==0)
  382.         move $2,$0              # 0
  383.         j $31                   # return
  384. atld3:  # Hier Carry
  385.           subu $4,4             # sourceptr--
  386.           subu $5,4             # destptr--
  387.           lw $12,($4)           # source1 = *sourceptr
  388.           lw $13,($5)           # source2 = *destptr
  389.           subu $6,1             # count--
  390.           addu $12,$13          # dest = source1 + source2
  391.           addu $12,1            #        + 1
  392.           sw $12,($5)           # *destptr = dest
  393.           bgtu $12,$13,atld2    # if (dest > source2) [also kein Carry] ...
  394. atld4:    bnez $6,atld3         # until (count==0)
  395.         li $2,1                 # 1
  396.         j $31                   # return
  397.         .end addto_loop_down
  398.  
  399. # extern uintD inc_loop_down (uintD* ptr, uintC count);
  400.         .align 2
  401.         .ent inc_loop_down # Input in $4,$5, Output in $2
  402. ild1:     subu $4,4             # ptr--
  403.           lw $12,($4)           # x = *ptr
  404.           subu $5,1             # count--
  405.           addu $12,1            # x++;
  406.           sw $12,($4)           # *ptr = x
  407.           bnez $12,ild3         # if (!(x==0)) ...
  408. inc_loop_down:
  409.           bnez $5,ild1          # until (count==0)
  410.         li $2,1                 # 1
  411.         j $31                   # return
  412. ild3:   move $2,$0              # 0
  413.         j $31                   # return
  414.         .end inc_loop_down
  415.  
  416. # extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  417.         .align 2
  418.         .ent sub_loop_down # Input in $4,$5,$6,$7, Output in $2
  419. sld1:     # kein Carry
  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.           bltu $12,$13,sld2     # if (source1 < source2) [also Carry] ...
  426.           subu $12,$13          # dest = source1 - source2
  427.           sw $12,($6)           # *destptr = dest
  428.           subu $7,1             # count--
  429. sub_loop_down:
  430.           bnez $7,sld1          # until (count==0)
  431.         move $2,$0              # 0
  432.         j $31                   # return
  433. sld2:     subu $12,$13          # dest = source1 - source2
  434.           sw $12,($6)           # *destptr = dest
  435.           subu $7,1             # count--
  436.           bnez $7,sld3          # until (count==0)
  437.         li $2,-1                # -1
  438.         j $31                   # return
  439. sld3:   # Hier Carry
  440.           subu $4,4             # sourceptr1--
  441.           subu $5,4             # sourceptr2--
  442.           lw $12,($4)           # source1 = *sourceptr1
  443.           lw $13,($5)           # source2 = *sourceptr2
  444.           subu $6,4             # destptr--
  445.           bgtu $12,$13,sld4     # if (source1 > source2) [also kein Carry] ...
  446.           subu $12,$13          # dest = source1 - source2
  447.           subu $12,1            #        - 1
  448.           sw $12,($6)           # *destptr = dest
  449.           subu $7,1             # count--
  450.           bnez $7,sld3          # until (count==0)
  451.         li $2,-1                # -1
  452.         j $31                   # return
  453. sld4:     subu $12,$13          # dest = source1 - source2
  454.           subu $12,1            #        - 1
  455.           sw $12,($6)           # *destptr = dest
  456.           subu $7,1             # count--
  457.           bnez $7,sld1          # until (count==0)
  458.         move $2,$0              # 0
  459.         j $31                   # return
  460.         .end sub_loop_down
  461.  
  462. # extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
  463.         .align 2
  464.         .ent subx_loop_down # Input in $4,$5,$6,$7, Output in $2
  465. subx_loop_down:
  466.         lw $12,16($sp)          # carry
  467.         bnez $12,sxld5          # !(carry==0) ?
  468.         b sxld2
  469. sxld1:    # kein Carry
  470.           subu $4,4             # sourceptr1--
  471.           subu $5,4             # sourceptr2--
  472.           lw $12,($4)           # source1 = *sourceptr1
  473.           lw $13,($5)           # source2 = *sourceptr2
  474.           subu $6,4             # destptr--
  475.           bltu $12,$13,sxld3    # if (source1 < source2) [also Carry] ...
  476.           subu $12,$13          # dest = source1 - source2
  477.           sw $12,($6)           # *destptr = dest
  478.           subu $7,1             # count--
  479. sxld2:    bnez $7,sxld1         # until (count==0)
  480.         move $2,$0              # 0
  481.         j $31                   # return
  482. sxld3:    subu $12,$13          # dest = source1 - source2
  483.           sw $12,($6)           # *destptr = dest
  484.           subu $7,1             # count--
  485.           bnez $7,sxld4         # until (count==0)
  486.         li $2,-1                # -1
  487.         j $31                   # return
  488. sxld4:  # Hier Carry
  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.           bgtu $12,$13,sxld6    # if (source1 > source2) [also kein Carry] ...
  495.           subu $12,$13          # dest = source1 - source2
  496.           subu $12,1            #        - 1
  497.           sw $12,($6)           # *destptr = dest
  498.           subu $7,1             # count--
  499. sxld5:    bnez $7,sxld4         # until (count==0)
  500.         li $2,-1                # -1
  501.         j $31                   # return
  502. sxld6:    subu $12,$13          # dest = source1 - source2
  503.           subu $12,1            #        - 1
  504.           sw $12,($6)           # *destptr = dest
  505.           subu $7,1             # count--
  506.           bnez $7,sxld1         # until (count==0)
  507.         move $2,$0              # 0
  508.         j $31                   # return
  509.         .end subx_loop_down
  510.  
  511. # extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  512.         .align 2
  513.         .ent subfrom_loop_down # Input in $4,$5,$6,$7, Output in $2
  514. sfld1:    # kein Carry
  515.           subu $4,4             # sourceptr--
  516.           subu $5,4             # destptr--
  517.           lw $12,($5)           # source1 = *destptr
  518.           lw $13,($4)           # source2 = *sourceptr
  519.           subu $6,1             # count--
  520.           bltu $12,$13,sfld2    # if (source1 < source2) [also Carry] ...
  521.           subu $12,$13          # dest = source1 - source2
  522.           sw $12,($5)           # *destptr = dest
  523. subfrom_loop_down:
  524.           bnez $6,sfld1         # until (count==0)
  525.         move $2,$0              # 0
  526.         j $31                   # return
  527. sfld2:    subu $12,$13          # dest = source1 - source2
  528.           sw $12,($5)           # *destptr = dest
  529.           bnez $6,sfld3         # until (count==0)
  530.         li $2,-1                # -1
  531.         j $31                   # return
  532. sfld3:  # Hier Carry
  533.           subu $4,4             # sourceptr--
  534.           subu $5,4             # destptr--
  535.           lw $12,($5)           # source1 = *destptr
  536.           lw $13,($4)           # source2 = *sourceptr
  537.           subu $6,1             # count--
  538.           bgtu $12,$13,sfld4    # if (source1 > source2) [also kein Carry] ...
  539.           subu $12,$13          # dest = source1 - source2
  540.           subu $12,1            #        - 1
  541.           sw $12,($5)           # *destptr = dest
  542.           bnez $6,sfld3         # until (count==0)
  543.         li $2,-1                # -1
  544.         j $31                   # return
  545. sfld4:    subu $12,$13          # dest = source1 - source2
  546.           subu $12,1            #        - 1
  547.           sw $12,($5)           # *destptr = dest
  548.           bnez $6,sfld1         # until (count==0)
  549.         move $2,$0              # 0
  550.         j $31                   # return
  551.         .end subfrom_loop_down
  552.  
  553. # extern uintD dec_loop_down (uintD* ptr, uintC count);
  554.         .align 2
  555.         .ent dec_loop_down # Input in $4,$5, Output in $2
  556. dld1:     subu $4,4             # ptr--
  557.           lw $12,($4)           # x = *ptr
  558.           subu $5,1             # count--
  559.           bnez $12,dld3         # if (!(x==0)) ...
  560.           subu $12,1            # x--;
  561.           sw $12,($4)           # *ptr = x
  562. dec_loop_down:
  563.           bnez $5,dld1          # until (count==0)
  564.         li $2,-1                # -1
  565.         j $31                   # return
  566. dld3:   subu $12,1              # x--;
  567.         sw $12,($4)             # *ptr = x
  568.         move $2,$0              # 0
  569.         j $31                   # return
  570.         .end dec_loop_down
  571.  
  572. # extern uintD neg_loop_down (uintD* ptr, uintC count);
  573.         .align 2
  574.         .ent neg_loop_down # Input in $4,$5, Output in $2
  575.         # erstes Digit /=0 suchen:
  576. nld1:     subu $4,4             # ptr--
  577.           lw $12,($4)           # x = *ptr
  578.           subu $5,1             # count--
  579.           bnez $12,nld3         # if (!(x==0)) ...
  580. neg_loop_down:
  581.           bnez $5,nld1          # until (count==0)
  582.         move $2,$0              # 0
  583.         j $31                   # return
  584. nld3:   # erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
  585.         # 1 Digit negieren:
  586.         subu $12,$0,$12         # x = -x
  587.         sw $12,($4)             # *ptr = x
  588.         # alle anderen Digits invertieren:
  589.         b nld5
  590. nld4:     subu $4,4             # xptr--
  591.           lw $12,($4)           # x = *xptr
  592.           subu $5,1             # count--
  593.           nor $12,$0            # x = ~x
  594.           sw $12,($4)           # *xptr = x
  595. nld5:     bnez $5,nld4          # until (count==0)
  596.         li $2,-1                # -1
  597.         j $31                   # return
  598.         .end neg_loop_down
  599.  
  600. #endif
  601.  
  602.