mkx86inl.pp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821
  1. program mkx86inl;
  2. {$mode objfpc}
  3. {$H+}
  4. uses
  5. sysutils, classes;
  6. type
  7. TOperDirection = (operIn, operVar, operOut);
  8. TOperand = record
  9. name,
  10. typ: string;
  11. direction: TOperDirection;
  12. end;
  13. const
  14. DirLUT: array[TOperDirection] of string = ('','var ','out ');
  15. { ***************************************************************************
  16. the routines Copy2SymbDel, PosSetEx, PosSet, RemoveTrailingChars, TrimRightSet are copied and reformatted
  17. from StrUtils and thus covered by the copyright of strutils (see below) as compiler utilities cannot
  18. depend on packages
  19. This file is part of the Free Pascal run time library.
  20. Copyright (c) 1999-2005 by the Free Pascal development team
  21. See the file COPYING.FPC, included in this distribution,
  22. for details about the copyright.
  23. This program is distributed in the hope that it will be useful,
  24. but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  26. *************************************************************************** }
  27. function Copy2SymbDel(var S: string; Symb: Char): string;
  28. var
  29. p: SizeInt;
  30. begin
  31. p:=Pos(Symb,S);
  32. if p=0 then
  33. begin
  34. result:=s;
  35. s:='';
  36. end
  37. else
  38. begin
  39. Result:=Copy(S,1,p-1);
  40. delete(s,1,p);
  41. end;
  42. end;
  43. function PosSetEx(const c: TSysCharSet; const s: ansistring; count: Integer): SizeInt;
  44. var
  45. i,j:SizeInt;
  46. begin
  47. if pchar(pointer(s))=nil then
  48. j:=0
  49. else
  50. begin
  51. i:=length(s);
  52. j:=count;
  53. if j>i then
  54. begin
  55. result:=0;
  56. exit;
  57. end;
  58. while (j<=i) and (not (s[j] in c)) do inc(j);
  59. if (j>i) then
  60. j:=0; // not found.
  61. end;
  62. result:=j;
  63. end;
  64. function PosSet(const c: TSysCharSet; const s: ansistring): SizeInt;
  65. begin
  66. result:=possetex(c,s,1);
  67. end;
  68. procedure RemoveTrailingChars(VAR S: AnsiString; const CSet: TSysCharset);
  69. var
  70. I,J: LONGINT;
  71. Begin
  72. I:=Length(S);
  73. IF (I>0) Then
  74. Begin
  75. J:=I;
  76. While (j>0) and (S[J] IN CSet) DO DEC(J);
  77. IF J<>I Then
  78. SetLength(S,J);
  79. End;
  80. End;
  81. function TrimRightSet(const S: String; const CSet: TSysCharSet): String;
  82. begin
  83. result:=s;
  84. RemoveTrailingchars(result,cset);
  85. end;
  86. { ***************************************************************************
  87. end of StrUtils code
  88. ***************************************************************************}
  89. function GetPascalType(const ATyp: string): string;
  90. begin
  91. case ATyp of
  92. 'r8': exit('byte');
  93. 'rs8': exit('shortint');
  94. 'r16': exit('word');
  95. 'rs16': exit('smallint');
  96. 'r32': exit('longword');
  97. 'rs32': exit('longint');
  98. 'r64': exit('qword');
  99. 'rs64': exit('int64');
  100. 'reg': exit('NativeUInt');
  101. 'sreg': exit('NativeInt');
  102. 'f32': exit('single');
  103. 'f64': exit('double');
  104. 'mm': exit('__m64');
  105. 'implicit_xmm0',
  106. 'xmm': exit('__m128');
  107. 'i32': exit('longint');
  108. 'edi_ptr': exit('pointer');
  109. 'ptr8',
  110. 'ptr16',
  111. 'ptr32',
  112. 'ptr64',
  113. 'ptr128': exit('pointer');
  114. else
  115. exit(ATyp);
  116. end;
  117. end;
  118. function GetTypeDef(const ATyp: string): string;
  119. begin
  120. case ATyp of
  121. 'r8': exit('u8inttype');
  122. 'rs8': exit('s8inttype');
  123. 'r16': exit('u16inttype');
  124. 'rs16': exit('s16inttype');
  125. 'r32': exit('u32inttype');
  126. 'rs32': exit('s32inttype');
  127. 'r64': exit('u64inttype');
  128. 'rs64': exit('s64inttype');
  129. 'reg': exit('uinttype');
  130. 'sreg': exit('sinttype');
  131. 'f32': exit('s32floattype');
  132. 'f64': exit('s64floattype');
  133. 'mm': exit('x86_m64type');
  134. 'implicit_xmm0',
  135. 'xmm': exit('x86_m128type');
  136. 'i32': exit('s32inttype');
  137. 'edi_ptr': exit('voidpointertype');
  138. 'ptr8',
  139. 'ptr16',
  140. 'ptr32',
  141. 'ptr64',
  142. 'ptr128': exit('voidpointertype');
  143. else
  144. exit(ATyp);
  145. end;
  146. end;
  147. function GetOper(const ATyp: string): string;
  148. begin
  149. case ATyp of
  150. 'r8': exit('_reg');
  151. 'rs8': exit('_reg');
  152. 'r16': exit('_reg');
  153. 'rs16': exit('_reg');
  154. 'r32': exit('_reg');
  155. 'rs32': exit('_reg');
  156. 'r64': exit('_reg_reg');
  157. 'rs64': exit('_reg_reg');
  158. 'reg': exit('_reg');
  159. 'sreg': exit('_reg');
  160. 'f32': exit('_reg');
  161. 'f64': exit('_reg');
  162. 'mm': exit('_reg');
  163. 'xmm': exit('_reg');
  164. 'i32': exit('_const');
  165. 'implicit_xmm0',
  166. 'edi_ptr': exit('');
  167. 'ptr8',
  168. 'ptr16',
  169. 'ptr32',
  170. 'ptr64',
  171. 'ptr128': exit('_ref');
  172. else
  173. exit('');
  174. end;
  175. end;
  176. function GetOperand(const ATyp: string; AIndex: longint): string;
  177. begin
  178. case ATyp of
  179. 'r8': exit(format(',paraarray[%d].location.register', [AIndex]));
  180. 'rs8': exit(format(',paraarray[%d].location.register', [AIndex]));
  181. 'r16': exit(format(',paraarray[%d].location.register', [AIndex]));
  182. 'rs16': exit(format(',paraarray[%d].location.register', [AIndex]));
  183. 'r32': exit(format(',paraarray[%d].location.register', [AIndex]));
  184. 'rs32': exit(format(',paraarray[%d].location.register', [AIndex]));
  185. 'r64': exit(format(',paraarray[%d].location.register64.reglo,paraarray[%d].location.register64.reghi', [AIndex,AIndex]));
  186. 'rs64': exit(format(',paraarray[%d].location.register64.reglo,paraarray[%d].location.register64.reghi', [AIndex,AIndex]));
  187. 'reg': exit(format(',paraarray[%d].location.register', [AIndex]));
  188. 'sreg': exit(format(',paraarray[%d].location.register', [AIndex]));
  189. 'f32': exit(format(',paraarray[%d].location.register', [AIndex]));
  190. 'f64': exit(format(',paraarray[%d].location.register', [AIndex]));
  191. 'mm': exit(format(',paraarray[%d].location.register', [AIndex]));
  192. 'xmm': exit(format(',paraarray[%d].location.register', [AIndex]));
  193. 'i32': exit(format(',GetConstInt(paraarray[%d])',[AIndex]));
  194. 'implicit_xmm0',
  195. 'edi_ptr': exit('');
  196. 'ptr8',
  197. 'ptr16',
  198. 'ptr32',
  199. 'ptr64',
  200. 'ptr128': exit(format(',paraarray[%d].location.reference', [AIndex]));
  201. else
  202. exit(ATyp);
  203. end;
  204. end;
  205. function GetOperandLoc(const ATyp: string): string;
  206. begin
  207. result:='';
  208. case ATyp of
  209. 'r8': exit(',location.register');
  210. 'rs8': exit(',location.register');
  211. 'r16': exit(',location.register');
  212. 'rs16': exit(',location.register');
  213. 'r32': exit(',location.register');
  214. 'rs32': exit(',location.register');
  215. 'r64': exit(',location.register64.reglo,location.register64.reghi');
  216. 'rs64': exit(',location.register64.reglo,location.register64.reghi');
  217. 'reg': exit(',location.register');
  218. 'sreg': exit(',location.register');
  219. 'f32': exit(',location.register');
  220. 'f64': exit(',location.register');
  221. 'mm': exit(',location.register');
  222. 'implicit_xmm0',
  223. 'xmm': exit(',location.register');
  224. 'edi_ptr': exit(',location.register');
  225. 'ptr8',
  226. 'ptr16',
  227. 'ptr32',
  228. 'ptr64',
  229. 'ptr128': exit(',location.register');
  230. end;
  231. end;
  232. function GetLocStatement(AIndex: longint; const ATyp: string; AConst: boolean): string;
  233. begin
  234. result:='';
  235. case ATyp of
  236. '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')]));
  237. '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')]));
  238. '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')]));
  239. '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')]));
  240. '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')]));
  241. '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')]));
  242. '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')]));
  243. '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')]));
  244. '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')]));
  245. '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')]));
  246. 'f32': exit(format('location_force_mmreg(current_asmdata.CurrAsmList, paraarray[%d].location, %s);', [AIndex+1, BoolToStr(aconst,'true','false')]));
  247. 'f64': exit(format('location_force_mmreg(current_asmdata.CurrAsmList, paraarray[%d].location, %s);', [AIndex+1, BoolToStr(aconst,'true','false')]));
  248. 'mm': exit(format('location_force_mmxreg(current_asmdata.CurrAsmList, paraarray[%d].location, %s);', [AIndex+1, BoolToStr(aconst,'true','false')]));
  249. 'xmm': exit(format('location_force_mmreg(current_asmdata.CurrAsmList, paraarray[%d].location, %s);', [AIndex+1, BoolToStr(aconst,'true','false')]));
  250. 'implicit_xmm0':
  251. exit(format('location_force_mmreg(current_asmdata.CurrAsmList, paraarray[%d].location, %s);'+LineEnding+
  252. ' hlcg.getcpuregister(current_asmdata.CurrAsmList,NR_XMM0);'+LineEnding+
  253. ' hlcg.a_loadmm_loc_reg(current_asmdata.CurrAsmList,paraarray[%d].resultdef,x86_m128type,paraarray[%d].location,NR_XMM0,nil);',
  254. [AIndex+1, BoolToStr(aconst,'true','false'), AIndex+1, AIndex+1]));
  255. 'edi_ptr':
  256. exit(format('hlcg.getcpuregister(current_asmdata.CurrAsmList,{$if defined(cpu64bitalu)}NR_RDI{$else}NR_EDI{$endif});'+LineEnding+
  257. ' hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,paraarray[%d].resultdef,voidpointertype,paraarray[%d].location,{$if defined(cpu64bitalu)}NR_RDI{$else}NR_EDI{$endif});',
  258. [AIndex+1, AIndex+1]));
  259. 'ptr8',
  260. 'ptr16',
  261. 'ptr32',
  262. 'ptr64',
  263. 'ptr128':exit(format('location_make_ref(paraarray[%d].location);', [AIndex+1]));
  264. end;
  265. end;
  266. function GetDeallocStatement(AIndex: longint; const ATyp: string): string;
  267. begin
  268. result:='';
  269. case ATyp of
  270. 'implicit_xmm0':
  271. exit('hlcg.ungetcpuregister(current_asmdata.CurrAsmList,NR_XMM0);');
  272. 'edi_ptr':
  273. exit('hlcg.ungetcpuregister(current_asmdata.CurrAsmList,{$if defined(cpu64bitalu)}NR_RDI{$else}NR_EDI{$endif});');
  274. end;
  275. end;
  276. function GetLoc(const ATyp: string; AWithSize: boolean = true): string;
  277. begin
  278. result:='';
  279. if AWithSize then
  280. case ATyp of
  281. 'r8': exit('LOC_REGISTER,OS_8');
  282. 'rs8': exit('LOC_REGISTER,OS_S8');
  283. 'r16': exit('LOC_REGISTER,OS_16');
  284. 'rs16': exit('LOC_REGISTER,OS_S16');
  285. 'r32': exit('LOC_REGISTER,OS_32');
  286. 'rs32': exit('LOC_REGISTER,OS_S32');
  287. 'r64': exit('LOC_REGISTER,OS_64');
  288. 'rs64': exit('LOC_REGISTER,OS_S64');
  289. 'reg': exit('LOC_REGISTER,OS_INT');
  290. 'sreg': exit('LOC_REGISTER,OS_SINT');
  291. 'f32': exit('LOC_MMREGISTER,OS_M128');
  292. 'f64': exit('LOC_MMREGISTER,OS_M128');
  293. 'mm': exit('LOC_MMXREGISTER,OS_M64');
  294. 'implicit_xmm0',
  295. 'xmm': exit('LOC_MMREGISTER,OS_M128');
  296. 'edi_ptr': exit('LOC_REGISTER,OS_INT');
  297. 'ptr8': exit('LOC_MEM,OS_8');
  298. 'ptr16': exit('LOC_MEM,OS_16');
  299. 'ptr32': exit('LOC_MEM,OS_32');
  300. 'ptr64': exit('LOC_MEM,OS_64');
  301. 'ptr128':exit('LOC_MEM,OS_128');
  302. end
  303. else
  304. case ATyp of
  305. 'r8': exit('LOC_REGISTER');
  306. 'rs8': exit('LOC_REGISTER');
  307. 'r16': exit('LOC_REGISTER');
  308. 'rs16': exit('LOC_REGISTER');
  309. 'r32': exit('LOC_REGISTER');
  310. 'rs32': exit('LOC_REGISTER');
  311. 'r64': exit('LOC_REGISTER');
  312. 'rs64': exit('LOC_REGISTER');
  313. 'reg': exit('LOC_REGISTER');
  314. 'sreg': exit('LOC_REGISTER');
  315. 'f32': exit('LOC_MMREGISTER');
  316. 'f64': exit('LOC_MMREGISTER');
  317. 'mm': exit('LOC_MMXREGISTER');
  318. 'implicit_xmm0',
  319. 'xmm': exit('LOC_MMREGISTER');
  320. 'edi_ptr': exit('LOC_REGISTER');
  321. 'ptr8',
  322. 'ptr16',
  323. 'ptr32',
  324. 'ptr64',
  325. 'ptr128':exit('LOC_MEM');
  326. end;
  327. end;
  328. function GetLocAllocation(const ATyp: string): string;
  329. begin
  330. result:='';
  331. case ATyp of
  332. 'r8': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_8);');
  333. 'rs8': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_8);');
  334. 'r16': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_16);');
  335. 'rs16': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_16);');
  336. 'r32': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
  337. 'rs32': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
  338. 'r64': exit('location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList, OS_32); location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
  339. 'rs64': exit('location.register64.reglo:=cg.getintregister(current_asmdata.CurrAsmList, OS_32); location.register64.reghi:=cg.getintregister(current_asmdata.CurrAsmList, OS_32);');
  340. 'reg': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_INT);');
  341. 'sreg': exit('location.register:=cg.getintregister(current_asmdata.CurrAsmList, OS_INT);');
  342. 'f32': exit('location.register:=cg.getmmregister(current_asmdata.CurrAsmList, OS_M128);');
  343. 'f64': exit('location.register:=cg.getmmregister(current_asmdata.CurrAsmList, OS_M128);');
  344. 'mm': exit('location.register:=tcgx86(cg).getmmxregister(current_asmdata.CurrAsmList);');
  345. 'xmm': exit('location.register:=cg.getmmregister(current_asmdata.CurrAsmList, OS_M128);');
  346. end;
  347. end;
  348. function GetPostFix(const APF: string): string;
  349. begin
  350. if APF<>'' then
  351. result:='PF_'+APF
  352. else
  353. result:='PF_None';
  354. end;
  355. procedure ParseList(const APrefix, AFilename: string);
  356. var
  357. f: TextFile;
  358. fprocs,
  359. fcinnr, fcpumminnr: TextFile;
  360. ftypechk, ffirst, fsecond: TStringList;
  361. str,
  362. instrPart,postfix,_alias,
  363. params, operline: String;
  364. opers: array[0..7] of TOperand;
  365. opercnt: longint;
  366. hasOutput: boolean;
  367. outputType: string;
  368. cnt,
  369. i, intrnum: longint;
  370. tmp, condition, target: String;
  371. function ParseOperands(AIndex: longint = -1): string;
  372. var
  373. idx: LongInt;
  374. pt: Integer;
  375. c: Char;
  376. begin
  377. idx:=opercnt;
  378. params:=trim(params);
  379. if params='' then
  380. exit('');
  381. inc(opercnt);
  382. if pos('var ', params)=1 then
  383. begin
  384. opers[idx].direction:=operVar;
  385. Delete(params,1,4);
  386. params:=trim(params);
  387. hasOutput:=true;
  388. end
  389. else if pos('out ', params)=1 then
  390. begin
  391. opers[idx].direction:=operOut;
  392. Delete(params,1,4);
  393. params:=trim(params);
  394. hasOutput:=true;
  395. end
  396. else
  397. begin
  398. if AIndex<>-1 then
  399. opers[idx].direction:=opers[AIndex].direction
  400. else
  401. opers[idx].direction:=operIn;
  402. end;
  403. pt:=PosSet([',',':'], params);
  404. c:=params[pt];
  405. opers[idx].name:=Copy2SymbDel(params, c);
  406. params:=trim(params);
  407. if c = ':' then
  408. begin
  409. opers[idx].typ:=Copy2SymbDel(params, ';');
  410. result:=opers[idx].typ;
  411. end
  412. else
  413. begin
  414. opers[idx].typ:=ParseOperands(idx);
  415. result:=opers[idx].typ;
  416. end;
  417. if opers[idx].direction<>operIn then
  418. outputType:=opers[idx].typ;
  419. end;
  420. function GetOperLine: string;
  421. var
  422. i: longint;
  423. begin
  424. result:='';
  425. for i := 0 to opercnt-1 do
  426. result:=result+DirLUT[opers[i].direction]+opers[i].name+':'+opers[i].typ+';';
  427. end;
  428. function GetParams: longint;
  429. var
  430. i: longint;
  431. begin
  432. result:=0;
  433. for i := 0 to opercnt-1 do
  434. if opers[i].direction in [operIn,operVar] then
  435. inc(result);
  436. end;
  437. function FindOperIdx(const AOper: string): longint;
  438. var
  439. i,cnt: longint;
  440. begin
  441. cnt:=0;
  442. result:=0;
  443. for i := 0 to opercnt-1 do
  444. if (opers[i].direction in [operIn,operVar]) then
  445. begin
  446. if opers[i].name=AOper then
  447. exit(cnt);
  448. inc(cnt);
  449. end;
  450. end;
  451. begin
  452. intrnum:=0;
  453. assignfile(f, AFilename);
  454. reset(f);
  455. assignfile(fprocs, 'cpummprocs.inc'); rewrite(fprocs);
  456. assignfile(fcinnr, 'c'+APrefix+'mminnr.inc'); rewrite(fcinnr);
  457. assignfile(fcpumminnr, 'cpumminnr.inc'); rewrite(fcpumminnr);
  458. // writeln(finnr,'const');
  459. ftypechk:=TStringList.Create;
  460. ffirst:=TStringList.Create;
  461. fsecond:=TStringList.Create;
  462. // writeln(finnr, ' fpc_in_', APrefix,'_first = fpc_in_',APrefix,'_base;');
  463. while not EOF(f) do
  464. begin
  465. readln(f, str);
  466. str:=trim(str);
  467. if (str='') or (Pos(';',str)=1) then
  468. continue;
  469. instrPart:=Copy2SymbDel(str, '(');
  470. // Check for postfix
  471. if pos('{',instrPart)>0 then
  472. begin
  473. postfix:=instrPart;
  474. instrPart:=Copy2SymbDel(postfix, '{');
  475. postfix:=TrimRightSet(postfix,['}']);
  476. end
  477. else
  478. postfix:='';
  479. // Check for alias
  480. if pos('[',instrPart)>0 then
  481. begin
  482. _alias:=instrPart;
  483. instrPart:=Copy2SymbDel(_alias, '[');
  484. _alias:='_'+TrimRightSet(_alias,[']']);
  485. end
  486. else
  487. _alias:='';
  488. // Get parameters
  489. params:=trim(Copy2SymbDel(str,')'));
  490. str:=trim(str);
  491. // Parse condition and target
  492. if pos('|', str)>0 then
  493. begin
  494. condition:=trim(Copy2SymbDel(str, '|'));
  495. target:=trim(str);
  496. end
  497. else
  498. begin
  499. condition:=str;
  500. target:='';
  501. end;
  502. hasOutput:=false;
  503. opercnt:=0;
  504. outputType:='';
  505. while params<>'' do
  506. ParseOperands;
  507. operline:=GetOperLine;
  508. // Write typecheck code
  509. i:=ftypechk.IndexOf(': //'+operline);
  510. if (i>=0) and (target='') then
  511. ftypechk.Insert(i,',in_'+APrefix+'_'+instrPart+postfix+_alias)
  512. else
  513. begin
  514. if target<>'' then
  515. ftypechk.add(format('{$ifdef %s}', [target]));
  516. ftypechk.Add('in_'+APrefix+'_'+instrPart+postfix+_alias);
  517. ftypechk.Add(': //'+operline);
  518. ftypechk.Add(' begin');
  519. ftypechk.Add(' CheckParameters('+inttostr(GetParams())+');');
  520. if hasOutput then
  521. ftypechk.Add(' resultdef:='+GetTypeDef(outputType)+';')
  522. else
  523. ftypechk.Add(' resultdef:=voidtype;');
  524. ftypechk.Add(' end;');
  525. if target<>'' then
  526. ftypechk.add('{$endif}');
  527. end;
  528. // Write firstpass code
  529. i:=ffirst.IndexOf(': //'+operline);
  530. if (i>=0) and (target='') then
  531. ffirst.Insert(i,',in_'+APrefix+'_'+instrPart+postfix+_alias)
  532. else
  533. begin
  534. if target<>'' then
  535. ffirst.add(format('{$ifdef %s}', [target]));
  536. ffirst.Add('in_'+APrefix+'_'+instrPart+postfix+_alias);
  537. ffirst.Add(': //'+operline);
  538. ffirst.Add(' begin');
  539. if hasOutput then
  540. ffirst.Add(' expectloc:='+GetLoc(outputType,false)+';')
  541. else
  542. ffirst.Add(' expectloc:=LOC_VOID;');
  543. ffirst.Add(' result:=nil;');
  544. ffirst.Add(' end;');
  545. if target<>'' then
  546. ffirst.add('{$endif}');
  547. end;
  548. // Write secondpass code
  549. i:=fsecond.IndexOf(': //'+operline);
  550. if (i>=0) and (target='') then
  551. begin
  552. fsecond.Insert(i+3,' in_'+APrefix+'_'+instrPart+postfix+_alias+': begin op:=A_'+instrPart+' end;');
  553. fsecond.Insert(i,',in_'+APrefix+'_'+instrPart+postfix+_alias);
  554. end
  555. else
  556. begin
  557. if target<>'' then
  558. fsecond.add(format('{$ifdef %s}', [target]));
  559. fsecond.Add('in_'+APrefix+'_'+instrPart+postfix+_alias);
  560. fsecond.Add(': //'+operline);
  561. fsecond.Add(' begin');
  562. fsecond.Add(' case inlinenumber of');
  563. fsecond.Add(' in_'+APrefix+'_'+instrPart+postfix+_alias+': begin op:=A_'+instrPart+'; end;');
  564. fsecond.Add(' else');
  565. fsecond.Add(' Internalerror(2020010201);');
  566. fsecond.Add(' end;');
  567. fsecond.Add('');
  568. i:=GetParams;
  569. fsecond.Add(' GetParameters('+inttostr(i)+');');
  570. fsecond.Add('');
  571. fsecond.Add(' for i := 1 to '+inttostr(i)+' do secondpass(paraarray[i]);');
  572. fsecond.Add('');
  573. // Force inputs
  574. cnt:=0;
  575. for i := 0 to opercnt-1 do
  576. begin
  577. case opers[i].direction of
  578. operIn:
  579. begin
  580. tmp:=GetLocStatement(cnt, opers[i].typ, true);
  581. if tmp<>'' then
  582. fsecond.add(' '+tmp);
  583. inc(cnt);
  584. end;
  585. operVar:
  586. begin
  587. tmp:=GetLocStatement(cnt, opers[i].typ, false);
  588. if tmp<>'' then
  589. fsecond.add(' '+tmp);
  590. inc(cnt);
  591. end;
  592. else
  593. ;
  594. end;
  595. end;
  596. // Allocate output
  597. cnt:=0;
  598. for i := 0 to opercnt-1 do
  599. begin
  600. case opers[i].direction of
  601. operOut:
  602. begin
  603. fsecond.add(' location_reset(location,'+GetLoc(opers[i].typ)+');');
  604. fsecond.Add(' '+GetLocAllocation(opers[i].typ));
  605. end;
  606. operVar:
  607. begin
  608. fsecond.Add(' location:=paraarray['+inttostr(cnt+1)+'].location;');
  609. inc(cnt);
  610. end;
  611. operIn:
  612. inc(cnt);
  613. end;
  614. end;
  615. operline:='taicpu.op';
  616. //for i := 0 to opercnt-1 do
  617. for i := opercnt-1 downto 0 do
  618. begin
  619. case opers[i].direction of
  620. operOut:
  621. operline:=operline+GetOper(opers[i].typ);
  622. operVar:
  623. operline:=operline+GetOper(opers[i].typ);
  624. operIn:
  625. operline:=operline+GetOper(opers[i].typ);
  626. end;
  627. end;
  628. if operline='taicpu.op' then
  629. operline:='taicpu.op_none(op,S_NO'
  630. else
  631. operline:=operline+'(op,S_NO';
  632. //for i := 0 to opercnt-1 do
  633. for i := opercnt-1 downto 0 do
  634. begin
  635. case opers[i].direction of
  636. operOut:
  637. operline:=operline+GetOperandLoc(opers[i].typ);
  638. operIn,
  639. operVar:
  640. begin
  641. dec(cnt);
  642. operline:=operline+GetOperand(opers[i].typ, cnt+1);
  643. end;
  644. end;
  645. end;
  646. operline:=operline+')';
  647. fsecond.Add(' current_asmdata.CurrAsmList.concat('+operline+');');
  648. // Deallocate CPU registers
  649. for i := 0 to opercnt-1 do
  650. begin
  651. tmp:=GetDeallocStatement(cnt, opers[i].typ);
  652. if tmp<>'' then
  653. fsecond.add(' '+tmp);
  654. end;
  655. fsecond.Add(' end;');
  656. if target<>'' then
  657. fsecond.add('{$endif}');
  658. end;
  659. // Write innr
  660. writeln(fcinnr, ' in_', APrefix,'_',instrPart,postfix+_alias,' = in_',APrefix,'_mm_first+',intrnum,',');
  661. writeln(fcpumminnr, ' fpc_in_', APrefix,'_',instrPart,postfix+_alias,' = fpc_in_',APrefix,'_mm_first+',intrnum,';');
  662. // Write function
  663. if target<>'' then
  664. writeln(fprocs, '{$ifdef ',target,'}');
  665. if hasOutput then write(fprocs,'function ') else write(fprocs,'procedure ');
  666. write(fprocs,APrefix,'_',instrPart,postfix,'(');
  667. cnt:=0;
  668. for i:=0 to opercnt-1 do
  669. begin
  670. if opers[i].direction=operOut then
  671. Continue;
  672. if cnt>0 then
  673. begin
  674. if opers[i].typ<>opers[i-1].typ then
  675. write(fprocs,': ',GetPascalType(opers[i-1].typ),'; ')
  676. else
  677. write(fprocs,', ');
  678. end;
  679. write(fprocs,opers[i].name);
  680. if i=opercnt-1 then
  681. write(fprocs,': ',GetPascalType(opers[i].typ));
  682. inc(cnt);
  683. end;
  684. write(fprocs,')');
  685. if hasOutput then write(fprocs,': ',GetPascalType(outputType));
  686. writeln(fprocs,'; [INTERNPROC: fpc_in_',APrefix,'_',instrPart,postfix+_alias,'];');
  687. if target<>'' then
  688. writeln(fprocs, '{$endif}');
  689. // Str now contains conditionals
  690. inc(intrnum);
  691. end;
  692. writeln(fcinnr, ' in_', APrefix,'mm_last = in_',APrefix,'_mm_first+',intrnum-1);
  693. ftypechk.SaveToFile(APrefix+'mmtype.inc');
  694. ffirst.SaveToFile(APrefix+'mmfirst.inc');
  695. fsecond.SaveToFile(APrefix+'mmsecond.inc');
  696. ftypechk.Free;
  697. ffirst.Free;
  698. fsecond.Free;
  699. CloseFile(fprocs);
  700. CloseFile(fcinnr);
  701. CloseFile(fcpumminnr);
  702. closefile(f);
  703. end;
  704. begin
  705. ParseList('x86', 'x86intr.dat');
  706. end.