]>
Commit | Line | Data |
---|---|---|
2c5d4daa AP |
1 | #!/usr/bin/env perl |
2 | ||
3 | # PowerPC assembler distiller by <appro>. | |
4 | ||
5 | my $output = shift; | |
6 | open STDOUT,">$output" || die "can't open $output: $!"; | |
7 | ||
8 | my $flavour = $output; | |
9 | my %GLOBALS; | |
10 | my $dotinlocallabels=0; | |
11 | ||
12 | ################################################################ | |
13 | # directives which need special treatment on different platforms | |
14 | ################################################################ | |
15 | my $globl = sub { | |
16 | my $junk = shift; | |
17 | my $name = shift; | |
18 | my $global = \$GLOBALS{$name}; | |
19 | my $ret; | |
20 | ||
21 | $name =~ s|^[\.\_]||; | |
22 | ||
23 | SWITCH: for ($flavour) { | |
24 | /aix/ && do { $name = ".$name"; | |
25 | last; | |
26 | }; | |
27 | /osx/ && do { $name = "_$name"; | |
28 | last; | |
29 | }; | |
30 | /linux.*32/ && do { $ret .= ".globl $name\n"; | |
31 | $ret .= ".type $name,\@function"; | |
32 | $dotinlocallabels = 1; | |
33 | last; | |
34 | }; | |
35 | /linux.*64/ && do { $ret .= ".globl .$name\n"; | |
36 | $ret .= ".type .$name,\@function\n"; | |
37 | $ret .= ".section \".opd\",\"aw\"\n"; | |
38 | $ret .= ".globl $name\n"; | |
39 | $ret .= ".align 3\n"; | |
40 | $ret .= "$name:\n"; | |
41 | $ret .= ".quad .$name,.TOC.\@tocbase,0\n"; | |
42 | $ret .= ".size $name,24\n"; | |
43 | $ret .= ".previous\n"; | |
44 | ||
45 | $name = ".$name"; | |
46 | $dotinlocallabels = 1; | |
47 | last; | |
48 | }; | |
49 | } | |
50 | ||
51 | $ret = ".globl $name" if (!$ret); | |
52 | $$global = $name; | |
53 | $ret; | |
54 | }; | |
fe716ba6 AP |
55 | my $text = sub { |
56 | ($flavour =~ /aix/) ? ".csect" : ".text"; | |
57 | }; | |
2c5d4daa AP |
58 | my $machine = sub { |
59 | my $junk = shift; | |
60 | my $arch = shift; | |
c09a0318 AP |
61 | if ($arch eq "any" and $flavour =~ /osx/) |
62 | { $arch = ($flavour =~ /64/) ? "ppc970-64" : "ppc970"; } | |
2c5d4daa AP |
63 | ".machine $arch"; |
64 | }; | |
65 | ||
66 | ################################################################ | |
67 | # simplified mnemonics not handled by at least one assembler | |
68 | ################################################################ | |
69 | my $cmplw = sub { | |
70 | my $f = shift; | |
71 | my $cr = 0; $cr = shift if ($#_>1); | |
72 | " cmpl$f ".join(',',$cr,0,@_); | |
73 | }; | |
74 | my $cmpld = sub { | |
75 | my $f = shift; | |
76 | my $cr = 0; $cr = shift if ($#_>1); | |
77 | " cmpl$f ".join(',',$cr,1,@_); | |
78 | }; | |
79 | my $bdnz = sub { | |
80 | my $f = shift; | |
81 | my $bo = $f=~/[\+\-]/ ? 17 : 16; | |
82 | " bc $bo,0,".shift; | |
83 | }; | |
84 | ||
85 | while($line=<>) { | |
86 | ||
87 | $line =~ s|[#!;].*$||; # get rid of asm-style comments... | |
88 | $line =~ s|/\*.*\*/||; # ... and C-style comments... | |
89 | $line =~ s|^\s+||; # ... and skip white spaces in beginning... | |
90 | $line =~ s|\s+$||; # ... and at the end | |
91 | ||
92 | { | |
93 | $line =~ s|\b\.L(\w+)|L$1|g; # common denominator for Locallabel | |
94 | $line =~ s|\bL(\w+)|\.L$1|g if ($dotinlocallabels); | |
95 | } | |
96 | ||
97 | { | |
98 | $line =~ s|(^[\.\w]+)\:\s*||; | |
99 | my $label = $1; | |
100 | printf "%s:",($GLOBALS{$label} or $label) if ($label); | |
101 | } | |
102 | ||
103 | { | |
104 | $line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||; | |
105 | my $c = $1; $c = "\t" if ($c eq ""); | |
106 | my $mnemonic = $2; | |
107 | my $f = $3; | |
108 | my $opcode = eval("\$$mnemonic"); | |
fe716ba6 | 109 | $line =~ s|\br([0-9]+)\b|$1|g if ($c ne "." and $flavour !~ /osx/); |
2c5d4daa AP |
110 | if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); } |
111 | elsif ($mnemonic) { $line = $c.$mnemonic.$f."\t".$line; } | |
112 | } | |
113 | ||
114 | print $line if ($line); | |
115 | print "\n"; | |
116 | } | |
117 | ||
118 | close STDOUT; |