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

Reply via email to