- assert(sse_pnc >= 0 && "unsupported floating point compare");
-
- lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "cmps%M %s, %d", irn, ia32_emit_binop(irn, env), sse_pnc);
- lc_esnprintf(arg_env, cmnt_buf, SNPRINTF_BUF_LEN, "/* SSE compare with result in %1D */", irn);
+ assert(sse_pnc >= 0 && "unsupported compare");
+
+ if (unord && sse_pnc != 3) {
+ /*
+ We need a separate compare against unordered.
+ Quick and Dirty solution:
+ - get some memory on stack
+ - compare
+ - store result
+ - compare
+ - and result and stored result
+ - cleanup stack
+ */
+ snprintf(cmd_buf, SNPRINTF_BUF_LEN, "sub %%esp, 8");
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* reserve some space for unordered compare result */");
+ IA32_DO_EMIT(NULL);
+ snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cmpsd %s, 3", ia32_emit_binop(irn, env));
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* SSE compare: unordered */");
+ IA32_DO_EMIT(NULL);
+ lc_esnprintf(arg_env, cmd_buf, SNPRINTF_BUF_LEN, "movsd [%%esp], %1D", irn);
+ snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* store compare result */");
+ IA32_DO_EMIT(NULL);
+ }
+
+ snprintf(cmd_buf, SNPRINTF_BUF_LEN, "cmpsd %s, %d", ia32_emit_binop(irn, env), sse_pnc);
+ lc_esnprintf(arg_env, cmnt_buf, SNPRINTF_BUF_LEN, "/* SSE compare (%+F) with result in %1D */", irn, irn);