Commit 04996dfb authored by David Conrad's avatar David Conrad Committed by Fiona Glaser

iPhone compilation support

Also add --sysroot to configure options

To build for iPhone 3gs / iPod touch 3g:
CC=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc ./configure --host=arm-apple-darwin --sysroot=/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk

For older devices, add
--extra-cflags='-arch armv6 -mcpu=arm1176jzf-s' --extra-ldflags='-arch armv6' --disable-asm
parent b46cec4f
......@@ -20,6 +20,12 @@
#include "config.h"
#ifdef PREFIX
# define EXTERN_ASM _
#else
# define EXTERN_ASM
#endif
#ifdef __ELF__
# define ELF
#else
......@@ -35,7 +41,8 @@ ELF .eabi_attribute 25, \val
.endm
.macro function name
.global \name
.global EXTERN_ASM\name
EXTERN_ASM\name:
ELF .hidden \name
ELF .type \name, %function
.func \name
......
......@@ -110,16 +110,17 @@ SAD4_ARMV6 8
.macro SAD_FUNC w, h, name, align:vararg
function x264_pixel_sad\name\()_\w\()x\h\()_neon
SAD_START_\w \align
.if \w == 16
.set r, \h / 2 - 1
.rept \h / 2 - 1
SAD_\w \align
.endr
.else
.set r, \h - 1
.endif
SAD_START_\w \align
.rept r
.rept \h - 1
SAD_\w \align
.endr
.endif
.if \w > 8
vabal.u8 q8, d4, d6
......
......@@ -23,6 +23,7 @@ echo " --extra-cflags=ECFLAGS add ECFLAGS to CFLAGS"
echo " --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS"
echo " --host=HOST build programs to run on HOST"
echo " --cross-prefix=PREFIX use PREFIX for compilation tools"
echo " --sysroot=SYSROOT root of cross-build tree"
echo ""
exit 1
fi
......@@ -223,6 +224,10 @@ for opt do
--cross-prefix=*)
cross_prefix="${opt#--cross-prefix=}"
;;
--sysroot=*)
CFLAGS="$CFLAGS --sysroot=${opt#--sysroot=}"
LDFLAGS="$LDFLAGS --sysroot=${opt#--sysroot=}"
;;
*)
echo "Unknown option $opt, ignored"
;;
......@@ -367,7 +372,17 @@ case $host_cpu in
;;
arm*)
ARCH="ARM"
AS="${AS-${cross_prefix}gcc}"
if [ "$SYS" = MACOSX ] ; then
AS="${AS-extras/gas-preprocessor.pl $CC}"
ASFLAGS="$ASFLAGS -DPREFIX -DPIC" # apple's ld doesn't support movw/movt relocations at all
# build for armv7 by default
if ! echo $CFLAGS | grep -Eq '\-arch' ; then
CFLAGS="$CFLAGS -arch armv7"
LDFLAGS="$LDFLAGS -arch armv7"
fi
else
AS="${AS-${cross_prefix}gcc}"
fi
;;
s390|s390x)
ARCH="S390"
......
#!/usr/bin/env perl
# by David Conrad
# This code is licensed under GPLv2 or later; go to gnu.org to read it
# (not that it much matters for an asm preprocessor)
# usage: set your assembler to be something like "perl gas-preprocessor.pl gcc"
use strict;
# Apple's gas is ancient and doesn't support modern preprocessing features like
# .rept and has ugly macro syntax, among other things. Thus, this script
# implements the subset of the gas preprocessor used by x264 and ffmpeg
# that isn't supported by Apple's gas.
# FIXME: doesn't work if the path has spaces, but oh well...
my $gcc_cmd = join(' ', @ARGV);
my $preprocess_c_cmd;
if ($gcc_cmd =~ /\S+\.c/) {
# C file (inline asm?) - compile
$preprocess_c_cmd = "$gcc_cmd -S";
$gcc_cmd =~ s/\S+\.c/-x assembler -/g;
} elsif ($gcc_cmd =~ /\S+\.S/) {
# asm file, just do C preprocessor
$preprocess_c_cmd = "$gcc_cmd -E";
$gcc_cmd =~ s/\S+\.S/-x assembler -/g;
} else {
die "Unrecognized input filetype";
}
$preprocess_c_cmd =~ s/\S+\.o/-/g;
open(ASMFILE, "-|", $preprocess_c_cmd) || die "Error running preprocessor";
my $current_macro = '';
my %macro_lines;
my %macro_args;
my %macro_args_default;
my @pass1_lines;
# pass 1: parse .macro
# note that the handling of arguments is probably overly permissive vs. gas
# but it should be the same for valid cases
while (<ASMFILE>) {
# comment out unsupported directives
s/\.type/@.type/x;
s/\.func/@.func/x;
s/\.endfunc/@.endfunc/x;
s/\.ltorg/@.ltorg/x;
s/\.size/@.size/x;
s/\.fpu/@.fpu/x;
# the syntax for these is a little different
s/\.global/.globl/x;
# also catch .section .rodata since the equivalent to .const_data is .section __DATA,__const
s/(.*)\.rodata/.const_data/x;
s/\.int/.long/x;
s/\.float/.single/x;
# catch unknown section names that aren't mach-o style (with a comma)
if (/.section ([^,]*)$/) {
die ".section $1 unsupported; figure out the mach-o section name and add it";
}
# macros creating macros is not handled (is that valid?)
if (/\.macro\s+([\d\w\.]+)\s*(.*)/) {
$current_macro = $1;
# commas in the argument list are optional, so only use whitespace as the separator
my $arglist = $2;
$arglist =~ s/,/ /g;
my @args = split(/\s+/, $arglist);
foreach my $i (0 .. $#args) {
my @argpair = split(/=/, $args[$i]);
$macro_args{$current_macro}[$i] = $argpair[0];
$argpair[0] =~ s/:vararg$//;
$macro_args_default{$current_macro}{$argpair[0]} = $argpair[1];
}
# ensure %macro_lines has the macro name added as a key
$macro_lines{$current_macro} = [];
} elsif (/\.endm/) {
if (!$current_macro) {
die "ERROR: .endm without .macro";
}
$current_macro = '';
} elsif ($current_macro) {
push(@{$macro_lines{$current_macro}}, $_);
} else {
expand_macros($_);
}
}
sub expand_macros {
my $line = @_[0];
if ($line =~ /(\S+:|)\s*([\w\d\.]+)\s*(.*)/ && exists $macro_lines{$2}) {
push(@pass1_lines, $1);
my $macro = $2;
# commas are optional here too, but are syntactically important because
# parameters can be blank
my @arglist = split(/,/, $3);
my @args;
foreach (@arglist) {
my @whitespace_split = split(/\s+/, $_);
if (!@whitespace_split) {
push(@args, '');
} else {
foreach (@whitespace_split) {
if (length($_)) {
push(@args, $_);
}
}
}
}
my %replacements;
if ($macro_args_default{$macro}){
%replacements = %{$macro_args_default{$macro}};
}
# construct hashtable of text to replace
foreach my $i (0 .. $#args) {
my $argname = $macro_args{$macro}[$i];
if ($args[$i] =~ m/=/) {
# arg=val references the argument name
# XXX: I'm not sure what the expected behaviour if a lot of
# these are mixed with unnamed args
my @named_arg = split(/=/, $args[$i]);
$replacements{$named_arg[0]} = $named_arg[1];
} elsif ($i > $#{$macro_args{$macro}}) {
# more args given than the macro has named args
# XXX: is vararg allowed on arguments before the last?
$argname = $macro_args{$macro}[-1];
if ($argname =~ s/:vararg$//) {
$replacements{$argname} .= ", $args[$i]";
} else {
die "Too many arguments to macro $macro";
}
} else {
$argname =~ s/:vararg$//;
$replacements{$argname} = $args[$i];
}
}
# apply replacements as regex
foreach (@{$macro_lines{$macro}}) {
my $macro_line = $_;
# do replacements by longest first, this avoids wrong replacement
# when argument names are subsets of each other
foreach (reverse sort {length $a <=> length $b} keys %replacements) {
$macro_line =~ s/\\$_/$replacements{$_}/g;
}
$macro_line =~ s/\\\(\)//g; # remove \()
expand_macros($macro_line);
}
} else {
push(@pass1_lines, $line);
}
}
close(ASMFILE) or exit 1;
open(ASMFILE, "|-", $gcc_cmd) or die "Error running assembler";
my @sections;
my $num_repts;
my $rept_lines;
my %literal_labels; # for ldr <reg>, =<expr>
my $literal_num = 0;
# pass 2: parse .rept and .if variants
# NOTE: since we don't implement a proper parser, using .rept with a
# variable assigned from .set is not supported
foreach my $line (@pass1_lines) {
# textual comparison .if
# this assumes nothing else on the same line
if ($line =~ /\.ifnb\s+(.*)/) {
if ($1) {
$line = ".if 1\n";
} else {
$line = ".if 0\n";
}
} elsif ($line =~ /\.ifb\s+(.*)/) {
if ($1) {
$line = ".if 0\n";
} else {
$line = ".if 1\n";
}
} elsif ($line =~ /\.ifc\s+(.*)\s*,\s*(.*)/) {
if ($1 eq $2) {
$line = ".if 1\n";
} else {
$line = ".if 0\n";
}
}
# handle .previous (only with regard to .section not .subsection)
if ($line =~ /\.(section|text|const_data)/) {
push(@sections, $line);
} elsif ($line =~ /\.previous/) {
if (!$sections[-2]) {
die ".previous without a previous section";
}
$line = $sections[-2];
push(@sections, $line);
}
# handle ldr <reg>, =<expr>
if ($line =~ /(.*)\s*ldr([\w\s\d]+)\s*,\s*=(.*)/) {
my $label = $literal_labels{$3};
if (!$label) {
$label = ".Literal_$literal_num";
$literal_num++;
$literal_labels{$3} = $label;
}
$line = "$1 ldr$2, $label\n";
} elsif ($line =~ /\.ltorg/) {
foreach my $literal (keys %literal_labels) {
$line .= "$literal_labels{$literal}:\n .word $literal\n";
}
%literal_labels = ();
}
# @l -> lo16() @ha -> ha16()
$line =~ s/,\s+([^,]+)\@l(\s)/, lo16($1)$2/g;
$line =~ s/,\s+([^,]+)\@ha(\s)/, ha16($1)$2/g;
if ($line =~ /\.rept\s+(.*)/) {
$num_repts = $1;
$rept_lines = "\n";
# handle the possibility of repeating another directive on the same line
# .endr on the same line is not valid, I don't know if a non-directive is
if ($num_repts =~ s/(\.\w+.*)//) {
$rept_lines .= "$1\n";
}
$num_repts = eval($num_repts);
} elsif ($line =~ /\.endr/) {
for (1 .. $num_repts) {
print ASMFILE $rept_lines;
}
$rept_lines = '';
} elsif ($rept_lines) {
$rept_lines .= $line;
} else {
print ASMFILE $line;
}
}
print ASMFILE ".text\n";
foreach my $literal (keys %literal_labels) {
print ASMFILE "$literal_labels{$literal}:\n .word $literal\n";
}
close(ASMFILE) or exit 1;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment