* @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"
ir_node *start_block = get_irg_start_block(irg);
ir_node *immediate = new_rd_ia32_Immediate(NULL, irg, start_block,
symconst, symconst_sign, val);
- arch_set_irn_register(env_cg->arch_env, immediate, &ia32_gp_regs[REG_GP_NOREG]);
+ arch_set_irn_register(immediate, &ia32_gp_regs[REG_GP_NOREG]);
return immediate;
}
#ifndef NDEBUG
const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
- ia32_isa_t *isa = (ia32_isa_t*) cg->arch_env;
+ const ia32_isa_t *isa = cg->isa;
lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
obstack_1grow(isa->name_obst, 0);
static void parse_asm_constraints(constraint_t *constraint, const char *c,
int is_output)
{
- asm_constraint_flags_t flags = 0;
char immediate_type = '\0';
unsigned limited = 0;
const arch_register_class_t *cls = NULL;
case '\n':
break;
- case '=':
- flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE
- | ASM_CONSTRAINT_FLAG_MODIFIER_NO_READ;
- break;
-
- case '+':
- flags |= ASM_CONSTRAINT_FLAG_MODIFIER_WRITE
- | ASM_CONSTRAINT_FLAG_MODIFIER_READ;
- break;
+ /* Skip out/in-out marker */
+ case '=': break;
+ case '+': break;
case '*':
++c;
#ifdef FIRM_GRGEN_BE
case TRANSFORMER_PBQP:
+ case TRANSFORMER_RAND:
new_block = get_nodes_block(node);
break;
#endif
#ifdef FIRM_GRGEN_BE
case TRANSFORMER_PBQP:
+ case TRANSFORMER_RAND:
input = get_irn_n(node, i);
break;
#endif
new_node = new_rd_ia32_Asm(dbgi, irg, new_block, arity, in, out_arity,
get_ASM_text(node), register_map);
+ if (arity == 0)
+ be_dep_on_frame(new_node);
+
set_ia32_out_req_all(new_node, out_reg_reqs);
set_ia32_in_req_all(new_node, in_reg_reqs);
#ifdef FIRM_GRGEN_BE
case TRANSFORMER_PBQP:
+ case TRANSFORMER_RAND:
block = get_nodes_block(node);
new_src = get_CopyB_src(node);
new_dst = get_CopyB_dst(node);
size >>= 2;
res = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, size);
- add_irn_dep(res, get_irg_frame(irg));
+ be_dep_on_frame(res);
res = new_rd_ia32_CopyB(dbgi, irg, block, new_dst, new_src, res, new_mem, rem);
} else {
#ifdef FIRM_GRGEN_BE
case TRANSFORMER_PBQP:
+ case TRANSFORMER_RAND:
block = get_nodes_block(node);
break;
#endif
ir_node *block = get_irg_start_block(irg);
ir_node *ret = new_rd_ia32_vfldz(dbgi, irg, block);
- /* Const Nodes before the initial IncSP are a bad idea, because
- * they could be spilled and we have no SP ready at that point yet.
- * So add a dependency to the initial frame pointer calculation to
- * avoid that situation.
- */
- add_irn_dep(ret, get_irg_frame(irg));
+ be_dep_on_frame(ret);
return ret;
}
} else if (ia32_mode_needs_gp_reg(mode)) {
if (same_as >= n_outs)
panic("invalid output number in same_as constraint");
- other_constr = out_reqs[same_as];
+ other_constr = out_reqs[same_as];
- req = obstack_alloc(obst, sizeof(req[0]));
- req->cls = other_constr->cls;
- req->type = arch_register_req_type_should_be_same;
- req->limited = NULL;
- req->other_same = 1U << pos;
- req->other_different = 0;
+ req = obstack_alloc(obst, sizeof(req[0]));
+ *req = *other_constr;
+ req->type |= arch_register_req_type_should_be_same;
+ req->other_same = 1U << pos;
/* switch constraints. This is because in firm we have same_as
* constraints on the output constraints while in the gcc asm syntax
unsigned *limited;
if(reg == NULL) {
- panic("Register '%s' mentioned in asm clobber is unknown\n", clobber);
+ panic("Register '%s' mentioned in asm clobber is unknown", clobber);
}
assert(reg->index < 32);
return req;
}
+
+int prevents_AM(ir_node *const block, ir_node *const am_candidate,
+ ir_node *const other)
+{
+ if (get_nodes_block(other) != block)
+ return 0;
+
+ if (is_Sync(other)) {
+ int i;
+
+ for (i = get_Sync_n_preds(other) - 1; i >= 0; --i) {
+ ir_node *const pred = get_Sync_pred(other, i);
+
+ if (get_nodes_block(pred) != block)
+ continue;
+
+ /* Do not block ourselves from getting eaten */
+ if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate)
+ continue;
+
+ if (!heights_reachable_in_block(heights, pred, am_candidate))
+ continue;
+
+ return 1;
+ }
+
+ return 0;
+ } else {
+ /* Do not block ourselves from getting eaten */
+ if (is_Proj(other) && get_Proj_pred(other) == am_candidate)
+ return 0;
+
+ if (!heights_reachable_in_block(heights, other, am_candidate))
+ return 0;
+
+ return 1;
+ }
+}
+
ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type)
{
int minus = 0;