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