* Further work to convert codegenerator register convention;

internalerror bug fixed.
This commit is contained in:
daniel 2003-01-13 14:54:34 +00:00
parent c134e2d478
commit cbe0383afe
7 changed files with 160 additions and 67 deletions

View File

@ -777,6 +777,10 @@ unit cgobj;
procedure tcg.a_load_loc_reg(list : taasmoutput;const loc: tlocation; reg : tregister);
begin
{$ifdef i386}
{For safety convert location register to enum for now...}
convert_register_to_enum(reg);
{$endif}
case loc.loc of
LOC_REFERENCE,LOC_CREFERENCE:
a_load_ref_reg(list,loc.size,loc.reference,reg);
@ -1694,7 +1698,11 @@ finalization
end.
{
$Log$
Revision 1.72 2003-01-09 22:00:53 florian
Revision 1.73 2003-01-13 14:54:34 daniel
* Further work to convert codegenerator register convention;
internalerror bug fixed.
Revision 1.72 2003/01/09 22:00:53 florian
* fixed some PowerPC issues
Revision 1.71 2003/01/09 20:41:10 florian

View File

@ -152,6 +152,8 @@ implementation
procedure emit_reg_reg(i : tasmop;s : topsize;reg1,reg2 : tregister);
begin
convert_register_to_enum(reg1);
convert_register_to_enum(reg2);
if (reg1.enum<>reg2.enum) or (i<>A_MOV) then
exprasmList.concat(Taicpu.Op_reg_reg(i,s,reg1,reg2));
end;
@ -174,7 +176,11 @@ implementation
end.
{
$Log$
Revision 1.34 2003-01-08 18:43:57 daniel
Revision 1.35 2003-01-13 14:54:34 daniel
* Further work to convert codegenerator register convention;
internalerror bug fixed.
Revision 1.34 2003/01/08 18:43:57 daniel
* Tregister changed into a record
Revision 1.33 2002/07/01 18:46:29 peter

View File

@ -121,7 +121,8 @@ implementation
else
begin
rg.getexplicitregisterint(exprasmlist,R_EDI);
hreg2.enum := R_EDI;
hreg2.enum := R_INTREGISTER;
hreg2.number := NR_EDI;
emit_reg_reg(A_MOV,S_L,hreg1,hreg2);
{ if the left value is signed, R_EDI := $ffffffff,
otherwise 0 }
@ -133,6 +134,8 @@ implementation
emit_reg_reg(A_ADD,S_L,hreg2,hreg1);
{ release EDX if we used it }
{ also releas EDI }
if (hreg2.enum=R_INTREGISTER) and (hreg2.number=NR_EDI) then
hreg2.enum:=R_EDI;
rg.ungetregisterint(exprasmlist,hreg2);
{ do the shift }
emit_const_reg(A_SAR,S_L,power,hreg1);
@ -163,12 +166,14 @@ implementation
rg.getexplicitregisterint(exprasmlist,R_EDI);
if right.location.loc<>LOC_CREGISTER then
location_release(exprasmlist,right.location);
r.enum:=R_EDI;
r.enum:=R_INTREGISTER;
r.number:=NR_EDI;
cg.a_load_loc_reg(exprasmlist,right.location,r);
popedx:=false;
popeax:=false;
r.enum:=R_EAX;
r2.enum:=R_EDX;
r.number:=NR_EAX;
r2.enum:=R_INTREGISTER;
r2.number:=NR_EDX;
if hreg1.enum=R_EDX then
begin
if not(R_EAX in rg.unusedregsint) then
@ -208,18 +213,23 @@ implementation
emit_none(A_CDQ,S_NO);
{ division depends on the right type }
r.enum:=R_EDI;
r.enum:=R_INTREGISTER;
r.number:=NR_EDI;
if torddef(right.resulttype.def).typ=u32bit then
emit_reg(A_DIV,S_L,r)
else
emit_reg(A_IDIV,S_L,r);
r.enum:=R_EDI;
rg.ungetregisterint(exprasmlist,r);
r.enum:=R_EAX;
r.enum:=R_INTREGISTER;
r.number:=NR_EAX;
if nodetype=divn then
begin
if not popedx and (hreg1.enum <> R_EDX) then
rg.ungetregister(exprasmlist,r2);
begin
r2.enum:=R_EDX;
rg.ungetregister(exprasmlist,r2);
end;
{ if result register is busy then copy }
if popeax then
begin
@ -239,7 +249,10 @@ implementation
else
begin
if not popeax and (hreg1.enum <> R_EAX)then
rg.ungetregister(exprasmlist,r);
begin
r.enum:=R_EAX;
rg.ungetregister(exprasmlist,r);
end;
if popedx then
{the mod was done by an (i)div (so the result is now in
edx), but edx was occupied prior to the division, so
@ -862,7 +875,11 @@ begin
end.
{
$Log$
Revision 1.42 2003-01-08 18:43:57 daniel
Revision 1.43 2003-01-13 14:54:34 daniel
* Further work to convert codegenerator register convention;
internalerror bug fixed.
Revision 1.42 2003/01/08 18:43:57 daniel
* Tregister changed into a record
Revision 1.41 2002/11/25 17:43:26 peter

View File

@ -113,9 +113,10 @@ procedure ti386classheader.cgintfwrapper(asmlist: TAAsmoutput; procdef: tprocdef
r:Tregister;
begin
{ mov offset(%esp),%eax }
r.enum:=R_ESP;
r.enum:=R_INTREGISTER;
r.number:=NR_ESP;
reference_reset_base(href,r,getselfoffsetfromsp(procdef));
r.enum:=R_EAX;
r.number:=NR_EAX;
cg.a_load_ref_reg(exprasmlist,OS_ADDR,href,r);
end;
@ -126,7 +127,8 @@ procedure ti386classheader.cgintfwrapper(asmlist: TAAsmoutput; procdef: tprocdef
begin
checkvirtual;
{ mov 0(%eax),%eax ; load vmt}
r.enum:=R_EAX;
r.enum:=R_INTREGISTER;
r.number:=NR_EAX;
reference_reset_base(href,r,0);
emit_ref_reg(A_MOV,S_L,href,r);
end;
@ -137,7 +139,8 @@ procedure ti386classheader.cgintfwrapper(asmlist: TAAsmoutput; procdef: tprocdef
r:Tregister;
begin
{ call/jmp vmtoffs(%eax) ; method offs }
r.enum:=R_EAX;
r.enum:=R_INTREGISTER;
r.number:=NR_EAX;
reference_reset_base(href,r,procdef._class.vmtmethodoffset(procdef.extnumber));
emit_ref(op,S_L,href);
end;
@ -148,7 +151,8 @@ procedure ti386classheader.cgintfwrapper(asmlist: TAAsmoutput; procdef: tprocdef
r:Tregister;
begin
{ mov vmtoffs(%eax),%eax ; method offs }
r.enum:=R_EAX;
r.enum:=R_INTREGISTER;
r.number:=NR_EAX;
reference_reset_base(href,r,procdef._class.vmtmethodoffset(procdef.extnumber));
emit_ref_reg(A_MOV,S_L,href,r);
end;
@ -203,17 +207,18 @@ begin
{ case 3 }
else if [po_virtualmethod,po_saveregisters]*procdef.procoptions=[po_virtualmethod,po_saveregisters] then
begin
r.enum:=R_EBX;
r.enum:=R_INTREGISTER;
r.number:=NR_EBX;
emit_reg(A_PUSH,S_L,r); { allocate space for address}
r.enum:=R_EAX;
r.number:=NR_EAX;
emit_reg(A_PUSH,S_L,r);
getselftoeax(8);
loadvmttoeax;
loadmethodoffstoeax;
{ mov %eax,4(%esp) }
r.enum:=R_ESP;
r.number:=NR_ESP;
reference_reset_base(href,r,4);
r.enum:=R_EAX;
r.number:=NR_EAX;
emit_reg_ref(A_MOV,S_L,r,href);
{ pop %eax }
emit_reg(A_POP,S_L,r);
@ -242,7 +247,11 @@ initialization
end.
{
$Log$
Revision 1.16 2003-01-08 18:43:57 daniel
Revision 1.17 2003-01-13 14:54:34 daniel
* Further work to convert codegenerator register convention;
internalerror bug fixed.
Revision 1.16 2003/01/08 18:43:57 daniel
* Tregister changed into a record
Revision 1.15 2002/08/11 14:32:30 peter

View File

@ -279,7 +279,8 @@ implementation
if (pleftreg.enum <> R_EDI) and
(left.location.loc = LOC_CREGISTER) then
begin
r.enum:=R_EDI;
r.enum:=R_INTREGISTER;
r.number:=NR_EDI;
rg.ungetregister(exprasmlist,pleftreg);
rg.getexplicitregisterint(exprasmlist,R_EDI);
reference_reset_base(href,pleftreg,-setparts[i].start);
@ -397,7 +398,8 @@ implementation
{ the set element isn't never samller than a byte }
{ and because it's a small set we need only 5 bits }
{ but 8 bits are easier to load }
r.enum:=R_EDI;
r.enum:=R_INTREGISTER;
r.number:=NR_EDI;
rg.getexplicitregisterint(exprasmlist,R_EDI);
emit_ref_reg(A_MOVZX,S_BL,left.location.reference,r);
hr:=r;
@ -433,6 +435,8 @@ implementation
internalerror(2002032210);
end;
{ simply to indicate EDI is deallocated here too (JM) }
if (hr.enum=R_INTREGISTER) and (hr.number=NR_EDI) then
hr.enum:=R_EDI;
rg.ungetregisterint(exprasmlist,hr);
location.loc:=LOC_FLAGS;
location.resflags:=F_C;
@ -710,7 +714,11 @@ begin
end.
{
$Log$
Revision 1.46 2003-01-08 18:43:57 daniel
Revision 1.47 2003-01-13 14:54:34 daniel
* Further work to convert codegenerator register convention;
internalerror bug fixed.
Revision 1.46 2003/01/08 18:43:57 daniel
* Tregister changed into a record
Revision 1.45 2002/11/25 17:43:27 peter

View File

@ -1011,6 +1011,7 @@ implementation
end;
dataSegment.concatlist(rawdata);
rawdata.free;
rawcode.convert_registers;
codeSegment.concatlist(rawcode);
rawcode.free;
freemem(impintfindexes,(max+1)*sizeof(longint));
@ -1332,7 +1333,11 @@ initialization
end.
{
$Log$
Revision 1.39 2003-01-09 21:52:37 peter
Revision 1.40 2003-01-13 14:54:34 daniel
* Further work to convert codegenerator register convention;
internalerror bug fixed.
Revision 1.39 2003/01/09 21:52:37 peter
* merged some verbosity options.
* V_LineInfo is a verbosity flag to include line info

View File

@ -480,10 +480,22 @@ unit cgx86;
var
op: tasmop;
s: topsize;
eq:boolean;
begin
sizes2load(fromsize,reg2opsize[reg2.enum],op,s);
if (rg.makeregsize(reg1,OS_INT).enum = rg.makeregsize(reg2,OS_INT).enum) then
if (reg1.enum=R_INTREGISTER) and (reg2.enum=R_INTREGISTER) then
begin
sizes2load(fromsize,subreg2opsize[reg2.number and $ff],op,s);
eq:=(reg1.number shr 8)=(reg2.number shr 8);
end
else if (reg1.enum<lastreg) and (reg2.enum<lastreg) then
begin
sizes2load(fromsize,reg2opsize[reg2.enum],op,s);
eq:=(rg.makeregsize(reg1,OS_INT).enum = rg.makeregsize(reg2,OS_INT).enum);
end
else
internalerror(200301081);
if eq then
begin
{ "mov reg1, reg1" doesn't make sense }
if op = A_MOV then
@ -787,6 +799,7 @@ unit cgx86;
internalerror(200301081);
if dst.enum>lastreg then
internalerror(200301081);
r.enum:=R_INTREGISTER;
dstsize := tcgsize2opsize[size];
dst := rg.makeregsize(dst,size);
case op of
@ -820,23 +833,22 @@ unit cgx86;
begin
{ is ecx still free (it's also free if it was allocated }
{ to dst, since we've moved dst somewhere else already) }
r.number:=NR_ECX;
if not((dst.enum = R_ECX) or
((R_ECX in rg.unusedregsint) and
{ this will always be true, it's just here to }
{ allocate ecx }
(rg.getexplicitregisterint(list,R_ECX).enum = R_ECX))) then
begin
r.enum:=R_ECX;
list.concat(taicpu.op_reg(A_PUSH,S_L,r));
popecx := true;
end;
r.enum:=R_ECX;
a_load_reg_reg(list,OS_32,OS_32,rg.makeregsize(src,OS_32),r);
end
else
src.enum := R_CL;
{ do the shift }
r.enum:=R_CL;
r.number:=NR_CL;
if tmpreg.enum = R_NO then
list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
r,dst))
@ -845,11 +857,11 @@ unit cgx86;
list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],S_L,
r,tmpreg));
{ move result back to the destination }
r.enum:=R_ECX;
r.number:=NR_ECX;
a_load_reg_reg(list,OS_32,OS_32,tmpreg,r);
free_scratch_reg(list,tmpreg);
end;
r.enum:=R_ECX;
r.number:=NR_ECX;
if popecx then
list.concat(taicpu.op_reg(A_POP,S_L,r))
else if not (dst.enum in [R_ECX,R_CX,R_CL]) then
@ -1133,7 +1145,8 @@ unit cgx86;
var r:Tregister;
begin
r.enum:=R_ECX;
r.enum:=R_INTREGISTER;
r.number:=NR_ECX;
if not(R_ECX in rg.unusedregsint) then
begin
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
@ -1147,13 +1160,14 @@ unit cgx86;
((len<=8) or
(not(cs_littlesize in aktglobalswitches ) and (len<=12))) then
begin
r.enum:=R_INTREGISTER;
helpsize:=len shr 2;
rg.getexplicitregisterint(list,R_EDI);
dstref:=dest;
srcref:=source;
for i:=1 to helpsize do
begin
r.enum:=R_EDI;
r.number:=NR_EDI;
a_load_ref_reg(list,OS_32,srcref,r);
If (len = 4) and delsource then
reference_release(list,source);
@ -1164,7 +1178,7 @@ unit cgx86;
end;
if len>1 then
begin
r.enum:=R_DI;
r.number:=NR_DI;
a_load_ref_reg(list,OS_16,srcref,r);
If (len = 2) and delsource then
reference_release(list,source);
@ -1175,6 +1189,9 @@ unit cgx86;
end;
r.enum:=R_EDI;
rg.ungetregisterint(list,r);
r.enum:=R_INTREGISTER;
reg8.enum:=R_INTREGISTER;
reg32.enum:=R_INTREGISTER;
if len>0 then
begin
{ and now look for an 8 bit register }
@ -1190,25 +1207,25 @@ unit cgx86;
{ one is always not index or base }
if (dest.base.enum<>R_EAX) and (dest.index.enum<>R_EAX) then
begin
reg8.enum:=R_AL;
reg32.enum:=R_EAX;
reg8.number:=NR_AL;
reg32.number:=NR_EAX;
end
else if (dest.base.enum<>R_EBX) and (dest.index.enum<>R_EBX) then
begin
reg8.enum:=R_BL;
reg32.enum:=R_EBX;
reg8.number:=NR_BL;
reg32.number:=NR_EBX;
end
else if (dest.base.enum<>R_ECX) and (dest.index.enum<>R_ECX) then
begin
reg8.enum:=R_CL;
reg32.enum:=R_ECX;
reg8.number:=NR_CL;
reg32.number:=NR_ECX;
end;
end;
if swap then
{ was earlier XCHG, of course nonsense }
begin
rg.getexplicitregisterint(list,R_EDI);
r.enum:=R_EDI;
r.number:=NR_EDI;
a_load_reg_reg(list,OS_32,OS_32,reg32,r);
end;
a_load_ref_reg(list,OS_8,srcref,reg8);
@ -1217,21 +1234,31 @@ unit cgx86;
a_load_reg_ref(list,OS_8,reg8,dstref);
if swap then
begin
r.enum:=R_EDI;
r.number:=NR_EDI;
a_load_reg_reg(list,OS_32,OS_32,r,reg32);
r.enum:=R_EDI;
rg.ungetregisterint(list,r);
end
else
rg.ungetregister(list,reg8);
begin
if reg8.number=NR_AL then
reg8.enum:=R_AL
else if reg8.number=NR_BL then
reg8.enum:=R_BL
else if reg8.number=NR_CL then
reg8.enum:=R_CL;
rg.ungetregister(list,reg8);
end;
end;
end
else
begin
r.enum:=R_EDI;
r.enum:=R_INTREGISTER;
r.number:=NR_EDI;
rg.getexplicitregisterint(list,R_EDI);
a_loadaddr_ref_reg(list,dest,r);
r.enum:=R_ESI;
list.concat(tai_regalloc.Alloc(r));
r.number:=NR_ESI;
list.concat(tai_regalloc.alloc(r));
if loadref then
a_load_ref_reg(list,OS_ADDR,source,r)
else
@ -1243,7 +1270,7 @@ unit cgx86;
list.concat(Taicpu.Op_none(A_CLD,S_NO));
ecxpushed:=false;
r.enum:=R_ECX;
r.number:=NR_ECX;
if cs_littlesize in aktglobalswitches then
begin
maybepushecx;
@ -1273,13 +1300,19 @@ unit cgx86;
end;
r.enum:=R_EDI;
rg.ungetregisterint(list,r);
r.enum:=R_ESI;
list.concat(tai_regalloc.DeAlloc(r));
r.enum:=R_ECX;
r.enum:=R_INTREGISTER;
r.number:=NR_ESI;
list.concat(tai_regalloc.dealloc(r));
if ecxpushed then
list.concat(Taicpu.Op_reg(A_POP,S_L,r))
begin
r.number:=NR_ECX;
list.concat(Taicpu.Op_reg(A_POP,S_L,r))
end
else
rg.ungetregisterint(list,r);
begin
r.enum:=R_ECX;
rg.ungetregisterint(list,r);
end;
{ loading SELF-reference again }
g_maybe_loadself(list);
@ -1295,7 +1328,8 @@ unit cgx86;
var r:Tregister;
begin
r.enum:=R_EAX;
r.enum:=R_INTREGISTER;
r.number:=NR_EAX;
list.concat(Taicpu.op_reg(A_PUSH,S_L,r));
end;
@ -1310,7 +1344,8 @@ unit cgx86;
var r:Tregister;
begin
r.enum:=R_EAX;
r.enum:=R_INTREGISTER;
r.number:=NR_EAX;
list.concat(Taicpu.op_reg(A_POP,S_L,r));
end;
@ -1469,27 +1504,27 @@ unit cgx86;
begin
r.enum:=R_INTREGISTER;
r.enum:=R_GS;
r.number:=NR_GS;
{ .... also the segment registers }
list.concat(Taicpu.Op_reg(A_PUSH,S_W,r));
r.enum:=R_FS;
r.number:=NR_FS;
list.concat(Taicpu.Op_reg(A_PUSH,S_W,r));
r.enum:=R_ES;
r.number:=NR_ES;
list.concat(Taicpu.Op_reg(A_PUSH,S_W,r));
r.enum:=R_DS;
r.number:=NR_DS;
list.concat(Taicpu.Op_reg(A_PUSH,S_W,r));
{ save the registers of an interrupt procedure }
r.enum:=R_EDI;
r.number:=NR_EDI;
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
r.enum:=R_ESI;
r.number:=NR_ESI;
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
r.enum:=R_EDX;
r.number:=NR_EDX;
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
r.enum:=R_ECX;
r.number:=NR_ECX;
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
r.enum:=R_EBX;
r.number:=NR_EBX;
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
r.enum:=R_EAX;
r.number:=NR_EAX;
list.concat(Taicpu.Op_reg(A_PUSH,S_L,r));
end;
@ -1687,7 +1722,8 @@ unit cgx86;
var r:Tregister;
begin
r.enum:=R_EDI;
r.enum:=R_INTREGISTER;
r.number:=NR_EDI;
if is_class(procinfo._class) then
begin
if (cs_implicit_exceptions in aktmoduleswitches) then
@ -1874,7 +1910,11 @@ unit cgx86;
end.
{
$Log$
Revision 1.28 2003-01-09 20:41:00 daniel
Revision 1.29 2003-01-13 14:54:34 daniel
* Further work to convert codegenerator register convention;
internalerror bug fixed.
Revision 1.28 2003/01/09 20:41:00 daniel
* Converted some code in cgx86.pas to new register numbering
Revision 1.27 2003/01/08 18:43:58 daniel