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