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)