diff options
Diffstat (limited to 'gcc/config/arm/lib1funcs.asm')
-rw-r--r-- | gcc/config/arm/lib1funcs.asm | 92 |
1 files changed, 80 insertions, 12 deletions
diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm index 93c0df824a8..f0cf5db85e8 100644 --- a/gcc/config/arm/lib1funcs.asm +++ b/gcc/config/arm/lib1funcs.asm @@ -1,7 +1,7 @@ @ libgcc routines for ARM cpu. @ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk) -/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005 +/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. This file is free software; you can redistribute it and/or modify it @@ -69,31 +69,30 @@ Boston, MA 02110-1301, USA. */ /* Function end macros. Variants for interworking. */ -@ This selects the minimum architecture level required. -#define __ARM_ARCH__ 3 - #if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \ || defined(__ARM_ARCH_4T__) /* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with long multiply instructions. That includes v3M. */ -# undef __ARM_ARCH__ # define __ARM_ARCH__ 4 #endif #if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \ || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \ || defined(__ARM_ARCH_5TEJ__) -# undef __ARM_ARCH__ # define __ARM_ARCH__ 5 #endif #if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \ - || defined(__ARM_ARCH_6ZK__) -# undef __ARM_ARCH__ + || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) # define __ARM_ARCH__ 6 #endif +#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) +# define __ARM_ARCH__ 7 +#endif + #ifndef __ARM_ARCH__ #error Unable to determine architecture. #endif @@ -193,7 +192,11 @@ LSYM(Lend_fde): .ifc "\regs","" ldr\cond lr, [sp], #8 .else +# if defined(__thumb2__) + pop\cond {\regs, lr} +# else ldm\cond\dirn sp!, {\regs, lr} +# endif .endif .ifnc "\unwind", "" /* Mark LR as restored. */ @@ -201,14 +204,51 @@ LSYM(Lend_fde): .endif bx\cond lr #else + /* Caller is responsible for providing IT instruction. */ .ifc "\regs","" ldr\cond pc, [sp], #8 .else - ldm\cond\dirn sp!, {\regs, pc} +# if defined(__thumb2__) + pop\cond {\regs, pc} +# else + ldm\cond\dirn sp!, {\regs, lr} +# endif .endif #endif .endm +/* The Unified assembly syntax allows the same code to be assembled for both + ARM and Thumb-2. However this is only supported by recent gas, so define + a set of macros to allow ARM code on older assemblers. */ +#if defined(__thumb2__) +.macro do_it cond, suffix="" + it\suffix \cond +.endm +.macro shift1 op, arg0, arg1, arg2 + \op \arg0, \arg1, \arg2 +.endm +#define do_push push +#define do_pop pop +#define COND(op1, op2, cond) op1 ## op2 ## cond +/* Perform an arithmetic operation with a variable shift operand. This + requires two instructions and a scratch register on Thumb-2. */ +.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp + \shiftop \tmp, \src2, \shiftreg + \name \dest, \src1, \tmp +.endm +#else +.macro do_it cond, suffix="" +.endm +.macro shift1 op, arg0, arg1, arg2 + mov \arg0, \arg1, \op \arg2 +.endm +#define do_push stmfd sp!, +#define do_pop ldmfd sp!, +#define COND(op1, op2, cond) op1 ## cond ## op2 +.macro shiftop name, dest, src1, src2, shiftop, shiftreg, tmp + \name \dest, \src1, \src2, \shiftop \shiftreg +.endm +#endif .macro ARM_LDIV0 name str lr, [sp, #-8]! @@ -260,11 +300,17 @@ SYM (\name): #ifdef __thumb__ #define THUMB_FUNC .thumb_func #define THUMB_CODE .force_thumb +# if defined(__thumb2__) +#define THUMB_SYNTAX .syntax divided +# else +#define THUMB_SYNTAX +# endif #else #define THUMB_FUNC #define THUMB_CODE +#define THUMB_SYNTAX #endif - + .macro FUNC_START name .text .globl SYM (__\name) @@ -272,13 +318,27 @@ SYM (\name): .align 0 THUMB_CODE THUMB_FUNC + THUMB_SYNTAX SYM (__\name): .endm /* Special function that will always be coded in ARM assembly, even if in Thumb-only compilation. */ -#if defined(__INTERWORKING_STUBS__) +#if defined(__thumb2__) + +/* For Thumb-2 we build everything in thumb mode. */ +.macro ARM_FUNC_START name + FUNC_START \name + .syntax unified +.endm +#define EQUIV .thumb_set +.macro ARM_CALL name + bl __\name +.endm + +#elif defined(__INTERWORKING_STUBS__) + .macro ARM_FUNC_START name FUNC_START \name bx pc @@ -294,7 +354,9 @@ _L__\name: .macro ARM_CALL name bl _L__\name .endm -#else + +#else /* !(__INTERWORKING_STUBS__ || __thumb2__) */ + .macro ARM_FUNC_START name .text .globl SYM (__\name) @@ -307,6 +369,7 @@ SYM (__\name): .macro ARM_CALL name bl __\name .endm + #endif .macro FUNC_ALIAS new old @@ -1183,6 +1246,10 @@ LSYM(Lover12): #endif /* L_call_via_rX */ +/* Don't bother with the old interworking routines for Thumb-2. */ +/* ??? Maybe only omit these on v7m. */ +#ifndef __thumb2__ + #if defined L_interwork_call_via_rX /* These labels & instructions are used by the Arm/Thumb interworking code, @@ -1307,6 +1374,7 @@ LSYM(Lchange_\register): SIZE (_interwork_call_via_lr) #endif /* L_interwork_call_via_rX */ +#endif /* !__thumb2__ */ #endif /* Arch supports thumb. */ #ifndef __symbian__ |