This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Resubmit MicroBlaze support - 3 of 6 - libgcc



-- Michael Eager eager@eagercon.com 1960 Park Blvd., Palo Alto, CA 94306 650-325-8077
2010-04-30  Michael Eager <eager@eagercon.com>

	* config.host (microblaze*-*-*): Add cpu_type and target. 
	* config/microblaze/divsi3.asm: New.
	* config/microblaze/stack_overflow_exit.asm: New.
	* config/microblaze/umodsi3.asm: New.
	* config/microblaze/udivsi3.asm: New.
	* config/microblaze/t-microblaze: New.
	* config/microblaze/divsi3_table.c: New.
	* config/microblaze/muldi3_hard.asm: New.
	* config/microblaze/mulsi3.asm: New.
	* config/microblaze/modsi3.asm: New.
	* config/microblaze/moddi3.asm: New.
Index: libgcc/config.host
===================================================================
--- libgcc/config.host	(revision 158738)
+++ libgcc/config.host	(working copy)
@@ -107,6 +107,9 @@
 	;;
 mep*-*-*)
 	;;
+microblaze*-*-*)
+	cpu_type=microblaze
+	;;
 mips*-*-*)
 	cpu_type=mips
 	;;
@@ -395,6 +398,9 @@
 	;;
 mcore-*-pe*)
 	;;
+microblaze*-*-*)
+        tmake_file="microblaze/t-microblaze"
+	;;
 mips-sgi-irix[56]*)
 	;;
 mips*-*-netbsd*)			# NetBSD/mips, either endian.
