1 /* This file is part of the program psim.
3 Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 static insn_word_entry
*
30 parse_insn_word (line_ref
*line
,
35 insn_word_entry
*word
= ZALLOC (insn_word_entry
);
37 /* create a leading sentinal */
38 word
->first
= ZALLOC (insn_field_entry
);
39 word
->first
->first
= -1;
40 word
->first
->last
= -1;
41 word
->first
->width
= 0;
43 /* and a trailing sentinal */
44 word
->last
= ZALLOC (insn_field_entry
);
45 word
->last
->first
= options
.insn_bit_size
;
46 word
->last
->last
= options
.insn_bit_size
;
47 word
->last
->width
= 0;
49 /* link them together */
50 word
->first
->next
= word
->last
;
51 word
->last
->prev
= word
->first
;
53 /* now work through the formats */
54 chp
= skip_spaces (string
);
56 while (*chp
!= '\0') {
61 insn_field_entry
*new_field
;
63 /* create / link in the new field */
64 new_field
= ZALLOC (insn_field_entry
);
65 new_field
->next
= word
->last
;
66 new_field
->prev
= word
->last
->prev
;
67 new_field
->next
->prev
= new_field
;
68 new_field
->prev
->next
= new_field
;
69 new_field
->word_nr
= word_nr
;
71 /* break out the first field (if present) */
73 chp
= skip_to_separator (chp
, ".,!");
74 strlen_pos
= back_spaces (start_pos
, chp
) - start_pos
;
76 /* break out the second field (if present) */
79 /* assume what was specified was the value (and not the start
80 position). Assume the value length implicitly specifies
82 start_val
= start_pos
;
83 strlen_val
= strlen_pos
;
90 chp
= skip_spaces (chp
);
92 if (*chp
== '/' || *chp
== '*')
98 while (*chp
== '/' || *chp
== '*');
100 else if (isalpha(*start_val
))
106 while (isalnum(*chp
) || *chp
== '_');
108 else if (isdigit(*start_val
))
113 while (isalnum(*chp
));
115 strlen_val
= chp
- start_val
;
116 chp
= skip_spaces (chp
);
119 error (line
, "Empty value field\n");
121 /* break out any conditional fields - { [ "!" | "=" [ <value> | <field-name> } */
122 while (*chp
== '!' || *chp
== '=')
127 insn_field_cond
*new_cond
= ZALLOC (insn_field_cond
);
129 /* determine the conditional test */
133 new_cond
->test
= insn_field_cond_eq
;
136 new_cond
->test
= insn_field_cond_ne
;
144 chp
= skip_spaces (chp
);
146 chp
= skip_to_separator (chp
, "+,:!=");
147 end
= back_spaces (start
, chp
);
150 error (line
, "Missing or invalid conditional value\n");
151 new_cond
->string
= NZALLOC (char, len
+ 1);
152 strncpy (new_cond
->string
, start
, len
);
154 /* determine the conditional type */
155 if (isdigit (*start
))
157 /* [ "!" | "=" ] <value> */
158 new_cond
->type
= insn_field_cond_value
;
159 new_cond
->value
= a2i (new_cond
->string
);
163 /* [ "!" | "=" ] <field> - check field valid */
164 new_cond
->type
= insn_field_cond_field
;
165 /* new_cond->field is determined in later */
168 /* Only a single `=' is permitted. */
169 if ((new_cond
->test
== insn_field_cond_eq
170 && new_field
->conditions
!= NULL
)
171 || (new_field
->conditions
!= NULL
172 && new_field
->conditions
->test
== insn_field_cond_eq
))
173 error (line
, "Only single conditional when `=' allowed\n");
177 insn_field_cond
**last
= &new_field
->conditions
;
178 while (*last
!= NULL
)
179 last
= &(*last
)->next
;
184 /* NOW verify that the field was finished */
187 chp
= skip_spaces (chp
+ 1);
189 error (line
, "empty field\n");
191 else if (*chp
!= '\0')
193 error (line
, "Missing field separator\n");
197 new_field
->val_string
= NZALLOC (char, strlen_val
+1);
198 strncpy (new_field
->val_string
, start_val
, strlen_val
);
199 if (isdigit (new_field
->val_string
[0]))
203 /* when the length/pos field is omited, an integer field
207 for (i
= 0; i
< strlen_val
; i
++)
209 if (new_field
->val_string
[i
] != '0'
210 && new_field
->val_string
[i
] != '1')
211 error (line
, "invalid binary field %s\n",
212 new_field
->val_string
);
213 val
= (val
<< 1) + (new_field
->val_string
[i
] == '1');
215 new_field
->val_int
= val
;
216 new_field
->type
= insn_field_int
;
220 new_field
->val_int
= a2i (new_field
->val_string
);
221 new_field
->type
= insn_field_int
;
224 else if (new_field
->val_string
[0] == '/')
226 new_field
->type
= insn_field_reserved
;
228 else if (new_field
->val_string
[0] == '*')
230 new_field
->type
= insn_field_wild
;
234 new_field
->type
= insn_field_string
;
235 if (filter_is_member (word
->field_names
, new_field
->val_string
))
236 error (line
, "Field name %s is duplicated\n", new_field
->val_string
);
237 filter_parse (&word
->field_names
, new_field
->val_string
);
239 if (new_field
->type
!= insn_field_string
240 && new_field
->conditions
!= NULL
)
241 error (line
, "Conditionals can only be applied to named fields\n");
243 /* the copy the position */
244 new_field
->pos_string
= NZALLOC (char, strlen_pos
+ 1);
245 strncpy (new_field
->pos_string
, start_pos
, strlen_pos
);
248 new_field
->first
= new_field
->prev
->last
+ 1;
249 if (new_field
->first
== 0 /* first field */
250 && *chp
== '\0' /* no further fields */
251 && new_field
->type
== insn_field_string
)
253 /* A single string without any position, assume that it
254 represents the entire instruction word */
255 new_field
->width
= options
.insn_bit_size
;
259 /* No explicit width/position, assume value implicitly
260 supplies the width */
261 new_field
->width
= strlen_val
;
263 new_field
->last
= new_field
->first
+ new_field
->width
- 1;
264 if (new_field
->last
>= options
.insn_bit_size
)
265 error (line
, "Bit position %d exceed instruction bit size (%d)\n",
266 new_field
->last
, options
.insn_bit_size
);
268 else if (options
.insn_specifying_widths
)
270 new_field
->first
= new_field
->prev
->last
+ 1;
271 new_field
->width
= a2i(new_field
->pos_string
);
272 new_field
->last
= new_field
->first
+ new_field
->width
- 1;
273 if (new_field
->last
>= options
.insn_bit_size
)
274 error (line
, "Bit position %d exceed instruction bit size (%d)\n",
275 new_field
->last
, options
.insn_bit_size
);
279 new_field
->first
= target_a2i(options
.hi_bit_nr
,
280 new_field
->pos_string
);
281 new_field
->last
= new_field
->next
->first
- 1; /* guess */
282 new_field
->width
= new_field
->last
- new_field
->first
+ 1; /* guess */
283 new_field
->prev
->last
= new_field
->first
- 1; /*fix*/
284 new_field
->prev
->width
= new_field
->first
- new_field
->prev
->first
; /*fix*/
288 /* fiddle first/last so that the sentinals disapear */
289 ASSERT(word
->first
->last
< 0);
290 ASSERT(word
->last
->first
>= options
.insn_bit_size
);
291 word
->first
= word
->first
->next
;
292 word
->last
= word
->last
->prev
;
294 /* check that the last field goes all the way to the last bit */
295 if (word
->last
->last
!= options
.insn_bit_size
- 1)
297 if (options
.warn
.width
)
298 options
.warning (line
, "Instruction format is not %d bits wide\n",
299 options
.insn_bit_size
);
300 word
->last
->last
= options
.insn_bit_size
- 1;
303 /* now go over this again, pointing each bit position at a field
306 insn_field_entry
*field
;
307 for (field
= word
->first
;
308 field
->last
< options
.insn_bit_size
;
312 for (i
= field
->first
; i
<= field
->last
; i
++)
314 word
->bit
[i
] = ZALLOC (insn_bit_entry
);
315 word
->bit
[i
]->field
= field
;
318 case insn_field_invalid
:
322 word
->bit
[i
]->mask
= 1;
323 word
->bit
[i
]->value
= ((field
->val_int
324 & ((insn_uint
)1 << (field
->last
- i
)))
326 case insn_field_reserved
:
327 case insn_field_wild
:
328 case insn_field_string
:
335 /* go over all fields that have conditionals refering to other
336 fields. Link the fields up. Verify that the two fields have the
337 same size. Verify that the two fields are different */
340 for (f
= word
->first
;
341 f
->last
< options
.insn_bit_size
;
344 insn_field_cond
*cond
;
345 for (cond
= f
->conditions
;
349 if (cond
->type
== insn_field_cond_field
)
351 insn_field_entry
*field
;
352 if (strcmp (cond
->string
, f
->val_string
) == 0)
353 error (line
, "Conditional of field `%s' refers to its self\n",
355 for (field
= word
->first
;
359 if (field
->type
== insn_field_string
360 && strcmp (field
->val_string
, cond
->string
) == 0)
362 /* found field being refered to by conditonal */
364 /* check refered to and this field are the
366 if (f
->width
!= field
->width
)
367 error (line
, "Conditional `%s' of field `%s' has different size\n",
368 field
->width
, f
->width
);
372 if (cond
->field
== NULL
)
373 error (line
, "Condition field refers to non-existant field `%s'\n",
385 parse_insn_words (insn_entry
*insn
,
388 insn_word_entry
**last_word
= &insn
->words
;
391 /* now work through the formats */
401 insn_word_entry
*new_word
;
403 /* skip leading spaces */
404 chp
= skip_spaces (chp
);
406 /* break out the format */
408 chp
= skip_to_separator (chp
, "+");
409 end_pos
= back_spaces (start_pos
, chp
);
410 strlen_pos
= end_pos
- start_pos
;
412 /* check that something was there */
414 error (insn
->line
, "missing or empty instruction format\n");
416 /* parse the field */
417 format
= NZALLOC (char, strlen_pos
+ 1);
418 strncpy (format
, start_pos
, strlen_pos
);
419 new_word
= parse_insn_word (insn
->line
, format
, insn
->nr_words
);
421 if (filter_is_common (insn
->field_names
, new_word
->field_names
))
422 error (insn
->line
, "Field name duplicated between two words\n");
423 filter_add (&insn
->field_names
, new_word
->field_names
);
426 *last_word
= new_word
;
427 last_word
= &new_word
->next
;
432 ASSERT (*chp
== '+');
436 /* now create a quick access array of the same structure */
439 insn_word_entry
*word
;
440 insn
->word
= NZALLOC (insn_word_entry
*, insn
->nr_words
+ 1);
441 for (i
= 0, word
= insn
->words
;
443 i
++, word
= word
->next
)
444 insn
->word
[i
] = word
;
450 insn_record
, /* default */
456 string_function_record
,
461 model_processor_record
,
465 model_function_record
,
466 model_internal_record
,
469 static const name_map insn_type_map
[] = {
470 { "option", option_record
},
471 { "cache", cache_record
},
472 { "compute", compute_record
},
473 { "scratch", scratch_record
},
474 { "define", define_record
},
475 { "include", include_record
},
476 { "%s", string_function_record
},
477 { "function", function_record
},
478 { "internal", internal_record
},
479 { "model", model_processor_record
},
480 { "model-macro", model_macro_record
},
481 { "model-data", model_data_record
},
482 { "model-static", model_static_record
},
483 { "model-internal", model_internal_record
},
484 { "model-function", model_function_record
},
485 { NULL
, insn_record
},
490 record_is_old (table_entry
*entry
)
492 if (entry
->nr_fields
> record_type_field
493 && strlen (entry
->field
[record_type_field
]) == 0)
498 static insn_record_type
499 record_type (table_entry
*entry
)
503 case table_code_entry
:
506 case table_colon_entry
:
507 if (record_is_old (entry
))
510 if (entry
->nr_fields
> old_record_type_field
)
512 int i
= name2i (entry
->field
[old_record_type_field
],
518 return unknown_record
;
521 else if (entry
->nr_fields
> record_type_field
522 && entry
->field
[0][0] == '\0')
525 int i
= name2i (entry
->field
[record_type_field
],
530 return insn_record
; /* default */
532 return unknown_record
;
536 record_prefix_is (table_entry
*entry
,
540 if (entry
->type
!= table_colon_entry
)
542 if (entry
->nr_fields
< nr_fields
)
544 if (entry
->field
[0][0] != ch
&& ch
!= '\0')
550 parse_model_data_record (insn_table
*isa
,
556 table_entry
*model_record
= record
;
557 table_entry
*code_record
= NULL
;
558 model_data
*new_data
;
559 if (record
->nr_fields
< nr_fields
)
560 error (record
->line
, "Incorrect number of fields\n");
561 record
= table_read (file
);
562 if (record
->type
== table_code_entry
)
564 code_record
= record
;
565 record
= table_read (file
);
567 /* create the new data record */
568 new_data
= ZALLOC (model_data
);
569 new_data
->line
= model_record
->line
;
570 filter_parse (&new_data
->flags
,
571 model_record
->field
[record_filter_flags_field
]);
572 new_data
->entry
= model_record
;
573 new_data
->code
= code_record
;
574 /* append it if not filtered out */
575 if (!is_filtered_out (options
.flags_filter
,
576 model_record
->field
[record_filter_flags_field
])
577 && !is_filtered_out (options
.model_filter
,
578 model_record
->field
[record_filter_models_field
]))
580 while (*list
!= NULL
)
581 list
= &(*list
)->next
;
589 insn_bit_size_option
= 1,
590 insn_specifying_widths_option
,
600 static const name_map option_map
[] = {
601 { "insn-bit-size", insn_bit_size_option
},
602 { "insn-specifying-widths", insn_specifying_widths_option
},
603 { "hi-bit-nr", hi_bit_nr_option
},
604 { "flags-filter", flags_filter_option
},
605 { "model-filter", model_filter_option
},
606 { "multi-sim", multi_sim_option
},
607 { "format-names", format_names_option
},
608 { "gen-delayed-branch", gen_delayed_branch
},
609 { NULL
, unknown_option
},
613 parse_include_record (table
*file
,
616 /* parse the include record */
617 if (record
->nr_fields
< nr_include_fields
)
618 error (record
->line
, "Incorrect nr fields for include record\n");
620 if (!is_filtered_out (options
.flags_filter
,
621 record
->field
[record_filter_flags_field
])
622 && !is_filtered_out (options
.model_filter
,
623 record
->field
[record_filter_models_field
]))
625 table_push (file
, record
->line
, options
.include
,
626 record
->field
[include_filename_field
]);
628 /* nb: can't read next record until after the file has been pushed */
629 record
= table_read (file
);
635 parse_option_record (table
*file
,
638 table_entry
*option_record
;
639 /* parse the option record */
640 option_record
= record
;
641 if (record
->nr_fields
< nr_option_fields
)
642 error (record
->line
, "Incorrect nr of fields for option record\n");
643 record
= table_read (file
);
645 if (!is_filtered_out (options
.flags_filter
,
646 option_record
->field
[record_filter_flags_field
])
647 && !is_filtered_out (options
.model_filter
,
648 option_record
->field
[record_filter_models_field
]))
650 char *name
= option_record
->field
[option_name_field
];
651 option_names option
= name2i (name
, option_map
);
652 char *value
= option_record
->field
[option_value_field
];
655 case insn_bit_size_option
:
657 options
.insn_bit_size
= a2i (value
);
658 if (options
.insn_bit_size
< 0
659 || options
.insn_bit_size
> max_insn_bit_size
)
660 error (option_record
->line
, "Instruction bit size out of range\n");
661 if (options
.hi_bit_nr
!= options
.insn_bit_size
- 1
662 && options
.hi_bit_nr
!= 0)
663 error (option_record
->line
, "insn-bit-size / hi-bit-nr conflict\n");
666 case insn_specifying_widths_option
:
668 options
.insn_specifying_widths
= a2i (value
);
671 case hi_bit_nr_option
:
673 options
.hi_bit_nr
= a2i (value
);
674 if (options
.hi_bit_nr
!= 0
675 && options
.hi_bit_nr
!= options
.insn_bit_size
- 1)
676 error (option_record
->line
, "hi-bit-nr / insn-bit-size conflict\n");
679 case flags_filter_option
:
681 filter_parse (&options
.flags_filter
, value
);
684 case model_filter_option
:
686 filter_parse (&options
.model_filter
, value
);
689 case multi_sim_option
:
691 options
.gen
.multi_sim
= a2i (value
);
694 case format_names_option
:
696 filter_parse (&options
.format_name_filter
, value
);
699 case gen_delayed_branch
:
701 options
.gen
.delayed_branch
= a2i (value
);
706 error (option_record
->line
, "Unknown option - %s\n", name
);
716 parse_function_record (table
*file
,
718 function_entry
**list
,
719 function_entry
**list_entry
,
723 function_entry
*new_function
;
724 new_function
= ZALLOC (function_entry
);
725 new_function
->line
= record
->line
;
726 new_function
->is_internal
= is_internal
;
727 /* parse the function header */
728 if (record_is_old (record
))
730 if (record
->nr_fields
< nr_old_function_fields
)
731 error (record
->line
, "Missing fields from (old) function record\n");
732 new_function
->type
= record
->field
[old_function_typedef_field
];
733 new_function
->type
= record
->field
[old_function_typedef_field
];
734 if (record
->nr_fields
> old_function_param_field
)
735 new_function
->param
= record
->field
[old_function_param_field
];
736 new_function
->name
= record
->field
[old_function_name_field
];
740 if (record
->nr_fields
< nr_function_fields
)
741 error (record
->line
, "Missing fields from function record\n");
742 filter_parse (&new_function
->flags
,
743 record
->field
[record_filter_flags_field
]);
744 filter_parse (&new_function
->models
,
745 record
->field
[record_filter_models_field
]);
746 new_function
->type
= record
->field
[function_typedef_field
];
747 new_function
->param
= record
->field
[function_param_field
];
748 new_function
->name
= record
->field
[function_name_field
];
750 record
= table_read (file
);
751 /* parse any function-model records */
752 while (record
!= NULL
753 && record_prefix_is (record
, '*', nr_function_model_fields
))
755 char *model_name
= record
->field
[function_model_name_field
] + 1; /*skip `*'*/
756 filter_parse (&new_function
->models
, model_name
);
757 if (!filter_is_subset (model
->processors
, new_function
->models
))
759 error (record
->line
, "machine model `%s' undefined\n", model_name
);
761 record
= table_read (file
);
763 /* parse the function body */
764 if (record
->type
== table_code_entry
)
766 new_function
->code
= record
;
767 record
= table_read (file
);
770 if (!filter_is_subset (options
.flags_filter
, new_function
->flags
))
772 if (options
.warn
.discard
)
773 notify (new_function
->line
, "Discarding function %s - filter flags\n",
776 else if (new_function
->models
!= NULL
777 && !filter_is_common (options
.model_filter
, new_function
->models
))
779 if (options
.warn
.discard
)
780 notify (new_function
->line
, "Discarding function %s - filter models\n",
785 while (*list
!= NULL
)
786 list
= &(*list
)->next
;
787 *list
= new_function
;
788 if (list_entry
!= NULL
)
789 *list_entry
= new_function
;
796 parse_insn_model_record (table
*file
,
801 insn_model_entry
**last_insn_model
;
802 insn_model_entry
*new_insn_model
= ZALLOC (insn_model_entry
);
804 new_insn_model
->line
= record
->line
;
805 if (record
->nr_fields
> insn_model_unit_data_field
)
806 new_insn_model
->unit_data
= record
->field
[insn_model_unit_data_field
];
807 new_insn_model
->insn
= insn
;
808 /* parse the model names, verify that all were defined */
809 new_insn_model
->names
= NULL
;
810 filter_parse (&new_insn_model
->names
,
811 record
->field
[insn_model_name_field
] + 1 /*skip `*'*/);
812 if (new_insn_model
->names
== NULL
)
814 /* No processor names - a generic model entry, enter it into all
815 the non-empty fields */
817 for (index
= 0; index
< model
->nr_models
; index
++)
818 if (insn
->model
[index
] == 0)
820 insn
->model
[index
] = new_insn_model
;
822 /* also add the complete processor set to this processor's set */
823 filter_add (&insn
->processors
, model
->processors
);
827 /* Find the corresponding master model record for each name so
828 that they can be linked in. */
833 name
= filter_next (new_insn_model
->names
, name
);
834 if (name
== NULL
) break;
835 index
= filter_is_member (model
->processors
, name
) - 1;
838 error (new_insn_model
->line
,
839 "machine model `%s' undefined\n", name
);
841 /* store it in the corresponding model array entry */
842 if (insn
->model
[index
] != NULL
843 && insn
->model
[index
]->names
!= NULL
)
845 warning (new_insn_model
->line
,
846 "machine model `%s' previously defined\n", name
);
847 error (insn
->model
[index
]->line
, "earlier definition\n");
849 insn
->model
[index
] = new_insn_model
;
850 /* also add the name to the instructions processor set as an
851 alternative lookup mechanism */
852 filter_parse (&insn
->processors
, name
);
856 /* for some reason record the max length of any
857 function unit field */
858 int len
= strlen (insn_model_ptr
->field
[insn_model_fields
]);
859 if (model
->max_model_fields_len
< len
)
860 model
->max_model_fields_len
= len
;
863 last_insn_model
= &insn
->models
;
864 while ((*last_insn_model
) != NULL
)
865 last_insn_model
= &(*last_insn_model
)->next
;
866 *last_insn_model
= new_insn_model
;
871 parse_insn_mnemonic_record (table
*file
,
875 insn_mnemonic_entry
**last_insn_mnemonic
;
876 insn_mnemonic_entry
*new_insn_mnemonic
= ZALLOC (insn_mnemonic_entry
);
878 new_insn_mnemonic
->line
= record
->line
;
879 ASSERT (record
->nr_fields
> insn_mnemonic_format_field
);
880 new_insn_mnemonic
->format
= record
->field
[insn_mnemonic_format_field
];
881 ASSERT (new_insn_mnemonic
->format
[0] == '"');
882 if (new_insn_mnemonic
->format
[strlen (new_insn_mnemonic
->format
) - 1] != '"')
883 error (new_insn_mnemonic
->line
, "Missing closing double quote in mnemonic field\n");
884 if (record
->nr_fields
> insn_mnemonic_condition_field
)
885 new_insn_mnemonic
->condition
= record
->field
[insn_mnemonic_condition_field
];
886 new_insn_mnemonic
->insn
= insn
;
888 last_insn_mnemonic
= &insn
->mnemonics
;
889 while ((*last_insn_mnemonic
) != NULL
)
890 last_insn_mnemonic
= &(*last_insn_mnemonic
)->next
;
891 insn
->nr_mnemonics
++;
892 *last_insn_mnemonic
= new_insn_mnemonic
;
897 parse_macro_record (table
*file
,
901 error (record
->line
, "Macros are not implemented");
903 /* parse the define record */
904 if (record
->nr_fields
< nr_define_fields
)
905 error (record
->line
, "Incorrect nr fields for define record\n");
907 if (!is_filtered_out (options
.flags_filter
,
908 record
->field
[record_filter_flags_field
])
909 && !is_filtered_out (options
.model_filter
,
910 record
->field
[record_filter_models_field
]))
914 record
->field
[macro_name_field
],
915 record
->field
[macro_args_field
],
916 record
->field
[macro_expr_field
]);
918 record
= table_read (file
);
925 load_insn_table (char *file_name
,
928 table
*file
= table_open (file_name
);
929 table_entry
*record
= table_read (file
);
931 insn_table
*isa
= ZALLOC (insn_table
);
932 model_table
*model
= ZALLOC (model_table
);
937 while (record
!= NULL
)
940 switch (record_type (record
))
945 record
= parse_include_record (file
, record
);
951 if (isa
->insns
!= NULL
)
952 error (record
->line
, "Option after first instruction\n");
953 record
= parse_option_record (file
, record
);
957 case string_function_record
:
959 function_entry
*function
= NULL
;
960 record
= parse_function_record (file
, record
,
965 /* convert a string function record into an internal function */
966 if (function
!= NULL
)
968 char *name
= NZALLOC (char,
970 + strlen (function
->name
)
972 strcat (name
, "str_");
973 strcat (name
, function
->name
);
974 function
->name
= name
;
975 function
->type
= "const char *";
980 case function_record
: /* function record */
982 record
= parse_function_record (file
, record
,
990 case internal_record
:
992 /* only insert it into the function list if it is unknown */
993 function_entry
*function
= NULL
;
994 record
= parse_function_record (file
, record
,
999 /* check what was inserted to see if a pseudo-instruction
1000 entry also needs to be created */
1001 if (function
!= NULL
)
1003 insn_entry
**insn
= NULL
;
1004 if (strcmp (function
->name
, "illegal") == 0)
1006 /* illegal function save it away */
1007 if (isa
->illegal_insn
!= NULL
)
1009 warning (function
->line
,
1010 "Multiple illegal instruction definitions\n");
1011 error (isa
->illegal_insn
->line
,
1012 "Location of first illegal instruction\n");
1015 insn
= &isa
->illegal_insn
;
1019 *insn
= ZALLOC (insn_entry
);
1020 (*insn
)->line
= function
->line
;
1021 (*insn
)->name
= function
->name
;
1022 (*insn
)->code
= function
->code
;
1028 case scratch_record
: /* cache macro records */
1030 case compute_record
:
1032 cache_entry
*new_cache
;
1033 /* parse the cache record */
1034 if (record
->nr_fields
< nr_cache_fields
)
1035 error (record
->line
,
1036 "Incorrect nr of fields for scratch/cache/compute record\n");
1038 new_cache
= ZALLOC (cache_entry
);
1039 new_cache
->line
= record
->line
;
1040 filter_parse (&new_cache
->flags
,
1041 record
->field
[record_filter_flags_field
]);
1042 filter_parse (&new_cache
->models
,
1043 record
->field
[record_filter_models_field
]);
1044 new_cache
->type
= record
->field
[cache_typedef_field
];
1045 new_cache
->name
= record
->field
[cache_name_field
];
1046 filter_parse (&new_cache
->original_fields
,
1047 record
->field
[cache_original_fields_field
]);
1048 new_cache
->expression
= record
->field
[cache_expression_field
];
1049 /* insert it but only if not filtered out */
1050 if (!filter_is_subset (options
.flags_filter
, new_cache
->flags
))
1052 notify (new_cache
->line
, "Discarding cache entry %s - filter flags\n",
1055 else if (is_filtered_out (options
.model_filter
,
1056 record
->field
[record_filter_models_field
]))
1058 notify (new_cache
->line
, "Discarding cache entry %s - filter models\n",
1064 last
= &isa
->caches
;
1065 while (*last
!= NULL
)
1066 last
= &(*last
)->next
;
1069 /* advance things */
1070 record
= table_read (file
);
1075 case model_processor_record
:
1077 model_entry
*new_model
;
1078 /* parse the model */
1079 if (record
->nr_fields
< nr_model_processor_fields
)
1080 error (record
->line
, "Incorrect nr of fields for model record\n");
1081 if (isa
->insns
!= NULL
)
1082 error (record
->line
, "Model appears after first instruction\n");
1083 new_model
= ZALLOC (model_entry
);
1084 filter_parse (&new_model
->flags
,
1085 record
->field
[record_filter_flags_field
]);
1086 new_model
->line
= record
->line
;
1087 new_model
->name
= record
->field
[model_name_field
];
1088 new_model
->full_name
= record
->field
[model_full_name_field
];
1089 new_model
->unit_data
= record
->field
[model_unit_data_field
];
1090 /* only insert it if not filtered out */
1091 if (!filter_is_subset (options
.flags_filter
, new_model
->flags
))
1093 notify (new_model
->line
, "Discarding processor model %s - filter flags\n",
1096 else if (is_filtered_out (options
.model_filter
,
1097 record
->field
[record_filter_models_field
]))
1099 notify (new_model
->line
, "Discarding processor model %s - filter models\n",
1102 else if (filter_is_member (model
->processors
, new_model
->name
))
1104 error (new_model
->line
, "Duplicate processor model %s\n",
1110 last
= &model
->models
;
1111 while (*last
!= NULL
)
1112 last
= &(*last
)->next
;
1115 model
->nr_models
++;
1116 filter_parse (&model
->processors
, new_model
->name
);
1118 /* advance things */
1119 record
= table_read (file
);
1123 case model_macro_record
:
1124 record
= parse_model_data_record (isa
, file
, record
,
1125 nr_model_macro_fields
,
1129 case model_data_record
:
1130 record
= parse_model_data_record (isa
, file
, record
,
1131 nr_model_data_fields
,
1135 case model_static_record
:
1136 record
= parse_function_record (file
, record
,
1143 case model_internal_record
:
1144 record
= parse_function_record (file
, record
,
1151 case model_function_record
:
1152 record
= parse_function_record (file
, record
,
1159 case insn_record
: /* instruction records */
1161 insn_entry
*new_insn
;
1163 /* parse the instruction */
1164 if (record
->nr_fields
< nr_insn_fields
)
1165 error (record
->line
, "Incorrect nr of fields for insn record\n");
1166 new_insn
= ZALLOC (insn_entry
);
1167 new_insn
->line
= record
->line
;
1168 filter_parse (&new_insn
->flags
,
1169 record
->field
[record_filter_flags_field
]);
1170 /* save the format field. Can't parse it until after the
1171 filter-out checks. Could be filtered out because the
1172 format is invalid */
1173 format
= record
->field
[insn_word_field
];
1174 new_insn
->format_name
= record
->field
[insn_format_name_field
];
1175 if (options
.format_name_filter
!= NULL
1176 && !filter_is_member (options
.format_name_filter
,
1177 new_insn
->format_name
))
1178 error (new_insn
->line
, "Unreconized instruction format name `%s'\n",
1179 new_insn
->format_name
);
1180 filter_parse (&new_insn
->options
,
1181 record
->field
[insn_options_field
]);
1182 new_insn
->name
= record
->field
[insn_name_field
];
1183 record
= table_read (file
);
1184 /* Parse any model/assember records */
1185 new_insn
->nr_models
= model
->nr_models
;
1186 new_insn
->model
= NZALLOC (insn_model_entry
*, model
->nr_models
+ 1);
1187 while (record
!= NULL
)
1189 if (record_prefix_is (record
, '*', nr_insn_model_fields
))
1190 parse_insn_model_record (file
, record
, new_insn
, model
);
1191 else if (record_prefix_is (record
, '"', nr_insn_mnemonic_fields
))
1192 parse_insn_mnemonic_record (file
, record
, new_insn
);
1196 record
= table_read (file
);
1198 /* Parse the code record */
1199 if (record
!= NULL
&& record
->type
== table_code_entry
)
1201 new_insn
->code
= record
;
1202 record
= table_read (file
);
1205 if (!filter_is_subset (options
.flags_filter
, new_insn
->flags
))
1207 if (options
.warn
.discard
)
1208 notify (new_insn
->line
,
1209 "Discarding instruction %s (flags-filter)\n",
1212 else if (new_insn
->processors
!= NULL
1213 && options
.model_filter
!= NULL
1214 && !filter_is_common (options
.model_filter
,
1215 new_insn
->processors
))
1217 /* only discard an instruction based in the processor
1218 model when both the instruction and the options are
1220 if (options
.warn
.discard
)
1221 notify (new_insn
->line
,
1222 "Discarding instruction %s (processor-model)\n",
1228 /* finish the parsing */
1229 parse_insn_words (new_insn
, format
);
1233 last
= &(*last
)->next
;
1235 /* update global isa counters */
1237 if (isa
->max_nr_words
< new_insn
->nr_words
)
1238 isa
->max_nr_words
= new_insn
->nr_words
;
1239 filter_add (&isa
->flags
, new_insn
->flags
);
1240 filter_add (&isa
->options
, new_insn
->options
);
1246 record
= parse_macro_record (file
, record
);
1249 case unknown_record
:
1251 error (record
->line
, "Unknown or unexpected entry\n");
1261 print_insn_words (lf
*file
,
1264 insn_word_entry
*word
= insn
->words
;
1269 insn_field_entry
*field
= word
->first
;
1272 if (options
.insn_specifying_widths
)
1273 lf_printf (file
, "%d.", field
->width
);
1275 lf_printf (file
, "%d.", i2target (options
.hi_bit_nr
, field
->first
));
1276 switch (field
->type
)
1278 case insn_field_invalid
:
1281 case insn_field_int
:
1282 lf_printf (file
, "0x%lx", (long) field
->val_int
);
1284 case insn_field_reserved
:
1285 lf_printf (file
, "/");
1287 case insn_field_wild
:
1288 lf_printf (file
, "*");
1290 case insn_field_string
:
1291 lf_printf (file
, "%s", field
->val_string
);
1294 if (field
== word
->last
)
1296 field
= field
->next
;
1297 lf_printf (file
, ",");
1302 lf_printf (file
, "+");
1310 function_entry_traverse (lf
*file
,
1311 function_entry
*functions
,
1312 function_entry_handler
*handler
,
1315 function_entry
*function
;
1316 for (function
= functions
; function
!= NULL
; function
= function
->next
)
1318 handler (file
, function
, data
);
1323 insn_table_traverse_insn (lf
*file
,
1325 insn_entry_handler
*handler
,
1329 for (insn
= isa
->insns
; insn
!= NULL
; insn
= insn
->next
)
1331 handler (file
, isa
, insn
, data
);
1337 dump_function_entry (lf
*file
,
1339 function_entry
*entry
,
1342 lf_printf (file
, "%s(function_entry *) 0x%lx", prefix
, (long) entry
);
1345 dump_line_ref (file
, "\n(line ", entry
->line
, ")");
1346 dump_filter (file
, "\n(flags ", entry
->flags
, ")");
1347 lf_printf (file
, "\n(type \"%s\")", entry
->type
);
1348 lf_printf (file
, "\n(name \"%s\")", entry
->name
);
1349 lf_printf (file
, "\n(param \"%s\")", entry
->param
);
1350 dump_table_entry (file
, "\n(code ", entry
->code
, ")");
1351 lf_printf (file
, "\n(is_internal %d)", entry
->is_internal
);
1352 lf_printf (file
, "\n(next 0x%lx)", (long) entry
->next
);
1354 lf_printf (file
, "%s", suffix
);
1358 dump_function_entries (lf
*file
,
1360 function_entry
*entry
,
1363 lf_printf (file
, "%s", prefix
);
1364 lf_indent (file
, +1);
1365 while (entry
!= NULL
)
1367 dump_function_entry (file
, "\n(", entry
, ")");
1368 entry
= entry
->next
;
1370 lf_indent (file
, -1);
1371 lf_printf (file
, "%s", suffix
);
1375 cache_entry_type_to_str (cache_entry_type type
)
1379 case scratch_value
: return "scratch";
1380 case cache_value
: return "cache";
1381 case compute_value
: return "compute";
1383 ERROR ("Bad switch");
1388 dump_cache_entry (lf
*file
,
1393 lf_printf (file
, "%s(cache_entry *) 0x%lx", prefix
, (long) entry
);
1396 dump_line_ref (file
, "\n(line ", entry
->line
, ")");
1397 dump_filter (file
, "\n(flags ", entry
->flags
, ")");
1398 lf_printf (file
, "\n(entry_type \"%s\")", cache_entry_type_to_str (entry
->entry_type
));
1399 lf_printf (file
, "\n(name \"%s\")", entry
->name
);
1400 dump_filter (file
, "\n(original_fields ", entry
->original_fields
, ")");
1401 lf_printf (file
, "\n(type \"%s\")", entry
->type
);
1402 lf_printf (file
, "\n(expression \"%s\")", entry
->expression
);
1403 lf_printf (file
, "\n(next 0x%lx)", (long) entry
->next
);
1405 lf_printf (file
, "%s", suffix
);
1409 dump_cache_entries (lf
*file
,
1414 lf_printf (file
, "%s", prefix
);
1415 lf_indent (file
, +1);
1416 while (entry
!= NULL
)
1418 dump_cache_entry (file
, "\n(", entry
, ")");
1419 entry
= entry
->next
;
1421 lf_indent (file
, -1);
1422 lf_printf (file
, "%s", suffix
);
1426 dump_model_data (lf
*file
,
1431 lf_printf (file
, "%s(model_data *) 0x%lx", prefix
, (long) entry
);
1434 lf_indent (file
, +1);
1435 dump_line_ref (file
, "\n(line ", entry
->line
, ")");
1436 dump_filter (file
, "\n(flags ", entry
->flags
, ")");
1437 dump_table_entry (file
, "\n(entry ", entry
->entry
, ")");
1438 dump_table_entry (file
, "\n(code ", entry
->code
, ")");
1439 lf_printf (file
, "\n(next 0x%lx)", (long) entry
->next
);
1440 lf_indent (file
, -1);
1442 lf_printf (file
, "%s", prefix
);
1446 dump_model_datas (lf
*file
,
1451 lf_printf (file
, "%s", prefix
);
1452 lf_indent (file
, +1);
1453 while (entry
!= NULL
)
1455 dump_model_data (file
, "\n(", entry
, ")");
1456 entry
= entry
->next
;
1458 lf_indent (file
, -1);
1459 lf_printf (file
, "%s", suffix
);
1463 dump_model_entry (lf
*file
,
1468 lf_printf (file
, "%s(model_entry *) 0x%lx", prefix
, (long) entry
);
1471 lf_indent (file
, +1);
1472 dump_line_ref (file
, "\n(line ", entry
->line
, ")");
1473 dump_filter (file
, "\n(flags ", entry
->flags
, ")");
1474 lf_printf (file
, "\n(name \"%s\")", entry
->name
);
1475 lf_printf (file
, "\n(full_name \"%s\")", entry
->full_name
);
1476 lf_printf (file
, "\n(unit_data \"%s\")", entry
->unit_data
);
1477 lf_printf (file
, "\n(next 0x%lx)", (long) entry
->next
);
1478 lf_indent (file
, -1);
1480 lf_printf (file
, "%s", prefix
);
1484 dump_model_entries (lf
*file
,
1489 lf_printf (file
, "%s", prefix
);
1490 lf_indent (file
, +1);
1491 while (entry
!= NULL
)
1493 dump_model_entry (file
, "\n(", entry
, ")");
1494 entry
= entry
->next
;
1496 lf_indent (file
, -1);
1497 lf_printf (file
, "%s", suffix
);
1502 dump_model_table (lf
*file
,
1507 lf_printf (file
, "%s(model_table *) 0x%lx", prefix
, (long) entry
);
1510 lf_indent (file
, +1);
1511 dump_filter (file
, "\n(processors ", entry
->processors
, ")");
1512 lf_printf (file
, "\n(nr_models %d)", entry
->nr_models
);
1513 dump_model_entries (file
, "\n(models ", entry
->models
, ")");
1514 dump_model_datas (file
, "\n(macros ", entry
->macros
, ")");
1515 dump_model_datas (file
, "\n(data ", entry
->data
, ")");
1516 dump_function_entries (file
, "\n(statics ", entry
->statics
, ")");
1517 dump_function_entries (file
, "\n(internals ", entry
->functions
, ")");
1518 dump_function_entries (file
, "\n(functions ", entry
->functions
, ")");
1519 lf_indent (file
, -1);
1521 lf_printf (file
, "%s", suffix
);
1526 insn_field_type_to_str (insn_field_type type
)
1530 case insn_field_invalid
: ASSERT (0); return "(invalid)";
1531 case insn_field_int
: return "int";
1532 case insn_field_reserved
: return "reserved";
1533 case insn_field_wild
: return "wild";
1534 case insn_field_string
: return "string";
1536 ERROR ("bad switch");
1541 dump_insn_field (lf
*file
,
1543 insn_field_entry
*field
,
1547 lf_printf (file
, "%s(insn_field_entry *) 0x%lx", prefix
, (long) field
);
1550 lf_indent (file
, +1);
1551 lf_printf (file
, "%s(first %d)", sep
, field
->first
);
1552 lf_printf (file
, "%s(last %d)", sep
, field
->last
);
1553 lf_printf (file
, "%s(width %d)", sep
, field
->width
);
1554 lf_printf (file
, "%s(type %s)", sep
, insn_field_type_to_str (field
->type
));
1555 switch (field
->type
)
1557 case insn_field_invalid
:
1560 case insn_field_int
:
1561 lf_printf (file
, "%s(val 0x%lx)", sep
, (long) field
->val_int
);
1563 case insn_field_reserved
:
1564 /* nothing output */
1566 case insn_field_wild
:
1567 /* nothing output */
1569 case insn_field_string
:
1570 lf_printf (file
, "%s(val \"%s\")", sep
, field
->val_string
);
1573 lf_printf (file
, "%s(next 0x%lx)", sep
, (long) field
->next
);
1574 lf_printf (file
, "%s(prev 0x%lx)", sep
, (long) field
->prev
);
1575 lf_indent (file
, -1);
1577 lf_printf (file
, "%s", suffix
);
1581 dump_insn_word_entry (lf
*file
,
1583 insn_word_entry
*word
,
1586 lf_printf (file
, "%s(insn_word_entry *) 0x%lx", prefix
, (long) word
);
1590 insn_field_entry
*field
;
1591 lf_indent (file
, +1);
1592 lf_printf (file
, "\n(first 0x%lx)", (long) word
->first
);
1593 lf_printf (file
, "\n(last 0x%lx)", (long) word
->last
);
1594 lf_printf (file
, "\n(bit");
1595 for (i
= 0; i
< options
.insn_bit_size
; i
++)
1596 lf_printf (file
, "\n ((value %d) (mask %d) (field 0x%lx))",
1597 word
->bit
[i
]->value
, word
->bit
[i
]->mask
, (long) word
->bit
[i
]->field
);
1598 lf_printf (file
, ")");
1599 for (field
= word
->first
; field
!= NULL
; field
= field
->next
)
1600 dump_insn_field (file
, "\n(", field
, ")");
1601 dump_filter (file
, "\n(field_names ", word
->field_names
, ")");
1602 lf_printf (file
, "\n(next 0x%lx)", (long) word
->next
);
1603 lf_indent (file
, -1);
1605 lf_printf (file
, "%s", suffix
);
1609 dump_insn_word_entries (lf
*file
,
1611 insn_word_entry
*word
,
1614 lf_printf (file
, "%s", prefix
);
1615 while (word
!= NULL
)
1617 dump_insn_word_entry (file
, "\n(", word
, ")");
1620 lf_printf (file
, "%s", suffix
);
1624 dump_insn_model_entry (lf
*file
,
1626 insn_model_entry
*model
,
1629 lf_printf (file
, "%s(insn_model_entry *) 0x%lx", prefix
, (long) model
);
1632 lf_indent (file
, +1);
1633 dump_line_ref (file
, "\n(line ", model
->line
, ")");
1634 dump_filter (file
, "\n(names ", model
->names
, ")");
1635 lf_printf (file
, "\n(full_name \"%s\")", model
->full_name
);
1636 lf_printf (file
, "\n(unit_data \"%s\")", model
->unit_data
);
1637 lf_printf (file
, "\n(insn (insn_entry *) 0x%lx)", (long) model
->insn
);
1638 lf_printf (file
, "\n(next (insn_model_entry *) 0x%lx)",
1639 (long) model
->next
);
1640 lf_indent (file
, -1);
1642 lf_printf (file
, "%s", suffix
);
1646 dump_insn_model_entries (lf
*file
,
1648 insn_model_entry
*model
,
1651 lf_printf (file
, "%s", prefix
);
1652 while (model
!= NULL
)
1654 dump_insn_model_entry (file
, "\n", model
, "");
1655 model
= model
->next
;
1657 lf_printf (file
, "%s", suffix
);
1662 dump_insn_mnemonic_entry (lf
*file
,
1664 insn_mnemonic_entry
*mnemonic
,
1667 lf_printf (file
, "%s(insn_mnemonic_entry *) 0x%lx", prefix
, (long) mnemonic
);
1668 if (mnemonic
!= NULL
)
1670 lf_indent (file
, +1);
1671 dump_line_ref (file
, "\n(line ", mnemonic
->line
, ")");
1672 lf_printf (file
, "\n(format \"%s\")", mnemonic
->format
);
1673 lf_printf (file
, "\n(condition \"%s\")", mnemonic
->condition
);
1674 lf_printf (file
, "\n(insn (insn_entry *) 0x%lx)",
1675 (long) mnemonic
->insn
);
1676 lf_printf (file
, "\n(next (insn_mnemonic_entry *) 0x%lx)",
1677 (long) mnemonic
->next
);
1678 lf_indent (file
, -1);
1680 lf_printf (file
, "%s", suffix
);
1684 dump_insn_mnemonic_entries (lf
*file
,
1686 insn_mnemonic_entry
*mnemonic
,
1689 lf_printf (file
, "%s", prefix
);
1690 while (mnemonic
!= NULL
)
1692 dump_insn_mnemonic_entry (file
, "\n", mnemonic
, "");
1693 mnemonic
= mnemonic
->next
;
1695 lf_printf (file
, "%s", suffix
);
1699 dump_insn_entry (lf
*file
,
1704 lf_printf (file
, "%s(insn_entry *) 0x%lx", prefix
, (long) entry
);
1708 lf_indent (file
, +1);
1709 dump_line_ref (file
, "\n(line ", entry
->line
, ")");
1710 dump_filter (file
, "\n(flags ", entry
->flags
, ")");
1711 lf_printf (file
, "\n(nr_words %d)", entry
->nr_words
);
1712 dump_insn_word_entries (file
, "\n(words ", entry
->words
, ")");
1713 lf_printf (file
, "\n(word");
1714 for (i
= 0; i
< entry
->nr_models
; i
++)
1715 lf_printf (file
, " 0x%lx", (long) entry
->word
[i
]);
1716 lf_printf (file
, ")");
1717 dump_filter (file
, "\n(field_names ", entry
->field_names
, ")");
1718 lf_printf (file
, "\n(format_name \"%s\")", entry
->format_name
);
1719 dump_filter (file
, "\n(options ", entry
->options
, ")");
1720 lf_printf (file
, "\n(name \"%s\")", entry
->name
);
1721 lf_printf (file
, "\n(nr_models %d)", entry
->nr_models
);
1722 dump_insn_model_entries (file
, "\n(models ", entry
->models
, ")");
1723 lf_printf (file
, "\n(model");
1724 for (i
= 0; i
< entry
->nr_models
; i
++)
1725 lf_printf (file
, " 0x%lx", (long) entry
->model
[i
]);
1726 lf_printf (file
, ")");
1727 dump_filter (file
, "\n(processors ", entry
->processors
, ")");
1728 dump_insn_mnemonic_entries (file
, "\n(mnemonics ", entry
->mnemonics
, ")");
1729 dump_table_entry (file
, "\n(code ", entry
->code
, ")");
1730 lf_printf (file
, "\n(next 0x%lx)", (long) entry
->next
);
1731 lf_indent (file
, -1);
1733 lf_printf (file
, "%s", suffix
);
1737 dump_insn_entries (lf
*file
,
1742 lf_printf (file
, "%s", prefix
);
1743 lf_indent (file
, +1);
1744 while (entry
!= NULL
)
1746 dump_insn_entry (file
, "\n(", entry
, ")");
1747 entry
= entry
->next
;
1749 lf_indent (file
, -1);
1750 lf_printf (file
, "%s", suffix
);
1756 dump_insn_table (lf
*file
,
1761 lf_printf (file
, "%s(insn_table *) 0x%lx", prefix
, (long) isa
);
1764 lf_indent (file
, +1);
1765 dump_cache_entries (file
, "\n(caches ", isa
->caches
, ")");
1766 lf_printf (file
, "\n(nr_insns %d)", isa
->nr_insns
);
1767 lf_printf (file
, "\n(max_nr_words %d)", isa
->max_nr_words
);
1768 dump_insn_entries (file
, "\n(insns ", isa
->insns
, ")");
1769 dump_function_entries (file
, "\n(functions ", isa
->functions
, ")");
1770 dump_insn_entry (file
, "\n(illegal_insn ", isa
->illegal_insn
, ")");
1771 dump_model_table (file
, "\n(model ", isa
->model
, ")");
1772 dump_filter (file
, "\n(flags ", isa
->flags
, ")");
1773 dump_filter (file
, "\n(options ", isa
->options
, ")");
1774 lf_indent (file
, -1);
1776 lf_printf (file
, "%s", suffix
);
1781 igen_options options
;
1784 main (int argc
, char **argv
)
1789 INIT_OPTIONS (options
);
1792 filter_parse (&options
.flags_filter
, argv
[2]);
1794 error (NULL
, "Usage: insn <insn-table> [ <filter-in> ]\n");
1796 isa
= load_insn_table (argv
[1], NULL
);
1797 l
= lf_open ("-", "stdout", lf_omit_references
, lf_is_text
, "tmp-ld-insn");
1798 dump_insn_table (l
, "(isa ", isa
, ")\n");