fpc/compiler/utils/mkx86inl.pp
florian 5950a5f97b * compiler utils cannot depend on StrUtils
git-svn-id: trunk@48408 -
2021-01-24 18:07:13 +00:00

822 lines
26 KiB
ObjectPascal

program mkx86inl;
{$mode objfpc}
{$H+}
uses
sysutils, classes;
type
TOperDirection = (operIn, operVar, operOut);
TOperand = record
name,
typ: string;
direction: TOperDirection;
end;
const
DirLUT: array[TOperDirection] of string = ('','var ','out ');
{ ***************************************************************************
the routines Copy2SymbDel, PosSetEx, PosSet, RemoveTrailingChars, TrimRightSet are copied and reformatted
from StrUtils and thus covered by the copyright of strutils (see below) as compiler utilities cannot
depend on packages
This file is part of the Free Pascal run time library.
Copyright (c) 1999-2005 by the Free Pascal development team
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*************************************************************************** }
function Copy2SymbDel(var S: string; Symb: Char): string;
var
p: SizeInt;
begin
p:=Pos(Symb,S);
if p=0 then
begin
result:=s;
s:='';
end
else
begin
Result:=Copy(S,1,p-1);
delete(s,1,p);
end;
end;
function PosSetEx(const c: TSysCharSet; const s: ansistring; count: Integer): SizeInt;
var
i,j:SizeInt;
begin
if pchar(pointer(s))=nil then
j:=0
else
begin
i:=length(s);
j:=count;
if j>i then
begin
result:=0;
exit;
end;
while (j<=i) and (not (s[j] in c)) do inc(j);
if (j>i) then
j:=0; // not found.
end;
result:=j;
end;
function PosSet(const c: TSysCharSet; const s: ansistring): SizeInt;
begin
result:=possetex(c,s,1);
end;
procedure RemoveTrailingChars(VAR S: AnsiString; const CSet: TSysCharset);
var
I,J: LONGINT;
Begin
I:=Length(S);
IF (I>0) Then
Begin
J:=I;
While (j>0) and (S[J] IN CSet) DO DEC(J);
IF J<>I Then
SetLength(S,J);
End;
End;
function TrimRightSet(const S: String; const CSet: TSysCharSet): String;
begin
result:=s;
RemoveTrailingchars(result,cset);
end;
{ ***************************************************************************
end of StrUtils code
***************************************************************************}
function GetPascalType(const ATyp: string): string;
begin
case ATyp of
'r8': exit('byte');
'rs8': exit('shortint');
'r16': exit('word');
'rs16': exit('smallint');
'r32': exit('longword');
'rs32': exit('longint');
'r64': exit('qword');
'rs64': exit('int64');
'reg': exit('NativeUInt');
'sreg': exit('NativeInt');
'f32': exit('single');
'f64': exit('double');
'mm': exit('__m64');
'implicit_xmm0',
'xmm': exit('__m128');
'i32': exit('longint');
'edi_ptr': exit('pointer');
'ptr8',
'ptr16',
'ptr32',
'ptr64',
'ptr128': exit('pointer');
else
exit(ATyp);
end;
end;
function GetTypeDef(const ATyp: string): string;
begin
case ATyp of
'r8': exit('u8inttype');
'rs8': exit('s8inttype');
'r16': exit('u16inttype');
'rs16': exit('s16inttype');
'r32': exit('u32inttype');
'rs32': exit('s32inttype');
'r64': exit('u64inttype');
'rs64': exit('s64inttype');
'reg': exit('uinttype');
'sreg': exit('sinttype');
'f32': exit('s32floattype');
'f64': exit('s64floattype');
'mm': exit('x86_m64type');
'implicit_xmm0',
'xmm': exit('x86_m128type');
'i32': exit('s32inttype');
'edi_ptr': exit('voidpointertype');
'ptr8',
'ptr16',
'ptr32',
'ptr64',
'ptr128': exit('voidpointertype');
else
exit(ATyp);
end;
end;
function GetOper(const ATyp: string): string;
begin
case ATyp of
'r8': exit('_reg');
'rs8': exit('_reg');
'r16': exit('_reg');
'rs16': exit('_reg');
'r32': exit('_reg');
'rs32': exit('_reg');
'r64': exit('_reg_reg');
'rs64': exit('_reg_reg');
'reg': exit('_reg');
'sreg': exit('_reg');
'f32': exit('_reg');
'f64': exit('_reg');
'mm': exit('_reg');
'xmm': exit('_reg');
'i32': exit('_const');
'implicit_xmm0',
'edi_ptr': exit('');
'ptr8',
'ptr16',
'ptr32',
'ptr64',
'ptr128': exit('_ref');
else
exit('');
end;
end;
function GetOperand(const ATyp: string; AIndex: longint): string;
begin
case ATyp of
'r8': exit(format(',paraarray[%d].location.register', [AIndex]));
'rs8': exit(format(',paraarray[%d].location.register', [AIndex]));
'r16': exit(format(',paraarray[%d].location.register', [AIndex]));
'rs16': exit(format(',paraarray[%d].location.register', [AIndex]));
'r32': exit(format(',paraarray[%d].location.register', [AIndex]));
'rs32': exit(format(',paraarray[%d].location.register', [AIndex]));
'r64': exit(format(',paraarray[%d].location.register64.reglo,paraarray[%d].location.register64.reghi', [AIndex,AIndex]));
'rs64': exit(format(',paraarray[%d].location.register64.reglo,paraarray[%d].location.register64.reghi', [AIndex,AIndex]));
'reg': exit(format(',paraarray[%d].location.register', [AIndex]));
'sreg': exit(format(',paraarray[%d].location.register', [AIndex]));
'f32': exit(format(',paraarray[%d].location.register', [AIndex]));
'f64': exit(format(',paraarray[%d].location.register', [AIndex]));
'mm': exit(format(',paraarray[%d].location.register', [AIndex]));
'xmm': exit(format(',paraarray[%d].location.register', [AIndex]));
'i32': exit(format(',GetConstInt(paraarray[%d])',[AIndex]));
'implicit_xmm0',
'edi_ptr': exit('');
'ptr8',
'ptr16',
'ptr32',
'ptr64',
'ptr128': exit(format(',paraarray[%d].location.reference', [AIndex]));
else
exit(ATyp);
end;
end;
function GetOperandLoc(const ATyp: string): string;
begin
result:='';
case ATyp of
'r8': exit(',location.register');
'rs8': exit(',location.register');
'r16': exit(',location.register');
'rs16': exit(',location.register');
'r32': exit(',location.register');
'rs32': exit(',location.register');
'r64': exit(',location.register64.reglo,location.register64.reghi');
'rs64': exit(',location.register64.reglo,location.register64.reghi');
'reg': exit(',location.register');
'sreg': exit(',location.register');
'f32': exit(',location.register');
'f64': exit(',location.register');
'mm': exit(',location.register');
'implicit_xmm0',
'xmm': exit(',location.register');
'edi_ptr': exit(',location.register');
'ptr8',
'ptr16',
'ptr32',
'ptr64',
'ptr128': exit(',location.register');
end;
end;
function GetLocStatement(AIndex: longint; const ATyp: string; AConst: boolean): string;
begin
result:='';
case ATyp of
'r8': exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u8inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
'rs8': exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u8inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
'r16': exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u16inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
'rs16': exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u16inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
'r32': exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u32inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
'rs32': exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u32inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
'r64': exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u64inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
'rs64': exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,u64inttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
'reg': exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,uinttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
'sreg': exit(format('hlcg.location_force_reg(current_asmdata.CurrAsmList, paraarray[%d].location, paraarray[%d].resultdef,sinttype,%s);', [AIndex+1, AIndex+1, BoolToStr(aconst,'true','false')]));
'f32': exit(format('location_force_mmreg(current_asmdata.CurrAsmList, paraarray[%d].location, %s);', [AIndex+1, BoolToStr(aconst,'true','false')]));
'f64': exit(format('location_force_mmreg(current_asmdata.CurrAsmList, paraarray[%d].location, %s);', [AIndex+1, BoolToStr(aconst,'true','false')]));
'mm': exit(format('location_force_mmxreg(current_asmdata.CurrAsmList, paraarray[%d].location, %s);', [AIndex+1, BoolToStr(aconst,'true','false')]));
'xmm': exit(format('location_force_mmreg(current_asmdata.CurrAsmList, paraarray[%d].location, %s);', [AIndex+1, BoolToStr(aconst,'true','false')]));
'implicit_xmm0':
exit(format('location_force_mmreg(current_asmdata.CurrAsmList, paraarray[%d].location, %s);'+LineEnding+
' hlcg.getcpuregister(current_asmdata.CurrAsmList,NR_XMM0);'+LineEnding+
' hlcg.a_loadmm_loc_reg(current_asmdata.CurrAsmList,paraarray[%d].resultdef,x86_m128type,paraarray[%d].location,NR_XMM0,nil);',
[AIndex+1, BoolToStr(aconst,'true','false'), AIndex+1, AIndex+1]));
'edi_ptr':
exit(format('hlcg.getcpuregister(current_asmdata.CurrAsmList,{$if defined(cpu64bitalu)}NR_RDI{$else}NR_EDI{$endif});'+LineEnding+
' hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,paraarray[%d].resultdef,voidpointertype,paraarray[%d].location,{$if defined(cpu64bitalu)}NR_RDI{$else}NR_EDI{$endif});',
[AIndex+1, AIndex+1]));
'ptr8',
'ptr16',
'ptr32',
'ptr64',
'ptr128':exit(format('location_make_ref(paraarray[%d].location);', [AIndex+1]));
end;
end;
function GetDeallocStatement(AIndex: longint; const ATyp: string): string;
begin
result:='';
case ATyp of
'implicit_xmm0':
exit('hlcg.ungetcpuregister(current_asmdata.CurrAsmList,NR_XMM0);');
'edi_ptr':
exit('hlcg.ungetcpuregister(current_asmdata.CurrAsmList,{$if defined(cpu64bitalu)}NR_RDI{$else}NR_EDI{$endif});');
end;
end;
function GetLoc(const ATyp: string; AWithSize: boolean = true): string;
begin
result:='';
if AWithSize then
case ATyp of
'r8': exit('LOC_REGISTER,OS_8');
'rs8': exit('LOC_REGISTER,OS_S8');
'r16': exit('LOC_REGISTER,OS_16');
'rs16': exit('LOC_REGISTER,OS_S16');
'r32': exit('LOC_REGISTER,OS_32');
'rs32': exit('LOC_REGISTER,OS_S32');
'r64': exit('LOC_REGISTER,OS_64');
'rs64': exit('LOC_REGISTER,OS_S64');
'reg': exit('LOC_REGISTER,OS_INT');
'sreg': exit('LOC_REGISTER,OS_SINT');
'f32': exit('LOC_MMREGISTER,OS_M128');
'f64': exit('LOC_MMREGISTER,OS_M128');
'mm': exit('LOC_MMXREGISTER,OS_M64');
'implicit_xmm0',
'xmm': exit('LOC_MMREGISTER,OS_M128');
'edi_ptr': exit('LOC_REGISTER,OS_INT');
'ptr8': exit('LOC_MEM,OS_8');
'ptr16': exit('LOC_MEM,OS_16');
'ptr32': exit('LOC_MEM,OS_32');
'ptr64': exit('LOC_MEM,OS_64');
'ptr128':exit('LOC_MEM,OS_128');
end
else
case ATyp of
'r8': exit('LOC_REGISTER');
'rs8': exit('LOC_REGISTER');
'r16': exit('LOC_REGISTER');
'rs16': exit('LOC_REGISTER');
'r32': exit('LOC_REGISTER');
'rs32': exit('LOC_REGISTER');
'r64': exit('LOC_REGISTER');
'rs64': exit('LOC_REGISTER');
'reg': exit('LOC_REGISTER');
'sreg': exit('LOC_REGISTER');
'f32': exit('LOC_MMREGISTER');
'f64': exit('LOC_MMREGISTER');
'mm': exit('LOC_MMXREGISTER');
'implicit_xmm0',
'xmm': exit('LOC_MMREGISTER');
'edi_ptr': exit('LOC_REGISTER');
'ptr8',
'ptr16',
'ptr32',
'ptr64',
'ptr128':exit('LOC_MEM');
end;
end;
function GetLocAllocation(const ATyp: string): string;
begin
result:='';
case ATyp of
'r8': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_8);');
'rs8': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_8);');
'r16': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_16);');
'rs16': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_16);');
'r32': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
'rs32': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
'r64': exit('location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList, OS_32); location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
'rs64': exit('location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList, OS_32); location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
'reg': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_INT);');
'sreg': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_INT);');
'f32': exit('location.register:=cg.getmmregister(current_asmdata.CurrAsmList, OS_M128);');
'f64': exit('location.register:=cg.getmmregister(current_asmdata.CurrAsmList, OS_M128);');
'mm': exit('location.register:=tcgx86(cg).getmmxregister(current_asmdata.CurrAsmList);');
'xmm': exit('location.register:=cg.getmmregister(current_asmdata.CurrAsmList, OS_M128);');
end;
end;
function GetPostFix(const APF: string): string;
begin
if APF<>'' then
result:='PF_'+APF
else
result:='PF_None';
end;
procedure ParseList(const APrefix, AFilename: string);
var
f: TextFile;
fprocs,
fcinnr, fcpumminnr: TextFile;
ftypechk, ffirst, fsecond: TStringList;
str,
instrPart,postfix,_alias,
params, operline: String;
opers: array[0..7] of TOperand;
opercnt: longint;
hasOutput: boolean;
outputType: string;
cnt,
i, intrnum: longint;
tmp, condition, target: String;
function ParseOperands(AIndex: longint = -1): string;
var
idx: LongInt;
pt: Integer;
c: Char;
begin
idx:=opercnt;
params:=trim(params);
if params='' then
exit('');
inc(opercnt);
if pos('var ', params)=1 then
begin
opers[idx].direction:=operVar;
Delete(params,1,4);
params:=trim(params);
hasOutput:=true;
end
else if pos('out ', params)=1 then
begin
opers[idx].direction:=operOut;
Delete(params,1,4);
params:=trim(params);
hasOutput:=true;
end
else
begin
if AIndex<>-1 then
opers[idx].direction:=opers[AIndex].direction
else
opers[idx].direction:=operIn;
end;
pt:=PosSet([',',':'], params);
c:=params[pt];
opers[idx].name:=Copy2SymbDel(params, c);
params:=trim(params);
if c = ':' then
begin
opers[idx].typ:=Copy2SymbDel(params, ';');
result:=opers[idx].typ;
end
else
begin
opers[idx].typ:=ParseOperands(idx);
result:=opers[idx].typ;
end;
if opers[idx].direction<>operIn then
outputType:=opers[idx].typ;
end;
function GetOperLine: string;
var
i: longint;
begin
result:='';
for i := 0 to opercnt-1 do
result:=result+DirLUT[opers[i].direction]+opers[i].name+':'+opers[i].typ+';';
end;
function GetParams: longint;
var
i: longint;
begin
result:=0;
for i := 0 to opercnt-1 do
if opers[i].direction in [operIn,operVar] then
inc(result);
end;
function FindOperIdx(const AOper: string): longint;
var
i,cnt: longint;
begin
cnt:=0;
result:=0;
for i := 0 to opercnt-1 do
if (opers[i].direction in [operIn,operVar]) then
begin
if opers[i].name=AOper then
exit(cnt);
inc(cnt);
end;
end;
begin
intrnum:=0;
assignfile(f, AFilename);
reset(f);
assignfile(fprocs, 'cpummprocs.inc'); rewrite(fprocs);
assignfile(fcinnr, 'c'+APrefix+'mminnr.inc'); rewrite(fcinnr);
assignfile(fcpumminnr, 'cpumminnr.inc'); rewrite(fcpumminnr);
// writeln(finnr,'const');
ftypechk:=TStringList.Create;
ffirst:=TStringList.Create;
fsecond:=TStringList.Create;
// writeln(finnr, ' fpc_in_', APrefix,'_first = fpc_in_',APrefix,'_base;');
while not EOF(f) do
begin
readln(f, str);
str:=trim(str);
if (str='') or (Pos(';',str)=1) then
continue;
instrPart:=Copy2SymbDel(str, '(');
// Check for postfix
if pos('{',instrPart)>0 then
begin
postfix:=instrPart;
instrPart:=Copy2SymbDel(postfix, '{');
postfix:=TrimRightSet(postfix,['}']);
end
else
postfix:='';
// Check for alias
if pos('[',instrPart)>0 then
begin
_alias:=instrPart;
instrPart:=Copy2SymbDel(_alias, '[');
_alias:='_'+TrimRightSet(_alias,[']']);
end
else
_alias:='';
// Get parameters
params:=trim(Copy2SymbDel(str,')'));
str:=trim(str);
// Parse condition and target
if pos('|', str)>0 then
begin
condition:=trim(Copy2SymbDel(str, '|'));
target:=trim(str);
end
else
begin
condition:=str;
target:='';
end;
hasOutput:=false;
opercnt:=0;
outputType:='';
while params<>'' do
ParseOperands;
operline:=GetOperLine;
// Write typecheck code
i:=ftypechk.IndexOf(': //'+operline);
if (i>=0) and (target='') then
ftypechk.Insert(i,',in_'+APrefix+'_'+instrPart+postfix+_alias)
else
begin
if target<>'' then
ftypechk.add(format('{$ifdef %s}', [target]));
ftypechk.Add('in_'+APrefix+'_'+instrPart+postfix+_alias);
ftypechk.Add(': //'+operline);
ftypechk.Add(' begin');
ftypechk.Add(' CheckParameters('+inttostr(GetParams())+');');
if hasOutput then
ftypechk.Add(' resultdef:='+GetTypeDef(outputType)+';')
else
ftypechk.Add(' resultdef:=voidtype;');
ftypechk.Add(' end;');
if target<>'' then
ftypechk.add('{$endif}');
end;
// Write firstpass code
i:=ffirst.IndexOf(': //'+operline);
if (i>=0) and (target='') then
ffirst.Insert(i,',in_'+APrefix+'_'+instrPart+postfix+_alias)
else
begin
if target<>'' then
ffirst.add(format('{$ifdef %s}', [target]));
ffirst.Add('in_'+APrefix+'_'+instrPart+postfix+_alias);
ffirst.Add(': //'+operline);
ffirst.Add(' begin');
if hasOutput then
ffirst.Add(' expectloc:='+GetLoc(outputType,false)+';')
else
ffirst.Add(' expectloc:=LOC_VOID;');
ffirst.Add(' result:=nil;');
ffirst.Add(' end;');
if target<>'' then
ffirst.add('{$endif}');
end;
// Write secondpass code
i:=fsecond.IndexOf(': //'+operline);
if (i>=0) and (target='') then
begin
fsecond.Insert(i+3,' in_'+APrefix+'_'+instrPart+postfix+_alias+': begin op:=A_'+instrPart+' end;');
fsecond.Insert(i,',in_'+APrefix+'_'+instrPart+postfix+_alias);
end
else
begin
if target<>'' then
fsecond.add(format('{$ifdef %s}', [target]));
fsecond.Add('in_'+APrefix+'_'+instrPart+postfix+_alias);
fsecond.Add(': //'+operline);
fsecond.Add(' begin');
fsecond.Add(' case inlinenumber of');
fsecond.Add(' in_'+APrefix+'_'+instrPart+postfix+_alias+': begin op:=A_'+instrPart+'; end;');
fsecond.Add(' else');
fsecond.Add(' Internalerror(2020010201);');
fsecond.Add(' end;');
fsecond.Add('');
i:=GetParams;
fsecond.Add(' GetParameters('+inttostr(i)+');');
fsecond.Add('');
fsecond.Add(' for i := 1 to '+inttostr(i)+' do secondpass(paraarray[i]);');
fsecond.Add('');
// Force inputs
cnt:=0;
for i := 0 to opercnt-1 do
begin
case opers[i].direction of
operIn:
begin
tmp:=GetLocStatement(cnt, opers[i].typ, true);
if tmp<>'' then
fsecond.add(' '+tmp);
inc(cnt);
end;
operVar:
begin
tmp:=GetLocStatement(cnt, opers[i].typ, false);
if tmp<>'' then
fsecond.add(' '+tmp);
inc(cnt);
end;
else
;
end;
end;
// Allocate output
cnt:=0;
for i := 0 to opercnt-1 do
begin
case opers[i].direction of
operOut:
begin
fsecond.add(' location_reset(location,'+GetLoc(opers[i].typ)+');');
fsecond.Add(' '+GetLocAllocation(opers[i].typ));
end;
operVar:
begin
fsecond.Add(' location:=paraarray['+inttostr(cnt+1)+'].location;');
inc(cnt);
end;
operIn:
inc(cnt);
end;
end;
operline:='taicpu.op';
//for i := 0 to opercnt-1 do
for i := opercnt-1 downto 0 do
begin
case opers[i].direction of
operOut:
operline:=operline+GetOper(opers[i].typ);
operVar:
operline:=operline+GetOper(opers[i].typ);
operIn:
operline:=operline+GetOper(opers[i].typ);
end;
end;
if operline='taicpu.op' then
operline:='taicpu.op_none(op,S_NO'
else
operline:=operline+'(op,S_NO';
//for i := 0 to opercnt-1 do
for i := opercnt-1 downto 0 do
begin
case opers[i].direction of
operOut:
operline:=operline+GetOperandLoc(opers[i].typ);
operIn,
operVar:
begin
dec(cnt);
operline:=operline+GetOperand(opers[i].typ, cnt+1);
end;
end;
end;
operline:=operline+')';
fsecond.Add(' current_asmdata.CurrAsmList.concat('+operline+');');
// Deallocate CPU registers
for i := 0 to opercnt-1 do
begin
tmp:=GetDeallocStatement(cnt, opers[i].typ);
if tmp<>'' then
fsecond.add(' '+tmp);
end;
fsecond.Add(' end;');
if target<>'' then
fsecond.add('{$endif}');
end;
// Write innr
writeln(fcinnr, ' in_', APrefix,'_',instrPart,postfix+_alias,' = in_',APrefix,'_mm_first+',intrnum,',');
writeln(fcpumminnr, ' fpc_in_', APrefix,'_',instrPart,postfix+_alias,' = fpc_in_',APrefix,'_mm_first+',intrnum,';');
// Write function
if target<>'' then
writeln(fprocs, '{$ifdef ',target,'}');
if hasOutput then write(fprocs,'function ') else write(fprocs,'procedure ');
write(fprocs,APrefix,'_',instrPart,postfix,'(');
cnt:=0;
for i:=0 to opercnt-1 do
begin
if opers[i].direction=operOut then
Continue;
if cnt>0 then
begin
if opers[i].typ<>opers[i-1].typ then
write(fprocs,': ',GetPascalType(opers[i-1].typ),'; ')
else
write(fprocs,', ');
end;
write(fprocs,opers[i].name);
if i=opercnt-1 then
write(fprocs,': ',GetPascalType(opers[i].typ));
inc(cnt);
end;
write(fprocs,')');
if hasOutput then write(fprocs,': ',GetPascalType(outputType));
writeln(fprocs,'; [INTERNPROC: fpc_in_',APrefix,'_',instrPart,postfix+_alias,'];');
if target<>'' then
writeln(fprocs, '{$endif}');
// Str now contains conditionals
inc(intrnum);
end;
writeln(fcinnr, ' in_', APrefix,'mm_last = in_',APrefix,'_mm_first+',intrnum-1);
ftypechk.SaveToFile(APrefix+'mmtype.inc');
ffirst.SaveToFile(APrefix+'mmfirst.inc');
fsecond.SaveToFile(APrefix+'mmsecond.inc');
ftypechk.Free;
ffirst.Free;
fsecond.Free;
CloseFile(fprocs);
CloseFile(fcinnr);
CloseFile(fcpumminnr);
closefile(f);
end;
begin
ParseList('x86', 'x86intr.dat');
end.