- flipped = 1;
- pnc = get_negated_pnc(pnc, mode);
- }
-
- if (mode_is_float(mode)) {
- /* Some floating point comparisons require a test of the parity flag, which
- * indicates that the result is unordered */
- switch (pnc & ~ia32_pn_Cmp_Unsigned) {
- case pn_Cmp_Uo:
- be_emit_cstring(env, "\tjp ");
- ia32_emit_cfop_target(env, proj_true);
- be_emit_finish_line_gas(env, proj_true);
- break;
-
- case pn_Cmp_Leg:
- be_emit_cstring(env, "\tjnp ");
- ia32_emit_cfop_target(env, proj_true);
- be_emit_finish_line_gas(env, proj_true);
- break;
-
- case pn_Cmp_Eq:
- case pn_Cmp_Lt:
- case pn_Cmp_Le:
- be_emit_cstring(env, "\tjp ");
- ia32_emit_cfop_target(env, proj_false);
- be_emit_finish_line_gas(env, proj_false);
- goto float_jcc;
-
- case pn_Cmp_Ug:
- case pn_Cmp_Uge:
- case pn_Cmp_Ne:
- be_emit_cstring(env, "\tjp ");
- ia32_emit_cfop_target(env, proj_true);
- be_emit_finish_line_gas(env, proj_true);
- goto float_jcc;
-
- default:
- float_jcc:
- /* The bits set by floating point compares correspond to unsigned
- * comparisons */
- pnc |= ia32_pn_Cmp_Unsigned;
- goto emit_jcc;
- }
- } else {
-emit_jcc:
- be_emit_cstring(env, "\tj");
- ia32_emit_cmp_suffix(env, pnc);
- be_emit_char(env, ' ');
- ia32_emit_cfop_target(env, proj_true);
- be_emit_finish_line_gas(env, proj_true);
- }
-
- /* the second Proj might be a fallthrough */
- if (get_cfop_target_block(proj_false) != next_block) {
- be_emit_cstring(env, "\tjmp ");
- ia32_emit_cfop_target(env, proj_false);
- be_emit_finish_line_gas(env, proj_false);
- } else {
- be_emit_cstring(env, "\t/* fallthrough to ");
- ia32_emit_cfop_target(env, proj_false);
- be_emit_cstring(env, " */");
- be_emit_finish_line_gas(env, proj_false);
- }
-}
-
-/**
- * Emits code for conditional jump.
- */
-static
-void CondJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
- be_emit_cstring(env, "\tcmp");
- ia32_emit_mode_suffix(env, node);
- be_emit_char(env, ' ');
- ia32_emit_binop(env, node);
- be_emit_finish_line_gas(env, node);
-
- finish_CondJmp(env, node, mode_Iu, get_ia32_pncode(node));
-}
-
-/**
- * Emits code for conditional jump with two variables.
- */
-static
-void emit_ia32_CmpJmp(ia32_emit_env_t *env, const ir_node *node) {
- CondJmp_emitter(env, node);
-}
-
-/**
- * Emits code for conditional test and jump.
- */
-static
-void TestJmp_emitter(ia32_emit_env_t *env, const ir_node *node) {
- be_emit_cstring(env, "\ttest");
- ia32_emit_mode_suffix(env, node);
- be_emit_char(env, ' ');
-
- ia32_emit_binop(env, node);
- be_emit_finish_line_gas(env, node);
-
- finish_CondJmp(env, node, mode_Iu, get_ia32_pncode(node));
-}
-
-/**
- * Emits code for conditional test and jump with two variables.
- */
-static
-void emit_ia32_TestJmp(ia32_emit_env_t *env, const ir_node *node) {
- TestJmp_emitter(env, node);
-}
-
-/**
- * Emits code for conditional SSE floating point jump with two variables.
- */
-static
-void emit_ia32_xCmpJmp(ia32_emit_env_t *env, const ir_node *node) {
- be_emit_cstring(env, "\tucomi");
- ia32_emit_xmm_mode_suffix(env, node);
- be_emit_char(env, ' ');
- ia32_emit_binop(env, node);
- be_emit_finish_line_gas(env, node);
-
- finish_CondJmp(env, node, mode_F, get_ia32_pncode(node));
-}
-
-/**
- * Emits code for conditional x87 floating point jump with two variables.
- */
-static
-void emit_ia32_x87CmpJmp(ia32_emit_env_t *env, const ir_node *node) {
- const ia32_x87_attr_t *x87_attr = get_ia32_x87_attr_const(node);
- const char *reg = x87_attr->x87[1]->name;
- long pnc = get_ia32_pncode(node);
-
- switch (get_ia32_irn_opcode(node)) {
- case iro_ia32_fcomrJmp:
- pnc = get_inversed_pnc(pnc);
- reg = x87_attr->x87[0]->name;
- case iro_ia32_fcomJmp:
- default:
- be_emit_cstring(env, "\tfucom ");
- break;
- case iro_ia32_fcomrpJmp:
- pnc = get_inversed_pnc(pnc);
- reg = x87_attr->x87[0]->name;
- case iro_ia32_fcompJmp:
- be_emit_cstring(env, "\tfucomp ");
- break;
- case iro_ia32_fcomrppJmp:
- pnc = get_inversed_pnc(pnc);
- case iro_ia32_fcomppJmp:
- be_emit_cstring(env, "\tfucompp ");
- reg = "";
- break;
- }
-
- if(reg[0] != '\0') {
- be_emit_char(env, '%');
- be_emit_string(env, reg);
- }
- be_emit_finish_line_gas(env, node);
-
- be_emit_cstring(env, "\tfnstsw %ax");
- be_emit_finish_line_gas(env, node);
- be_emit_cstring(env, "\tsahf");
- be_emit_finish_line_gas(env, node);
-
- finish_CondJmp(env, node, mode_E, pnc);
-}
-
-static
-void CMov_emitter(ia32_emit_env_t *env, const ir_node *node)
-{
- const arch_register_t *in1, *in2, *out;
- long pnc = get_ia32_pncode(node);
-
- out = arch_get_irn_register(env->arch_env, node);
-
- /* we have to emit the cmp first, because the destination register */
- /* could be one of the compare registers */
- if (is_ia32_xCmpCMov(node)) {
- be_emit_cstring(env, "\tucomis");
- ia32_emit_mode_suffix_mode(env, get_irn_mode(node));
- be_emit_char(env, ' ');
- ia32_emit_source_register(env, node, 1);
- be_emit_cstring(env, ", ");
- ia32_emit_source_register(env, node, 0);
-
- in1 = arch_get_irn_register(env->arch_env, get_irn_n(node, 2));
- in2 = arch_get_irn_register(env->arch_env, get_irn_n(node, 3));
- } else {
- if (is_ia32_CmpCMov(node) || is_ia32_CmpCMov8Bit(node)) {
- be_emit_cstring(env, "\tcmp ");