assert(reg && "no in register found");
- /* in case of a joker register: just return a valid register */
- if (arch_register_type_is(reg, joker)) {
+ if(reg == &ia32_gp_regs[REG_GP_NOREG])
+ panic("trying to emit noreg");
+
+ /* in case of unknown register: just return a valid register */
+ if (reg == &ia32_gp_regs[REG_GP_UKNWN]) {
const arch_register_req_t *req;
/* ask for the requirements */
case 64:
return 'l';
case 80:
+ case 96:
return 't';
}
} else {
static
int produces_result(const ir_node *node) {
- return !(is_ia32_St(node) ||
- is_ia32_CondJmp(node) ||
- is_ia32_xCondJmp(node) ||
- is_ia32_CmpSet(node) ||
- is_ia32_xCmpSet(node) ||
- is_ia32_SwitchJmp(node));
+ return
+ !is_ia32_CmpSet(node) &&
+ !is_ia32_CondJmp(node) &&
+ !is_ia32_St(node) &&
+ !is_ia32_SwitchJmp(node) &&
+ !is_ia32_TestJmp(node) &&
+ !is_ia32_xCmpSet(node) &&
+ !is_ia32_xCondJmp(node);
}
static
return;
case ia32_ImmSymConst:
ent = get_ia32_Immop_symconst(node);
- mark_entity_visited(ent);
+ set_entity_backend_marked(ent, 1);
id = get_entity_ld_ident(ent);
be_emit_ident(env, id);
return;
* Emits registers and/or address mode of a binary operation.
*/
void ia32_emit_binop(ia32_emit_env_t *env, const ir_node *node) {
+ int right_pos;
const ir_node *right_op;
switch(get_ia32_op_type(node)) {
}
break;
case ia32_AddrModeD:
- right_op = get_irn_n(node, 3);
+ right_pos = get_irn_arity(node) == 5 ? 3 : 2;
+ right_op = get_irn_n(node, right_pos);
if(is_ia32_Immediate(right_op)) {
emit_ia32_Immediate(env, right_op);
be_emit_cstring(env, ", ");
be_emit_cstring(env, ", ");
ia32_emit_am(env, node);
} else {
- const arch_register_t *in1 = get_in_reg(env, node,
- get_irn_arity(node) == 5 ? 3 : 2);
+ const arch_register_t *in1 = get_in_reg(env, node, right_pos);
ir_mode *mode = get_ia32_ls_mode(node);
const char *in_name;
if (ent != NULL) {
ident *id;
- mark_entity_visited(ent);
+ set_entity_backend_marked(ent, 1);
id = get_entity_ld_ident(ent);
if (is_ia32_am_sc_sign(node))
be_emit_char(env, '-');
* returns the condition code
*/
static
-const char *get_cmp_suffix(int cmp_code)
+const char *get_cmp_suffix(pn_Cmp cmp_code)
{
assert( (cmp2condition_s[cmp_code & 15].num) == (cmp_code & 15));
assert( (cmp2condition_u[cmp_code & 7].num) == (cmp_code & 7));
return get_irn_link(irn);
}
+/**
+ * Emits a block label for the given block.
+ */
static
void ia32_emit_block_name(ia32_emit_env_t *env, const ir_node *block)
{
}
/**
- * Returns the target label for a control flow node.
+ * Emits the target label for a control flow node.
*/
static
void ia32_emit_cfop_target(ia32_emit_env_t * env, const ir_node *node) {
*/
static
void TestJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
- if(is_ia32_ImmSymConst(node) || is_ia32_ImmConst(node)) {
- be_emit_cstring(env, "\ttest ");
- ia32_emit_immediate(env, node);
- be_emit_cstring(env, ", ");
- ia32_emit_source_register(env, node, 0);
- be_emit_finish_line_gas(env, node);
- } else {
- be_emit_cstring(env, "\ttest ");
- ia32_emit_source_register(env, node, 1);
- be_emit_cstring(env, ", ");
- ia32_emit_source_register(env, node, 0);
- be_emit_finish_line_gas(env, node);
- }
+ be_emit_cstring(env, "\ttest ");
+ ia32_emit_binop(env, node);
+ be_emit_finish_line_gas(env, node);
+
finish_CondJmp(env, node, mode_Iu, get_ia32_pncode(node));
}
int is_ia32_Immediate_0(const ir_node *node)
{
const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
- tarval *tv = attr->offset;
- if(tv == NULL || attr->symconst != NULL)
- return 0;
-
- return classify_tarval(tv) == CNST_NULL;
+ return attr->offset == 0 && attr->symconst == NULL;
}
static
-void CMov_emitter(ia32_emit_env_t *env, const ir_node *node) {
+void CMov_emitter(ia32_emit_env_t *env, const ir_node *node)
+{
long pnc = get_ia32_pncode(node);
const arch_register_t *in1, *in2, *out;
} else {
/* out is different from in: need copy default -> out */
be_emit_cstring(env, "\tmovl ");
- ia32_emit_source_register(env, node, 3);
+ ia32_emit_source_register(env, node, n_ia32_CmpCMov_val_false);
be_emit_cstring(env, ", ");
ia32_emit_dest_register(env, node, 0);
be_emit_finish_line_gas(env, node);
be_emit_cstring(env, "\tcmov");
ia32_emit_cmp_suffix(env, pnc);
be_emit_cstring(env, "l ");
- ia32_emit_source_register(env, node, 2);
+ ia32_emit_source_register(env, node, n_ia32_CmpCMov_val_true);
be_emit_cstring(env, ", ");
ia32_emit_dest_register(env, node, 0);
be_emit_finish_line_gas(env, node);
}
static
-void emit_ia32_CmpCMov(ia32_emit_env_t *env, const ir_node *node) {
+void emit_ia32_CmpCMov(ia32_emit_env_t *env, const ir_node *node)
+{
CMov_emitter(env, node);
}
static
-void emit_ia32_xCmpCMov(ia32_emit_env_t *env, const ir_node *node) {
+void emit_ia32_xCmpCMov(ia32_emit_env_t *env, const ir_node *node)
+{
CMov_emitter(env, node);
}
static
-void Set_emitter(ia32_emit_env_t *env, const ir_node *node, ir_mode *mode) {
+void Set_emitter(ia32_emit_env_t *env, const ir_node *node)
+{
long pnc = get_ia32_pncode(node);
const char *reg8bit;
const arch_register_t *out;
static
void emit_ia32_CmpSet(ia32_emit_env_t *env, const ir_node *node) {
- Set_emitter(env, node, get_irn_mode(get_irn_n(node, 2)));
+ Set_emitter(env, node);
}
static
void emit_ia32_xCmpSet(ia32_emit_env_t *env, const ir_node *node) {
- Set_emitter(env, node, get_irn_mode(get_irn_n(node, 2)));
+ Set_emitter(env, node);
}
static
/* jump table for switch generation */
typedef struct _jmp_tbl_t {
ir_node *defProj; /**< default target */
- int min_value; /**< smallest switch case */
- int max_value; /**< largest switch case */
- int num_branches; /**< number of jumps */
+ long min_value; /**< smallest switch case */
+ long max_value; /**< largest switch case */
+ long num_branches; /**< number of jumps */
char *label; /**< label of the jump table */
branch_t *branches; /**< jump array */
} jmp_tbl_t;
{
const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
- assert(attr->symconst != NULL || attr->offset != NULL);
+ be_emit_char(env, '$');
if(attr->symconst != NULL) {
ident *id = get_entity_ld_ident(attr->symconst);
be_emit_char(env, '-');
be_emit_ident(env, id);
}
- if(attr->offset != NULL) {
+ if(attr->symconst == NULL || attr->offset != 0) {
if(attr->symconst != NULL)
be_emit_char(env, '+');
- else
- be_emit_char(env, '$');
- be_emit_tarval(env, attr->offset);
+ be_emit_irprintf(env->emit, "%d", attr->offset);
}
}
be_emit_cstring(env, "\tcall ");
if (ent) {
- mark_entity_visited(ent);
+ set_entity_backend_marked(ent, 1);
be_emit_string(env, get_entity_ld_name(ent));
} else {
be_emit_char(env, '*');
}
static
-void emit_be_Return(ia32_emit_env_t *env, const ir_node *node) {
+void emit_be_Return(ia32_emit_env_t *env, const ir_node *node)
+{
be_emit_cstring(env, "\tret");
be_emit_finish_line_gas(env, node);
}
static
-void emit_Nothing(ia32_emit_env_t *env, const ir_node *node) {
+void emit_Nothing(ia32_emit_env_t *env, const ir_node *node)
+{
+ (void) env;
+ (void) node;
}
ir_node *pred_block = get_nodes_block(pred);
/* we don't need labels for fallthrough blocks, however switch-jmps
- * are no fallthoughs */
+ * are no fallthroughs */
if(pred_block == prev &&
!(is_Proj(pred) && is_ia32_SwitchJmp(get_Proj_pred(pred)))) {
need_label = 0;
* Sets labels for control flow nodes (jump target)
*/
static
-void ia32_gen_labels(ir_node *block, void *data) {
+void ia32_gen_labels(ir_node *block, void *data)
+{
ir_node *pred;
int n = get_Block_n_cfgpreds(block);
+ (void) data;
for (n--; n >= 0; n--) {
pred = get_Block_cfgpred(block, n);