our $arch;
our $additional_opcodes;
our %nodes;
-our %operands;
our %cpu;
our $default_op_attr_type;
our $default_attr_type;
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}",
);
}
-# Operands are really just nodes with some special constraints, we check
-# these and create new entries in the nodes hashmap
-foreach my $op (keys(%operands)) {
- my %operand = %{ $operands{"$op"} };
- my %op_node;
-
- # constraints
- if(defined($operand{op_flags})) { die "Fatal error: operands can't have op_flags ($op)"; }
- if(defined($operand{cmp_attr})) { die "Fatal error: cmp_attr not allowed for operands ($op)"; }
- if(defined($operand{mode})) { die "Operand must not have a mode defined ($op)"; }
- if(defined($operand{out_arity})) { die "operand must not have out_arity defined ($op)"; }
- if(defined($nodes{$op})) { die "$op defined as operand and as node"; };
-
-
- foreach my $flag (keys(%operand)) {
- $op_node{$flag} = $operand{$flag};
- }
- $op_node{op_flags} = "O";
- $op_node{cmp_attr} = 'return 1;';
- $op_node{mode} = 'mode_ANY';
-
- $nodes{$op} = \%op_node;
-}
-
-#print Dumper(%nodes);
-#print Dumper(%operands);
-
# create c code file from specs
my @obst_limit_func;
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",
- "machine", "machine_op", "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 .= "|irop_flag_machine, ".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");
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);