Add support for ARM's Thumb instruction set.
From-SVN: r18822
This commit is contained in:
parent
8cf619daa1
commit
e98e406fcc
@ -1,3 +1,8 @@
|
||||
Wed Mar 25 10:04:18 1998 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* configure.in: Add thumb-coff target.
|
||||
* config.sub: Add thumb-coff target.
|
||||
|
||||
Fri Mar 20 09:32:14 1998 Manfred Hollstein <manfred@s-direktnet.de>
|
||||
|
||||
* Makefile.in (install-gcc): Don't specify LANGUAGES here.
|
||||
|
5
config.sub
vendored
5
config.sub
vendored
@ -173,6 +173,9 @@ case $basic_machine in
|
||||
m88110 | m680[01234]0 | m683?2 | m68360 | z8k | v70 | h8500 | w65) # CYGNUS LOCAL
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
thumb)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
mips64vr4300 | mips64vr4300el) # CYGNUS LOCAL jsmith/vr4300
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
@ -216,6 +219,8 @@ case $basic_machine in
|
||||
;;
|
||||
m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | h8500-* | d10v-*) # CYGNUS LOCAL
|
||||
;;
|
||||
thumb-*)
|
||||
;;
|
||||
mips64vr4300-* | mips64vr4300el-*) # CYGNUS LOCAL jsmith/vr4300
|
||||
;;
|
||||
mips64vr4100-* | mips64vr4100el-*) # CYGNUS LOCAL jsmith/vr4100
|
||||
|
@ -540,6 +540,9 @@ case "${target}" in
|
||||
arm-*-riscix*)
|
||||
noconfigdirs="$noconfigdirs ld target-libgloss"
|
||||
;;
|
||||
thumb-*-coff)
|
||||
noconfigdirs="$noconfigdirs target-libgloss"
|
||||
;;
|
||||
d10v-*-*)
|
||||
noconfigdirs="$noconfigdirs target-librx target-libg++ target-libstdc++ target-libio target-libgloss"
|
||||
;;
|
||||
|
@ -1,3 +1,17 @@
|
||||
Wed Mar 25 10:05:19 1998 Nick Clifton <nickc@cygnus.com>
|
||||
|
||||
* config/arm/thumb.c: New File. Support for ARM's Thumb
|
||||
instruction set.
|
||||
* config/arm/thumb.h: New File. Thumb definitions.
|
||||
* config/arm/thumb.md: New File. Thumb machine description.
|
||||
* config/arm/tcoff.h: New File. Thumb COFF support.
|
||||
* config/arm/t-thumb: New File. Thumb makefile fragment.
|
||||
* config/arm/lib1thumb.asm: New File. Thumb libgcc support functions.
|
||||
|
||||
* configure.in: Add Thumb-coff target.
|
||||
* configure: Add Thumb-coff target.
|
||||
* config.sub: Add Thumb-coff target.
|
||||
|
||||
Wed Mar 25 10:30:32 1998 Jim Wilson <wilson@cygnus.com>
|
||||
|
||||
* loop.c (scan_loop): Initialize move_insn_first to zero.
|
||||
|
3
gcc/config.sub
vendored
3
gcc/config.sub
vendored
@ -159,6 +159,9 @@ case $basic_machine in
|
||||
| sparc | sparclet | sparclite | sparc64 | v850)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
thumb | thumbel)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
# (2) the word "unknown" tends to confuse beginning users.
|
||||
|
702
gcc/config/arm/lib1thumb.asm
Normal file
702
gcc/config/arm/lib1thumb.asm
Normal file
@ -0,0 +1,702 @@
|
||||
@ libgcc1 routines for ARM cpu.
|
||||
@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
|
||||
|
||||
/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
|
||||
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 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file with other programs, and to distribute
|
||||
those programs without any restriction coming from the use of this
|
||||
file. (The General Public License restrictions do apply in other
|
||||
respects; for example, they cover modification of the file, and
|
||||
distribution when not linked into another program.)
|
||||
|
||||
This file 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, if you link this library with other files,
|
||||
some of which are compiled with GCC, to produce an executable,
|
||||
this library does not by itself cause the resulting executable
|
||||
to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public License. */
|
||||
|
||||
.code 16
|
||||
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
#error USER_LABEL_PREFIX not defined
|
||||
#endif
|
||||
|
||||
#define RET mov pc, lr
|
||||
|
||||
/* ANSI concatenation macros. */
|
||||
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
|
||||
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
|
||||
work .req r4 @ XXXX is this safe ?
|
||||
|
||||
#ifdef L_udivsi3
|
||||
|
||||
dividend .req r0
|
||||
divisor .req r1
|
||||
result .req r2
|
||||
curbit .req r3
|
||||
ip .req r12
|
||||
sp .req r13
|
||||
lr .req r14
|
||||
pc .req r15
|
||||
|
||||
.text
|
||||
.globl SYM (__udivsi3)
|
||||
.align 0
|
||||
.thumb_func
|
||||
SYM (__udivsi3):
|
||||
cmp divisor, #0
|
||||
beq Ldiv0
|
||||
mov curbit, #1
|
||||
mov result, #0
|
||||
|
||||
push { work }
|
||||
cmp dividend, divisor
|
||||
bcc Lgot_result
|
||||
|
||||
@ Load the constant 0x10000000 into our work register
|
||||
mov work, #1
|
||||
lsl work, #28
|
||||
Loop1:
|
||||
@ Unless the divisor is very big, shift it up in multiples of
|
||||
@ four bits, since this is the amount of unwinding in the main
|
||||
@ division loop. Continue shifting until the divisor is
|
||||
@ larger than the dividend.
|
||||
cmp divisor, work
|
||||
bcs Lbignum
|
||||
cmp divisor, dividend
|
||||
bcs Lbignum
|
||||
lsl divisor, #4
|
||||
lsl curbit, #4
|
||||
b Loop1
|
||||
|
||||
Lbignum:
|
||||
@ Set work to 0x80000000
|
||||
lsl work, #3
|
||||
Loop2:
|
||||
@ For very big divisors, we must shift it a bit at a time, or
|
||||
@ we will be in danger of overflowing.
|
||||
cmp divisor, work
|
||||
bcs Loop3
|
||||
cmp divisor, dividend
|
||||
bcs Loop3
|
||||
lsl divisor, #1
|
||||
lsl curbit, #1
|
||||
b Loop2
|
||||
|
||||
Loop3:
|
||||
@ Test for possible subtractions, and note which bits
|
||||
@ are done in the result. On the final pass, this may subtract
|
||||
@ too much from the dividend, but the result will be ok, since the
|
||||
@ "bit" will have been shifted out at the bottom.
|
||||
cmp dividend, divisor
|
||||
bcc Over1
|
||||
sub dividend, dividend, divisor
|
||||
orr result, result, curbit
|
||||
Over1:
|
||||
lsr work, divisor, #1
|
||||
cmp dividend, work
|
||||
bcc Over2
|
||||
sub dividend, dividend, work
|
||||
lsr work, curbit, #1
|
||||
orr result, work
|
||||
Over2:
|
||||
lsr work, divisor, #2
|
||||
cmp dividend, work
|
||||
bcc Over3
|
||||
sub dividend, dividend, work
|
||||
lsr work, curbit, #2
|
||||
orr result, work
|
||||
Over3:
|
||||
lsr work, divisor, #3
|
||||
cmp dividend, work
|
||||
bcc Over4
|
||||
sub dividend, dividend, work
|
||||
lsr work, curbit, #3
|
||||
orr result, work
|
||||
Over4:
|
||||
cmp dividend, #0 @ Early termination?
|
||||
beq Lgot_result
|
||||
lsr curbit, #4 @ No, any more bits to do?
|
||||
beq Lgot_result
|
||||
lsr divisor, #4
|
||||
b Loop3
|
||||
Lgot_result:
|
||||
mov r0, result
|
||||
pop { work }
|
||||
RET
|
||||
|
||||
Ldiv0:
|
||||
push { lr }
|
||||
bl SYM (__div0)
|
||||
mov r0, #0 @ about as wrong as it could be
|
||||
pop { pc }
|
||||
|
||||
#endif /* L_udivsi3 */
|
||||
|
||||
#ifdef L_umodsi3
|
||||
|
||||
dividend .req r0
|
||||
divisor .req r1
|
||||
overdone .req r2
|
||||
curbit .req r3
|
||||
ip .req r12
|
||||
sp .req r13
|
||||
lr .req r14
|
||||
pc .req r15
|
||||
.text
|
||||
.globl SYM (__umodsi3)
|
||||
.align 0
|
||||
.thumb_func
|
||||
SYM (__umodsi3):
|
||||
cmp divisor, #0
|
||||
beq Ldiv0
|
||||
mov curbit, #1
|
||||
cmp dividend, divisor
|
||||
bcs Over1
|
||||
RET
|
||||
|
||||
Over1:
|
||||
@ Load the constant 0x10000000 into our work register
|
||||
push { work }
|
||||
mov work, #1
|
||||
lsl work, #28
|
||||
Loop1:
|
||||
@ Unless the divisor is very big, shift it up in multiples of
|
||||
@ four bits, since this is the amount of unwinding in the main
|
||||
@ division loop. Continue shifting until the divisor is
|
||||
@ larger than the dividend.
|
||||
cmp divisor, work
|
||||
bcs Lbignum
|
||||
cmp divisor, dividend
|
||||
bcs Lbignum
|
||||
lsl divisor, #4
|
||||
lsl curbit, #4
|
||||
b Loop1
|
||||
|
||||
Lbignum:
|
||||
@ Set work to 0x80000000
|
||||
lsl work, #3
|
||||
Loop2:
|
||||
@ For very big divisors, we must shift it a bit at a time, or
|
||||
@ we will be in danger of overflowing.
|
||||
cmp divisor, work
|
||||
bcs Loop3
|
||||
cmp divisor, dividend
|
||||
bcs Loop3
|
||||
lsl divisor, #1
|
||||
lsl curbit, #1
|
||||
b Loop2
|
||||
|
||||
Loop3:
|
||||
@ Test for possible subtractions. On the final pass, this may
|
||||
@ subtract too much from the dividend, so keep track of which
|
||||
@ subtractions are done, we can fix them up afterwards...
|
||||
mov overdone, #0
|
||||
cmp dividend, divisor
|
||||
bcc Over2
|
||||
sub dividend, dividend, divisor
|
||||
Over2:
|
||||
lsr work, divisor, #1
|
||||
cmp dividend, work
|
||||
bcc Over3
|
||||
sub dividend, dividend, work
|
||||
mov ip, curbit
|
||||
mov work, #1
|
||||
ror curbit, work
|
||||
orr overdone, curbit
|
||||
mov curbit, ip
|
||||
Over3:
|
||||
lsr work, divisor, #2
|
||||
cmp dividend, work
|
||||
bcc Over4
|
||||
sub dividend, dividend, work
|
||||
mov ip, curbit
|
||||
mov work, #2
|
||||
ror curbit, work
|
||||
orr overdone, curbit
|
||||
mov curbit, ip
|
||||
Over4:
|
||||
lsr work, divisor, #3
|
||||
cmp dividend, work
|
||||
bcc Over5
|
||||
sub dividend, dividend, work
|
||||
mov ip, curbit
|
||||
mov work, #3
|
||||
ror curbit, work
|
||||
orr overdone, curbit
|
||||
mov curbit, ip
|
||||
Over5:
|
||||
mov ip, curbit
|
||||
cmp dividend, #0 @ Early termination?
|
||||
beq Over6
|
||||
lsr curbit, #4 @ No, any more bits to do?
|
||||
beq Over6
|
||||
lsr divisor, #4
|
||||
b Loop3
|
||||
|
||||
Over6:
|
||||
@ Any subtractions that we should not have done will be recorded in
|
||||
@ the top three bits of "overdone". Exactly which were not needed
|
||||
@ are governed by the position of the bit, stored in ip.
|
||||
@ If we terminated early, because dividend became zero,
|
||||
@ then none of the below will match, since the bit in ip will not be
|
||||
@ in the bottom nibble.
|
||||
|
||||
mov work, #0xe
|
||||
lsl work, #28
|
||||
and overdone, work
|
||||
bne Over7
|
||||
pop { work }
|
||||
RET @ No fixups needed
|
||||
Over7:
|
||||
mov curbit, ip
|
||||
mov work, #3
|
||||
ror curbit, work
|
||||
tst overdone, curbit
|
||||
beq Over8
|
||||
lsr work, divisor, #3
|
||||
add dividend, dividend, work
|
||||
Over8:
|
||||
mov curbit, ip
|
||||
mov work, #2
|
||||
ror curbit, work
|
||||
tst overdone, curbit
|
||||
beq Over9
|
||||
lsr work, divisor, #2
|
||||
add dividend, dividend, work
|
||||
Over9:
|
||||
mov curbit, ip
|
||||
mov work, #1
|
||||
ror curbit, work
|
||||
tst overdone, curbit
|
||||
beq Over10
|
||||
lsr work, divisor, #1
|
||||
add dividend, dividend, work
|
||||
Over10:
|
||||
pop { work }
|
||||
RET
|
||||
|
||||
Ldiv0:
|
||||
push { lr }
|
||||
bl SYM (__div0)
|
||||
mov r0, #0 @ about as wrong as it could be
|
||||
pop { pc }
|
||||
|
||||
#endif /* L_umodsi3 */
|
||||
|
||||
#ifdef L_divsi3
|
||||
|
||||
dividend .req r0
|
||||
divisor .req r1
|
||||
result .req r2
|
||||
curbit .req r3
|
||||
ip .req r12
|
||||
sp .req r13
|
||||
lr .req r14
|
||||
pc .req r15
|
||||
.text
|
||||
.globl SYM (__divsi3)
|
||||
.align 0
|
||||
.thumb_func
|
||||
SYM (__divsi3):
|
||||
cmp divisor, #0
|
||||
beq Ldiv0
|
||||
|
||||
push { work }
|
||||
mov work, dividend
|
||||
eor work, divisor @ Save the sign of the result.
|
||||
mov ip, work
|
||||
mov curbit, #1
|
||||
mov result, #0
|
||||
cmp divisor, #0
|
||||
bpl Over1
|
||||
neg divisor, divisor @ Loops below use unsigned.
|
||||
Over1:
|
||||
cmp dividend, #0
|
||||
bpl Over2
|
||||
neg dividend, dividend
|
||||
Over2:
|
||||
cmp dividend, divisor
|
||||
bcc Lgot_result
|
||||
|
||||
mov work, #1
|
||||
lsl work, #28
|
||||
Loop1:
|
||||
@ Unless the divisor is very big, shift it up in multiples of
|
||||
@ four bits, since this is the amount of unwinding in the main
|
||||
@ division loop. Continue shifting until the divisor is
|
||||
@ larger than the dividend.
|
||||
cmp divisor, work
|
||||
Bcs Lbignum
|
||||
cmp divisor, dividend
|
||||
Bcs Lbignum
|
||||
lsl divisor, #4
|
||||
lsl curbit, #4
|
||||
b Loop1
|
||||
|
||||
Lbignum:
|
||||
@ For very big divisors, we must shift it a bit at a time, or
|
||||
@ we will be in danger of overflowing.
|
||||
lsl work, #3
|
||||
Loop2:
|
||||
cmp divisor, work
|
||||
Bcs Loop3
|
||||
cmp divisor, dividend
|
||||
Bcs Loop3
|
||||
lsl divisor, #1
|
||||
lsl curbit, #1
|
||||
b Loop2
|
||||
|
||||
Loop3:
|
||||
@ Test for possible subtractions, and note which bits
|
||||
@ are done in the result. On the final pass, this may subtract
|
||||
@ too much from the dividend, but the result will be ok, since the
|
||||
@ "bit" will have been shifted out at the bottom.
|
||||
cmp dividend, divisor
|
||||
Bcc Over3
|
||||
sub dividend, dividend, divisor
|
||||
orr result, result, curbit
|
||||
Over3:
|
||||
lsr work, divisor, #1
|
||||
cmp dividend, work
|
||||
Bcc Over4
|
||||
sub dividend, dividend, work
|
||||
lsr work, curbit, #1
|
||||
orr result, work
|
||||
Over4:
|
||||
lsr work, divisor, #2
|
||||
cmp dividend, work
|
||||
Bcc Over5
|
||||
sub dividend, dividend, work
|
||||
lsr work, curbit, #2
|
||||
orr result, result, work
|
||||
Over5:
|
||||
lsr work, divisor, #3
|
||||
cmp dividend, work
|
||||
Bcc Over6
|
||||
sub dividend, dividend, work
|
||||
lsr work, curbit, #3
|
||||
orr result, result, work
|
||||
Over6:
|
||||
cmp dividend, #0 @ Early termination?
|
||||
Beq Lgot_result
|
||||
lsr curbit, #4 @ No, any more bits to do?
|
||||
Beq Lgot_result
|
||||
lsr divisor, #4
|
||||
b Loop3
|
||||
|
||||
Lgot_result:
|
||||
mov r0, result
|
||||
mov work, ip
|
||||
cmp work, #0
|
||||
Bpl Over7
|
||||
neg r0, r0
|
||||
Over7:
|
||||
pop { work }
|
||||
RET
|
||||
|
||||
Ldiv0:
|
||||
push { lr }
|
||||
bl SYM (__div0)
|
||||
mov r0, #0 @ about as wrong as it could be
|
||||
pop { pc }
|
||||
|
||||
#endif /* L_divsi3 */
|
||||
|
||||
#ifdef L_modsi3
|
||||
|
||||
dividend .req r0
|
||||
divisor .req r1
|
||||
overdone .req r2
|
||||
curbit .req r3
|
||||
ip .req r12
|
||||
sp .req r13
|
||||
lr .req r14
|
||||
pc .req r15
|
||||
.text
|
||||
.globl SYM (__modsi3)
|
||||
.align 0
|
||||
.thumb_func
|
||||
SYM (__modsi3):
|
||||
mov curbit, #1
|
||||
cmp divisor, #0
|
||||
beq Ldiv0
|
||||
Bpl Over1
|
||||
neg divisor, divisor @ Loops below use unsigned.
|
||||
Over1:
|
||||
push { work }
|
||||
@ Need to save the sign of the dividend, unfortunately, we need
|
||||
@ ip later on. Must do this after saving the original value of
|
||||
@ the work register, because we will pop this value off first.
|
||||
push { dividend }
|
||||
cmp dividend, #0
|
||||
Bpl Over2
|
||||
neg dividend, dividend
|
||||
Over2:
|
||||
cmp dividend, divisor
|
||||
bcc Lgot_result
|
||||
mov work, #1
|
||||
lsl work, #28
|
||||
Loop1:
|
||||
@ Unless the divisor is very big, shift it up in multiples of
|
||||
@ four bits, since this is the amount of unwinding in the main
|
||||
@ division loop. Continue shifting until the divisor is
|
||||
@ larger than the dividend.
|
||||
cmp divisor, work
|
||||
bcs Lbignum
|
||||
cmp divisor, dividend
|
||||
bcs Lbignum
|
||||
lsl divisor, #4
|
||||
lsl curbit, #4
|
||||
b Loop1
|
||||
|
||||
Lbignum:
|
||||
@ Set work to 0x80000000
|
||||
lsl work, #3
|
||||
Loop2:
|
||||
@ For very big divisors, we must shift it a bit at a time, or
|
||||
@ we will be in danger of overflowing.
|
||||
cmp divisor, work
|
||||
bcs Loop3
|
||||
cmp divisor, dividend
|
||||
bcs Loop3
|
||||
lsl divisor, #1
|
||||
lsl curbit, #1
|
||||
b Loop2
|
||||
|
||||
Loop3:
|
||||
@ Test for possible subtractions. On the final pass, this may
|
||||
@ subtract too much from the dividend, so keep track of which
|
||||
@ subtractions are done, we can fix them up afterwards...
|
||||
mov overdone, #0
|
||||
cmp dividend, divisor
|
||||
bcc Over3
|
||||
sub dividend, dividend, divisor
|
||||
Over3:
|
||||
lsr work, divisor, #1
|
||||
cmp dividend, work
|
||||
bcc Over4
|
||||
sub dividend, dividend, work
|
||||
mov ip, curbit
|
||||
mov work, #1
|
||||
ror curbit, work
|
||||
orr overdone, curbit
|
||||
mov curbit, ip
|
||||
Over4:
|
||||
lsr work, divisor, #2
|
||||
cmp dividend, work
|
||||
bcc Over5
|
||||
sub dividend, dividend, work
|
||||
mov ip, curbit
|
||||
mov work, #2
|
||||
ror curbit, work
|
||||
orr overdone, curbit
|
||||
mov curbit, ip
|
||||
Over5:
|
||||
lsr work, divisor, #3
|
||||
cmp dividend, work
|
||||
bcc Over6
|
||||
sub dividend, dividend, work
|
||||
mov ip, curbit
|
||||
mov work, #3
|
||||
ror curbit, work
|
||||
orr overdone, curbit
|
||||
mov curbit, ip
|
||||
Over6:
|
||||
mov ip, curbit
|
||||
cmp dividend, #0 @ Early termination?
|
||||
beq Over7
|
||||
lsr curbit, #4 @ No, any more bits to do?
|
||||
beq Over7
|
||||
lsr divisor, #4
|
||||
b Loop3
|
||||
|
||||
Over7:
|
||||
@ Any subtractions that we should not have done will be recorded in
|
||||
@ the top three bits of "overdone". Exactly which were not needed
|
||||
@ are governed by the position of the bit, stored in ip.
|
||||
@ If we terminated early, because dividend became zero,
|
||||
@ then none of the below will match, since the bit in ip will not be
|
||||
@ in the bottom nibble.
|
||||
mov work, #0xe
|
||||
lsl work, #28
|
||||
and overdone, work
|
||||
beq Lgot_result
|
||||
|
||||
mov curbit, ip
|
||||
mov work, #3
|
||||
ror curbit, work
|
||||
tst overdone, curbit
|
||||
beq Over8
|
||||
lsr work, divisor, #3
|
||||
add dividend, dividend, work
|
||||
Over8:
|
||||
mov curbit, ip
|
||||
mov work, #2
|
||||
ror curbit, work
|
||||
tst overdone, curbit
|
||||
beq Over9
|
||||
lsr work, divisor, #2
|
||||
add dividend, dividend, work
|
||||
Over9:
|
||||
mov curbit, ip
|
||||
mov work, #1
|
||||
ror curbit, work
|
||||
tst overdone, curbit
|
||||
beq Lgot_result
|
||||
lsr work, divisor, #1
|
||||
add dividend, dividend, work
|
||||
Lgot_result:
|
||||
pop { work }
|
||||
cmp work, #0
|
||||
bpl Over10
|
||||
neg dividend, dividend
|
||||
Over10:
|
||||
pop { work }
|
||||
RET
|
||||
|
||||
Ldiv0:
|
||||
push { lr }
|
||||
bl SYM (__div0)
|
||||
mov r0, #0 @ about as wrong as it could be
|
||||
pop { pc }
|
||||
|
||||
#endif /* L_modsi3 */
|
||||
|
||||
#ifdef L_dvmd_tls
|
||||
|
||||
.globl SYM (__div0)
|
||||
.align 0
|
||||
.thumb_func
|
||||
SYM (__div0):
|
||||
RET
|
||||
|
||||
#endif /* L_divmodsi_tools */
|
||||
|
||||
|
||||
#ifdef L_call_via_rX
|
||||
|
||||
/* These labels & instructions are used by the Arm/Thumb interworking code.
|
||||
The address of function to be called is loaded into a register and then
|
||||
one of these labels is called via a BL instruction. This puts the
|
||||
return address into the link register with the bottom bit set, and the
|
||||
code here switches to the correct mode before executing the function. */
|
||||
|
||||
.text
|
||||
.align 0
|
||||
|
||||
.globl SYM (_call_via_r0)
|
||||
.thumb_func
|
||||
SYM (_call_via_r0):
|
||||
bx r0
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_r1)
|
||||
.thumb_func
|
||||
SYM (_call_via_r1):
|
||||
bx r1
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_r2)
|
||||
.thumb_func
|
||||
SYM (_call_via_r2):
|
||||
bx r2
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_r3)
|
||||
.thumb_func
|
||||
SYM (_call_via_r3):
|
||||
bx r3
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_r4)
|
||||
.thumb_func
|
||||
SYM (_call_via_r4):
|
||||
bx r4
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_r5)
|
||||
.thumb_func
|
||||
SYM (_call_via_r5):
|
||||
bx r5
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_r6)
|
||||
.thumb_func
|
||||
SYM (_call_via_r6):
|
||||
bx r6
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_r7)
|
||||
.thumb_func
|
||||
SYM (_call_via_r7):
|
||||
bx r7
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_r8)
|
||||
.thumb_func
|
||||
SYM (_call_via_r8):
|
||||
bx r8
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_r9)
|
||||
.thumb_func
|
||||
SYM (_call_via_r9):
|
||||
bx r9
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_sl)
|
||||
.thumb_func
|
||||
SYM (_call_via_sl):
|
||||
bx sl
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_fp)
|
||||
.thumb_func
|
||||
SYM (_call_via_fp):
|
||||
bx fp
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_ip)
|
||||
.thumb_func
|
||||
SYM (_call_via_ip):
|
||||
bx ip
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_sp)
|
||||
.thumb_func
|
||||
SYM (_call_via_sp):
|
||||
bx sp
|
||||
nop
|
||||
|
||||
.globl SYM (_call_via_lr)
|
||||
.thumb_func
|
||||
SYM (_call_via_lr):
|
||||
bx lr
|
||||
nop
|
||||
|
||||
#endif /* L_call_via_rX */
|
32
gcc/config/arm/t-thumb
Normal file
32
gcc/config/arm/t-thumb
Normal file
@ -0,0 +1,32 @@
|
||||
CROSS_LIBGCC1 = libgcc1-asm.a
|
||||
LIB1ASMSRC = arm/lib1thumb.asm
|
||||
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _call_via_rX
|
||||
# adddi3/subdi3 added to machine description
|
||||
#LIB1ASMFUNCS = _adddi3 _subdi3 _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls
|
||||
|
||||
# These are really part of libgcc1, but this will cause them to be
|
||||
# built correctly, so...
|
||||
|
||||
LIB2FUNCS_EXTRA = fp-bit.c dp-bit.c
|
||||
|
||||
fp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#define FLOAT' > fp-bit.c
|
||||
echo '#ifndef __ARMEB__' >> fp-bit.c
|
||||
echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
|
||||
echo '#endif' >> fp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
|
||||
|
||||
dp-bit.c: $(srcdir)/config/fp-bit.c
|
||||
echo '#ifndef __ARMEB__' > dp-bit.c
|
||||
echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
|
||||
echo '#define FLOAT_WORD_ORDER_MISMATCH' >> dp-bit.c
|
||||
echo '#endif' >> dp-bit.c
|
||||
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
|
||||
|
||||
# Avoid building a duplicate set of libraries for the default endian-ness.
|
||||
MULTILIB_OPTIONS = mlittle-endian/mbig-endian mno-thumb-interwork/mthumb-interwork
|
||||
MULTILIB_DIRNAMES = le be normal interwork
|
||||
MULTILIB_MATCHES = mbig-endian=mbe mlittle-endian=mle
|
||||
|
||||
LIBGCC = stmp-multilib
|
||||
INSTALL_LIBGCC = install-multilib
|
192
gcc/config/arm/tcoff.h
Normal file
192
gcc/config/arm/tcoff.h
Normal file
@ -0,0 +1,192 @@
|
||||
/* Definitions of target machine for GNU compiler,
|
||||
for Thumb with COFF obj format.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Derived from arm/coff.h originally by Doug Evans (dje@cygnus.com).
|
||||
|
||||
This file is part of GNU CC.
|
||||
|
||||
GNU CC 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 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU CC 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU CC; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "arm/thumb.h"
|
||||
|
||||
/* Run-time Target Specification. */
|
||||
#undef TARGET_VERSION
|
||||
#define TARGET_VERSION fputs (" (Thumb/coff)", stderr)
|
||||
|
||||
#define MULTILIB_DEFAULTS { "mlittle-endian" }
|
||||
|
||||
/* Setting this to 32 produces more efficient code, but the value set in previous
|
||||
versions of this toolchain was 8, which produces more compact structures. The
|
||||
command line option -mstructure_size_boundary=<n> can be used to change this
|
||||
value. */
|
||||
#undef STRUCTURE_SIZE_BOUNDARY
|
||||
#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
|
||||
|
||||
extern int arm_structure_size_boundary;
|
||||
|
||||
/* This is COFF, but prefer stabs. */
|
||||
#define SDB_DEBUGGING_INFO
|
||||
|
||||
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
|
||||
|
||||
#include "dbxcoff.h"
|
||||
|
||||
/* Note - it is important that these definitions match those in semi.h for the ARM port. */
|
||||
#undef LOCAL_LABEL_PREFIX
|
||||
#define LOCAL_LABEL_PREFIX "."
|
||||
|
||||
#undef USER_LABEL_PREFIX
|
||||
#define USER_LABEL_PREFIX "_"
|
||||
|
||||
/* A C statement to output assembler commands which will identify the
|
||||
object file as having been compiled with GNU CC (or another GNU
|
||||
compiler). */
|
||||
#define ASM_IDENTIFY_GCC(STREAM) \
|
||||
fprintf (STREAM, "%sgcc2_compiled.:\n", LOCAL_LABEL_PREFIX )
|
||||
|
||||
#undef ASM_FILE_START
|
||||
#define ASM_FILE_START(STREAM) \
|
||||
do { \
|
||||
extern char *version_string; \
|
||||
fprintf ((STREAM), "%s Generated by gcc %s for Thumb/coff\n", \
|
||||
ASM_COMMENT_START, version_string); \
|
||||
fprintf ((STREAM), ASM_APP_OFF); \
|
||||
} while (0)
|
||||
|
||||
/* A C statement to output something to the assembler file to switch to section
|
||||
NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
|
||||
NULL_TREE. Some target formats do not support arbitrary sections. Do not
|
||||
define this macro in such cases. */
|
||||
#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
|
||||
do { \
|
||||
if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \
|
||||
fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \
|
||||
else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \
|
||||
fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \
|
||||
else \
|
||||
fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \
|
||||
} while (0)
|
||||
|
||||
/* Support the ctors/dtors and other sections. */
|
||||
|
||||
#undef INIT_SECTION_ASM_OP
|
||||
|
||||
/* Define this macro if jump tables (for `tablejump' insns) should be
|
||||
output in the text section, along with the assembler instructions.
|
||||
Otherwise, the readonly data section is used. */
|
||||
#define JUMP_TABLES_IN_TEXT_SECTION
|
||||
|
||||
#undef READONLY_DATA_SECTION
|
||||
#define READONLY_DATA_SECTION rdata_section
|
||||
#undef RDATA_SECTION_ASM_OP
|
||||
#define RDATA_SECTION_ASM_OP "\t.section .rdata"
|
||||
|
||||
#undef CTORS_SECTION_ASM_OP
|
||||
#define CTORS_SECTION_ASM_OP "\t.section .ctors,\"x\""
|
||||
#undef DTORS_SECTION_ASM_OP
|
||||
#define DTORS_SECTION_ASM_OP "\t.section .dtors,\"x\""
|
||||
|
||||
/* A list of other sections which the compiler might be "in" at any
|
||||
given time. */
|
||||
|
||||
#undef EXTRA_SECTIONS
|
||||
#define EXTRA_SECTIONS SUBTARGET_EXTRA_SECTIONS in_rdata, in_ctors, in_dtors
|
||||
|
||||
#define SUBTARGET_EXTRA_SECTIONS
|
||||
|
||||
/* A list of extra section function definitions. */
|
||||
|
||||
#undef EXTRA_SECTION_FUNCTIONS
|
||||
#define EXTRA_SECTION_FUNCTIONS \
|
||||
RDATA_SECTION_FUNCTION \
|
||||
CTORS_SECTION_FUNCTION \
|
||||
DTORS_SECTION_FUNCTION \
|
||||
SUBTARGET_EXTRA_SECTION_FUNCTIONS
|
||||
|
||||
#define SUBTARGET_EXTRA_SECTION_FUNCTIONS
|
||||
|
||||
#define RDATA_SECTION_FUNCTION \
|
||||
void \
|
||||
rdata_section () \
|
||||
{ \
|
||||
if (in_section != in_rdata) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "%s\n", RDATA_SECTION_ASM_OP); \
|
||||
in_section = in_rdata; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CTORS_SECTION_FUNCTION \
|
||||
void \
|
||||
ctors_section () \
|
||||
{ \
|
||||
if (in_section != in_ctors) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \
|
||||
in_section = in_ctors; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DTORS_SECTION_FUNCTION \
|
||||
void \
|
||||
dtors_section () \
|
||||
{ \
|
||||
if (in_section != in_dtors) \
|
||||
{ \
|
||||
fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
|
||||
in_section = in_dtors; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Support the ctors/dtors sections for g++. */
|
||||
|
||||
#define INT_ASM_OP ".word"
|
||||
|
||||
/* A C statement (sans semicolon) to output an element in the table of
|
||||
global constructors. */
|
||||
#undef ASM_OUTPUT_CONSTRUCTOR
|
||||
#define ASM_OUTPUT_CONSTRUCTOR(STREAM,NAME) \
|
||||
do { \
|
||||
ctors_section (); \
|
||||
fprintf (STREAM, "\t%s\t ", INT_ASM_OP); \
|
||||
assemble_name (STREAM, NAME); \
|
||||
fprintf (STREAM, "\n"); \
|
||||
} while (0)
|
||||
|
||||
/* A C statement (sans semicolon) to output an element in the table of
|
||||
global destructors. */
|
||||
#undef ASM_OUTPUT_DESTRUCTOR
|
||||
#define ASM_OUTPUT_DESTRUCTOR(STREAM,NAME) \
|
||||
do { \
|
||||
dtors_section (); \
|
||||
fprintf (STREAM, "\t%s\t ", INT_ASM_OP); \
|
||||
assemble_name (STREAM, NAME); \
|
||||
fprintf (STREAM, "\n"); \
|
||||
} while (0)
|
||||
|
||||
/* __CTOR_LIST__ and __DTOR_LIST__ must be defined by the linker script. */
|
||||
#define CTOR_LISTS_DEFINED_EXTERNALLY
|
||||
|
||||
#undef DO_GLOBAL_CTORS_BODY
|
||||
#undef DO_GLOBAL_DTORS_BODY
|
||||
|
||||
/* The ARM development system has atexit and doesn't have _exit,
|
||||
so define this for now. */
|
||||
#define HAVE_ATEXIT
|
||||
|
||||
/* The ARM development system defines __main. */
|
||||
#define NAME__MAIN "__gccmain"
|
||||
#define SYMBOL__MAIN __gccmain
|
1965
gcc/config/arm/thumb.c
Normal file
1965
gcc/config/arm/thumb.c
Normal file
File diff suppressed because it is too large
Load Diff
1102
gcc/config/arm/thumb.h
Normal file
1102
gcc/config/arm/thumb.h
Normal file
File diff suppressed because it is too large
Load Diff
1144
gcc/config/arm/thumb.md
Normal file
1144
gcc/config/arm/thumb.md
Normal file
File diff suppressed because it is too large
Load Diff
10
gcc/configure
vendored
10
gcc/configure
vendored
@ -4168,6 +4168,13 @@ for machine in $build $host $target; do
|
||||
# ;;
|
||||
# tahoe-*-bsd*) # tahoe running BSD
|
||||
# ;;
|
||||
thumb-*-coff* | thumbel-*-coff*)
|
||||
tm_file=arm/tcoff.h
|
||||
out_file=arm/thumb.c
|
||||
xm_file=arm/xm-thumb.h
|
||||
md_file=arm/thumb.md
|
||||
tmake_file=arm/t-thumb
|
||||
;;
|
||||
# This hasn't been upgraded to GCC 2.
|
||||
# tron-*-*)
|
||||
# cpu_type=gmicro
|
||||
@ -4445,7 +4452,8 @@ then extra_headers=; fi
|
||||
if [ x"$xm_file" = x ]
|
||||
then xm_file=$cpu_type/xm-$cpu_type.h; fi
|
||||
|
||||
md_file=$cpu_type/$cpu_type.md
|
||||
if [ x$md_file = x ]
|
||||
then md_file=$cpu_type/$cpu_type.md; fi
|
||||
|
||||
if [ x$out_file = x ]
|
||||
then out_file=$cpu_type/$cpu_type.c; fi
|
||||
|
@ -2485,6 +2485,13 @@ for machine in $build $host $target; do
|
||||
# ;;
|
||||
# tahoe-*-bsd*) # tahoe running BSD
|
||||
# ;;
|
||||
thumb-*-coff* | thumbel-*-coff*)
|
||||
tm_file=arm/tcoff.h
|
||||
out_file=arm/thumb.c
|
||||
xm_file=arm/xm-thumb.h
|
||||
md_file=arm/thumb.md
|
||||
tmake_file=arm/t-thumb
|
||||
;;
|
||||
# This hasn't been upgraded to GCC 2.
|
||||
# tron-*-*)
|
||||
# cpu_type=gmicro
|
||||
@ -2762,7 +2769,8 @@ then extra_headers=; fi
|
||||
if [[ x"$xm_file" = x ]]
|
||||
then xm_file=$cpu_type/xm-$cpu_type.h; fi
|
||||
|
||||
md_file=$cpu_type/$cpu_type.md
|
||||
if [[ x$md_file = x ]]
|
||||
then md_file=$cpu_type/$cpu_type.md; fi
|
||||
|
||||
if [[ x$out_file = x ]]
|
||||
then out_file=$cpu_type/$cpu_type.c; fi
|
||||
|
Loading…
Reference in New Issue
Block a user