+static void emit_ia32_Conv_FP2FP(const ir_node *irn, ia32_emit_env_t *emit_env) {
+ emit_ia32_Conv_with_FP(irn, emit_env);
+}
+
+/**
+ * Emits code for an Int conversion.
+ */
+static void emit_ia32_Conv_I2I(const ir_node *irn, ia32_emit_env_t *emit_env) {
+ FILE *F = emit_env->out;
+ const lc_arg_env_t *env = ia32_get_arg_env();
+ char *move_cmd = "movzx";
+ char *conv_cmd = NULL;
+ ir_mode *src_mode = get_ia32_src_mode(irn);
+ ir_mode *tgt_mode = get_ia32_tgt_mode(irn);
+ int n, m;
+ char cmd_buf[SNPRINTF_BUF_LEN], cmnt_buf[SNPRINTF_BUF_LEN];
+ const arch_register_t *in_reg, *out_reg;
+
+ n = get_mode_size_bits(src_mode);
+ m = get_mode_size_bits(tgt_mode);
+
+ if (mode_is_signed(n < m ? src_mode : tgt_mode)) {
+ move_cmd = "movsx";
+ if (n == 8 || m == 8)
+ conv_cmd = "cbw";
+ else if (n == 16 || m == 16)
+ conv_cmd = "cwde";
+ else
+ assert(0 && "unsupported Conv_I2I");
+ }
+
+ switch(get_ia32_op_type(irn)) {
+ case ia32_Normal:
+ in_reg = get_in_reg(irn, 2);
+ out_reg = get_out_reg(irn, 0);
+
+ if (REGS_ARE_EQUAL(in_reg, &ia32_gp_regs[REG_EAX]) &&
+ REGS_ARE_EQUAL(out_reg, in_reg) &&
+ mode_is_signed(n < m ? src_mode : tgt_mode))
+ {
+ /* argument and result are both in EAX and */
+ /* signedness is ok: -> use converts */
+ lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "%s", conv_cmd);
+ }
+ else if (REGS_ARE_EQUAL(out_reg, in_reg) &&
+ ! mode_is_signed(n < m ? src_mode : tgt_mode))
+ {
+ /* argument and result are in the same register */
+ /* and signedness is ok: -> use and with mask */
+ int mask = (1 << (n < m ? n : m)) - 1;
+ lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "and %1D, 0x%x", irn, mask);
+ }
+ else {
+ /* use move w/o sign extension */
+ lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "%s %1D, %%%s",
+ move_cmd, irn, ia32_get_reg_name_for_mode(emit_env, n < m ? src_mode : tgt_mode, in_reg));
+ }
+
+ break;
+ case ia32_AddrModeS:
+ lc_esnprintf(env, cmd_buf, SNPRINTF_BUF_LEN, "%s %1D, %s",
+ move_cmd, irn, ia32_emit_am(irn, emit_env));
+ break;
+ default:
+ assert(0 && "unsupported op type for Conv");
+ }
+
+ lc_esnprintf(env, cmnt_buf, SNPRINTF_BUF_LEN, "/* %+F(%d Bit mode_%F -> %d Bit mode_%F) */",
+ irn, n, src_mode, m, tgt_mode);
+
+ IA32_DO_EMIT(irn);