On Wed, 12 Mar 2014, Janne Grunau wrote:
On 2014-03-12 13:24:42 +0200, Martin Storsjö wrote:
This syntax is supported by the official arm tools and
by Microsoft's assembler.
This currently only supports microsoft's assembler, the
armasm assembler in RVCT requires a few more tweaks to
be able to build libav.
The preprocessing is done by invoking cpp (do we need to
be able to override this?).
The converted output is written to a file instead of using
a pipe, since Microsoft's armasm can't read the input from
a pipe.
Does the name still makes sense? I guess it preprocesses
modern gas asm files so that other assemblers can use them.
I guess it still makes sense, I don't have any better suggestions,
especially not that would be worth the hassle of changing.
If anyone has a good idea how the support for different
target assemblers could be made more modular without requiring
all the ifs scattered through the source it would be welcome.
It might possibly be simplified a little by moving the directive
reformatting/commenting out to the final stage of the preprocessing (so
that most of it deals with the original gas syntax), and adding a bunch of
flags for which parts of the conversion machinery to enable - so we don't
need to check for e.g. aarch64 || armasm, but only check whether .req
alias expansion should be done. I haven't thought it through to the end
though how much could be gained by this.
I looked only lightly at the armasm specific parts, looks ok-ish
aside from my comments below.
Janne
---
gas-preprocessor.pl | 274 ++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 245 insertions(+), 29 deletions(-)
diff --git a/gas-preprocessor.pl b/gas-preprocessor.pl
index a8f119a..50b5de9 100755
--- a/gas-preprocessor.pl
+++ b/gas-preprocessor.pl
@@ -40,7 +40,7 @@ command. Following options are currently supported:
-help - this usage text
-arch - target architecture
- -as-type - one value out of {,apple-}{gas,clang}
+ -as-type - one value out of {{,apple-}{gas,clang},armasm}
-fix-unreq
-no-fix-unreq
";
@@ -79,7 +79,7 @@ while (@options) {
die "unkown arch: '$arch'\n" if not exists $comments{$arch};
} elsif ($opt eq "-as-type") {
$as_type = shift @options;
- die "unkown as type: '$as_type'\n" if $as_type !~
/^(apple-)?(gas|clang)$/;
+ die "unkown as type: '$as_type'\n" if $as_type !~
/^((apple-)?(gas|clang)|armasm)$/;
} elsif ($opt eq "-help") {
usage();
exit 0;
@@ -103,6 +103,25 @@ if (grep /\.c$/, @gcc_cmd) {
} else {
die "Unrecognized input filetype";
}
+if ($as_type eq "armasm") {
+
+ $preprocess_c_cmd[0] = "cpp";
+
+ @preprocess_c_cmd = grep ! /^-nologo$/, @preprocess_c_cmd;
+ # Remove -ignore XX parameter pairs from preprocess_c_cmd
+ my $index = 1;
+ while ($index < $#preprocess_c_cmd) {
+ if ($preprocess_c_cmd[$index] eq "-ignore" and $index + 1 <
$#preprocess_c_cmd) {
+ splice(@preprocess_c_cmd, $index, 2);
+ next;
+ }
+ $index++;
+ }
+ if (grep /^-MM$/, @preprocess_c_cmd) {
+ system(@preprocess_c_cmd) == 0 or die "Error running preprocessor";
+ exit 0;
+ }
+}
# if compiling, avoid creating an output file named '-.o'
if ((grep /^-c$/, @gcc_cmd) && !(grep /^-o/, @gcc_cmd)) {
@@ -116,8 +135,27 @@ if ((grep /^-c$/, @gcc_cmd) && !(grep /^-o/, @gcc_cmd)) {
}
}
}
-@gcc_cmd = map { /\.[csS]$/ ? qw(-x assembler -) : $_ } @gcc_cmd;
@preprocess_c_cmd = map { /\.o$/ ? "-" : $_ } @preprocess_c_cmd;
+my $tempfile;
+if ($as_type ne "armasm") {
+ @gcc_cmd = map { /\.[csS]$/ ? qw(-x assembler -) : $_ } @gcc_cmd;
+} else {
+ @preprocess_c_cmd = grep ! /^-c$/, @preprocess_c_cmd;
+ @preprocess_c_cmd = grep ! /^-m/, @preprocess_c_cmd;
+
+ my @outfiles = grep /\.o$/, @gcc_cmd;
+ $tempfile = $outfiles[0].".asm";
+
+ # Remove most parameters from gcc_cmd, which actually is the armasm
command,
+ # which doesn't support any of the common compiler/preprocessor options.
+ @gcc_cmd = grep ! /^-D/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-U/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-m/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-M/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-c$/, @gcc_cmd;
+ @gcc_cmd = grep ! /^-I/, @gcc_cmd;
+ @gcc_cmd = map { /\.S$/ ? $tempfile : $_ } @gcc_cmd;
+}
# detect architecture from gcc binary name
if (!$arch) {
@@ -167,23 +205,53 @@ my %symbols;
while (<ASMFILE>) {
# remove all comments (to avoid interfering with evaluating directives)
s/(?<!\\)$comm.*//x;
+ # Strip out windows linefeeds
+ s/\r$//;
+ # Strip out line number comments - armasm can handle them in a separate
+ # syntax, but since the line numbers are off they are only misleading.
+ s/^#\s+(\d+).*// if $as_type =~ /armasm/;
# comment out unsupported directives
- s/\.type/$comm$&/x if $as_type =~ /^apple-/;
+ s/\.type/$comm$&/x if $as_type =~ /^(apple-|armasm)/;
s/\.func/$comm$&/x if $as_type =~ /^(apple-|clang)/;
s/\.endfunc/$comm$&/x if $as_type =~ /^(apple-|clang)/;
- s/\.ltorg/$comm$&/x if $as_type =~ /^(apple-|clang)/;
- s/\.size/$comm$&/x if $as_type =~ /^apple-/;
- s/\.fpu/$comm$&/x if $as_type =~ /^apple-/;
- s/\.arch/$comm$&/x if $as_type =~ /^(apple-|clang)/;
- s/\.object_arch/$comm$&/x if $as_type =~ /^apple-/;
-
- # the syntax for these is a little different
- s/\.global/.globl/x if $as_type =~ /apple-/;
- # also catch .section .rodata since the equivalent to .const_data is
.section __DATA,__const
- s/(.*)\.rodata/.const_data/x if $as_type =~ /apple-/;
- s/\.int/.long/x;
- s/\.float/.single/x;
+ s/\.endfunc/ENDP/x if $as_type =~ /armasm/;
+ s/\.ltorg/$comm$&/x if $as_type =~ /^(apple-|clang|armasm)/;
+ s/\.size/$comm$&/x if $as_type =~ /^(apple-|armasm)/;
+ s/\.fpu/$comm$&/x if $as_type =~ /^(apple-|armasm)/;
+ s/\.arch/$comm$&/x if $as_type =~ /^(apple-|clang|armasm)/;
+ s/\.object_arch/$comm$&/x if $as_type =~ /^(apple-|armasm)/;
+
+ s/\.syntax/$comm$&/x if $as_type =~ /armasm/;
+ s/\.thumb/THUMB/x if $as_type =~ /armasm/;
+ s/\.arm/ARM/x if $as_type =~ /armasm/;
we use .arm|.thumb in the 2nd pass to set $thumb and that is not
modified, does thumb work with armasm?
Yes, thumb works just fine there. In fact, with windows phone (and WinRT I
guess as well) one is supposed to build everything in thumb mode, afaik
the linker is missing some feature to have mixing of arm and thumb working
properly. (Their compiler only produces thumb, and if linking in arm
routines it occasionally works and occasionally fails.)
You're right that we miss to set $thumb = 1 for these cases though - the
only thing that flag is used for is for adding the .thumb_func stuff
(which shouldn't be used on armasm anyway), and for changing add into
add.w for large immediates (which doesn't seem to be necessary).
What's your preferred way of solving this? Moving the directive
reformatting from .thumb to THUMB etc (including all the other directive
reformatting) to a stage later than the one that checks for .thumb/.code
16 would probably be a quite big refactoring. The dirty way is changing
that check into looking for ARM/THUMB for armasm, but that's not too
nice...
Also if you have ideas how the as_type based commenting could be
improved. I wasn't really happy with it when I wrote it.
You mean how the ... if $as_type =~ are added at the end of the line? This
solution kinda acceptable I think, the alternative would be to have it
grouped up in larger if clauses for the different backends.
+ # armasm uses a different comment character. We don't want to change
+ # $comm originally since that matches what the input source uses.
+ s/$comm/;/ if $as_type =~ /armasm/;
+
+ if ($as_type ne "armasm") {
I think this could be $as_type =~ /apple-/, no need to replace .int and .float
with modern gas and upstream clang, I didn't made them conditional since both
support .long/.single too
Right, I'll fix that.
+ # the syntax for these is a little different
+ s/\.global/.globl/x if $as_type =~ /apple-/;
+ # also catch .section .rodata since the equivalent to .const_data is
.section __DATA,__const
+ s/(.*)\.rodata/.const_data/x if $as_type =~ /apple-/;
+ s/\.int/.long/x;
+ s/\.float/.single/x;
+ } else {
+ s/\.global/EXPORT/x;
+ s/\.int/dcd/x;
+ s/\.long/dcd/x;
+ s/\.float/dcfs/x;
+ s/\.word/dcd/x;
+ s/\.short/dcw/x;
+ s/\.byte/dcb/x;
+ # The alignment in AREA is the power of two, just as .align in gas
+ s/\.text/AREA |.text|, CODE, READONLY, ALIGN=2, CODEALIGN/;
+ s/(.*)\.rodata/AREA |.rodata|, DATA, READONLY, ALIGN=5/;
+
+ s/fmxr/vmsr/;
+ s/fmrx/vmrs/;
+ s/fadds/vadd/;
+ }
# catch unknown section names that aren't mach-o style (with a comma)
if ($as_type =~ /apple-/ and /.section ([^,]*)$/) {
@@ -327,7 +395,9 @@ sub handle_set {
my $line = $_[0];
if ($line =~ /\.set\s+(.*),\s*(.*)/) {
$symbols{$1} = eval_expr($2);
+ return 1;
}
+ return 0;
}
sub expand_macros {
@@ -450,7 +520,11 @@ close(ASMFILE) or exit 1;
if ($ENV{GASPP_DEBUG}) {
open(ASMFILE, ">&STDOUT");
} else {
- open(ASMFILE, "|-", @gcc_cmd) or die "Error running assembler";
+ if ($as_type ne "armasm") {
+ open(ASMFILE, "|-", @gcc_cmd) or die "Error running assembler";
+ } else {
+ open(ASMFILE, ">", $tempfile);
+ }
}
my @sections;
@@ -466,6 +540,7 @@ my $thumb = 0;
my %thumb_labels;
my %call_targets;
+my %mov32_targets;
my @irp_args;
my $irp_param;
@@ -473,6 +548,12 @@ my $irp_param;
my %neon_alias_reg;
my %neon_alias_type;
+my $temp_label_next = 0;
+my %last_temp_labels;
+my %next_temp_labels;
+
+my %labels_seen;
+
my %aarch64_req_alias;
# pass 2: parse .rept and .if variants
@@ -492,7 +573,7 @@ foreach my $line (@pass1_lines) {
$thumb = 0 if $line =~ /\.code\s+32|\.arm/;
# handle ldr <reg>, =<expr>
- if ($line =~ /(.*)\s*ldr([\w\s\d]+)\s*,\s*=(.*)/) {
+ if ($line =~ /(.*)\s*ldr([\w\s\d]+)\s*,\s*=(.*)/ and $as_type ne "armasm")
{
my $label = $literal_labels{$3};
if (!$label) {
$label = "Literal_$literal_num";
@@ -500,7 +581,7 @@ foreach my $line (@pass1_lines) {
$literal_labels{$3} = $label;
}
$line = "$1 ldr$2, $label\n";
- } elsif ($line =~ /\.ltorg/) {
+ } elsif ($line =~ /\.ltorg/ and $as_type ne "armasm") {
$line .= ".align 2\n";
foreach my $literal (keys %literal_labels) {
$line .= "$literal_labels{$literal}:\n $literal_expr $literal\n";
@@ -533,7 +614,7 @@ foreach my $line (@pass1_lines) {
}
if ($line =~ /^\s*((\w+\s*:\s*)?bl?x?(..)?(?:\.w)?|\.globl)\s+(\w+)/ and
- $as_type ne "gas") {
+ $as_type !~ "gas|armasm") {
this also excludes apple-gas
Thanks for noting it, will fix
// Martin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel