aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir.h
blob: eee485994b39c76f32f23f081981041589ed546a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "common.h"

enum irclass {
   KXXX,
   KI4, KI8, KPTR,
   KF4, KF8,
};

#define kisint(k) in_range((k), KI4, KIP)
#define kisflt(k) in_range((k), KF4, KF8)

union irtype {
   struct { ushort isagg : 1, cls : 15; };
   struct { ushort _     : 1, dat : 15; };
   ushort bits;
};

struct irdat {
   uchar align : 7, mut : 1;
   uint siz;
   union {
      vec_of(uchar) dat;
      uchar sdat[8];
   };
   struct symref {
      struct symref *next;
      const char *sym;
      uint off;
      vlong addend;
   } *syms;
};

struct xcon {
   bool issym;
   uchar cls;
   union {
      const char *sym;
      int i4;
      vlong i8;
      float fs;
      double fd;
   };
};

struct call {
   short narg;
   short vararg; /* first variadic arg or -1 */
   union irtype *typs;
   union ref *args;
};

struct phi {
   struct block **blk;
   union ref *ref;
   int n, cap;
};

enum refkind {
   RNONE, RTMP, RARG, RICON, RXCON, RSYM, REXT
};

union ref {
   struct { uint t : 3, idx : 29; };
   struct { signed _0: 3, i : 29; }; /* RICON */
   uint bits;
};

enum op {
   Oxxx,
#define _(o,...) O##o,
#include "op.def"
#undef _
};

struct instr {
   uchar op;
   uchar cls;
   union ref l, r;
};

enum jumpkind {
   JXXX, Jb, Jbcnd, Jret, Jrets,
};

struct block {
   int id;
   struct block *s1, *s2;
   struct { uchar t; union ref arg; } jmp;   
   vec_of(ushort) phi;
   vec_of(ushort) ins;
   struct block *lprev, *lnext;
};

struct function {
   struct arena *arena;
   const char *name;
   struct block *entry, *curblk;
   union type fnty, retty, *paramty;
   uint nblk;
   uint nparam;
   bool globl;
};

extern uchar type2cls[];
extern uchar cls2siz[];
extern const uchar siz2intcls[];
void irinit(struct function *);
#define NOREF ((union ref) {0})
#define mkref(t, x) ((union ref) {{ (t), (x) }})
#define mkzerocon() ((union irref){ RICON, 0 })
union irtype mkirtype(union type);
union ref mkintcon(struct function *, enum irclass, vlong);
union ref mkfltcon(struct function *, enum irclass, double);
union ref mksymref(struct function *, const char *);
void conputdat(struct irdat *, uint off, enum typetag t, const void *dat);
union ref mkcall(struct function *, union type fnty, uint narg, union ref *, union irtype *);
union ref addinstr(struct function *, struct instr);
union ref addphi2(struct function *, enum irclass cls,
                  struct block *b1, union ref r1, struct block *b2, union ref r2);
struct block *newblk(struct function *);
void useblk(struct function *, struct block *);
void putjump(struct function *, enum jumpkind, union ref arg, struct block *t, struct block *f);
void irdump(struct function *, const char *fname);

/* vim:set ts=3 sw=3 expandtab: */