FORTRAN 77 on PDP-11
der Mouse
mouse at Rodents.Montreal.QC.CA
Thu Jul 28 23:23:40 CDT 2005
> ;assuming A[0] = MSW, and that each "number"
> ;is 7 bytes long
...
> movw #7,r3
> clrw r6 ; clear carry over
> .loop: clrw r4 ; clear tmp registers
> clrw r5
> movb (r0)[r3],r4 ; get unsigned byte into signed word
> movb (r1)[r3],r5
> mulw r4,r5 ; do signed multiplication
> addw r6,r5 ; add in previous "carry over"
> movb r5,(r2)[r3] ; save result
> rotl -8,r5,r6 ; save "carry over"
> bitcw #00FF,r6 ; make sure "carry over" is between 0 - 255
> sobgeq r3,.loop ; loop
* The comment says 7 bytes long; the code actually does 8 (7..0)
* Why not use movzbw instead of clrw-and-movb?
* It's canonically bicw, not bitcw.
* You need bicw #ff00,r6, not #00ff.
* movzbw r6,r6 does what your bi[t]cw tries to, and is shorter.
* If you'd store the numbevrs little-endian, the VAX way, instead of
big-endian, you could do it much more cheaply with emul - especially
if you do use a multiple of 4 bytes.
> Get's around the fact that the MUL instruction is signed only, even
> though the longer number is unsigned.
Provided you have integer overflow traps turned off, the difference
doesn't matter; the only difference between signed and unsigned
multiply is what constitutes arithmetic overflow.
Here's what I'd do, which rolls all the above suggestions together:
; All numbers are 8 bytes long, unsigned, LSB-first (native-endian)
; Overflow is ignored (high 64 bits of the 128-bit product are lost)
; r0 - points to first byte of multiplier A
; r1 - points to first byte of multiplier B
; r2 - points to first byte of result
; r3,r4,r5 - ignored on input and garbaged on output
emul (r0),(r1),$0,r3
emul (r0),4(r1),r4,r4
emul 4(r0),(r1),r4,r4
movq r3,(r2)
If you want the whole 128-bit product, then
; r0 - input A, 8 bytes
; r1 - input B, 8 bytes
; r2 - output, 16 bytes
; r3-r9 - scratch
emul (r0),(r1),$0,r3
emul (r0),4(r1),r4,r4
emul 4(r0),4(r1),r5,r5
emul 4(r0),(r1),r4,r8
addl2 r9,r5
adwc $0,r6
movl r3,(r2)
movl r8,4(r2)
movq r5,8(r2)
> If you do have a DIV instruction,
What VAX doesn't?
> and for printing out the result, it's easy to divide through the
> large number by 10 (as long as you get both the quotient and
> remainder from the DIV instruction).
Except you don't. You probably want EDIV, which does give both.
/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML mouse at rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
More information about the cctalk
mailing list