? t1 Index: Codex86.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Codex86.m3,v retrieving revision 1.117 diff -u -r1.117 Codex86.m3 --- Codex86.m3 15 Mar 2010 14:40:14 -0000 1.117 +++ Codex86.m3 15 Mar 2010 15:05:07 -0000 @@ -904,6 +904,11 @@ PROCEDURE movOp1 (t: T; READONLY dest, src: Operand) = VAR ins: Instruction; mnemonic: TEXT := NIL; BEGIN + + IF dest.loc = OLoc.register THEN + t.parent.proc_reguse[dest.reg[0]] := TRUE; + END; + <* ASSERT dest.loc = OLoc.register OR dest.loc = OLoc.mem *> IF src.loc = OLoc.imm THEN movImmT(t, dest, src.imm); @@ -1572,6 +1577,9 @@ VAR ins: Instruction; mnemonic := "MOV"; BEGIN + + t.parent.proc_reguse[r] := TRUE; + <* ASSERT ind.loc = OLoc.register *> ins.opcode := 16_8B; @@ -1922,16 +1930,7 @@ val - (ptr.offs + 1) >= -16_80 *> t.obj.patch(ptr.seg, ptr.offs, val - (ptr.offs + 1), 1); ELSE - (* Filling labels at the end (really, past the end) - * of the object file occurs when we generate - * an epilogue. There should be a cleaner way to handle this. - * In the past, it was handled another way but not cleanly, - * where procedure_epilogue would use patch to generate - * the epilogue. - *) - IF ptr.offs < t.obj.cursor(Seg.Text) THEN - t.obj.patch(ptr.seg, ptr.offs, val - (ptr.offs + 4), 4); - END + t.obj.patch(ptr.seg, ptr.offs, val - (ptr.offs + 4), 4); END END; ptr := ptr.link; Index: M3x86.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/M3x86.m3,v retrieving revision 1.179 diff -u -r1.179 M3x86.m3 --- M3x86.m3 15 Mar 2010 14:40:14 -0000 1.179 +++ M3x86.m3 15 Mar 2010 15:05:08 -0000 @@ -1353,6 +1353,12 @@ u.last_exitbranch := -1; u.exit_proclabel := -1; + (* Mark non-volatiles as not used, until known otherwise. *) + + u.proc_reguse[EBX] := FALSE; + u.proc_reguse[ESI] := FALSE; + u.proc_reguse[EDI] := FALSE; + realproc.offset := u.obj.cursor(Seg.Text); realproc.bound := TRUE; @@ -1613,27 +1619,42 @@ END exit_proc; PROCEDURE procedure_epilogue (u: U) = - VAR callee_cleans := u.current_proc.stdcall; + CONST NOP = 16_90; BEGIN IF u.exit_proclabel = -1 THEN RETURN; - (* Strange as it may seem, some procedures have no exit points... *) + (* Strange as it may seem, some procedures have no exit points. *) END; IF u.last_exitbranch = u.obj.cursor(Seg.Text) - 5 THEN (* Don't generate a branch to the epilogue at the last exit point of the procedure *) + u.cg.set_label(u.exit_proclabel, offset := -5); u.obj.backup(Seg.Text, 5); + ELSE + u.cg.set_label(u.exit_proclabel); + END; + + IF u.proc_reguse[EDI] THEN + u.cg.popOp(u.cg.reg[EDI]); + ELSE + u.obj.patch(Seg.Text, u.procframe_ptr + 6, NOP, 1); END; - - u.cg.set_label(u.exit_proclabel); - u.cg.popOp(u.cg.reg[EDI]); - u.cg.popOp(u.cg.reg[ESI]); - u.cg.popOp(u.cg.reg[EBX]); + IF u.proc_reguse[ESI] THEN + u.cg.popOp(u.cg.reg[ESI]); + ELSE + u.obj.patch(Seg.Text, u.procframe_ptr + 5, NOP, 1); + END; + + IF u.proc_reguse[EBX] THEN + u.cg.popOp(u.cg.reg[EBX]); + ELSE + u.obj.patch(Seg.Text, u.procframe_ptr + 4, NOP, 1); + END; u.cg.noargOp(Op.oLEAVE); - IF callee_cleans THEN + IF u.current_proc.stdcall THEN u.cg.cleanretOp(u.current_proc.paramsize - 8); ELSE u.cg.noargOp(Op.oRET); @@ -3046,6 +3067,8 @@ IF n > MAXINLINECOPY THEN u.vstack.find(stack0, Force.regset, RegSet { ESI } ); u.vstack.find(stack1, Force.regset, RegSet { EDI } ); + u.proc_reguse[ESI] := TRUE; + u.proc_reguse[EDI] := TRUE; ELSE u.vstack.find(stack0, Force.anyreg, AllRegisters, TRUE); u.vstack.find(stack1, Force.anyreg, AllRegisters, TRUE); @@ -4320,6 +4343,8 @@ atomicVariable = x.vstack.pos(2, "fetch_and_op") DO x.vstack.find(newValue, Force.regset, RegSet{ECX, EBX}); + x.proc_reguse[EBX] := TRUE; + (* x.vstack.find(atomicVariable, Force.any); bug *) x.vstack.find(atomicVariable, Force.anyreg); x.cg.load_ind(EAX, x.vstack.op(atomicVariable), 0, type); @@ -4433,6 +4458,7 @@ *) x.vstack.find(compareValueAndOldValueIfFailed, Force.regset, RegSet{EAX, EDX}); x.vstack.find(newValue, Force.regset, RegSet{ECX, EBX}); + x.proc_reguse[EBX] := TRUE; ELSE x.vstack.find(compareValueAndOldValueIfFailed, Force.regset, RegSet{EAX}); x.vstack.find(newValue, Force.anyreg); @@ -4542,6 +4568,7 @@ IF is64 THEN x.vstack.pushnew(type, Force.regset, RegSet{EDX, EAX}); x.vstack.pushnew(type, Force.regset, RegSet{ECX, EBX}); + x.proc_reguse[EBX] := TRUE; ELSE x.vstack.pushnew(type, Force.regset, RegSet{EAX}); x.vstack.pushnew(type, Force.anyreg); Index: M3x86Rep.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/M3x86Rep.i3,v retrieving revision 1.46 diff -u -r1.46 M3x86Rep.i3 --- M3x86Rep.i3 15 Mar 2010 13:23:11 -0000 1.46 +++ M3x86Rep.i3 15 Mar 2010 15:05:08 -0000 @@ -17,6 +17,7 @@ TYPE U <: Public; TYPE Public = M3CG.T OBJECT + proc_reguse := ARRAY Regno OF BOOLEAN{FALSE,..}; METHODS NewVar (t: Type; m3t: TypeUID; s: ByteSize; a: Alignment; name: Name := M3ID.NoID): x86Var; Index: Stackx86.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-sys/m3back/src/Stackx86.m3,v retrieving revision 1.146 diff -u -r1.146 Stackx86.m3 --- Stackx86.m3 15 Mar 2010 13:23:11 -0000 1.146 +++ Stackx86.m3 15 Mar 2010 15:05:08 -0000 @@ -405,6 +405,7 @@ ELSIF compare_exchange_64 THEN to[0] := EBX; to[1] := ECX; + t.parent.proc_reguse[EBX] := TRUE; ELSIF i = 1 AND done[0] = FALSE THEN to[i] := pickreg(t, set - RegSet{to[0]}, hintaddr); ELSE @@ -531,6 +532,8 @@ END; t.reguse[to[0]].locked := TRUE; t.reguse[to[size - 1]].locked := TRUE; + t.parent.proc_reguse[to[0]] := TRUE; + t.parent.proc_reguse[to[size - 1]] := TRUE; END find; PROCEDURE freereg (t: T; set := AllRegisters; operandPart: OperandPart): Regno = @@ -756,6 +759,7 @@ t.vstack[stackp].reg[operandPart] := r; t.reguse[r].stackp := stackp; t.reguse[r].operandPart := operandPart; + t.parent.proc_reguse[r] := TRUE; END set_reg; PROCEDURE dealloc_reg (t: T; stackp: CARDINAL; operandPart: OperandPart) = @@ -770,6 +774,7 @@ IF t.reguse[reg].stackp # -1 THEN forceout(t, reg, operandPart); END; + t.parent.proc_reguse[reg] := TRUE; t.reguse[reg] := InitRegister(locked := t.reguse[reg].locked); END corrupt;