|
|
1.1 root 1: #! /usr/local/bin/perl -w
2:
3: # m68k-opmap-make.pl - compiles the complete decoding of all legal
4: # first-instruction-word values into the opcode map used by the C
5: # decoder:
6:
7: # $Id: m68k-opmap-make.pl,v 1.3 2003/04/23 19:20:30 fredette Exp $
8:
9: # globals:
10: $0 =~ /^(.*\/)?([^\/]+)$/; $PROG = $2;
11: $debug = 0;
12:
13: # to silence -w:
14: undef($value);
15:
16: # emit our header:
17: print <<"EOF;";
18: /* generated automatically by $PROG, do not edit! */
19:
20: /* includes: */
21: #include "m68k-impl.h"
22: EOF;
23:
24: # we begin with no submaps and no opcode maps:
25: $submap_next = 0;
26: $opcode_map_next = 0;
27: %opcode_maps = ();
28:
29: # assuming an ILP32 machine, various sizeofs:
30: $sizeof_opcode = 12;
31: $sizeof_submap = 64 * 24;
32:
33: # loop over standard input:
34: for ($line = 1; defined($_ = <STDIN>); $line++) {
35: chomp;
36:
37: # break the line into tokens:
38: @tokens = split(' ', $_);
39:
40: # if this is the beginning of a new CPU:
41: if ($tokens[0] eq "cpu-begin") {
42: $cpu_name = $tokens[1];
43:
44: # initialize for this CPU:
45: print STDERR "$PROG: initializing for $cpu_name...";
46:
47: # initialize the full map:
48: undef(@map_line);
49: for ($pattern = 65536; $pattern-- > 0;) {
50: $map_op0[$pattern] = "U";
51: $map_op1[$pattern] = "U";
52: $map_eax_size[$pattern] = "U";
53: $map_eax_cycles[$pattern] = "U";
54: $map_imm_operand[$pattern] = "U";
55: $map_imm_size[$pattern] = "U";
56: $map_eay_size[$pattern] = "U";
57: $map_eay_cycles[$pattern] = "U";
58: }
59:
60: # initialize the special operations:
61: undef(%specop);
62:
63: # we're done initializing and we're now reading patterns:
64: $patterns = 0;
65: print STDERR " done\n$PROG: reading $cpu_name patterns...";
66: }
67:
68: # if this is a special-operation line:
69: elsif ($tokens[0] eq "specop") {
70: shift(@tokens);
71: $specop = shift(@tokens);
72: foreach (@tokens) {
73: $specop{$_} = $specop;
74: }
75: }
76:
77: # if this is a pattern:
78: elsif ($tokens[0] =~ /^[01]/) {
79:
80: # the first token is the pattern. die if this pattern has already
81: # appeared:
82: $pattern = oct("0b".shift(@tokens));
83: die "stdin:$line: duplicate pattern of line $map_line[$pattern]\n"
84: if (defined($map_line[$pattern]));
85: $map_line[$pattern] = $line;
86:
87: # fill this map entry:
88: foreach $token (@tokens) {
89: ($what, $value) = split(/=/, $token, 2);
90: eval("\$map_".$what."[$pattern] = \$value;");
91: }
92: die "stdin:$line: no function given\n"
93: if (!defined($map_func[$pattern]));
94: $patterns++;
95: }
96:
97: # if this is the end of a CPU:
98: elsif ($tokens[0] eq "cpu-end") {
99: $cpu_name = $tokens[1];
100:
101: # note how many patterns we read:
102: print STDERR " read $patterns $cpu_name patterns\n";
103:
104: # sanity-check the information read in, and force all unused
105: # full map entries to illegal:
106: print STDERR "$PROG: finding unused $cpu_name patterns...";
107: $unused = 0;
108: for ($pattern = 65536; $pattern-- > 0;) {
109:
110: # if this is an unused map entry:
111: if (!defined($map_line[$pattern])) {
112: $map_func[$pattern] = "illegal";
113: $unused++;
114: next;
115: }
116:
117: # since the overwhelming majority of instructions use at
118: # most one effective address path (the eax path), only the
119: # size of the eax path operand is stored in the opcode
120: # maps. any instruction that uses the eay path must do so
121: # with the same size as the eax path:
122: if ($map_eay_size[$pattern] ne "U") {
123:
124: # if this instruction isn't using the eax path, switch
125: # to using the eax path instead. the only instruction
126: # allowed to do this is move.S. temporarily rewrite
127: # this function to a special function "movenonmemtomem":
128: if ($map_eax_size[$pattern] eq "U") {
129: die "$PROG: pattern ".sprintf("%b", $pattern)." ($map_func[$pattern]) uses the eay path\n"
130: if ($map_func[$pattern] !~ /^(move)(\d+)$/);
131: $map_func[$pattern] = $1."nonmemtomem".$2;
132: $map_eax_size[$pattern] = $map_eay_size[$pattern];
133: $map_eax_cycles[$pattern] = $map_eay_cycles[$pattern];
134: $map_op0[$pattern] =~ s/^memy/memx/;
135: $map_op1[$pattern] =~ s/^memy/memx/;
136: }
137:
138: # otherwise, this instruction is using both ea paths.
139: # the only instruction allowed to do this is move.S.
140: # temporarily rewrite this function to a special
141: # function "movememtomem":
142: else {
143: die "$PROG: pattern ".sprintf("%b", $pattern)." ($map_func[$pattern]) uses both ea paths\n"
144: if ($map_func[$pattern] !~ /^(move)(\d+)$/);
145: $map_func[$pattern] = $1."memtomem".$2;
146: die "$PROG: pattern ".sprintf("%b", $pattern)." ($map_func[$pattern]) uses both ea paths at different sizes\n"
147: if ($map_eay_size[$pattern] ne $map_eax_size[$pattern]);
148: die "$PROG: pattern ".sprintf("%b", $pattern)." ($map_func[$pattern]) doesn't use eay write-only\n"
149: if ($map_eay_cycles[$pattern] ne "wo");
150: }
151: }
152: }
153: print STDERR " found $unused unused $cpu_name patterns\n";
154:
155: # loop over the root patterns to come up with the root map
156: # entry, the submap key and the functions list for each:
157: print STDERR "$PROG: making $cpu_name root map entries and submap keys...";
158: for ($root = 0; $root < 1024; $root++) {
159:
160: # get counts of the different map entry attribute values.
161: # the most popular attribute values will get stored in the
162: # root map entry, while the others will get set in submap
163: # entries:
164: #
165: undef(%count_func);
166: undef(%count_op0);
167: undef(%count_op1);
168: undef(%count_eax_size);
169: undef(%count_imm);
170: for ($sub = 0, $pattern = $root << 6; $sub < 64 ; $sub++, $pattern++) {
171:
172: # the decoder specially cancels all attributes other
173: # than "function" when the function is "illegal", so
174: # don't count any of its attribute values.
175: #
176: # otherwise, function, specop, and EA cycles go
177: # together, and immediate operand and immediate size
178: # go together:
179: #
180: $func = $map_func[$pattern];
181: if ($func ne "illegal") {
182: $specop = "un" if (!defined($specop = $specop{$func}));
183: $func .= ".$specop";
184: if ($map_eax_size[$pattern] eq "U") {
185: # a pattern that doesn't use the EA path can have
186: # any value for its opcode map entry cycles:
187: die "$PROG: pattern ".sprintf("%b", $pattern)." ($func) doesn't use the EA path but needs $map_eax_cycles[$pattern] cycles?\n"
188: if ($map_eax_cycles[$pattern] ne "U");
189: $func .= ".any";
190: }
191: elsif ($map_eax_size[$pattern] eq "UNSIZED") {
192: # a pattern that uses the raw effective address
193: # must have UNDEF for its opcode map entry cycles:
194: die "$PROG: pattern ".sprintf("%b", $pattern)." ($func) takes the raw EA path but needs $map_eax_cycles[$pattern] cycles?\n"
195: if ($map_eax_cycles[$pattern] ne "U");
196: $func .= ".un";
197: }
198: else {
199: # otherwise, this pattern must have its specified
200: # value for its opcode map entry cycles:
201: die "$PROG: pattern ".sprintf("%b", $pattern)." ($func) uses the EA path at size $map_eax_size[$pattern] but needs $map_eax_cycles[$pattern] cycles?\n"
202: if ($map_eax_cycles[$pattern] eq "U"
203: || $map_eax_cycles[$pattern] eq "un");
204: $func .= ".".$map_eax_cycles[$pattern];
205: }
206: $map_func[$pattern] = $func;
207: $count_op0{$map_op0[$pattern]}++;
208: $count_op1{$map_op1[$pattern]}++;
209: $count_eax_size{$map_eax_size[$pattern]}++;
210: $count_imm{$map_imm_operand[$pattern].".".$map_imm_size[$pattern]}++;
211: }
212: $count_func{$func}++;
213: }
214:
215: # a pattern that doesn't use the EA path can use the same
216: # opcode map entry as a pattern that has the same function
217: # but does use the EA path, because the former pattern
218: # will have UNDEF for its eax size, which makes the cycles
219: # member of the opcode map entry a don't care:
220: #
221: @funcs = (keys(%count_func));
222: %funcs_rewrite = ();
223: foreach $func (@funcs) {
224: @parts = split(/\./, $func);
225: if (@parts == 3
226: && $parts[2] ne "any") {
227: $func_rewrite = $parts[0].".".$parts[1].".any";
228: if (defined($count_func{$func_rewrite})) {
229: $count_func{$func} += delete($count_func{$func_rewrite});
230: $funcs_rewrite{$func_rewrite} = $func;
231: }
232: }
233: }
234: for ($sub = 0, $pattern = $root << 6; $sub < 64 ; $sub++, $pattern++) {
235: $map_func[$pattern] = $func
236: if (defined($func = $funcs_rewrite{$map_func[$pattern]}));
237: }
238:
239: # sort the attributes:
240: @funcs = (sort { ($count_func{$b} == $count_func{$a}
241: ? $a cmp $b
242: : $count_func{$b} <=> $count_func{$a}) } keys(%count_func));
243: @op0s = (sort { ($count_op0{$b} == $count_op0{$a}
244: ? $a cmp $b
245: : $count_op0{$b} <=> $count_op0{$a}) } keys(%count_op0));
246: @op1s = (sort { ($count_op1{$b} == $count_op1{$a}
247: ? $a cmp $b
248: : $count_op1{$b} <=> $count_op1{$a}) } keys(%count_op1));
249: @eax_sizes = (sort { ($count_eax_size{$b} == $count_eax_size{$a}
250: ? $a cmp $b
251: : $count_eax_size{$b} <=> $count_eax_size{$a}) } keys(%count_eax_size));
252: @imms = (sort { ($count_imm{$b} == $count_imm{$a}
253: ? $a cmp $b
254: : $count_imm{$b} <=> $count_imm{$a}) } keys(%count_imm));
255:
256: # make sure the attributes have at least undef in them. for
257: # all-illegal roots they would otherwise be empty:
258: push(@op0s, "U"); $count_op0{"U"}++;
259: push(@op1s, "U"); $count_op1{"U"}++;
260: push(@eax_sizes, "U"); $count_eax_size{"U"}++;
261: push(@imms, "U.U"); $count_imm{"U.U"}++;
262:
263: # display the attributes:
264: if (1 && $debug) {
265: print STDERR "root $root:";
266: print STDERR "\n funcs"; foreach (@funcs) { print STDERR " $_ ($count_func{$_})"}
267: print STDERR "\n op0s"; foreach (@op0s) { print STDERR " $_ ($count_op0{$_})"}
268: print STDERR "\n op1s"; foreach (@op1s) { print STDERR " $_ ($count_op1{$_})"}
269: print STDERR "\n eax_sizes"; foreach (@eax_sizes) { print STDERR " $_ ($count_eax_size{$_})"}
270: print STDERR "\n imms"; foreach (@imms) { print STDERR " $_ ($count_imm{$_})"}
271: print STDERR "\n";
272: }
273:
274: # form the submap key. this is a very long string
275: # describing what a submap must do with attributes in
276: # order to be associated with this root. this string is
277: # very long because it lists all attributes for the 64
278: # subs under this root:
279: #
280: # this string really ends up being a regular expression,
281: # and since the decoder specially cancels all attributes
282: # when the function is "illegal", illegal can really take
283: # any attributes, so wildcards are used:
284: #
285: @key = ();
286: for ($sub = 0, $pattern = $root << 6; $sub < 64 ; $sub++, $pattern++) {
287: if ($map_func[$pattern] eq "illegal") {
288: push(@key, '\S+');
289: push(@key, '\S+');
290: push(@key, '\S+');
291: push(@key, '\S+');
292: }
293: else {
294:
295: # the op0 and op1 attributes can be anything for
296: # patterns that don't use them ("U" for
297: # undefined), because even if they are defined in
298: # the submap or root, the instruction decoder does
299: # nothing except pass them to the instruction
300: # functions, which don't care. so they can be
301: # anything in the submap key:
302: $_ = $map_op0[$pattern]; push(@key, ($_ eq "U" ? '\S+' : $_ eq $op0s[0] ? "U" : $_));
303: $_ = $map_op1[$pattern]; push(@key, ($_ eq "U" ? '\S+' : $_ eq $op1s[0] ? "U" : $_));
304:
305: # however, the same is not true for the EA size
306: # and immediate operand attributes. if a pattern
307: # doesn't use these attributes, they *must* be
308: # undefined in the submap, so that any defined
309: # attribute in the root is ignored - otherwise the
310: # instruction decoder will do EA work and fetch
311: # immediates when it isn't supposed to. this
312: # means that we have to introduce a
313: # use-the-root-attribute value for those patterns
314: # that *must* use the root attribute value. we
315: # use "X" to stand for this value:
316: $_ = $map_eax_size[$pattern]; push(@key, ($_ eq $eax_sizes[0] ? "X" : $_));
317: $_ = $map_imm_operand[$pattern].".".$map_imm_size[$pattern]; push(@key, ($_ eq $imms[0] ? "X" : $_));
318: }
319: }
320: $key = join(" ", @key);
321: $root_key[$root] = $key;
322: $root_funcs[$root] = join(",", @funcs);
323: $root_op0[$root] = $op0s[0];
324: $root_op1[$root] = $op1s[0];
325: $root_eax_size[$root] = $eax_sizes[0];
326: $imms[0] =~ /^(.*)\.(.*)$/;
327: $root_imm_operand[$root] = $1;
328: $root_imm_size[$root] = $2;
329: undef($root_submap[$root]);
330: print STDERR " key $key\n" if (0 && $debug);
331: }
332: print STDERR " done\n";
333:
334: # create submaps and opcode maps for the roots:
335: $submaps_new = $submap_next;
336: print STDERR "$PROG: creating $cpu_name submaps...";
337: for ($root = 0; $root < 1024; $root++) {
338:
339: # get the function array and key for this root:
340: @funcs = split(/,/, $root_funcs[$root]);
341: $key = $root_key[$root];
342: print STDERR " root $root key $key\n" if (0 && $debug);
343:
344: # calculate the additional memory cost of creating a new
345: # submap for this root:
346: $submap_best_cost = ($sizeof_submap
347: # our opcode map:
348: + (@funcs * $sizeof_opcode));
349:
350: # check all of the existing submaps for a key match:
351: undef($submap_best);
352: $key =~ s/\./\\\./g;
353: for ($submap = 0; $submap < $submap_next; $submap++) {
354: next unless ($submap_key[$submap] =~ /^$key$/);
355:
356: # get the opcode map indices array, and the size of
357: # the opcode map currently required by this submap:
358: @opcode_map_indices = split(/,/, $submap_opcode_map_indices[$submap]);
359: $opcode_map_size = $submap_opcode_map_size[$submap];
360:
361: # loop over the submap entries, seeing how the submap's opcode
362: # map indices would have to change to accomodate this root:
363: undef(@index_to_func);
364: undef(%func_to_new_index);
365: for ($sub = 0, $pattern = $root << 6; $sub < 64 ; $sub++, $pattern++) {
366: $opcode_map_index = $opcode_map_indices[$sub];
367: $func = $index_to_func[$opcode_map_index];
368: if (!defined($func)) {
369: $index_to_func[$opcode_map_index] = $map_func[$pattern];
370: }
371: elsif ($func ne $map_func[$pattern]) {
372: if (!defined($_ = $func_to_new_index{$map_func[$pattern]})) {
373: $_ = $func_to_new_index{$func} = $opcode_map_size++;
374: $index_to_func[$_] = $func;
375: }
376: $opcode_map_indices[$sub] = $_;
377: }
378: }
379:
380: # a submap for an earlier CPU is off-limits unless we
381: # can use it without growing the opcode map it
382: # requires, since both the submap and the earlier
383: # CPU's opcode maps have already been generated:
384: next if ($submap < $submaps_new
385: && $opcode_map_size > $submap_opcode_map_size[$submap]);
386:
387: # calculate the additional memory cost of reusing this
388: # submap for this root:
389: $submap_cost = 0;
390:
391: # if the exact opcode map we would need doesn't
392: # already exist, we would have to create it:
393: $opcode_map_key = join(" ", @index_to_func);
394: $submap_cost += ($sizeof_opcode
395: * $opcode_map_size)
396: if (!defined($opcode_map{$opcode_map_key}));
397:
398: # if we would grow the size of the opcode map required
399: # by this submap by N entries, that's N more opcodes
400: # for *each* root already using this submap:
401: $submap_cost += ($sizeof_opcode
402: * ($submap_refcnt[$submap]
403: * ($opcode_map_size
404: - $submap_opcode_map_size[$submap])));
405:
406: # if using this submap for this root is still better
407: # than any alternative, remember it and how we may
408: # want to change it:
409: if ($submap_cost < $submap_best_cost) {
410: $submap_best = $submap;
411: $submap_best_cost = $submap_cost;
412: @submap_best_opcode_map_indices = @opcode_map_indices;
413: $submap_best_opcode_map_size = $opcode_map_size;
414: }
415: }
416:
417: # if there is a best existing submap, make changes to it:
418: if (defined($submap_best)) {
419: if ($submap_opcode_map_size[$submap_best] != $submap_best_opcode_map_size) {
420: $submap_opcode_map_indices[$submap_best] = join(",", @submap_best_opcode_map_indices);
421: $submap_opcode_map_size[$submap_best] = $submap_best_opcode_map_size;
422: print STDERR " submap $submap_best now funcs ".join(",", @funcs).", ($opcode_map_size) indices ".join(",", @opcode_map_indices)."\n"
423: if ($debug);
424: }
425: }
426:
427: # otherwise, create a new submap:
428: else {
429:
430: # allocate a new submap number:
431: $submap_best = $submap_next++;
432:
433: # create the hash of function name to opcode map index:
434: undef(%func_to_index);
435: $opcode_map_size = 0;
436: foreach $func (@funcs) {
437: $func_to_index{$func} = $opcode_map_size++;
438: }
439:
440: # now make the list of opcode map indices:
441: @opcode_map_indices = ();
442: for ($sub = 0, $pattern = $root << 6; $sub < 64 ; $sub++, $pattern++) {
443: die "internal error - func $map_func[$pattern] missing from ".join(" ", @funcs)."\n"
444: if (!defined($func_to_index{$map_func[$pattern]}));
445: push(@opcode_map_indices, $func_to_index{$map_func[$pattern]});
446: }
447:
448: # officially add this new submap:
449: $submap_opcode_map_indices[$submap_best] = join(",", @opcode_map_indices);
450: $submap_opcode_map_size[$submap_best] = $opcode_map_size;
451: $submap_key[$submap_best] = $root_key[$root];
452: print STDERR " new submap $submap_best, funcs ".join(",", @funcs).", ($opcode_map_size) indices ".join(",", @opcode_map_indices)."\n"
453: if ($debug);
454: }
455:
456: # note how reference counts have changed:
457: $root_submap[$root] = $submap_best;
458: $submap_refcnt[$submap_best]++;
459: print STDERR " refcnt on submap $submap_best now $submap_refcnt[$submap_best]\n" if ($debug);
460: }
461:
462: # write out any newly created submaps:
463: $submaps = 0;
464: for ($submap = $submaps_new; $submap < $submap_next; $submap++) {
465: next if ($submap_refcnt[$submap] == 0);
466: $submaps++;
467:
468: print <<"EOF;";
469:
470: /* create submap $submap: */
471: static struct _tme_m68k_decoder_submap *
472: _tme_m68k_create_submap$submap(struct tme_m68k *ic)
473: {
474: struct _tme_m68k_decoder_submap *submap, *submap_entry;
475: int entry_i;
476:
477: /* allocate and initialize the submap: */
478: submap = tme_new(struct _tme_m68k_decoder_submap, 64);
479: submap_entry = submap;
480: for (entry_i = 0; entry_i < 64; entry_i++) {
481: submap_entry->_tme_m68k_decoder_submap_gen._tme_m68k_decoder_gen_operand0 = NULL;
482: submap_entry->_tme_m68k_decoder_submap_gen._tme_m68k_decoder_gen_operand1 = NULL;
483: submap_entry->_tme_m68k_decoder_submap_gen._tme_m68k_decoder_gen_eax_size = TME_M68K_SIZE_UNDEF;
484: submap_entry->_tme_m68k_decoder_submap_gen._tme_m68k_decoder_gen_imm_operand = TME_M68K_OPNUM_UNDEF;
485: submap_entry++;
486: }
487:
488: /* fill the submap: */
489: submap_entry = submap;
490: EOF;
491:
492: # get the submap key and opcode map indices and split them up:
493: @key = split(' ', $submap_key[$submap]);
494: @opcode_map_indices = split(/,/, $submap_opcode_map_indices[$submap]);
495:
496: # emit the code to initialize each submap entry:
497: for ($sub = 0; $sub < 64 ; $sub++) {
498: print "\n /* submap $submap sub $sub */\n";
499:
500: # emit op0:
501: $op0 = &operand_final(shift(@key));
502: print " submap_entry->_tme_m68k_decoder_submap_gen._tme_m68k_decoder_gen_operand0 = $op0;\n"
503: if (defined($op0));
504:
505: # emit op1:
506: $op1 = &operand_final(shift(@key));
507: print " submap_entry->_tme_m68k_decoder_submap_gen._tme_m68k_decoder_gen_operand1 = $op1;\n"
508: if (defined($op1));
509:
510: # emit eax_size:
511: $eax_size = shift(@key);
512: $eax_size = "SUBMAP_X" if ($eax_size eq "X");
513: print " submap_entry->_tme_m68k_decoder_submap_gen._tme_m68k_decoder_gen_eax_size = TME_M68K_SIZE_$eax_size;\n"
514: if ($eax_size ne "U" && $eax_size ne '\S+');
515:
516: # emit imm_size and imm_operand:
517: $_ = shift(@key);
518: if ($_ eq "X") {
519: print " submap_entry->_tme_m68k_decoder_submap_gen._tme_m68k_decoder_gen_imm_operand = TME_M68K_OPNUM_SUBMAP_X;\n";
520: }
521: elsif ($_ !~ /^U/ && $_ ne '\S+') {
522: ($imm_operand, $imm_size) = (/^(\S+)\.(\S+)/);
523: $imm_size = "16U8" if ($imm_size eq "8");
524: print " submap_entry->_tme_m68k_decoder_submap_gen._tme_m68k_decoder_gen_imm_operand = $imm_operand;\n";
525: print " submap_entry->_tme_m68k_decoder_submap_gen._tme_m68k_decoder_gen_imm_size = TME_M68K_SIZE_$imm_size;\n";
526: }
527:
528: # emit the opcode map index:
529: print " (submap_entry++)->_tme_m68k_decoder_submap_opcode_map_index = $opcode_map_indices[$sub];\n";
530: }
531:
532: # finish the function:
533: print <<"EOF;";
534:
535: /* done: */
536: return(submap);
537: }
538: EOF;
539: }
540:
541: # for each root, according to the submap used, either use an
542: # existing opcode map or create a new opcode map:
543: $opcode_maps = 0;
544: for ($root = 0; $root < 1024; $root++) {
545:
546: # create the opcode map key:
547: $submap = $root_submap[$root];
548: @opcode_map_indices = split(/,/, $submap_opcode_map_indices[$submap]);
549: $opcode_map_size = $submap_opcode_map_size[$submap];
550: undef(@index_to_func);
551: for ($sub = 0, $pattern = $root << 6; $sub < 64 ; $sub++, $pattern++) {
552: $opcode_map_index = $opcode_map_indices[$sub];
553: $func = $index_to_func[$opcode_map_index];
554: if (!defined($func)) {
555: $index_to_func[$opcode_map_index] = $map_func[$pattern];
556: }
557: elsif ($func ne $map_func[$pattern]) {
558: die "$PROG internal error: opcode map indices broken (root $root, submap $submap, sub $sub index $opcode_map_index needs to be $map_func[$pattern], but it's already $func)\n";
559: }
560: }
561: $opcode_map_key = join(" ", @index_to_func);
562:
563: # if the exact opcode map we need doesn't already exist,
564: # create it:
565: if (!defined($opcode_map = $opcode_maps{$opcode_map_key})) {
566: $opcode_map = $opcode_map_next++;
567: $opcode_maps{$opcode_map_key} = $opcode_map;
568: $opcode_maps++;
569:
570: print "\n";
571: print "/* opcode map for $cpu_name root $root (submap $submap): */\n";
572: print "static const struct _tme_m68k_opcode _tme_m68k_opcode_map${opcode_map}[$opcode_map_size] = {\n";
573: for ($map_i = 0; $map_i < $opcode_map_size; $map_i++) {
574: @parts = split(/\./, $index_to_func[$map_i]);
575: ($func, $specop, $cycles) = @parts;
576: if ($func =~ /^(\S+)(nonmemtomem)(\d+)/
577: || $func =~ /^(\S+)(memtomem)(\d+)/) {
578: $func = $1.$3;
579: $specop = $1.$2;
580: }
581: $specop = "undef"
582: if (!defined($specop)
583: || $specop eq "un");
584: $specop =~ tr/a-z/A-Z/;
585: $specop = "TME_M68K_SPECOP_$specop";
586: if (!defined($cycles)
587: || $cycles eq "un"
588: || $cycles eq "any") {
589: $cycles = "TME_BUS_CYCLE_UNDEF";
590: }
591: elsif ($cycles eq "ro") {
592: $cycles = "TME_BUS_CYCLE_READ";
593: }
594: elsif ($cycles eq "wo") {
595: $cycles = "TME_BUS_CYCLE_WRITE";
596: }
597: elsif ($cycles eq "rw") {
598: $cycles = "TME_BUS_CYCLE_READ|TME_BUS_CYCLE_WRITE";
599: }
600: else {
601: die "$PROG error: bad cycles $cycles\n";
602: }
603: print " { tme_m68k_$func, $specop, $cycles },\n";
604: }
605: print "};\n";
606: }
607: $root_opcode_map[$root] = $opcode_map;
608: }
609: print STDERR " created $submaps new submaps, $opcode_maps new opcode maps\n";
610:
611: # write out the function that creates the root map:
612: print <<"EOF;";
613:
614: /* initializes the ${cpu_name} decoder map: */
615: void
616: _tme_${cpu_name}_decoder_map_init(struct tme_m68k *ic)
617: {
618: struct _tme_m68k_decoder_root *root, *root_entry;
619: int entry_i;
620: EOF;
621:
622: print "\n";
623: print " /* the submaps used by this CPU: */\n";
624: undef(@submap_done);
625: for ($root = 0; $root < 1024; $root++) {
626: $submap = $root_submap[$root];
627: if (!$submap_done[$submap]) {
628: print " struct _tme_m68k_decoder_submap *submap$submap = _tme_m68k_create_submap$submap(ic);\n";
629: $submap_done[$submap] = 1;
630: }
631: }
632:
633: print <<'EOF;';
634:
635: /* allocate and initialize the root map: */
636: root = tme_new(struct _tme_m68k_decoder_root, 1024);
637: ic->_tme_m68k_decoder_root = root;
638: root_entry = root;
639: for (entry_i = 0; entry_i < 1024; entry_i++) {
640: root_entry->_tme_m68k_decoder_root_gen._tme_m68k_decoder_gen_operand0 = NULL;
641: root_entry->_tme_m68k_decoder_root_gen._tme_m68k_decoder_gen_operand1 = NULL;
642: root_entry->_tme_m68k_decoder_root_gen._tme_m68k_decoder_gen_eax_size = TME_M68K_SIZE_UNDEF;
643: root_entry->_tme_m68k_decoder_root_gen._tme_m68k_decoder_gen_imm_operand = TME_M68K_OPNUM_UNDEF;
644: root_entry++;
645: }
646: root_entry = root;
647: EOF;
648:
649: print "\n";
650: print " /* fill the root map: */\n";
651: for ($root = 0; $root < 1024; $root++) {
652: print "\n /* root $root (base opcode ".sprintf("0x%04x", ($root << 6))."): */\n";
653:
654: # emit op0:
655: $op0 = &operand_final($root_op0[$root]);
656: print " root_entry->_tme_m68k_decoder_root_gen._tme_m68k_decoder_gen_operand0 = $op0;\n"
657: if (defined($op0));
658:
659: # emit op1:
660: $op1 = &operand_final($root_op1[$root]);
661: print " root_entry->_tme_m68k_decoder_root_gen._tme_m68k_decoder_gen_operand1 = $op1;\n"
662: if (defined($op1));
663:
664: # emit eax_size:
665: $eax_size = $root_eax_size[$root];
666: print " root_entry->_tme_m68k_decoder_root_gen._tme_m68k_decoder_gen_eax_size = TME_M68K_SIZE_$eax_size;\n"
667: if ($eax_size ne "U");
668:
669: # emit imm_size and imm_operand:
670: $imm_operand = $root_imm_operand[$root];
671: if ($imm_operand ne "U" && $imm_operand ne '\S+') {
672: $imm_size = $root_imm_size[$root];
673: $imm_size = "16U8" if ($imm_size eq "8");
674: print " root_entry->_tme_m68k_decoder_root_gen._tme_m68k_decoder_gen_imm_operand = $imm_operand;\n";
675: print " root_entry->_tme_m68k_decoder_root_gen._tme_m68k_decoder_gen_imm_size = TME_M68K_SIZE_$imm_size;\n";
676: }
677:
678: # emit the submap and opcode map:
679: print " root_entry->_tme_m68k_decoder_root_submap = submap$root_submap[$root];\n";
680: print " (root_entry++)->_tme_m68k_decoder_root_opcode_map = _tme_m68k_opcode_map$root_opcode_map[$root];\n";
681: }
682:
683: # close the function:
684: print "\n}\n";
685: }
686:
687: # anything else is an error:
688: else {
689: print STDERR "stdin:$line $PROG error: don't know how to handle: ".join(" ", @tokens)."\n";
690: exit(1);
691: }
692: }
693:
694: # done:
695: exit(0);
696:
697: # this subroutine returns the final C version of an operand:
698: sub operand_final {
699: local ($op) = @_;
700:
701: if ($op eq "U" || $op eq '\S+') {
702: undef($op);
703: }
704: elsif ($op =~ /^\%([ad][0-7])\.(\d+)/) {
705: ($op, $op_size) = ($1, $2);
706: $op =~ tr/a-z/A-Z/;
707: if ($op_size == 16) {
708: $op .= " << 1";
709: }
710: elsif ($op_size == 8) {
711: $op .= " << 2";
712: }
713: $op = "&ic->tme_m68k_ireg_uint${op_size}(TME_M68K_IREG_${op})";
714: }
715: elsif ($op eq "eax.32") {
716: $op = "&ic->_tme_m68k_ea_address";
717: }
718: elsif ($op =~ /^imm(\d+)\.(\d+)/) {
719: $op = "(tme_uint${2}_t *) &_tme_m68k_imm${2}[${1}]";
720: }
721: elsif ($op =~ /^mem[xy]\.(\d+)/) {
722: $op = "&ic->tme_m68k_ireg_memx${1}";
723: }
724: else {
725: die "$PROG fatal: unknown operand $op\n";
726: }
727: $op;
728: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.