mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 20:59:42 +02:00
* support scalefactor for opr_local
* support reference with opr_local set, fixes tw2631
This commit is contained in:
parent
9ff3d9ac58
commit
48ef24605a
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user