Remove the unused parameter const arch_env_t *env from arch_get_irn_register().
[libfirm] / ir / be / ia32 / ia32_emitter.c
index 56a9311..e5c46b7 100644 (file)
@@ -129,7 +129,7 @@ static const arch_register_t *get_in_reg(const ir_node *irn, int pos)
           in register we need. */
        op = get_irn_n(irn, pos);
 
-       reg = arch_get_irn_register(arch_env, op);
+       reg = arch_get_irn_register(op);
 
        assert(reg && "no in register found");
 
@@ -138,10 +138,7 @@ static const arch_register_t *get_in_reg(const ir_node *irn, int pos)
 
        /* 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 */
-               req = arch_get_register_req(arch_env, irn, pos);
+               const arch_register_req_t *req = arch_get_register_req(irn, pos);
 
                if (arch_register_req_is(req, limited)) {
                        /* in case of limited requirements: get the first allowed register */
@@ -171,7 +168,7 @@ static const arch_register_t *get_out_reg(const ir_node *irn, int pos)
 
        if (get_irn_mode(irn) != mode_T) {
                assert(pos == 0);
-               reg = arch_get_irn_register(arch_env, irn);
+               reg = arch_get_irn_register(irn);
        } else if (is_ia32_irn(irn)) {
                reg = get_ia32_out_reg(irn, pos);
        } else {
@@ -181,7 +178,7 @@ static const arch_register_t *get_out_reg(const ir_node *irn, int pos)
                        proj = get_edge_src_irn(edge);
                        assert(is_Proj(proj) && "non-Proj from mode_T node");
                        if (get_Proj_proj(proj) == pos) {
-                               reg = arch_get_irn_register(arch_env, proj);
+                               reg = arch_get_irn_register(proj);
                                break;
                        }
                }
@@ -255,7 +252,52 @@ void ia32_emit_source_register(const ir_node *node, int pos)
        emit_register(reg, NULL);
 }
 
-static void emit_ia32_Immediate(const ir_node *node);
+static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
+{
+       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");
+               }
+       }
+
+       if (!no_pic_adjust && do_pic) {
+               /* TODO: only do this when necessary */
+               be_emit_char('-');
+               be_emit_string(pic_base_label);
+       }
+}
+
+static void emit_ia32_Immediate_no_prefix(const ir_node *node)
+{
+       const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
+
+       if (attr->symconst != NULL) {
+               if (attr->sc_sign)
+                       be_emit_char('-');
+               ia32_emit_entity(attr->symconst, 0);
+       }
+       if (attr->symconst == NULL || attr->offset != 0) {
+               if (attr->symconst != NULL) {
+                       be_emit_irprintf("%+d", attr->offset);
+               } else {
+                       be_emit_irprintf("0x%X", attr->offset);
+               }
+       }
+}
+
+static void emit_ia32_Immediate(const ir_node *node)
+{
+       be_emit_char('$');
+       emit_ia32_Immediate_no_prefix(node);
+}
 
 void ia32_emit_8bit_source_register_or_immediate(const ir_node *node, int pos)
 {
@@ -476,6 +518,11 @@ static void ia32_emit_cmp_suffix(int pnc)
        be_emit_string(str);
 }
 