Index: libgcc/config/microblaze/divsi3.asm
===================================================================
--- libgcc/config/microblaze/divsi3.asm	(revision 0)
+++ libgcc/config/microblaze/divsi3.asm	(revision 0)
@@ -0,0 +1,96 @@
+###################################-
+# 
+#  Copyright 2009, 2010 Free Software Foundation, Inc.
+#
+#  Contributed by Michael Eager <eager@eagercon.com>.
+#
+#  This file is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by the
+#  Free Software Foundation; either version 3, or (at your option) any
+#  later version.
+#
+#  GCC is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+#  License for more details.
+#
+#  Under Section 7 of GPL version 3, you are granted additional
+#  permissions described in the GCC Runtime Library Exception, version
+#  3.1, as published by the Free Software Foundation.
+#
+#  You should have received a copy of the GNU General Public License and
+#  a copy of the GCC Runtime Library Exception along with this program;
+#  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+#  <http://www.gnu.org/licenses/>. 
+#
+#  divsi3.asm 
+# 
+#  Divide operation for 32 bit integers.
+#	Input :	Dividend in Reg r5
+#		Divisor in Reg r6
+#	Output: Result in Reg r3
+# 
+#######################################
+	
+	.globl	__divsi3
+	.ent	__divsi3
+	.type	__divsi3,@function
+__divsi3:
+	.frame	r1,0,r15	
+
+	ADDIK   r1,r1,-16
+	SWI     r28,r1,0
+	SWI     r29,r1,4
+	SWI     r30,r1,8
+	SWI     r31,r1,12
+
+	BEQI    r6,$LaDiv_By_Zero       # Div_by_Zero   # Division Error
+	BEQI    r5,$LaResult_Is_Zero    # Result is Zero 
+	BGEID   r5,$LaR5_Pos 
+	XOR     r28,r5,r6               # Get the sign of the result
+	RSUBI   r5,r5,0                 # Make r5 positive
+$LaR5_Pos:
+	BGEI    r6,$LaR6_Pos
+	RSUBI   r6,r6,0                 # Make r6 positive
+$LaR6_Pos:
+	ADDIK   r30,r0,0                # Clear mod
+	ADDIK   r3,r0,0                 # clear div
+	ADDIK   r29,r0,32               # Initialize the loop count
+
+        # First part try to find the first '1' in the r5
+$LaDIV0: 
+        BLTI    r5,$LaDIV2              # This traps r5 == 0x80000000 
+$LaDIV1:
+	ADD     r5,r5,r5                # left shift logical r5
+	BGTID   r5,$LaDIV1       
+	ADDIK   r29,r29,-1
+$LaDIV2:
+	ADD     r5,r5,r5                # left shift logical  r5 get the '1' into the Carry
+	ADDC    r30,r30,r30             # Move that bit into the Mod register
+	RSUB    r31,r6,r30              # Try to subtract (r30 a r6)
+	BLTI    r31,$LaMOD_TOO_SMALL
+	OR      r30,r0,r31              # Move the r31 to mod since the result was positive
+	ADDIK   r3,r3,1
+$LaMOD_TOO_SMALL:
+	ADDIK   r29,r29,-1
+	BEQi    r29,$LaLOOP_END
+	ADD     r3,r3,r3                # Shift in the '1' into div
+	BRI     $LaDIV2                 # Div2
+$LaLOOP_END:
+	BGEI    r28,$LaRETURN_HERE
+	BRID    $LaRETURN_HERE
+	RSUBI   r3,r3,0                 # Negate the result
+$LaDiv_By_Zero:
+$LaResult_Is_Zero:
+	OR      r3,r0,r0 # set result to 0
+$LaRETURN_HERE:
+# Restore values of CSRs and that of r3 and the divisor and the dividend
+	LWI     r28,r1,0
+	LWI     r29,r1,4
+	LWI     r30,r1,8
+	LWI     r31,r1,12
+	RTSD    r15,8
+	ADDIK   r1,r1,16
+.end __divsi3
+	.size	__divsi3, . - __divsi3
+
Index: libgcc/config/microblaze/stack_overflow_exit.asm
===================================================================
--- libgcc/config/microblaze/stack_overflow_exit.asm	(revision 0)
+++ libgcc/config/microblaze/stack_overflow_exit.asm	(revision 0)
@@ -0,0 +1,61 @@
+###################################-*-asm*- 
+# 
+#    Copyright 2009 Free Software Foundation, Inc.
+# 
+#
+#  Contributed by Michael Eager <eager@eagercon.com>.
+#
+#  This file is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by the
+#  Free Software Foundation; either version 3, or (at your option) any
+#  later version.
+#
+#  GCC is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+#  License for more details.
+#
+#  Under Section 7 of GPL version 3, you are granted additional
+#  permissions described in the GCC Runtime Library Exception, version
+#  3.1, as published by the Free Software Foundation.
+#
+#  You should have received a copy of the GNU General Public License and
+#  a copy of the GCC Runtime Library Exception along with this program;
+#  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+#  <http://www.gnu.org/licenses/>.  
+# 
+#  stack_overflow_exit.asm
+# 
+#  Checks for stack overflows and sets the global variable 
+#  stack_overflow_error with the value of current stack pointer
+#
+#  This routine exits from the program
+# 
+#######################################
+
+	.globl	_stack_overflow_error
+	.data
+	.align	2
+	.type	_stack_overflow_error,@object
+	.size	_stack_overflow_error,4
+_stack_overflow_error:
+	.data32	0
+
+	.text 
+	.globl	_stack_overflow_exit	
+	.ent	_stack_overflow_exit
+	.type	_stack_overflow_exit,@function
+
+_stack_overflow_exit:
+#ifdef __PIC__
+	mfs	r20,rpc
+	addik	r20,r20,_GLOBAL_OFFSET_TABLE_+8
+	swi	r1,r20,_stack_overflow_error@GOTOFF
+	bri	exit@PLT
+#else
+	swi	r1,r0,_stack_overflow_error
+	bri	exit
+#endif
+
+	.end 	_stack_overflow_exit
+	.size	_stack_overflow_exit,. - _stack_overflow_exit
Index: libgcc/config/microblaze/umodsi3.asm
===================================================================
--- libgcc/config/microblaze/umodsi3.asm	(revision 0)
+++ libgcc/config/microblaze/umodsi3.asm	(revision 0)
@@ -0,0 +1,106 @@
+###################################
+# 
+#  Copyright 2009, 2010 Free Software Foundation, Inc.
+#
+#  Contributed by Michael Eager <eager@eagercon.com>.
+#
+#  This file is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by the
+#  Free Software Foundation; either version 3, or (at your option) any
+#  later version.
+#
+#  GCC is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+#  License for more details.
+#
+#  Under Section 7 of GPL version 3, you are granted additional
+#  permissions described in the GCC Runtime Library Exception, version
+#  3.1, as published by the Free Software Foundation.
+#
+#  You should have received a copy of the GNU General Public License and
+#  a copy of the GCC Runtime Library Exception along with this program;
+#  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+#  <http://www.gnu.org/licenses/>. 
+# 
+#  umodsi3.asm 
+#
+#  Unsigned modulo operation for 32 bit integers.
+#	Input :	op1 in Reg r5
+#		op2 in Reg r6
+#	Output: op1 mod op2 in Reg r3
+# 
+#######################################
+	
+	.globl	__umodsi3
+	.ent	__umodsi3
+	.type	__umodsi3,@function
+__umodsi3:
+	.frame	r1,0,r15	
+
+	addik	r1,r1,-12
+	swi	r29,r1,0
+	swi	r30,r1,4
+	swi	r31,r1,8
+
+	BEQI	r6,$LaDiv_By_Zero         # Div_by_Zero   # Division Error
+	BEQId	r5,$LaResult_Is_Zero     # Result is Zero 
+	ADDIK 	r3,r0,0                  # Clear div
+	ADDIK 	r30,r0,0     	# clear mod
+	ADDIK 	r29,r0,32       # Initialize the loop count
+
+# Check if r6 and r5 are equal # if yes, return 0
+	rsub 	r18,r5,r6
+	beqi	r18,$LaRETURN_HERE
+
+# Check if (uns)r6 is greater than (uns)r5. In that case, just return r5
+	xor	r18,r5,r6
+	bgeid	r18,16
+	addik	r3,r5,0
+	blti	r6,$LaRETURN_HERE
+	bri	$LCheckr6
+	rsub	r18,r5,r6 # MICROBLAZEcmp
+	bgti	r18,$LaRETURN_HERE
+
+# If r6 [bit 31] is set, then return result as r5-r6
+$LCheckr6:
+	bgtid	r6,$LaDIV0
+	addik	r3,r0,0
+	addik	r18,r0,0x7fffffff
+	and	r5,r5,r18
+	and 	r6,r6,r18
+	brid	$LaRETURN_HERE
+	rsub	r3,r6,r5
+# First part: try to find the first '1' in the r5
+$LaDIV0:
+	BLTI	r5,$LaDIV2
+$LaDIV1:
+	ADD 	r5,r5,r5     # left shift logical r5
+	BGEID 	r5,$LaDIV1   #
+	ADDIK 	r29,r29,-1
+$LaDIV2:
+	ADD 	r5,r5,r5     # left shift logical  r5 get the '1' into the Carry
+	ADDC 	r3,r3,r3     # Move that bit into the Mod register
+	rSUB 	r31,r6,r3    # Try to subtract (r3 a r6)
+	BLTi 	r31,$LaMOD_TOO_SMALL
+	OR  	r3,r0,r31    # Move the r31 to mod since the result was positive
+	ADDIK 	r30,r30,1
+$LaMOD_TOO_SMALL:
+	ADDIK 	r29,r29,-1
+	BEQi 	r29,$LaLOOP_END
+	ADD 	r30,r30,r30 # Shift in the '1' into div
+	BRI 	$LaDIV2     # Div2
+$LaLOOP_END:
+	BRI 	$LaRETURN_HERE
+$LaDiv_By_Zero:
+$LaResult_Is_Zero:
+	or 	r3,r0,r0   # set result to 0
+$LaRETURN_HERE:
+# Restore values of CSRs and that of r3 and the divisor and the dividend
+	lwi 	r29,r1,0
+	lwi 	r30,r1,4
+	lwi 	r31,r1,8
+	rtsd 	r15,8
+	addik 	r1,r1,12
+.end __umodsi3
+	.size	__umodsi3, . - __umodsi3
Index: libgcc/config/microblaze/udivsi3.asm
===================================================================
--- libgcc/config/microblaze/udivsi3.asm	(revision 0)
+++ libgcc/config/microblaze/udivsi3.asm	(revision 0)
@@ -0,0 +1,103 @@
+###################################-
+# 
+#  Copyright 2009, 2010 Free Software Foundation, Inc.
+#
+#  Contributed by Michael Eager <eager@eagercon.com>.
+#
+#  This file is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by the
+#  Free Software Foundation; either version 3, or (at your option) any
+#  later version.
+#
+#  GCC is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+#  License for more details.
+#
+#  Under Section 7 of GPL version 3, you are granted additional
+#  permissions described in the GCC Runtime Library Exception, version
+#  3.1, as published by the Free Software Foundation.
+#
+#  You should have received a copy of the GNU General Public License and
+#  a copy of the GCC Runtime Library Exception along with this program;
+#  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+#  <http://www.gnu.org/licenses/>. 
+# 
+#  udivsi3.asm 
+# 
+#  Unsigned divide operation.
+#	Input :	Divisor in Reg r5
+#		Dividend in Reg r6
+#	Output: Result in Reg r3
+# 
+#######################################
+	
+	.globl	__udivsi3
+	.ent	__udivsi3
+	.type	__udivsi3,@function
+__udivsi3:
+	.frame	r1,0,r15	
+
+	ADDIK   r1,r1,-12
+    	SWI     r29,r1,0
+	SWI     r30,r1,4
+	SWI     r31,r1,8
+
+	BEQI    r6,$LaDiv_By_Zero           # Div_by_Zero   # Division Error
+	BEQID   r5,$LaResult_Is_Zero        # Result is Zero 
+	ADDIK   r30,r0,0                    # Clear mod
+	ADDIK   r29,r0,32                   # Initialize the loop count
+
+        # Check if r6 and r5 are equal # if yes, return 1
+	RSUB 	r18,r5,r6
+	BEQID	r18,$LaRETURN_HERE
+	ADDIK	r3,r0,1
+
+        # Check if (uns)r6 is greater than (uns)r5. In that case, just return 0
+	XOR	r18,r5,r6
+	BGEID	r18,16
+	ADD	r3,r0,r0                    # We would anyways clear r3
+	BLTI	r6,$LaRETURN_HERE           # r6[bit 31 = 1] hence is greater
+	BRI	$LCheckr6
+	RSUB	r18,r6,r5                   # MICROBLAZEcmp
+	BLTI	r18,$LaRETURN_HERE
+
+        # If r6 [bit 31] is set, then return result as 1
+$LCheckr6:
+	BGTI	r6,$LaDIV0
+	BRID	$LaRETURN_HERE
+	ADDIK	r3,r0,1
+
+        # First part try to find the first '1' in the r5
+$LaDIV0:
+	BLTI    r5,$LaDIV2	
+$LaDIV1:
+	ADD     r5,r5,r5                    # left shift logical r5
+	BGTID   r5,$LaDIV1       
+	ADDIK   r29,r29,-1
+$LaDIV2:
+	ADD     r5,r5,r5                    # left shift logical  r5 get the '1' into the Carry
+	ADDC    r30,r30,r30                 # Move that bit into the Mod register
+	RSUB    r31,r6,r30                  # Try to subtract (r30 a r6)
+    	BLTI    r31,$LaMOD_TOO_SMALL
+	OR      r30,r0,r31                  # Move the r31 to mod since the result was positive
+	ADDIK   r3,r3,1
+$LaMOD_TOO_SMALL:
+	ADDIK   r29,r29,-1
+	BEQi    r29,$LaLOOP_END
+	ADD     r3,r3,r3 # Shift in the '1' into div
+	BRI     $LaDIV2   # Div2
+$LaLOOP_END:
+	BRI     $LaRETURN_HERE
+$LaDiv_By_Zero:
+$LaResult_Is_Zero:
+	OR      r3,r0,r0 # set result to 0
+$LaRETURN_HERE:
+        # Restore values of CSRs and that of r3 and the divisor and the dividend
+	LWI     r29,r1,0
+	LWI     r30,r1,4
+	LWI     r31,r1,8
+	RTSD    r15,8
+	ADDIK   r1,r1,12
+        .end __udivsi3
+	.size	__udivsi3, . - __udivsi3
Index: libgcc/config/microblaze/t-microblaze
===================================================================
--- libgcc/config/microblaze/t-microblaze	(revision 0)
+++ libgcc/config/microblaze/t-microblaze	(revision 0)
@@ -0,0 +1,12 @@
+LIB2ADD += \
+        $(srcdir)/config/microblaze/divsi3.asm \
+        $(srcdir)/config/microblaze/moddi3.asm \
+        $(srcdir)/config/microblaze/modsi3.asm \
+        $(srcdir)/config/microblaze/muldi3_hard.asm \
+        $(srcdir)/config/microblaze/mulsi3.asm \
+        $(srcdir)/config/microblaze/stack_overflow_exit.asm \
+        $(srcdir)/config/microblaze/udivsi3.asm \
+        $(srcdir)/config/microblaze/umodsi3.asm \
+        $(srcdir)/config/microblaze/divsi3_table.c
+
+MULTILIB_OPTIONS = mxl-barrel-shift mno-xl-soft-mul mxl-multiply-high
Index: libgcc/config/microblaze/divsi3_table.c
===================================================================
--- libgcc/config/microblaze/divsi3_table.c	(revision 0)
+++ libgcc/config/microblaze/divsi3_table.c	(revision 0)
@@ -0,0 +1,62 @@
+/*  Table for software lookup divide for Xilinx MicroBlaze.
+ 
+   Copyright 2009, 2010 Free Software Foundation, Inc.
+
+   Contributed by Michael Eager <eager@eagercon.com>.
+
+   This file is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+ 
+unsigned char _divsi3_table[] =
+{
+       0,   0/1,   0/2,   0/3,   0/4,   0/5,   0/6,   0/7, 
+     0/8,   0/9,  0/10,  0/11,  0/12,  0/13,  0/14,  0/15,
+       0,   1/1,   1/2,   1/3,   1/4,   1/5,   1/6,   1/7, 
+     1/8,   1/9,  1/10,  1/11,  1/12,  1/13,  1/14,  1/15,
+       0,   2/1,   2/2,   2/3,   2/4,   2/5,   2/6,   2/7, 
+     2/8,   2/9,  2/10,  2/11,  2/12,  2/13,  2/14,  2/15,
+       0,   3/1,   3/2,   3/3,   3/4,   3/5,   3/6,   3/7, 
+     3/8,   3/9,  3/10,  3/11,  3/12,  3/13,  3/14,  3/15,
+       0,   4/1,   4/2,   4/3,   4/4,   4/5,   4/6,   4/7, 
+     4/8,   4/9,  4/10,  4/11,  4/12,  4/13,  4/14,  4/15,
+       0,   5/1,   5/2,   5/3,   5/4,   5/5,   5/6,   5/7, 
+     5/8,   5/9,  5/10,  5/11,  5/12,  5/13,  5/14,  5/15,
+       0,   6/1,   6/2,   6/3,   6/4,   6/5,   6/6,   6/7, 
+     6/8,   6/9,  6/10,  6/11,  6/12,  6/13,  6/14,  6/15,
+       0,   7/1,   7/2,   7/3,   7/4,   7/5,   7/6,   7/7, 
+     7/8,   7/9,  7/10,  7/11,  7/12,  7/13,  7/14,  7/15,
+       0,   8/1,   8/2,   8/3,   8/4,   8/5,   8/6,   8/7, 
+     8/8,   8/9,  8/10,  8/11,  8/12,  8/13,  8/14,  8/15,
+       0,   9/1,   9/2,   9/3,   9/4,   9/5,   9/6,   9/7, 
+     9/8,   9/9,  9/10,  9/11,  9/12,  9/13,  9/14,  9/15,
+       0,  10/1,  10/2,  10/3,  10/4,  10/5,  10/6,  10/7, 
+    10/8,  10/9, 10/10, 10/11, 10/12, 10/13, 10/14, 10/15,
+       0,  11/1,  11/2,  11/3,  11/4,  11/5,  11/6,  11/7, 
+    11/8,  11/9, 11/10, 11/11, 11/12, 11/13, 11/14, 11/15,
+       0,  12/1,  12/2,  12/3,  12/4,  12/5,  12/6,  12/7, 
+    12/8,  12/9, 12/10, 12/11, 12/12, 12/13, 12/14, 12/15,
+       0,  13/1,  13/2,  13/3,  13/4,  13/5,  13/6,  13/7, 
+    13/8,  13/9, 13/10, 13/11, 13/12, 13/13, 13/14, 13/15,
+       0,  14/1,  14/2,  14/3,  14/4,  14/5,  14/6,  14/7, 
+    14/8,  14/9, 14/10, 14/11, 14/12, 14/13, 14/14, 14/15,
+       0,  15/1,  15/2,  15/3,  15/4,  15/5,  15/6,  15/7, 
+    15/8,  15/9, 15/10, 15/11, 15/12, 15/13, 15/14, 15/15,
+};
+
Index: libgcc/config/microblaze/muldi3_hard.asm
===================================================================
--- libgcc/config/microblaze/muldi3_hard.asm	(revision 0)
+++ libgcc/config/microblaze/muldi3_hard.asm	(revision 0)
@@ -0,0 +1,144 @@
+###################################- 
+# 
+#  Copyright 2009, 2010 Free Software Foundation, Inc.
+#
+#  Contributed by Michael Eager <eager@eagercon.com>.
+#
+#  This file is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by the
+#  Free Software Foundation; either version 3, or (at your option) any
+#  later version.
+#
+#  GCC is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+#  License for more details.
+#
+#  Under Section 7 of GPL version 3, you are granted additional
+#  permissions described in the GCC Runtime Library Exception, version
+#  3.1, as published by the Free Software Foundation.
+#
+#  You should have received a copy of the GNU General Public License and
+#  a copy of the GCC Runtime Library Exception along with this program;
+#  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+#  <http://www.gnu.org/licenses/>. 
+# 
+#  muldi3_hard.asm 
+# 
+#  Multiply operation for 64 bit integers, for devices with hard multiply
+#	Input :	Operand1[H] in Reg r5
+#		Operand1[L] in Reg r6		
+#		Operand2[H] in Reg r7
+#		Operand2[L] in Reg r8	
+#	Output: Result[H] in Reg r3
+#		Result[L] in Reg r4	
+# 
+#  Explaination:
+#
+# 	Both the input numbers are divided into 16 bit number as follows
+#		op1 = A B C D
+# 		op2 = E F G H
+#	result =    D * H 
+#		 + (C * H + D * G) << 16
+#		 + (B * H + C * G + D * F) << 32
+#		 + (A * H + B * G + C * F + D * E) << 48 
+#
+# 	Only 64 bits of the output are considered
+#
+#######################################
+
+	.globl	muldi3_hardproc
+	.ent	muldi3_hardproc
+muldi3_hardproc:
+	addi	r1,r1,-40
+
+#  Save the input operands on the caller's stack
+	swi	r5,r1,44
+	swi	r6,r1,48
+	swi	r7,r1,52
+	swi	r8,r1,56
+
+# Store all the callee saved registers 
+	sw	r20,r1,r0
+	swi	r21,r1,4
+	swi	r22,r1,8
+	swi	r23,r1,12
+	swi	r24,r1,16
+	swi	r25,r1,20
+	swi	r26,r1,24
+	swi	r27,r1,28
+
+# Load all the 16 bit values for A thru H
+	lhui	r20,r1,44   # A
+	lhui	r21,r1,46   # B
+	lhui	r22,r1,48   # C
+	lhui	r23,r1,50   # D
+	lhui	r24,r1,52   # E
+	lhui	r25,r1,54   # F
+	lhui	r26,r1,56   # G
+	lhui	r27,r1,58   # H
+
+# D * H ==> LSB of the result on stack ==> Store1
+	mul	r9,r23,r27
+	swi	r9,r1,36    # Pos2 and Pos3
+
+# Hi (Store1) + C * H + D * G ==> Store2 ==> Pos1 and Pos2
+# Store the carry generated in position 2 for Pos 3
+	lhui	r11,r1,36   # Pos2
+	mul	r9,r22,r27   # C * H
+	mul	r10,r23,r26  # D * G
+	add	r9,r9,r10
+	addc	r12,r0,r0
+	add	r9,r9,r11
+	addc	r12,r12,r0    # Store the Carry
+	shi	r9,r1,36    # Store Pos2
+	swi	r9,r1,32 
+	lhui	r11,r1,32
+	shi	r11,r1,34   # Store Pos1
+
+# Hi (Store2) + B * H + C * G + D * F ==> Store3 ==> Pos0 and Pos1
+	mul	r9,r21,r27  # B * H
+	mul	r10,r22,r26 # C * G
+	mul	r7,r23,r25 # D * F	
+	add	r9,r9,r11
+	add	r9,r9,r10
+	add	r9,r9,r7
+	swi	r9,r1,32   # Pos0 and Pos1
+
+# Hi (Store3) + A * H + B * G + C * F + D * E ==> Store3 ==> Pos0
+	lhui	r11,r1,32  # Pos0
+	mul	r9,r20,r27  # A * H
+	mul	r10,r21,r26 # B * G
+	mul	r7,r22,r25 # C * F
+	mul	r8,r23,r24 # D * E
+	add	r9,r9,r11
+	add 	r9,r9,r10
+	add	r9,r9,r7
+	add	r9,r9,r8
+	sext16	r9,r9       # Sign extend the MSB
+	shi	r9,r1,32
+
+# Move results to r3 and r4
+	lhui	r3,r1,32
+	add	r3,r3,r12
+	shi	r3,r1,32
+	lwi	r3,r1,32  # Hi Part
+	lwi	r4,r1,36  # Lo Part
+
+# Restore Callee saved registers
+	lw	r20,r1,r0
+	lwi	r21,r1,4
+	lwi	r22,r1,8
+	lwi	r23,r1,12
+	lwi	r24,r1,16
+	lwi	r25,r1,20
+	lwi	r26,r1,24
+	lwi	r27,r1,28
+
+# Restore Frame and return	
+	rtsd	r15,8
+	addi	r1,r1,40
+
+.end muldi3_hardproc 
+	
+
Index: libgcc/config/microblaze/mulsi3.asm
===================================================================
--- libgcc/config/microblaze/mulsi3.asm	(revision 0)
+++ libgcc/config/microblaze/mulsi3.asm	(revision 0)
@@ -0,0 +1,69 @@
+###################################-*-asm*- 
+# 
+#  Copyright 2009, 2010 Free Software Foundation, Inc.
+#
+#  Contributed by Michael Eager <eager@eagercon.com>.
+#
+#  This file is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by the
+#  Free Software Foundation; either version 3, or (at your option) any
+#  later version.
+#
+#  GCC is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+#  License for more details.
+#
+#  Under Section 7 of GPL version 3, you are granted additional
+#  permissions described in the GCC Runtime Library Exception, version
+#  3.1, as published by the Free Software Foundation.
+#
+#  You should have received a copy of the GNU General Public License and
+#  a copy of the GCC Runtime Library Exception along with this program;
+#  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+#  <http://www.gnu.org/licenses/>. 
+# 
+#  mulsi3.asm 
+# 
+#  Multiply operation for 32 bit integers.
+#	Input :	Operand1 in Reg r5
+#		Operand2 in Reg r6
+#	Output: Result [op1 * op2] in Reg r3
+# 
+#######################################
+
+	.globl	__mulsi3
+	.ent	__mulsi3
+	.type	__mulsi3,@function
+__mulsi3:
+	.frame	r1,0,r15
+	add	r3,r0,r0
+	BEQI	r5,$L_Result_Is_Zero      # Multiply by Zero
+	BEQI	r6,$L_Result_Is_Zero      # Multiply by Zero
+	BGEId	r5,$L_R5_Pos 
+	XOR	r4,r5,r6                  # Get the sign of the result
+	RSUBI	r5,r5,0	                  # Make r5 positive
+$L_R5_Pos:
+	BGEI	r6,$L_R6_Pos
+	RSUBI	r6,r6,0	                  # Make r6 positive
+$L_R6_Pos:	
+	bri	$L1
+$L2:	
+	add	r5,r5,r5
+$L1:	
+	srl	r6,r6
+	addc	r7,r0,r0
+	beqi	r7,$L2
+	bneid	r6,$L2
+	add	r3,r3,r5	
+	blti	r4,$L_NegateResult			
+	rtsd	r15,8
+	nop
+$L_NegateResult:
+	rtsd	r15,8
+	rsub	r3,r3,r0
+$L_Result_Is_Zero:
+	rtsd	r15,8
+	addi	r3,r0,0
+	.end __mulsi3
+	.size	__mulsi3, . - __mulsi3
Index: libgcc/config/microblaze/modsi3.asm
===================================================================
--- libgcc/config/microblaze/modsi3.asm	(revision 0)
+++ libgcc/config/microblaze/modsi3.asm	(revision 0)
@@ -0,0 +1,93 @@
+###################################
+# 
+#  Copyright 2009, 2010 Free Software Foundation, Inc.
+#
+#  Contributed by Michael Eager <eager@eagercon.com>.
+#
+#  This file is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by the
+#  Free Software Foundation; either version 3, or (at your option) any
+#  later version.
+#
+#  GCC is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+#  License for more details.
+#
+#  Under Section 7 of GPL version 3, you are granted additional
+#  permissions described in the GCC Runtime Library Exception, version
+#  3.1, as published by the Free Software Foundation.
+#
+#  You should have received a copy of the GNU General Public License and
+#  a copy of the GCC Runtime Library Exception along with this program;
+#  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+#  <http://www.gnu.org/licenses/>. 
+# 
+#  modsi3.asm 
+# 
+#  modulo operation for 32 bit integers.
+#	Input :	op1 in Reg r5
+#		op2 in Reg r6
+#	Output: op1 mod op2 in Reg r3
+# 
+#######################################
+
+	.globl	__modsi3
+	.ent	__modsi3
+	.type	__modsi3,@function
+__modsi3:
+	.frame	r1,0,r15	
+
+	addik	r1,r1,-16
+	swi	r28,r1,0
+	swi	r29,r1,4
+	swi	r30,r1,8
+	swi	r31,r1,12
+
+	BEQI	r6,$LaDiv_By_Zero       # Div_by_Zero   # Division Error
+	BEQI	r5,$LaResult_Is_Zero    # Result is Zero 
+	BGEId	r5,$LaR5_Pos 
+	ADD	r28,r5,r0               # Get the sign of the result [ Depends only on the first arg]
+	RSUBI	r5,r5,0	                # Make r5 positive
+$LaR5_Pos:
+	BGEI	r6,$LaR6_Pos
+	RSUBI	r6,r6,0	    # Make r6 positive
+$LaR6_Pos:
+	ADDIK	r3,r0,0      # Clear mod
+	ADDIK	r30,r0,0     # clear div
+	ADDIK	r29,r0,32    # Initialize the loop count
+   # First part try to find the first '1' in the r5
+$LaDIV1:
+	ADD	r5,r5,r5         # left shift logical r5
+	BGEID	r5,$LaDIV1       #
+	ADDIK	r29,r29,-1
+$LaDIV2:
+	ADD	r5,r5,r5         # left shift logical  r5 get the '1' into the Carry
+	ADDC	r3,r3,r3         # Move that bit into the Mod register
+	rSUB	r31,r6,r3        # Try to subtract (r30 a r6)
+	BLTi	r31,$LaMOD_TOO_SMALL
+	OR	r3,r0,r31       # Move the r31 to mod since the result was positive
+	ADDIK	r30,r30,1
+$LaMOD_TOO_SMALL:
+	ADDIK	r29,r29,-1
+	BEQi	r29,$LaLOOP_END
+	ADD	r30,r30,r30         # Shift in the '1' into div
+	BRI	$LaDIV2          # Div2
+$LaLOOP_END:
+	BGEI	r28,$LaRETURN_HERE
+	BRId	$LaRETURN_HERE
+	rsubi	r3,r3,0 # Negate the result
+$LaDiv_By_Zero:
+$LaResult_Is_Zero:
+	or	r3,r0,r0        # set result to 0 [Both mod as well as div are 0]
+$LaRETURN_HERE:
+# Restore values of CSRs and that of r3 and the divisor and the dividend
+	lwi	r28,r1,0
+	lwi	r29,r1,4
+	lwi	r30,r1,8
+	lwi	r31,r1,12
+	rtsd	r15,8
+	addik	r1,r1,16
+        .end __modsi3
+	.size	__modsi3, . - __modsi3
+
Index: libgcc/config/microblaze/moddi3.asm
===================================================================
--- libgcc/config/microblaze/moddi3.asm	(revision 0)
+++ libgcc/config/microblaze/moddi3.asm	(revision 0)
@@ -0,0 +1,115 @@
+###################################
+# 
+#  Copyright 2009, 2010 Free Software Foundation, Inc.
+#
+#  Contributed by Michael Eager <eager@eagercon.com>.
+#
+#  This file is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by the
+#  Free Software Foundation; either version 3, or (at your option) any
+#  later version.
+#
+#  GCC is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+#  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+#  License for more details.
+#
+#  Under Section 7 of GPL version 3, you are granted additional
+#  permissions described in the GCC Runtime Library Exception, version
+#  3.1, as published by the Free Software Foundation.
+#
+#  You should have received a copy of the GNU General Public License and
+#  a copy of the GCC Runtime Library Exception along with this program;
+#  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+#  <http://www.gnu.org/licenses/>. 
+#
+#  modsi3.asm 
+# 
+#  modulo operation for 64 bit integers.
+# 
+#######################################
+
+
+	.globl	__moddi3
+	.ent	__moddi3
+__moddi3:
+	.frame	r1,0,r15	
+
+#Change the stack pointer value and Save callee saved regs
+	addik	r1,r1,-24
+	swi	r25,r1,0
+	swi	r26,r1,4
+	swi	r27,r1,8	# used for sign
+	swi	r28,r1,12	# used for loop count
+	swi	r29,r1,16	# Used for div value High
+	swi	r30,r1,20	# Used for div value Low
+
+#Check for Zero Value in the divisor/dividend
+	OR	r9,r5,r6			# Check for the op1 being zero
+	BEQID	r9,$LaResult_Is_Zero		# Result is zero
+	OR	r9,r7,r8			# Check for the dividend being zero
+	BEQI	r9,$LaDiv_By_Zero	        # Div_by_Zero   # Division Error
+	BGEId	r5,$La1_Pos 
+	XOR	r27,r5,r7			# Get the sign of the result
+	RSUBI	r6,r6,0				# Make dividend positive
+	RSUBIC	r5,r5,0				# Make dividend positive
+$La1_Pos:
+	BGEI	r7,$La2_Pos
+	RSUBI	r8,r8,0				# Make Divisor Positive
+	RSUBIC	r9,r9,0				# Make Divisor Positive
+$La2_Pos:
+	ADDIK	r4,r0,0				# Clear mod low
+	ADDIK	r3,r0,0                	        # Clear mod high
+	ADDIK	r29,r0,0			# clear div high
+	ADDIK	r30,r0,0			# clear div low
+	ADDIK	r28,r0,64			# Initialize the loop count
+   # First part try to find the first '1' in the r5/r6
+$LaDIV1:
+	ADD	r6,r6,r6
+	ADDC	r5,r5,r5			# left shift logical r5
+	BGEID	r5,$LaDIV1			
+	ADDIK	r28,r28,-1
+$LaDIV2:
+	ADD	r6,r6,r6
+	ADDC	r5,r5,r5	# left shift logical r5/r6 get the '1' into the Carry
+	ADDC	r4,r4,r4	# Move that bit into the Mod register
+	ADDC	r3,r3,r3	# Move carry into high mod register
+	rsub	r18,r7,r3	# Compare the High Parts of Mod and Divisor
+	bnei	r18,$L_High_EQ
+	rsub	r18,r6,r4	# Compare Low Parts only if Mod[h] == Divisor[h]
+$L_High_EQ:	
+	rSUB	r26,r8,r4	# Subtract divisor[L] from Mod[L]
+	rsubc	r25,r7,r3	# Subtract divisor[H] from Mod[H]
+	BLTi	r25,$LaMOD_TOO_SMALL
+	OR	r3,r0,r25	# move r25 to mod [h]
+	OR	r4,r0,r26	# move r26 to mod [l]
+	ADDI	r30,r30,1
+	ADDC	r29,r29,r0
+$LaMOD_TOO_SMALL:
+	ADDIK	r28,r28,-1
+	BEQi	r28,$LaLOOP_END
+	ADD	r30,r30,r30		# Shift in the '1' into div [low]
+	ADDC	r29,r29,r29		# Move the carry generated into high
+	BRI	$LaDIV2   # Div2
+$LaLOOP_END:
+	BGEI	r27,$LaRETURN_HERE
+	rsubi	r30,r30,0
+	rsubc	r29,r29,r0
+	BRI	$LaRETURN_HERE
+$LaDiv_By_Zero:
+$LaResult_Is_Zero:
+	or	r29,r0,r0	# set result to 0 [High]
+	or	r30,r0,r0	# set result to 0 [Low]
+$LaRETURN_HERE:
+# Restore values of CSRs and that of r29 and the divisor and the dividend
+	
+	lwi	r25,r1,0
+	lwi	r26,r1,4
+	lwi	r27,r1,8
+	lwi	r28,r1,12
+	lwi	r29,r1,16
+	lwi	r30,r1,20
+	rtsd	r15,8
+	addik r1,r1,24
+        .end __moddi3
+	

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]