our $additional_opcodes;
our %nodes;
our %cpu;
-our $default_cmp_attr;
our $default_attr_type;
+our $default_cmp_attr;
+our %init_attr;
+our %compare_attr;
# include spec file
if(!defined($default_attr_type)) {
$default_attr_type = "${arch}_attr_t";
}
+if(!defined(%init_attr)) {
+ %init_attr = (
+ "$default_attr_type" => "\tinit_${arch}_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);",
+ );
+}
+if(!defined($default_cmp_attr)) {
+ $default_cmp_attr = "${arch}_compare_attr";
+}
+if(!defined(%compare_attr)) {
+ %compare_attr = (
+ "${default_attr_type}" => "${default_cmp_attr}",
+ );
+}
#print Dumper(%nodes);
#print Dumper(%operands);
push(@obst_header, "void ".$arch."_create_opcodes(void);\n");
-# create default compare function
-if(defined($default_cmp_attr)) {
- my $cmpcode = $default_cmp_attr;
- push(@obst_cmp_attr, "static int default_cmp_attr(ir_node *a, ir_node *b) {\n");
- if($cmpcode =~ m/attr_a/) {
- push(@obst_cmp_attr, "\t${default_attr_type} *attr_a = get_irn_generic_attr(a);\n");
- }
- if($cmpcode =~ m/attr_b/) {
- push(@obst_cmp_attr, "\t${default_attr_type} *attr_b = get_irn_generic_attr(b);\n");
- }
- push(@obst_cmp_attr, "\t${cmpcode}\n");
- push(@obst_cmp_attr, "}\n\n");
-}
-
push(@obst_enum_op, "typedef enum _$arch\_opcodes {\n");
foreach my $op (keys(%nodes)) {
my %n = %{ $nodes{"$op"} };
# determine compare function
my $cmp_attr_func;
- if(defined($default_cmp_attr)) {
- $cmp_attr_func = "default_cmp_attr";
- }
if (exists($n{"cmp_attr"})) {
my $cmpcode = $n{"cmp_attr"};
push(@obst_cmp_attr, "}\n\n");
$cmp_attr_func = "cmp_attr_${op}";
+ } else {
+ if(defined($compare_attr{${attr_type}})) {
+ $cmp_attr_func = $compare_attr{${attr_type}};
+ } else {
+ die "No compare function defined for ${attr_type} attributes.";
+ }
}
if (exists($n{"rd_constructor"}) && $n{"rd_constructor"} =~ /^NONE$/i) {
$temp .= "\n";
$temp .= "\t/* init node attributes */\n";
- $temp .= "\tinit_$arch\_attributes(res, flags, in_reqs, out_reqs, exec_units, n_res, latency);\n";
+ # lookup init function
+ my $attr_init_code = $init_attr{$attr_type};
+ if(!defined($attr_init_code)) {
+ die "Couldn't find attribute initialisation code for type '${attr_type}'";
+ }
+ $temp .= "${attr_init_code}\n";
$temp .= "\n";
# set flags for outs
if (exists($n{"init_attr"})) {
- $temp .= "\tattr = get_$arch\_attr(res);\n";
- $temp .= $n{"init_attr"}."\n";
+ $temp .= "\tattr = get_irn_generic_attr(res);\n";
+ $temp .= "\t".$n{"init_attr"}."\n";
}
$temp .= "\t/* optimize node */\n";
$n_res = "20"; # hacky....
}
$temp = "\top_$op = new_ir_op(cur_opcode + iro_$op, \"$op\", op_pin_state_".$n{"state"}.", ".$n{"op_flags"};
- $temp .= "|M, ".translate_arity($arity).", 0, sizeof(${attr_type}) + $n_res * sizeof(arch_register_t *), &ops);\n";
+ $temp .= "|M, ".translate_arity($arity).", 0, sizeof(${attr_type}), &ops);\n";
push(@obst_new_irop, $temp);
push(@obst_new_irop, "\tset_op_tag(op_$op, &$arch\_op_tag);\n");
push(@obst_enum_op, "\tiro_$op,\n");