+/**
+ * Emits address mode.
+ */
+void ia32_emit_am(const ir_node *node)
+{
+ ir_entity *ent = get_ia32_am_sc(node);
+ int offs = get_ia32_am_offs_int(node);
+ ir_node *base = get_irn_n(node, n_ia32_base);
+ int has_base = !is_ia32_NoReg_GP(base);
+ ir_node *index = get_irn_n(node, n_ia32_index);
+ int has_index = !is_ia32_NoReg_GP(index);
+
+ /* just to be sure... */
+ assert(!is_ia32_use_frame(node) || get_ia32_frame_ent(node) != NULL);
+
+ /* emit offset */
+ if (ent != NULL) {
+ const ia32_attr_t *attr = get_ia32_attr_const(node);
+ if (is_ia32_am_sc_sign(node))
+ be_emit_char('-');
+ ia32_emit_entity(ent, attr->data.am_sc_no_pic_adjust);
+ }
+
+ /* also handle special case if nothing is set */
+ if (offs != 0 || (ent == NULL && !has_base && !has_index)) {
+ if (ent != NULL) {
+ be_emit_irprintf("%+d", offs);
+ } else {
+ be_emit_irprintf("%d", offs);
+ }
+ }
+
+ if (has_base || has_index) {
+ be_emit_char('(');
+
+ /* emit base */
+ if (has_base) {
+ const arch_register_t *reg = get_in_reg(node, n_ia32_base);
+ emit_register(reg, NULL);
+ }
+
+ /* emit index + scale */
+ if (has_index) {
+ const arch_register_t *reg = get_in_reg(node, n_ia32_index);
+ int scale;
+ be_emit_char(',');
+ emit_register(reg, NULL);
+
+ scale = get_ia32_am_scale(node);
+ if (scale > 0) {
+ be_emit_irprintf(",%d", 1 << scale);
+ }
+ }
+ be_emit_char(')');
+ }
+}
+