1 {
2 
3   Copyright (C) <avx-testfile-generator> <Torsten Grundke>
4 
5   This source is free software; you can redistribute it and/or modify it under
6   the terms of the GNU General Public License as published by the Free
7   Software Foundation; either version 2 of the License, or (at your option)
8   any later version.
9 
10   This code is distributed in the hope that it will be useful, but WITHOUT ANY
11   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
13   details.
14 
15   A copy of the GNU General Public License is available on the World Wide Web
16   at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
17   to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18   MA 02110-1301, USA.
19 }
20 
21 {$mode objfpc}
22 
23 unit asmtestgenerator;
24 
25 interface
26 
27 uses BaseList, Classes;
28 
29 type
30   TOpType = (otUnknown, otXMMReg, otXMMRM, otXMMRM16, otXMMRM8, otYMMReg, otYMMRM, otEAX, otRAX, otMem32,
31              otMem8, otMem16, otMem64, otMem128, otMem256, otREG64, otREG32, otRM32, otRM64, otIMM8,
32              otXMEM32, otXMEM64, otYMEM32, otYMEM64);
33 
34   TOperandListItem = class(TObject)
35   private
36     FOpActive: boolean;
37     FOpNumber: integer;
38     FOpTyp: TOpType;
39     FValues: TStringList;
40   public
41     constructor Create;
42     destructor Destroy; override;
43 
44     property OpNumber: integer read FOpNumber write FOpNumber;
45     property OpTyp: TOpType read FOpTyp write FOpTyp;
46     property OpActive: boolean read FOpActive write FOpActive;
47 
48     property Values: TStringList read FValues;
49   end;
50 
51   TOperandList = class(TBaseList)
52   private
GetItemsnull53     function GetItems(aIndex: integer): TOperandListItem;
54 
55   public
Addnull56     function Add(aItem: TOperandListItem): integer;
57 
58     property Items[aIndex: integer]: TOperandListItem read GetItems;
59   end;
60 
61 
62   { TAsmTestGenerator }
63 
64   TAsmTestGenerator = class(TObject)
65   private
66     FReg32Base     : TStringList;
67     FReg32Index    : TStringList;
68     FReg64Base     : TStringList;
69     FReg64Index    : TStringList;
70     FReg6432Base   : TStringList;
71     FReg6432Index  : TStringList;
72     FReg32XMMIndex : TStringList;
73     FReg32YMMIndex : TStringList;
74     FReg64XMMIndex : TStringList;
75     FReg64YMMIndex : TStringList;
76 
77     Fx64: boolean;
78 
79     procedure MemRegBaseIndexCombi(const aPrefix: String; aSLBaseReg, aSLIndexReg, aRList: TStringList);
80     procedure VectorMemRegBaseIndexCombi(const aPrefix: String; aSLBaseReg, aSLIndexReg, aRList: TStringList);
81 
InternalCalcTestDatanull82     function InternalCalcTestData(const aInst, aOp1, aOp2, aOp3, aOp4: String): TStringList;
83   public
84     constructor Create;
85     destructor Destroy; override;
86 
87     class procedure CalcTestData(aX64: boolean; const aInst, aOp1, aOp2, aOp3, aOp4: String; aSL: TStringList);
88 
89     property x64: boolean read Fx64;
90   end;
91 
92 implementation
93 
94 uses SysUtils, Dialogs;
95 
96 { TOperandListItem }
97 
98 constructor TOperandListItem.Create;
99 begin
100   inherited;
101 
102   FOpActive := false;
103   FOpNumber := -1;
104   FOpTyp    := otUnknown;
105   FValues := TStringList.Create;
106 end;
107 
108 destructor TOperandListItem.Destroy;
109 begin
110   FreeAndNil(FValues);
111   inherited;
112 end;
113 
114 { TOperandList }
115 
Addnull116 function TOperandList.Add(aItem: TOperandListItem): integer;
117 begin
118   result := FList.Add(aItem);
119 end;
120 
TOperandList.GetItemsnull121 function TOperandList.GetItems(aIndex: integer): TOperandListItem;
122 begin
123   result := TOperandListItem(FList[aIndex]);
124 end;
125 
126 { TAsmTestGenerator }
127 
InternalCalcTestDatanull128 function TAsmTestGenerator.InternalCalcTestData(const aInst, aOp1, aOp2, aOp3,
129   aOp4: String): TStringList;
130 var
131   Item: TOperandListItem;
132   OItem1: TOperandListItem;
133   OItem2: TOperandListItem;
134   OItem3: TOperandListItem;
135   OItem4: TOperandListItem;
136 
137   il_Op: integer;
138   il_Op1: integer;
139   il_Op2: integer;
140   il_Op3: integer;
141   il_Op4: integer;
142 
143   sl_Operand: String;
144   sl_Inst   : String;
145   sl_RegCombi: String;
146   sl_Prefix: String;
147   UsePrefix: boolean;
148   il_Operands: integer;
149   UsedParams: cardinal;
150   UseDefault: boolean;
151   sl_RegCombi1: string;
152   sl_RegCombi2: string;
153   sl_RegCombi3: string;
154 
PrepareOperandTypnull155   function PrepareOperandTyp(const aTyp: String): String;
156   begin
157     result := aTyp;
158     if copy(result, length(result), 1) = '*' then result := copy(result, 1, length(result) - 1);
159     if result = 'XMMRM128' then result := 'XMMRM';
160     if result = 'YMMRM256' then result := 'YMMRM';
161   end;
162 
163 
164 begin
165   result := TStringList.Create;
166 
167   OItem1 := TOperandListItem.Create;
168   try
169     OItem2 := TOperandListItem.Create;
170     try
171       OItem3 := TOperandListItem.Create;
172       try
173         OItem4 := TOperandListItem.Create;
174         try
175 
176           UsePrefix := (aInst = 'VCVTPD2DQ') OR
177                        (aInst = 'VCVTPD2PS') OR
178                        (aInst = 'VCVTSI2SD') OR
179                        (aInst = 'VCVTSI2SS') OR
180                        (aInst = 'VCVTTPD2DQ');
181 
182           for il_Op := 1 to 4 do
183           begin
184             sl_Prefix := '';
185 
186             case il_Op of
187               1: begin
188                    Item := OItem1;
189                    sl_Operand := aOp1;
190                  end;
191               2: begin
192                    Item := OItem2;
193                    sl_Operand := aOp2;
194                  end;
195               3: begin
196                    Item := OItem3;
197                    sl_Operand := aOp3;
198                  end;
199               4: begin
200                    Item := OItem4;
201                    sl_Operand := aOp4;
202                  end;
203             end;
204 
205             sl_Operand := PrepareOperandTyp(sl_Operand);
206 
207             if AnsiSameText(sl_Operand, 'XMMREG') then
208             begin
209               Item.OpNumber := il_Op;
210               Item.OpTyp    := otXMMReg;
211               Item.OpActive := true;
212 
213               Item.Values.Add('XMM0');
214               Item.Values.Add('XMM1');
215               Item.Values.Add('XMM2');
216               Item.Values.Add('XMM3');
217               Item.Values.Add('XMM4');
218               Item.Values.Add('XMM5');
219               Item.Values.Add('XMM6');
220               Item.Values.Add('XMM7');
221 
222               if x64 then
223               begin
224                 if aOp4 <> 'XMMREG' then
225                 begin
226                   Item.Values.Add('XMM8');
227                   Item.Values.Add('XMM9');
228                   Item.Values.Add('XMM10');
229                   Item.Values.Add('XMM11');
230                   Item.Values.Add('XMM12');
231                   Item.Values.Add('XMM13');
232                   Item.Values.Add('XMM14');
233                   Item.Values.Add('XMM15');
234                 end
235                 else
236                 begin
237                   Item.Values.Clear;
238 
239                   Item.Values.Add('XMM0');
240                   Item.Values.Add('XMM7');
241                   Item.Values.Add('XMM8');
242                   Item.Values.Add('XMM15');
243                 end;
244               end;
245             end
246             else if AnsiSameText(sl_Operand, 'XMMRM') then
247             begin
248               Item.OpNumber := il_Op;
249               Item.OpTyp    := otXMMRM;
250               Item.OpActive := true;
251 
252               if UsePrefix then sl_Prefix := 'oword ';
253 
254               Item.Values.Add('XMM0');
255               Item.Values.Add('XMM1');
256               Item.Values.Add('XMM2');
257               Item.Values.Add('XMM3');
258               Item.Values.Add('XMM4');
259               Item.Values.Add('XMM5');
260               Item.Values.Add('XMM6');
261               Item.Values.Add('XMM7');
262 
263               if x64 then
264               begin
265                 Item.Values.Add('XMM8');
266                 Item.Values.Add('XMM9');
267                 Item.Values.Add('XMM10');
268                 Item.Values.Add('XMM11');
269                 Item.Values.Add('XMM12');
270                 Item.Values.Add('XMM13');
271                 Item.Values.Add('XMM14');
272                 Item.Values.Add('XMM15');
273 
274                 //Item.Values.Add('[RIP]');
275                 //Item.Values.Add('[RIP + 16]');
276 
277                 MemRegBaseIndexCombi(sl_Prefix, FReg64Base, FReg64Index, Item.Values);
278                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
279               end
280               else
281               begin
282                 MemRegBaseIndexCombi(sl_Prefix, FReg32Base, FReg32Index, Item.Values);
283               end;
284             end
285             else if AnsiSameText(sl_Operand, 'XMMRM8') then
286             begin
287               Item.OpNumber := il_Op;
288               Item.OpTyp    := otXMMRM8;
289               Item.OpActive := true;
290 
291               if UsePrefix then sl_Prefix := 'byte ';
292 
293               Item.Values.Add('XMM0');
294               Item.Values.Add('XMM1');
295               Item.Values.Add('XMM2');
296               Item.Values.Add('XMM3');
297               Item.Values.Add('XMM4');
298               Item.Values.Add('XMM5');
299               Item.Values.Add('XMM6');
300               Item.Values.Add('XMM7');
301 
302               if x64 then
303               begin
304                 Item.Values.Add('XMM8');
305                 Item.Values.Add('XMM9');
306                 Item.Values.Add('XMM10');
307                 Item.Values.Add('XMM11');
308                 Item.Values.Add('XMM12');
309                 Item.Values.Add('XMM13');
310                 Item.Values.Add('XMM14');
311                 Item.Values.Add('XMM15');
312 
313                 //Item.Values.Add('[RIP]');
314                 //Item.Values.Add('[RIP + 16]');
315 
316                 MemRegBaseIndexCombi(sl_Prefix, FReg64Base, FReg64Index, Item.Values);
317                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
318               end
319               else
320               begin
321                 MemRegBaseIndexCombi(sl_Prefix, FReg32Base, FReg32Index, Item.Values);
322               end;
323             end
324             else if AnsiSameText(sl_Operand, 'XMMRM16') then
325             begin
326               Item.OpNumber := il_Op;
327               Item.OpTyp    := otXMMRM16;
328               Item.OpActive := true;
329 
330               if UsePrefix then sl_Prefix := 'word ';
331 
332               Item.Values.Add('XMM0');
333               Item.Values.Add('XMM1');
334               Item.Values.Add('XMM2');
335               Item.Values.Add('XMM3');
336               Item.Values.Add('XMM4');
337               Item.Values.Add('XMM5');
338               Item.Values.Add('XMM6');
339               Item.Values.Add('XMM7');
340 
341               if x64 then
342               begin
343                 Item.Values.Add('XMM8');
344                 Item.Values.Add('XMM9');
345                 Item.Values.Add('XMM10');
346                 Item.Values.Add('XMM11');
347                 Item.Values.Add('XMM12');
348                 Item.Values.Add('XMM13');
349                 Item.Values.Add('XMM14');
350                 Item.Values.Add('XMM15');
351 
352                 //Item.Values.Add('[RIP]');
353                 //Item.Values.Add('[RIP + 16]');
354 
355                 MemRegBaseIndexCombi(sl_prefix, FReg64Base, FReg64Index, Item.Values);
356                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
357               end
358               else
359               begin
360                 MemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32Index, Item.Values);
361               end;
362             end
363             else if AnsiSameText(sl_Operand, 'YMMREG') then
364             begin
365               Item.OpNumber := il_Op;
366               Item.OpTyp    := otYMMReg;
367               Item.OpActive := true;
368 
369               Item.Values.Add('YMM0');
370               Item.Values.Add('YMM1');
371               Item.Values.Add('YMM2');
372               Item.Values.Add('YMM3');
373               Item.Values.Add('YMM4');
374               Item.Values.Add('YMM5');
375               Item.Values.Add('YMM6');
376               Item.Values.Add('YMM7');
377 
378               if x64 then
379               begin
380                 if aOp4 <> 'YMMREG' then
381                 begin
382                   Item.Values.Add('YMM8');
383                   Item.Values.Add('YMM9');
384                   Item.Values.Add('YMM10');
385                   Item.Values.Add('YMM11');
386                   Item.Values.Add('YMM12');
387                   Item.Values.Add('YMM13');
388                   Item.Values.Add('YMM14');
389                   Item.Values.Add('YMM15');
390                 end
391                 else
392                 begin
393                   Item.Values.Clear;
394 
395                   Item.Values.Add('YMM0');
396                   Item.Values.Add('YMM7');
397                   Item.Values.Add('YMM8');
398                   Item.Values.Add('YMM15');
399                 end;
400               end;
401             end
402             else if AnsiSameText(sl_Operand, 'YMMRM') then
403             begin
404               Item.OpNumber := il_Op;
405               Item.OpTyp    := otYMMRM;
406               Item.OpActive := true;
407 
408               if UsePrefix then sl_Prefix := 'yword ';
409 
410               Item.Values.Add('YMM0');
411               Item.Values.Add('YMM1');
412               Item.Values.Add('YMM2');
413               Item.Values.Add('YMM3');
414               Item.Values.Add('YMM4');
415               Item.Values.Add('YMM5');
416               Item.Values.Add('YMM6');
417               Item.Values.Add('YMM7');
418 
419               if x64 then
420               begin
421                 Item.Values.Add('YMM8');
422                 Item.Values.Add('YMM9');
423                 Item.Values.Add('YMM10');
424                 Item.Values.Add('YMM11');
425                 Item.Values.Add('YMM12');
426                 Item.Values.Add('YMM13');
427                 Item.Values.Add('YMM14');
428                 Item.Values.Add('YMM15');
429 
430                 MemRegBaseIndexCombi(sl_prefix, FReg64Base, FReg64Index, Item.Values);
431                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
432               end
433               else
434               begin
435                 MemRegBaseIndexCombi(sl_Prefix, FReg32Base, FReg32Index, Item.Values);
436               end;
437             end
438             else if AnsiSameText(sl_Operand, 'MEM8') then
439             begin
440               Item.OpNumber := il_Op;
441               Item.OpTyp    := otMEM8;
442               Item.OpActive := true;
443 
444               if UsePrefix then sl_Prefix := 'byte ';
445 
446               if x64 then
447               begin
448                 MemRegBaseIndexCombi(sl_Prefix, FReg64Base, FReg64Index, Item.Values);
449                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
450               end
451               else MemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32Index, Item.Values);
452             end
453             else if AnsiSameText(sl_Operand, 'MEM16') then
454             begin
455               Item.OpNumber := il_Op;
456               Item.OpTyp    := otMEM16;
457               Item.OpActive := true;
458 
459               if UsePrefix then sl_Prefix := 'word ';
460 
461               if x64 then
462               begin
463                 MemRegBaseIndexCombi(sl_Prefix, FReg64Base, FReg64Index, Item.Values);
464                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
465               end
466               else MemRegBaseIndexCombi(sl_Prefix, FReg32Base, FReg32Index, Item.Values);
467             end
468             else if AnsiSameText(sl_Operand, 'MEM32') then
469             begin
470               Item.OpNumber := il_Op;
471               Item.OpTyp    := otMEM32;
472               Item.OpActive := true;
473 
474               if UsePrefix then sl_Prefix := 'dword ';
475 
476               if x64 then
477               begin
478                 MemRegBaseIndexCombi(sl_prefix, FReg64Base, FReg64Index, Item.Values);
479                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
480               end
481               else MemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32Index, Item.Values);
482             end
483             else if AnsiSameText(sl_Operand, 'MEM64') then
484             begin
485               Item.OpNumber := il_Op;
486               Item.OpTyp    := otMEM64;
487               Item.OpActive := true;
488 
489               if UsePrefix then sl_Prefix := 'qword ';
490 
491               if x64 then
492               begin
493                 MemRegBaseIndexCombi(sl_Prefix, FReg64Base, FReg64Index, Item.Values);
494                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
495               end
496               else MemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32Index, Item.Values);
497             end
498             else if AnsiSameText(sl_Operand, 'MEM128') then
499             begin
500               Item.OpNumber := il_Op;
501               Item.OpTyp    := otMEM128;
502               Item.OpActive := true;
503 
504               if UsePrefix then sl_Prefix := 'oword ';
505 
506               if x64 then
507               begin
508                 MemRegBaseIndexCombi(sl_prefix, FReg64Base, FReg64Index, Item.Values);
509                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
510               end
511               else MemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32Index, Item.Values);
512             end
513             else if AnsiSameText(sl_Operand, 'MEM256') then
514             begin
515               Item.OpNumber := il_Op;
516               Item.OpTyp    := otMEM256;
517               Item.OpActive := true;
518 
519               if UsePrefix then sl_Prefix := 'yword ';
520 
521               if x64 then
522               begin
523                 MemRegBaseIndexCombi(sl_prefix, FReg64Base, FReg64Index, Item.Values);
524                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
525               end
526               else MemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32Index, Item.Values);
527             end
528             else if AnsiSameText(sl_Operand, 'REG32') then
529             begin
530               Item.OpNumber := il_Op;
531               Item.OpTyp    := otREG32;
532               Item.OpActive := true;
533 
534               if x64 then
535               begin
536                 Item.Values.AddStrings(FReg32Base);
537               end
538               else Item.Values.AddStrings(FReg32Base);
539             end
540             else if AnsiSameText(sl_Operand, 'REG64') then
541             begin
542               Item.OpNumber := il_Op;
543               Item.OpTyp    := otREG64;
544               Item.OpActive := true;
545 
546               if x64 then
547               begin
548                 Item.Values.AddStrings(FReg64Base);
549               end;
550             end
551             else if AnsiSameText(sl_Operand, 'RM32') then
552             begin
553               Item.OpNumber := il_Op;
554               Item.OpTyp    := otRM32;
555               Item.OpActive := true;
556 
557               Item.Values.AddStrings(FReg32Base);
558 
559               if UsePrefix then sl_Prefix := 'dword ';
560 
561               if x64 then
562               begin
563                 MemRegBaseIndexCombi(sl_Prefix, FReg64Base, FReg64Index, Item.Values);
564                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
565               end
566               else MemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32Index, Item.Values);
567             end
568             else if AnsiSameText(sl_Operand, 'RM64') then
569             begin
570               Item.OpNumber := il_Op;
571               Item.OpTyp    := otRM32;
572               Item.OpActive := true;
573 
574 
575 
576               if UsePrefix then sl_Prefix := 'qword ';
577 
578               if x64 then
579               begin
580                 Item.Values.AddStrings(FReg64Base);
581                 MemRegBaseIndexCombi(sl_Prefix, FReg64Base, FReg64Index, Item.Values);
582                 //MemRegBaseIndexCombi(FReg6432Base, FReg6432Index, Item.Values);
583               end
584               else MemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32Index, Item.Values);
585             end
586             else if AnsiSameText(sl_Operand, 'IMM8') then
587             begin
588               Item.OpNumber := il_Op;
589               Item.OpTyp    := otIMM8;
590               Item.OpActive := true;
591 
592               Item.Values.Add('0');
593             end
594             else if AnsiSameText(sl_Operand, 'XMEM32') then
595             begin
596               Item.OpNumber := il_Op;
597               Item.OpTyp    := otXMEM32;
598               Item.OpActive := true;
599 
600               if UsePrefix then sl_Prefix := 'oword ';
601 
602               if x64 then
603               begin
604                 VectorMemRegBaseIndexCombi(sl_prefix, FReg64Base, FReg64XMMIndex, Item.Values);
605               end
606               else
607               begin
608                 VectorMemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32XMMIndex, Item.Values);
609               end;
610             end
611             else if AnsiSameText(sl_Operand, 'XMEM64') then
612             begin
613               Item.OpNumber := il_Op;
614               Item.OpTyp    := otXMEM64;
615               Item.OpActive := true;
616 
617               if UsePrefix then sl_Prefix := 'oword ';
618 
619               if x64 then
620               begin
621                 VectorMemRegBaseIndexCombi(sl_prefix, FReg64Base, FReg64XMMIndex, Item.Values);
622               end
623               else
624               begin
625                 VectorMemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32XMMIndex, Item.Values);
626               end;
627             end
628             else if AnsiSameText(sl_Operand, 'YMEM32') then
629             begin
630               Item.OpNumber := il_Op;
631               Item.OpTyp    := otYMEM32;
632               Item.OpActive := true;
633 
634               if UsePrefix then sl_Prefix := 'yword ';
635 
636               if x64 then
637               begin
638                 VectorMemRegBaseIndexCombi(sl_prefix, FReg64Base, FReg64YMMIndex, Item.Values);
639               end
640               else
641               begin
642                 VectorMemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32YMMIndex, Item.Values);
643               end;
644             end
645             else if AnsiSameText(sl_Operand, 'YMEM64') then
646             begin
647               Item.OpNumber := il_Op;
648               Item.OpTyp    := otYMEM64;
649               Item.OpActive := true;
650 
651               if UsePrefix then sl_Prefix := 'yword ';
652 
653               if x64 then
654               begin
655                 VectorMemRegBaseIndexCombi(sl_prefix, FReg64Base, FReg64YMMIndex, Item.Values);
656               end
657               else
658               begin
659                 VectorMemRegBaseIndexCombi(sl_prefix, FReg32Base, FReg32YMMIndex, Item.Values);
660               end;
661             end
662 
663 
664             else
665             begin
666               Item.OpNumber := il_Op;
667               Item.OpTyp    := otUnknown;
668               Item.OpActive := false;
669 
670               Item.Values.Add('');
671             end
672 
673           end;
674 
675           sl_RegCombi := '';
676 
677 
678           il_Operands := 0;
679           UsedParams  := 0;
680 
681           if OItem1.OpActive then
682           begin
683             inc(il_Operands);
684             UsedParams := UsedParams or 1;
685           end;
686 
687           if OItem2.OpActive then
688           begin
689             inc(il_Operands);
690             UsedParams := UsedParams or 2;
691           end;
692 
693           if OItem3.OpActive then
694           begin
695             inc(il_Operands);
696             UsedParams := UsedParams or 4;
697           end;
698 
699           if OItem4.OpActive then
700           begin
701             inc(il_Operands);
702             UsedParams := UsedParams or 8;
703           end;
704 
705           case il_Operands of
706               1: UseDefault := UsedParams <> 1;
707               2: UseDefault := UsedParams <> 3;
708               3: UseDefault := UsedParams <> 7;
709               4: UseDefault := UsedParams <> 15;
710             else UseDefault := true;
711           end;
712 
713           //UseDefault := true;
714 
715           if UseDefault then
716           begin
717             sl_Inst := format('%-20s', [aInst]);
718 
719             for il_Op1 := 0 to OItem1.Values.Count - 1 do
720             begin
721               for il_Op2 := 0 to OItem2.Values.Count - 1 do
722               begin
723                 for il_Op3 := 0 to OItem3.Values.Count - 1 do
724                 begin
725                   for il_Op4 := 0 to OItem4.Values.Count - 1 do
726                   begin
727                     sl_RegCombi := '';
728 
729                     if OItem1.OpActive then
730                     begin
731                       if sl_RegCombi <> '' then sl_RegCombi := sl_RegCombi + ', ';
732                       sl_RegCombi := sl_RegCombi + OItem1.Values[il_Op1];
733                     end;
734 
735                     if OItem2.OpActive then
736                     begin
737                       if sl_RegCombi <> '' then sl_RegCombi := sl_RegCombi + ', ';
738                       sl_RegCombi := sl_RegCombi + OItem2.Values[il_Op2];
739                     end;
740 
741                     if OItem3.OpActive then
742                     begin
743                       if sl_RegCombi <> '' then sl_RegCombi := sl_RegCombi + ', ';
744                       sl_RegCombi := sl_RegCombi + OItem3.Values[il_Op3];
745                     end;
746 
747                     if OItem4.OpActive then
748                     begin
749                       if sl_RegCombi <> '' then sl_RegCombi := sl_RegCombi + ', ';
750                       sl_RegCombi := sl_RegCombi + OItem4.Values[il_Op4];
751                     end;
752 
753                     if sl_RegCombi <> '' then
754                     begin
755                       //result.Add(format('%-20s%s', [aInst, sl_RegCombi]));
756                       result.Add(sl_Inst + sl_RegCombi);
757                       sl_RegCombi := '';
758                     end;
759                   end;
760                 end;
761               end;
762             end;
763           end
764           else
765           begin
766             sl_Inst := format('%-20s', [aInst]);
767 
768             for il_Op1 := 0 to OItem1.Values.Count - 1 do
769             begin
770               if OItem1.OpActive then
771               begin
772                 sl_RegCombi1 := OItem1.Values[il_Op1];
773               end
774               else sl_RegCombi1 := '';
775 
776               for il_Op2 := 0 to OItem2.Values.Count - 1 do
777               begin
778                 if OItem2.OpActive then
779                 begin
780                   sl_RegCombi2 := sl_RegCombi1 + ', ' + OItem2.Values[il_Op2];
781                 end
782                 else sl_RegCombi2 := sl_RegCombi1;
783 
784                 for il_Op3 := 0 to OItem3.Values.Count - 1 do
785                 begin
786                   if OItem3.OpActive then
787                   begin
788                     sl_RegCombi3 := sl_RegCombi2 + ', ' + OItem3.Values[il_Op3];
789                   end
790                   else sl_RegCombi3 := sl_RegCombi2;
791 
792                   for il_Op4 := 0 to OItem4.Values.Count - 1 do
793                   begin
794                     if OItem4.OpActive then
795                     begin
796                       sl_RegCombi := sl_RegCombi3 + ', ' + OItem4.Values[il_Op4];
797                     end
798                     else sl_RegCombi := sl_RegCombi3;
799 
800                     if sl_RegCombi <> '' then
801                     begin
802                       //result.Add(format('%-20s%s', [aInst, sl_RegCombi]));
803                       result.Add(sl_Inst + sl_RegCombi);
804                       sl_RegCombi := '';
805                     end;
806                   end;
807                 end;
808               end;
809             end;
810           end;
811         finally
812           FreeAndNil(OItem4);
813         end;
814       finally
815         FreeAndNil(OItem3);
816       end;
817     finally
818       FreeAndNil(OItem2);
819     end;
820   finally
821     FreeAndNil(OItem1);
822   end;
823 end;
824 
825 constructor TAsmTestGenerator.Create;
826 begin
827   inherited;
828 
829   FX64 := true;
830 
831   FReg32Base     := TStringList.Create;
832   FReg32Index    := TStringList.Create;
833   FReg64Base     := TStringList.Create;
834   FReg64Index    := TStringList.Create;
835   FReg6432Base   := TStringList.Create;
836   FReg6432Index  := TStringList.Create;
837   FReg32XMMIndex := TStringList.Create;
838   FReg32YMMIndex := TStringList.Create;
839   FReg64XMMIndex := TStringList.Create;
840   FReg64YMMIndex := TStringList.Create;
841 
842 
843   FReg32Base.Add('EAX');
844   FReg32Base.Add('EBX');
845   FReg32Base.Add('ECX');
846   FReg32Base.Add('EDX');
847   FReg32Base.Add('ESP');
848   FReg32Base.Add('EBP');
849   FReg32Base.Add('EDI');
850   FReg32Base.Add('ESI');
851 
852 
853   FReg32Index.Add('EAX');
854   FReg32Index.Add('EBX');
855   FReg32Index.Add('ECX');
856   FReg32Index.Add('EDX');
857   FReg32Index.Add('EBP');
858   FReg32Index.Add('EDI');
859   FReg32Index.Add('ESI');
860 
861 
862   FReg64Base.Add('RAX');
863   FReg64Base.Add('RBX');
864   FReg64Base.Add('RCX');
865   FReg64Base.Add('RDX');
866   FReg64Base.Add('RSP');
867   FReg64Base.Add('RBP');
868   FReg64Base.Add('RDI');
869   FReg64Base.Add('RSI');
870   FReg64Base.Add('R8');
871   FReg64Base.Add('R9');
872   FReg64Base.Add('R10');
873   FReg64Base.Add('R11');
874   FReg64Base.Add('R12');
875   FReg64Base.Add('R13');
876   FReg64Base.Add('R14');
877   FReg64Base.Add('R15');
878 
879   FReg64Index.Add('RAX');
880   FReg64Index.Add('RBX');
881   FReg64Index.Add('RCX');
882   FReg64Index.Add('RDX');
883   FReg64Index.Add('RBP');
884   FReg64Index.Add('RDI');
885   FReg64Index.Add('RSI');
886   FReg64Index.Add('R8');
887   FReg64Index.Add('R9');
888   FReg64Index.Add('R10');
889   FReg64Index.Add('R11');
890   FReg64Index.Add('R12');
891   FReg64Index.Add('R13');
892   FReg64Index.Add('R14');
893   FReg64Index.Add('R15');
894 
895   FReg6432Base.Add('EAX');
896   FReg6432Base.Add('EBX');
897   FReg6432Base.Add('ECX');
898   FReg6432Base.Add('EDX');
899   FReg6432Base.Add('ESP');
900   FReg6432Base.Add('EBP');
901   FReg6432Base.Add('EDI');
902   FReg6432Base.Add('ESI');
903   FReg6432Base.Add('R8D');
904   FReg6432Base.Add('R9D');
905   FReg6432Base.Add('R10D');
906   FReg6432Base.Add('R11D');
907   FReg6432Base.Add('R12D');
908   FReg6432Base.Add('R13D');
909   FReg6432Base.Add('R14D');
910   FReg6432Base.Add('R15D');
911 
912   FReg6432Index.Add('EAX');
913   FReg6432Index.Add('EBX');
914   FReg6432Index.Add('ECX');
915   FReg6432Index.Add('EDX');
916   FReg6432Index.Add('EBP');
917   FReg6432Index.Add('EDI');
918   FReg6432Index.Add('ESI');
919   FReg6432Index.Add('R8D');
920   FReg6432Index.Add('R9D');
921   FReg6432Index.Add('R10D');
922   FReg6432Index.Add('R11D');
923   FReg6432Index.Add('R12D');
924   FReg6432Index.Add('R13D');
925   FReg6432Index.Add('R14D');
926   FReg6432Index.Add('R15D');
927 
928   FReg32XMMIndex.ADD('XMM0');
929   FReg32XMMIndex.ADD('XMM1');
930   FReg32XMMIndex.ADD('XMM2');
931   FReg32XMMIndex.ADD('XMM3');
932   FReg32XMMIndex.ADD('XMM4');
933   FReg32XMMIndex.ADD('XMM5');
934   FReg32XMMIndex.ADD('XMM6');
935   FReg32XMMIndex.ADD('XMM7');
936 
937   FReg32YMMIndex.ADD('YMM0');
938   FReg32YMMIndex.ADD('YMM1');
939   FReg32YMMIndex.ADD('YMM2');
940   FReg32YMMIndex.ADD('YMM3');
941   FReg32YMMIndex.ADD('YMM4');
942   FReg32YMMIndex.ADD('YMM5');
943   FReg32YMMIndex.ADD('YMM6');
944   FReg32YMMIndex.ADD('YMM7');
945 
946   FReg64XMMIndex.ADD('XMM0');
947   FReg64XMMIndex.ADD('XMM1');
948   FReg64XMMIndex.ADD('XMM2');
949   FReg64XMMIndex.ADD('XMM3');
950   FReg64XMMIndex.ADD('XMM4');
951   FReg64XMMIndex.ADD('XMM5');
952   FReg64XMMIndex.ADD('XMM6');
953   FReg64XMMIndex.ADD('XMM7');
954   FReg64XMMIndex.ADD('XMM8');
955   FReg64XMMIndex.ADD('XMM9');
956   FReg64XMMIndex.ADD('XMM10');
957   FReg64XMMIndex.ADD('XMM11');
958   FReg64XMMIndex.ADD('XMM12');
959   FReg64XMMIndex.ADD('XMM13');
960   FReg64XMMIndex.ADD('XMM14');
961   FReg64XMMIndex.ADD('XMM15');
962 
963 
964   FReg64YMMIndex.ADD('YMM0');
965   FReg64YMMIndex.ADD('YMM1');
966   FReg64YMMIndex.ADD('YMM2');
967   FReg64YMMIndex.ADD('YMM3');
968   FReg64YMMIndex.ADD('YMM4');
969   FReg64YMMIndex.ADD('YMM5');
970   FReg64YMMIndex.ADD('YMM6');
971   FReg64YMMIndex.ADD('YMM7');
972   FReg64YMMIndex.ADD('YMM8');
973   FReg64YMMIndex.ADD('YMM9');
974   FReg64YMMIndex.ADD('YMM10');
975   FReg64YMMIndex.ADD('YMM11');
976   FReg64YMMIndex.ADD('YMM12');
977   FReg64YMMIndex.ADD('YMM13');
978   FReg64YMMIndex.ADD('YMM14');
979   FReg64YMMIndex.ADD('YMM15');
980 
981 end;
982 
983 destructor TAsmTestGenerator.Destroy;
984 begin
985   FreeAndNil(FReg32Base);
986   FreeAndNil(FReg32Index);
987   FreeAndNil(FReg64Base);
988   FreeAndNil(FReg64Index);
989   FreeAndNil(FReg6432Base);
990   FreeAndNil(FReg6432Index);
991 
992   FreeAndNil(FReg32XMMIndex);
993   FreeAndNil(FReg32YMMIndex);
994   FreeAndNil(FReg64XMMIndex);
995   FreeAndNil(FReg64YMMIndex);
996 
997   inherited;
998 end;
999 
1000 procedure TAsmTestGenerator.MemRegBaseIndexCombi(const aPrefix: String; aSLBaseReg,
1001   aSLIndexReg, aRList: TStringList);
1002 var
1003   il_Base: integer;
1004   il_Index: integer;
1005 begin
1006 
1007   for il_Base := 0 to aSLBaseReg.Count - 1 do
1008   begin
1009     aRList.Add(format(aPrefix + '[%s]', [aSLBaseReg[il_Base]]));
1010 
1011     for il_Index := 0 to aSLIndexReg.Count - 1 do
1012     begin
1013       aRList.Add(format(aPrefix + '[%s + %s]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1014 
1015       aRList.Add(format(aPrefix + '[%s + %s * 2]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1016       aRList.Add(format(aPrefix + '[%s + %s * 4]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1017       aRList.Add(format(aPrefix + '[%s + %s * 8]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1018 
1019       aRList.Add(format(aPrefix + '[%s + %s * 2 + 16]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1020       aRList.Add(format(aPrefix + '[%s + %s * 4 + 32]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1021       aRList.Add(format(aPrefix + '[%s + %s * 8 + 48]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1022     end;
1023   end;
1024 end;
1025 
1026 procedure TAsmTestGenerator.VectorMemRegBaseIndexCombi(const aPrefix: String;
1027   aSLBaseReg, aSLIndexReg, aRList: TStringList);
1028 var
1029   il_Base: integer;
1030   il_Index: integer;
1031 begin
1032 
1033   //for il_Index := 0 to aSLIndexReg.Count - 1 do
1034   //begin
1035   //  aRList.Add(format(aPrefix + '[%s]', [aSLIndexReg[il_Index]]));
1036   //
1037   //  aRList.Add(format(aPrefix + '[%s * 2]', [aSLIndexReg[il_Index]]));
1038   //  aRList.Add(format(aPrefix + '[%s * 4]', [aSLIndexReg[il_Index]]));
1039   //  aRList.Add(format(aPrefix + '[%s * 8]', [aSLIndexReg[il_Index]]));
1040   //
1041   //  aRList.Add(format(aPrefix + '[%s * 2 + 16]', [aSLIndexReg[il_Index]]));
1042   //  aRList.Add(format(aPrefix + '[%s * 4 + 32]', [aSLIndexReg[il_Index]]));
1043   //  aRList.Add(format(aPrefix + '[%s * 8 + 48]', [aSLIndexReg[il_Index]]));
1044   //end;
1045 
1046 
1047   for il_Base := 0 to aSLBaseReg.Count - 1 do
1048   begin
1049     //aRList.Add(format(aPrefix + '[%s]', [aSLBaseReg[il_Base]]));
1050 
1051     for il_Index := 0 to aSLIndexReg.Count - 1 do
1052     begin
1053       aRList.Add(format(aPrefix + '[%s + %s]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1054 
1055       aRList.Add(format(aPrefix + '[%s + %s * 2]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1056       aRList.Add(format(aPrefix + '[%s + %s * 4]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1057       aRList.Add(format(aPrefix + '[%s + %s * 8]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1058 
1059       aRList.Add(format(aPrefix + '[%s + %s * 2 + 16]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1060       aRList.Add(format(aPrefix + '[%s + %s * 4 + 32]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1061       aRList.Add(format(aPrefix + '[%s + %s * 8 + 48]', [aSLBaseReg[il_Base], aSLIndexReg[il_Index]]));
1062 
1063 
1064       aRList.Add(format(aPrefix + '[%s + %s]', [aSLIndexReg[il_Index], aSLBaseReg[il_Base]]));
1065 
1066       aRList.Add(format(aPrefix + '[%s + %s + 16]', [aSLIndexReg[il_Index], aSLBaseReg[il_Base]]));
1067     end;
1068   end;
1069 end;
1070 
1071 class procedure TAsmTestGenerator.CalcTestData(aX64: boolean; const aInst, aOp1, aOp2, aOp3,
1072   aOp4: String; aSL: TStringList);
1073 var
1074   sl: TStringList;
1075 begin
1076   with TAsmTestGenerator.Create do
1077   try
1078     Fx64 := aX64;
1079 
1080     sl := InternalCalcTestData(aInst, aOp1, aOp2, aOp3, aOp4);
1081     try
1082       aSL.AddStrings(sl);
1083     finally
1084       FreeAndNil(sl);
1085     end;
1086   finally
1087     Free;
1088   end;
1089 end;
1090 
1091 end.
1092