1 /*
2  * Copyright (C) 2002-2014, Parrot Foundation.
3  */
4 
5 #ifndef PARROT_IMCC_INSTRUCTIONS_H_GUARD
6 #define PARROT_IMCC_INSTRUCTIONS_H_GUARD
7 
8 /* Types */
9 
10 enum INSTYPE {    /* instruction type can be   */
11     ITBRANCH   =   0x10000, /*  branch        */
12     ITPCCRET   =   0x20000, /*  PCC sub return */
13     ITCALL     =   0x40000, /*  function call */
14     ITLABEL    =   0x80000, /*  label         */
15     ITPCCPARAM =  0x100000, /*  .get_params */
16     ITPUREFUNC =  0x200000, /*  purely functional, no sideeffects */
17     ITRESULT   =  0x400000, /*  .get_results */
18     ITPCCSUB   = 0x1000000, /*  PCC sub call */
19     ITPCCYIELD = 0x2000000  /*  yield from PCC call instead of return */
20 };
21 
22 
23 typedef struct _Instruction {
24     char        *opname;   /* opstring w/o params */
25     char        *format;   /* printf style format string for params   */
26     int          keys;     /* bitmask of keys used in this instruction */
27     unsigned int flags;    /* how the instruction affects each of the values */
28     unsigned int type;     /* 16 bit register branches, + ITxxx */
29     unsigned int index;    /* index on instructions[] */
30     unsigned int bbindex;  /* number of basic block containing instruction */
31 
32     struct _Instruction *prev;
33     struct _Instruction *next;
34 
35     op_info_t *op;         /* parrot opcode */
36     int     opsize;        /* parrot op size   */
37     int     line;          /* source code line number */
38     int     symreg_count;  /* count of regs in **symregs */
39     SymReg *symregs[1];    /* instruction is allocated variable sized
40                               to hold more SymRegs */
41 } Instruction;
42 
43 
44 /* XXX fix flags [bitmap]
45  * int flags_r
46  * int flags_w
47  * int flags_jump
48  */
49 #define INSTRUCTION_BIT(n) ((UINTVAL)1 << (n))
50 typedef enum {
51     /* Indicate how the instruction affects each of the registers */
52     IF_r0_read      = INSTRUCTION_BIT(0),
53     IF_r1_read      = INSTRUCTION_BIT(1),
54     IF_r2_read      = INSTRUCTION_BIT(2),
55     IF_r3_read      = INSTRUCTION_BIT(3),
56     /* .... */
57     IF_r0_write     = INSTRUCTION_BIT(16),
58     IF_r1_write     = INSTRUCTION_BIT(17),
59     IF_r2_write     = INSTRUCTION_BIT(18),
60     IF_r3_write     = INSTRUCTION_BIT(19),
61     /* .... */
62     IF_binary       = (IF_r0_write|IF_r1_read|IF_r2_read), /* templ for binary op */
63     IF_unary        = (IF_r0_write|IF_r1_read),           /* templ for unary  op */
64     IF_inplace      = (IF_r0_write|IF_r0_read),    /* templ for inplace unary  op */
65     /* the branch flags are the low 16 bits of type
66      * for upper 16 see ITXX above */
67     IF_r0_branch    = INSTRUCTION_BIT(0),
68     IF_r1_branch    = INSTRUCTION_BIT(1),
69     IF_r2_branch    = INSTRUCTION_BIT(2),
70     IF_r3_branch    = INSTRUCTION_BIT(3),
71     IF_goto         = INSTRUCTION_BIT(15)
72 } Instruction_Flags;
73 #undef INSTRUCTION_BIT
74 
75 /* HEADERIZER BEGIN: compilers/imcc/instructions.c */
76 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
77 
78 PARROT_WARN_UNUSED_RESULT
79 PARROT_CAN_RETURN_NULL
80 Instruction * _delete_ins(ARGMOD(IMC_Unit *unit), ARGIN(Instruction *ins))
81         __attribute__nonnull__(1)
82         __attribute__nonnull__(2)
83         FUNC_MODIFIES(*unit);
84 
85 PARROT_MALLOC
86 PARROT_CANNOT_RETURN_NULL
87 Instruction * _mk_instruction(
88     ARGIN(const char *op),
89     ARGIN(const char *fmt),
90     int n,
91     ARGIN(SymReg * const *r),
92     int flags)
93         __attribute__nonnull__(1)
94         __attribute__nonnull__(2)
95         __attribute__nonnull__(4);
96 
97 PARROT_WARN_UNUSED_RESULT
98 PARROT_CAN_RETURN_NULL
99 Instruction * delete_ins(ARGMOD(IMC_Unit *unit), ARGMOD(Instruction *ins))
100         __attribute__nonnull__(1)
101         __attribute__nonnull__(2)
102         FUNC_MODIFIES(*unit)
103         FUNC_MODIFIES(*ins);
104 
105 void emit_close(ARGMOD(imc_info_t *imcc), ARGIN_NULLOK(void *param))
106         __attribute__nonnull__(1)
107         FUNC_MODIFIES(*imcc);
108 
109 void emit_flush(
110     ARGMOD(imc_info_t * imcc),
111     ARGIN_NULLOK(void *param),
112     ARGIN(IMC_Unit *unit))
113         __attribute__nonnull__(1)
114         __attribute__nonnull__(3)
115         FUNC_MODIFIES(* imcc);
116 
117 void emit_open(ARGMOD(imc_info_t * imcc))
118         __attribute__nonnull__(1)
119         FUNC_MODIFIES(* imcc);
120 
121 PARROT_CAN_RETURN_NULL
122 Instruction * emitb(
123     ARGMOD(imc_info_t * imcc),
124     ARGMOD_NULLOK(IMC_Unit *unit),
125     ARGIN_NULLOK(Instruction *i))
126         __attribute__nonnull__(1)
127         FUNC_MODIFIES(* imcc)
128         FUNC_MODIFIES(*unit);
129 
130 void free_ins(ARGMOD(Instruction *ins))
131         __attribute__nonnull__(1)
132         FUNC_MODIFIES(*ins);
133 
134 PARROT_WARN_UNUSED_RESULT
135 PARROT_CAN_RETURN_NULL
136 SymReg * get_branch_reg(ARGIN(const Instruction *ins))
137         __attribute__nonnull__(1);
138 
139 int get_branch_regno(ARGIN(const Instruction *ins))
140         __attribute__nonnull__(1);
141 
142 PARROT_IGNORABLE_RESULT
143 int /*@alt void@*/
144 ins_print(
145     ARGMOD(imc_info_t * imcc),
146     PIOHANDLE io,
147     ARGIN(const Instruction *ins))
148         __attribute__nonnull__(1)
149         __attribute__nonnull__(3)
150         FUNC_MODIFIES(* imcc);
151 
152 void insert_ins(
153     ARGMOD(IMC_Unit *unit),
154     ARGMOD_NULLOK(Instruction *ins),
155     ARGMOD(Instruction *tmp))
156         __attribute__nonnull__(1)
157         __attribute__nonnull__(3)
158         FUNC_MODIFIES(*unit)
159         FUNC_MODIFIES(*ins)
160         FUNC_MODIFIES(*tmp);
161 
162 int instruction_reads(ARGIN(const Instruction *ins), ARGIN(const SymReg *r))
163         __attribute__nonnull__(1)
164         __attribute__nonnull__(2);
165 
166 int instruction_writes(
167     ARGIN(const Instruction *ins),
168     ARGIN(const SymReg *r))
169         __attribute__nonnull__(1)
170         __attribute__nonnull__(2);
171 
172 PARROT_CAN_RETURN_NULL
173 Instruction * move_ins(
174     ARGMOD(IMC_Unit *unit),
175     ARGMOD(Instruction *ins),
176     ARGMOD(Instruction *to))
177         __attribute__nonnull__(1)
178         __attribute__nonnull__(2)
179         __attribute__nonnull__(3)
180         FUNC_MODIFIES(*unit)
181         FUNC_MODIFIES(*ins)
182         FUNC_MODIFIES(*to);
183 
184 void prepend_ins(
185     ARGMOD(IMC_Unit *unit),
186     ARGMOD_NULLOK(Instruction *ins),
187     ARGMOD(Instruction *tmp))
188         __attribute__nonnull__(1)
189         __attribute__nonnull__(3)
190         FUNC_MODIFIES(*unit)
191         FUNC_MODIFIES(*ins)
192         FUNC_MODIFIES(*tmp);
193 
194 void subst_ins(
195     ARGMOD(IMC_Unit *unit),
196     ARGMOD(Instruction *ins),
197     ARGMOD(Instruction *tmp),
198     int needs_freeing)
199         __attribute__nonnull__(1)
200         __attribute__nonnull__(2)
201         __attribute__nonnull__(3)
202         FUNC_MODIFIES(*unit)
203         FUNC_MODIFIES(*ins)
204         FUNC_MODIFIES(*tmp);
205 
206 #define ASSERT_ARGS__delete_ins __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
207        PARROT_ASSERT_ARG(unit) \
208     , PARROT_ASSERT_ARG(ins))
209 #define ASSERT_ARGS__mk_instruction __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
210        PARROT_ASSERT_ARG(op) \
211     , PARROT_ASSERT_ARG(fmt) \
212     , PARROT_ASSERT_ARG(r))
213 #define ASSERT_ARGS_delete_ins __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
214        PARROT_ASSERT_ARG(unit) \
215     , PARROT_ASSERT_ARG(ins))
216 #define ASSERT_ARGS_emit_close __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
217        PARROT_ASSERT_ARG(imcc))
218 #define ASSERT_ARGS_emit_flush __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
219        PARROT_ASSERT_ARG(imcc) \
220     , PARROT_ASSERT_ARG(unit))
221 #define ASSERT_ARGS_emit_open __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
222        PARROT_ASSERT_ARG(imcc))
223 #define ASSERT_ARGS_emitb __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
224        PARROT_ASSERT_ARG(imcc))
225 #define ASSERT_ARGS_free_ins __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
226        PARROT_ASSERT_ARG(ins))
227 #define ASSERT_ARGS_get_branch_reg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
228        PARROT_ASSERT_ARG(ins))
229 #define ASSERT_ARGS_get_branch_regno __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
230        PARROT_ASSERT_ARG(ins))
231 #define ASSERT_ARGS_ins_print __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
232        PARROT_ASSERT_ARG(imcc) \
233     , PARROT_ASSERT_ARG(ins))
234 #define ASSERT_ARGS_insert_ins __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
235        PARROT_ASSERT_ARG(unit) \
236     , PARROT_ASSERT_ARG(tmp))
237 #define ASSERT_ARGS_instruction_reads __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
238        PARROT_ASSERT_ARG(ins) \
239     , PARROT_ASSERT_ARG(r))
240 #define ASSERT_ARGS_instruction_writes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
241        PARROT_ASSERT_ARG(ins) \
242     , PARROT_ASSERT_ARG(r))
243 #define ASSERT_ARGS_move_ins __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
244        PARROT_ASSERT_ARG(unit) \
245     , PARROT_ASSERT_ARG(ins) \
246     , PARROT_ASSERT_ARG(to))
247 #define ASSERT_ARGS_prepend_ins __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
248        PARROT_ASSERT_ARG(unit) \
249     , PARROT_ASSERT_ARG(tmp))
250 #define ASSERT_ARGS_subst_ins __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
251        PARROT_ASSERT_ARG(unit) \
252     , PARROT_ASSERT_ARG(ins) \
253     , PARROT_ASSERT_ARG(tmp))
254 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will be lost. */
255 /* HEADERIZER END: compilers/imcc/instructions.c */
256 
257 /*
258  * _mk_instruction and iANY are not intended for outside usage
259  * please use INS
260  */
261 #ifndef _PARSER
262 #  define _mk_instruction(a, b, n, c, d) dont_use_this_function((a), (b))
263 #endif
264 /* This macro must come after the declaration of _mk_instruction() */
265 
266 #endif /* PARROT_IMCC_INSTRUCTIONS_H_GUARD */
267 
268 
269 /*
270  * Local variables:
271  *   c-file-style: "parrot"
272  * End:
273  * vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
274  */
275 
276