added get_next_ir_opcodes() to allow allocation of cosecutive opcodes
[libfirm] / ir / be / ia32 / ia32_emitter.c
index e668f91..999317a 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <limits.h>
 
+#include "xmalloc.h"
 #include "tv.h"
 #include "iredges.h"
 #include "debug.h"
@@ -44,7 +45,7 @@ const char *node_const_to_str(ir_node *n) {
        tarval *tv = get_ia32_Immop_tarval(n);
 
        if (tv) {
-               buf = malloc(SNPRINTF_BUF_LEN);
+               buf = xmalloc(SNPRINTF_BUF_LEN);
                tarval_snprintf(buf, SNPRINTF_BUF_LEN, tv);
                return buf;
        }
@@ -63,7 +64,7 @@ char *node_offset_to_str(ir_node *n) {
        tarval *tv = get_ia32_am_offs(n);
 
        if (tv) {
-               buf = malloc(SNPRINTF_BUF_LEN);
+               buf = xmalloc(SNPRINTF_BUF_LEN);
                tarval_snprintf(buf, SNPRINTF_BUF_LEN, tv);
                return buf;
        }
@@ -474,11 +475,11 @@ void emit_ia32_SwitchJmp(const ir_node *irn, emit_env_t *emit_env) {
        FILE               *F   = emit_env->out;
 
        /* fill the table structure */
-       tbl.label        = malloc(SNPRINTF_BUF_LEN);
+       tbl.label        = xmalloc(SNPRINTF_BUF_LEN);
        tbl.label        = get_unique_label(tbl.label, SNPRINTF_BUF_LEN, "JMPTBL_");
        tbl.defProj      = NULL;
        tbl.num_branches = get_irn_n_edges(irn);
-       tbl.branches     = calloc(tbl.num_branches, sizeof(tbl.branches[0]));
+       tbl.branches     = xcalloc(tbl.num_branches, sizeof(tbl.branches[0]));
        tbl.min_value    = INT_MAX;
        tbl.max_value    = INT_MIN;
 
@@ -668,6 +669,48 @@ void emit_ia32_Call(ir_node *irn, emit_env_t *emit_env) {
 }
 
 
+
+/**
+ * Emits code for Alloca (increase stack pointer, cpoy to destination)
+ */
+void emit_Alloca(ir_node *irn, emit_env_t *emit_env, int is_imm) {
+       const lc_arg_env_t *env = ia32_get_arg_env();
+       FILE               *F   = emit_env->out;
+       char               *sp;
+
+       if (emit_env->cg->has_alloca) {
+               sp = "%ebp";
+       }
+       else {
+               sp = "%esp";
+       }
+
+
+       /* allocate the memory */
+       fprintf(F, "\tsub %s", sp);
+
+       if (is_imm) {
+               lc_efprintf(env, F, "%C", irn);
+       }
+       else {
+               lc_efprintf(env, F, "%1S", irn);
+       }
+
+       fprintf(F, "\t\t\t\t/* reserve memory on stack */\n");
+
+       /* copy the new stack pointer to destination register */
+       lc_efprintf(env, F, "\tmov %s, %1D\t\t\t/* copy stack pointer to destination */\n", sp, irn);
+}
+
+void emit_ia32_Alloca(ir_node *irn, emit_env_t *emit_env) {
+       emit_Alloca(irn, emit_env, 0);
+}
+
+void emit_ia32_Alloca_i(ir_node *irn, emit_env_t *emit_env) {
+       emit_Alloca(irn, emit_env, 1);
+}
+
+
 /***********************************************************************************
  *                  _          __                                             _
  *                 (_)        / _|                                           | |
@@ -759,6 +802,8 @@ void ia32_emit_node(ir_node *irn, void *env) {
        IA32_EMIT(CondJmp_i);
        IA32_EMIT(SwitchJmp);
        IA32_EMIT(Call);
+       IA32_EMIT(Alloca);
+       IA32_EMIT(Alloca_i);
 
        EMIT(Jmp);
        EMIT(Proj);