mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-22 09:45:22 +02:00
* Work to handle new register notation in ag386nsm
+ Added newra version of Ti386moddivnode
This commit is contained in:
parent
2801609d3f
commit
fb55235acc
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user