pdp11: sort out more of the low level bits
authorAlan Cox <alan@linux.intel.com>
Sun, 18 Feb 2018 14:01:34 +0000 (14:01 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 18 Feb 2018 14:01:34 +0000 (14:01 +0000)
Kernel/lowlevel-pdp11.S

index 56838b9..119d98b 100644 (file)
@@ -69,12 +69,35 @@ _doexec:
 #endif
        
 
-___udivhi3:
-___umodhi3:
 _abort:
        rts pc
 
+outhd:
+       bicb $0x0F,r0
+       add $48,r0
+       cmpb 57,r0
+       blos hexgood
+       add $7,r0
+hexgood:
+       jmp outchar
+
+out0hb:
+       mov r0,-(sp)
+       rorb r0
+       rorb r0
+       rorb r0
+       rorb r0
+       jsr pc,outhd
+       mov (sp),r0
+       jsr pc,outhd
+       mov (sp)+,r0
+       rts pc
+
 outr0hex:
+       jsr pc,out0hb
+       swab r0
+       jsr pc,out0hb
+       swab r0
        rts pc
 
 outstring:
@@ -89,3 +112,86 @@ outstring:
 2:
        mov (sp)+,r1
        rts pc
+
+/*
+ *     The PDP 11 have a signed divide (except early machines) but not an
+ *     unsigned one. For some reason the PDP-11 gcc support lib forgets to
+ *     include this helper so we use our own
+ *
+ *     There are faster divide algorithms based upon lookup tables but they
+ *     take a lot more memory.
+ *
+ *     WARNING: untested at this point
+ */
+       .text
+       .even
+
+       .globl __divmodhi3
+       .globl __umodhi3
+       .globl __udivhi3
+/*
+ *     Maybe should panic ?
+ */
+divide_zero:
+       clr r0
+       clr r1
+       rts pc
+
+divops:
+       mov $1,r0
+       clr r1
+       tst r3
+       beq divide_zero
+align:
+       cmp r2,r3
+       bhis divide     /* if its bigger we are done */
+       bmi divide      /* if the top bit is set we are done */
+       tst r0
+       beq divide      /* and if we ran out of bits it is done */
+       asl r0
+       asl r3
+       br align
+divide:
+       tst r0          /* keep going until we've dealt with each bit we
+                          set in the first pass */
+       beq donediv
+       cmp r3,r2
+       blo wentover
+       sub r3,r2       /* set the bit and account for that chunk */
+       bis r0,r1
+wentover:
+       clc
+       ror r0
+       clc
+       ror r3
+       br divide
+donediv:
+       mov r2,r1       /* makes it easier to handle */
+       rts pc
+
+/*
+ *     Basically a C wrapper around the helper that returns the answer
+ *     in r0 and r1.
+ *
+ *     For the later machines I'm not clear if this or somehow mangling div
+ *     into udiv is faster.
+ */
+__divmodhi3:
+       mov r2,-(sp)
+       mov r3,-(sp)
+       mov 8(sp),r2
+       mov 10(sp),r3
+       jsr pc,divops
+       mov (sp)+,r3
+       mov (sp)+,r2
+       rts pc
+/*
+ *     And we get both forms just by looking at r0 or r1
+ */
+___umodhi3:
+       jsr pc,__divmodhi3
+       mov r1,r0
+       rts pc
+___udivhi3:
+       jsr pc,__divmodhi3
+       rts pc