+typedef enum ia32_emit_mod_t {
+       EMIT_RESPECT_LS   = 1U << 0,
+       EMIT_ALTERNATE_AM = 1U << 1
+} ia32_emit_mod_t;
+
 /**
  * fmt  parameter               output
  * ---- ----------------------  ---------------------------------------------
@@ -495,6 +542,7 @@ static void ia32_emit_cmp_suffix(int pnc)
  *
  * x starts at 0
  * # modifier for %ASx, %D and %S uses ls mode of node to alter register width
+ * * modifier does not prefix immediates with $, but AM with *
  */
 static void ia32_emitf(const ir_node *node, const char *fmt, ...)
 {
@@ -502,8 +550,8 @@ static void ia32_emitf(const ir_node *node, const char *fmt, ...)
        va_start(ap, fmt);
 
        for (;;) {
-               const char    *start = fmt;
-               const ir_mode *mode  = NULL;
+               const char      *start = fmt;
+               ia32_emit_mod_t  mod   = 0;
 
                while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
                        ++fmt;
@@ -523,8 +571,13 @@ static void ia32_emitf(const ir_node *node, const char *fmt, ...)
                        break;
 
                ++fmt;
+               if (*fmt == '*') {
+                       mod |= EMIT_ALTERNATE_AM;
+                       ++fmt;
+               }
+
                if (*fmt == '#') {
-                       mode = get_ia32_ls_mode(node);
+                       mod |= EMIT_RESPECT_LS;
                        ++fmt;
                }
 
@@ -536,11 +589,15 @@ static void ia32_emitf(const ir_node *node, const char *fmt, ...)
                        case 'A': {
                                switch (*fmt++) {
                                        case 'M':
+                                               if (mod & EMIT_ALTERNATE_AM)
+                                                       be_emit_char('*');
                                                ia32_emit_am(node);
                                                break;
 
                                        case 'R': {
                                                const arch_register_t *reg = va_arg(ap, const arch_register_t*);
+                                               if (mod & EMIT_ALTERNATE_AM)
+                                                       be_emit_char('*');
                                                if (get_ia32_op_type(node) == ia32_AddrModeS) {
                                                        ia32_emit_am(node);
                                                } else {
@@ -551,6 +608,8 @@ static void ia32_emitf(const ir_node *node, const char *fmt, ...)
 
                                        case 'S':
                                                if (get_ia32_op_type(node) == ia32_AddrModeS) {
+                                                       if (mod & EMIT_ALTERNATE_AM)
+                                                               be_emit_char('*');
                                                        ia32_emit_am(node);
                                                        ++fmt;
                                                } else {
@@ -573,12 +632,14 @@ static void ia32_emitf(const ir_node *node, const char *fmt, ...)
 
                                pos = *fmt++ - '0';
                                reg = get_out_reg(node, pos);
-                               emit_register(reg, mode);
+                               emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
                                break;
                        }
 
                        case 'I':
-                               emit_ia32_Immediate(node);
+                               if (!(mod & EMIT_ALTERNATE_AM))
+                                       be_emit_char('$');
+                               emit_ia32_Immediate_no_prefix(node);
                                break;
 
                        case 'L':
@@ -613,10 +674,14 @@ emit_S:
                                pos = *fmt++ - '0';
                                in  = get_irn_n(node, pos);
                                if (is_ia32_Immediate(in)) {
-                                       emit_ia32_Immediate(in);
+                                       if (!(mod & EMIT_ALTERNATE_AM))
+                                               be_emit_char('$');
+                                       emit_ia32_Immediate_no_prefix(in);
                                } else {
+                                       if (mod & EMIT_ALTERNATE_AM)
+                                               be_emit_char('*');
                                        const arch_register_t *reg = get_in_reg(node, pos);
-                                       emit_register(reg, mode);
+                                       emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
                                }
                                break;
                        }
@@ -698,29 +763,6 @@ void ia32_emit_unop(const ir_node *node, int pos)
        ia32_emitf(node, fmt);
 }
 
-static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
-{
-       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");
-               }
-       }
-
-       if (!no_pic_adjust && do_pic) {
-               /* TODO: only do this when necessary */
-               be_emit_char('-');
-               be_emit_string(pic_base_label);
-       }
-}
-
 /**
  * Emits address mode.
  */
@@ -1024,17 +1066,15 @@ static void emit_ia32_CMov(const ir_node *node)
 {
        const ia32_attr_t     *attr         = get_ia32_attr_const(node);
        int                    ins_permuted = attr->data.ins_permuted;
-       const arch_register_t *out          = arch_get_irn_register(arch_env, node);
+       const arch_register_t *out          = arch_get_irn_register(node);
        pn_Cmp                 pnc          = get_ia32_condcode(node);
        const arch_register_t *in_true;
        const arch_register_t *in_false;
 
        pnc = determine_final_pnc(node, n_ia32_CMov_eflags, pnc);
 
-       in_true  = arch_get_irn_register(arch_env,
-                                        get_irn_n(node, n_ia32_CMov_val_true));
-       in_false = arch_get_irn_register(arch_env,
-                                        get_irn_n(node, n_ia32_CMov_val_false));
+       in_true  = arch_get_irn_register(get_irn_n(node, n_ia32_CMov_val_true));
+       in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMov_val_false));
 
        /* should be same constraint fullfilled? */
        if (out == in_false) {
@@ -1215,25 +1255,6 @@ static void emit_Jmp(const ir_node *node)
        }
 }
 
