* Created newra version of secondmul in n386add.pas

This commit is contained in:
daniel 2003-03-08 10:53:48 +00:00
parent 0d490a4344
commit 2801609d3f
2 changed files with 159 additions and 95 deletions

View File

@ -45,6 +45,7 @@ interface
procedure second_addboolean;
procedure second_addfloat;
procedure second_addsmallset;
procedure second_mul;
{$ifdef SUPPORT_MMX}
procedure second_addmmx;
{$endif SUPPORT_MMX}
@ -1311,6 +1312,131 @@ interface
end;
{$endif SUPPORT_MMX}
{*****************************************************************************
MUL
*****************************************************************************}
{$ifdef newra}
procedure ti386addnode.second_mul;
var r,r_eax:Tregister;
begin
{The location.register will be filled in later (JM)}
location_reset(location,LOC_REGISTER,OS_INT);
{Get a temp register and load the left value into it
and free the location.}
r:=rg.getregisterint(exprasmlist,OS_INT);
cg.a_load_loc_reg(exprasmlist,left.location,r);
location_release(exprasmlist,left.location);
{Allocate EAX.}
rg.getexplicitregisterint(exprasmlist,NR_EAX);
r_eax.enum:=R_INTREGISTER;
r_eax.number:=NR_EAX;
{Load the right value.}
cg.a_load_loc_reg(exprasmlist,right.location,r_eax);
location_release(exprasmlist,right.location);
{Also allocate EDX, since it is also modified by a mul (JM).}
rg.getexplicitregisterint(exprasmlist,NR_EDX);
emit_reg(A_MUL,S_L,r);
rg.ungetregisterint(exprasmlist,r);
{Free EDX}
r.enum:=R_INTREGISTER;
r.number:=NR_EDX;
rg.ungetregisterint(exprasmlist,r);
{Free EAX}
rg.ungetregisterint(exprasmlist,r_eax);
location.register:=rg.getregisterint(exprasmlist,OS_INT);
emit_reg_reg(A_MOV,S_L,r_eax,location.register);
location_freetemp(exprasmlist,left.location);
location_freetemp(exprasmlist,right.location);
end;
{$else}
procedure ti386addnode.second_mul;
var popeax,popedx:boolean;
regstopush:Tsupregset;
r:Tregister;
begin
popeax:=false;
popedx:=false;
{ here you need to free the symbol first }
{ left.location and right.location must }
{ only be freed when they are really released, }
{ because the optimizer NEEDS correct regalloc }
{ info!!! (JM) }
{ the location.register will be filled in later (JM) }
location_reset(location,LOC_REGISTER,OS_INT);
regstopush := all_intregisters;
remove_non_regvars_from_loc(right.location,regstopush);
remove_non_regvars_from_loc(left.location,regstopush);
{ now, regstopush does NOT contain EAX and/or EDX if they are }
{ used in either the left or the right location, excepts if }
{they are regvars. It DOES contain them if they are used in }
{ another location (JM) }
r.enum:=R_INTREGISTER;
if not(RS_EAX in rg.unusedregsint) and
(RS_EAX in regstopush) then
begin
r.number:=NR_EAX;
emit_reg(A_PUSH,S_L,r);
popeax:=true;
end;
if not(RS_EDX in rg.unusedregsint) and
(RS_EDX in regstopush) then
begin
r.number:=NR_EDX;
emit_reg(A_PUSH,S_L,r);
popedx:=true;
end;
{ left.location can be R_EAX !!! }
rg.getexplicitregisterint(exprasmlist,NR_EDI);
{ load the left value }
r.number:=NR_EDI;
cg.a_load_loc_reg(exprasmlist,left.location,r);
location_release(exprasmlist,left.location);
{ allocate EAX }
r.number:=NR_EAX;
if RS_EAX in rg.unusedregsint then
exprasmList.concat(tai_regalloc.Alloc(r));
{ load he right value }
cg.a_load_loc_reg(exprasmlist,right.location,r);
location_release(exprasmlist,right.location);
{ allocate EAX if it isn't yet allocated (JM) }
if (RS_EAX in rg.unusedregsint) then
exprasmlist.concat(tai_regalloc.Alloc(r));
{ also allocate EDX, since it is also modified by }
{ a mul (JM) }
r.number:=NR_EDX;
if RS_EDX in rg.unusedregsint then
exprasmlist.concat(tai_regalloc.Alloc(r));
r.number:=NR_EDI;
emit_reg(A_MUL,S_L,r);
rg.ungetregisterint(exprasmlist,r);
r.enum:=R_INTREGISTER;
r.number:=NR_EDX;
if RS_EDX in rg.unusedregsint then
exprasmlist.concat(tai_regalloc.DeAlloc(r));
r.number:=NR_EAX;
if RS_EAX in rg.unusedregsint then
exprasmlist.concat(tai_regalloc.DeAlloc(r));
location.register:=rg.getregisterint(exprasmlist,OS_INT);
r.number:=NR_EAX;
emit_reg_reg(A_MOV,S_L,r,location.register);
r.number:=NR_EDX;
if popedx then
emit_reg(A_POP,S_L,r);
r.number:=NR_EAX;
if popeax then
emit_reg(A_POP,S_L,r);
location_freetemp(exprasmlist,left.location);
location_freetemp(exprasmlist,right.location);
end;
{$endif}
{*****************************************************************************
pass_2
@ -1320,7 +1446,6 @@ interface
{ is also being used for xor, and "mul", "sub, or and comparative }
{ operators }
var
popeax,popedx,
pushedfpu,
mboverflow,cmpop : boolean;
op : tasmop;
@ -1335,9 +1460,6 @@ interface
{ true, if for sets subtractions the extra not should generated }
extra_not : boolean;
regstopush:Tsupregset;
r:Tregister;
begin
{ to make it more readable, string and set (not smallset!) have their
own procedures }
@ -1455,80 +1577,7 @@ interface
{ filter MUL, which requires special handling }
if op=A_MUL then
begin
popeax:=false;
popedx:=false;
{ here you need to free the symbol first }
{ left.location and right.location must }
{ only be freed when they are really released, }
{ because the optimizer NEEDS correct regalloc }
{ info!!! (JM) }
{ the location.register will be filled in later (JM) }
location_reset(location,LOC_REGISTER,OS_INT);
regstopush := all_intregisters;
remove_non_regvars_from_loc(right.location,regstopush);
remove_non_regvars_from_loc(left.location,regstopush);
{ now, regstopush does NOT contain EAX and/or EDX if they are }
{ used in either the left or the right location, excepts if }
{they are regvars. It DOES contain them if they are used in }
{ another location (JM) }
r.enum:=R_INTREGISTER;
if not(RS_EAX in rg.unusedregsint) and
(RS_EAX in regstopush) then
begin
r.number:=NR_EAX;
emit_reg(A_PUSH,S_L,r);
popeax:=true;
end;
if not(RS_EDX in rg.unusedregsint) and
(RS_EDX in regstopush) then
begin
r.number:=NR_EDX;
emit_reg(A_PUSH,S_L,r);
popedx:=true;
end;
{ left.location can be R_EAX !!! }
rg.getexplicitregisterint(exprasmlist,NR_EDI);
{ load the left value }
r.number:=NR_EDI;
cg.a_load_loc_reg(exprasmlist,left.location,r);
location_release(exprasmlist,left.location);
{ allocate EAX }
r.number:=NR_EAX;
if RS_EAX in rg.unusedregsint then
exprasmList.concat(tai_regalloc.Alloc(r));
{ load he right value }
cg.a_load_loc_reg(exprasmlist,right.location,r);
location_release(exprasmlist,right.location);
{ allocate EAX if it isn't yet allocated (JM) }
if (RS_EAX in rg.unusedregsint) then
exprasmlist.concat(tai_regalloc.Alloc(r));
{ also allocate EDX, since it is also modified by }
{ a mul (JM) }
r.number:=NR_EDX;
if RS_EDX in rg.unusedregsint then
exprasmlist.concat(tai_regalloc.Alloc(r));
r.number:=NR_EDI;
emit_reg(A_MUL,S_L,r);
rg.ungetregisterint(exprasmlist,r);
r.enum:=R_INTREGISTER;
r.number:=NR_EDX;
if RS_EDX in rg.unusedregsint then
exprasmlist.concat(tai_regalloc.DeAlloc(r));
r.number:=NR_EAX;
if RS_EAX in rg.unusedregsint then
exprasmlist.concat(tai_regalloc.DeAlloc(r));
location.register:=rg.getregisterint(exprasmlist,OS_INT);
r.number:=NR_EAX;
emit_reg_reg(A_MOV,S_L,r,location.register);
r.number:=NR_EDX;
if popedx then
emit_reg(A_POP,S_L,r);
r.number:=NR_EAX;
if popeax then
emit_reg(A_POP,S_L,r);
location_freetemp(exprasmlist,left.location);
location_freetemp(exprasmlist,right.location);
second_mul;
exit;
end;
@ -1586,7 +1635,10 @@ begin
end.
{
$Log$
Revision 1.55 2003-02-19 22:00:15 daniel
Revision 1.56 2003-03-08 10:53:48 daniel
* Created newra version of secondmul in n386add.pas
Revision 1.55 2003/02/19 22:00:15 daniel
* Code generator converted to new register notation
- Horribily outdated todo.txt removed

View File

@ -73,6 +73,7 @@ unit rgobj;
{ aren't currently allocated to a regvar. The "unusedregsxxx" }
{ contain all registers of type "xxx" that aren't currenly }
{ allocated }
lastintreg:Tsuperregister;
unusedregsint,usableregsint:Tsupregset;
unusedregsfpu,usableregsfpu : tregisterset;
unusedregsmm,usableregsmm : tregisterset;
@ -347,6 +348,7 @@ unit rgobj;
usedbyproc:=[];
t_times := 0;
resetusableregisters;
lastintreg:=0;
{$ifdef TEMPREGDEBUG}
fillchar(reg_user,sizeof(reg_user),0);
fillchar(reg_releaser,sizeof(reg_releaser),0);
@ -387,21 +389,28 @@ unit rgobj;
r:Tregister;
begin
for i:=lowreg to highreg do
begin
if i in unusedregs then
begin
exclude(unusedregs,i);
include(fusedinproc,i);
include(fusedbyproc,i);
dec(countunusedregs);
r.enum:=R_INTREGISTER;
r.number:=i shl 8 or subreg;
list.concat(tai_regalloc.alloc(r));
result:=r;
exit;
end;
end;
if not (lastintreg in [lowreg..highreg]) then
lastintreg:=lowreg;
i:=lastintreg;
repeat
if i=highreg then
i:=lowreg
else
inc(i);
if i in unusedregs then
begin
exclude(unusedregs,i);
include(fusedinproc,i);
include(fusedbyproc,i);
dec(countunusedregs);
r.enum:=R_INTREGISTER;
r.number:=i shl 8 or subreg;
list.concat(Tai_regalloc.alloc(r));
result:=r;
lastintreg:=i;
exit;
end;
until i=lastintreg;
internalerror(10);
end;
@ -1217,7 +1226,10 @@ end.
{
$Log$
Revision 1.26 2003-03-08 08:59:07 daniel
Revision 1.27 2003-03-08 10:53:48 daniel
* Created newra version of secondmul in n386add.pas
Revision 1.26 2003/03/08 08:59:07 daniel
+ $define newra will enable new register allocator
+ getregisterint will return imaginary registers with $newra
+ -sr switch added, will skip register allocation so you can see