OSDN Git Service

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