+static void emit_be_MemPerm(const ir_node *node)
+{
+ int i;
+ int memperm_arity;
+ int sp_change = 0;
+
+ /* TODO: this implementation is slower than necessary.
+ The longterm goal is however to avoid the memperm node completely */
+
+ memperm_arity = be_get_MemPerm_entity_arity(node);
+ if (memperm_arity > 12)
+ panic("memperm with more than 12 inputs not supported yet");
+
+ for (i = 0; i < memperm_arity; ++i) {
+ int offset;
+ ir_entity *entity = be_get_MemPerm_in_entity(node, i);
+
+ /* spill register */
+ be_emit_irprintf("\tstr r%d, [sp, #-4]!", i);
+ be_emit_finish_line_gas(node);
+ sp_change += 4;
+ /* load from entity */
+ offset = get_entity_offset(entity) + sp_change;
+ be_emit_irprintf("\tldr r%d, [sp, #%d]", i, offset);
+ be_emit_finish_line_gas(node);
+ }
+
+ for (i = memperm_arity-1; i >= 0; --i) {
+ int offset;
+ ir_entity *entity = be_get_MemPerm_out_entity(node, i);
+
+ /* store to new entity */
+ offset = get_entity_offset(entity) + sp_change;
+ be_emit_irprintf("\tstr r%d, [sp, #%d]", i, offset);
+ be_emit_finish_line_gas(node);
+ /* restore register */
+ be_emit_irprintf("\tldr r%d, [sp], #4", i);
+ sp_change -= 4;
+ be_emit_finish_line_gas(node);
+ }
+ assert(sp_change == 0);
+}
+
+static void emit_be_Start(const ir_node *node)
+{
+ ir_graph *irg = get_irn_irg(node);
+ ir_type *frame_type = get_irg_frame_type(irg);
+ unsigned size = get_type_size_bytes(frame_type);
+
+ /* allocate stackframe */
+ if (size > 0) {
+ be_emit_cstring("\tsub ");
+ arm_emit_register(&arm_registers[REG_SP]);
+ be_emit_cstring(", ");
+ arm_emit_register(&arm_registers[REG_SP]);
+ be_emit_irprintf(", #0x%X", size);
+ be_emit_finish_line_gas(node);
+ }
+}
+
+static void emit_be_Return(const ir_node *node)
+{
+ ir_graph *irg = get_irn_irg(node);
+ ir_type *frame_type = get_irg_frame_type(irg);
+ unsigned size = get_type_size_bytes(frame_type);