| 1 | .globl _dmlad |
| 2 | # |
| 3 | # routine for destructive multiplication and additon to a bignum by |
| 4 | # two fixnums. |
| 5 | # |
| 6 | # from C, the invocation is dmlad(sdot,mul,add); |
| 7 | # where sdot is the address of the first special cell of the bignum |
| 8 | # mul is the multiplier, add is the fixnum to be added (The latter |
| 9 | # being passed by value, as is the usual case. |
| 10 | # |
| 11 | # |
| 12 | # Register assignments: |
| 13 | # |
| 14 | # r11 = current sdot |
| 15 | # r10 = carry |
| 16 | # r9 = previous sdot, for relinking. |
| 17 | # |
| 18 | _dmlad: .word 0x0e00 |
| 19 | movl 4(ap),r11 #initialize cell pointer |
| 20 | movl 12(ap),r10 #initialize carry |
| 21 | loop: emul 8(ap),(r11),r10,r0 #r0 gets cell->car times mul + carry |
| 22 | # ediv $0x40000000,r0,r10,(r11)#cell->car gets prod % 2**30 |
| 23 | # #carry gets quotient |
| 24 | extzv $0,$30,r0,(r11) |
| 25 | extv $30,$32,r0,r10 |
| 26 | movl r11,r9 #save last cell for fixup at end. |
| 27 | movl 4(r11),r11 #move to next cell |
| 28 | bneq loop #done indicated by 0 for next sdot |
| 29 | tstl r10 #if carry zero no need to allocate |
| 30 | beql done #new bigit |
| 31 | mcoml r10,r3 #test to see if neg 1. |
| 32 | bneq alloc #if not must allocate new cell. |
| 33 | tstl (r9) #make sure product isn't -2**30 |
| 34 | beql alloc |
| 35 | movl r0,(r9) #save old lower half of product. |
| 36 | brb done |
| 37 | alloc: calls $0,_newsdot #otherwise allocate new bigit |
| 38 | movl r10,(r0) #store carry |
| 39 | movl r0,4(r9) #save new link cell |
| 40 | done: movl 4(ap),r0 |
| 41 | ret |