* @file
* @brief This file implements the common parts of IR transformation from
* firm into ia32-Firm.
- * @author Sebastian Buchwald
+ * @author Matthias Braun, Sebastian Buchwald
* @version $Id: ia32_common_transform.c 21012 2008-08-06 13:35:17Z beck $
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
#include "error.h"
#include "irargs_t.h"
#include "typerep.h"
#include "../betranshlp.h"
+#include "../beirg_t.h"
#include "ia32_architecture.h"
#include "ia32_common_transform.h"
ir_node *gen_ASM(ir_node *node)
{
ir_graph *irg = current_ir_graph;
- ir_node *block = get_nodes_block(node);
- ir_node *new_block = be_transform_node(block);
+
+ ir_node *block = NULL;
+ ir_node *new_block = NULL;
+ switch (be_transformer) {
+ case TRANSFORMER_DEFAULT:
+ block = get_nodes_block(node);
+ new_block = be_transform_node(block);
+ break;
+
+#ifdef FIRM_GRGEN_BE
+ case TRANSFORMER_PBQP:
+ new_block = get_nodes_block(node);
+ break;
+#endif
+
+ default: panic("invalid transformer");
+ }
+
dbg_info *dbgi = get_irn_dbg_info(node);
int i, arity;
int out_idx;
const ir_asm_constraint *out_constraints;
ident **clobbers;
int clobbers_flags = 0;
+ unsigned clobber_bits[N_CLASSES];
+
+ memset(&clobber_bits, 0, sizeof(clobber_bits));
/* workaround for lots of buggy code out there as most people think volatile
* asm is enough for everything and forget the flags (linux kernel, etc.)
clobbers = get_ASM_clobbers(node);
n_clobbers = 0;
for(i = 0; i < get_ASM_n_clobbers(node); ++i) {
- const char *c = get_id_str(clobbers[i]);
+ const arch_register_req_t *req;
+ const char *c = get_id_str(clobbers[i]);
+
if (strcmp(c, "memory") == 0)
continue;
if (strcmp(c, "cc") == 0) {
clobbers_flags = 1;
continue;
}
+
+ req = parse_clobber(c);
+ clobber_bits[req->cls->index] |= *req->limited;
+
n_clobbers++;
}
n_out_constraints = get_ASM_n_output_constraints(node);
unsigned pos = constraint->pos;
int is_memory_op = 0;
ir_node *input = NULL;
+ unsigned r_clobber_bits;
constraint_t parsed_constraint;
const arch_register_req_t *req;
parse_asm_constraints(&parsed_constraint, c, 0);
+ if (parsed_constraint.cls != NULL) {
+ r_clobber_bits = clobber_bits[parsed_constraint.cls->index];
+ if (r_clobber_bits != 0) {
+ if (parsed_constraint.all_registers_allowed) {
+ parsed_constraint.all_registers_allowed = 0;
+ be_abi_set_non_ignore_regs(env_cg->birg->abi,
+ parsed_constraint.cls,
+ &parsed_constraint.allowed_registers);
+ }
+ parsed_constraint.allowed_registers &= ~r_clobber_bits;
+ }
+ }
+
req = make_register_req(&parsed_constraint, n_out_constraints,
out_reg_reqs, i);
in_reg_reqs[i] = req;
}
if (input == NULL) {
- ir_node *pred = get_irn_n(node, i);
- input = be_transform_node(pred);
+ ir_node *pred = NULL;
+ switch (be_transformer) {
+ case TRANSFORMER_DEFAULT:
+ pred = get_irn_n(node, i);
+ input = be_transform_node(pred);
+ break;
+
+#ifdef FIRM_GRGEN_BE
+ case TRANSFORMER_PBQP:
+ input = get_irn_n(node, i);
+ break;
+#endif
+
+ default: panic("invalid transformer");
+ }
if (parsed_constraint.cls == NULL
&& parsed_constraint.same_as < 0) {