On Mon, 17 Mar 2014, Janne Grunau wrote:
On 2014-03-17 10:56:49 +0200, Martin Storsjö wrote:
This does some rudimentary conversions of instructions that aren't
available in thumb mode.
This allows building OpenH264 for Windows Phone 8 (and Windows RT),
which only supports thumb mode, and the OpenH264 arm assembly is
hardcoded for arm mode.
This is similar to how libvpx supports assembling in thumb mode - the
source itself is arm mode only, but a perl script can replace
instruction combinations that aren't supported in thumb mode. This
is a small subset of those conversions.
---
gas-preprocessor.pl | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/gas-preprocessor.pl b/gas-preprocessor.pl
index 3d1049b..bbc5ff4 100755
--- a/gas-preprocessor.pl
+++ b/gas-preprocessor.pl
@@ -27,6 +27,7 @@ my $arch;
my $as_type = "apple-gas";
my $fix_unreq = $^O eq "darwin";
+my $force_thumb = 0;
my $usage_str = "
$0\n
@@ -43,6 +44,7 @@ command. Following options are currently supported:
-as-type - one value out of {{,apple-}{gas,clang},armasm}
-fix-unreq
-no-fix-unreq
+ -force-thumb - assemble as thumb regardless of the input source
a warning that it is incomplete will probably only work for sources
it was tested with might be appropriate although nobody will read it.
Sure, will add something like that.
";
sub usage() {
@@ -74,6 +76,8 @@ while (@options) {
my $opt = shift @options;
if ($opt =~ /^-(no-)?fix-unreq$/) {
$fix_unreq = $1 ne "no-";
+ } elsif ($opt eq "-force-thumb") {
+ $force_thumb = 1;
} elsif ($opt eq "-arch") {
$arch = shift @options;
die "unknown arch: '$arch'\n" if not exists $comments{$arch};
@@ -213,6 +217,15 @@ my @ifstack;
my %symbols;
+if ($force_thumb) {
+ # This doesn't go through the initial parsing loop below
+ if ($as_type eq "armasm") {
+ parse_line("THUMB\n");
+ } else {
+ parse_line(".thumb\n");
+ }
+}
+
# 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
@@ -883,6 +896,24 @@ sub handle_serialized_line {
$line =~ s/&0x/& 0x/g;
}
+ if ($force_thumb) {
+ # Convert register post indexing to a separate add instruction.
+ # This converts "ldrneb r9, [r0], r2" into "ldrneb r9, [r0]",
+ # "add r0, r2".
+ $line =~
s/^(\s*)((ldr|str)(ne)?[bhd]?)(\s+)(\w+),(\s*\w+,)?\s*\[(\w+)\],\s*(\w+)/$1$2$5$6,$7
[$8]\n$1add$4$5$8, $8, $9/g;
You're removing the condition.
Oh, actually it's just the comment that is off - the regexp does the right
thing. $4 should be the condition subexpression, and that's suffixed after
the add instruction. Will fix anyway.
If openh264 is open to patches it would probably a good idea to convert
it to unified assembler syntax which has the condition codes at the end.
They're quite open to patches, but they are actually already using unified
syntax.
I copied this regexp over straight from libvpx (which doesn't use the
unified syntax) - in openh264 none of these occurrances use condition
codes at all (nor do they use the bhd suffixes either, it's all plain
str/ldr instructions). For the record, you can see the full set of
conversions they use in
https://chromium.googlesource.com/webm/libvpx/+/master/build/make/thumb.pm.
For openh264 I just needed this one (and a few other ones that I didn't
run into in libvpx).
This would be as function more readable considering that it might need
to be extended. Missing are condition codes, the sign extending
byte/half-word loads/stores and '!'
You mean moving all of these thumb fixups to a separate function, or how
should I make it more readable?
I don't think we need to handle the '!' variants since those are allowed
as such in thumb anyway, or am I missing something? It's only the case
with post-incrementing with a register that needs to be handled.
+
+ # Convert "mov pc, lr" into "bx lr", since the former only works
+ # for switching from arm to thumb (and only in armv7), but not
+ # from thumb to arm.
+ s/mov(\s*)pc\s*,\s*lr/bx$1lr/g;
+
+ # Convert stmdb/ldmia with only one register into a plain str/ldr with
post-increment/decrement
+ $line =~ s/^(\s*)stmdb(\s+)sp!\s*,\s*\{([^,-]+)\}/$1str$2$3, [sp,
#-4]!/g;
+ $line =~ s/^(\s*)ldmia(\s+)sp!\s*,\s*\{([^,-]+)\}/$1ldr$2$3, [sp],
#4/g;
+
+ $line =~ s/\.arm/.thumb/x;
+ }
does openh264 use no conditional instructions or does armasm insert the
appropriate 'it' instructions automatically?
armasm adds the appropriate 'it' instructions automatically (and warns
about it). For the --enable-thumb case in libvpx (enabling the same
conversions but building with normal gas for linux, where I wrote most of
this logic originally, as a stepping stone before trying to bring all of
it into armasm) it requires building with -mimplicit-it=always though.
// Martin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel