mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-11 11:58:41 +02:00
* fixed support for access from inline asm to absolute vars, pointing to an
array element (previously, it would always point to the start of the array) git-svn-id: trunk@37558 -
This commit is contained in:
parent
a230826357
commit
24d447716e
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -12129,6 +12129,7 @@ tests/test/cpu16/i8086/tasm16_32_3.pp svneol=native#text/pascal
|
||||
tests/test/cpu16/i8086/tasm16_32_4.pp svneol=native#text/pascal
|
||||
tests/test/cpu16/i8086/tasmabs1.pp svneol=native#text/pascal
|
||||
tests/test/cpu16/i8086/tasmabs2.pp svneol=native#text/pascal
|
||||
tests/test/cpu16/i8086/tasmabs3.pp svneol=native#text/pascal
|
||||
tests/test/cpu16/i8086/tasmseg1.pp svneol=native#text/pascal
|
||||
tests/test/cpu16/i8086/tfarcal1.pp svneol=native#text/pascal
|
||||
tests/test/cpu16/i8086/tfarcal2.pp svneol=native#text/pascal
|
||||
|
@ -28,7 +28,7 @@ Interface
|
||||
Uses
|
||||
cutils,cclasses,
|
||||
globtype,aasmbase,aasmtai,aasmdata,cpubase,cpuinfo,cgbase,cgutils,
|
||||
symconst,symbase,symtype,symdef,symsym,symcpu;
|
||||
symconst,symbase,symtype,symdef,symsym,constexp,symcpu;
|
||||
|
||||
Const
|
||||
RPNMax = 10; { I think you only need 4, but just to be safe }
|
||||
@ -812,6 +812,10 @@ var
|
||||
indexreg : tregister;
|
||||
plist : ppropaccesslistitem;
|
||||
size_set_from_absolute : boolean = false;
|
||||
{ offset fixup (in bytes), coming from an absolute declaration with an index
|
||||
(e.g. var tralala: word absolute moo[5]; ) }
|
||||
absoffset: asizeint=0;
|
||||
harrdef: tarraydef;
|
||||
Begin
|
||||
SetupVar:=false;
|
||||
asmsearchsym(s,sym,srsymtable);
|
||||
@ -830,6 +834,40 @@ Begin
|
||||
setvarsize(tabstractvarsym(sym));
|
||||
size_set_from_absolute:=true;
|
||||
sym:=plist^.sym;
|
||||
{ resolve the chain of array indexes (if there are any) }
|
||||
harrdef:=nil;
|
||||
while assigned(plist^.next) do
|
||||
begin
|
||||
plist:=plist^.next;
|
||||
if (plist^.sltype=sl_vec) and (tabstractvarsym(sym).vardef.typ=arraydef) then
|
||||
begin
|
||||
if harrdef=nil then
|
||||
harrdef:=tarraydef(tabstractvarsym(sym).vardef)
|
||||
else if harrdef.elementdef.typ=arraydef then
|
||||
harrdef:=tarraydef(harrdef.elementdef)
|
||||
else
|
||||
begin
|
||||
Message(asmr_e_unsupported_symbol_type);
|
||||
exit;
|
||||
end;
|
||||
if is_special_array(harrdef) then
|
||||
begin
|
||||
Message(asmr_e_unsupported_symbol_type);
|
||||
exit;
|
||||
end;
|
||||
if not is_packed_array(harrdef) then
|
||||
Inc(absoffset,asizeint(Int64(plist^.value-harrdef.lowrange))*harrdef.elesize)
|
||||
else if (Int64(plist^.value-harrdef.lowrange)*harrdef.elepackedbitsize mod 8)=0 then
|
||||
Inc(absoffset,asizeint(Int64(plist^.value-harrdef.lowrange)*harrdef.elepackedbitsize div 8))
|
||||
else
|
||||
Message(asmr_e_packed_element);
|
||||
end
|
||||
else
|
||||
begin
|
||||
Message(asmr_e_unsupported_symbol_type);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -858,9 +896,9 @@ Begin
|
||||
fieldvarsym :
|
||||
begin
|
||||
if not tabstractrecordsymtable(sym.owner).is_packed then
|
||||
setconst(tfieldvarsym(sym).fieldoffset)
|
||||
setconst(absoffset+tfieldvarsym(sym).fieldoffset)
|
||||
else if tfieldvarsym(sym).fieldoffset mod 8 = 0 then
|
||||
setconst(tfieldvarsym(sym).fieldoffset div 8)
|
||||
setconst(absoffset+tfieldvarsym(sym).fieldoffset div 8)
|
||||
else
|
||||
Message(asmr_e_packed_element);
|
||||
if not size_set_from_absolute then
|
||||
@ -885,6 +923,7 @@ Begin
|
||||
begin
|
||||
initref;
|
||||
opr.ref.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(sym).mangledname,AT_DATA);
|
||||
Inc(opr.ref.offset,absoffset);
|
||||
end;
|
||||
paravarsym,
|
||||
localvarsym :
|
||||
@ -911,7 +950,7 @@ Begin
|
||||
symtable_has_localvarsyms(current_procinfo.procdef.localst) then
|
||||
message1(asmr_e_local_para_unreachable,s);
|
||||
opr.localsym:=tabstractnormalvarsym(sym);
|
||||
opr.localsymofs:=0;
|
||||
opr.localsymofs:=absoffset;
|
||||
opr.localindexreg:=indexreg;
|
||||
opr.localscale:=0;
|
||||
opr.localgetoffset:=GetOffset;
|
||||
@ -951,6 +990,7 @@ Begin
|
||||
OPR_REFERENCE:
|
||||
begin
|
||||
opr.ref.symbol:=current_asmdata.RefAsmSymbol(tprocdef(tprocsym(sym).ProcdefList[0]).mangledname,AT_FUNCTION);
|
||||
Inc(opr.ref.offset,absoffset);
|
||||
{$ifdef i8086}
|
||||
opr.ref_farproc_entry:=is_proc_far(tprocdef(tprocsym(sym).ProcdefList[0]))
|
||||
and not (po_interrupt in tprocdef(tprocsym(sym).ProcdefList[0]).procoptions);
|
||||
@ -964,7 +1004,7 @@ Begin
|
||||
opr.sym_farproc_entry:=is_proc_far(tprocdef(tprocsym(sym).ProcdefList[0]))
|
||||
and not (po_interrupt in tprocdef(tprocsym(sym).ProcdefList[0]).procoptions);
|
||||
{$endif i8086}
|
||||
opr.symofs:=0;
|
||||
opr.symofs:=absoffset;
|
||||
end;
|
||||
else
|
||||
Message(asmr_e_invalid_operand_type);
|
||||
@ -981,6 +1021,7 @@ Begin
|
||||
OPR_REFERENCE:
|
||||
begin
|
||||
opr.ref.symbol:=current_asmdata.RefAsmSymbol(tlabelsym(sym).mangledname,AT_FUNCTION);
|
||||
Inc(opr.ref.offset,absoffset);
|
||||
if opr.ref.segment=NR_NO then
|
||||
opr.ref.segment:=NR_CS;
|
||||
end;
|
||||
|
44
tests/test/cpu16/i8086/tasmabs3.pp
Normal file
44
tests/test/cpu16/i8086/tasmabs3.pp
Normal file
@ -0,0 +1,44 @@
|
||||
program tasmabs3;
|
||||
|
||||
{ NOT TP7 compatible (TP7 doesn't support absolute with an index) }
|
||||
|
||||
{$ASMMODE INTEL}
|
||||
{$ASMCPU 80386}
|
||||
|
||||
var
|
||||
barr: array [-7..100] of byte;
|
||||
l: longint absolute barr[17];
|
||||
w: word absolute barr[53];
|
||||
b: byte absolute barr[62];
|
||||
begin
|
||||
FillChar(barr, SizeOf(barr), $ff);
|
||||
asm
|
||||
mov l, 4
|
||||
end;
|
||||
if (barr[17+0] <> 4) or (barr[17+1] <> 0) or (barr[17+2] <> 0) or
|
||||
(barr[17+3] <> 0) or (barr[17+4] <> 255) or (barr[17-1] <> 255) then
|
||||
begin
|
||||
Writeln('Error!');
|
||||
Halt(1);
|
||||
end;
|
||||
FillChar(barr, SizeOf(barr), $ff);
|
||||
asm
|
||||
mov w, 2
|
||||
end;
|
||||
if (barr[53] <> 2) or (barr[54] <> 0) or (barr[55] <> 255) or
|
||||
(barr[52] <> 255) then
|
||||
begin
|
||||
Writeln('Error!');
|
||||
Halt(1);
|
||||
end;
|
||||
FillChar(barr, SizeOf(barr), $ff);
|
||||
asm
|
||||
mov b, 1
|
||||
end;
|
||||
if (barr[62] <> 1) or (barr[63] <> 255) or (barr[61] <> 255) then
|
||||
begin
|
||||
Writeln('Error!');
|
||||
Halt(1);
|
||||
end;
|
||||
Writeln('Ok!');
|
||||
end.
|
Loading…
Reference in New Issue
Block a user