+/**
+ * Emits a block label for the given block.
+ */
+static void ia32_emit_block_name(const ir_node *block)
+{
+ if (has_Block_label(block)) {
+ be_emit_string(be_gas_block_label_prefix());
+ be_emit_irprintf("%lu", get_Block_label(block));
+ } else {
+ be_emit_cstring(BLOCK_PREFIX);
+ be_emit_irprintf("%ld", get_irn_node_nr(block));
+ }
+}
+
+/**
+ * Emits the target label for a control flow node.
+ */
+static void ia32_emit_cfop_target(const ir_node *node)
+{
+ ir_node *block = get_cfop_target_block(node);
+ ia32_emit_block_name(block);
+}
+
+/*
+ * positive conditions for signed compares
+ */
+static const char *const cmp2condition_s[] = {
+ NULL, /* always false */
+ "e", /* == */
+ "l", /* < */
+ "le", /* <= */
+ "g", /* > */
+ "ge", /* >= */
+ "ne", /* != */
+ NULL /* always true */
+};
+
+/*
+ * positive conditions for unsigned compares
+ */
+static const char *const cmp2condition_u[] = {
+ NULL, /* always false */
+ "e", /* == */
+ "b", /* < */
+ "be", /* <= */
+ "a", /* > */
+ "ae", /* >= */
+ "ne", /* != */
+ NULL /* always true */
+};
+
+/**
+ * Emit the suffix for a compare instruction.
+ */
+static void ia32_emit_cmp_suffix(int pnc)
+{
+ const char *str;
+
+ if (pnc == ia32_pn_Cmp_parity) {
+ be_emit_char('p');
+ return;
+ }
+ if (pnc & ia32_pn_Cmp_float || pnc & ia32_pn_Cmp_unsigned) {
+ str = cmp2condition_u[pnc & 7];
+ } else {
+ str = cmp2condition_s[pnc & 7];
+ }
+
+ be_emit_string(str);
+}
+
+typedef enum ia32_emit_mod_t {
+ EMIT_RESPECT_LS = 1U << 0,
+ EMIT_ALTERNATE_AM = 1U << 1,
+ EMIT_LONG = 1U << 2
+} ia32_emit_mod_t;
+
+/**
+ * fmt parameter output
+ * ---- ---------------------- ---------------------------------------------
+ * %% %
+ * %AM <node> address mode of the node
+ * %AR const arch_register_t* address mode of the node or register
+ * %ASx <node> address mode of the node or source register x
+ * %Dx <node> destination register x
+ * %I <node> immediate of the node
+ * %L <node> control flow target of the node
+ * %M <node> mode suffix of the node
+ * %P int condition code
+ * %R const arch_register_t* register
+ * %Sx <node> source register x
+ * %s const char* string
+ * %u unsigned int unsigned int
+ * %d signed int signed int
+ *
+ * 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 *
+ * l modifier for %lu and %ld
+ */
+static void ia32_emitf(const ir_node *node, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+
+ for (;;) {
+ const char *start = fmt;
+ ia32_emit_mod_t mod = 0;
+
+ while (*fmt != '%' && *fmt != '\n' && *fmt != '\0')
+ ++fmt;
+ if (fmt != start) {
+ be_emit_string_len(start, fmt - start);
+ }
+
+ if (*fmt == '\n') {
+ be_emit_finish_line_gas(node);
+ ++fmt;
+ if (*fmt == '\0')
+ break;
+ continue;
+ }
+
+ if (*fmt == '\0')