[cage] Unbreak the build
[parrot.git] / tools / dev / as2c.pl
blob63dc87df5a700a3e8dc980e07aa54557c8947465
1 #! perl
3 # Copyright (C) 2004-2007, Parrot Foundation.
5 # $Id$
7 =head1 NAME
9 as2c.pl - convert gas assembler listing to i386 code array
11 =head1 DESCRIPTION
13 The plan behind of as2c.pl is to create compiler independent
14 machine code for an architecture. Code in e.g. masm, gas, nasm syntax
15 doesn't fit all compilers. Therefore as2c.pl translates gas syntax to a
16 bytestring, which is then used as the asm code.
18 as2c.pl is used very rarely. Once the code is generated and
19 checked in, there's usually no need to change it later.
21 =cut
23 use strict;
24 use warnings;
26 my $src = $ARGV[0];
27 my $cmd = "cc -c $src.c -Wall -O3 -fomit-frame-pointer -DNDEBUG -Wa,-a > $src.s";
28 my ($func);
30 print_header($src);
31 create_s($cmd);
32 parse_s("$src.s");
33 add_glue("$src.c");
34 print_coda();
36 sub print_header {
37 my $s = shift;
38 print <<EOT;
40 * DO NOT EDIT THIS FILE
42 * Generated from $s.c via $s.s
43 * by '$0 $s'
46 EOT
49 sub print_coda {
50 print <<EOT;
52 * Local variables:
53 * c-file-style: "parrot"
54 * End:
55 * vim: expandtab shiftwidth=4:
57 EOT
60 sub create_s {
61 my $cmd = shift;
62 my $r = system($cmd);
63 if ($r) {
64 die "$cmd failed: $r";
68 sub parse_s {
69 my $s = shift;
70 open my $IN, "<", "$s" or die "Can't read '$s': $1";
71 my ($in_comment);
72 $in_comment = 1;
73 print "/*\n";
74 while (<$IN>) {
75 next if (/^\f/); # FF
76 next if (/#(?:NO_)?APP/); # APP, NO_APP
77 chomp;
78 if (/^\s*\d+\s[\da-fA-F]{4}\s([\dA-F]{2,8})\s+(.*)/) {
79 if ($in_comment) {
80 print " */\n";
82 my ( $bytes, $src ) = ( $1, $2 );
83 $src =~ s/\t/ /g;
84 my $len = length($bytes);
85 my @pairs = ( $bytes =~ m/../g );
86 print " " . join '', map { "0x$_, " } @pairs;
87 print " " x ( 3 * ( 8 - $len ) );
88 print " /* $src */\n";
90 elsif (/\.type\s+(\w+)\s*,\s*\@function/) {
91 $in_comment = 0;
92 $func = $1;
93 print " *\n */\n";
94 print "static const char ${func}_code[] = {\n";
96 elsif (/^\s*\d+\s+(\w+):/) {
97 print " " x 26, " /* $1: */\n";
99 elsif ($in_comment) {
100 s/\s+//g;
101 print " * $_\n";
104 print " 0x00\n";
105 print "};\n";
106 close $IN;
109 sub add_glue {
110 my $s = shift;
111 open $IN, "<", "$s" or die "Can't read '$s': $1";
112 while (<$IN>) {
113 if (/\/\*INTERFACE/) {
114 my $text = "";
115 while (<$IN>) {
116 last if (/INTERFACE\*\//);
117 $text .= $_;
119 $text =~ s/\@FUNC\@/$func/g;
120 $text =~ s!\@\*!/*!g;
121 $text =~ s!\*\@!*/!g;
122 print $text;
125 close $IN;
128 # Local Variables:
129 # mode: cperl
130 # cperl-indent-level: 4
131 # fill-column: 100
132 # End:
133 # vim: expandtab shiftwidth=4: