* support scalefactor for opr_local

* support reference with opr_local set, fixes tw2631
This commit is contained in:
peter 2003-10-30 19:59:00 +00:00
parent 9ff3d9ac58
commit 48ef24605a
6 changed files with 192 additions and 109 deletions

View File

@ -156,7 +156,8 @@ interface
top_symbol : (sym:tasmsymbol;symofs:longint);
top_bool : (b:boolean);
{ local varsym that will be inserted in pass_2 }
top_local : (localsym:pointer;localsymderef:tderef;localsymofs:longint;localindexreg:tregister;localgetoffset:boolean);
top_local : (localsym:pointer;localsymderef:tderef;localsymofs:longint;localindexreg:tregister;
localscale:byte;localgetoffset:boolean);
end;
poper=^toper;
@ -465,7 +466,7 @@ interface
procedure allocate_oper(opers:longint);
procedure loadconst(opidx:longint;l:aword);
procedure loadsymbol(opidx:longint;s:tasmsymbol;sofs:longint);
procedure loadlocal(opidx:longint;s:pointer;sofs:longint;indexreg:tregister;getoffset:boolean);
procedure loadlocal(opidx:longint;s:pointer;sofs:longint;indexreg:tregister;scale:byte;getoffset:boolean);
procedure loadref(opidx:longint;const r:treference);
procedure loadreg(opidx:longint;r:tregister);
procedure loadoper(opidx:longint;o:toper);
@ -1590,7 +1591,7 @@ implementation
end;
procedure taicpu_abstract.loadlocal(opidx:longint;s:pointer;sofs:longint;indexreg:tregister;getoffset:boolean);
procedure taicpu_abstract.loadlocal(opidx:longint;s:pointer;sofs:longint;indexreg:tregister;scale:byte;getoffset:boolean);
begin
if not assigned(s) then
internalerror(200204251);
@ -1602,6 +1603,7 @@ implementation
localsym:=s;
localsymofs:=sofs;
localindexreg:=indexreg;
localscale:=scale;
localgetoffset:=getoffset;
typ:=top_local;
end;
@ -1870,7 +1872,7 @@ implementation
reg3 := getsupreg(oper[2]^.reg)
else
reg3 := 0;
supreg:=reg1;
if supregset_in(r,supreg) then
begin
@ -1882,7 +1884,7 @@ implementation
// lwz r23d, -60(r1)
// add r23d, r21d, r22d
// stw r23d, -60(r1)
pos := get_insert_pos(Tai(previous),reg1,reg2,reg3,unusedregsint);
rgget(list,pos,R_SUBWHOLE,helpreg);
spill_registers := true;
@ -1898,7 +1900,7 @@ implementation
forward_allocation(tai(helpins.next),unusedregsint);
{ list.insertafter(tai_comment.Create(strpnew('Spilling!')),helpins);}
end;
for i := 1 to 2 do
if (oper[i]^.typ = top_reg) then
begin
@ -1913,7 +1915,7 @@ implementation
// lwz r23d, -60(r1)
// add r23d, r21d, r22d
// stw r23d, -60(r1)
pos := get_insert_pos(Tai(previous),reg1,reg2,reg3,unusedregsint);
rgget(list,pos,R_SUBWHOLE,helpreg);
spill_registers := true;
@ -2138,7 +2140,11 @@ implementation
end.
{
$Log$
Revision 1.52 2003-10-29 21:06:39 jonas
Revision 1.53 2003-10-30 19:59:00 peter
* support scalefactor for opr_local
* support reference with opr_local set, fixes tw2631
Revision 1.52 2003/10/29 21:06:39 jonas
* allow more than 3 args in the spilling routine
Revision 1.51 2003/10/29 15:40:20 peter

View File

@ -1021,13 +1021,13 @@ var
tempstr,hs : string;
typesize : longint;
code : integer;
hreg,
oldbase : tregister;
hreg : tregister;
GotStar,GotOffset,HadVar,
GotPlus,Negative : boolean;
Begin
Consume(AS_LBRACKET);
InitRef;
if not(opr.typ in [OPR_LOCAL,OPR_REFERENCE]) then
InitRef;
GotStar:=false;
GotPlus:=true;
GotOffset:=false;
@ -1053,15 +1053,29 @@ Begin
l:=BuildRefConstExpression;
GotPlus:=(prevasmtoken=AS_PLUS);
GotStar:=(prevasmtoken=AS_STAR);
if GotStar then
opr.ref.scalefactor:=l
else
begin
if negative then
Dec(opr.ref.offset,l)
else
Inc(opr.ref.offset,l);
end;
case opr.typ of
OPR_LOCAL :
begin
if GotStar then
Message(asmr_e_invalid_reference_syntax);
if negative then
Dec(opr.localsymofs,l)
else
Inc(opr.localsymofs,l);
end;
OPR_REFERENCE :
begin
if GotStar then
opr.ref.scalefactor:=l
else
begin
if negative then
Dec(opr.ref.offset,l)
else
Inc(opr.ref.offset,l);
end;
end;
end;
end
else
Begin
@ -1112,29 +1126,6 @@ Begin
{ should we allow ?? }
end;
end;
(*
if (opr.typ=OPR_REFERENCE) then
begin
{ is the base register loaded by the var ? }
if (opr.ref.base<>NR_NO) then
begin
{ check if we can move the old base to the index register }
if (opr.ref.index<>NR_NO) then
Message(asmr_e_wrong_base_index)
else
opr.ref.index:=oldbase;
end
else
opr.ref.base:=oldbase;
{ we can't have a Constant here so add the constant value to the
offset }
if opr.typ=OPR_CONSTANT then
begin
opr.typ:=OPR_REFERENCE;
inc(opr.ref.offset,opr.val);
end;
end;
*)
end;
GotOffset:=false;
end;
@ -1172,26 +1163,55 @@ Begin
end;
AS_REGISTER :
begin
if opr.ref.scalefactor=0 then
if scale<>0 then
begin
opr.ref.scalefactor:=scale;
scale:=0;
end
else
Message(asmr_e_wrong_scale_factor);
case opr.typ of
OPR_REFERENCE :
begin
if opr.ref.scalefactor=0 then
begin
if scale<>0 then
begin
opr.ref.scalefactor:=scale;
scale:=0;
end
else
Message(asmr_e_wrong_scale_factor);
end
else
Message(asmr_e_invalid_reference_syntax);
end;
OPR_LOCAL :
begin
if opr.localscale=0 then
begin
if scale<>0 then
begin
opr.localscale:=scale;
scale:=0;
end
else
Message(asmr_e_wrong_scale_factor);
end
else
Message(asmr_e_invalid_reference_syntax);
end;
end;
end;
else
Message(asmr_e_invalid_reference_syntax);
end;
if actasmtoken<>AS_REGISTER then
begin
if hs<>'' then
val(hs,l,code);
opr.ref.scalefactor:=l;
if l>9 then
Message(asmr_e_wrong_scale_factor);
end;
begin
if hs<>'' then
val(hs,l,code);
case opr.typ of
OPR_REFERENCE :
opr.ref.scalefactor:=l;
OPR_LOCAL :
opr.localscale:=l;
end;
if l>9 then
Message(asmr_e_wrong_scale_factor);
end;
GotPlus:=false;
GotStar:=false;
end;
@ -1203,34 +1223,41 @@ Begin
Message(asmr_e_invalid_reference_syntax);
hreg:=actasmregister;
Consume(AS_REGISTER);
if opr.typ=OPR_LOCAL then
begin
if (opr.localindexreg<>NR_NO) then
Message(asmr_e_multiple_index);
opr.localindexreg:=hreg;
end
else
begin
{ this register will be the index:
1. just read a *
2. next token is a *
3. base register is already used }
if (GotStar) or
(actasmtoken=AS_STAR) or
(opr.ref.base<>NR_NO) then
begin
if (opr.ref.index<>NR_NO) then
{ this register will be the index:
1. just read a *
2. next token is a *
3. base register is already used }
case opr.typ of
OPR_LOCAL :
begin
if (opr.localindexreg<>NR_NO) then
Message(asmr_e_multiple_index);
opr.ref.index:=hreg;
if scale<>0 then
begin
opr.ref.scalefactor:=scale;
scale:=0;
end;
end
else
opr.ref.base:=hreg;
end;
opr.localindexreg:=hreg;
if scale<>0 then
begin
opr.localscale:=scale;
scale:=0;
end;
end;
OPR_REFERENCE :
begin
if (GotStar) or
(actasmtoken=AS_STAR) or
(opr.ref.base<>NR_NO) then
begin
if (opr.ref.index<>NR_NO) then
Message(asmr_e_multiple_index);
opr.ref.index:=hreg;
if scale<>0 then
begin
opr.ref.scalefactor:=scale;
scale:=0;
end;
end
else
opr.ref.base:=hreg;
end;
end;
GotPlus:=false;
GotStar:=false;
end;
@ -1260,22 +1287,46 @@ Begin
else
Message(asmr_e_cant_have_multiple_relocatable_symbols);
end;
if GotStar then
opr.ref.scalefactor:=l
else if (prevasmtoken = AS_STAR) then
begin
if scale<>0 then
scale:=l*scale
else
scale:=l;
end
else
begin
if negative then
Dec(opr.ref.offset,l)
else
Inc(opr.ref.offset,l);
end;
case opr.typ of
OPR_REFERENCE :
begin
if GotStar then
opr.ref.scalefactor:=l
else if (prevasmtoken = AS_STAR) then
begin
if scale<>0 then
scale:=l*scale
else
scale:=l;
end
else
begin
if negative then
Dec(opr.ref.offset,l)
else
Inc(opr.ref.offset,l);
end;
end;
OPR_LOCAL :
begin
if GotStar then
opr.localscale:=l
else if (prevasmtoken = AS_STAR) then
begin
if scale<>0 then
scale:=l*scale
else
scale:=l;
end
else
begin
if negative then
Dec(opr.localsymofs,l)
else
Inc(opr.localsymofs,l);
end;
end;
end;
GotPlus:=(prevasmtoken=AS_PLUS) or
(prevasmtoken=AS_MINUS);
if GotPlus then
@ -1543,7 +1594,6 @@ Begin
AS_LBRACKET: { a variable reference, register ref. or a constant reference }
Begin
InitRef;
BuildReference;
end;
@ -1921,7 +1971,11 @@ finalization
end.
{
$Log$
Revision 1.62 2003-10-29 16:47:18 peter
Revision 1.63 2003-10-30 19:59:00 peter
* support scalefactor for opr_local
* support reference with opr_local set, fixes tw2631
Revision 1.62 2003/10/29 16:47:18 peter
* fix field offset in reference
Revision 1.61 2003/10/29 15:40:20 peter

View File

@ -133,6 +133,7 @@ interface
procedure ResolveRef(var op:toper);
var
sym : tvarsym;
scale : byte;
getoffset : boolean;
indexreg : tregister;
sofs : longint;
@ -141,6 +142,7 @@ interface
begin
sofs:=op.localsymofs;
indexreg:=op.localindexreg;
scale:=op.localscale;
getoffset:=op.localgetoffset;
sym:=tvarsym(pointer(op.localsym));
case sym.localloc.loc of
@ -168,6 +170,7 @@ interface
reference_reset_base(op.ref^,sym.localloc.reference.index,
sym.localloc.reference.offset+sofs);
op.ref^.index:=indexreg;
op.ref^.scalefactor:=scale;
end;
end;
LOC_REGISTER :
@ -399,7 +402,11 @@ begin
end.
{
$Log$
Revision 1.47 2003-10-29 15:40:20 peter
Revision 1.48 2003-10-30 19:59:00 peter
* support scalefactor for opr_local
* support reference with opr_local set, fixes tw2631
Revision 1.47 2003/10/29 15:40:20 peter
* support indexing and offset retrieval for locals
Revision 1.46 2003/10/24 17:39:41 peter

View File

@ -76,7 +76,7 @@ type
OPR_CONSTANT : (val:longint);
OPR_SYMBOL : (symbol:tasmsymbol;symofs:longint);
OPR_REFERENCE : (ref:treference);
OPR_LOCAL : (localsym:tvarsym;localsymofs:longint;localindexreg:tregister;localgetoffset:boolean);
OPR_LOCAL : (localsym:tvarsym;localsymofs:longint;localindexreg:tregister;localscale:byte;localgetoffset:boolean);
OPR_REGISTER : (reg:tregister);
{$ifdef m68k}
OPR_REGLIST : (reglist:Tsupregset);
@ -899,6 +899,7 @@ Begin
opr.localsym:=tvarsym(sym);
opr.localsymofs:=0;
opr.localindexreg:=indexreg;
opr.localscale:=0;
opr.localgetoffset:=GetOffset;
end;
if paramanager.push_addr_param(tvarsym(sym).varspez,tvarsym(sym).vartype.def,current_procinfo.procdef.proccalloption) then
@ -1602,7 +1603,11 @@ end;
end.
{
$Log$
Revision 1.75 2003-10-29 16:47:18 peter
Revision 1.76 2003-10-30 19:59:00 peter
* support scalefactor for opr_local
* support reference with opr_local set, fixes tw2631
Revision 1.75 2003/10/29 16:47:18 peter
* fix field offset in reference
Revision 1.74 2003/10/29 15:40:20 peter

View File

@ -771,6 +771,7 @@ implementation
ppufile.getderef(o.localsymderef);
o.localsymofs:=ppufile.getlongint;
o.localindexreg:=tregister(ppufile.getlongint);
o.localscale:=ppufile.getbyte;
o.localgetoffset:=(ppufile.getbyte<>0);
end;
end;
@ -805,6 +806,7 @@ implementation
ppufile.putderef(o.localsymderef);
ppufile.putlongint(longint(o.localsymofs));
ppufile.putlongint(longint(o.localindexreg));
ppufile.putbyte(o.localscale);
ppufile.putbyte(byte(o.localgetoffset));
end;
end;
@ -2332,7 +2334,11 @@ implementation
end.
{
$Log$
Revision 1.36 2003-10-29 15:40:20 peter
Revision 1.37 2003-10-30 19:59:00 peter
* support scalefactor for opr_local
* support reference with opr_local set, fixes tw2631
Revision 1.36 2003/10/29 15:40:20 peter
* support indexing and offset retrieval for locals
Revision 1.35 2003/10/23 14:44:07 peter

View File

@ -674,7 +674,8 @@ begin
OPR_SYMBOL:
ai.loadsymbol(i-1,operands[i].opr.symbol,operands[i].opr.symofs);
OPR_LOCAL :
ai.loadlocal(i-1,operands[i].opr.localsym,operands[i].opr.localsymofs,operands[i].opr.localindexreg,operands[i].opr.localgetoffset);
ai.loadlocal(i-1,operands[i].opr.localsym,operands[i].opr.localsymofs,operands[i].opr.localindexreg,
operands[i].opr.localscale,operands[i].opr.localgetoffset);
OPR_REFERENCE:
begin
ai.loadref(i-1,operands[i].opr.ref);
@ -735,7 +736,11 @@ end;
end.
{
$Log$
Revision 1.12 2003-10-29 15:40:20 peter
Revision 1.13 2003-10-30 19:59:00 peter
* support scalefactor for opr_local
* support reference with opr_local set, fixes tw2631
Revision 1.12 2003/10/29 15:40:20 peter
* support indexing and offset retrieval for locals
Revision 1.11 2003/10/21 15:15:36 peter