106 lines
1.8 KiB
Plaintext
106 lines
1.8 KiB
Plaintext
|
|
// multiply.dsa
|
|
// usage:
|
|
//
|
|
// include multiply "<relative path>"
|
|
//
|
|
// usage for multiply:
|
|
// push (arg1)
|
|
// push (arg0)
|
|
// call multiply::multiply
|
|
// pop (arg0)
|
|
// pop (arg1)
|
|
|
|
multiply:
|
|
push bpr
|
|
mov spr, bpr
|
|
|
|
ldw bpr, rg0, 8 // load op 2
|
|
ldw bpr, rg1, 12 // load op 1
|
|
lwi 0, rg2 // initialise rg2 to zero
|
|
|
|
_multiply_loop:
|
|
add rg2, rg0, rg2
|
|
dec rg1
|
|
|
|
cmp rg1, zero
|
|
jgt _multiply_loop
|
|
|
|
_multiply_end:
|
|
stw rg2, bpr, 8
|
|
|
|
mov bpr, spr
|
|
pop bpr
|
|
return
|
|
|
|
divmod:
|
|
push bpr
|
|
mov spr, bpr
|
|
|
|
ldw bpr, rg1, 8 // load op 2
|
|
ldw bpr, rg0, 12 // load op 1
|
|
|
|
lli 0, rg3
|
|
|
|
_divmod_loop:
|
|
cmp rg0, rg1
|
|
jlt _divmod_end
|
|
|
|
sub rg0, rg1, rg0
|
|
inc rg3
|
|
|
|
jmp _divmod_loop
|
|
|
|
_divmod_end:
|
|
// store div in first arg
|
|
// store mod in second arg
|
|
stw rg3, bpr, 8
|
|
stw rg0, bpr, 12
|
|
|
|
mov bpr, spr
|
|
pop bpr
|
|
return
|
|
|
|
// multiply.dsa - improved version
|
|
// Multiplies two 32-bit numbers using shift-and-add
|
|
//
|
|
// Usage:
|
|
// push operand2 (multiplier)
|
|
// push operand1 (multiplicand)
|
|
// call multiply::multiply
|
|
// pop result
|
|
// pop zero (discard second argument)
|
|
|
|
new_multiply:
|
|
push bpr
|
|
mov spr, bpr
|
|
|
|
ldw bpr, rg0, 8 // rg0 = multiplicand
|
|
ldw bpr, rg1, 12 // rg1 = multiplier
|
|
|
|
lli 0, rg2 // rg2 = result (accumulator)
|
|
lli 32, rg3 // rg3 = bit counter
|
|
|
|
mult_loop:
|
|
// Check if lowest bit of multiplier is 1
|
|
lli 1, acc
|
|
and rg1, acc, acc // acc = rg1 & 1
|
|
cmp acc, zero
|
|
jeq skip_add // if (rg1 & 1) == 0, skip addition
|
|
|
|
// Add multiplicand to result
|
|
add rg2, rg0, rg2
|
|
|
|
skip_add:
|
|
shl rg0, 1 // shift multiplicand left
|
|
shr rg1, 1 // shift multiplier right
|
|
|
|
dec rg3
|
|
cmp rg3, zero
|
|
jgt mult_loop
|
|
|
|
stw rg2, bpr, 8 // store result
|
|
mov bpr, spr
|
|
pop bpr
|
|
return
|