[mono/mono] 4c0376d0: [amd64] Unify the register saving/restoring code for the fp/no-fp cases.

"Zoltan Varga ([email protected])" <[email protected]> Mon, 25 Nov 2013 09:35:03 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <000001428e9cb466-179f5886-cb9d-48af-80f4-76a5e7f98144-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/0ad5599acb3e...4c0376d037e3

   Commit: 4c0376d037e3cd5910a24b3e568c6e9ad5bb40d2
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-25 09:33:46 GMT
      URL: https://github.com/mono/mono/commit/4c0376d037e3cd5910a24b3e568c6e9ad5bb40d2

[amd64] Unify the register saving/restoring code for the fp/no-fp cases.

Changed paths:
  M mono/mini/mini-amd64.c

Modified: mono/mini/mini-amd64.c
===================================================================
@@ -1744,6 +1744,8 @@
 			if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
 				offset += sizeof(mgreg_t);
 			}
+		if (!cfg->arch.omit_fp)
+			cfg->arch.reg_save_area_offset = -offset;
 	}
 
 	if (sig_ret->type != MONO_TYPE_VOID) {
@@ -6741,23 +6743,6 @@
 #endif
 	}
 
-	/* Save callee saved registers */
-	if (!cfg->arch.omit_fp && !method->save_lmf) {
-		int offset = cfa_offset;
-
-		for (i = 0; i < AMD64_NREG; ++i)
-			if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-				amd64_push_reg (code, i);
-				pos += 8; /* AMD64 push inst is always 8 bytes, no way to change it */
-				offset += 8;
-				mono_emit_unwind_op_offset (cfg, code, i, - offset);
-				async_exc_point (code);
-
-				/* These are handled automatically by the stack marking code */
-				mini_gc_set_slot_type_from_cfa (cfg, - offset, SLOT_NOREF);
-			}
-	}
-
 	/* The param area is always at offset 0 from sp */
 	/* This needs to be allocated here, since it has to come after the spill area */
 	if (cfg->arch.no_pushes && cfg->param_area) {
@@ -6894,19 +6879,31 @@
 	}
 
 	/* Save callee saved registers */
-	if (cfg->arch.omit_fp && !method->save_lmf) {
-		gint32 save_area_offset = cfg->arch.reg_save_area_offset;
+	if (!method->save_lmf) {
+		gint32 save_area_offset;
+
+		if (cfg->arch.omit_fp) {
+			save_area_offset = cfg->arch.reg_save_area_offset;
+			/* Save caller saved registers after sp is adjusted */
+			/* The registers are saved at the bottom of the frame */
+			/* FIXME: Optimize this so the regs are saved at the end of the frame in increasing order */
+		} else {
+			/* The registers are saved just below the saved rbp */
+			save_area_offset = cfg->arch.reg_save_area_offset;
+		}
 
-		/* Save caller saved registers after sp is adjusted */
-		/* The registers are saved at the bottom of the frame */
-		/* FIXME: Optimize this so the regs are saved at the end of the frame in increasing order */
 		for (i = 0; i < AMD64_NREG; ++i)
 			if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-				amd64_mov_membase_reg (code, AMD64_RSP, save_area_offset, i, 8);
-				mono_emit_unwind_op_offset (cfg, code, i, - (cfa_offset - save_area_offset));
+				amd64_mov_membase_reg (code, cfg->frame_reg, save_area_offset, i, 8);
 
-				/* These are handled automatically by the stack marking code */
-				mini_gc_set_slot_type_from_cfa (cfg, - (cfa_offset - save_area_offset), SLOT_NOREF);
+				if (cfg->arch.omit_fp) {
+					mono_emit_unwind_op_offset (cfg, code, i, - (cfa_offset - save_area_offset));
+					/* These are handled automatically by the stack marking code */
+					mini_gc_set_slot_type_from_cfa (cfg, - (cfa_offset - save_area_offset), SLOT_NOREF);
+				} else {
+					mono_emit_unwind_op_offset (cfg, code, i, - (-save_area_offset + (2 * 8)));
+					// FIXME: GC
+				}
 
 				save_area_offset += 8;
 				async_exc_point (code);
@@ -7305,40 +7302,13 @@
 		}
 #endif
 	} else {
+		gint32 save_area_offset = cfg->arch.reg_save_area_offset;
 
-		if (cfg->arch.omit_fp) {
-			gint32 save_area_offset = cfg->arch.reg_save_area_offset;
-
-			for (i = 0; i < AMD64_NREG; ++i)
-				if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-					amd64_mov_reg_membase (code, i, AMD64_RSP, save_area_offset, 8);
-					save_area_offset += 8;
-				}
-		}
-		else {
-			for (i = 0; i < AMD64_NREG; ++i)
-				if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i)))
-					pos -= sizeof(mgreg_t);
-
-			if (pos) {
-				if (pos == - sizeof(mgreg_t)) {
-					/* Only one register, so avoid lea */
-					for (i = AMD64_NREG - 1; i > 0; --i)
-						if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-							amd64_mov_reg_membase (code, i, AMD64_RBP, pos, 8);
-						}
-				}
-				else {
-					amd64_lea_membase (code, AMD64_RSP, AMD64_RBP, pos);
-
-					/* Pop registers in reverse order */
-					for (i = AMD64_NREG - 1; i > 0; --i)
-						if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-							amd64_pop_reg (code, i);
-						}
-				}
+		for (i = 0; i < AMD64_NREG; ++i)
+			if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
+				amd64_mov_reg_membase (code, i, cfg->frame_reg, save_area_offset, 8);
+				save_area_offset += 8;
 			}
-		}
 	}
 
 	/* Load returned vtypes into registers if needed */


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches