OSDN Git Service

マルチプロジェクト型にレポジトリを変更するために移動した
[toppersasp4lpc/asp.git] / asp / utils / genoffset
1 #! /usr/bin/perl
2 #
3 #  TOPPERS Software
4 #      Toyohashi Open Platform for Embedded Real-Time Systems
5
6 #  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 #                              Toyohashi Univ. of Technology, JAPAN
8 #  Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
9 #              Graduate School of Information Science, Nagoya Univ., JAPAN
10
11 #  上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
12 #  ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 #  変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 #  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 #      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 #      スコード中に含まれていること.
17 #  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 #      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 #      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 #      の無保証規定を掲載すること.
21 #  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 #      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23 #      と.
24 #    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 #        作権表示,この利用条件および下記の無保証規定を掲載すること.
26 #    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27 #        報告すること.
28 #  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 #      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 #      また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 #      由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32 #      免責すること.
33
34 #  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 #  よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 #  に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 #  アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38 #  の責任を負わない.
39
40 #  @(#) $Id: genoffset 1840 2010-07-10 17:29:42Z ertl-hiro $
41
42
43 #
44 #  初期化
45 #
46 $infile = $ARGV[0];
47 $sil_endian = "";
48
49 #
50 #  解釈できるディレクティブのテーブル
51 #
52 %directives = (
53         "long", "",
54         "dword", "",
55         "word", "",
56         "hword", "",
57         "int", "",
58         "short", "",
59         "half", "",
60         "byte", "",
61         "value", "",
62         "uaword", "",
63         "uashort", "",
64         "data32", 4,
65         "data16", 2,
66         "data8", 1,
67         "zero", -1,
68         "space", -1,
69         "globl", 0,
70         "global", 0,
71         "align", 0,
72         "p2align", 0,
73         "even", 0,
74         "data", 0,
75         "stabs", 0,
76         "type", 0,
77         "size", 0,
78         "section", 0,
79         "sdata", 0,
80         "code", 0,
81 );
82
83 #
84 #  オフセット値の出力
85 #
86 sub parse_offset {
87         my($label, $val) = @_;
88
89         printf "#define %s\t%d\n",$label,$val;
90 }
91
92 #
93 #  ディレクティブの読み取り
94 #
95 sub ref_bit {
96         my($size) = @_;
97         my($dir, $directive);
98
99         while ($line = <INFILE>) {
100                 chomp $line;
101                 next if ($line =~ /^[ \t]*[#;].*$/);
102
103                 if ($line =~ /[ \t]*\.([a-zA-Z0-9]+)[ \t]*([^ \t]*)[ \t]*/
104                                                 && defined($dir = $directives{$1})) {
105                         $directive = $1;
106                         if ($dir eq "") {
107                                 # 登録すべきディレクティブ
108                                 $directives{$directive} = $size;
109                         }
110                         last;
111                 }
112                 else {
113                         # 解析できない行
114                         print STDERR "genoffset: cannot parse: $line\n";
115                         $error = 1;
116                 }
117         }
118 }
119
120 #
121 #  ビットサーチ
122 #
123 sub search_bit {
124         my($val) = @_;
125         my($val_bit);
126
127         return(-1) if ($val == 0);
128
129         $val_bit = 0;
130         while (($val & 1) == 0) {
131                 $val >>= 1;
132                 $val_bit++;
133         }
134         return($val_bit);
135 }
136
137 #
138 #  ビット位置の出力
139 #
140 sub parse_bit {
141         my($endian, $size, $label) = @_;
142         my($offset, $dir, $val, $val_bit);
143
144         if ($sil_endian && $endian ne $sil_endian) {
145                 # エンディアンの不一致
146                 print STDERR "genoffset: endian mismatch: $line\n";
147                 $error = 1;
148         }
149
150         $offset = 0;
151         while ($line = <INFILE>) {
152                 chomp $line;
153                 next if ($line =~ /^[ \t]*[#;].*$/);
154
155                 if ($line =~ /[ \t]*\.([a-zA-Z0-9]+)[ \t]*([^ \t]*)[ \t]*/
156                                                 && defined($dir = $directives{$1})) {
157                         $val = $2;
158
159                         # 16進数と8進数の数値への変換処理
160                         if ($val =~ /^0x(.+)$/) {
161                                 $val = hex($1);
162                         }
163                         elsif ($val =~ /^0(.+)$/) {
164                                 $val = oct($1);
165                         }
166
167                         if ($dir eq "") {
168                                 # サイズを知らないディレクティブ
169                                 print STDERR "genoffset: unknown directive: $line\n";
170                                 $error = 1;
171                         }
172                         elsif ($dir == 0) {
173                                 # 読み飛ばすべきディレクティブ
174                         }
175                         elsif ($dir == -1) {
176                                 # .zeroディレクティブの処理
177                                 $offset += $val;
178                         }
179                         elsif ($val == 0) {
180                                 # 値が0のフィールドの処理
181                                 $offset += $dir;
182                         }
183                         else {
184                                 # 値が0でないフィールドが見つかればループを終了
185                                 last;
186                         }
187                 }
188                 else {
189                         # 解析できない行
190                         print STDERR "genoffset: cannot parse: $line\n";
191                         $error = 1;
192                 }
193         }
194
195         # ビット位置を探す
196         $val_bit = do search_bit($val);
197
198         # バイト単位に換算する
199         if ($endian eq "B") {
200                 $offset += $dir - 1;
201                 $offset -= $val_bit >> 3;
202         }
203         else {
204                 $offset += $val_bit >> 3;
205         }
206         $val_bit &= 0x07;
207
208         # 出力単位に換算する
209         if ($size eq "W") {
210                 if ($endian eq "B") {
211                         $val_bit += 24;
212                         $val_bit -= ($offset & 0x03) << 3;
213                 }
214                 else {
215                         $val_bit += ($offset & 0x03) << 3;
216                 }
217                 $offset &= ~0x03;
218         }
219         elsif ($size eq "H") {
220                 if ($endian eq "B") {
221                         $val_bit += 8;
222                         $val_bit -= ($offset & 0x01) << 3;
223                 }
224                 else {
225                         $val_bit += ($offset & 0x01) << 3;
226                 }
227                 $offset &= ~0x01;
228         }
229
230         # 定義の出力
231         $label =~ s/^_//;
232         printf "#define %s\t%d\n",$label,$offset;
233         printf "#define %s_bit\t%d\n",$label,$val_bit;
234         printf "#define %s_mask\t0x%x\n",$label,(1 << $val_bit);
235 }
236
237 #
238 #  メインルーチン
239 #
240 print "/* This file is generated by genoffset. */\n";
241 print "\n";
242
243 $error = 0;
244 open(INFILE, $infile) || die "Cannot open $infile";
245 while ($line = <INFILE>) {
246         chomp $line;
247
248         if ($line =~ /^[ \t]*OFFSET_DEF ([^ \t]+) = [#\$]?([^ \t]+)/) {
249                 do parse_offset($1, $2);
250         }
251         elsif ($line =~ /^[ \t]*_?BIT_REF_([0-9]+):/) {
252                 do ref_bit($1);
253         }
254         elsif ($line =~ /^[ \t]*_?BIT_([BL])([BHW])_([^ \t]+):/) {
255                 do parse_bit($1, $2, $3);
256         }
257         elsif ($line =~ /^[ \t]*SIL_ENDIAN = ([BL])/) {
258                 $sil_endian = $1;
259         }
260 }
261 close(INFILE);
262 exit($error);