ia32_emit_mode_suffix_mode(mode);
}
-static
-char get_xmm_mode_suffix(ir_mode *mode)
+static char get_xmm_mode_suffix(ir_mode *mode)
{
assert(mode_is_float(mode));
switch(get_mode_size_bits(mode)) {
}
}
-static
-void ia32_emit_function_object(const char *name)
+static void ia32_emit_function_object(const char *name)
{
switch (be_gas_flavour) {
case GAS_FLAVOUR_NORMAL:
}
}
-static
-void ia32_emit_function_size(const char *name)
+static void ia32_emit_function_size(const char *name)
{
switch (be_gas_flavour) {
case GAS_FLAVOUR_NORMAL:
/**
* Returns the target block for a control flow node.
*/
-static
-ir_node *get_cfop_target_block(const ir_node *irn) {
+static ir_node *get_cfop_target_block(const ir_node *irn) {
return get_irn_link(irn);
}
/**
* Emits a block label for the given block.
*/
-static
-void ia32_emit_block_name(const ir_node *block)
+static void ia32_emit_block_name(const ir_node *block)
{
if (has_Block_label(block)) {
be_emit_string(be_gas_label_prefix());
*/
static void emit_ia32_Jcc(const ir_node *node)
{
+ int need_parity_label = 0;
const ir_node *proj_true;
const ir_node *proj_false;
const ir_node *block;
/* Some floating point comparisons require a test of the parity flag,
* which indicates that the result is unordered */
switch (pnc & 15) {
- case pn_Cmp_Uo:
+ case pn_Cmp_Uo: {
be_emit_cstring("\tjp ");
ia32_emit_cfop_target(proj_true);
be_emit_finish_line_gas(proj_true);
break;
+ }
case pn_Cmp_Leg:
be_emit_cstring("\tjnp ");
case pn_Cmp_Eq:
case pn_Cmp_Lt:
- case pn_Cmp_Le: {
- ir_node *dest_block = get_cfop_target_block(proj_false);
- mark_Block_block_visited(dest_block);
-
- be_emit_cstring("\tjp ");
- ia32_emit_cfop_target(proj_false);
+ case pn_Cmp_Le:
+ /* we need a local label if the false proj is a fallthrough
+ * as the falseblock might have no label emitted then */
+ if (get_cfop_target_block(proj_false) == next_block) {
+ need_parity_label = 1;
+ be_emit_cstring("\tjp 1f");
+ } else {
+ be_emit_cstring("\tjp ");
+ ia32_emit_cfop_target(proj_false);
+ }
be_emit_finish_line_gas(proj_false);
goto emit_jcc;
- }
case pn_Cmp_Ug:
case pn_Cmp_Uge:
- case pn_Cmp_Ne: {
- ir_node *dest_block = get_cfop_target_block(proj_false);
- mark_Block_block_visited(dest_block);
-
+ case pn_Cmp_Ne:
be_emit_cstring("\tjp ");
ia32_emit_cfop_target(proj_true);
be_emit_finish_line_gas(proj_true);
goto emit_jcc;
- }
default:
goto emit_jcc;
be_emit_finish_line_gas(proj_true);
}
+ if(need_parity_label) {
+ be_emit_cstring("1:");
+ be_emit_write_line();
+ }
+
/* the second Proj might be a fallthrough */
if (get_cfop_target_block(proj_false) != next_block) {
be_emit_cstring("\tjmp ");
/**
* Compare two variables of type branch_t. Used to sort all switch cases
*/
-static
-int ia32_cmp_branch_t(const void *a, const void *b) {
+static int ia32_cmp_branch_t(const void *a, const void *b) {
branch_t *b1 = (branch_t *)a;
branch_t *b2 = (branch_t *)b;
* Enters the emitter functions for handled nodes into the generic
* pointer of an opcode.
*/
-static
-void ia32_register_emitters(void) {
+static void ia32_register_emitters(void) {
#define IA32_EMIT2(a,b) op_ia32_##a->ops.generic = (op_func)emit_ia32_##b
#define IA32_EMIT(a) IA32_EMIT2(a,a)
if(is_ia32_SwitchJmp(pred))
return 0;
- return Block_not_block_visited(get_nodes_block(cfgpred));
+ return 1;
}
static void ia32_emit_block_header(ir_node *block, ir_node *prev)
{
+ ir_graph *irg = current_ir_graph;
int n_cfgpreds;
int need_label = 1;
int i, arity;
ir_exec_freq *exec_freq = cg->birg->exec_freq;
+ if(block == get_irg_end_block(irg) || block == get_irg_start_block(irg))
+ return;
+
n_cfgpreds = get_Block_n_cfgpreds(block);
if(n_cfgpreds == 0) {
be_emit_char(':');
be_emit_pad_comment();
- be_emit_cstring(" /* preds:");
-
- /* emit list of pred blocks in comment */
- arity = get_irn_arity(block);
- for (i = 0; i < arity; ++i) {
- ir_node *predblock = get_Block_cfgpred_block(block, i);
- be_emit_irprintf(" %d", get_irn_node_nr(predblock));
- }
+ be_emit_cstring(" /* ");
} else {
be_emit_cstring("\t/* ");
ia32_emit_block_name(block);
be_emit_cstring(": ");
}
+
+ be_emit_cstring("preds:");
+
+ /* emit list of pred blocks in comment */
+ arity = get_irn_arity(block);
+ for (i = 0; i < arity; ++i) {
+ ir_node *predblock = get_Block_cfgpred_block(block, i);
+ be_emit_irprintf(" %d", get_irn_node_nr(predblock));
+ }
if (exec_freq != NULL) {
be_emit_irprintf(" freq: %f",
get_block_execfreq(exec_freq, block));
ia32_emit_func_prolog(irg);
irg_block_walk_graph(irg, ia32_gen_labels, NULL, NULL);
- /* we mark blocks that must have a label */
- set_using_block_visited(irg);
- inc_irg_block_visited(irg);
-
n = ARR_LEN(cg->blk_sched);
for (i = 0; i < n;) {
ir_node *next_bl;
last_block = block;
}
- clear_using_block_visited(irg);
-
ia32_emit_func_epilog(irg);
}