FS#6734 by me: optionally build with -mthumb on ARM

You'll need a libgcc build with interworking enabled (our eabi gcc works)
Confirmed to work on Sansa AMS
Confirmed to boot on Gigabeat S
Not working on PP, linker generates invalid branches when mixing
ARM->thumb switches and long calls

Build time will be about 50% longer, because the gcc wrapper script
tries to build everything with -mthumb and falls back to default if it
fails (for example if the file uses inline ARM-only assembly)

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26760 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Rafaël Carré 2010-06-11 05:37:37 +00:00
parent e3263b70c3
commit 675dcd1a9c
2 changed files with 93 additions and 1 deletions

14
tools/configure vendored
View file

@ -369,7 +369,7 @@ whichadvanced () {
interact=1
echo ""
echo "Enter your developer options (press enter when done)"
printf "(D)EBUG, (L)ogf, Boot(c)hart, (S)imulator, (P)rofiling, (V)oice, (W)in32 crosscompile, (T)est plugins"
printf "(D)EBUG, (L)ogf, Boot(c)hart, (S)imulator, (P)rofiling, (V)oice, (W)in32 crosscompile, (T)est plugins, T(H)umb"
if [ "$memory" = "2" ]; then
printf ", (8)MB MOD"
fi
@ -414,6 +414,10 @@ whichadvanced () {
echo "Including test plugins"
extradefines="$extradefines -DHAVE_TEST_PLUGINS"
;;
[Hh])
echo "Building with thumb"
config_thumb="#define USE_THUMB"
;;
[Cc])
echo "bootchart enabled (logf also enabled)"
bootchart="yes"
@ -2923,6 +2927,10 @@ DLLTOOL=`findtool ${DLLTOOL} --lit`
DLLWRAP=`findtool ${DLLWRAP} --lit`
RANLIB=`findtool ${RANLIB} --lit`
if test -n "$config_thumb"; then
CC="$toolsdir/thumb-cc.py $CC"
fi
if test -n "$ccache"; then
CC="$ccache $CC"
fi
@ -2948,6 +2956,7 @@ sed > autoconf.h \
-e "s,@have_backlight@,$have_backlight,g" \
-e "s,@have_fmradio_in@,$have_fmradio_in,g" \
-e "s,@have_ata_poweroff@,$have_ata_poweroff,g" \
-e "s,@config_thumb@,$config_thumb,g" \
<<EOF
/* This header was made by configure */
#ifndef __BUILD_AUTOCONF_H
@ -2971,6 +2980,9 @@ sed > autoconf.h \
/* optional define for ATA poweroff on Player */
@have_ata_poweroff@
/* optional define for ARM thumb builds */
@config_thumb@
/* optional defines for RTC mod for h1x0 */
@config_rtc@
@have_rtc_alarm@

80
tools/thumb-cc.py Executable file
View file

@ -0,0 +1,80 @@
#!/usr/bin/python
# -*- coding: utf8 -*-
# __________ __ ___.
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/
#
# Copyright © 2010 Rafaël Carré <rafael.carre@gmail>
#
# This program 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
# of the License, or (at your option) any later version.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
import sys
import os
import subprocess
import tempfile
def run_gcc(args):
os.execv(args[0], args) # run real gcc
def get_output(args):
output = False
for i in args:
if output == True:
return i
elif i == '-o':
output = True
def try_thumb(args, output):
thumb_args = args + ['-mthumb']
thumb_args[thumb_args.index('-o') + 1] = output
thumb_gcc = subprocess.Popen(thumb_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = thumb_gcc.communicate()
if thumb_gcc.returncode != 0: # building failed
return False
# building with thumb succeeded, show our output
#sys.stderr.write(bytes.decode(stderr))
#sys.stdout.write(bytes.decode(stdout))
sys.stderr.write(stderr)
sys.stdout.write(stdout)
return True
##### main
args=sys.argv[1:] # remove script path
for opt in ['-E', '-MM', '-v', '--version']:
if opt in args:
run_gcc(args)
output = get_output(args)
split = output.rsplit('.o', 1)
if len(split) == 1: # output doesn't end in .o
run_gcc(args)
dirname = os.path.dirname(output)
thumb_output = tempfile.mktemp(suffix='.o', prefix=split[0], dir=dirname)
args.append('-mthumb-interwork')
if try_thumb(args, thumb_output):
os.rename(thumb_output, output)
sys.exit(0)
else:
#sys.stderr.write('skipped ' + os.path.basename(output) + '\n')
run_gcc(args)