Subject: asm support for 64-bit abi
To: None <port-mips@netbsd.org>
From: Christopher SEKIYA <wileyc@rezrov.net>
List: port-mips
Date: 08/11/2004 20:33:10
All,
Playing with the MIPS 64-bit ABI (necessary for SGI Octane support), I notice
that sys/lib/libkern/arch/mips/*.S are not 64-bit clean.
The appended patch addresses this -- essentially, it replaces addu/subu with
a macro that uses daddu/dsubu if _LP64 is defined.
This, plus a slightly modified toolchain, results in a SGI bootloader that
does the right thing (with string operations) on my IP30:
>> boot -f bootp()hulk
Setting $netaddr to 192.168.11.7 (from server guncho)
Obtaining hulk from server guncho
52400+544 entry: 0xa800000020080000
NetBSD/sgimips 2.0G Bootstrap, Revision 1.0
(wileyc@guncho, Wed Aug 11 20:27:01 JST 2004)
1
2
3
a800000020ffd1b0
bootp()hulk
strlen: 6
4
open xio(0)pci(15)scsi(0)disk(1)rdisk(0)partition(0)/unix: Device not configured
Boot failed! Halting...
>>
Is this okay to commit? Or is there a better way to do this?
-- Chris
GPG key FEB9DE7F (91AF 4534 4529 4BCC 31A5 938E 023E EEFB FEB9 DE7F)
Index: ffs.S
===================================================================
RCS file: /cvsroot/src/sys/lib/libkern/arch/mips/ffs.S,v
retrieving revision 1.5
diff -u -r1.5 ffs.S
--- ffs.S 7 Aug 2003 16:32:18 -0000 1.5
+++ ffs.S 11 Aug 2004 11:28:04 -0000
@@ -45,6 +45,14 @@
#endif
#endif
+#if defined(_LP64)
+#define ADDU daddu
+#define SUBU dsubu
+#else
+#define ADDU addu
+#define SUBU subu
+#endif
+
/* bit = ffs(value) */
LEAF(ffs)
@@ -57,7 +65,7 @@
nop
#endif
and v1, a0, 1 # bit set?
- addu v0, v0, 1
+ ADDU v0, v0, 1
srl a0, a0, 1
beq v1, zero, 1b # no, continue
done:
Index: memcpy.S
===================================================================
RCS file: /cvsroot/src/sys/lib/libkern/arch/mips/memcpy.S,v
retrieving revision 1.7
diff -u -r1.7 memcpy.S
--- memcpy.S 16 Oct 2001 15:40:53 -0000 1.7
+++ memcpy.S 11 Aug 2004 11:28:04 -0000
@@ -5,6 +5,14 @@
#include <mips/asm.h>
#include <machine/endian.h>
+#if defined(_LP64)
+#define ADDU daddu
+#define SUBU dsubu
+#else
+#define ADDU addu
+#define SUBU subu
+#endif
+
.set push
.set noreorder
@@ -32,7 +40,7 @@
* Make sure we can copy forwards.
*/
sltu t0,a1,a0 # t0 == a1 < a0
- addu a3,a1,a2 # a3 == end of source
+ ADDU a3,a1,a2 # a3 == end of source
sltu t1,a0,a3 # t1 == a0 < a1+a2
and t2,t0,t1 # overlap -- copy backwards
bne t2,zero,backcopy
@@ -61,10 +69,10 @@
*/
li AT,-32 # BDSLOT
and t0,a2,AT # count truncated to multiple of 32
- addu a3,a1,t0 # run fast loop up to this address
+ ADDU a3,a1,t0 # run fast loop up to this address
sltu AT,a1,a3 # any work to do?
beq AT,zero,wordcopy
- subu a2,t0 # BDSLOT
+ SUBU a2,t0 # BDSLOT
/*
* loop body
@@ -81,13 +89,13 @@
ld v1,8(a1)
ld t0,16(a1)
ld t1,24(a1)
- addu a1,32
+ ADDU a1,32
sd t3,0(a0)
sd v1,8(a0)
sd t0,16(a0)
sd t1,24(a0)
bne a1,a3,cp8
- addu a0,32 # BDSLOT
+ ADDU a0,32 # BDSLOT
b wordcopy
nop # BDSLOT
@@ -97,7 +105,7 @@
lw v1,4(a1)
lw t0,8(a1)
lw t1,12(a1)
- addu a1,32
+ ADDU a1,32
sw t3,0(a0)
sw v1,4(a0)
sw t0,8(a0)
@@ -106,7 +114,7 @@
lw t0,-8(a1)
lw v1,-12(a1)
lw t3,-16(a1)
- addu a0,32
+ ADDU a0,32
sw t1,-4(a0)
sw t0,-8(a0)
sw v1,-12(a0)
@@ -118,34 +126,34 @@
*/
wordcopy:
andi t2,a2,3 # get byte count / 4
- subu t2,a2,t2 # t2 = number of words to copy * 4
+ SUBU t2,a2,t2 # t2 = number of words to copy * 4
beq t2,zero,bytecopy
- addu t0,a1,t2 # BDSLOT stop at t0
- subu a2,a2,t2
+ ADDU t0,a1,t2 # BDSLOT stop at t0
+ SUBU a2,a2,t2
1:
lw t3,0(a1)
- addu a1,4
+ ADDU a1,4
sw t3,0(a0)
#ifdef MIPS3_5900
nop
nop
#endif
bne a1,t0,1b
- addu a0,4 # BDSLOT
+ ADDU a0,4 # BDSLOT
bytecopy:
beq a2,zero,copydone # nothing left to do?
nop
2:
lb t3,0(a1)
- addu a1,1
+ ADDU a1,1
sb t3,0(a0)
- subu a2,1
+ SUBU a2,1
#ifdef MIPS3_5900
nop
#endif
bgtz a2,2b
- addu a0,1 # BDSLOT
+ ADDU a0,1 # BDSLOT
copydone:
j ra
@@ -155,9 +163,9 @@
*/
destaligned:
andi t0,a2,3 # t0 = bytecount mod 4
- subu a3,a2,t0 # number of words to transfer
+ SUBU a3,a2,t0 # number of words to transfer
beq a3,zero,bytecopy
- addu a3,a1,a3 # BDSLOT: stop point for destaligned
+ ADDU a3,a1,a3 # BDSLOT: stop point for destaligned
move a2,t0 # this many to do after we are done
3:
@@ -179,18 +187,18 @@
*/
backcopy:
blez a2,copydone # nothing left to do?
- addu t0,a1,a2 # BDSLOT: end of source
- addu t1,a0,a2 # end of destination
+ ADDU t0,a1,a2 # BDSLOT: end of source
+ ADDU t1,a0,a2 # end of destination
4:
lb t3,-1(t0)
- subu t0,1
+ SUBU t0,1
sb t3,-1(t1)
#ifdef MIPS3_5900
nop
nop
#endif
bne t0,a1,4b
- subu t1,1 # BDSLOT
+ SUBU t1,1 # BDSLOT
j ra
nop
Index: memset.S
===================================================================
RCS file: /cvsroot/src/sys/lib/libkern/arch/mips/memset.S,v
retrieving revision 1.3
diff -u -r1.3 memset.S
--- memset.S 16 Oct 2001 15:40:53 -0000 1.3
+++ memset.S 11 Aug 2004 11:28:04 -0000
@@ -3,6 +3,14 @@
#include <mips/asm.h>
#include <machine/endian.h>
+#if defined(_LP64)
+#define ADDU daddu
+#define SUBU dsubu
+#else
+#define ADDU addu
+#define SUBU subu
+#endif
+
.set noreorder
@@ -19,19 +27,19 @@
sll t2, t1, 16 # shift that left 16
or t1, t2, t1 # or together
- subu t0, zero, a0 # compute # bytes to word align address
+ SUBU t0, zero, a0 # compute # bytes to word align address
and t0, t0, 3
beq t0, zero, 1f # skip if word aligned
- subu a2, a2, t0 # subtract from remaining count
+ SUBU a2, a2, t0 # subtract from remaining count
SWHI t1, 0(a0) # store 1, 2, or 3 bytes to align
- addu a0, a0, t0
+ ADDU a0, a0, t0
1:
and v1, a2, 3 # compute number of whole words left
- subu t0, a2, v1
- subu a2, a2, t0
- addu t0, t0, a0 # compute ending address
+ SUBU t0, a2, v1
+ SUBU a2, a2, t0
+ ADDU t0, t0, a0 # compute ending address
2:
- addu a0, a0, 4 # clear words
+ ADDU a0, a0, 4 # clear words
#ifdef MIPS3_5900
nop
nop
@@ -43,9 +51,9 @@
smallclr:
ble a2, zero, 2f
- addu t0, a2, a0 # compute ending address
+ ADDU t0, a2, a0 # compute ending address
1:
- addu a0, a0, 1 # clear bytes
+ ADDU a0, a0, 1 # clear bytes
#ifdef MIPS3_5900
nop
nop
Index: strcmp.S
===================================================================
RCS file: /cvsroot/src/sys/lib/libkern/arch/mips/strcmp.S,v
retrieving revision 1.1
diff -u -r1.1 strcmp.S
--- strcmp.S 15 Jan 1999 08:44:27 -0000 1.1
+++ strcmp.S 11 Aug 2004 11:28:04 -0000
@@ -2,6 +2,14 @@
#include <machine/cdefs.h>
#include <mips/asm.h>
+#if defined(_LP64)
+#define ADDU daddu
+#define SUBU dsubu
+#else
+#define ADDU addu
+#define SUBU subu
+#endif
+
.set noreorder
/*
@@ -18,13 +26,13 @@
lbu t0, 1(a0) # unroll loop
lbu t1, 1(a1)
beq t0, zero, LessOrEq # end of first string?
- addu a0, a0, 2
+ ADDU a0, a0, 2
beq t0, t1, 1b
- addu a1, a1, 2
+ ADDU a1, a1, 2
NotEq:
j ra
- subu v0, t0, t1
+ SUBU v0, t0, t1
LessOrEq:
j ra
- subu v0, zero, t1
+ SUBU v0, zero, t1
END(strcmp)
Index: strlen.S
===================================================================
RCS file: /cvsroot/src/sys/lib/libkern/arch/mips/strlen.S,v
retrieving revision 1.1
diff -u -r1.1 strlen.S
--- strlen.S 15 Jan 1999 08:44:27 -0000 1.1
+++ strlen.S 11 Aug 2004 11:28:04 -0000
@@ -2,18 +2,26 @@
#include <machine/cdefs.h>
#include <mips/asm.h>
+#if defined(_LP64)
+#define ADDU daddu
+#define SUBU dsubu
+#else
+#define ADDU addu
+#define SUBU subu
+#endif
+
.set noreorder
/*
* strlen(str)
*/
LEAF(strlen)
- addu v1, a0, 1
+ ADDU v1, a0, 1
1:
lb v0, 0(a0) # get byte from string
- addu a0, a0, 1 # increment pointer
+ ADDU a0, a0, 1 # increment pointer
bne v0, zero, 1b # continue if not end
nop
j ra
- subu v0, a0, v1 # compute length - 1 for '\0' char
+ SUBU v0, a0, v1 # compute length - 1 for '\0' char
END(strlen)