if(!defined($default_attr_type)) {
$default_attr_type = "${arch}_attr_t";
}
-if(!defined(%init_attr)) {
+if(! %init_attr) {
%init_attr = (
"$default_attr_type" => "\tinit_${arch}_attributes(res, irn_flags_, in_reqs, n_res);",
);
if(!defined($default_cmp_attr)) {
$default_cmp_attr = "${arch}_compare_attr";
}
-if(!defined(%compare_attr)) {
+if(! %compare_attr) {
%compare_attr = (
"${default_attr_type}" => "${default_cmp_attr}",
);
my @obst_get_opvar; # stack for the get_op_<arch>_<op-name>() functions
my $obst_constructor; # stack for node constructor functions
my @obst_new_irop; # stack for the new_ir_op calls
+my @obst_free_irop; # stack for free_ir_op calls
my @obst_enum_op; # stack for creating the <arch>_opcode enum
my $obst_header; # stack for function prototypes
my @obst_is_archirn; # stack for the is_$arch_irn() function
$n_opcodes += $additional_opcodes if (defined($additional_opcodes));
$obst_header .= "void ${arch}_create_opcodes(const arch_irn_ops_t *be_ops);\n";
+$obst_header .= "void ${arch}_free_opcodes(void);\n";
sub create_constructor {
my $op = shift;
"simple_jump" => "arch_irn_flags_simple_jump",
"not_scheduled" => "arch_irn_flags_not_scheduled",
);
- if (defined(%custom_irn_flags)) {
+ if (%custom_irn_flags) {
%known_irn_flags = (%known_irn_flags, %custom_irn_flags);
}
foreach my $flag (@{$n->{"irn_flags"}}) {
$n{"dump_func"} = "${arch}_dump_node" if (!exists($n{"dump_func"}));
my $dump_func = $n{"dump_func"};
- push(@obst_new_irop, "\n\tmemset(&ops, 0, sizeof(ops));\n");
- push(@obst_new_irop, "\tops.be_ops = be_ops;\n");
- push(@obst_new_irop, "\tops.dump_node = ${dump_func};\n");
-
- if (defined($cmp_attr_func)) {
- push(@obst_new_irop, "\tops.node_cmp_attr = ${cmp_attr_func};\n");
- }
- my $copy_attr_func = $copy_attr{$attr_type};
- if (!defined($copy_attr_func)) {
- if ($attr_type eq "") {
- $copy_attr_func = "NULL";
- } else {
- $copy_attr_func = $default_copy_attr;
- }
- }
- if (defined($copy_attr_func)) {
- push(@obst_new_irop, "\tops.copy_attr = ${copy_attr_func};\n");
- }
- if (defined($hash_func)) {
- push(@obst_new_irop, "\tops.hash = ${hash_func};\n");
- }
-
my %known_flags = map { $_ => 1 } (
- "none", "labeled", "commutative", "cfopcode", "unknown_jump", "fragile",
- "forking", "highlevel", "constlike", "always_opt", "keep",
- "start_block", "uses_memory", "dump_noblock", "dump_noinput",
- "cse_neutral"
+ "none", "commutative", "cfopcode", "unknown_jump", "fragile",
+ "forking", "highlevel", "constlike", "keep", "start_block",
+ "uses_memory", "dump_noblock", "cse_neutral"
);
my $is_fragile = 0;
foreach my $flag (@{$n{"op_flags"}}) {
}
$n_opcodes++;
- $temp = "\top_$op = new_ir_op(cur_opcode + iro_$op, \"$op\", op_pin_state_".$n{"state"}.", $op_flags";
- $temp .= ", ".translate_arity($arity).", 0, ${attr_size}, &ops);\n";
+ $temp = "\top = new_ir_op(cur_opcode + iro_$op, \"$op\", op_pin_state_".$n{"state"}.", $op_flags";
+ $temp .= ", ".translate_arity($arity).", 0, ${attr_size});\n";
push(@obst_new_irop, $temp);
- if ($is_fragile) {
- push(@obst_new_irop, "\tir_op_set_fragile_indices(op_${op}, n_${op}_mem, pn_${op}_X_regular, pn_${op}_X_except);\n");
+ push(@obst_new_irop, "\top->ops.be_ops = be_ops;\n");
+ push(@obst_new_irop, "\top->ops.dump_node = ${dump_func};\n");
+ if (defined($cmp_attr_func)) {
+ push(@obst_new_irop, "\top->ops.node_cmp_attr = ${cmp_attr_func};\n");
}
- push(@obst_new_irop, "\tset_op_tag(op_$op, $arch\_op_tag);\n");
- if(defined($default_op_attr_type)) {
- push(@obst_new_irop, "\tattr = &attrs[iro_$op];\n");
- if(defined($n{op_attr_init})) {
- push(@obst_new_irop, "\t".$n{op_attr_init}."\n");
+ my $copy_attr_func = $copy_attr{$attr_type};
+ if (!defined($copy_attr_func)) {
+ # don't set a copy_attr function if the node has no additional attributes.
+ if ($attr_type ne "") {
+ $copy_attr_func = $default_copy_attr;
}
- push(@obst_new_irop, "\tset_op_attr(op_$op, attr);\n");
+ }
+ if (defined($copy_attr_func)) {
+ push(@obst_new_irop, "\top->ops.copy_attr = ${copy_attr_func};\n");
+ }
+ if (defined($hash_func)) {
+ push(@obst_new_irop, "\top->ops.hash = ${hash_func};\n");
}
+ if ($is_fragile) {
+ push(@obst_new_irop, "\tir_op_set_memory_index(op, n_${op}_mem);\n");
+ push(@obst_new_irop, "\tir_op_set_fragile_indices(op, pn_${op}_X_regular, pn_${op}_X_except);\n");
+ }
+ push(@obst_new_irop, "\tset_op_tag(op, $arch\_op_tag);\n");
+ if(defined($n{op_attr_init})) {
+ push(@obst_new_irop, "\t".$n{op_attr_init}."\n");
+ }
+ push(@obst_new_irop, "\top_${op} = op;\n");
+
+ push(@obst_free_irop, "\tfree_ir_op(op_$op); op_$op = NULL;\n");
+
push(@obst_enum_op, "\tiro_$op,\n");
$obst_header .= "\n";
print OUT "#include \"gen_$arch\_regalloc_if.h\"\n";
print OUT "#include \"irverify_t.h\"\n";
+print OUT "#include \"fourcc.h\"\n";
print OUT "\n";
print OUT @obst_cmp_attr;
print OUT "\n";
* Creates the $arch specific Firm machine operations
* needed for the assembler irgs.
*/
-void $arch\_create_opcodes(const arch_irn_ops_t *be_ops) {
- ir_op_ops ops;
- int cur_opcode;
- static int run_once = 0;
-ENDOFMAIN
-
- if (defined($default_op_attr_type)) {
- print OUT "\t$default_op_attr_type *attr, *attrs;\n";
- }
-
-print OUT<<ENDOFMAIN;
-
- if (run_once)
- return;
- run_once = 1;
-
- cur_opcode = get_next_ir_opcodes(iro_$arch\_last);
+void $arch\_create_opcodes(const arch_irn_ops_t *be_ops)
+{
+ ir_op *op;
+ int cur_opcode = get_next_ir_opcodes(iro_$arch\_last);
$arch\_opcode_start = cur_opcode;
ENDOFMAIN
- if (defined($default_op_attr_type)) {
- print OUT "\tattrs = XMALLOCNZ(${default_op_attr_type}, iro_${arch}_last);\n";
- }
-
print OUT @obst_new_irop;
print OUT "\n";
print OUT "\t$arch\_register_additional_opcodes(cur_opcode);\n" if (defined($additional_opcodes));
print OUT "\t$arch\_opcode_end = cur_opcode + iro_$arch\_last";
print OUT " + $additional_opcodes" if (defined($additional_opcodes));
print OUT ";\n";
-print OUT "}\n";
+print OUT <<ENDOFMAIN;
+}
+
+void $arch\_free_opcodes(void)
+{
+ENDOFMAIN
+
+print OUT @obst_free_irop;
+
+print OUT <<ENDOFMAIN;
+}
+ENDOFMAIN
close(OUT);