static void amd64_emit_immediate64(const amd64_imm64_t *const imm) { if (imm->kind == X86_IMM_VALUE) { assert(imm->entity == NULL); be_emit_irprintf("0x%" PRIX64, imm->offset); return; } x86_emit_relocation_no_offset(imm->kind, imm->entity); if (imm->offset != 0) be_emit_irprintf("%+" PRId64, imm->offset); }
void be_emit_finish_line_gas(const ir_node *node) { if (node && be_options.verbose_asm) { be_emit_pad_comment(); dbg_info *const dbg = get_irn_dbg_info(node); src_loc_t const loc = ir_retrieve_dbg_info(dbg); char const *const fmt = !loc.file ? "/* %+F */\n" : loc.line == 0 ? "/* %+F %s */\n" : loc.column == 0 ? "/* %+F %s:%u */\n" : /* */ "/* %+F %s:%u:%u */\n"; be_emit_irprintf(fmt, node, loc.file, loc.line, loc.column); } else { be_emit_char('\n'); } be_emit_write_line(); }
static void emit_shiftop(const ir_node *const node) { amd64_shift_attr_t const *const attr = get_amd64_shift_attr_const(node); switch (attr->base.op_mode) { case AMD64_OP_SHIFT_IMM: { be_emit_irprintf("$%u, ", attr->immediate); const arch_register_t *reg = arch_get_irn_register_in(node, 0); emit_register_mode(reg, attr->base.size); return; } case AMD64_OP_SHIFT_REG: { const arch_register_t *reg0 = arch_get_irn_register_in(node, 0); const arch_register_t *reg1 = arch_get_irn_register_in(node, 1); emit_register_mode(reg1, X86_SIZE_8); be_emit_cstring(", "); emit_register_mode(reg0, attr->base.size); return; } default: break; } panic("invalid op_mode for shiftop"); }
void amd64_emitf(ir_node const *const node, char const *fmt, ...) { va_list ap; va_start(ap, fmt); be_emit_char('\t'); for (;;) { char const *start = fmt; while (*fmt != '%' && *fmt != '\n' && *fmt != '\0') ++fmt; if (fmt != start) { be_emit_string_len(start, fmt - start); } if (*fmt == '\n') { be_emit_char('\n'); be_emit_write_line(); be_emit_char('\t'); ++fmt; continue; } if (*fmt == '\0') break; ++fmt; amd64_emit_mod_t mod = EMIT_NONE; for (;;) { switch (*fmt) { case '#': mod |= EMIT_RESPECT_LS; break; case '^': mod |= EMIT_IGNORE_MODE; break; default: goto end_of_mods; } ++fmt; } end_of_mods: switch (*fmt++) { arch_register_t const *reg; case '%': be_emit_char('%'); break; case 'C': { amd64_attr_t const *const attr = get_amd64_attr_const(node); /* FIXME: %d is a hack... we must emit 64bit constants, or sign * extended 32bit constants... */ be_emit_irprintf("$%d", attr->ext.imm_value); break; } case 'D': if (*fmt < '0' || '9' <= *fmt) goto unknown; reg = arch_get_irn_register_out(node, *fmt++ - '0'); goto emit_R; case 'E': { ir_entity const *const ent = va_arg(ap, ir_entity const*); be_gas_emit_entity(ent); break; } case 'L': { ir_node *const block = get_cfop_target_block(node); be_gas_emit_block_name(block); break; } case 'O': { amd64_SymConst_attr_t const *const attr = get_amd64_SymConst_attr_const(node); if (attr->fp_offset) be_emit_irprintf("%d", attr->fp_offset); break; } case 'R': reg = va_arg(ap, arch_register_t const*); emit_R: if (mod & EMIT_IGNORE_MODE) { emit_register(reg); } else { amd64_attr_t const *const attr = get_amd64_attr_const(node); if (mod & EMIT_RESPECT_LS) { emit_register_mode(reg, attr->ls_mode); } else { emit_register_insn_mode(reg, attr->data.insn_mode); } } break; case 'S': { int pos; if ('0' <= *fmt && *fmt <= '9') { pos = *fmt++ - '0'; } else { goto unknown; } reg = arch_get_irn_register_in(node, pos); goto emit_R; } case 'M': { amd64_attr_t const *const attr = get_amd64_attr_const(node); if (mod & EMIT_RESPECT_LS) { amd64_emit_mode_suffix(attr->ls_mode); } else { amd64_emit_insn_mode_suffix(attr->data.insn_mode); } break; } case 'd': { int const num = va_arg(ap, int); be_emit_irprintf("%d", num); break; } case 's': { char const *const str = va_arg(ap, char const*); be_emit_string(str); break; } case 'u': { unsigned const num = va_arg(ap, unsigned); be_emit_irprintf("%u", num); break; } case 'c': { amd64_attr_t const *const attr = get_amd64_attr_const(node); ir_mode *mode = attr->ls_mode; if (get_mode_size_bits(mode) == 64) break; if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode) && attr->data.insn_mode == INSN_MODE_32) break; be_emit_char(mode_is_signed(mode) ? 's' : 'z'); amd64_emit_mode_suffix(mode); break; } default: unknown: panic("unknown format conversion"); } } be_emit_finish_line_gas(node); va_end(ap); }