-static void emit_ia32_Immediate(const ir_node *node)
-{
-       const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
-
-       be_emit_char('$');
-       if (attr->symconst != NULL) {
-               if (attr->sc_sign)
-                       be_emit_char('-');
-               ia32_emit_entity(attr->symconst, 0);
-       }
-       if (attr->symconst == NULL || attr->offset != 0) {
-               if (attr->symconst != NULL) {
-                       be_emit_irprintf("%+d", attr->offset);
-               } else {
-                       be_emit_irprintf("0x%X", attr->offset);
-               }
-       }
-}
-
 /**
  * Emit an inline assembler operand.
  *
@@ -1511,7 +1532,7 @@ static void emit_ia32_Conv_I2I(const ir_node *node)
        if (signed_mode                                    &&
                        smaller_bits == 16                             &&
                        &ia32_gp_regs[REG_EAX] == get_out_reg(node, 0) &&
-                       &ia32_gp_regs[REG_EAX] == arch_get_irn_register(arch_env, get_irn_n(node, n_ia32_unary_op))) {
+                       &ia32_gp_regs[REG_EAX] == arch_get_irn_register(get_irn_n(node, n_ia32_unary_op))) {
                /* argument and result are both in EAX and signedness is ok: use the
                 * smaller cwtl opcode */
                ia32_emitf(node, "\tcwtl\n");
@@ -1521,6 +1542,16 @@ static void emit_ia32_Conv_I2I(const ir_node *node)
        }
 }
 
+/**
+ * Emits a call
+ */
+static void emit_ia32_Call(const ir_node *node)
+{
+       /* Special case: Call must not have its immediates prefixed by $, instead
+        * address mode is prefixed by *. */
+       ia32_emitf(node, "\tcall %*AS3\n");
+}
+
 
 /*******************************************
  *  _                          _
@@ -1532,24 +1563,6 @@ static void emit_ia32_Conv_I2I(const ir_node *node)
  *
  *******************************************/
 
-/**
- * Emits a backend call
- */
-static void emit_be_Call(const ir_node *node)
-{
-       ir_entity *ent = be_Call_get_entity(node);
-
-       be_emit_cstring("\tcall ");
-       if (ent) {
-               ia32_emit_entity(ent, 1);
-       } else {
-               const arch_register_t *reg = get_in_reg(node, be_pos_Call_ptr);
-               be_emit_char('*');
-               emit_register(reg, NULL);
-       }
-       be_emit_finish_line_gas(node);
-}
-
 /**
  * Emits code to increase stack pointer.
  */
@@ -1572,8 +1585,8 @@ static void emit_be_IncSP(const ir_node *node)
  */
 static void Copy_emitter(const ir_node *node, const ir_node *op)
 {
-       const arch_register_t *in  = arch_get_irn_register(arch_env, op);
-       const arch_register_t *out = arch_get_irn_register(arch_env, node);
+       const arch_register_t *in  = arch_get_irn_register(op);
+       const arch_register_t *out = arch_get_irn_register(node);
 
        if (in == out) {
                return;
@@ -1609,8 +1622,8 @@ static void emit_be_Perm(const ir_node *node)
        const arch_register_t *in0, *in1;
        const arch_register_class_t *cls0, *cls1;
 
-       in0 = arch_get_irn_register(arch_env, get_irn_n(node, 0));
-       in1 = arch_get_irn_register(arch_env, get_irn_n(node, 1));
+       in0 = arch_get_irn_register(get_irn_n(node, 0));
+       in1 = arch_get_irn_register(get_irn_n(node, 1));
 
        cls0 = arch_register_get_class(in0);
        cls1 = arch_register_get_class(in1);
@@ -1795,6 +1808,7 @@ static void ia32_register_emitters(void)
        IA32_EMIT2(Conv_I2I8Bit, Conv_I2I);
        IA32_EMIT(Asm);
        IA32_EMIT(CMov);
+       IA32_EMIT(Call);
        IA32_EMIT(Const);
        IA32_EMIT(Conv_FP2FP);
        IA32_EMIT(Conv_FP2I);
@@ -1810,7 +1824,6 @@ static void ia32_register_emitters(void)
        IA32_EMIT(SwitchJmp);
 
        /* benode emitter */
-       BE_EMIT(Call);
        BE_EMIT(Copy);
        BE_EMIT(CopyKeep);
        BE_EMIT(IncSP);
@@ -1824,7 +1837,6 @@ static void ia32_register_emitters(void)
        /* firm emitter */
        EMIT(Jmp);
        IGN(Phi);
-       IGN(Proj);
        IGN(Start);
 
 #undef BE_EMIT