+
+ if (*fmt == 'l') {
+ mod |= EMIT_LONG;
+ ++fmt;
+ }
+
+ switch (*fmt++) {
+ case '%':
+ be_emit_char('%');
+ break;
+
+ case 'A': {
+ switch (*fmt++) {
+ case 'M':
+ if (mod & EMIT_ALTERNATE_AM)
+ be_emit_char('*');
+ ia32_emit_am(node);
+ break;
+
+ case 'R': {
+ const arch_register_t *reg = va_arg(ap, const arch_register_t*);
+ if (mod & EMIT_ALTERNATE_AM)
+ be_emit_char('*');
+ if (get_ia32_op_type(node) == ia32_AddrModeS) {
+ ia32_emit_am(node);
+ } else {
+ emit_register(reg, NULL);
+ }
+ break;
+ }
+
+ case 'S':
+ if (get_ia32_op_type(node) == ia32_AddrModeS) {
+ if (mod & EMIT_ALTERNATE_AM)
+ be_emit_char('*');
+ ia32_emit_am(node);
+ ++fmt;
+ } else {
+ assert(get_ia32_op_type(node) == ia32_Normal);
+ goto emit_S;
+ }
+ break;
+
+ default: goto unknown;
+ }
+ break;
+ }
+
+ case 'D': {
+ unsigned pos;
+ const arch_register_t *reg;
+
+ if (*fmt < '0' || '9' <= *fmt)
+ goto unknown;
+
+ pos = *fmt++ - '0';
+ reg = get_out_reg(node, pos);
+ emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
+ break;
+ }
+
+ case 'I':
+ if (!(mod & EMIT_ALTERNATE_AM))
+ be_emit_char('$');
+ emit_ia32_Immediate_no_prefix(node);
+ break;
+
+ case 'L':
+ ia32_emit_cfop_target(node);
+ break;
+
+ case 'M': {
+ ia32_emit_mode_suffix_mode(get_ia32_ls_mode(node));
+ break;
+ }
+
+ case 'P': {
+ int pnc = va_arg(ap, int);
+ ia32_emit_cmp_suffix(pnc);
+ break;
+ }
+
+ case 'R': {
+ const arch_register_t *reg = va_arg(ap, const arch_register_t*);
+ emit_register(reg, NULL);
+ break;
+ }
+
+emit_S:
+ case 'S': {
+ unsigned pos;
+ const ir_node *in;
+
+ if (*fmt < '0' || '9' <= *fmt)
+ goto unknown;
+
+ pos = *fmt++ - '0';
+ in = get_irn_n(node, pos);
+ if (is_ia32_Immediate(in)) {
+ if (!(mod & EMIT_ALTERNATE_AM))
+ be_emit_char('$');
+ emit_ia32_Immediate_no_prefix(in);
+ } else {
+ const arch_register_t *reg;
+
+ if (mod & EMIT_ALTERNATE_AM)
+ be_emit_char('*');
+ reg = get_in_reg(node, pos);
+ emit_register(reg, mod & EMIT_RESPECT_LS ? get_ia32_ls_mode(node) : NULL);
+ }
+ break;
+ }
+
+ case 's': {
+ const char *str = va_arg(ap, const char*);
+ be_emit_string(str);
+ break;
+ }
+
+ case 'u':
+ if (mod & EMIT_LONG) {
+ unsigned long num = va_arg(ap, unsigned long);
+ be_emit_irprintf("%lu", num);
+ } else {
+ unsigned num = va_arg(ap, unsigned);
+ be_emit_irprintf("%u", num);
+ }
+ break;
+
+ case 'd':
+ if (mod & EMIT_LONG) {
+ long num = va_arg(ap, long);
+ be_emit_irprintf("%ld", num);
+ } else {
+ int num = va_arg(ap, int);
+ be_emit_irprintf("%d", num);
+ }
+ break;
+
+ default:
+unknown:
+ panic("unknown format conversion in ia32_emitf()");
+ }
+ }
+
+ va_end(ap);
+}
+
+/**
+ * Emits registers and/or address mode of a binary operation.
+ */
+void ia32_emit_binop(const ir_node *node)
+{
+ if (is_ia32_Immediate(get_irn_n(node, n_ia32_binary_right))) {
+ ia32_emitf(node, "%#S4, %#AS3");
+ } else {
+ ia32_emitf(node, "%#AS4, %#S3");