nany
data.h
1 #pragma once
2 #include "libnanyc.h"
3 #include <nany/nany.h>
4 #include "opcodes.h"
5 #include <iosfwd>
6 #include <yuni/core/string.h>
7 
8 
9 namespace ny {
10 struct AtomMap;
11 namespace ir {
12 struct Sequence;
13 struct Instruction;
14 }
15 }
16 
17 namespace ny {
18 namespace ir {
19 namespace isa {
20 
21 enum class Pragma : uint32_t {
23  unknown = 0,
25  codegen,
26 
27  // --- pragma for compilation only
29  blueprintsize,
31  visibility,
33  bodystart,
35  shortcircuit,
37  shortcircuitOpNopOffset,
39  shortcircuitMutateToBool,
41  builtinalias,
43  suggest,
45  synthetic,
46 };
47 static const constexpr uint32_t PragmaCount = 1 + (uint32_t) Pragma::synthetic;
48 
49 
54 enum class Blueprint : uint32_t {
56  funcdef,
58  vardef,
60  classdef,
62  typealias,
64  param,
66  gentypeparam,
68  paramself,
70  namespacedef,
72  unit,
73 
74 }; // enum Blueprint
75 
76 enum class TypeQualifier : uint32_t {
78  ref,
80  constant,
81 };
82 static const constexpr uint32_t TypeQualifierCount = 1 + (uint32_t) TypeQualifier::constant;
83 
84 
85 template<ny::ir::isa::Op O> struct Operand final {};
86 
87 
88 template<> struct Operand<ny::ir::isa::Op::nop> final {
89  constexpr static const char* opname() {
90  return "nop";
91  }
92  uint32_t opcode;
93 
94  template<class T> void eachLVID(T&) {}
95 };
96 
97 template<> struct Operand<ny::ir::isa::Op::eq> final {
98  constexpr static const char* opname() {
99  return "eq";
100  }
101  uint32_t opcode;
102  uint32_t lvid;
103  uint32_t lhs;
104  uint32_t rhs;
105 
106  template<class T> void eachLVID(T& c) {
107  c(lvid, lhs, rhs);
108  }
109 };
110 
111 template<> struct Operand<ny::ir::isa::Op::neq> final {
112  constexpr static const char* opname() {
113  return "neq";
114  }
115  uint32_t opcode;
116  uint32_t lvid;
117  uint32_t lhs;
118  uint32_t rhs;
119 
120  template<class T> void eachLVID(T& c) {
121  c(lvid, lhs, rhs);
122  }
123 };
124 
125 template<> struct Operand<ny::ir::isa::Op::flt> final {
126  constexpr static const char* opname() {
127  return "flt";
128  }
129  uint32_t opcode;
130  uint32_t lvid;
131  uint32_t lhs;
132  uint32_t rhs;
133 
134  template<class T> void eachLVID(T& c) {
135  c(lvid, lhs, rhs);
136  }
137 };
138 
139 template<> struct Operand<ny::ir::isa::Op::flte> final {
140  constexpr static const char* opname() {
141  return "flte";
142  }
143  uint32_t opcode;
144  uint32_t lvid;
145  uint32_t lhs;
146  uint32_t rhs;
147 
148  template<class T> void eachLVID(T& c) {
149  c(lvid, lhs, rhs);
150  }
151 };
152 
153 template<> struct Operand<ny::ir::isa::Op::fgt> final {
154  constexpr static const char* opname() {
155  return "fgt";
156  }
157  uint32_t opcode;
158  uint32_t lvid;
159  uint32_t lhs;
160  uint32_t rhs;
161 
162  template<class T> void eachLVID(T& c) {
163  c(lvid, lhs, rhs);
164  }
165 };
166 
167 template<> struct Operand<ny::ir::isa::Op::fgte> final {
168  constexpr static const char* opname() {
169  return "fgte";
170  }
171  uint32_t opcode;
172  uint32_t lvid;
173  uint32_t lhs;
174  uint32_t rhs;
175 
176  template<class T> void eachLVID(T& c) {
177  c(lvid, lhs, rhs);
178  }
179 };
180 
181 template<> struct Operand<ny::ir::isa::Op::lt> final {
182  constexpr static const char* opname() {
183  return "lt";
184  }
185  uint32_t opcode;
186  uint32_t lvid;
187  uint32_t lhs;
188  uint32_t rhs;
189 
190  template<class T> void eachLVID(T& c) {
191  c(lvid, lhs, rhs);
192  }
193 };
194 
195 template<> struct Operand<ny::ir::isa::Op::lte> final {
196  constexpr static const char* opname() {
197  return "lte";
198  }
199  uint32_t opcode;
200  uint32_t lvid;
201  uint32_t lhs;
202  uint32_t rhs;
203 
204  template<class T> void eachLVID(T& c) {
205  c(lvid, lhs, rhs);
206  }
207 };
208 
209 template<> struct Operand<ny::ir::isa::Op::ilt> final {
210  constexpr static const char* opname() {
211  return "ilt";
212  }
213  uint32_t opcode;
214  uint32_t lvid;
215  uint32_t lhs;
216  uint32_t rhs;
217 
218  template<class T> void eachLVID(T& c) {
219  c(lvid, lhs, rhs);
220  }
221 };
222 
223 template<> struct Operand<ny::ir::isa::Op::ilte> final {
224  constexpr static const char* opname() {
225  return "ilte";
226  }
227  uint32_t opcode;
228  uint32_t lvid;
229  uint32_t lhs;
230  uint32_t rhs;
231 
232  template<class T> void eachLVID(T& c) {
233  c(lvid, lhs, rhs);
234  }
235 };
236 
237 template<> struct Operand<ny::ir::isa::Op::gt> final {
238  constexpr static const char* opname() {
239  return "gt";
240  }
241  uint32_t opcode;
242  uint32_t lvid;
243  uint32_t lhs;
244  uint32_t rhs;
245 
246  template<class T> void eachLVID(T& c) {
247  c(lvid, lhs, rhs);
248  }
249 };
250 
251 template<> struct Operand<ny::ir::isa::Op::gte> final {
252  constexpr static const char* opname() {
253  return "gte";
254  }
255  uint32_t opcode;
256  uint32_t lvid;
257  uint32_t lhs;
258  uint32_t rhs;
259 
260  template<class T> void eachLVID(T& c) {
261  c(lvid, lhs, rhs);
262  }
263 };
264 
265 template<> struct Operand<ny::ir::isa::Op::igt> final {
266  constexpr static const char* opname() {
267  return "igt";
268  }
269  uint32_t opcode;
270  uint32_t lvid;
271  uint32_t lhs;
272  uint32_t rhs;
273 
274  template<class T> void eachLVID(T& c) {
275  c(lvid, lhs, rhs);
276  }
277 };
278 
279 template<> struct Operand<ny::ir::isa::Op::igte> final {
280  constexpr static const char* opname() {
281  return "igte";
282  }
283  uint32_t opcode;
284  uint32_t lvid;
285  uint32_t lhs;
286  uint32_t rhs;
287 
288  template<class T> void eachLVID(T& c) {
289  c(lvid, lhs, rhs);
290  }
291 };
292 
293 template<> struct Operand<ny::ir::isa::Op::opand> final {
294  constexpr static const char* opname() {
295  return "and";
296  }
297  uint32_t opcode;
298  uint32_t lvid;
299  uint32_t lhs;
300  uint32_t rhs;
301 
302  template<class T> void eachLVID(T& c) {
303  c(lvid, lhs, rhs);
304  }
305 };
306 
307 template<> struct Operand<ny::ir::isa::Op::opor> final {
308  constexpr static const char* opname() {
309  return "or";
310  }
311  uint32_t opcode;
312  uint32_t lvid;
313  uint32_t lhs;
314  uint32_t rhs;
315 
316  template<class T> void eachLVID(T& c) {
317  c(lvid, lhs, rhs);
318  }
319 };
320 
321 template<> struct Operand<ny::ir::isa::Op::opxor> final {
322  constexpr static const char* opname() {
323  return "xor";
324  }
325  uint32_t opcode;
326  uint32_t lvid;
327  uint32_t lhs;
328  uint32_t rhs;
329 
330  template<class T> void eachLVID(T& c) {
331  c(lvid, lhs, rhs);
332  }
333 };
334 
335 template<> struct Operand<ny::ir::isa::Op::opmod> final {
336  constexpr static const char* opname() {
337  return "mod";
338  }
339  uint32_t opcode;
340  uint32_t lvid;
341  uint32_t lhs;
342  uint32_t rhs;
343 
344  template<class T> void eachLVID(T& c) {
345  c(lvid, lhs, rhs);
346  }
347 };
348 
349 template<> struct Operand<ny::ir::isa::Op::negation> final {
350  constexpr static const char* opname() {
351  return "negation";
352  }
353  uint32_t opcode;
354  uint32_t lvid;
355  uint32_t lhs;
356 
357  template<class T> void eachLVID(T& c) {
358  c(lvid, lhs);
359  }
360 };
361 
362 template<> struct Operand<ny::ir::isa::Op::fadd> final {
363  constexpr static const char* opname() {
364  return "fadd";
365  }
366  uint32_t opcode;
367  uint32_t lvid;
368  uint32_t lhs;
369  uint32_t rhs;
370  template<class T> void eachLVID(T& c) {
371  c(lvid, lhs, rhs);
372  }
373 };
374 
375 template<> struct Operand<ny::ir::isa::Op::fsub> final {
376  constexpr static const char* opname() {
377  return "fsub";
378  }
379  uint32_t opcode;
380  uint32_t lvid;
381  uint32_t lhs;
382  uint32_t rhs;
383 
384  template<class T> void eachLVID(T& c) {
385  c(lvid, lhs, rhs);
386  }
387 };
388 
389 template<> struct Operand<ny::ir::isa::Op::fmul> final {
390  constexpr static const char* opname() {
391  return "fmul";
392  }
393  uint32_t opcode;
394  uint32_t lvid;
395  uint32_t lhs;
396  uint32_t rhs;
397 
398  template<class T> void eachLVID(T& c) {
399  c(lvid, lhs, rhs);
400  }
401 };
402 
403 template<> struct Operand<ny::ir::isa::Op::fdiv> final {
404  constexpr static const char* opname() {
405  return "fdiv";
406  }
407  uint32_t opcode;
408  uint32_t lvid;
409  uint32_t lhs;
410  uint32_t rhs;
411 
412  template<class T> void eachLVID(T& c) {
413  c(lvid, lhs, rhs);
414  }
415 };
416 
417 template<> struct Operand<ny::ir::isa::Op::add> final {
418  constexpr static const char* opname() {
419  return "add";
420  }
421  uint32_t opcode;
422  uint32_t lvid;
423  uint32_t lhs;
424  uint32_t rhs;
425 
426  template<class T> void eachLVID(T& c) {
427  c(lvid, lhs, rhs);
428  }
429 };
430 
431 template<> struct Operand<ny::ir::isa::Op::sub> final {
432  constexpr static const char* opname() {
433  return "sub";
434  }
435  uint32_t opcode;
436  uint32_t lvid;
437  uint32_t lhs;
438  uint32_t rhs;
439 
440  template<class T> void eachLVID(T& c) {
441  c(lvid, lhs, rhs);
442  }
443 };
444 
445 template<> struct Operand<ny::ir::isa::Op::mul> final {
446  constexpr static const char* opname() {
447  return "mul";
448  }
449  uint32_t opcode;
450  uint32_t lvid;
451  uint32_t lhs;
452  uint32_t rhs;
453 
454  template<class T> void eachLVID(T& c) {
455  c(lvid, lhs, rhs);
456  }
457 };
458 
459 template<> struct Operand<ny::ir::isa::Op::div> final {
460  constexpr static const char* opname() {
461  return "div";
462  }
463  uint32_t opcode;
464  uint32_t lvid;
465  uint32_t lhs;
466  uint32_t rhs;
467 
468  template<class T> void eachLVID(T& c) {
469  c(lvid, lhs, rhs);
470  }
471 };
472 
473 template<> struct Operand<ny::ir::isa::Op::imul> final {
474  constexpr static const char* opname() {
475  return "imul";
476  }
477  uint32_t opcode;
478  uint32_t lvid;
479  uint32_t lhs;
480  uint32_t rhs;
481 
482  template<class T> void eachLVID(T& c) {
483  c(lvid, lhs, rhs);
484  }
485 };
486 
487 template<> struct Operand<ny::ir::isa::Op::idiv> final {
488  constexpr static const char* opname() {
489  return "idiv";
490  }
491  uint32_t opcode;
492  uint32_t lvid;
493  uint32_t lhs;
494  uint32_t rhs;
495 
496  template<class T> void eachLVID(T& c) {
497  c(lvid, lhs, rhs);
498  }
499 };
500 
501 template<> struct Operand<ny::ir::isa::Op::fieldget> final {
502  constexpr static const char* opname() {
503  return "fieldget";
504  }
505  uint32_t opcode;
506  uint32_t lvid; // dest pointer
507  uint32_t self;
508  uint32_t var;
509  template<class T> void eachLVID(T& c) {
510  c(lvid, self);
511  }
512 };
513 
514 template<> struct Operand<ny::ir::isa::Op::fieldset> final {
515  constexpr static const char* opname() {
516  return "fieldset";
517  }
518  uint32_t opcode;
519  uint32_t lvid; // value
520  uint32_t self;
521  uint32_t var;
522  template<class T> void eachLVID(T& c) {
523  c(lvid, self);
524  }
525 };
526 
527 template<> struct Operand<ny::ir::isa::Op::stacksize> final {
528  constexpr static const char* opname() {
529  return "stacksize";
530  }
531  uint32_t opcode;
532  uint32_t add;
533  template<class T> void eachLVID(T&) {}
534 };
535 
536 template<> struct Operand<ny::ir::isa::Op::comment> final {
537  constexpr static const char* opname() {
538  return "comment";
539  }
540  uint32_t opcode;
541  uint32_t text;
542  template<class T> void eachLVID(T&) {}
543 };
544 
545 template<> struct Operand<ny::ir::isa::Op::stackalloc> final {
546  constexpr static const char* opname() {
547  return "stackalloc";
548  }
549  uint32_t opcode;
550  uint32_t lvid;
551  uint32_t type; // nytype_t
552  uint32_t atomid; // atom id if (type == any)
553  template<class T> void eachLVID(T& c) {
554  c(lvid);
555  }
556 };
557 
558 template<> struct Operand<ny::ir::isa::Op::storeConstant> final {
559  constexpr static const char* opname() {
560  return "storeConstant";
561  }
562  uint32_t opcode;
563  uint32_t lvid;
564  union {
565  uint64_t u64;
566  double f64;
567  } value;
568  template<class T> void eachLVID(T& c) {
569  c(lvid);
570  }
571 };
572 
573 template<> struct Operand<ny::ir::isa::Op::storeText> final {
574  constexpr static const char* opname() {
575  return "storeText";
576  }
577  uint32_t opcode;
578  uint32_t lvid;
579  uint32_t text;
580  template<class T> void eachLVID(T& c) {
581  c(lvid);
582  }
583 };
584 
585 template<> struct Operand<ny::ir::isa::Op::store> final {
586  constexpr static const char* opname() {
587  return "store";
588  }
589  uint32_t opcode;
590  uint32_t lvid;
591  uint32_t source;
592  template<class T> void eachLVID(T& c) {
593  c(lvid);
594  }
595 };
596 
597 template<> struct Operand<ny::ir::isa::Op::ret> final {
598  constexpr static const char* opname() {
599  return "ret";
600  }
601  uint32_t opcode;
602  uint32_t lvid;
603  uint32_t tmplvid; // unused by nyprogram_t
604  template<class T> void eachLVID(T& c) {
605  c(lvid, tmplvid);
606  }
607 };
608 
609 template<> struct Operand<ny::ir::isa::Op::push> final {
610  constexpr static const char* opname() {
611  return "push";
612  }
613  uint32_t opcode;
614  uint32_t lvid;
615  uint32_t name; // if named parameter
616  template<class T> void eachLVID(T& c) {
617  c(lvid);
618  }
619 };
620 
621 template<> struct Operand<ny::ir::isa::Op::tpush> final {
622  constexpr static const char* opname() {
623  return "tpush";
624  }
625  uint32_t opcode;
626  uint32_t lvid;
627  uint32_t name; // if named parameter
628  template<class T> void eachLVID(T& c) {
629  c(lvid);
630  }
631 };
632 
633 template<> struct Operand<ny::ir::isa::Op::call> final {
634  constexpr static const char* opname() {
635  return "call";
636  }
637  uint32_t opcode;
638  uint32_t lvid;
639  uint32_t ptr2func; // or atomid
640  uint32_t instanceid;
641  template<class T> void eachLVID(T& c) {
642  c(lvid, ptr2func);
643  }
644 };
645 
646 template<> struct Operand<ny::ir::isa::Op::intrinsic> final {
647  constexpr static const char* opname() {
648  return "intrinsic";
649  }
650  uint32_t opcode;
651  uint32_t lvid;
653  uint32_t iid;
654  // intrinsic name
655  uint32_t intrinsic;
656  template<class T> void eachLVID(T& c) {
657  c(lvid);
658  }
659 };
660 
661 template<> struct Operand<ny::ir::isa::Op::debugfile> final {
662  constexpr static const char* opname() {
663  return "debugfile";
664  }
665  uint32_t opcode;
666  uint32_t filename;
667  template<class T> void eachLVID(T&) {}
668 };
669 
670 template<> struct Operand<ny::ir::isa::Op::namealias> final {
671  constexpr static const char* opname() {
672  return "namealias";
673  }
674  uint32_t opcode;
675  uint32_t lvid;
676  uint32_t name;
677  template<class T> void eachLVID(T& c) {
678  c(lvid);
679  }
680 };
681 
682 template<> struct Operand<ny::ir::isa::Op::debugpos> final {
683  constexpr static const char* opname() {
684  return "debugpos";
685  }
686  uint32_t opcode;
687  uint32_t line;
688  uint32_t offset;
689  template<class T> void eachLVID(T&) {}
690 };
691 
692 template<> struct Operand<ny::ir::isa::Op::scope> final {
693  constexpr static const char* opname() {
694  return "scope";
695  }
696  uint32_t opcode;
697  template<class T> void eachLVID(T&) {}
698 };
699 
700 template<> struct Operand<ny::ir::isa::Op::end> final {
701  constexpr static const char* opname() {
702  return "end";
703  }
704  uint32_t opcode;
705  template<class T> void eachLVID(T&) {}
706 };
707 
708 template<> struct Operand<ny::ir::isa::Op::qualifiers> final {
709  constexpr static const char* opname() {
710  return "qualifiers";
711  }
712  uint32_t opcode;
713  uint32_t lvid;
714  TypeQualifier qualifier;
715  uint32_t flag;
716 
717  template<class T> void eachLVID(T& c) {
718  static_assert(sizeof(Operand<ny::ir::isa::Op::qualifiers>) <= sizeof(uint32_t) * 4, "alignment required");
719  c(lvid);
720  }
721 };
722 
723 template<> struct Operand<ny::ir::isa::Op::opassert> final {
724  constexpr static const char* opname() {
725  return "assert";
726  }
727  uint32_t opcode;
728  uint32_t lvid;
729  template<class T> void eachLVID(T& c) {
730  c(lvid);
731  }
732 };
733 
734 template<> struct Operand<ny::ir::isa::Op::memcheckhold> final {
735  constexpr static const char* opname() {
736  return "memcheckhold";
737  }
738  uint32_t opcode;
739  uint32_t lvid;
740  uint32_t size;
741  template<class T> void eachLVID(T& c) {
742  c(lvid, size);
743  }
744 };
745 
746 template<> struct Operand<ny::ir::isa::Op::label> final {
747  constexpr static const char* opname() {
748  return "label";
749  }
750  uint32_t opcode;
751  uint32_t label;
752  template<class T> void eachLVID(T& c) {
753  c(label);
754  }
755 };
756 
757 template<> struct Operand<ny::ir::isa::Op::jmp> final {
758  constexpr static const char* opname() {
759  return "jmp";
760  }
761  uint32_t opcode;
762  uint32_t label;
763  template<class T> void eachLVID(T&) {}
764 };
765 
766 template<> struct Operand<ny::ir::isa::Op::jz> final {
767  constexpr static const char* opname() {
768  return "jz";
769  }
770  uint32_t opcode;
771  uint32_t lvid; // the local variable
772  uint32_t result; // local variable to set to 1 if jump
773  uint32_t label;
774  template<class T> void eachLVID(T& c) {
775  c(lvid, result);
776  }
777 };
778 
779 template<> struct Operand<ny::ir::isa::Op::jnz> final {
780  constexpr static const char* opname() {
781  return "jnz";
782  }
783  uint32_t opcode;
784  uint32_t lvid; // the local variable
785  uint32_t result; // local variable to set to 1 if jump
786  uint32_t label;
787  template<class T> void eachLVID(T& c) {
788  c(lvid, result);
789  }
790 };
791 
792 template<> struct Operand<ny::ir::isa::Op::memalloc> final {
793  constexpr static const char* opname() {
794  return "memalloc";
795  }
796  uint32_t opcode;
797  uint32_t lvid;
798  uint32_t regsize;
799  template<class T> void eachLVID(T& c) {
800  c(lvid, regsize);
801  }
802 };
803 
804 template<> struct Operand<ny::ir::isa::Op::memfree> final {
805  constexpr static const char* opname() {
806  return "memfree";
807  }
808  uint32_t opcode;
809  uint32_t lvid;
810  uint32_t regsize;
811  template<class T> void eachLVID(T& c) {
812  c(lvid, regsize);
813  }
814 };
815 
816 template<> struct Operand<ny::ir::isa::Op::memfill> final {
817  constexpr static const char* opname() {
818  return "memfill";
819  }
820  uint32_t opcode;
821  uint32_t lvid;
822  uint32_t regsize;
823  uint32_t pattern;
824  template<class T> void eachLVID(T& c) {
825  c(lvid, regsize);
826  }
827 };
828 
829 template<> struct Operand<ny::ir::isa::Op::memcopy> final {
830  constexpr static const char* opname() {
831  return "memcopy";
832  }
833  uint32_t opcode;
834  uint32_t lvid;
835  uint32_t srclvid;
836  uint32_t regsize;
837  template<class T> void eachLVID(T& c) {
838  c(lvid, srclvid, regsize);
839  }
840 };
841 
842 template<> struct Operand<ny::ir::isa::Op::memmove> final {
843  constexpr static const char* opname() {
844  return "memmove";
845  }
846  uint32_t opcode;
847  uint32_t lvid;
848  uint32_t srclvid;
849  uint32_t regsize;
850  template<class T> void eachLVID(T& c) {
851  c(lvid, srclvid, regsize);
852  }
853 };
854 
855 template<> struct Operand<ny::ir::isa::Op::memcmp> final {
856  constexpr static const char* opname() {
857  return "memcmp";
858  }
859  uint32_t opcode;
860  uint32_t lvid;
861  uint32_t srclvid;
862  uint32_t regsize; // and result as well
863  template<class T> void eachLVID(T& c) {
864  c(lvid, srclvid, regsize);
865  }
866 };
867 
868 template<> struct Operand<ny::ir::isa::Op::cstrlen> final {
869  constexpr static const char* opname() {
870  return "cstrlen";
871  }
872  uint32_t opcode;
873  uint32_t lvid;
874  uint32_t bits;
875  uint32_t ptr;
876  template<class T> void eachLVID(T& c) {
877  c(lvid, ptr);
878  }
879 };
880 
881 template<> struct Operand<ny::ir::isa::Op::load_u64> final {
882  constexpr static const char* opname() {
883  return "load_u64";
884  }
885  uint32_t opcode;
886  uint32_t lvid;
887  uint32_t ptrlvid;
888  template<class T> void eachLVID(T& c) {
889  c(lvid, ptrlvid);
890  }
891 };
892 template<> struct Operand<ny::ir::isa::Op::load_u32> final {
893  constexpr static const char* opname() {
894  return "load_u32";
895  }
896  uint32_t opcode;
897  uint32_t lvid;
898  uint32_t ptrlvid;
899  template<class T> void eachLVID(T& c) {
900  c(lvid, ptrlvid);
901  }
902 };
903 template<> struct Operand<ny::ir::isa::Op::load_u8> final {
904  constexpr static const char* opname() {
905  return "load_u8";
906  }
907  uint32_t opcode;
908  uint32_t lvid;
909  uint32_t ptrlvid;
910  template<class T> void eachLVID(T& c) {
911  c(lvid, ptrlvid);
912  }
913 };
914 
915 template<> struct Operand<ny::ir::isa::Op::store_u64> final {
916  constexpr static const char* opname() {
917  return "store_u64";
918  }
919  uint32_t opcode;
920  uint32_t lvid;
921  uint32_t ptrlvid;
922  template<class T> void eachLVID(T& c) {
923  c(lvid, ptrlvid);
924  }
925 };
926 template<> struct Operand<ny::ir::isa::Op::store_u32> final {
927  constexpr static const char* opname() {
928  return "store_u32";
929  }
930  uint32_t opcode;
931  uint32_t lvid;
932  uint32_t ptrlvid;
933  template<class T> void eachLVID(T& c) {
934  c(lvid, ptrlvid);
935  }
936 };
937 template<> struct Operand<ny::ir::isa::Op::store_u8> final {
938  constexpr static const char* opname() {
939  return "store_u8";
940  }
941  uint32_t opcode;
942  uint32_t lvid;
943  uint32_t ptrlvid;
944  template<class T> void eachLVID(T& c) {
945  c(lvid, ptrlvid);
946  }
947 };
948 
949 template<> struct Operand<ny::ir::isa::Op::memrealloc> final {
950  constexpr static const char* opname() {
951  return "memrealloc";
952  }
953  uint32_t opcode;
954  uint32_t lvid;
955  uint32_t oldsize;
956  uint32_t newsize;
957  template<class T> void eachLVID(T& c) {
958  c(lvid, oldsize, newsize);
959  }
960 };
961 
962 template<> struct Operand<ny::ir::isa::Op::pragma> final {
963  constexpr static const char* opname() {
964  return "pragma";
965  }
966  uint32_t opcode;
967  Pragma pragma;
968 
969  union {
970  uint32_t codegen;
971  uint32_t error;
972  uint32_t visibility;
973  uint32_t blueprintsize;
974  uint32_t shortcircuit;
975  uint32_t suggest;
976  struct {
977  uint32_t lvid;
978  uint32_t onoff;
979  } synthetic;
980  struct {
981  uint32_t namesid;
982  } builtinalias;
983  struct {
984  uint32_t label;
985  } shortcircuitMetadata;
986  struct {
987  uint32_t lvid;
988  uint32_t source;
989  } shortcircuitMutate;
990  }
991  value;
992 
993  template<class T> void eachLVID(T& c) {
994  static_assert(sizeof(Operand<ny::ir::isa::Op::pragma>) <= sizeof(uint32_t) * 4, "alignment required");
995  switch (pragma) {
996  case Pragma::synthetic: {
997  c(value.synthetic.lvid);
998  break;
999  }
1000  case Pragma::shortcircuitOpNopOffset: {
1001  c(value.shortcircuitMetadata.label);
1002  break;
1003  }
1004  case Pragma::shortcircuitMutateToBool: {
1005  c(value.shortcircuitMutate.lvid);
1006  break;
1007  }
1008  case Pragma::unknown:
1009  case Pragma::codegen:
1010  case Pragma::blueprintsize:
1011  case Pragma::visibility:
1012  case Pragma::bodystart:
1013  case Pragma::shortcircuit:
1014  case Pragma::builtinalias:
1015  case Pragma::suggest:
1016  break;
1017  }
1018  }
1019 };
1020 
1021 template<> struct Operand<ny::ir::isa::Op::blueprint> final {
1022  constexpr static const char* opname() {
1023  return "blueprint";
1024  }
1025 
1026  uint32_t opcode;
1029  uint32_t kind: 4;
1031  uint32_t lvid: 28; // should be big enough even for large func
1033  uint32_t name;
1035  uint32_t atomid;
1036 
1037  void setLVID(uint32_t newlvid) { // only to avoid warning
1038  union {
1039  uint32_t i;
1040  uint32_t lvid: 28;
1041  } converter {newlvid};
1042  lvid = converter.lvid;
1043  }
1044  template<class T> void eachLVID(T& c) {
1045  static_assert(sizeof(Operand<ny::ir::isa::Op::blueprint>) <= sizeof(uint32_t) * 4, "alignment required");
1046  uint32_t cplvid = lvid;
1047  c(cplvid);
1048  setLVID(cplvid);
1049  }
1050 };
1051 
1052 template<> struct Operand<ny::ir::isa::Op::self> final {
1053  constexpr static const char* opname() {
1054  return "self";
1055  }
1056  uint32_t opcode;
1057  uint32_t self;
1058  template<class T> void eachLVID(T& c) {
1059  c(self);
1060  }
1061 };
1062 
1063 template<> struct Operand<ny::ir::isa::Op::identify> final {
1064  constexpr static const char* opname() {
1065  return "identify";
1066  }
1067  uint32_t opcode;
1068  uint32_t lvid;
1069  uint32_t self;
1070  uint32_t text;
1071  template<class T> void eachLVID(T& c) {
1072  c(lvid, self);
1073  }
1074 };
1075 template<> struct Operand<ny::ir::isa::Op::identifyset> final { // MUST be identical to 'identify'
1076  constexpr static const char* opname() {
1077  return "identifyset";
1078  }
1079  uint32_t opcode;
1080  uint32_t lvid;
1081  uint32_t self;
1082  uint32_t text;
1083  template<class T> void eachLVID(T& c) {
1084  c(lvid, self);
1085  }
1086 };
1087 
1088 template<> struct Operand<ny::ir::isa::Op::ensureresolved> final {
1089  constexpr static const char* opname() {
1090  return "ensureresolved";
1091  }
1092  uint32_t opcode;
1093  uint32_t lvid;
1094  template<class T> void eachLVID(T& c) {
1095  c(lvid);
1096  }
1097 };
1098 
1099 template<> struct Operand<ny::ir::isa::Op::commontype> final {
1100  constexpr static const char* opname() {
1101  return "commontype";
1102  }
1103  uint32_t opcode;
1104  uint32_t lvid;
1105  uint32_t previous;
1106  template<class T> void eachLVID(T& c) {
1107  c(lvid, previous);
1108  }
1109 };
1110 
1111 template<> struct Operand<ny::ir::isa::Op::assign> final {
1112  constexpr static const char* opname() {
1113  return "assign";
1114  }
1115  uint32_t opcode;
1116  uint32_t lhs;
1117  uint32_t rhs;
1118  uint32_t disposelhs;
1119  template<class T> void eachLVID(T& c) {
1120  c(lhs, rhs);
1121  }
1122 };
1123 
1124 template<> struct Operand<ny::ir::isa::Op::follow> final {
1125  constexpr static const char* opname() {
1126  return "follow";
1127  }
1128  uint32_t opcode;
1129  uint32_t lvid;
1130  uint32_t follower;
1131  uint32_t symlink;
1132  template<class T> void eachLVID(T& c) {
1133  c(lvid, follower);
1134  }
1135 };
1136 
1137 template<> struct Operand<ny::ir::isa::Op::typeisobject> final {
1138  constexpr static const char* opname() {
1139  return "typeisobject";
1140  }
1141  uint32_t opcode;
1142  uint32_t lvid;
1143  template<class T> void eachLVID(T& c) {
1144  c(lvid);
1145  }
1146 };
1147 
1148 template<> struct Operand<ny::ir::isa::Op::classdefsizeof> final {
1149  constexpr static const char* opname() {
1150  return "classdefsizeof";
1151  }
1152  uint32_t opcode;
1153  uint32_t lvid;
1154  uint32_t type; // lvid or atomid
1155  template<class T> void eachLVID(T& c) {
1156  c(lvid, type);
1157  }
1158 };
1159 
1160 template<> struct Operand<ny::ir::isa::Op::ref> final {
1161  constexpr static const char* opname() {
1162  return "ref";
1163  }
1164  uint32_t opcode;
1165  uint32_t lvid;
1166  template<class T> void eachLVID(T& c) {
1167  c(lvid);
1168  }
1169 };
1170 
1171 template<> struct Operand<ny::ir::isa::Op::unref> final {
1172  constexpr static const char* opname() {
1173  return "unref";
1174  }
1175  uint32_t opcode;
1176  uint32_t lvid;
1177 
1178  // atomid
1179  uint32_t atomid; // or atomid
1180  // destructor to call
1181  uint32_t instanceid;
1182 
1183  template<class T> void eachLVID(T& c) {
1184  c(lvid);
1185  }
1186 };
1187 
1188 template<> struct Operand<ny::ir::isa::Op::allocate> final {
1189  constexpr static const char* opname() {
1190  return "allocate";
1191  }
1192  uint32_t opcode;
1193  uint32_t lvid;
1194  // atomid
1195  uint32_t atomid; // or atomid
1196  template<class T> void eachLVID(T& c) {
1197  c(lvid);
1198  }
1199 };
1200 
1201 template<> struct Operand<ny::ir::isa::Op::dispose> final {
1202  constexpr static const char* opname() {
1203  return "dispose";
1204  }
1205  uint32_t opcode;
1206  uint32_t lvid;
1207 
1208  // atomid
1209  uint32_t atomid; // or atomid
1210  // destructor to call
1211  uint32_t instanceid;
1212 
1213  template<class T> void eachLVID(T& c) {
1214  c(lvid);
1215  }
1216 };
1217 
1218 
1219 
1220 Yuni::String print(const Sequence&, const ny::ir::Instruction&, const AtomMap* = nullptr);
1221 
1222 template<ny::ir::isa::Op O>
1223 inline Yuni::String
1224 print(const Sequence& sequence, const ny::ir::isa::Operand<O>& operands, const AtomMap* map = nullptr) {
1225  return print(sequence, reinterpret_cast<const ny::ir::Instruction&>(operands), map);
1226 }
1227 
1228 void printExtract(YString& out, const Sequence&, uint32_t offset, const AtomMap* = nullptr);
1229 
1230 
1231 } // namespace isa
1232 } // namespace ir
1233 } // namespace ny
uint32_t name
Blueprint name.
Definition: data.h:1033
Definition: ast.cpp:6
uint32_t atomid
Attached atomid (if any)
Definition: data.h:1035
Atoms.
Definition: atom-map.h:17
Definition: instruction.h:12
uint32_t iid
Intrinsic ID (only valid at execution)
Definition: data.h:653
Definition: data.h:85
Definition: sequence.h:22