#!/usr/bin/perl -w
#
-# Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
+# Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
#
# This file is part of libFirm.
#
# for registering additional opcodes
$n_opcodes += $additional_opcodes if (defined($additional_opcodes));
-push(@obst_header, "void ".$arch."_create_opcodes(void);\n");
+push(@obst_header, "void ".$arch."_create_opcodes(const arch_irn_ops_t *be_ops);\n");
push(@obst_enum_op, "typedef enum _$arch\_opcodes {\n");
foreach my $op (keys(%nodes)) {
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 = $arch\_dump_node;\n");
if (defined($cmp_attr_func)) {
* Creates the $arch specific Firm machine operations
* needed for the assembler irgs.
*/
-void $arch\_create_opcodes(void) {
+void $arch\_create_opcodes(const arch_irn_ops_t *be_ops) {
#define N irop_flag_none
#define L irop_flag_labeled
#define C irop_flag_commutative
ir_op_ops ops;
int cur_opcode;
static int run_once = 0;
+ int i;
+
+ /* we handle all middleend nodes as well */
+ for (i = 0; i <= iro_Last; ++i) {
+ ir_op *op = get_irp_opcode(i);
+ op->ops.be_ops = be_ops;
+ }
ENDOFMAIN
if(defined($default_op_attr_type)) {
my $class = undef;
my $has_limit = 0;
my $limit_name;
- my $same_pos = undef;
- my $same_pos2 = undef;
- my $different_pos = undef;
+ my $same_pos = 0;
+ my $different_pos = 0;
my $temp;
my @obst_init;
my @obst_limits;
# set/unset registers
CHECK_REQS: foreach (@regs) {
if (!$is_in && /(!)?in_r(\d+)/) {
- if (($1 && defined($different_pos)) || (!$1 && defined($same_pos2))) {
- print STDERR "Multiple in/out references of same type in one requirement not allowed.\n";
- return (undef, undef, undef, undef, undef);
+ my $bit_pos = 1 << ($2 - 1);
+ if ($different_pos & $bit_pos) {
+ if ($1) {
+ print STDERR "duplicate !in constraint\n";
+ } else {
+ print STDERR "conflicting !in and in constraints\n";
+ }
+ return (undef, undef, undef, undef);
}
- if ($1) {
- $different_pos = $2 - 1;
- } else {
- if (!defined($same_pos)) {
- $same_pos = $2 - 1;
+ if ($same_pos & $bit_pos) {
+ if ($1) {
+ print STDERR "conflicting !in and in constraints\n";
} else {
- $same_pos2 = $2 - 1;
+ print STDERR "duplicate in constraint\n";
}
+ return (undef, undef, undef, undef);
+ }
+
+ if ($1) {
+ $different_pos |= $bit_pos;
+ } else {
+ $same_pos |= $bit_pos;
}
$class = $idx_class[$2 - 1];
next CHECK_REQS;
- } elsif (/!in/) {
- $class = $idx_class[0];
- return ($class, "NULL", undef, undef, 666);
}
# check for negate
# we have seen a positiv constraint as first one but this one is negative
# this doesn't make sense
print STDERR "Mixed positive and negative constraints for the same slot are not allowed.\n";
- return (undef, undef, undef, undef, undef);
+ return (undef, undef, undef, undef);
}
if (!defined($neg)) {
# we have seen a negative constraint as first one but this one is positive
# this doesn't make sense
print STDERR "Mixed positive and negative constraints for the same slot are not allowed.\n";
- return (undef, undef, undef, undef, undef);
+ return (undef, undef, undef, undef);
}
$has_limit = 1;
$temp = get_reg_class($_);
if (!defined($temp)) {
print STDERR "Unknown register '$_'!\n";
- return (undef, undef, undef, undef, undef);
+ return (undef, undef, undef, undef);
}
# set class
} elsif ($class ne $temp) {
# all registers must belong to the same class
print STDERR "Registerclass mismatch. '$_' is not member of class '$class'.\n";
- return (undef, undef, undef, undef, undef);
+ return (undef, undef, undef, undef);
}
# calculate position inside the initializer bitfield (only 32 bits per
if(defined($limit_bitsets{$limit_name})) {
$limit_name = $limit_bitsets{$limit_name};
- return ($class, $limit_name, $same_pos, $same_pos2, $different_pos);
+ return ($class, $limit_name, $same_pos, $different_pos);
}
$limit_bitsets{$limit_name} = $limit_name;
push(@obst_limit_func, " };\n");
}
- return ($class, $limit_name, $same_pos, $same_pos2, $different_pos);
+ return ($class, $limit_name, $same_pos, $different_pos);
}
###
arch_register_req_type_none,
NULL, /* regclass */
NULL, /* limit bitset */
- { -1, -1 }, /* same pos */
- -1 /* different pos */
+ 0, /* same pos */
+ 0 /* different pos */
};
EOF
arch_register_req_type_should_be_different_from_all,
& ${arch}_reg_classes[CLASS_${arch}_${class}],
NULL, /* limit bitset */
- { -1, -1 }, /* same pos */
- -1 /* different pos */
+ 0, /* same pos */
+ 0 /* different pos */
};
EOF
arch_register_req_type_normal,
& ${arch}_reg_classes[CLASS_${arch}_${class}],
NULL, /* limit bitset */
- { -1, -1 }, /* same pos */
- -1 /* different pos */
+ 0, /* same pos */
+ 0 /* different pos */
};
EOF
} else {
my @req_type_mask;
- my ($regclass, $limit_bitset, $same_pos, $same_pos2, $different_pos)
+ my ($regclass, $limit_bitset, $same_pos, $different_pos)
= build_subset_class_func($node, $op, $idx, $is_in, $reqs);
if (!defined($regclass)) {
if (defined($limit_bitset) && $limit_bitset ne "NULL") {
push(@req_type_mask, "arch_register_req_type_limited");
}
- if (defined($same_pos)) {
+ if ($same_pos != 0) {
push(@req_type_mask, "arch_register_req_type_should_be_same");
}
- if (defined($different_pos)) {
- if ($different_pos == 666) {
- push(@req_type_mask, "arch_register_req_type_should_be_different_from_all");
- undef $different_pos;
- } else {
- push(@req_type_mask, "arch_register_req_type_should_be_different");
- }
+ if ($different_pos != 0) {
+ push(@req_type_mask, "arch_register_req_type_should_be_different");
}
my $reqtype = join(" | ", @req_type_mask);
if(!defined($limit_bitset)) {
$limit_bitset = "NULL";
}
- my $same_pos_str = (defined($same_pos) ? $same_pos : "-1");
- my $same_pos_str2 = (defined($same_pos2) ? $same_pos2 : "-1");
- my $different_pos_str = (defined($different_pos) ? $different_pos : "-1");
$class = $regclass;
$result = <<EOF;
${reqtype},
& ${arch}_reg_classes[CLASS_${arch}_${class}],
${limit_bitset},
- { ${same_pos_str}, ${same_pos_str2} }, /* same pos */
- ${different_pos_str} /* different pos */
+ ${same_pos}, /* same pos */
+ ${different_pos} /* different pos */
};
EOF