* Work to handle new register notation in ag386nsm

+ Added newra version of Ti386moddivnode
This commit is contained in:
daniel 2003-03-08 13:59:16 +00:00
parent 2801609d3f
commit fb55235acc
5 changed files with 165 additions and 10 deletions

View File

@ -384,6 +384,7 @@ interface
found,
do_line,
quoted : boolean;
regstr:string[5];
begin
if not assigned(p) then
exit;
@ -454,8 +455,12 @@ interface
ait_regalloc :
begin
if tai_regalloc(hp).reg.enum=R_INTREGISTER then
regstr:=intel_regname(tai_regalloc(hp).reg.number)
else
regstr:=std_reg2str[tai_regalloc(hp).reg.enum];
if (cs_asm_regalloc in aktglobalswitches) then
AsmWriteLn(target_asm.comment+'Register '+std_reg2str[tai_regalloc(hp).reg.enum]+
AsmWriteLn(target_asm.comment+'Register '+regstr+
allocstr[tai_regalloc(hp).allocation]);
end;
@ -916,7 +921,11 @@ initialization
end.
{
$Log$
Revision 1.31 2003-03-08 08:59:07 daniel
Revision 1.32 2003-03-08 13:59:17 daniel
* Work to handle new register notation in ag386nsm
+ Added newra version of Ti386moddivnode
Revision 1.31 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

View File

@ -1344,10 +1344,11 @@ interface
r.enum:=R_INTREGISTER;
r.number:=NR_EDX;
rg.ungetregisterint(exprasmlist,r);
{Free EAX}
rg.ungetregisterint(exprasmlist,r_eax);
{Allocate a new register and store the result in EAX in it.}
location.register:=rg.getregisterint(exprasmlist,OS_INT);
emit_reg_reg(A_MOV,S_L,r_eax,location.register);
{Free EAX}
rg.ungetregisterint(exprasmlist,r_eax);
location_freetemp(exprasmlist,left.location);
location_freetemp(exprasmlist,right.location);
end;
@ -1635,7 +1636,11 @@ begin
end.
{
$Log$
Revision 1.56 2003-03-08 10:53:48 daniel
Revision 1.57 2003-03-08 13:59:17 daniel
* Work to handle new register notation in ag386nsm
+ Added newra version of Ti386moddivnode
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

View File

@ -64,6 +64,130 @@ implementation
TI386MODDIVNODE
*****************************************************************************}
{$ifdef newra}
procedure ti386moddivnode.pass_2;
var r,r2,hreg1,hreg2:Tregister;
power:longint;
hl:Tasmlabel;
pushedregs:Tmaybesave;
begin
secondpass(left);
if codegenerror then
exit;
maybe_save(exprasmlist,right.registers32,left.location,pushedregs);
secondpass(right);
maybe_restore(exprasmlist,left.location,pushedregs);
if codegenerror then
exit;
location_copy(location,left.location);
if is_64bitint(resulttype.def) then
begin
{ should be handled in pass_1 (JM) }
internalerror(200109052);
end
else
begin
{ put numerator in register }
location_reset(location,LOC_REGISTER,OS_INT);
location_force_reg(exprasmlist,left.location,OS_INT,false);
hreg1:=left.location.register;
if (nodetype=divn) and (right.nodetype=ordconstn) and
ispowerof2(tordconstnode(right).value,power) then
begin
{ for signed numbers, the numerator must be adjusted before the
shift instruction, but not wih unsigned numbers! Otherwise,
"Cardinal($ffffffff) div 16" overflows! (JM) }
if is_signed(left.resulttype.def) Then
begin
if (aktOptProcessor <> class386) and
not(CS_LittleSize in aktglobalswitches) then
{ use a sequence without jumps, saw this in
comp.compilers (JM) }
begin
{ no jumps, but more operations }
hreg2:=rg.getregisterint(exprasmlist,OS_INT);
emit_reg_reg(A_MOV,S_L,hreg1,hreg2);
{ if the left value is signed, hreg2 := $ffffffff,
otherwise 0 }
emit_const_reg(A_SAR,S_L,31,hreg2);
{ if signed, hreg2 := right value-1, otherwise 0 }
emit_const_reg(A_AND,S_L,tordconstnode(right).value-1,hreg2);
{ add to the left value }
emit_reg_reg(A_ADD,S_L,hreg2,hreg1);
{ release EDX if we used it }
{ also releas EDI }
rg.ungetregisterint(exprasmlist,hreg2);
{ do the shift }
emit_const_reg(A_SAR,S_L,power,hreg1);
end
else
begin
{ a jump, but less operations }
emit_reg_reg(A_TEST,S_L,hreg1,hreg1);
objectlibrary.getlabel(hl);
emitjmp(C_NS,hl);
if power=1 then
emit_reg(A_INC,S_L,hreg1)
else
emit_const_reg(A_ADD,S_L,tordconstnode(right).value-1,hreg1);
cg.a_label(exprasmlist,hl);
emit_const_reg(A_SAR,S_L,power,hreg1);
end
end
else
emit_const_reg(A_SHR,S_L,power,hreg1);
location.register:=hreg1;
end
else
begin
{Bring denominator to a register.}
hreg2:=rg.getregisterint(exprasmlist,OS_INT);
if right.location.loc<>LOC_CREGISTER then
location_release(exprasmlist,right.location);
cg.a_load_loc_reg(exprasmlist,right.location,hreg2);
rg.getexplicitregisterint(exprasmlist,NR_EAX);
rg.getexplicitregisterint(exprasmlist,NR_EDX);
r.enum:=R_INTREGISTER;
r.number:=NR_EAX;
r2.enum:=R_INTREGISTER;
r2.number:=NR_EDX;
emit_reg_reg(A_MOV,S_L,hreg1,r);
rg.ungetregisterint(exprasmlist,hreg1);
{Sign extension depends on the left type.}
if torddef(left.resulttype.def).typ=u32bit then
emit_reg_reg(A_XOR,S_L,r2,r2)
else
emit_none(A_CDQ,S_NO);
{Division depends on the right type.}
if torddef(right.resulttype.def).typ=u32bit then
emit_reg(A_DIV,S_L,hreg2)
else
emit_reg(A_IDIV,S_L,hreg2);
rg.ungetregisterint(exprasmlist,hreg2);
if nodetype=divn then
begin
rg.ungetregisterint(exprasmlist,r2);
location.register:=rg.getregisterint(exprasmlist,OS_INT);
emit_reg_reg(A_MOV,S_L,r,location.register);
rg.ungetregisterint(exprasmlist,r);
end
else
begin
rg.ungetregisterint(exprasmlist,r);
location.register:=rg.getregisterint(exprasmlist,OS_INT);
emit_reg_reg(A_MOV,S_L,r2,location.register);
rg.ungetregisterint(exprasmlist,r2);
end;
end;
end;
end;
{$else}
procedure ti386moddivnode.pass_2;
var
hreg1 : tregister;
@ -281,6 +405,7 @@ implementation
location.register:=hreg1;
end;
end;
{$endif}
{*****************************************************************************
@ -883,7 +1008,11 @@ begin
end.
{
$Log$
Revision 1.45 2003-02-19 22:00:15 daniel
Revision 1.46 2003-03-08 13:59:17 daniel
* Work to handle new register notation in ag386nsm
+ Added newra version of Ti386moddivnode
Revision 1.45 2003/02/19 22:00:15 daniel
* Code generator converted to new register notation
- Horribily outdated todo.txt removed

View File

@ -288,8 +288,10 @@ unit rgcpu;
procedure trgcpu.ungetreference(list: taasmoutput; const ref : treference);
begin
ungetregisterint(list,ref.base);
ungetregisterint(list,ref.index);
if ref.base.number<>NR_NO then
ungetregisterint(list,ref.base);
if ref.index.number<>NR_NO then
ungetregisterint(list,ref.index);
end;
@ -515,7 +517,11 @@ end.
{
$Log$
Revision 1.14 2003-03-08 08:59:07 daniel
Revision 1.15 2003-03-08 13:59:17 daniel
* Work to handle new register notation in ag386nsm
+ Added newra version of Ti386moddivnode
Revision 1.14 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

View File

@ -453,8 +453,10 @@ unit rgobj;
internalerror(2003010803);
supreg:=r.number shr 8;
{ takes much time }
{$ifndef newra}
if not(supreg in usableregs) then
exit;
{$endif}
{$ifdef TEMPREGDEBUG}
if (supreg in unusedregs) then
{$ifdef EXTTEMPREGDEBUG}
@ -1226,7 +1228,11 @@ end.
{
$Log$
Revision 1.27 2003-03-08 10:53:48 daniel
Revision 1.28 2003-03-08 13:59:16 daniel
* Work to handle new register notation in ag386nsm
+ Added newra version of Ti386moddivnode
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