+/**
+ * binary emitter for setcc.
+ */
+static void bemit_setcc(const ir_node *node)
+{
+ const arch_register_t *dreg = get_out_reg(node, pn_ia32_Setcc_res);
+
+ int pnc = get_ia32_condcode(node);
+ pnc = determine_final_pnc(node, n_ia32_Setcc_eflags, pnc);
+ if (pnc & ia32_pn_Cmp_float) {
+ switch (pnc & 0x0f) {
+ case pn_Cmp_Uo:
+ /* setp <dreg */
+ bemit8(0x0F);
+ bemit8(0x9A);
+ bemit_modrm8(REG_LOW, dreg);
+ return;
+
+ case pn_Cmp_Leg:
+ /* setnp <dreg*/
+ bemit8(0x0F);
+ bemit8(0x9B);
+ bemit_modrm8(REG_LOW, dreg);
+ return;
+
+ case pn_Cmp_Eq:
+ case pn_Cmp_Lt:
+ case pn_Cmp_Le:
+ /* set%PNC <dreg */
+ bemit8(0x0F);
+ bemit8(0x90 | pnc2cc(pnc));
+ bemit_modrm8(REG_LOW, dreg);
+
+ /* setnp >dreg */
+ bemit8(0x0F);
+ bemit8(0x9B);
+ bemit_modrm8(REG_HIGH, dreg);
+
+ /* andb %>dreg, %<dreg */
+ bemit8(0x20);
+ bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
+ return;
+
+ case pn_Cmp_Ug:
+ case pn_Cmp_Uge:
+ case pn_Cmp_Ne:
+ /* set%PNC <dreg */
+ bemit8(0x0F);
+ bemit8(0x90 | pnc2cc(pnc));
+ bemit_modrm8(REG_LOW, dreg);
+
+ /* setp >dreg */
+ bemit8(0x0F);
+ bemit8(0x9A);
+ bemit_modrm8(REG_HIGH, dreg);
+
+ /* orb %>dreg, %<dreg */
+ bemit8(0x08);
+ bemit_modrr8(REG_LOW, dreg, REG_HIGH, dreg);
+ return;
+
+ default:
+ break;
+ }
+ }
+ /* set%PNC <dreg */
+ bemit8(0x0F);
+ bemit8(0x90 | pnc2cc(pnc));
+ bemit_modrm8(REG_LOW, dreg);
+}
+