+ some more arm binary writer stuff, this is mainly a transfer commit

git-svn-id: trunk@1068 -
This commit is contained in:
florian 2005-09-09 16:12:19 +00:00
parent 9452e2a91f
commit e7e12f0f31
2 changed files with 188 additions and 12 deletions

View File

@ -531,13 +531,36 @@ implementation
end;
procedure BuildInsTabCache;
var
i : longint;
begin
new(instabcache);
FillChar(instabcache^,sizeof(tinstabcache),$ff);
i:=0;
while (i<InsTabEntries) do
begin
if InsTabCache^[InsTab[i].Opcode]=-1 then
InsTabCache^[InsTab[i].Opcode]:=i;
inc(i);
end;
end;
procedure InitAsm;
begin
if not assigned(instabcache) then
BuildInsTabCache;
end;
procedure DoneAsm;
begin
if assigned(instabcache) then
begin
dispose(instabcache);
instabcache:=nil;
end;
end;
@ -823,6 +846,23 @@ implementation
function taicpu.Pass1(offset:longint):longint;
begin
Pass1:=0;
{ Save the old offset and set the new offset }
InsOffset:=Offset;
{ Error? }
if (Insentry=nil) and (InsSize=-1) then
exit;
{ set the file postion }
aktfilepos:=fileinfo;
{ Get InsEntry }
if FindInsEntry then
begin
InsSize:=4;
LastInsOffset:=InsOffset;
Pass1:=InsSize;
exit;
end;
LastInsOffset:=-1;
end;
@ -861,8 +901,130 @@ implementation
end;
function taicpu.Matches(p:PInsEntry):longint;
function taicpu.Matches(p:PInsEntry):longint;
{ * IF_SM stands for Size Match: any operand whose size is not
* explicitly specified by the template is `really' intended to be
* the same size as the first size-specified operand.
* Non-specification is tolerated in the input instruction, but
* _wrong_ specification is not.
*
* IF_SM2 invokes Size Match on only the first _two_ operands, for
* three-operand instructions such as SHLD: it implies that the
* first two operands must match in size, but that the third is
* required to be _unspecified_.
*
* IF_SB invokes Size Byte: operands with unspecified size in the
* template are really bytes, and so no non-byte specification in
* the input instruction will be tolerated. IF_SW similarly invokes
* Size Word, and IF_SD invokes Size Doubleword.
*
* (The default state if neither IF_SM nor IF_SM2 is specified is
* that any operand with unspecified size in the template is
* required to have unspecified size in the instruction too...)
}
var
i,j,asize,oprs : longint;
siz : array[0..3] of longint;
begin
Matches:=100;
{ Check the opcode and operands }
if (p^.opcode<>opcode) or (p^.ops<>ops) then
begin
Matches:=0;
exit;
end;
{ Check that no spurious colons or TOs are present }
for i:=0 to p^.ops-1 do
if (oper[i]^.ot and (not p^.optypes[i]) and (OT_COLON or OT_TO))<>0 then
begin
Matches:=0;
exit;
end;
{ Check that the operand flags all match up }
for i:=0 to p^.ops-1 do
begin
if ((p^.optypes[i] and (not oper[i]^.ot)) or
((p^.optypes[i] and OT_SIZE_MASK) and
((p^.optypes[i] xor oper[i]^.ot) and OT_SIZE_MASK)))<>0 then
begin
if ((p^.optypes[i] and (not oper[i]^.ot) and OT_NON_SIZE) or
(oper[i]^.ot and OT_SIZE_MASK))<>0 then
begin
Matches:=0;
exit;
end
else
Matches:=1;
end;
end;
{ Check operand sizes }
{ as default an untyped size can get all the sizes, this is different
from nasm, but else we need to do a lot checking which opcodes want
size or not with the automatic size generation }
asize:=longint($ffffffff);
(*
if (p^.flags and IF_SB)<>0 then
asize:=OT_BITS8
else if (p^.flags and IF_SW)<>0 then
asize:=OT_BITS16
else if (p^.flags and IF_SD)<>0 then
asize:=OT_BITS32;
if (p^.flags and IF_ARMASK)<>0 then
begin
siz[0]:=0;
siz[1]:=0;
siz[2]:=0;
if (p^.flags and IF_AR0)<>0 then
siz[0]:=asize
else if (p^.flags and IF_AR1)<>0 then
siz[1]:=asize
else if (p^.flags and IF_AR2)<>0 then
siz[2]:=asize;
end
else
begin
{ we can leave because the size for all operands is forced to be
the same
but not if IF_SB IF_SW or IF_SD is set PM }
if asize=-1 then
exit;
siz[0]:=asize;
siz[1]:=asize;
siz[2]:=asize;
end;
if (p^.flags and (IF_SM or IF_SM2))<>0 then
begin
if (p^.flags and IF_SM2)<>0 then
oprs:=2
else
oprs:=p^.ops;
for i:=0 to oprs-1 do
if ((p^.optypes[i] and OT_SIZE_MASK) <> 0) then
begin
for j:=0 to oprs-1 do
siz[j]:=p^.optypes[i] and OT_SIZE_MASK;
break;
end;
end
else
oprs:=2;
{ Check operand sizes }
for i:=0 to p^.ops-1 do
begin
if ((p^.optypes[i] and OT_SIZE_MASK)=0) and
((oper[i]^.ot and OT_SIZE_MASK and (not siz[i]))<>0) and
{ Immediates can always include smaller size }
((oper[i]^.ot and OT_IMMEDIATE)=0) and
(((p^.optypes[i] and OT_SIZE_MASK) or siz[i])<(oper[i]^.ot and OT_SIZE_MASK)) then
Matches:=2;
end;
*)
end;
@ -931,8 +1093,6 @@ implementation
inssize:=-1;
end;
end.
{$ifdef dummy}

View File

@ -1040,6 +1040,11 @@ Implementation
objectdata.alloc(Taicpu(hp).Pass1(objectdata.currsec.datasize));
{$endif NOAG386BIN}
{$endif i386}
{$ifdef arm}
{ reset instructions which could change in pass 2 }
Taicpu(hp).resetpass2;
objectdata.alloc(Taicpu(hp).Pass1(objectdata.currsec.datasize));
{$endif arm}
end;
ait_cutobject :
if SmartAsm then
@ -1054,12 +1059,8 @@ Implementation
function TInternalAssembler.TreePass1(hp:Tai):Tai;
var
InlineLevel,
l : longint;
{$ifdef i386}
{$ifndef NOAG386BIN}
l,
i : longint;
{$endif NOAG386BIN}
{$endif i386}
begin
inlinelevel:=0;
while assigned(hp) do
@ -1210,6 +1211,25 @@ Implementation
end;
{$endif NOAG386BIN}
{$endif i386}
{$ifdef arm}
objectdata.alloc(Taicpu(hp).Pass1(objectdata.currsec.datasize));
{ fixup the references }
for i:=1 to Taicpu(hp).ops do
begin
with Taicpu(hp).oper[i-1]^ do
begin
case typ of
top_ref :
begin
if assigned(ref^.symbol) then
objectlibrary.UsedAsmSymbolListInsert(ref^.symbol);
if assigned(ref^.relsymbol) then
objectlibrary.UsedAsmSymbolListInsert(ref^.symbol);
end;
end;
end;
end;
{$endif arm}
end;
ait_direct :
Message(asmw_f_direct_not_supported);
@ -1340,12 +1360,8 @@ Implementation
but it's better to be on the safe side (PFV) }
objectoutput.exportsymbol(Tai_label(hp).l);
end;
{$ifdef i386}
{$ifndef NOAG386BIN}
ait_instruction :
Taicpu(hp).Pass2(objectdata);
{$endif NOAG386BIN}
{$endif i386}
{$ifdef GDB}
ait_stabn :
convertstabs(Tai_stabn(hp).str);