#define NEW_BD_DIVOP(instr) \
static ir_node * \
new_bd_##instr(dbg_info *db, ir_node *block, \
- ir_node *memop, ir_node *op1, ir_node *op2) \
+ ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) \
{ \
ir_node *in[3]; \
ir_node *res; \
in[1] = op1; \
in[2] = op2; \
res = new_ir_node(db, irg, block, op_##instr, mode_T, 3, in); \
+ res->attr.divmod.exc.pin_state = op_pin_state_pinned; \
+ res->attr.divmod.res_mode = mode; \
res = optimize_node(res); \
IRN_VRFY_IRG(res, irg); \
return res; \
#define NEW_RD_DIVOP(instr) \
ir_node * \
new_rd_##instr(dbg_info *db, ir_graph *irg, ir_node *block, \
- ir_node *memop, ir_node *op1, ir_node *op2) \
+ ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) \
{ \
ir_node *res; \
ir_graph *rem = current_ir_graph; \
current_ir_graph = irg; \
- res = new_bd_##instr(db, block, memop, op1, op2); \
+ res = new_bd_##instr(db, block, memop, op1, op2, mode); \
current_ir_graph = rem; \
return res; \
}
/**
* Constructs a Block with a fixed number of predecessors.
- * Does not set current_block. Can not be used with automatic
+ * Does not set current_block. Cannot be used with automatic
* Phi node construction.
*/
static ir_node *
-new_bd_Block(dbg_info *db, int arity, ir_node **in) {
+new_bd_Block(dbg_info *db, int arity, ir_node **in) {
ir_node *res;
ir_graph *irg = current_ir_graph;
- res = new_ir_node (db, irg, NULL, op_Block, mode_BB, arity, in);
- set_Block_matured(res, 1);
- set_Block_block_visited(res, 0);
+ res = new_ir_node(db, irg, NULL, op_Block, mode_BB, arity, in);
- /* res->attr.block.exc = exc_normal; */
- /* res->attr.block.handler_entry = 0; */
- res->attr.block.dead = 0;
+ /* macroblock header */
+ res->in[0] = res;
+
+ res->attr.block.is_dead = 0;
+ res->attr.block.is_mb_head = 1;
res->attr.block.irg = irg;
res->attr.block.backedge = new_backedge_arr(irg->obst, arity);
res->attr.block.in_cg = NULL;
res->attr.block.cg_backedge = NULL;
res->attr.block.extblk = NULL;
+ res->attr.block.mb_depth = 0;
- IRN_VRFY_IRG(res, irg);
+ set_Block_matured(res, 1);
+ set_Block_block_visited(res, 0);
+
+ IRN_VRFY_IRG(res, irg);
return res;
- } /* new_bd_Block */
+} /* new_bd_Block */
static ir_node *
new_bd_Start(dbg_info *db, ir_node *block) {
ir_graph *irg = current_ir_graph;
res = new_ir_node(db, irg, block, op_Start, mode_T, 0, NULL);
- /* res->attr.start.irg = irg; */
IRN_VRFY_IRG(res, irg);
return res;
break;
}
- if (!has_unknown) res = optimize_node (res);
+ if (!has_unknown) res = optimize_node(res);
IRN_VRFY_IRG(res, irg);
/* Memory Phis in endless loops must be kept alive.
return res;
} /* new_bd_Pin */
+static ir_node *
+new_bd_ASM(dbg_info *db, ir_node *block, ir_node *store, int arity, ir_node *inputs[], ident *asm_text) {
+ ir_node *res, **in;
+ ir_graph *irg = current_ir_graph;
+ int i;
+
+ NEW_ARR_A(ir_node *, in, arity + 1);
+
+ in[0] = store;
+ for (i = 0; i < arity; ++i)
+ in[i + 1] = inputs[i];
+
+ res = new_ir_node(db, irg, block, op_ASM, mode_T, arity + 1, in);
+ res->attr.assem.asm_text = asm_text;
+
+ res = optimize_node(res);
+ IRN_VRFY_IRG(res, irg);
+ return res;
+} /* new_bd_ASM */
+
/* --------------------------------------------- */
/* private interfaces, for professional use only */
/* --------------------------------------------- */
Does not set current_block. Can not be used with automatic
Phi node construction. */
ir_node *
-new_rd_Block(dbg_info *db, ir_graph *irg, int arity, ir_node **in) {
+new_rd_Block(dbg_info *db, ir_graph *irg, int arity, ir_node **in) {
ir_graph *rem = current_ir_graph;
ir_node *res;
return res;
} /* new_rd_Pin */
+ir_node *new_rd_ASM(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store,
+ int arity, ir_node *inputs[], ident *asm_text) {
+ ir_node *res;
+ ir_graph *rem = current_ir_graph;
+
+ current_ir_graph = irg;
+ res = new_bd_ASM(db, block, store, arity, inputs, asm_text);
+ current_ir_graph = rem;
+
+ return res;
+} /* new_rd_ASM */
+
+
ir_node *new_r_Block(ir_graph *irg, int arity, ir_node **in) {
return new_rd_Block(NULL, irg, arity, in);
}
return new_rd_Mul(NULL, irg, block, op1, op2, mode);
}
ir_node *new_r_Quot(ir_graph *irg, ir_node *block,
- ir_node *memop, ir_node *op1, ir_node *op2) {
- return new_rd_Quot(NULL, irg, block, memop, op1, op2);
+ ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
+ return new_rd_Quot(NULL, irg, block, memop, op1, op2, mode);
}
ir_node *new_r_DivMod(ir_graph *irg, ir_node *block,
- ir_node *memop, ir_node *op1, ir_node *op2) {
- return new_rd_DivMod(NULL, irg, block, memop, op1, op2);
+ ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
+ return new_rd_DivMod(NULL, irg, block, memop, op1, op2, mode);
}
ir_node *new_r_Div(ir_graph *irg, ir_node *block,
- ir_node *memop, ir_node *op1, ir_node *op2) {
- return new_rd_Div(NULL, irg, block, memop, op1, op2);
+ ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
+ return new_rd_Div(NULL, irg, block, memop, op1, op2, mode);
}
ir_node *new_r_Mod(ir_graph *irg, ir_node *block,
- ir_node *memop, ir_node *op1, ir_node *op2) {
- return new_rd_Mod(NULL, irg, block, memop, op1, op2);
+ ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
+ return new_rd_Mod(NULL, irg, block, memop, op1, op2, mode);
}
ir_node *new_r_Abs(ir_graph *irg, ir_node *block,
ir_node *op, ir_mode *mode) {
ir_node *new_r_Pin(ir_graph *irg, ir_node *block, ir_node *node) {
return new_rd_Pin(NULL, irg, block, node);
}
+ir_node *new_r_ASM(ir_graph *irg, ir_node *block, ir_node *store,
+ int arity, ir_node *inputs[], ident *asm_text) {
+ return new_rd_ASM(NULL, irg, block, store, arity, inputs, asm_text);
+}
/** ********************/
/** public interfaces */
/* case 2 -- If the value is actually computed, return it. */
if (res) return res;
- if (block->attr.block.matured) { /* case 3 */
+ if (block->attr.block.is_matured) { /* case 3 */
/* The Phi has the same amount of ins as the corresponding block. */
int ins = get_irn_arity(block);
/* Error Message */
printf("Error: no value set. Use of undefined variable. Initializing to zero.\n");
assert(mode->code >= irm_F && mode->code <= irm_P);
- res = new_rd_Const(NULL, current_ir_graph, block, mode,
- tarval_mode_null[mode->code]);
+ res = new_rd_Const(NULL, current_ir_graph, block, mode, tarval_mode_null[mode->code]);
}
/* The local valid value is available now. */
if (block->attr.block.graph_arr[pos]) {
/* There was a set_value() after the cfOp and no get_value before that
set_value(). We must build a Phi node now. */
- if (block->attr.block.matured) {
+ if (block->attr.block.is_matured) {
int ins = get_irn_arity(block);
ir_node **nin;
- NEW_ARR_A (ir_node *, nin, ins);
+ NEW_ARR_A(ir_node *, nin, ins);
res = phi_merge(block, pos, mode, nin, ins);
} else {
- res = new_rd_Phi0 (current_ir_graph, block, mode);
- res->attr.phi0_pos = pos;
+ res = new_rd_Phi0(current_ir_graph, block, mode);
+ res->attr.phi0.pos = pos;
res->link = block->link;
block->link = res;
}
/* case 2 -- If the value is actually computed, return it. */
if (res) { return res; };
- if (block->attr.block.matured) { /* case 3 */
+ if (block->attr.block.is_matured) { /* case 3 */
/* The Phi has the same amount of ins as the corresponding block. */
int ins = get_irn_arity(block);
The Phi0 has to remember the pos of it's internal value. If the real
Phi is computed, pos is used to update the array with the local
values. */
- res = new_rd_Phi0 (current_ir_graph, block, mode);
- res->attr.phi0_pos = pos;
+ res = new_rd_Phi0(current_ir_graph, block, mode);
+ res->attr.phi0.pos = pos;
res->link = block->link;
block->link = res;
}
assert (!get_Block_matured(block) && "Block already matured"); */
if (!get_Block_matured(block)) {
- ins = ARR_LEN (block->in)-1;
+ ins = ARR_LEN(block->in)-1;
/* Fix block parameters */
block->attr.block.backedge = new_backedge_arr(current_ir_graph->obst, ins);
/* An array for building the Phi nodes. */
- NEW_ARR_A (ir_node *, nin, ins);
+ NEW_ARR_A(ir_node *, nin, ins);
/* Traverse a chain of Phi nodes attached to this block and mature
these, too. **/
for (n = block->link; n; n = next) {
inc_irg_visited(current_ir_graph);
next = n->link;
- exchange(n, phi_merge (block, n->attr.phi0_pos, n->mode, nin, ins));
+ exchange(n, phi_merge(block, n->attr.phi0.pos, n->mode, nin, ins));
}
- block->attr.block.matured = 1;
+ block->attr.block.is_matured = 1;
/* Now, as the block is a finished firm node, we can optimize it.
Since other nodes have been allocated since the block was created
} /* allocate_frag_arr */
ir_node *
-new_d_Quot(dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2) {
+new_d_Quot(dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
ir_node *res;
- res = new_bd_Quot(db, current_ir_graph->current_block, memop, op1, op2);
- res->attr.except.pin_state = op_pin_state_pinned;
+ res = new_bd_Quot(db, current_ir_graph->current_block, memop, op1, op2, mode);
#if PRECISE_EXC_CONTEXT
allocate_frag_arr(res, op_Quot, &res->attr.except.frag_arr); /* Could be optimized away. */
#endif
} /* new_d_Quot */
ir_node *
-new_d_DivMod(dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2) {
+new_d_DivMod(dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
ir_node *res;
- res = new_bd_DivMod(db, current_ir_graph->current_block, memop, op1, op2);
- res->attr.except.pin_state = op_pin_state_pinned;
+ res = new_bd_DivMod(db, current_ir_graph->current_block, memop, op1, op2, mode);
#if PRECISE_EXC_CONTEXT
allocate_frag_arr(res, op_DivMod, &res->attr.except.frag_arr); /* Could be optimized away. */
#endif
} /* new_d_DivMod */
ir_node *
-new_d_Div(dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2) {
+new_d_Div(dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
ir_node *res;
- res = new_bd_Div(db, current_ir_graph->current_block, memop, op1, op2);
- res->attr.except.pin_state = op_pin_state_pinned;
+ res = new_bd_Div(db, current_ir_graph->current_block, memop, op1, op2, mode);
#if PRECISE_EXC_CONTEXT
allocate_frag_arr(res, op_Div, &res->attr.except.frag_arr); /* Could be optimized away. */
#endif
}
ir_node *
-new_d_Mod(dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2) {
+new_d_Mod(dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
ir_node *res;
- res = new_bd_Mod(db, current_ir_graph->current_block, memop, op1, op2);
- res->attr.except.pin_state = op_pin_state_pinned;
+ res = new_bd_Mod(db, current_ir_graph->current_block, memop, op1, op2, mode);
#if PRECISE_EXC_CONTEXT
allocate_frag_arr(res, op_Mod, &res->attr.except.frag_arr); /* Could be optimized away. */
#endif
return new_bd_Pin(db, current_ir_graph->current_block, node);
} /* new_d_Pin */
+ir_node *
+new_d_ASM(dbg_info *db, ir_node *store, int arity, ir_node *inputs[], ident *asm_text) {
+ return new_bd_ASM(db, current_ir_graph->current_block, store, arity, inputs, asm_text);
+} /* new_d_ASM */
+
/* ********************************************************************* */
/* Comfortable interface with automatic Phi node construction. */
/* (Uses also constructors of ?? interface, except new_Block. */
/* Block construction */
/* immature Block without predecessors */
-ir_node *new_d_immBlock(dbg_info *db) {
+ir_node *
+new_d_immBlock(dbg_info *db) {
ir_node *res;
assert(get_irg_phase_state(current_ir_graph) == phase_building);
/* creates a new dynamic in-array as length of in is -1 */
- res = new_ir_node (db, current_ir_graph, NULL, op_Block, mode_BB, -1, NULL);
+ res = new_ir_node(db, current_ir_graph, NULL, op_Block, mode_BB, -1, NULL);
current_ir_graph->current_block = res;
- res->attr.block.matured = 0;
- res->attr.block.dead = 0;
+
+ /* macroblock head */
+ res->in[0] = res;
+
+ res->attr.block.is_matured = 0;
+ res->attr.block.is_dead = 0;
+ res->attr.block.is_mb_head = 1;
res->attr.block.irg = current_ir_graph;
res->attr.block.backedge = NULL;
res->attr.block.in_cg = NULL;
res->attr.block.cg_backedge = NULL;
res->attr.block.extblk = NULL;
res->attr.block.region = NULL;
+ res->attr.block.mb_depth = 0;
+
set_Block_block_visited(res, 0);
/* Create and initialize array for Phi-node construction. */
return new_d_immBlock(NULL);
} /* new_immBlock */
+/* immature PartBlock with its predecessors */
+ir_node *
+new_d_immPartBlock(dbg_info *db, ir_node *pred_jmp) {
+ ir_node *res = new_d_immBlock(db);
+ ir_node *blk = get_nodes_block(pred_jmp);
+
+ res->in[0] = blk->in[0];
+ res->attr.block.is_mb_head = 0;
+ res->attr.block.mb_depth = blk->attr.block.mb_depth + 1;
+
+ add_immBlock_pred(res, pred_jmp);
+
+ return res;
+} /* new_d_immPartBlock */
+
+ir_node *
+new_immPartBlock(ir_node *pred_jmp) {
+ return new_d_immPartBlock(NULL, pred_jmp);
+} /* new_immPartBlock */
+
/* add an edge to a jmp/control flow node */
void
add_immBlock_pred(ir_node *block, ir_node *jmp) {
- if (block->attr.block.matured) {
- assert(0 && "Error: Block already matured!\n");
- } else {
- int n = ARR_LEN(block->in) - 1;
- assert(jmp != NULL);
- ARR_APP1(ir_node *, block->in, jmp);
- /* Call the hook */
- hook_set_irn_n(block, n, jmp, NULL);
- }
+ int n = ARR_LEN(block->in) - 1;
+
+ assert(!block->attr.block.is_matured && "Error: Block already matured!\n");
+ assert(block->attr.block.is_mb_head && "Error: Cannot add a predecessor to a PartBlock");
+ assert(jmp != NULL);
+
+ ARR_APP1(ir_node *, block->in, jmp);
+ /* Call the hook */
+ hook_set_irn_n(block, n, jmp, NULL);
} /* add_immBlock_pred */
/* changing the current block */
ir_node *new_Mul(ir_node *op1, ir_node *op2, ir_mode *mode) {
return new_d_Mul(NULL, op1, op2, mode);
}
-ir_node *new_Quot(ir_node *memop, ir_node *op1, ir_node *op2) {
- return new_d_Quot(NULL, memop, op1, op2);
+ir_node *new_Quot(ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
+ return new_d_Quot(NULL, memop, op1, op2, mode);
}
-ir_node *new_DivMod(ir_node *memop, ir_node *op1, ir_node *op2) {
- return new_d_DivMod(NULL, memop, op1, op2);
+ir_node *new_DivMod(ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
+ return new_d_DivMod(NULL, memop, op1, op2, mode);
}
-ir_node *new_Div(ir_node *memop, ir_node *op1, ir_node *op2) {
- return new_d_Div(NULL, memop, op1, op2);
+ir_node *new_Div(ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
+ return new_d_Div(NULL, memop, op1, op2, mode);
}
-ir_node *new_Mod(ir_node *memop, ir_node *op1, ir_node *op2) {
- return new_d_Mod(NULL, memop, op1, op2);
+ir_node *new_Mod(ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode) {
+ return new_d_Mod(NULL, memop, op1, op2, mode);
}
ir_node *new_Abs(ir_node *op, ir_mode *mode) {
return new_d_Abs(NULL, op, mode);
ir_node *new_Pin(ir_node *node) {
return new_d_Pin(NULL, node);
}
+ir_node *new_ASM(ir_node *store, int arity, ir_node *inputs[], ident *asm_text) {
+ return new_d_ASM(NULL, store, arity, inputs, asm_text);
+}