Subject: Bug in divide & remainder
To: None <port-alpha@NetBSD.ORG>
From: Trevor Blackwell <tlb@eecs.harvard.edu>
List: port-alpha
Date: 08/13/1995 13:27:35
It may be that divide and remainder (which use a nonstandard calling
convention: t10 / t11 -> t12) are supposed to preserve t10 and t11. 

At least, that's what gcc thinks, from looking at the output code -
the OSF1 Assembly Language Programmer's Guide isn't very clear.

Paraphrasing a comment in Gcc's machine description:

 The divide and remainder operations always take their inputs from
 t10 and t11, put their output in t12, and clobber
 t9 and at.

Perhaps this is actually a bug in gcc or gas, in which case the real
solution is presumably to fix these tools.

This was causing everything to fail rather spectacularily with
-O. kprintf("%d") was failing in an obvious way.

Here's a diff that at least makes some things work.

*** /usr/src/sys/lib/libkern/arch/alpha/divrem.m4       Sun Aug 13 10:22:38 1995
--- /usr/src/sys/lib/libkern/arch/alpha/divrem.m4-orig  Sun Aug 13 10:06:50 1995
***************
*** 57,71 ****
  #include "DEFS.h"
  
  LEAF(NAME, 0)                                 /* XXX */
!       lda     sp, -56(sp)
        stq     BIT, 0(sp)
        stq     I, 8(sp)
        stq     CC, 16(sp)
        stq     T_0, 24(sp)
  ifelse(S, `true',
  `     stq     SIGN, 32(sp)')
-       stq     A, 40(sp)
-       stq     B, 48(sp)
        mov     zero, RESULT                    /* Initialize result to zero */
  
  ifelse(S, `true',
--- 57,69 ----
  #include "DEFS.h"
  
  LEAF(NAME, 0)                                 /* XXX */
!       lda     sp, -48(sp)
        stq     BIT, 0(sp)
        stq     I, 8(sp)
        stq     CC, 16(sp)
        stq     T_0, 24(sp)
  ifelse(S, `true',
  `     stq     SIGN, 32(sp)')
        mov     zero, RESULT                    /* Initialize result to zero */
  
  ifelse(S, `true',
***************
*** 168,176 ****
        ldq     T_0, 24(sp)
  ifelse(S, `true',
  `     ldq     SIGN, 32(sp)')
!       ldq     A, 40(sp)
!       ldq     B, 48(sp)
!       lda     sp, 56(sp)
        ret     zero, (t9), 1
  
  Ldotrap:
--- 166,172 ----
        ldq     T_0, 24(sp)
  ifelse(S, `true',
  `     ldq     SIGN, 32(sp)')
!       lda     sp, 48(sp)
        ret     zero, (t9), 1
  
  Ldotrap:

--
Trevor Blackwell         tlb@eecs.harvard.edu          (617) 495-8912