-/* Subroutines used for the C front end for Xilinx MicroBlaze (tumbl).
- Copyright 2010 Free Software Foundation, Inc.
-
- Contributed by Michael Eager <eager@eagercon.com>.
+/* Common hooks for Xilinx MicroBlaze.
+ Copyright 2009, 2010, 2011 Free Software Foundation, Inc.
This file is part of GCC.
mxl-soft-mul
Target Mask(SOFT_MUL)
-Use the soft multiply emulation (default)
+Use the soft multiply emulation
mxl-soft-div
Target Mask(SOFT_DIV)
-Use the software emulation for divides (default)
+Use the software emulation for divides
mxl-barrel-shift
Target Mask(BARREL_SHIFT)
-Use the hardware barrel shifter instead of emulation
+Use the hardware barrel shifter instead of emulation (default)
mxl-pattern-compare
Target Mask(PATTERN_COMPARE)
-MULTILIB_OPTIONS = mxl-barrel-shift mno-xl-soft-mul mxl-multiply-high
-MULTILIB_DIRNAMES = bs m mh
-MULTILIB_EXCEPTIONS = *mxl-barrel-shift/mxl-multiply-high mxl-multiply-high
+MULTILIB_OPTIONS = mno-xl-barrel-shift mxl-soft-mul
+MULTILIB_DIRNAMES = nbs nm
+MULTILIB_EXCEPTIONS =
# Extra files
mbtumbl-c.o: $(srcdir)/config/mbtumbl/mbtumbl-c.c \
"-mxl-multiply-high can be used only with -mcpu=v6.00.a or greater");
}
+#ifndef ARCH_mbtumbl
if (TARGET_MULTIPLY_HIGH && TARGET_SOFT_MUL)
error ("-mxl-multiply-high requires -mno-xl-soft-mul");
+#else
+ if (TARGET_MULTIPLY_HIGH && TARGET_SOFT_MUL)
+ error ("-mxl-multiply-high must not be used with -mxl-soft-mul");
+#endif
/* Always use DFA scheduler. */
microblaze_sched_use_dfa = 1;
#define OBJECT_FORMAT_ELF
/* Default target_flags if no switches are specified */
+#ifndef ARCH_mbtumbl
#define TARGET_DEFAULT (MASK_SOFT_MUL | MASK_SOFT_DIV | MASK_SOFT_FLOAT)
+#else
+#define TARGET_DEFAULT (MASK_BARREL_SHIFT | MASK_SOFT_DIV | MASK_SOFT_FLOAT)
+#endif
/* What is the default setting for -mcpu= . We set it to v4.00.a even though
we are actually ahead. This is safest version that has generate code
;;
m68k-*-*)
;;
+mbtumbl*-*-*)
+ cpu_type=mbtumbl
+ ;;
mep*-*-*)
;;
microblaze*-*-*)
tmake_file="$tmake_file m68k/t-floatlib"
extra_parts="$extra_parts crti.o crtn.o"
;;
+mbtumbl*-*-*)
+ tmake_file="mbtumbl/t-mbtumbl t-fdpbit"
+ extra_parts="crtbegin.o crtend.o crti.o crtn.o"
+ ;;
mcore-*-elf)
tmake_file="mcore/t-mcore t-fdpbit"
extra_parts="$extra_parts crti.o crtn.o"
.section .init, "ax"
lw r15, r0, r1
- rtsd r15, 8
addik r1, r1, 8
+ rts r15, 4
.section .fini, "ax"
lw r15, r0, r1
- rtsd r15, 8
- addik r1, r1, 8
+ addik r1, r1, 8
+ rts r15, 4
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
+ BEQI r5,$LaResult_Is_Zero # Result is Zero
XOR r28,r5,r6 # Get the sign of the result
+ BGEI r5,$LaR5_Pos
RSUBI r5,r5,0 # Make r5 positive
$LaR5_Pos:
BGEI r6,$LaR6_Pos
BLTI r5,$LaDIV2 # This traps r5 == 0x80000000
$LaDIV1:
ADD r5,r5,r5 # left shift logical r5
- BGTID r5,$LaDIV1
ADDIK r29,r29,-1
+ BGTI r5,$LaDIV1
$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
BRI $LaDIV2 # Div2
$LaLOOP_END:
BGEI r28,$LaRETURN_HERE
- BRID $LaRETURN_HERE
RSUBI r3,r3,0 # Negate the result
+ BRI $LaRETURN_HERE
$LaDiv_By_Zero:
$LaResult_Is_Zero:
OR r3,r0,r0 # set result to 0
LWI r29,r1,4
LWI r30,r1,8
LWI r31,r1,12
- RTSD r15,8
ADDIK r1,r1,16
+ RTS r15,4
.end __divsi3
.size __divsi3, . - __divsi3
#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
+ BEQI 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
+ BGEI r5,$La1_Pos
RSUBI r6,r6,0 # Make dividend positive
RSUBIC r5,r5,0 # Make dividend positive
$La1_Pos:
$LaDIV1:
ADD r6,r6,r6
ADDC r5,r5,r5 # left shift logical r5
- BGEID r5,$LaDIV1
ADDIK r28,r28,-1
+ BGEI r5,$LaDIV1
$LaDIV2:
ADD r6,r6,r6
ADDC r5,r5,r5 # left shift logical r5/r6 get the '1' into the Carry
lwi r28,r1,12
lwi r29,r1,16
lwi r30,r1,20
- rtsd r15,8
addik r1,r1,24
+ rts r15,4
.end __moddi3
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]
+ BGEI r5,$LaR5_Pos
RSUBI r5,r5,0 # Make r5 positive
$LaR5_Pos:
BGEI r6,$LaR6_Pos
# 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
+ BGEI r5,$LaDIV1 #
$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
BRI $LaDIV2 # Div2
$LaLOOP_END:
BGEI r28,$LaRETURN_HERE
- BRId $LaRETURN_HERE
rsubi r3,r3,0 # Negate the result
+ BRI $LaRETURN_HERE
$LaDiv_By_Zero:
$LaResult_Is_Zero:
or r3,r0,r0 # set result to 0 [Both mod as well as div are 0]
lwi r29,r1,4
lwi r30,r1,8
lwi r31,r1,12
- rtsd r15,8
addik r1,r1,16
+ rts r15,4
.end __modsi3
.size __modsi3, . - __modsi3
lwi r27,r1,28
# Restore Frame and return
- rtsd r15,8
addi r1,r1,40
+ rts r15,4
.end muldi3_hardproc
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
+ BGEI r5,$L_R5_Pos
RSUBI r5,r5,0 # Make r5 positive
$L_R5_Pos:
BGEI r6,$L_R6_Pos
srl r6,r6
addc r7,r0,r0
beqi r7,$L2
- bneid r6,$L2
add r3,r3,r5
+ bnei r6,$L2
blti r4,$L_NegateResult
- rtsd r15,8
- nop
+ rts r15,4
$L_NegateResult:
- rtsd r15,8
rsub r3,r3,r0
+ rts r15,4
$L_Result_Is_Zero:
- rtsd r15,8
addi r3,r0,0
+ rts r15,4
.end __mulsi3
.size __mulsi3, . - __mulsi3
+++ /dev/null
-###################################-*-asm*-
-#
-# Copyright 2009, 2011 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.S
-#
-# 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
$(srcdir)/config/mbtumbl/modsi3.S \
$(srcdir)/config/mbtumbl/muldi3_hard.S \
$(srcdir)/config/mbtumbl/mulsi3.S \
- $(srcdir)/config/mbtumbl/stack_overflow_exit.S \
$(srcdir)/config/mbtumbl/udivsi3.S \
$(srcdir)/config/mbtumbl/umodsi3.S \
$(srcdir)/config/mbtumbl/divsi3_table.c
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
+ BEQI r5,$LaResult_Is_Zero # Result is Zero
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
+ BEQI r18,$LaRETURN_HERE
# 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
+ BGEI r18,16
BLTI r6,$LaRETURN_HERE # r6[bit 31 = 1] hence is greater
BRI $LCheckr6
RSUB r18,r6,r5 # MICROBLAZEcmp
# If r6 [bit 31] is set, then return result as 1
$LCheckr6:
BGTI r6,$LaDIV0
- BRID $LaRETURN_HERE
ADDIK r3,r0,1
+ BRI $LaRETURN_HERE
# 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
+ BGTI r5,$LaDIV1
$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
LWI r29,r1,0
LWI r30,r1,4
LWI r31,r1,8
- RTSD r15,8
ADDIK r1,r1,12
+ RTS r15,4
.end __udivsi3
.size __udivsi3, . - __udivsi3
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
+ BEQI r5,$LaResult_Is_Zero # Result is Zero
ADDIK r30,r0,0 # clear mod
ADDIK r29,r0,32 # Initialize the loop count
# 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
+ bgei r18,16
blti r6,$LaRETURN_HERE
bri $LCheckr6
rsub r18,r5,r6 # MICROBLAZEcmp
# If r6 [bit 31] is set, then return result as r5-r6
$LCheckr6:
- bgtid r6,$LaDIV0
addik r3,r0,0
+ bgti r6,$LaDIV0
addik r18,r0,0x7fffffff
and r5,r5,r18
and r6,r6,r18
- brid $LaRETURN_HERE
rsub r3,r6,r5
+ bri $LaRETURN_HERE
# 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
+ BGEI r5,$LaDIV1 #
$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
lwi r29,r1,0
lwi r30,r1,4
lwi r31,r1,8
- rtsd r15,8
addik r1,r1,12
+ rts r15,4
.end __umodsi3
.size __umodsi3, . - __umodsi3