#include "execfreq.h"
#include "error.h"
#include "raw_bitset.h"
+#include "dbginfo.h"
#include "../besched_t.h"
#include "../benode_t.h"
#include "ia32_nodes_attr.h"
#include "ia32_new_nodes.h"
#include "ia32_map_regs.h"
+#include "ia32_architecture.h"
#include "bearch_ia32_t.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
switch(get_mode_size_bits(mode)) {
case 32: be_emit_char('s'); return;
case 64: be_emit_char('l'); return;
- case 80: be_emit_char('t'); return;
+ case 80:
+ case 96: be_emit_char('t'); return;
}
} else {
assert(mode_is_int(mode) || mode_is_reference(mode));
}
}
+static void ia32_emit_entity(ir_entity *entity)
+{
+ ident *id;
+
+ set_entity_backend_marked(entity, 1);
+ id = get_entity_ld_ident(entity);
+ be_emit_ident(id);
+
+ if(get_entity_owner(entity) == get_tls_type()) {
+ if (get_entity_visibility(entity) == visibility_external_allocated) {
+ be_emit_cstring("@INDNTPOFF");
+ } else {
+ be_emit_cstring("@NTPOFF");
+ }
+ }
+}
+
/**
* Emits address mode.
*/
/* emit offset */
if (ent != NULL) {
- ident *id;
-
- set_entity_backend_marked(ent, 1);
- id = get_entity_ld_ident(ent);
if (is_ia32_am_sc_sign(node))
be_emit_char('-');
- be_emit_ident(id);
-
- if(get_entity_owner(ent) == get_tls_type()) {
- if (get_entity_visibility(ent) == visibility_external_allocated) {
- be_emit_cstring("@INDNTPOFF");
- } else {
- be_emit_cstring("@NTPOFF");
- }
- }
+ ia32_emit_entity(ent);
}
if(offs != 0) {
pnc = get_mirrored_pnc(pnc);
pnc |= ia32_pn_Cmp_float;
} else {
+#if 0
assert(is_ia32_Cmp(flags) || is_ia32_Test(flags)
|| is_ia32_Cmp8Bit(flags) || is_ia32_Test8Bit(flags));
+#endif
flags_attr = get_ia32_attr_const(flags);
if(flags_attr->data.ins_permuted)
* possible otherwise a cmp-jmp cascade). Port from
* cggg ia32 backend
*/
-static
-void emit_ia32_SwitchJmp(const ir_node *node) {
+static void emit_ia32_SwitchJmp(const ir_node *node)
+{
unsigned long interval;
int last_value, i;
long pnc;
+ long default_pn;
jmp_tbl_t tbl;
ir_node *proj;
const ir_edge_t *edge;
tbl.label = xmalloc(SNPRINTF_BUF_LEN);
tbl.label = get_unique_label(tbl.label, SNPRINTF_BUF_LEN, ".TBL_");
tbl.defProj = NULL;
- tbl.num_branches = get_irn_n_edges(node);
+ tbl.num_branches = get_irn_n_edges(node) - 1;
tbl.branches = xcalloc(tbl.num_branches, sizeof(tbl.branches[0]));
tbl.min_value = INT_MAX;
tbl.max_value = INT_MIN;
+ default_pn = get_ia32_condcode(node);
i = 0;
/* go over all proj's and collect them */
foreach_out_edge(node, edge) {
pnc = get_Proj_proj(proj);
- /* create branch entry */
- tbl.branches[i].target = proj;
- tbl.branches[i].value = pnc;
-
- tbl.min_value = pnc < tbl.min_value ? pnc : tbl.min_value;
- tbl.max_value = pnc > tbl.max_value ? pnc : tbl.max_value;
-
/* check for default proj */
- if (pnc == get_ia32_condcode(node)) {
- assert(tbl.defProj == NULL && "found two defProjs at SwitchJmp");
+ if (pnc == default_pn) {
+ assert(tbl.defProj == NULL && "found two default Projs at SwitchJmp");
tbl.defProj = proj;
+ } else {
+ tbl.min_value = pnc < tbl.min_value ? pnc : tbl.min_value;
+ tbl.max_value = pnc > tbl.max_value ? pnc : tbl.max_value;
+
+ /* create branch entry */
+ tbl.branches[i].target = proj;
+ tbl.branches[i].value = pnc;
+ ++i;
}
- i++;
}
+ assert(i == tbl.num_branches);
/* sort the branches by their number */
qsort(tbl.branches, tbl.num_branches, sizeof(tbl.branches[0]), ia32_cmp_branch_t);
be_emit_char('$');
if(attr->symconst != NULL) {
- ident *id = get_entity_ld_ident(attr->symconst);
-
if(attr->sc_sign)
be_emit_char('-');
- be_emit_ident(id);
+ ia32_emit_entity(attr->symconst);
}
if(attr->symconst == NULL || attr->offset != 0) {
if(attr->symconst != NULL) {
be_emit_cstring("\tcall ");
if (ent) {
- set_entity_backend_marked(ent, 1);
- be_emit_string(get_entity_ld_name(ent));
+ ia32_emit_entity(ent);
} else {
const arch_register_t *reg = get_in_reg(node, be_pos_Call_ptr);
be_emit_char('*');
{
dbg_info *db = get_irn_dbg_info(node);
unsigned lineno;
- const char *fname = be_retrieve_dbg_info(db, &lineno);
+ const char *fname = ir_retrieve_dbg_info(db, &lineno);
if (! cg->birg->main_env->options->stabs_debug_support)
return;
/**
* Emits gas alignment directives for Functions depended on cpu architecture.
*/
-static void ia32_emit_align_func(cpu_support cpu)
+static void ia32_emit_align_func(void)
{
- unsigned align;
- unsigned maximum_skip;
+ unsigned align = ia32_cg_config.function_alignment;
+ unsigned maximum_skip = (1 << align) - 1;
- switch (cpu) {
- case arch_i386:
- align = 2;
- break;
- case arch_i486:
- align = 4;
- break;
- case arch_k6:
- align = 5;
- break;
- default:
- align = 4;
- }
- maximum_skip = (1 << align) - 1;
ia32_emit_alignment(align, maximum_skip);
}
/**
* Emits gas alignment directives for Labels depended on cpu architecture.
*/
-static void ia32_emit_align_label(cpu_support cpu)
+static void ia32_emit_align_label(void)
{
- unsigned align; unsigned maximum_skip;
-
- switch (cpu) {
- case arch_i386:
- align = 2;
- break;
- case arch_i486:
- align = 4;
- break;
- case arch_k6:
- align = 5;
- break;
- default:
- align = 4;
- }
- maximum_skip = (1 << align) - 1;
+ unsigned align = ia32_cg_config.label_alignment;
+ unsigned maximum_skip = (1 << align) - 1;
ia32_emit_alignment(align, maximum_skip);
}
double block_freq;
double prev_freq = 0; /**< execfreq of the fallthrough block */
double jmp_freq = 0; /**< execfreq of all non-fallthrough blocks */
- cpu_support cpu = isa->opt_arch;
int i, n_cfgpreds;
if(exec_freq == NULL)
return 0;
- if(cpu == arch_i386 || cpu == arch_i486)
+ if(ia32_cg_config.label_alignment_factor <= 0)
return 0;
block_freq = get_block_execfreq(exec_freq, block);
jmp_freq /= prev_freq;
- switch (cpu) {
- case arch_athlon:
- case arch_athlon_64:
- case arch_k6:
- return jmp_freq > 3;
- default:
- return jmp_freq > 2;
- }
+ return jmp_freq > ia32_cg_config.label_alignment_factor;
}
static void ia32_emit_block_header(ir_node *block, ir_node *prev)
if (should_align_block(block, prev)) {
assert(need_label);
- ia32_emit_align_label(isa->opt_arch);
+ ia32_emit_align_label();
}
if(need_label) {
{
ir_entity *irg_ent = get_irg_entity(irg);
const char *irg_name = get_entity_ld_name(irg_ent);
- cpu_support cpu = isa->opt_arch;
const be_irg_t *birg = cg->birg;
/* write the begin line (used by scripts processing the assembler... */
be_gas_emit_switch_section(GAS_SECTION_TEXT);
be_dbg_method_begin(birg->main_env->db_handle, irg_ent, be_abi_get_stack_layout(birg->abi));
- ia32_emit_align_func(cpu);
+ ia32_emit_align_func();
if (get_entity_visibility(irg_ent) == visibility_external_visible) {
be_emit_cstring(".global ");
be_emit_string(irg_name);