123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821 |
- 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.
|