1 {
2     Copyright (c) 2010, 2013 by Jonas Maebe
3 
4     Contains the assembler object for the LLVM target
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 
20  ****************************************************************************
21 }
22 unit aasmllvm;
23 
24 {$i fpcdefs.inc}
25 
26 interface
27 
28     uses
29       globtype,verbose,cclasses,
30       aasmbase,aasmtai,aasmdata,aasmsym,
31       cpubase,cgbase,cgutils,
32       symtype,symdef,symsym,
33       llvmbase;
34 
35     type
36       { taillvm }
37       taillvm = class(tai_cpu_abstract_sym)
38         llvmopcode: tllvmop;
39 
40         constructor create_llvm(op: tllvmop);
41 
42         { e.g. ret void }
43         constructor op_size(op : tllvmop; size: tdef);
44 
45         { e.g. dst = alloca size }
46         constructor op_reg_size(op:tllvmop;dst:tregister;size:tdef);
47         { e.g. dst = alloca size }
48         constructor op_ref_size(op:tllvmop;const dst:treference;size:tdef);
49 
50         { e.g. dst = add size src1, src2 }
51         constructor op_reg_size_reg_reg(op:tllvmop;dst:tregister;size:tdef;src1,src2:tregister);
52         { e.g. dst = shl size src1, 1 ( = src1 shl 1) }
53         constructor op_reg_size_reg_const(op:tllvmop;dst:tregister;size:tdef;src1:tregister;src2:int64);
54         { e.g. dst = sub size 0, src2 ( = 0 - src2) }
55         constructor op_reg_size_const_reg(op:tllvmop;dst:tregister;size:tdef;src1:int64;src2:tregister);
56         { e.g. dst = bitcast size1 src to tosize }
57         constructor op_reg_size_reg_size(op:tllvmop;dst:tregister;fromsize:tdef;src:tregister;tosize:tdef);
58         { e.g. dst = bitcast fromsize 255 to tosize }
59         constructor op_reg_size_const_size(op:tllvmop;dst:tregister;fromsize:tdef;src:int64;tosize:tdef);
60         { e.g. dst = bitcast fromsize double to tosize }
61         constructor op_reg_size_fpconst_size(op:tllvmop;dst:tregister;fromsize:tdef;src:double;tosize:tdef);
62 {$ifdef cpuextended}
63         { e.g. dst = bitcast fromsize extended to tosize }
64         constructor op_reg_size_fpconst80_size(op:tllvmop;dst:tregister;fromsize:tdef;src:extended;tosize:tdef);
65 {$endif cpuextended}
66         { e.g. dst = bitcast fromsize @globalvar to tosize }
67         constructor op_reg_size_sym_size(op:tllvmop;dst:tregister;fromsize:tdef;src:TAsmSymbol;tosize:tdef);
68         { e.g. dst = bitcast fromsize <abstracttaidata> to tosize }
69         constructor op_reg_tai_size(op:tllvmop;dst:tregister;src:tai;tosize:tdef);
70 
71         { dst = bitcast size undef to size }
72         constructor op_reg_size_undef(op: tllvmop; dst: tregister; size: tdef);
73 
74         { return size undef }
75         constructor op_size_undef(op: tllvmop; size: tdef);
76 
77         { e.g. dst = bitcast fromsize src to tosize }
78         constructor op_reg_size_ref_size(op:tllvmop;dst:tregister;fromsize:tdef;const src:treference;tosize:tdef);
79         { e.g. store fromsize src, ptrsize toref}
80         constructor op_size_reg_size_ref(op:tllvmop;fromsize:tdef;src:tregister;ptrsize:tdef;const toref:treference);
81         { e.g. store fromsize srcref, ptrsize toref (with srcref.refaddr=full) }
82         constructor op_size_ref_size_ref(op:tllvmop;fromsize:tdef;const src:treference;ptrsize:tdef;const toref:treference);
83         { e.g. store fromsize const, ptrsize toref}
84         constructor op_size_const_size_ref(op:tllvmop;fromsize:tdef;src:int64;ptrsize:tdef;const toref:treference);
85         { e.g. dst = load fromsize fromref }
86         constructor op_reg_size_ref(op:tllvmop;dst:tregister;fromsize:tdef;const fromref:treference);
87 
88         { e.g. dst = icmp cmpcond size reg1, reg2 }
89         constructor op_reg_cond_size_reg_reg(op:tllvmop;dst:tregister;cmpcond:topcmp;size:tdef;reg1,reg2:tregister);
90         { e.g. dst = icmp cmpcond size reg1, constant }
91         constructor op_reg_cond_size_reg_const(op:tllvmop;dst:tregister;cmpcond:topcmp;size:tdef;reg1:tregister;cnst:int64);
92         { e.g. dst = fcmp cmpcond size reg1, reg2 }
93         constructor op_reg_fpcond_size_reg_reg(op:tllvmop;dst:tregister;cmpcond:tllvmfpcmp;size:tdef;reg1,reg2:tregister);
94         { e.g. br label lab }
95         constructor op_lab(op:tllvmop;lab:tasmlabel);
96         { e.g. br i1 condreg, label iftrue, label iffalse }
97         constructor op_size_reg_lab_lab(op:tllvmop;fromsize:tdef;condreg:tregister;labtrue,labfalse: tasmlabel);
98 
99         { e.g. la_ret retdef retval }
100         constructor op_size_reg(op:tllvmop;def: tdef;reg: tregister);
101 
102         { e.g. dst = getelementptr ptrsize ref, i32 0 (if indirect), index1type index1 }
103         constructor getelementptr_reg_size_ref_size_reg(dst:tregister;ptrsize:tdef;const ref:treference;indextype:tdef;index1:tregister;indirect:boolean);
104         constructor getelementptr_reg_size_ref_size_const(dst:tregister;ptrsize:tdef;const ref:treference;indextype:tdef;index1:ptrint;indirect:boolean);
105         constructor getelementptr_reg_tai_size_const(dst:tregister;const ai:tai;indextype:tdef;index1:ptrint;indirect:boolean);
106 
107         constructor blockaddress(fun, lab: tasmsymbol);
108         constructor landingpad(dst:tregister;def:tdef;firstclause:taillvm);
109         constructor exceptclause(op:tllvmop;def:tdef;kind:TAsmSymbol;nextclause:taillvm);
110 
111         { e.g. dst = call retsize name (paras) }
112         constructor call_size_name_paras(callpd: tdef; dst: tregister;retsize: tdef;name:tasmsymbol;paras: tfplist);
113         { e.g. dst = call retsize reg (paras) }
114         constructor call_size_reg_paras(callpd: tdef; dst: tregister;retsize: tdef;reg:tregister;paras: tfplist);
115 
116         { inline function-level assembler code and parameters }
117         constructor asm_paras(asmlist: tasmlist; paras: tfplist);
118 
119         procedure loadoper(opidx: longint; o: toper); override;
120         procedure clearop(opidx: longint); override;
121         procedure loadtai(opidx: longint; _ai: tai);
122         procedure loaddef(opidx: longint; _def: tdef);
123         procedure loadundef(opidx: longint);
124         procedure loadsingle(opidx: longint; _sval: single);
125         procedure loaddouble(opidx: longint; _dval: double);
126 {$ifdef cpuextended}
127         procedure loadextended(opidx: longint; _eval: extended);
128 {$endif cpuextended}
129         procedure loadcond(opidx: longint; _cond: topcmp);
130         procedure loadfpcond(opidx: longint; _fpcond: tllvmfpcmp);
131         procedure loadparas(opidx: longint; _paras: tfplist);
132         procedure loadasmlist(opidx: longint; _asmlist: tasmlist);
133 
134         { register spilling code }
spilling_get_operation_typenull135         function spilling_get_operation_type(opnr: longint): topertype;override;
spilling_get_reg_typenull136         function spilling_get_reg_type(opnr: longint): tdef;
137       end;
138 
139 
140     tllvmvisibility = (llv_default, llv_hidden, llv_protected);
141 
142     tllvmlinkage = (
143       { llvm 2.5 }
144       lll_default { = externally visible/global },
145       lll_private, lll_internal, lll_linkonce, lll_common,
146       lll_weak, lll_appending, lll_extern_weak,
147       lll_dllimport, lll_dllexport,
148       { llvm 2.6+ }
149       lll_linker_private, lll_private_weak, lll_private_weak_def_auto,
150       lll_available_externally,lll_linkonce_odr, lll_weak_odr
151       );
152 
153     taillvmalias = class(tailineinfo)
154       bind: tasmsymbind;
155       oldsym, newsym: TAsmSymbol;
156       def: tdef;
157       constructor create(_oldsym: tasmsymbol; const newname: TSymStr; _def: tdef; _bind: tasmsymbind);
158     end;
159 
160     taillvmdeclflag =
161     (
162       ldf_definition,   { definition as opposed to (an external) declaration }
163       ldf_tls,          { tls definition }
164       ldf_unnamed_addr, { address doesn't matter, only content }
165       ldf_vectorized,   { vectorized, dead-strippable data }
166       ldf_weak,         { weak definition }
167       ldf_appending     { appending linkage definition }
168     );
169     taillvmdeclflags = set of taillvmdeclflag;
170 
171     { declarations/definitions of symbols (procedures, variables), both defined
172       here and external }
173     taillvmdecl = class(tai)
174       { initialisation data, if any }
175       initdata: tasmlist;
176       namesym: tasmsymbol;
177       def: tdef;
178       sec: TAsmSectiontype;
179       alignment: shortint;
180       flags: taillvmdeclflags;
181       secname: TSymStr;
182       constructor createdecl(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist; _sec: tasmsectiontype; _alignment: shortint);
183       constructor createdef(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist; _sec: tasmsectiontype; _alignment: shortint);
184       constructor createtls(_namesym: tasmsymbol; _def: tdef; _alignment: shortint);
185       procedure setsecname(const name: TSymStr);
186       destructor destroy; override;
187     end;
188 
189     { parameter to an llvm call instruction }
190     pllvmcallpara = ^tllvmcallpara;
191     tllvmcallpara = record
192       def: tdef;
193       valueext: tllvmvalueextension;
194       byval,
195       sret: boolean;
196       case loc: tcgloc of
197         LOC_REFERENCE,
198         LOC_REGISTER,
199         LOC_FPUREGISTER,
200         LOC_MMREGISTER: (reg: tregister);
201         LOC_CONSTANT: (value: tcgint);
202     end;
203 
204 
205 implementation
206 
207 uses
208   cutils, strings,
209   symconst,
210   aasmcnst,aasmcpu;
211 
212     { taillvmprocdecl }
213 
214     constructor taillvmdecl.createdecl(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist; _sec: tasmsectiontype; _alignment: shortint);
215       begin
216         inherited create;
217         typ:=ait_llvmdecl;
218         namesym:=_namesym;
219         def:=_def;
220         initdata:=_initdata;
221         sec:=_sec;
222         alignment:=_alignment;
223         _namesym.declared:=true;
224         flags:=[];
225       end;
226 
227 
228     constructor taillvmdecl.createdef(_namesym: tasmsymbol; _def: tdef; _initdata: tasmlist; _sec: tasmsectiontype; _alignment: shortint);
229       begin
230         createdecl(_namesym,_def,_initdata,_sec,_alignment);
231         include(flags,ldf_definition);
232       end;
233 
234 
235     constructor taillvmdecl.createtls(_namesym: tasmsymbol; _def: tdef; _alignment: shortint);
236       begin
237         createdef(_namesym,_def,nil,sec_data,_alignment);
238         include(flags,ldf_tls);
239       end;
240 
241 
242     procedure taillvmdecl.setsecname(const name: TSymStr);
243       begin
244         if sec<>sec_user then
245           internalerror(2015111501);
246         secname:=name;
247       end;
248 
249 
250     destructor taillvmdecl.destroy;
251       begin
252         initdata.free;
253         inherited destroy;
254       end;
255 
256     { taillvmalias }
257 
258     constructor taillvmalias.create(_oldsym: tasmsymbol; const newname: TSymStr; _def: tdef; _bind: tasmsymbind);
259       begin
260         inherited Create;
261         typ:=ait_llvmalias;
262         oldsym:=_oldsym;
_defnull263         newsym:=current_asmdata.DefineAsmSymbol(newname,AB_GLOBAL,AT_FUNCTION,_def);
264         newsym.declared:=true;
265         def:=_def;
266         { alias cannot be external }
267         case _bind of
268           { weak external should actually become weak, but we don't support that
269             yet }
270           AB_WEAK_EXTERNAL:
271             internalerror(2016071203);
272           AB_EXTERNAL:
273             _bind:=AB_GLOBAL;
274           AB_EXTERNAL_INDIRECT:
275             _bind:=AB_INDIRECT;
276         end;
277         bind:=_bind;
278       end;
279 
280 
281 
282 
283 {*****************************************************************************
284                                  taicpu Constructors
285 *****************************************************************************}
286 
287     constructor taillvm.create_llvm(op: tllvmop);
288       begin
289         create(a_none);
290         llvmopcode:=op;
291         typ:=ait_llvmins;
292       end;
293 
294 
295     procedure taillvm.loadoper(opidx: longint; o: toper);
296       var
297         i: longint;
298         callpara: pllvmcallpara;
299       begin
300         inherited;
301         if o.typ=top_para then
302           begin
303             oper[opidx]^.paras:=tfplist.create;
304             for i:=0 to o.paras.count-1 do
305               begin
306                 new(callpara);
307                 callpara^:=pllvmcallpara(o.paras[i])^;
308                 oper[opidx]^.paras.add(callpara);
309                 if (callpara^.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER]) and
310                    assigned(add_reg_instruction_hook) then
311                   add_reg_instruction_hook(self,callpara^.reg);
312               end;
313           end;
314       end;
315 
316 
317     procedure taillvm.clearop(opidx: longint);
318       var
319         i: longint;
320       begin
321         case oper[opidx]^.typ of
322           top_para:
323             begin
324               for i:=0 to oper[opidx]^.paras.count-1 do
325                 dispose(pllvmcallpara(oper[opidx]^.paras[i]));
326               oper[opidx]^.paras.free;
327             end;
328           top_tai:
329             oper[opidx]^.ai.free;
330           top_asmlist:
331             oper[opidx]^.asmlist.free;
332         end;
333         inherited;
334       end;
335 
336 
337     procedure taillvm.loadtai(opidx: longint; _ai: tai);
338       begin
339         allocate_oper(opidx+1);
340         with oper[opidx]^ do
341          begin
342            clearop(opidx);
343            ai:=_ai;
344            typ:=top_tai;
345          end;
346       end;
347 
348 
349     procedure taillvm.loaddef(opidx:longint;_def: tdef);
350       begin
351         allocate_oper(opidx+1);
352         with oper[opidx]^ do
353          begin
354            if typ<>top_def then
355              clearop(opidx);
356            def:=_def;
357            typ:=top_def;
358          end;
359       end;
360 
361 
362     procedure taillvm.loadundef(opidx: longint);
363       begin
364         allocate_oper(opidx+1);
365         with oper[opidx]^ do
366           typ:=top_undef
367       end;
368 
369 
370     procedure taillvm.loadsingle(opidx: longint; _sval: single);
371       begin
372         allocate_oper(opidx+1);
373         with oper[opidx]^ do
374          begin
375            if typ<>top_single then
376              clearop(opidx);
377            sval:=_sval;
378            typ:=top_single;
379          end;
380       end;
381 
382 
383     procedure taillvm.loaddouble(opidx: longint; _dval: double);
384       begin
385         allocate_oper(opidx+1);
386         with oper[opidx]^ do
387          begin
388            if typ<>top_double then
389              clearop(opidx);
390            dval:=_dval;
391            typ:=top_double;
392          end;
393       end;
394 
395 
396 {$ifdef cpuextended}
397     procedure taillvm.loadextended(opidx: longint; _eval: extended);
398       begin
399         allocate_oper(opidx+1);
400         with oper[opidx]^ do
401          begin
402            if typ<>top_extended80 then
403              clearop(opidx);
404            eval:=_eval;
405            typ:=top_extended80;
406          end;
407       end;
408 {$endif cpuextended}
409 
410 
411     procedure taillvm.loadcond(opidx: longint; _cond: topcmp);
412       begin
413         allocate_oper(opidx+1);
414         with oper[opidx]^ do
415          begin
416            if typ<>top_cond then
417              clearop(opidx);
418            cond:=_cond;
419            typ:=top_cond;
420          end;
421       end;
422 
423     procedure taillvm.loadfpcond(opidx: longint; _fpcond: tllvmfpcmp);
424       begin
425         allocate_oper(opidx+1);
426         with oper[opidx]^ do
427          begin
428            if typ<>top_fpcond then
429              clearop(opidx);
430            fpcond:=_fpcond;
431            typ:=top_fpcond;
432          end;
433       end;
434 
435 
436     procedure taillvm.loadparas(opidx: longint; _paras: tfplist);
437       var
438         callpara: pllvmcallpara;
439         i: longint;
440       begin
441         allocate_oper(opidx+1);
442         with oper[opidx]^ do
443           begin
444             clearop(opidx);
445             paras:=_paras;
446             for i:=0 to _paras.count-1 do
447               begin
448                 callpara:=pllvmcallpara(_paras[i]);
449                 if (callpara^.loc in [LOC_REGISTER,LOC_FPUREGISTER,LOC_MMREGISTER]) and
450                    assigned(add_reg_instruction_hook) then
451                   add_reg_instruction_hook(self,callpara^.reg);
452               end;
453             typ:=top_para;
454           end;
455       end;
456 
457 
458     procedure taillvm.loadasmlist(opidx: longint; _asmlist: tasmlist);
459       begin
460         allocate_oper(opidx+1);
461         with oper[opidx]^ do
462          begin
463            clearop(opidx);
464            asmlist:=_asmlist;
465            typ:=top_asmlist;
466          end;
467       end;
468 
469 
taillvm.spilling_get_operation_typenull470     function taillvm.spilling_get_operation_type(opnr: longint): topertype;
471       begin
472         case llvmopcode of
473           la_ret, la_br, la_switch, la_indirectbr,
474           la_resume,
475           la_unreachable,
476           la_store,
477           la_fence,
478           la_cmpxchg,
479           la_atomicrmw:
480             begin
481               { instructions that never have a result }
482               result:=operand_read;
483             end;
484           la_alloca,
485           la_trunc, la_zext, la_sext, la_fptrunc, la_fpext,
486           la_fptoui, la_fptosi, la_uitofp, la_sitofp,
487           la_ptrtoint, la_inttoptr,
488           la_bitcast,
489           la_add, la_fadd, la_sub, la_fsub, la_mul, la_fmul,
490           la_udiv,la_sdiv, la_fdiv, la_urem, la_srem, la_frem,
491           la_shl, la_lshr, la_ashr, la_and, la_or, la_xor,
492           la_extractelement, la_insertelement, la_shufflevector,
493           la_extractvalue, la_insertvalue,
494           la_getelementptr,
495           la_load,
496           la_icmp, la_fcmp,
497           la_phi, la_select,
498           la_va_arg, la_landingpad:
499             begin
500               if opnr=0 then
501                 result:=operand_write
502               else
503                 result:=operand_read;
504             end;
505           la_invoke, la_call:
506             begin
507               if opnr=1 then
508                 result:=operand_write
509               else
510                 result:=operand_read;
511             end;
512           la_blockaddress:
513             case opnr of
514               0: result:=operand_write
515               else
516                 result:=operand_read;
517             end
518           else
519             internalerror(2013103101)
520         end;
521       end;
522 
523 
taillvm.spilling_get_reg_typenull524     function taillvm.spilling_get_reg_type(opnr: longint): tdef;
525       begin
526         case llvmopcode of
527           la_trunc, la_zext, la_sext, la_fptrunc, la_fpext,
528           la_fptoui, la_fptosi, la_uitofp, la_sitofp,
529           la_ptrtoint, la_inttoptr,
530           la_bitcast:
531             begin
532               { toreg = bitcast fromsize fromreg to tosize }
533               case opnr of
534                 0: result:=oper[3]^.def;
535                 2: result:=oper[1]^.def
536                 else
537                   internalerror(2013103102);
538               end;
539             end;
540           la_ret, la_switch, la_indirectbr,
541           la_resume:
542             begin
543               { ret size reg }
544               if opnr=1 then
545                 result:=oper[0]^.def
546               else
547                 internalerror(2013110101);
548             end;
549           la_invoke, la_call:
550             begin
551               case opnr of
552                 1: result:=oper[0]^.def;
553                 3:
554                   begin
555                     if oper[3]^.typ=top_reg then
556                       result:=oper[2]^.def
557                     else
558                       internalerror(2015112001)
559                   end
560                 else
561                   internalerror(2013110102);
562               end;
563             end;
564           la_br,
565           la_unreachable:
566             internalerror(2013110103);
567           la_store:
568             begin
569               case opnr of
570                 1: result:=oper[0]^.def;
571                 { type of the register in the reference }
572                 3: result:=oper[2]^.def;
573                 else
574                   internalerror(2013110104);
575               end;
576             end;
577           la_load:
578             begin
579               { dst = load ptrdef srcref }
580               case opnr of
581                 0: result:=tpointerdef(oper[1]^.def).pointeddef;
582                 2: result:=oper[1]^.def;
583                 else
584                   internalerror(2013110105);
585               end;
586             end;
587           la_getelementptr:
588             begin
589               { dst = getelementptr ref ... }
590               case opnr of
591                 0:
592                   begin
593                     case oper[1]^.typ of
594                       top_def:
595                         result:=oper[1]^.def;
596                       top_tai:
597                         begin
598                           case oper[1]^.ai.typ of
599                             ait_llvmins:
600                               result:=taillvm(oper[1]^.ai).spilling_get_reg_type(0);
601                             ait_typedconst:
602                               result:=tai_abstracttypedconst(oper[1]^.ai).def
603                             else
604                               internalerror(2016071202);
605                           end
606                         end
607                       else
608                         internalerror(2016071201);
609                     end
610                   end;
611                 2:
612                   result:=oper[1]^.def;
613                 else
614                   internalerror(2013110105);
615               end;
616             end;
617           la_fence,
618           la_cmpxchg,
619           la_atomicrmw:
620             begin
621               internalerror(2013110610);
622             end;
623           la_add, la_fadd, la_sub, la_fsub, la_mul, la_fmul,
624           la_udiv,la_sdiv, la_fdiv, la_urem, la_srem, la_frem,
625           la_shl, la_lshr, la_ashr, la_and, la_or, la_xor:
626             begin
627               case opnr of
628                 0,2,3:
629                   result:=oper[1]^.def;
630                 else
631                   internalerror(2013110106);
632               end;
633             end;
634           la_extractelement, la_insertelement, la_shufflevector,
635           la_extractvalue:
636             begin
637               { todo }
638               internalerror(2013110107);
639             end;
640           la_insertvalue:
641             begin
642               case opnr of
643                 0,2: result:=oper[1]^.def;
644                 else
645                   internalerror(2013110108);
646               end;
647             end;
648           la_icmp, la_fcmp:
649             begin
650               case opnr of
651                 0: result:=llvmbool1type;
652                 3,4: result:=oper[2]^.def;
653                 else
654                   internalerror(2013110801);
655               end
656             end;
657           la_alloca:
658             begin
659               { shouldn't be spilled, the result of alloca should be read-only }
660               internalerror(2013110109);
661             end;
662           la_select:
663             begin
664               case opnr of
665                 0,4,6: result:=oper[3]^.def;
666                 2: result:=oper[1]^.def;
667                 else
668                   internalerror(2013110110);
669               end;
670             end;
671           la_blockaddress:
672             case opnr of
673               0: result:=voidcodepointertype
674               else
675                 internalerror(2015111904);
676             end
677           else
678             internalerror(2013103101)
679         end;
680       end;
681 
682 
683     constructor taillvm.op_size(op : tllvmop; size: tdef);
684       begin
685         create_llvm(op);
686         ops:=1;
687         loaddef(0,size);
688       end;
689 
690 
691     constructor taillvm.op_reg_size(op: tllvmop; dst: tregister; size: tdef);
692       begin
693         create_llvm(op);
694         ops:=2;
695         loadreg(0,dst);
696         loaddef(1,size);
697       end;
698 
699 
700     constructor taillvm.op_ref_size(op: tllvmop; const dst: treference; size: tdef);
701       begin
702         create_llvm(op);
703         ops:=2;
704         loadref(0,dst);
705         loaddef(1,size);
706       end;
707 
708 
709     { %dst = add i32 %src1, %src2 }
710     constructor taillvm.op_reg_size_reg_reg(op: tllvmop; dst: tregister;size: tdef; src1, src2: tregister);
711       begin
712         create_llvm(op);
713         ops:=4;
714         loadreg(0,dst);
715         loaddef(1,size);
716         loadreg(2,src1);
717         loadreg(3,src2);
718       end;
719 
720     { %dst = shl i32 %reg, 1 (= %reg shl 1) }
721     constructor taillvm.op_reg_size_reg_const(op: tllvmop; dst: tregister; size: tdef; src1: tregister; src2: int64);
722       begin
723         create_llvm(op);
724         ops:=4;
725         loadreg(0,dst);
726         loaddef(1,size);
727         loadreg(2,src1);
728         loadconst(3,src2);
729       end;
730 
731 
732     { %dst = sub i32 1, %src (= 1 - %src) }
733     constructor taillvm.op_reg_size_const_reg(op: tllvmop; dst: tregister; size: tdef; src1: int64; src2: tregister);
734       begin
735         create_llvm(op);
736         ops:=4;
737         loadreg(0,dst);
738         loaddef(1,size);
739         loadconst(2,src1);
740         loadreg(3,src2);
741       end;
742 
743 
744     { %dst = bitcast i32 %src to i8 }
745     constructor taillvm.op_reg_size_reg_size(op: tllvmop; dst: tregister; fromsize: tdef; src: tregister; tosize: tdef);
746       begin
747         create_llvm(op);
748         ops:=4;
749         loadreg(0,dst);
750         loaddef(1,fromsize);
751         loadreg(2,src);
752         loaddef(3,tosize);
753       end;
754 
755 
756     { %dst = bitcast i32 -1 to i8 }
757     constructor taillvm.op_reg_size_const_size(op: tllvmop; dst: tregister; fromsize: tdef; src: int64; tosize: tdef);
758       begin
759         create_llvm(op);
760         ops:=4;
761         loadreg(0,dst);
762         loaddef(1,fromsize);
763         loadconst(2,src);
764         loaddef(3,tosize);
765       end;
766 
767 
768     constructor taillvm.op_reg_size_fpconst_size(op: tllvmop; dst: tregister; fromsize: tdef; src: double; tosize: tdef);
769       begin
770         create_llvm(op);
771         ops:=4;
772         loadreg(0,dst);
773         loaddef(1,fromsize);
774         if fromsize.typ<>floatdef then
775           internalerror(2014012214);
776         case tfloatdef(fromsize).floattype of
777           s32real:
778             loadsingle(2,src);
779           s64real:
780             loaddouble(2,src);
781           else
782             internalerror(2014012215);
783         end;
784         loaddef(3,tosize);
785       end;
786 
787 {$ifdef cpuextended}
788     constructor taillvm.op_reg_size_fpconst80_size(op: tllvmop; dst: tregister; fromsize: tdef; src: extended; tosize: tdef);
789       begin
790         create_llvm(op);
791         ops:=4;
792         loadreg(0,dst);
793         loaddef(1,fromsize);
794         loadextended(2,src);
795         loaddef(3,tosize);
796       end;
797 {$endif cpuextended}
798 
799 
800     constructor taillvm.op_reg_size_sym_size(op: tllvmop; dst: tregister; fromsize: tdef; src: TAsmSymbol; tosize: tdef);
801       begin
802         create_llvm(op);
803         ops:=4;
804         loadreg(0,dst);
805         loaddef(1,fromsize);
806         loadsymbol(2,src,0);
807         loaddef(3,tosize);
808       end;
809 
810 
811     constructor taillvm.op_reg_tai_size(op:tllvmop;dst:tregister;src:tai;tosize:tdef);
812       begin
813         create_llvm(op);
814         ops:=3;
815         loadreg(0,dst);
816         loadtai(1,src);
817         loaddef(2,tosize);
818       end;
819 
820 
821     constructor taillvm.op_reg_size_undef(op: tllvmop; dst: tregister; size: tdef);
822       begin
823         create_llvm(op);
824         ops:=4;
825         loadreg(0,dst);
826         loaddef(1,size);
827         loadundef(2);
828         loaddef(3,size);
829       end;
830 
831     constructor taillvm.op_size_undef(op: tllvmop; size: tdef);
832       begin
833         create_llvm(op);
834         ops:=2;
835         loaddef(0,size);
836         loadundef(1);
837       end;
838 
839 
840     constructor taillvm.op_reg_size_ref_size(op: tllvmop; dst: tregister; fromsize: tdef; const src: treference; tosize: tdef);
841       begin
842         create_llvm(op);
843         ops:=4;
844         loadreg(0,dst);
845         loaddef(1,fromsize);
846         loadref(2,src);
847         loaddef(3,tosize);
848       end;
849 
850 
851     { store i32 3, i32* %ptr }
852     constructor taillvm.op_size_reg_size_ref(op: tllvmop; fromsize: tdef; src: tregister; ptrsize: tdef; const toref: treference);
853       begin
854         create_llvm(op);
855         ops:=4;
856         loaddef(0,fromsize);
857         loadreg(1,src);
858         loaddef(2,ptrsize);
859         loadref(3,toref);
860       end;
861 
862 
863     constructor taillvm.op_size_ref_size_ref(op: tllvmop; fromsize: tdef; const src: treference; ptrsize: tdef; const toref: treference);
864       begin
865         create_llvm(op);
866         ops:=4;
867         loaddef(0,fromsize);
868         loadref(1,src);
869         loaddef(2,ptrsize);
870         loadref(3,toref);
871       end;
872 
873 
874     constructor taillvm.op_size_const_size_ref(op: tllvmop; fromsize: tdef; src: int64; ptrsize: tdef; const toref: treference);
875       begin
876         create_llvm(op);
877         ops:=4;
878         loaddef(0,fromsize);
879         loadconst(1,src);
880         loaddef(2,ptrsize);
881         loadref(3,toref);
882       end;
883 
884 
885     constructor taillvm.op_reg_size_ref(op: tllvmop; dst: tregister; fromsize: tdef; const fromref: treference);
886       begin
887         create_llvm(op);
888         ops:=3;
889         loadreg(0,dst);
890         loaddef(1,fromsize);
891         loadref(2,fromref);
892       end;
893 
894 
895     constructor taillvm.op_reg_cond_size_reg_reg(op: tllvmop; dst: tregister; cmpcond: topcmp; size: tdef; reg1, reg2: tregister);
896       begin
897         create_llvm(op);
898         ops:=5;
899         loadreg(0,dst);
900         loadcond(1,cmpcond);
901         loaddef(2,size);
902         loadreg(3,reg1);
903         loadreg(4,reg2);
904       end;
905 
906     constructor taillvm.op_reg_cond_size_reg_const(op: tllvmop; dst: tregister; cmpcond: topcmp; size: tdef; reg1: tregister; cnst: int64);
907       begin
908         create_llvm(op);
909         ops:=5;
910         loadreg(0,dst);
911         loadcond(1,cmpcond);
912         loaddef(2,size);
913         loadreg(3,reg1);
914         loadconst(4,cnst);
915       end;
916 
917     constructor taillvm.op_reg_fpcond_size_reg_reg(op: tllvmop; dst: tregister; cmpcond: tllvmfpcmp; size: tdef; reg1, reg2: tregister);
918       begin
919         create_llvm(op);
920         ops:=5;
921         loadreg(0,dst);
922         loadfpcond(1,cmpcond);
923         loaddef(2,size);
924         loadreg(3,reg1);
925         loadreg(4,reg2);
926       end;
927 
928 
929     constructor taillvm.op_lab(op: tllvmop; lab: tasmlabel);
930       begin
931         create_llvm(op);
932         ops:=1;
933         loadsymbol(0,lab,0);
934       end;
935 
936 
937     constructor taillvm.op_size_reg_lab_lab(op: tllvmop; fromsize: tdef; condreg: tregister; labtrue, labfalse: tasmlabel);
938       begin
939         create_llvm(op);
940         ops:=4;
941         loaddef(0,fromsize);
942         loadreg(1,condreg);
943         loadsymbol(2,labtrue,0);
944         loadsymbol(3,labfalse,0);
945       end;
946 
947 
948     constructor taillvm.op_size_reg(op: tllvmop; def: tdef; reg: tregister);
949       begin
950         create_llvm(op);
951         ops:=2;
952         loaddef(0,def);
953         loadreg(1,reg);
954       end;
955 
956 
957     constructor taillvm.getelementptr_reg_size_ref_size_reg(dst: tregister; ptrsize: tdef; const ref: treference; indextype: tdef; index1: tregister; indirect: boolean);
958       var
959         index: longint;
960       begin
961         create_llvm(la_getelementptr);
962         if indirect then
963           ops:=7
964         else
965           ops:=5;
966         loadreg(0,dst);
967         loaddef(1,ptrsize);
968         loadref(2,ref);
969         if indirect then
970           begin
971             loaddef(3,s32inttype);
972             loadconst(4,0);
973             index:=5;
974           end
975         else
976           index:=3;
977         loaddef(index,indextype);
978         loadreg(index+1,index1);
979       end;
980 
981 
982     constructor taillvm.getelementptr_reg_size_ref_size_const(dst: tregister; ptrsize: tdef; const ref: treference; indextype: tdef; index1: ptrint; indirect: boolean);
983       var
984         index: longint;
985       begin
986         create_llvm(la_getelementptr);
987         if indirect then
988           ops:=7
989         else
990           ops:=5;
991         loadreg(0,dst);
992         loaddef(1,ptrsize);
993         loadref(2,ref);
994         if indirect then
995           begin
996             loaddef(3,s32inttype);
997             loadconst(4,0);
998             index:=5;
999           end
1000         else
1001           index:=3;
1002         loaddef(index,indextype);
1003         loadconst(index+1,index1);
1004       end;
1005 
1006 
1007     constructor taillvm.getelementptr_reg_tai_size_const(dst: tregister; const ai: tai; indextype: tdef; index1: ptrint; indirect: boolean);
1008       var
1009         index: longint;
1010       begin
1011         create_llvm(la_getelementptr);
1012         if indirect then
1013           ops:=6
1014         else
1015           ops:=4;
1016         loadreg(0,dst);
1017         loadtai(1,ai);
1018         if indirect then
1019           begin
1020             loaddef(2,s32inttype);
1021             loadconst(3,0);
1022             index:=4;
1023           end
1024         else
1025           index:=2;
1026         loaddef(index,indextype);
1027         loadconst(index+1,index1);
1028       end;
1029 
1030     constructor taillvm.blockaddress(fun, lab: tasmsymbol);
1031       begin
1032         create_llvm(la_blockaddress);
1033         ops:=2;
1034         loadsymbol(0,fun,0);
1035         loadsymbol(1,lab,0);
1036       end;
1037 
1038 
1039     constructor taillvm.landingpad(dst: tregister; def: tdef; firstclause: taillvm);
1040       begin
1041         create_llvm(la_landingpad);
1042         ops:=3;
1043         loadreg(0,dst);
1044         loaddef(1,def);
1045         loadtai(2,firstclause);
1046       end;
1047 
1048 
1049     constructor taillvm.exceptclause(op: tllvmop; def: tdef; kind: TAsmSymbol; nextclause: taillvm);
1050       begin
1051         create_llvm(op);
1052         ops:=3;
1053         loaddef(0,def);
1054         loadsymbol(1,kind,0);
1055         loadtai(2,nextclause);
1056       end;
1057 
1058 
1059     constructor taillvm.call_size_name_paras(callpd: tdef; dst: tregister; retsize: tdef; name:tasmsymbol; paras: tfplist);
1060       begin
1061         create_llvm(la_call);
1062         ops:=5;
1063         { we need this in case the call symbol is an alias for a symbol with a
1064           different def in the same module (via "external"), because then we
1065           have to insert a type conversion later from the alias def to the
1066           call def here; we can't always do that at the point the call itself
1067           is generated, because the alias declaration may occur anywhere }
1068         loaddef(0,retsize);
1069         loadreg(1,dst);
1070         loaddef(2,callpd);
1071         loadsymbol(3,name,0);
1072         loadparas(4,paras);
1073       end;
1074 
1075 
1076     constructor taillvm.call_size_reg_paras(callpd: tdef; dst: tregister; retsize: tdef; reg: tregister; paras: tfplist);
1077       begin
1078         create_llvm(la_call);
1079         ops:=5;
1080         loaddef(0,retsize);
1081         loadreg(1,dst);
1082         loaddef(2,callpd);
1083         loadreg(3,reg);
1084         loadparas(4,paras);
1085       end;
1086 
1087 
1088     constructor taillvm.asm_paras(asmlist: tasmlist; paras: tfplist);
1089       begin
1090         create_llvm(la_asmblock);
1091         ops:=2;
1092         loadasmlist(0,asmlist);
1093         loadparas(1,paras);
1094       end;
1095 
1096 end.
1097