diff options
author | Michael Eager <eager@gcc.gnu.org> | 2010-09-30 18:21:57 +0000 |
---|---|---|
committer | Michael Eager <eager@gcc.gnu.org> | 2010-09-30 18:21:57 +0000 |
commit | 809201325afb3d70e517d30a483b39251b1b6e27 (patch) | |
tree | 3e6ddc920dca714da86387abe482505839030906 /libgcc/config | |
parent | 51be162e8ebb3b173c7f93c7719a7bc6192cbc42 (diff) | |
download | gcc-809201325afb3d70e517d30a483b39251b1b6e27.zip gcc-809201325afb3d70e517d30a483b39251b1b6e27.tar.gz gcc-809201325afb3d70e517d30a483b39251b1b6e27.tar.bz2 |
Check in support for Xilinx MicroBlaze processor.
From-SVN: r164756
Diffstat (limited to 'libgcc/config')
-rw-r--r-- | libgcc/config/microblaze/divsi3.asm | 96 | ||||
-rw-r--r-- | libgcc/config/microblaze/divsi3_table.c | 62 | ||||
-rw-r--r-- | libgcc/config/microblaze/moddi3.asm | 115 | ||||
-rw-r--r-- | libgcc/config/microblaze/modsi3.asm | 93 | ||||
-rw-r--r-- | libgcc/config/microblaze/muldi3_hard.asm | 144 | ||||
-rw-r--r-- | libgcc/config/microblaze/mulsi3.asm | 69 | ||||
-rw-r--r-- | libgcc/config/microblaze/stack_overflow_exit.asm | 61 | ||||
-rw-r--r-- | libgcc/config/microblaze/t-microblaze | 12 | ||||
-rw-r--r-- | libgcc/config/microblaze/udivsi3.asm | 103 | ||||
-rw-r--r-- | libgcc/config/microblaze/umodsi3.asm | 106 |
10 files changed, 861 insertions, 0 deletions
diff --git a/libgcc/config/microblaze/divsi3.asm b/libgcc/config/microblaze/divsi3.asm new file mode 100644 index 0000000..7d888b3 --- /dev/null +++ b/libgcc/config/microblaze/divsi3.asm @@ -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 + diff --git a/libgcc/config/microblaze/divsi3_table.c b/libgcc/config/microblaze/divsi3_table.c new file mode 100644 index 0000000..d37f2ae --- /dev/null +++ b/libgcc/config/microblaze/divsi3_table.c @@ -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, +}; + diff --git a/libgcc/config/microblaze/moddi3.asm b/libgcc/config/microblaze/moddi3.asm new file mode 100644 index 0000000..4923b45 --- /dev/null +++ b/libgcc/config/microblaze/moddi3.asm @@ -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 + diff --git a/libgcc/config/microblaze/modsi3.asm b/libgcc/config/microblaze/modsi3.asm new file mode 100644 index 0000000..cae95c8 --- /dev/null +++ b/libgcc/config/microblaze/modsi3.asm @@ -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 + diff --git a/libgcc/config/microblaze/muldi3_hard.asm b/libgcc/config/microblaze/muldi3_hard.asm new file mode 100644 index 0000000..0499e2a --- /dev/null +++ b/libgcc/config/microblaze/muldi3_hard.asm @@ -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 + + diff --git a/libgcc/config/microblaze/mulsi3.asm b/libgcc/config/microblaze/mulsi3.asm new file mode 100644 index 0000000..03fe028 --- /dev/null +++ b/libgcc/config/microblaze/mulsi3.asm @@ -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 diff --git a/libgcc/config/microblaze/stack_overflow_exit.asm b/libgcc/config/microblaze/stack_overflow_exit.asm new file mode 100644 index 0000000..30b31f0 --- /dev/null +++ b/libgcc/config/microblaze/stack_overflow_exit.asm @@ -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 diff --git a/libgcc/config/microblaze/t-microblaze b/libgcc/config/microblaze/t-microblaze new file mode 100644 index 0000000..85fc8d3 --- /dev/null +++ b/libgcc/config/microblaze/t-microblaze @@ -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 diff --git a/libgcc/config/microblaze/udivsi3.asm b/libgcc/config/microblaze/udivsi3.asm new file mode 100644 index 0000000..879cd34 --- /dev/null +++ b/libgcc/config/microblaze/udivsi3.asm @@ -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 diff --git a/libgcc/config/microblaze/umodsi3.asm b/libgcc/config/microblaze/umodsi3.asm new file mode 100644 index 0000000..f7fd008 --- /dev/null +++ b/libgcc/config/microblaze/umodsi3.asm @@ -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 |