mkx86inl.pp 24 KB

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