char *ia32_emit_binop(const ir_node *n) {
static char *buf = NULL;
+ /* verify that this function is never called on non-AM supporting operations */
+ assert(get_ia32_am_support(n) != ia32_am_None && "emit binop expects addressmode support");
+
if (! buf) {
buf = xcalloc(1, SNPRINTF_BUF_LEN);
}
switch(get_ia32_op_type(n)) {
case ia32_Normal:
if (get_ia32_cnst(n)) {
- lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D, %s", n, get_ia32_cnst(n));
+ lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%3S, %s", n, get_ia32_cnst(n));
}
else {
- lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D, %4S", n, n);
+ lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%3S, %4S", n, n);
}
break;
case ia32_AddrModeS:
- lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%1D, %s", n, ia32_emit_am(n));
+ lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%4S, %s", n, ia32_emit_am(n));
break;
case ia32_AddrModeD:
if (get_ia32_cnst(n)) {
lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %s", ia32_emit_am(n), get_ia32_cnst(n));
}
else {
- if (is_ia32_St(n)) {
- lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %3S", ia32_emit_am(n), n);
- }
- else {
- lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %4S", ia32_emit_am(n), n);
- }
+ lc_esnprintf(ia32_get_arg_env(), buf, SNPRINTF_BUF_LEN, "%s, %3S", ia32_emit_am(n), n);
}
break;
default:
char *s;
int size;
static struct obstack *obst = NULL;
+ ir_mode *mode = get_ia32_ls_mode(n);
+
+ if (! is_ia32_Lea(n))
+ assert(mode && "AM node must have ls_mode attribute set.");
if (! obst) {
obst = xcalloc(1, sizeof(*obst));
/* obstack_free with NULL results in an uninitialized obstack */
obstack_init(obst);
+ if (mode) {
+ switch (get_mode_size_bits(mode)) {
+ case 8:
+ obstack_printf(obst, "BYTE PTR ");
+ break;
+ case 16:
+ obstack_printf(obst, "WORD PTR ");
+ break;
+ case 32:
+ obstack_printf(obst, "DWORD PTR ");
+ break;
+ default:
+ assert(0 && "unsupported mode size");
+ }
+ }
+
obstack_printf(obst, "[");
if (am_flav & ia32_B) {
ir_node *proj;
const arch_register_t *reg = NULL;
- assert(get_irn_n_edges(irn) > pos && "Invalid OUT position");
-
/* 1st case: irn is not of mode_T, so it has only */
/* one OUT register -> good */
/* 2nd case: irn is of mode_T -> collect all Projs and ask the */
return reg;
}
-/**
- * Returns the number of the in register at position pos.
- */
-int get_ia32_reg_nr(ir_node *irn, int pos, int in_out) {
- const arch_register_t *reg;
-
- if (in_out == 1) {
- reg = get_in_reg(irn, pos);
- }
- else {
- reg = get_out_reg(irn, pos);
- }
-
- return arch_register_get_index(reg);
-}
-
enum io_direction {
IN_REG,
OUT_REG
reg = get_in_reg(irn, pos);
}
else {
+ /* destination address mode nodes don't have outputs */
+ if (is_ia32_irn(irn) && get_ia32_op_type(irn) == ia32_AddrModeD) {
+ return "MEM";
+ }
+
reg = get_out_reg(irn, pos);
}
buf = get_ia32_am_offs(X);
}
- return lc_arg_append(app, occ, buf, strlen(buf));
+ return buf ? lc_arg_append(app, occ, buf, strlen(buf)) : 0;
}
/**
static void emit_ia32_CondJmp(const ir_node *irn, emit_env_t *env) {
FILE *F = env->out;
- lc_efprintf(ia32_get_arg_env(), F, "\tcmp %2S, %1S\t\t\t/* CondJmp(%+F, %+F) */\n", irn, irn,
- get_irn_n(irn, 0), get_irn_n(irn, 1));
+ lc_efprintf(ia32_get_arg_env(), F, "\tcmp %s\t\t\t/* CondJmp(%+F, %+F) */\n",
+ ia32_emit_binop(irn), get_irn_n(irn, 0), get_irn_n(irn, 1));
finish_CondJmp(F, irn);
}
void emit_ia32_CondJmp_i(const ir_node *irn, emit_env_t *env) {
FILE *F = env->out;
- lc_efprintf(ia32_get_arg_env(), F, "\tcmp %C, %1S\t\t\t/* CondJmp_i(%+F) */\n", irn, irn, get_irn_n(irn, 0));
+ lc_efprintf(ia32_get_arg_env(), F, "\tcmp %s\t\t\t/* CondJmp_i(%+F) */\n",
+ ia32_emit_binop(irn), get_irn_n(irn, 0));
finish_CondJmp(F, irn);
}
if (tbl.num_branches > 1) {
/* create table */
- lc_efprintf(env, F, "\tjmp *%s(,%1S,4)\t\t/* get jump table entry as target */\n", tbl.label, irn);
+ lc_efprintf(env, F, "\tjmp [%1S*4+%s]\t\t/* get jump table entry as target */\n", irn, tbl.label);
fprintf(F, "\t.section\t.rodata\t\t/* start jump table */\n");
fprintf(F, "\t.align 4\n");
void emit_be_Call(const ir_node *irn, emit_env_t *emit_env) {
FILE *F = emit_env->out;
+ entity *ent = be_Call_get_entity(irn);
+
+ fprintf(F, "\tcall ");
- lc_efprintf(ia32_get_arg_env(), F, "\tcall %3S\t\t\t/* %+F(%+F) (be_Call) */\n", irn, irn, get_irn_n(irn, 2));
+ if (ent) {
+ fprintf(F, "%s", get_entity_name(ent));
+ }
+ else {
+ lc_efprintf(ia32_get_arg_env(), F, "%1D", get_irn_n(irn, be_pos_Call_ptr));
+ }
+
+ ir_fprintf(F, "\t\t\t/* %+F (be_Call) */\n", irn);
}
void emit_be_IncSP(const ir_node *irn, emit_env_t *emit_env) {
}
}
-void emit_be_AddSP(const ir_node *irn, emit_env_t *emit_env) {
+void emit_be_SetSP(const ir_node *irn, emit_env_t *emit_env) {
FILE *F = emit_env->out;
- lc_efprintf(ia32_get_arg_env(), F, "\tadd %1D, %1S\t\t\t/* %+F (AddSP) */\n", irn, irn, irn);
+
+ lc_efprintf(ia32_get_arg_env(), F, "\tmov %1D,%3S\t\t\t/* restore SP */\n", irn, irn);
}
+void emit_be_Copy(const ir_node *irn, emit_env_t *emit_env) {
+ FILE *F = emit_env->out;
+ lc_efprintf(ia32_get_arg_env(), F, "\tmov %1D,%1S\t\t\t/* %+F */\n", irn, irn, irn);
+}
+
+void emit_be_Perm(const ir_node *irn, emit_env_t *emit_env) {
+ FILE *F = emit_env->out;
+
+ lc_efprintf(ia32_get_arg_env(), F, "\txchg %1S, %2S\t\t\t/* %+F(%1A, %2A) */\n", irn, irn, irn);
+}
/***********************************************************************************
* _ __ _
/* benode emitter */
BE_EMIT(Call);
BE_EMIT(IncSP);
- BE_EMIT(AddSP);
+ BE_EMIT(SetSP);
+ BE_EMIT(Copy);
+ BE_EMIT(Perm);
/* firm emitter */
EMIT(Jmp);