- my @class = @{ $reg_classes{"$class_name"} };
- my $old_classname = $class_name;
-
- $class_name = $arch."_".$class_name;
- $numregs = "N_".$class_name."_REGS";
- $class_ptr = "&".$arch."_reg_classes[CLASS_".$class_name."]";
-
- push(@obst_regtypes, "#define $numregs ".($#class + 1)."\n");
- push(@obst_regtypes, "arch_register_t ".$class_name."_regs[$numregs];\n\n");
-
- push(@obst_classdef, "#define CLASS_$class_name $class_idx\n");
- push(@obst_regclasses, "{ \"$class_name\", $numregs, ".$class_name."_regs }");
-
- # there is a default NORMAL requirement for each class
- $tmp = "/* Default NORMAL register requirements for class $class_name */\n";
- $tmp .= "const arch_register_req_t ia32_default_req_$class_name = {\n";
- $tmp .= " arch_register_req_type_normal,\n";
- $tmp .= " $class_ptr,\n";
- $tmp .= " { NULL }\n";
- $tmp .= "};\n\n";
- push(@obst_req, $tmp);
-
- push(@obst_header_all, "\nextern const arch_register_req_t ia32_default_req_$class_name;\n");
-
- my $idx = 0;
- push(@obst_reginit, " /* Init of all registers in class '$class_name' */\n\n");
- foreach (@class) {
- # For each class we build for each of it's member registers a limit function
- # which limits the class to this particular register. We also build the
- # corresponding requirement structs.
- # We need those functions to set register requirements on demand in transformation
- # esp. for Call and RegParams where we can mix int and float parameters.
-
- my $limit_func_name = $arch."_limit_".$class_name."_".$_->{"name"};
-
- # push the function prototype
- $tmp = "int $limit_func_name(const ir_node *irn, int pos, bitset_t *bs)";
- push(@obst_defreq_head, $tmp.";\n");
-
- # push the function definition
- $tmp .= " {\n";
- $tmp .= " bs = bitset_clear_all(bs);\n";
- $tmp .= " bitset_set(bs, REG_".uc($_->{"name"}).");\n"; # REGISTER to index assignment is done some lines down
- $tmp .= " return 1;\n";
- $tmp .= "}\n\n";
- push(@obst_limit_func, $tmp);
-
- # push the default requirement struct
- $tmp = "const arch_register_req_t ia32_default_req_$class_name\_".$_->{"name"}." = {\n";
- $tmp .= " arch_register_req_type_limited,\n";
- $tmp .= " $class_ptr,\n";
- $tmp .= " { $limit_func_name }\n";
- $tmp .= "};\n\n";
- push(@obst_req, $tmp);
-
- push(@obst_header_all, "extern const arch_register_req_t ia32_default_req_$class_name\_".$_->{"name"}.";\n");
-
- $reg2class{$_->{"name"}} = { "class" => $old_classname, "index" => $idx }; # remember reg to class for later use
- push(@obst_regdef, "#define REG_".uc($_->{"name"})." $idx\n");
- push(@obst_reginit, " ".$class_name."_regs[$idx].name = \"".$_->{"name"}."\";\n");
- push(@obst_reginit, " ".$class_name."_regs[$idx].reg_class = $class_ptr;\n");
- push(@obst_reginit, " ".$class_name."_regs[$idx].index = $idx;\n");
- push(@obst_reginit, " ".$class_name."_regs[$idx].type = ".$rt[$_->{"type"}].";\n\n");
- $idx++;
- }
-
- $class_idx++;
+ my @class = @{ $reg_classes{"$class_name"} };
+ my $old_classname = $class_name;
+
+ $class_name = $arch."_".$class_name;
+ $numregs = "N_".$class_name."_REGS";
+ $class_ptr = "&".$arch."_reg_classes[CLASS_".$class_name."]";
+ $class_mode = pop(@class)->{"mode"};
+
+ push(@obst_regtypes_decl, "extern arch_register_t ".$class_name."_regs[$numregs];\n");
+ push(@obst_regtypes_def, "arch_register_t ".$class_name."_regs[$numregs];\n");
+
+ push(@obst_classdef, " CLASS_$class_name = $class_idx,\n");
+ push(@obst_regclasses, "{ \"$class_name\", $numregs, NULL, ".$class_name."_regs }");
+
+ # there is a default NORMAL requirement for each class
+ $tmp = "/* Default NORMAL register requirements for class $class_name */\n";
+ $tmp .= "const $arch\_register_req_t $arch\_default_req_$class_name = {\n";
+ $tmp .= " {\n";
+ $tmp .= " arch_register_req_type_normal,\n";
+ $tmp .= " $class_ptr,\n";
+ $tmp .= " NULL, /* limit function */ \n";
+ $tmp .= " NULL, /* limit environment */\n";
+ $tmp .= " NULL, /* node for same */\n";
+ $tmp .= " NULL /* node for different */\n";
+ $tmp .= " },\n";
+ $tmp .= " 0, /* same pos */\n";
+ $tmp .= " 0 /* different pos */\n";
+ $tmp .= "};\n\n";
+ push(@obst_req, $tmp);
+ push(@obst_header_all, "extern const $arch\_register_req_t $arch\_default_req_$class_name;\n");
+
+ my $idx = 0;
+ push(@obst_reginit, " /* Init of all registers in class '$class_name' */\n\n");
+ push(@obst_reginit, " /* set largest possible mode for '$class_name' */\n");
+ push(@obst_reginit, " $arch\_reg_classes[CLASS_".$class_name."].mode = $class_mode;\n\n");
+ push(@obst_regdef, "enum reg_".$class_name."_values {\n");
+ foreach (@class) {
+ # For each class we build for each of it's member registers a limit function
+ # which limits the class to this particular register. We also build the
+ # corresponding requirement structs.
+ # We need those functions to set register requirements on demand in transformation
+ # esp. for Call and RegParams where we can mix int and float parameters.
+
+ my $limit_func_name = $arch."_limit_".$class_name."_".$_->{"name"};
+
+ # push the function prototype
+ $tmp = "void $limit_func_name(void *_unused, bitset_t *bs)";
+ push(@obst_defreq_head, $tmp.";\n");
+
+ # push the function definition
+ $tmp .= " {\n";
+ $tmp .= " bs = bitset_clear_all(bs);\n";
+ $tmp .= " bitset_set(bs, REG_".uc($_->{"name"}).");\n"; # REGISTER to index assignment is done some lines down
+ $tmp .= "}\n\n";
+ push(@obst_limit_func, $tmp);
+
+ # push the default requirement struct
+ $tmp = "const $arch\_register_req_t $arch\_default_req_$class_name\_".$_->{"name"}." = {\n";
+ $tmp .= " {\n";
+ $tmp .= " arch_register_req_type_limited,\n";
+ $tmp .= " $class_ptr,\n";
+ $tmp .= " $limit_func_name,\n";
+ $tmp .= " NULL, /* limit environment */\n";
+ $tmp .= " NULL, /* node for same */\n";
+ $tmp .= " NULL /* node for different */\n";
+ $tmp .= " },\n";
+ $tmp .= " 0, /* same pos */\n";
+ $tmp .= " 0 /* different pos */\n";
+ $tmp .= "};\n\n";
+ push(@obst_req, $tmp);
+ push(@obst_header_all,"extern const $arch\_register_req_t $arch\_default_req_$class_name\_".$_->{"name"}.";\n");
+
+ $reg2class{$_->{"name"}} = { "class" => $old_classname, "index" => $idx }; # remember reg to class for later use
+ push(@obst_regdef, " REG_".uc($_->{"name"})." = $idx,\n");
+ push(@obst_reginit, " ".$class_name."_regs[$idx].name = \"".$_->{"name"}."\";\n");
+ push(@obst_reginit, " ".$class_name."_regs[$idx].reg_class = $class_ptr;\n");
+ push(@obst_reginit, " ".$class_name."_regs[$idx].index = $idx;\n");
+ push(@obst_reginit, " ".$class_name."_regs[$idx].type = ".translate_reg_type($_->{"type"}).";\n");
+ push(@obst_reginit, "\n");
+ $idx++;
+ }
+ push(@obst_regdef, " $numregs = $idx\n");
+ push(@obst_regdef, "};\n\n");
+
+ $class_idx++;