*
***************************************************************************************/
+static
+int TEMPLATE_compare_attr(ir_node *a, ir_node *b)
+{
+ const TEMPLATE_attr_t *attr_a = get_TEMPLATE_attr_const(a);
+ const TEMPLATE_attr_t *attr_b = get_TEMPLATE_attr_const(b);
+
+ if(attr_a->flags != attr_b->flags)
+ return 1;
+
+ return 0;
+}
+
+
/* Include the generated constructor functions */
#include "gen_TEMPLATE_new_nodes.c.inl"
# |_| #
#--------------------------------------------------#
+$default_cmp_attr = "NULL";
+
%nodes = (
#-----------------------------------------------------------------#
return x87_attr;
}
+const ia32_asm_attr_t *get_ia32_asm_attr_const(const ir_node *node) {
+ const ia32_attr_t *attr = get_ia32_attr_const(node);
+ const ia32_asm_attr_t *asm_attr = CONST_CAST_IA32_ATTR(ia32_asm_attr_t, attr);
+
+ return asm_attr;
+}
+
/**
* Gets the type of an ia32 node.
*/
return 0;
}
+static
+int ia32_compare_nodes_attr(ir_node *a, ir_node *b)
+{
+ const ia32_attr_t* attr_a = get_ia32_attr_const(a);
+ const ia32_attr_t* attr_b = get_ia32_attr_const(b);
+
+ return ia32_compare_attr(attr_a, attr_b);
+}
+
+static
+int ia32_compare_x87_attr(ir_node *a, ir_node *b)
+{
+ return ia32_compare_nodes_attr(a, b);
+}
+
+static
+int ia32_compare_asm_attr(ir_node *a, ir_node *b)
+{
+ const ia32_asm_attr_t *attr_a;
+ const ia32_asm_attr_t *attr_b;
+
+ if(ia32_compare_nodes_attr(a, b))
+ return 1;
+
+ attr_a = get_ia32_asm_attr_const(a);
+ attr_b = get_ia32_asm_attr_const(b);
+
+ if(attr_a->asm_text != attr_b->asm_text)
+ return 1;
+
+ return 0;
+}
+
/* copies the ia32 attributes */
static void ia32_copy_attr(const ir_node *old_node, ir_node *new_node)
{
# |_| #
#--------------------------------------------------#
-$default_cmp_attr = "return ia32_compare_attr(attr_a, attr_b);";
$default_attr_type = "ia32_attr_t";
%init_attr = (
);
%compare_attr = (
- ia32_attr_t => "return ia32_compare_attr(attr_a, attr_b);",
- ia32_x87_attr_t => "return ia32_compare_x87_attr(attr_a, attr_b);",
- ia32_asm_attr_t => "return ia32_compare_asm_attr(attr_a, attr_b);"
+ ia32_attr_t => "ia32_compare_nodes_attr",
+ ia32_x87_attr_t => "ia32_compare_x87_attr",
+ ia32_asm_attr_t => "ia32_compare_asm_attr",
);
%operands = (
static
ir_entity *mips_get_frame_entity(const void *self, const ir_node *node) {
- mips_attr_t *attr;
+ const mips_attr_t *attr;
if(!is_mips_irn(node))
return NULL;
- attr = get_mips_attr(node);
+ attr = get_mips_attr_const(node);
return attr->stack_entity;
}
void mips_emit_immediate(mips_emit_env_t *env, const ir_node *node)
{
- const mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
if(attr->tv != NULL) {
be_emit_tarval(env->emit, attr->tv);
* possible otherwise a cmp-jmp cascade). Stolen from ia32
*/
void emit_mips_jump_table(mips_emit_env_t *env, const ir_node *irn) {
- int lastval, i, i2, pn;
- jmp_tbl_t tbl;
- ir_node *proj;
- const ir_edge_t *edge;
- mips_attr_t *attr = get_mips_attr(irn);
+ int lastval, i, i2, pn;
+ jmp_tbl_t tbl;
+ ir_node *proj;
+ const ir_edge_t *edge;
+ const mips_attr_t *attr = get_mips_attr_const(irn);
/* fill the table structure */
tbl.label = xmalloc(SNPRINTF_BUF_LEN);
* |___/
***************************************************************************************************/
-/**
- * Wraps get_irn_generic_attr() as it takes no const ir_node, so we need to do a cast.
- * Firm was made by people hating const :-(
- */
-mips_attr_t *get_mips_attr(const ir_node *node) {
+mips_attr_t *get_mips_attr(ir_node *node) {
+ assert(is_mips_irn(node) && "need mips node to get attributes");
+ return (mips_attr_t *) get_irn_generic_attr(node);
+}
+
+const mips_attr_t *get_mips_attr_const(const ir_node *node) {
assert(is_mips_irn(node) && "need mips node to get attributes");
- return (mips_attr_t *)get_irn_generic_attr((ir_node *)node);
+ return get_irn_generic_attr_const(node);
}
/**
* Returns the argument register requirements of a mips node.
*/
const arch_register_req_t **get_mips_in_req_all(const ir_node *node) {
- mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
return attr->in_req;
}
* Returns the result register requirements of an mips node.
*/
const arch_register_req_t **get_mips_out_req_all(const ir_node *node) {
- mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
return attr->out_req;
}
* Returns the argument register requirement at position pos of an mips node.
*/
const arch_register_req_t *get_mips_in_req(const ir_node *node, int pos) {
- mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
return attr->in_req[pos];
}
* Returns the result register requirement at position pos of an mips node.
*/
const arch_register_req_t *get_mips_out_req(const ir_node *node, int pos) {
- mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
return attr->out_req[pos];
}
* Returns the register flag of an mips node.
*/
arch_irn_flags_t get_mips_flags(const ir_node *node) {
- mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
return attr->flags;
}
/**
* Sets the register flag of an mips node.
*/
-void set_mips_flags(const ir_node *node, arch_irn_flags_t flags) {
+void set_mips_flags(ir_node *node, arch_irn_flags_t flags) {
mips_attr_t *attr = get_mips_attr(node);
attr->flags = flags;
}
* Returns the result register slots of an mips node.
*/
const arch_register_t **get_mips_slots(const ir_node *node) {
- mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
return attr->slots;
}
* Returns the name of the OUT register at position pos.
*/
const char *get_mips_out_reg_name(const ir_node *node, int pos) {
- mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
assert(is_mips_irn(node) && "Not an mips node.");
assert(pos < ARR_LEN(attr->slots) && "Invalid OUT position.");
* Returns the index of the OUT register at position pos within its register class.
*/
int get_mips_out_regnr(const ir_node *node, int pos) {
- mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
assert(is_mips_irn(node) && "Not an mips node.");
assert(pos < ARR_LEN(attr->slots) && "Invalid OUT position.");
* Returns the OUT register at position pos.
*/
const arch_register_t *get_mips_out_reg(const ir_node *node, int pos) {
- mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
assert(is_mips_irn(node) && "Not an mips node.");
assert(pos < ARR_LEN(attr->slots) && "Invalid OUT position.");
* Returns the number of results.
*/
int get_mips_n_res(const ir_node *node) {
- mips_attr_t *attr = get_mips_attr(node);
+ const mips_attr_t *attr = get_mips_attr_const(node);
return ARR_LEN(attr->slots);
}
}
static
-int mips_compare_attr(const mips_attr_t *a, const mips_attr_t *b)
+int mips_compare_attr(ir_node *node_a, ir_node *node_b)
{
+ const mips_attr_t *a = get_mips_attr_const(node_a);
+ const mips_attr_t *b = get_mips_attr_const(node_b);
+
if(a->tv != b->tv)
return 1;
if(a->symconst != b->symconst)
/**
* Returns the attributes of an mips node.
*/
-mips_attr_t *get_mips_attr(const ir_node *node);
-
+mips_attr_t *get_mips_attr(ir_node *node);
+const mips_attr_t *get_mips_attr_const(const ir_node *node);
/**
* Returns the argument register requirements of an mips node.
*/
/**
* Sets the register flag of an mips node.
*/
-void set_mips_flags(const ir_node *node, arch_irn_flags_t flags);
+void set_mips_flags(ir_node *node, arch_irn_flags_t flags);
/**
* Returns the result register slots of an mips node.
# |_| #
#--------------------------------------------------#
-$default_cmp_attr = "return mips_compare_attr(attr_a, attr_b);";
-
%nodes = (
#-----------------------------------------------------------------#
RLWIMI => "${arch}_emit_rlwimi_helper(env, node);",
);
+$default_cmp_attr = "NULL";
+
#--------------------------------------------------#
# _ #
# (_) #
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;
"$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, "\tconst ${default_attr_type} *attr_a = get_irn_generic_attr_const(a);\n");
- }
- if($cmpcode =~ m/attr_b/) {
- push(@obst_cmp_attr, "\tconst ${default_attr_type} *attr_b = get_irn_generic_attr_const(b);\n");
- }
- push(@obst_cmp_attr, "\t${cmpcode}\n");
- push(@obst_cmp_attr, "}\n\n");
-}
-# TODO: create compare functions
-
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) {