* @file
* @brief The codegenerator (transform FIRM into arm FIRM)
* @author Matthias Braun, Oliver Richter, Tobias Gneist, Michael Beck
- * @version $Id$
*/
#include "config.h"
#include "iropt_t.h"
#include "debug.h"
#include "error.h"
+#include "util.h"
-#include "../benode.h"
-#include "../beirg.h"
-#include "../beutil.h"
-#include "../betranshlp.h"
-#include "../beabihelper.h"
-#include "../beabi.h"
+#include "benode.h"
+#include "beirg.h"
+#include "beutil.h"
+#include "betranshlp.h"
+#include "beabihelper.h"
+#include "beabi.h"
#include "bearch_arm_t.h"
#include "arm_nodes_attr.h"
static ir_mode *mode_gp;
static ir_mode *mode_fp;
static beabi_helper_env_t *abihelper;
+static be_stackorder_t *stackorder;
static calling_convention_t *cconv = NULL;
static arm_isa_t *isa;
static pmap *node_to_stack;
+static const arch_register_t *const callee_saves[] = {
+ &arm_registers[REG_R4],
+ &arm_registers[REG_R5],
+ &arm_registers[REG_R6],
+ &arm_registers[REG_R7],
+ &arm_registers[REG_R8],
+ &arm_registers[REG_R9],
+ &arm_registers[REG_R10],
+ &arm_registers[REG_R11],
+ &arm_registers[REG_LR],
+};
+
+static const arch_register_t *const caller_saves[] = {
+ &arm_registers[REG_R0],
+ &arm_registers[REG_R1],
+ &arm_registers[REG_R2],
+ &arm_registers[REG_R3],
+ &arm_registers[REG_LR],
+
+ &arm_registers[REG_F0],
+ &arm_registers[REG_F1],
+ &arm_registers[REG_F2],
+ &arm_registers[REG_F3],
+ &arm_registers[REG_F4],
+ &arm_registers[REG_F5],
+ &arm_registers[REG_F6],
+ &arm_registers[REG_F7],
+};
+
static bool mode_needs_gp_reg(ir_mode *mode)
{
return mode_is_int(mode) || mode_is_reference(mode);
if (vn.ops < v.ops) {
/* remove bits */
result = new_bd_arm_Mvn_imm(dbgi, block, vn.values[0], vn.rors[0]);
- be_dep_on_frame(result);
for (cnt = 1; cnt < vn.ops; ++cnt) {
result = new_bd_arm_Bic_imm(dbgi, block, result,
} else {
/* add bits */
result = new_bd_arm_Mov_imm(dbgi, block, v.values[0], v.rors[0]);
- be_dep_on_frame(result);
for (cnt = 1; cnt < v.ops; ++cnt) {
result = new_bd_arm_Or_imm(dbgi, block, result,
}
if (try_encode_as_immediate(op2, &imm)) {
- ir_node *new_op1 = be_transform_node(op1);
+ new_op1 = be_transform_node(op1);
return factory->new_binop_imm(dbgi, block, new_op1, imm.imm_8, imm.rot);
}
new_op2 = be_transform_node(op2);
if (USE_FPA(isa)) {
return new_bd_arm_Adf(dbgi, block, new_op1, new_op2, mode);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
if (USE_FPA(isa)) {
return new_bd_arm_Muf(dbg, block, new_op1, new_op2, mode);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
ir_mode *mode = get_Div_resmode(node);
dbg_info *dbg = get_irn_dbg_info(node);
- assert(mode != mode_E && "IEEE Extended FP not supported");
/* integer division should be replaced by builtin call */
assert(mode_is_float(mode));
if (USE_FPA(isa)) {
return new_bd_arm_Dvf(dbg, block, new_op1, new_op2, mode);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
if (USE_FPA(isa)) {
return new_bd_arm_Suf(dbgi, block, new_op1, new_op2, mode);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
ir_node *op1 = get_binop_left(node);
ir_node *op2 = get_binop_right(node);
dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_mode *mode = get_irn_mode(node);
ir_node *new_op1;
ir_node *new_op2;
+ if (get_mode_modulo_shift(mode) != 32)
+ panic("modulo shift!=32 not supported");
+
if (flags & MATCH_SIZE_NEUTRAL) {
op1 = arm_skip_downconv(op1);
op2 = arm_skip_downconv(op2);
if (USE_FPA(isa)) {
return new_bd_arm_Mvf(dbgi, block, op, mode);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_load = NULL;
+ if (get_Load_unaligned(node) == align_non_aligned)
+ panic("unaligned Loads not supported yet");
+
if (mode_is_float(mode)) {
if (USE_FPA(isa)) {
new_load = new_bd_arm_Ldf(dbgi, block, new_ptr, new_mem, mode,
NULL, 0, 0, false);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_store = NULL;
+ if (get_Store_unaligned(node) == align_non_aligned)
+ panic("unaligned Stores not supported yet");
+
if (mode_is_float(mode)) {
if (USE_FPA(isa)) {
new_store = new_bd_arm_Stf(dbgi, block, new_ptr, new_val,
new_mem, mode, NULL, 0, 0, false);
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
return new_bd_arm_Jmp(dbgi, new_block);
}
-static ir_node *gen_SwitchJmp(ir_node *node)
+static ir_node *gen_Switch(ir_node *node)
{
- ir_node *block = be_transform_node(get_nodes_block(node));
- ir_node *selector = get_Cond_selector(node);
- dbg_info *dbgi = get_irn_dbg_info(node);
- ir_node *new_op = be_transform_node(selector);
- ir_node *const_graph;
- ir_node *sub;
-
- ir_node *proj;
- const ir_edge_t *edge;
- int min = INT_MAX;
- int max = INT_MIN;
- int translation;
- int pn;
- int n_projs;
-
- foreach_out_edge(node, edge) {
- proj = get_edge_src_irn(edge);
- assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
+ ir_graph *irg = get_irn_irg(node);
+ ir_node *block = be_transform_node(get_nodes_block(node));
+ ir_node *selector = get_Switch_selector(node);
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_node *new_op = be_transform_node(selector);
+ ir_mode *mode = get_irn_mode(selector);
+ const ir_switch_table *table = get_Switch_table(node);
+ unsigned n_outs = get_Switch_n_outs(node);
- pn = get_Proj_proj(proj);
+ table = ir_switch_table_duplicate(irg, table);
- min = pn<min ? pn : min;
- max = pn>max ? pn : max;
- }
- translation = min;
- n_projs = max - translation + 1;
-
- foreach_out_edge(node, edge) {
- proj = get_edge_src_irn(edge);
- assert(is_Proj(proj) && "Only proj allowed at SwitchJmp");
-
- pn = get_Proj_proj(proj) - translation;
- set_Proj_proj(proj, pn);
- }
+ /* switch with smaller modes not implemented yet */
+ assert(get_mode_size_bits(mode) == 32);
- const_graph = create_const_graph_value(dbgi, block, translation);
- sub = new_bd_arm_Sub_reg(dbgi, block, new_op, const_graph);
- return new_bd_arm_SwitchJmp(dbgi, block, sub, n_projs, get_Cond_default_proj(node) - translation);
+ return new_bd_arm_SwitchJmp(dbgi, block, new_op, n_outs, table);
}
static ir_node *gen_Cmp(ir_node *node)
static ir_node *gen_Cond(ir_node *node)
{
- ir_node *selector = get_Cond_selector(node);
- ir_mode *mode = get_irn_mode(selector);
- ir_node *block;
- ir_node *flag_node;
- dbg_info *dbgi;
+ ir_node *selector = get_Cond_selector(node);
+ ir_relation relation;
+ ir_node *block;
+ ir_node *flag_node;
+ dbg_info *dbgi;
- if (mode != mode_b) {
- return gen_SwitchJmp(node);
- }
- assert(is_Proj(selector));
+ assert(is_Cmp(selector));
block = be_transform_node(get_nodes_block(node));
dbgi = get_irn_dbg_info(node);
- flag_node = be_transform_node(get_Proj_pred(selector));
+ flag_node = be_transform_node(selector);
+ relation = get_Cmp_relation(selector);
- return new_bd_arm_B(dbgi, block, flag_node, get_Proj_pn_cmp(selector));
+ return new_bd_arm_B(dbgi, block, flag_node, relation);
}
enum fpa_imm_mode {
FPA_IMM_FLOAT = 0,
FPA_IMM_DOUBLE = 1,
- FPA_IMM_EXTENDED = 2,
- FPA_IMM_MAX = FPA_IMM_EXTENDED
+ FPA_IMM_MAX = FPA_IMM_DOUBLE
};
static ir_tarval *fpa_imm[FPA_IMM_MAX + 1][fpa_max];
case 64:
i = FPA_IMM_DOUBLE;
break;
- default:
- i = FPA_IMM_EXTENDED;
}
if (tarval_is_negative(tv)) {
if (USE_FPA(isa)) {
ir_tarval *tv = get_Const_tarval(node);
node = new_bd_arm_fConst(dbg, block, tv);
- be_dep_on_frame(node);
return node;
} else if (USE_VFP(isa)) {
- assert(mode != mode_E && "IEEE Extended FP not supported");
panic("VFP not supported yet");
} else {
panic("Softfloat not supported yet");
ir_node *new_node;
new_node = new_bd_arm_SymConst(dbgi, block, entity, 0);
- be_dep_on_frame(new_node);
return new_node;
}
* registers... */
ir_graph *irg = current_ir_graph;
ir_node *stack = get_irg_frame(irg);
- ir_node *nomem = new_r_NoMem(irg);
+ ir_node *nomem = get_irg_no_mem(irg);
ir_node *str0 = new_bd_arm_Str(dbgi, block, stack, node0, nomem, mode_gp,
NULL, 0, 0, true);
ir_node *str1 = new_bd_arm_Str(dbgi, block, stack, node1, nomem, mode_gp,
{
ir_graph *irg = current_ir_graph;
ir_node *stack = get_irg_frame(irg);
- ir_node *nomem = new_r_NoMem(irg);
+ ir_node *nomem = get_irg_no_mem(irg);
ir_node *str = new_bd_arm_Str(dbgi, block, stack, node, nomem, mode_gp,
NULL, 0, 0, true);
ir_node *ldf;
{
ir_graph *irg = current_ir_graph;
ir_node *stack = get_irg_frame(irg);
- ir_node *nomem = new_r_NoMem(irg);
+ ir_node *nomem = get_irg_no_mem(irg);
ir_node *stf = new_bd_arm_Stf(dbgi, block, stack, node, nomem, mode_F,
NULL, 0, 0, true);
ir_node *ldr;
{
ir_graph *irg = current_ir_graph;
ir_node *stack = get_irg_frame(irg);
- ir_node *nomem = new_r_NoMem(irg);
+ ir_node *nomem = get_irg_no_mem(irg);
ir_node *stf = new_bd_arm_Stf(dbgi, block, stack, node, nomem, mode_D,
NULL, 0, 0, true);
ir_node *ldr0, *ldr1;
ir_node *src_copy;
ir_node *dst_copy;
- src_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], block, new_src);
- dst_copy = be_new_Copy(&arm_reg_classes[CLASS_arm_gp], block, new_dst);
+ src_copy = be_new_Copy(block, new_src);
+ dst_copy = be_new_Copy(block, new_dst);
return new_bd_arm_CopyB(dbg, block, dst_copy, src_copy,
new_bd_arm_EmptyReg(dbg, block),
case ir_bk_inner_trampoline:
break;
}
- panic("Builtin %s not implemented in ARM", get_builtin_kind_name(kind));
+ panic("Builtin %s not implemented", get_builtin_kind_name(kind));
}
/**
case ir_bk_parity:
case ir_bk_popcount:
case ir_bk_bswap:
- assert(get_Proj_proj(proj) == pn_Builtin_1_result);
+ assert(get_Proj_proj(proj) == pn_Builtin_max+1);
return new_node;
case ir_bk_trap:
case ir_bk_debugbreak:
case ir_bk_inner_trampoline:
break;
}
- panic("Builtin %s not implemented in ARM", get_builtin_kind_name(kind));
+ panic("Builtin %s not implemented", get_builtin_kind_name(kind));
}
static ir_node *gen_Proj_Load(ir_node *node)
panic("Unsupported Proj from Div");
}
-/**
- * Transform the Projs from a Cmp.
- */
-static ir_node *gen_Proj_Cmp(ir_node *node)
-{
- (void) node;
- /* we should only be here in case of a Mux node */
- panic("Mux NYI");
-}
-
static ir_node *gen_Proj_Start(ir_node *node)
{
ir_node *block = get_nodes_block(node);
ir_node *new_block = be_transform_node(block);
- ir_node *barrier = be_transform_node(get_Proj_pred(node));
long proj = get_Proj_proj(node);
switch ((pn_Start) proj) {
return new_bd_arm_Jmp(NULL, new_block);
case pn_Start_M:
- return new_r_Proj(barrier, mode_M, 0);
+ return be_prolog_get_memory(abihelper);
case pn_Start_T_args:
- return barrier;
+ return new_r_Bad(get_irn_irg(block), mode_T);
case pn_Start_P_frame_base:
return be_prolog_get_reg_value(abihelper, sp_reg);
-
- case pn_Start_P_tls:
- return new_r_Bad(get_irn_irg(node));
-
- case pn_Start_max:
- break;
}
panic("unexpected start proj: %ld\n", proj);
}
*/
static int find_out_for_reg(ir_node *node, const arch_register_t *reg)
{
- int n_outs = arch_irn_get_n_outs(node);
+ int n_outs = arch_get_irn_n_outs(node);
int o;
for (o = 0; o < n_outs; ++o) {
- const arch_register_req_t *req = arch_get_out_register_req(node, o);
+ const arch_register_req_t *req = arch_get_irn_register_req_out(node, o);
if (req == reg->single_req)
return o;
}
case pn_Call_X_regular:
case pn_Call_X_except:
case pn_Call_T_result:
- case pn_Call_P_value_res_base:
- case pn_Call_max:
break;
}
panic("Unexpected Call proj %ld\n", pn);
return gen_Proj_CopyB(node);
case iro_Div:
return gen_Proj_Div(node);
- case iro_Cmp:
- return gen_Proj_Cmp(node);
case iro_Start:
return gen_Proj_Start(node);
case iro_Cond:
+ case iro_Switch:
/* nothing to do */
return be_duplicate_node(node);
case iro_Proj: {
/* just produce a 0 */
ir_mode *mode = get_irn_mode(node);
if (mode_is_float(mode)) {
- ir_tarval *tv = get_mode_null(mode);
- ir_node *node = new_bd_arm_fConst(dbgi, new_block, tv);
- be_dep_on_frame(node);
- return node;
+ ir_tarval *tv = get_mode_null(mode);
+ ir_node *fconst = new_bd_arm_fConst(dbgi, new_block, tv);
+ return fconst;
} else if (mode_needs_gp_reg(mode)) {
return create_const_graph_value(dbgi, new_block, 0);
}
layout->frame_type = get_irg_frame_type(irg);
layout->between_type = arm_get_between_type();
layout->arg_type = arg_type;
- layout->param_map = NULL; /* TODO */
layout->initial_offset = 0;
layout->initial_bias = 0;
- layout->stack_dir = -1;
layout->sp_relative = true;
assert(N_FRAME_TYPES == 3);
}
/**
- * transform the start node to the prolog code + initial barrier
+ * transform the start node to the prolog code
*/
static ir_node *gen_Start(ir_node *node)
{
ir_node *new_block = be_transform_node(block);
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *start;
- ir_node *incsp;
- ir_node *sp;
- ir_node *barrier;
size_t i;
/* stackpointer is important at function prolog */
be_prolog_add_reg(abihelper, param->reg1, arch_register_req_type_none);
}
/* announce that we need the values of the callee save regs */
- for (i = 0; i < (sizeof(callee_saves)/sizeof(callee_saves[0])); ++i) {
+ for (i = 0; i != ARRAY_SIZE(callee_saves); ++i) {
be_prolog_add_reg(abihelper, callee_saves[i], arch_register_req_type_none);
}
start = be_prolog_create_start(abihelper, dbgi, new_block);
- sp = be_prolog_get_reg_value(abihelper, sp_reg);
- incsp = be_new_IncSP(sp_reg, new_block, sp, BE_STACK_FRAME_SIZE_EXPAND, 0);
- be_prolog_set_reg_value(abihelper, sp_reg, incsp);
- barrier = be_prolog_create_barrier(abihelper, new_block);
-
- return barrier;
+ return start;
}
static ir_node *get_stack_pointer_for(ir_node *node)
{
/* get predecessor in stack_order list */
- ir_node *stack_pred = be_get_stack_pred(abihelper, node);
- ir_node *stack_pred_transformed;
+ ir_node *stack_pred = be_get_stack_pred(stackorder, node);
ir_node *stack;
if (stack_pred == NULL) {
return sp_proj;
}
- stack_pred_transformed = be_transform_node(stack_pred);
- stack = (ir_node*)pmap_get(node_to_stack, stack_pred);
+ be_transform_node(stack_pred);
+ stack = pmap_get(ir_node, node_to_stack, stack_pred);
if (stack == NULL) {
return get_stack_pointer_for(stack_pred);
}
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *mem = get_Return_mem(node);
ir_node *new_mem = be_transform_node(mem);
- int n_callee_saves = sizeof(callee_saves)/sizeof(callee_saves[0]);
+ size_t n_callee_saves = ARRAY_SIZE(callee_saves);
ir_node *sp_proj = get_stack_pointer_for(node);
- int n_res = get_Return_n_ress(node);
+ size_t n_res = get_Return_n_ress(node);
ir_node *bereturn;
- ir_node *incsp;
- int i;
+ size_t i;
be_epilog_begin(abihelper);
be_epilog_set_memory(abihelper, new_mem);
be_epilog_add_reg(abihelper, reg, arch_register_req_type_none, value);
}
- /* create the barrier before the epilog code */
- be_epilog_create_barrier(abihelper, new_block);
-
/* epilog code: an incsp */
- sp_proj = be_epilog_get_reg_value(abihelper, sp_reg);
- incsp = be_new_IncSP(sp_reg, new_block, sp_proj,
- BE_STACK_FRAME_SIZE_SHRINK, 0);
- be_epilog_set_reg_value(abihelper, sp_reg, incsp);
-
bereturn = be_epilog_create_return(abihelper, dbgi, new_block);
-
return bereturn;
}
ir_type *type = get_Call_type(node);
calling_convention_t *cconv = arm_decide_calling_convention(NULL, type);
size_t n_params = get_Call_n_params(node);
- size_t n_param_regs = sizeof(param_regs)/sizeof(param_regs[0]);
+ size_t const n_param_regs = cconv->n_reg_params;
/* max inputs: memory, callee, register arguments */
- int max_inputs = 2 + n_param_regs;
+ size_t const max_inputs = 2 + n_param_regs;
ir_node **in = ALLOCAN(ir_node*, max_inputs);
ir_node **sync_ins = ALLOCAN(ir_node*, max_inputs);
struct obstack *obst = be_get_be_obst(irg);
const arch_register_req_t **in_req
= OALLOCNZ(obst, const arch_register_req_t*, max_inputs);
- int in_arity = 0;
- int sync_arity = 0;
- int n_caller_saves
- = sizeof(caller_saves)/sizeof(caller_saves[0]);
- ir_entity *entity = NULL;
- ir_node *incsp = NULL;
+ size_t in_arity = 0;
+ size_t sync_arity = 0;
+ size_t const n_caller_saves = ARRAY_SIZE(caller_saves);
+ ir_entity *entity = NULL;
+ ir_node *incsp = NULL;
int mem_pos;
ir_node *res;
size_t p;
- int o;
- int out_arity;
+ size_t o;
+ size_t out_arity;
assert(n_params == get_method_n_params(type));
pmap_insert(node_to_stack, node, incsp);
}
- arch_set_in_register_reqs(res, in_req);
+ arch_set_irn_register_reqs_in(res, in_req);
/* create output register reqs */
- arch_set_out_register_req(res, 0, arch_no_register_req);
+ arch_set_irn_register_req_out(res, 0, arch_no_register_req);
for (o = 0; o < n_caller_saves; ++o) {
const arch_register_t *reg = caller_saves[o];
- arch_set_out_register_req(res, o+1, reg->single_req);
+ arch_set_irn_register_req_out(res, o+1, reg->single_req);
}
/* copy pinned attribute */
/* must be the frame pointer all other sels must have been lowered
* already */
assert(is_Proj(ptr) && is_Start(get_Proj_pred(ptr)));
- /* we should not have value types from parameters anymore - they should be
- lowered */
- assert(get_entity_owner(entity) !=
- get_method_value_param_type(get_entity_type(get_irg_entity(get_irn_irg(node)))));
return new_bd_arm_FrameAddr(dbgi, new_block, new_ptr, entity, 0);
}
copy_node_attr(irg, node, phi);
be_duplicate_deps(node, phi);
- arch_set_out_register_req(phi, 0, req);
+ arch_set_irn_register_req_out(phi, 0, req);
be_enqueue_preds(node);
be_set_transform_function(op_Start, gen_Start);
be_set_transform_function(op_Store, gen_Store);
be_set_transform_function(op_Sub, gen_Sub);
+ be_set_transform_function(op_Switch, gen_Switch);
be_set_transform_function(op_SymConst, gen_SymConst);
be_set_transform_function(op_Unknown, gen_Unknown);
be_set_transform_function(op_Builtin, gen_Builtin);
fpa_imm[FPA_IMM_DOUBLE][fpa_five] = new_tarval_from_str("5", 1, mode_D);
fpa_imm[FPA_IMM_DOUBLE][fpa_ten] = new_tarval_from_str("10", 2, mode_D);
fpa_imm[FPA_IMM_DOUBLE][fpa_half] = new_tarval_from_str("0.5", 3, mode_D);
-
- fpa_imm[FPA_IMM_EXTENDED][fpa_null] = get_mode_null(mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_one] = get_mode_one(mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_two] = new_tarval_from_str("2", 1, mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_three] = new_tarval_from_str("3", 1, mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_four] = new_tarval_from_str("4", 1, mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_five] = new_tarval_from_str("5", 1, mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_ten] = new_tarval_from_str("10", 2, mode_E);
- fpa_imm[FPA_IMM_EXTENDED][fpa_half] = new_tarval_from_str("0.5", 3, mode_E);
}
/**
ir_type *frame_type;
mode_gp = mode_Iu;
- mode_fp = mode_E;
+ mode_fp = mode_F;
if (! imm_initialized) {
arm_init_fpa_immediate();
assert(abihelper == NULL);
abihelper = be_abihelper_prepare(irg);
- be_collect_stacknodes(abihelper);
+ stackorder = be_collect_stacknodes(irg);
assert(cconv == NULL);
cconv = arm_decide_calling_convention(irg, get_entity_type(entity));
create_stacklayout(irg);
be_abihelper_finish(abihelper);
abihelper = NULL;
+ be_free_stackorder(stackorder);
+ stackorder = NULL;
arm_free_calling_convention(cconv);
cconv = NULL;