Browse Source

2004-08-24 Zoltan Varga <[email protected]>

	* cpu-amd64.md: sreg1 of div instructions must be %rax.

	* mini-amd64.c: Register allocator fixes.

	* mini.c: Add an optimization to emit_state to avoid allocation of new
	registers on some platforms.

svn path=/trunk/mono/; revision=32776
Zoltan Varga 21 years ago
parent
commit
99f43af5bf
4 changed files with 48 additions and 10 deletions
  1. 9 0
      mono/mini/ChangeLog
  2. 8 9
      mono/mini/cpu-amd64.md
  3. 14 0
      mono/mini/mini-amd64.c
  4. 17 1
      mono/mini/mini.c

+ 9 - 0
mono/mini/ChangeLog

@@ -1,3 +1,12 @@
+2004-08-24  Zoltan Varga  <[email protected]>
+
+	* cpu-amd64.md: sreg1 of div instructions must be %rax.
+
+	* mini-amd64.c: Register allocator fixes.
+
+	* mini.c: Add an optimization to emit_state to avoid allocation of new
+	registers on some platforms.
+
 2004-08-23  Zoltan Varga  <[email protected]>
 
 	* inssel-x86.brg inssel-amd64: Add yet another missing tree->dreg assignment.

+ 8 - 9
mono/mini/cpu-amd64.md

@@ -96,10 +96,10 @@ stind.r8: dest:f src1:b
 add: dest:i src1:i src2:i len:3 clob:1
 sub: dest:i src1:i src2:i len:3 clob:1
 mul: dest:i src1:i src2:i len:4 clob:1
-div: dest:a src1:i src2:i len:16 clob:d
-div.un: dest:a src1:i src2:i len:16 clob:d
-rem: dest:d src1:i src2:i len:16 clob:d
-rem.un: dest:d src1:i src2:i len:16 clob:d
+div: dest:a src1:a src2:i len:16 clob:d
+div.un: dest:a src1:a src2:i len:16 clob:d
+rem: dest:d src1:a src2:i len:16 clob:d
+rem.un: dest:d src1:a src2:i len:16 clob:d
 and: dest:i src1:i src2:i len:3 clob:1
 or: dest:i src1:i src2:i len:3 clob:1
 xor: dest:i src1:i src2:i len:3 clob:1
@@ -120,7 +120,6 @@ callvirt:
 cpobj:
 ldobj:
 ldstr:
-newobj:
 castclass:
 isinst:
 conv.r.un: dest:f src1:i len:8
@@ -531,10 +530,10 @@ int_sub: dest:i src1:i src2:i clob:1 len:64
 int_mul: dest:i src1:i src2:i clob:1 len:64
 int_mul_ovf: dest:i src1:i src2:i clob:1 len:64
 int_mul_ovf_un: dest:i src1:i src2:i clob:1 len:64
-int_div: dest:a src1:i src2:i clob:d len:64
-int_div_un: dest:a src1:i src2:i clob:d len:64
-int_rem: dest:d src1:i src2:i clob:d len:64
-int_rem_un: dest:d src1:i src2:i clob:d len:64
+int_div: dest:a src1:a src2:i clob:d len:64
+int_div_un: dest:a src1:a src2:i clob:d len:64
+int_rem: dest:d src1:a src2:i clob:d len:64
+int_rem_un: dest:d src1:a src2:i clob:d len:64
 int_and: dest:i src1:i src2:i clob:1 len:64
 int_or: dest:i src1:i src2:i clob:1 len:64
 int_xor: dest:i src1:i src2:i clob:1 len:64

+ 14 - 0
mono/mini/mini-amd64.c

@@ -2451,6 +2451,20 @@ mono_arch_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
 		}
 		/* handle clobbering of sreg1 */
 		if ((spec [MONO_INST_CLOB] == '1' || spec [MONO_INST_CLOB] == 's') && ins->dreg != ins->sreg1) {
+			if (ins->dreg == ins->sreg2) {
+				/* 
+				 * copying sreg1 to dreg could clobber sreg2, so allocate a new
+				 * register for it.
+				 */
+				int reg2 = mono_amd64_alloc_int_reg (cfg, tmp, ins, dest_mask, ins->sreg2, 0);
+				MonoInst *copy;
+
+				DEBUG (g_print ("\tneed to copy sreg2 %s to reg %s\n", mono_arch_regname (ins->sreg2), mono_arch_regname (reg2)));
+				copy = create_copy_ins (cfg, reg2, ins->sreg2, NULL);
+				insert_before_ins (ins, tmp, copy);
+				prev_sreg2 = ins->sreg2 = reg2;
+			}
+
 			MonoInst *copy = create_copy_ins (cfg, ins->dreg, ins->sreg1, NULL);
 			DEBUG (g_print ("\tneed to copy sreg1 %s to dreg %s\n", mono_arch_regname (ins->sreg1), mono_arch_regname (ins->dreg)));
 			insert_before_ins (ins, tmp, copy);

+ 17 - 1
mono/mini/mini.c

@@ -7077,7 +7077,10 @@ emit_state (MonoCompile *cfg, MBState *state, int goal)
 		//if (state->reg2)
 		//	state->reg1 = state->reg2; /* chain rule */
 		//else
-		state->reg1 = mono_regstate_next_int (cfg->rs);
+#ifdef MONO_ARCH_ENABLE_EMIT_STATE_OPT
+		if (!state->reg1)
+#endif
+			state->reg1 = mono_regstate_next_int (cfg->rs);
 		//g_print ("alloc symbolic R%d (reg2: R%d) in block %d\n", state->reg1, state->reg2, cfg->cbb->block_num);
 		break;
 	case MB_NTERM_lreg:
@@ -7088,6 +7091,19 @@ emit_state (MonoCompile *cfg, MBState *state, int goal)
 		state->reg1 = mono_regstate_next_float (cfg->rs);
 		break;
 	default:
+#ifdef MONO_ARCH_ENABLE_EMIT_STATE_OPT
+		/*
+		 * Enabling this might cause bugs to surface in the local register
+		 * allocators on some architectures like x86.
+		 */
+		if ((state->tree->ssa_op == MONO_SSA_STORE) && (state->left->tree->opcode == OP_REGVAR)) {
+			/* Do not optimize away reg-reg moves */
+			if (! ((state->right->tree->ssa_op == MONO_SSA_LOAD) && (state->right->left->tree->opcode == OP_REGVAR))) {
+				state->right->reg1 = state->left->tree->dreg;
+			}
+		}
+#endif
+
 		/* do nothing */
 		break;
 	}