+/* Spill register l0 or both l0 and l1, depending on n_spilled and n_to_spill.*/
+static void memperm_emit_spill_registers(const ir_node *node, int n_spilled,
+ int n_to_spill)
+{
+ assert(n_spilled < n_to_spill);
+
+ if (n_spilled == 0) {
+ /* We always reserve stack space for two registers because during copy
+ * processing we don't know yet if we also need to handle a cycle which
+ * needs two registers. More complicated code in emit_MemPerm would
+ * prevent wasting SPARC_REGISTER_SIZE bytes of stack space but
+ * it is not worth the worse readability of emit_MemPerm. */
+
+ /* Keep stack pointer aligned. */
+ unsigned sp_change = get_aligned_sp_change(2);
+ sparc_emitf(node, "sub %%sp, %u, %%sp", sp_change);
+
+ /* Spill register l0. */
+ sparc_emitf(node, "st %%l0, [%%sp%+d]", SPARC_MIN_STACKSIZE);
+ }
+
+ if (n_to_spill == 2) {
+ /* Spill register l1. */
+ sparc_emitf(node, "st %%l1, [%%sp%+d]", SPARC_MIN_STACKSIZE + SPARC_REGISTER_SIZE);
+ }
+}
+
+/* Restore register l0 or both l0 and l1, depending on n_spilled. */
+static void memperm_emit_restore_registers(const ir_node *node, int n_spilled)
+{
+ if (n_spilled == 2) {
+ /* Restore register l1. */
+ sparc_emitf(node, "ld [%%sp%+d], %%l1", SPARC_MIN_STACKSIZE + SPARC_REGISTER_SIZE);
+ }
+
+ /* Restore register l0. */
+ sparc_emitf(node, "ld [%%sp%+d], %%l0", SPARC_MIN_STACKSIZE);
+
+ /* Restore stack pointer. */
+ unsigned sp_change = get_aligned_sp_change(2);
+ sparc_emitf(node, "add %%sp, %u, %%sp", sp_change);
+}
+
+/* Emit code to copy in_ent to out_ent. Only uses l0. */
+static void memperm_emit_copy(const ir_node *node, ir_entity *in_ent,
+ ir_entity *out_ent)
+{
+ ir_graph *irg = get_irn_irg(node);
+ be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
+ int off_in = be_get_stack_entity_offset(layout, in_ent, 0);
+ int off_out = be_get_stack_entity_offset(layout, out_ent, 0);
+
+ /* Load from input entity. */
+ sparc_emitf(node, "ld [%%fp%+d], %%l0", off_in);
+ /* Store to output entity. */
+ sparc_emitf(node, "st %%l0, [%%fp%+d]", off_out);
+}
+
+/* Emit code to swap ent1 and ent2. Uses l0 and l1. */
+static void memperm_emit_swap(const ir_node *node, ir_entity *ent1,
+ ir_entity *ent2)
+{
+ ir_graph *irg = get_irn_irg(node);
+ be_stack_layout_t *layout = be_get_irg_stack_layout(irg);
+ int off1 = be_get_stack_entity_offset(layout, ent1, 0);
+ int off2 = be_get_stack_entity_offset(layout, ent2, 0);
+
+ /* Load from first input entity. */
+ sparc_emitf(node, "ld [%%fp%+d], %%l0", off1);
+ /* Load from second input entity. */
+ sparc_emitf(node, "ld [%%fp%+d], %%l1", off2);
+ /* Store first value to second output entity. */
+ sparc_emitf(node, "st %%l0, [%%fp%+d]", off2);
+ /* Store second value to first output entity. */
+ sparc_emitf(node, "st %%l1, [%%fp%+d]", off1);
+}
+
+/* Find the index of ent in ents or return -1 if not found. */
+static int get_index(ir_entity **ents, int n, ir_entity *ent)