/opengles/src/codegen/instruction.h

http://ftk.googlecode.com/ · C Header · 641 lines · 482 code · 112 blank · 47 comment · 1 complexity · ce91354dd4047fc7a3520958075cc150 MD5 · raw file

  1. #ifndef CODEGEN_INSTRUCTION_H
  2. #define CODEGEN_INSTRUCTION_H 1
  3. /****************************************************************************/
  4. /* */
  5. /* Copyright (c) 2004, Hans-Martin Will. All rights reserved. */
  6. /* */
  7. /* Redistribution and use in source and binary forms, with or without */
  8. /* modification, are permitted provided that the following conditions are */
  9. /* met: */
  10. /* */
  11. /* * Redistributions of source code must retain the above copyright */
  12. /* notice, this list of conditions and the following disclaimer. */
  13. /* */
  14. /* * Redistributions in binary form must reproduce the above copyright */
  15. /* notice, this list of conditions and the following disclaimer in the */
  16. /* documentation and/or other materials provided with the distribution. */
  17. /* */
  18. /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
  19. /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
  20. /* LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A */
  21. /* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER */
  22. /* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */
  23. /* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, */
  24. /* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR */
  25. /* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
  26. /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
  27. /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
  28. /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
  29. /* */
  30. /****************************************************************************/
  31. #include "codegen.h"
  32. #include "heap.h"
  33. #ifdef __cplusplus
  34. extern "C" {
  35. #endif
  36. #if defined(__GCC32__) && defined(__cplusplus)
  37. struct cg_module_t;
  38. union cg_inst_t;
  39. struct cg_block_t;
  40. struct cg_proc_t;
  41. struct cg_virtual_reg_t;
  42. struct cg_block_ref_t;
  43. #else
  44. typedef struct cg_module_t cg_module_t;
  45. typedef union cg_inst_t cg_inst_t;
  46. typedef struct cg_block_t cg_block_t;
  47. typedef struct cg_proc_t cg_proc_t;
  48. typedef struct cg_virtual_reg_t cg_virtual_reg_t;
  49. typedef struct cg_block_ref_t cg_block_ref_t;
  50. #endif
  51. struct cg_label_t;
  52. struct cg_bitset_t;
  53. typedef enum cg_inst_kind_t {
  54. cg_inst_none,
  55. cg_inst_unary,
  56. cg_inst_binary,
  57. cg_inst_compare,
  58. cg_inst_load,
  59. cg_inst_store,
  60. cg_inst_load_immed,
  61. cg_inst_branch_label,
  62. cg_inst_branch_cond,
  63. cg_inst_phi,
  64. cg_inst_call,
  65. cg_inst_ret,
  66. // ARM specific formats
  67. cg_inst_arm_unary_immed,
  68. cg_inst_arm_unary_shift_reg,
  69. cg_inst_arm_unary_shift_immed,
  70. cg_inst_arm_binary_immed,
  71. cg_inst_arm_binary_shift_reg,
  72. cg_inst_arm_binary_shift_immed,
  73. cg_inst_arm_compare_immed,
  74. cg_inst_arm_compare_shift_reg,
  75. cg_inst_arm_compare_shift_immed,
  76. cg_inst_arm_load_immed_offset,
  77. cg_inst_arm_load_reg_offset,
  78. cg_inst_arm_store_immed_offset,
  79. cg_inst_arm_store_reg_offset,
  80. cg_inst_count
  81. }
  82. cg_inst_kind_t;
  83. typedef enum cg_opcode_t {
  84. cg_op_nop,
  85. cg_op_add, cg_op_and, cg_op_asr, cg_op_cmp, cg_op_div,
  86. cg_op_lsl, cg_op_lsr, cg_op_mod, cg_op_mul, cg_op_neg,
  87. cg_op_not, cg_op_or, cg_op_sub, cg_op_xor,
  88. cg_op_min, cg_op_max,
  89. cg_op_fadd, cg_op_fcmp, cg_op_fdiv, cg_op_fmul, cg_op_fneg,
  90. cg_op_fsub, cg_op_finv, cg_op_fsqrt, cg_op_abs, cg_op_log2,
  91. cg_op_trunc, cg_op_round, cg_op_fcnv,
  92. cg_op_beq, cg_op_bge, cg_op_ble, cg_op_bgt, cg_op_blt,
  93. cg_op_bne, cg_op_bra,
  94. cg_op_ldb, cg_op_ldh, cg_op_ldi, cg_op_ldw, cg_op_stb,
  95. cg_op_sth, cg_op_stw,
  96. cg_op_call, cg_op_ret, cg_op_phi
  97. }
  98. cg_opcode_t;
  99. typedef struct cg_inst_base_t
  100. {
  101. cg_inst_t * next;
  102. cg_block_t * block;
  103. cg_inst_kind_t kind;
  104. cg_opcode_t opcode;
  105. int used : 1;
  106. #ifndef NDEBUG
  107. const char * file;
  108. int line;
  109. #endif
  110. }
  111. cg_inst_base_t;
  112. typedef enum cg_shift_op_t
  113. {
  114. cg_shift_lsl,
  115. cg_shift_lsr,
  116. cg_shift_asr,
  117. cg_shift_ror
  118. }
  119. cg_shift_op_t;
  120. typedef union
  121. {
  122. cg_virtual_reg_t * source;
  123. I32 immed;
  124. struct
  125. {
  126. cg_virtual_reg_t * source;
  127. cg_virtual_reg_t * shift;
  128. cg_shift_op_t op;
  129. } shift_reg;
  130. struct
  131. {
  132. cg_virtual_reg_t * source;
  133. U32 shift;
  134. cg_shift_op_t op;
  135. } shift_immed;
  136. }
  137. cg_data_operand_t;
  138. typedef union
  139. {
  140. cg_virtual_reg_t * base;
  141. struct
  142. {
  143. cg_virtual_reg_t * base;
  144. cg_virtual_reg_t * offset;
  145. } reg_offset;
  146. struct
  147. {
  148. cg_virtual_reg_t * base;
  149. I32 offset;
  150. } immed_offset;
  151. }
  152. cg_mem_operand_t;
  153. typedef struct cg_inst_unary_t
  154. {
  155. cg_inst_base_t base;
  156. cg_virtual_reg_t * dest_value;
  157. cg_virtual_reg_t * dest_flags;
  158. cg_data_operand_t operand;
  159. }
  160. cg_inst_unary_t;
  161. typedef struct cg_inst_binary_t
  162. {
  163. cg_inst_base_t base;
  164. cg_virtual_reg_t * dest_value;
  165. cg_virtual_reg_t * dest_flags;
  166. cg_virtual_reg_t * source;
  167. cg_data_operand_t operand;
  168. }
  169. cg_inst_binary_t;
  170. typedef struct cg_inst_compare_t
  171. {
  172. cg_inst_base_t base;
  173. cg_virtual_reg_t * dest_flags;
  174. cg_virtual_reg_t * source;
  175. cg_data_operand_t operand;
  176. }
  177. cg_inst_compare_t;
  178. typedef struct cg_inst_load_immed_t
  179. {
  180. cg_inst_base_t base;
  181. cg_virtual_reg_t * dest;
  182. I32 value;
  183. }
  184. cg_inst_load_immed_t;
  185. typedef struct cg_inst_load_t
  186. {
  187. cg_inst_base_t base;
  188. cg_virtual_reg_t * dest;
  189. cg_mem_operand_t mem;
  190. }
  191. cg_inst_load_t;
  192. typedef struct cg_inst_store_t
  193. {
  194. cg_inst_base_t base;
  195. cg_virtual_reg_t * source;
  196. cg_mem_operand_t mem;
  197. }
  198. cg_inst_store_t;
  199. typedef struct cg_virtual_reg_list_t
  200. {
  201. struct cg_virtual_reg_list_t * next;
  202. cg_virtual_reg_t * reg;
  203. }
  204. cg_virtual_reg_list_t;
  205. typedef struct cg_inst_call_t
  206. {
  207. cg_inst_base_t base;
  208. cg_proc_t * proc;
  209. cg_virtual_reg_list_t * args;
  210. cg_virtual_reg_t * dest;
  211. }
  212. cg_inst_call_t;
  213. typedef struct cg_inst_ret_t
  214. {
  215. cg_inst_base_t base;
  216. cg_virtual_reg_t * result;
  217. }
  218. cg_inst_ret_t;
  219. typedef struct cg_inst_phi_t
  220. {
  221. cg_inst_base_t base;
  222. cg_virtual_reg_t * dest;
  223. cg_virtual_reg_list_t * regs;
  224. }
  225. cg_inst_phi_t;
  226. typedef struct cg_branch_t
  227. {
  228. cg_inst_base_t base;
  229. cg_block_ref_t * target;
  230. cg_virtual_reg_t * cond;
  231. }
  232. cg_inst_branch_t;
  233. union cg_inst_t
  234. {
  235. cg_inst_base_t base;
  236. cg_inst_unary_t unary;
  237. cg_inst_binary_t binary;
  238. cg_inst_compare_t compare;
  239. cg_inst_load_immed_t immed;
  240. cg_inst_load_t load;
  241. cg_inst_store_t store;
  242. cg_inst_branch_t branch;
  243. cg_inst_call_t call;
  244. cg_inst_ret_t ret;
  245. cg_inst_phi_t phi;
  246. };
  247. typedef struct cg_block_list_t
  248. {
  249. struct cg_block_list_t * next;
  250. struct cg_block_t * block;
  251. }
  252. cg_block_list_t;
  253. typedef struct cg_inst_list_head_t
  254. {
  255. cg_inst_t * head;
  256. cg_inst_t * tail;
  257. }
  258. cg_inst_list_head_t;
  259. struct cg_block_t
  260. {
  261. struct cg_block_t * next;
  262. cg_proc_t * proc;
  263. struct cg_label_t * label;
  264. cg_inst_list_head_t insts;
  265. struct cg_bitset_t * def; /* set of defined regs */
  266. struct cg_bitset_t * use; /* set of used regs */
  267. struct cg_bitset_t * live_in; /* set of regs live on entering */
  268. struct cg_bitset_t * live_out; /* set of regs live on leaving */
  269. cg_block_list_t * pred; /* list of predecessor blocks */
  270. cg_block_list_t * succ; /* list of successor blocks */
  271. int weight; /* weighting factor for block */
  272. };
  273. struct cg_block_ref_t
  274. {
  275. cg_block_t * block;
  276. };
  277. typedef struct cg_inst_list_t
  278. {
  279. struct cg_inst_list_t * next;
  280. cg_inst_t * inst;
  281. }
  282. cg_inst_list_t;
  283. struct cg_physical_reg_t;
  284. typedef enum cg_reg_type_t
  285. {
  286. cg_reg_type_general,
  287. cg_reg_type_flags
  288. }
  289. cg_reg_type_t;
  290. struct cg_virtual_reg_t
  291. {
  292. cg_virtual_reg_t * next;
  293. cg_virtual_reg_t * representative; /* for union-find */
  294. struct cg_physical_reg_t * physical_reg; /* physical register assigned */
  295. cg_virtual_reg_list_t * interferences; /* list of interfering regs. */
  296. size_t reg_no; /* virtual register number */
  297. int fp_offset; /* FP offset for spilling */
  298. cg_inst_t * def; /* defining instruction */
  299. cg_inst_list_t * use; /* use set */
  300. cg_reg_type_t type; /* type of this register */
  301. short use_cost; /* repeated usage cost */
  302. short def_cost; /* definition cost */
  303. int is_global : 1; /* is this a global register? */
  304. int is_arg : 1; /* is passed in as argument val.*/
  305. };
  306. struct cg_proc_t
  307. {
  308. cg_proc_t * next;
  309. cg_module_t * module; /* uplink to module */
  310. cg_block_t * blocks; /* linked list of blocks */
  311. cg_block_t * last_block; /* pointer to last block */
  312. cg_virtual_reg_t * registers; /* list of virtual registers */
  313. cg_virtual_reg_t * last_register; /* ptr to last register in list */
  314. cg_virtual_reg_t ** reg_array; /* array of register pointers */
  315. cg_virtual_reg_list_t * globals; /* list of registers selected for global allocation */
  316. size_t num_registers; /* number of virtual registers */
  317. size_t num_args; /* number of arguments */
  318. size_t local_storage; /* size of activation record */
  319. struct cg_label_t * prologue; /* assembly label begin */
  320. struct cg_label_t * epilogue; /* assembly label end */
  321. };
  322. struct cg_module_t
  323. {
  324. cg_heap_t * heap;
  325. cg_proc_t * procs;
  326. };
  327. /****************************************************************************/
  328. /* Determine the set of defined registers for the instruction passed in. */
  329. /* dest points to a buffer into which the result will be stored, limit */
  330. /* specifies an upper limit on this buffer. The return value will be */
  331. /* pointing right after the last register stored in the destanation area. */
  332. /****************************************************************************/
  333. cg_virtual_reg_t ** cg_inst_def(const cg_inst_t * inst,
  334. cg_virtual_reg_t ** dest,
  335. cg_virtual_reg_t *const * limit);
  336. /****************************************************************************/
  337. /* Determine the set of used registers for the instruction passed in. */
  338. /* dest points to a buffer into which the result will be stored, limit */
  339. /* specifies an upper limit on this buffer. The return value will be */
  340. /* pointing right after the last register stored in the destanation area. */
  341. /****************************************************************************/
  342. cg_virtual_reg_t ** cg_inst_use(const cg_inst_t * inst,
  343. cg_virtual_reg_t ** dest,
  344. cg_virtual_reg_t * const * limit);
  345. cg_module_t * cg_module_create(cg_heap_t * heap);
  346. cg_proc_t * cg_proc_create(cg_module_t * module);
  347. cg_block_t * cg_block_create(cg_proc_t * proc, int weight);
  348. cg_virtual_reg_t * cg_virtual_reg_create(cg_proc_t * proc, cg_reg_type_t type);
  349. // create a register list
  350. cg_virtual_reg_list_t * cg_create_virtual_reg_list(cg_heap_t * heap, ...);
  351. // add an instruction to a block
  352. #ifndef NDEBUG
  353. #define CG_INST_DEBUG_ARG_DECL ,const char * file, int line
  354. #define CG_INST_DEBUG_ARGS ,__FILE__, __LINE__
  355. #define CG_INST_SET_DEBUG(inst) (inst)->base.file = file; (inst)->base.line = line;
  356. #define CG_INST_DEBUG_PASS ,file, line
  357. #else
  358. #define CG_INST_DEBUG_ARG_DECL
  359. #define CG_INST_DEBUG_ARGS
  360. #define CG_INST_SET_DEBUG(inst)
  361. #define CG_INST_DEBUG_PASS
  362. #endif
  363. cg_inst_t * cg_create_inst_unary(cg_block_t * block,
  364. cg_opcode_t op,
  365. cg_virtual_reg_t * dest,
  366. cg_virtual_reg_t * source
  367. CG_INST_DEBUG_ARG_DECL);
  368. #define NEG(dest, source) cg_create_inst_unary(block, cg_op_neg, dest, source CG_INST_DEBUG_ARGS)
  369. #define FNEG(dest, source) cg_create_inst_unary(block, cg_op_fneg, dest, source CG_INST_DEBUG_ARGS)
  370. #define NOT(dest, source) cg_create_inst_unary(block, cg_op_not, dest, source CG_INST_DEBUG_ARGS)
  371. #define FINV(dest, source) cg_create_inst_unary(block, cg_op_finv, dest, source CG_INST_DEBUG_ARGS)
  372. #define FSQRT(dest, source) cg_create_inst_unary(block, cg_op_fsqrt, dest, source CG_INST_DEBUG_ARGS)
  373. #define TRUNC(dest, source) cg_create_inst_unary(block, cg_op_trunc, dest, source CG_INST_DEBUG_ARGS)
  374. #define ROUND(dest, source) cg_create_inst_unary(block, cg_op_round, dest, source CG_INST_DEBUG_ARGS)
  375. #define FCNV(dest, source) cg_create_inst_unary(block, cg_op_fcnv, dest, source CG_INST_DEBUG_ARGS)
  376. #define ABS(dest, source) cg_create_inst_unary(block, cg_op_abs, dest, source CG_INST_DEBUG_ARGS)
  377. #define LOG2(dest, source) cg_create_inst_unary(block, cg_op_log2, dest, source CG_INST_DEBUG_ARGS)
  378. cg_inst_t * cg_create_inst_unary_s(cg_block_t * block,
  379. cg_opcode_t op,
  380. cg_virtual_reg_t * dest,
  381. cg_virtual_reg_t * flags,
  382. cg_virtual_reg_t * source
  383. CG_INST_DEBUG_ARG_DECL);
  384. #define NEG_S(dest, flags, source) cg_create_inst_unary_s(block, cg_op_neg, dest, flags, source CG_INST_DEBUG_ARGS)
  385. #define FNEG_S(dest, flags, source) cg_create_inst_unary_s(block, cg_op_fneg, dest, flags, source CG_INST_DEBUG_ARGS)
  386. #define NOT_S(dest, flags, source) cg_create_inst_unary_s(block, cg_op_not, dest, flags, source CG_INST_DEBUG_ARGS)
  387. #define FINV_S(dest, flags, source) cg_create_inst_unary_s(block, cg_op_finv, dest, flags, source CG_INST_DEBUG_ARGS)
  388. #define FSQRT_S(dest, flags, source) cg_create_inst_unary_s(block, cg_op_fsqrt, dest, flags, source CG_INST_DEBUG_ARGS)
  389. #define TRUNC_S(dest, flags, source) cg_create_inst_unary_s(block, cg_op_trunc, dest, flags, source CG_INST_DEBUG_ARGS)
  390. #define ROUND_S(dest, flags, source) cg_create_inst_unary_s(block, cg_op_round, dest, flags, source CG_INST_DEBUG_ARGS)
  391. #define FCNV_S(dest, flags, source) cg_create_inst_unary_s(block, cg_op_fcnv, dest, flags, source CG_INST_DEBUG_ARGS)
  392. cg_inst_t * cg_create_inst_binary(cg_block_t * block,
  393. cg_opcode_t op,
  394. cg_virtual_reg_t * dest,
  395. cg_virtual_reg_t * source,
  396. cg_virtual_reg_t * operand
  397. CG_INST_DEBUG_ARG_DECL);
  398. #define ADD(dest, source, operand) cg_create_inst_binary(block, cg_op_add, dest, source, operand CG_INST_DEBUG_ARGS)
  399. #define AND(dest, source, operand) cg_create_inst_binary(block, cg_op_and, dest, source, operand CG_INST_DEBUG_ARGS)
  400. #define ASR(dest, source, operand) cg_create_inst_binary(block, cg_op_asr, dest, source, operand CG_INST_DEBUG_ARGS)
  401. #define DIV(dest, source, operand) cg_create_inst_binary(block, cg_op_div, dest, source, operand CG_INST_DEBUG_ARGS)
  402. #define LSL(dest, source, operand) cg_create_inst_binary(block, cg_op_lsl, dest, source, operand CG_INST_DEBUG_ARGS)
  403. #define LSR(dest, source, operand) cg_create_inst_binary(block, cg_op_lsr, dest, source, operand CG_INST_DEBUG_ARGS)
  404. #define MOD(dest, source, operand) cg_create_inst_binary(block, cg_op_mod, dest, source, operand CG_INST_DEBUG_ARGS)
  405. #define MUL(dest, source, operand) cg_create_inst_binary(block, cg_op_mul, dest, source, operand CG_INST_DEBUG_ARGS)
  406. #define OR(dest, source, operand) cg_create_inst_binary(block, cg_op_or, dest, source, operand CG_INST_DEBUG_ARGS)
  407. #define SUB(dest, source, operand) cg_create_inst_binary(block, cg_op_sub, dest, source, operand CG_INST_DEBUG_ARGS)
  408. #define XOR(dest, source, operand) cg_create_inst_binary(block, cg_op_xor, dest, source, operand CG_INST_DEBUG_ARGS)
  409. #define FADD(dest, source, operand) cg_create_inst_binary(block, cg_op_fadd, dest, source, operand CG_INST_DEBUG_ARGS)
  410. #define FDIV(dest, source, operand) cg_create_inst_binary(block, cg_op_fdiv, dest, source, operand CG_INST_DEBUG_ARGS)
  411. #define FMUL(dest, source, operand) cg_create_inst_binary(block, cg_op_fmul, dest, source, operand CG_INST_DEBUG_ARGS)
  412. #define FSUB(dest, source, operand) cg_create_inst_binary(block, cg_op_fsub, dest, source, operand CG_INST_DEBUG_ARGS)
  413. #define MIN(dest, source, operand) cg_create_inst_binary(block, cg_op_min, dest, source, operand CG_INST_DEBUG_ARGS)
  414. #define MAX(dest, source, operand) cg_create_inst_binary(block, cg_op_max, dest, source, operand CG_INST_DEBUG_ARGS)
  415. cg_inst_t * cg_create_inst_binary_s(cg_block_t * block,
  416. cg_opcode_t op,
  417. cg_virtual_reg_t * dest,
  418. cg_virtual_reg_t * flags,
  419. cg_virtual_reg_t * source,
  420. cg_virtual_reg_t * operand
  421. CG_INST_DEBUG_ARG_DECL);
  422. #define ADD_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_add, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  423. #define AND_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_and, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  424. #define ASR_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_asr, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  425. #define DIV_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_div, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  426. #define LSL_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_lsl, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  427. #define LSR_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_lsr, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  428. #define MOD_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_mod, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  429. #define MUL_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_mul, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  430. #define OR_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_or, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  431. #define SUB_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_sub, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  432. #define XOR_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_xor, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  433. #define FADD_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_fadd, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  434. #define FDIV_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_fdiv, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  435. #define FMUL_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_fmul, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  436. #define FSUB_S(dest, flags, source, operand) cg_create_inst_binary_s(block, cg_op_fsub, dest, flags, source, operand CG_INST_DEBUG_ARGS)
  437. cg_inst_t * cg_create_inst_compare(cg_block_t * block,
  438. cg_opcode_t op,
  439. cg_virtual_reg_t * dest,
  440. cg_virtual_reg_t * source,
  441. cg_virtual_reg_t * operand
  442. CG_INST_DEBUG_ARG_DECL);
  443. #define CMP(dest, source, operand) cg_create_inst_compare(block, cg_op_cmp, dest, source, operand CG_INST_DEBUG_ARGS)
  444. #define FCMP(dest, source, operand) cg_create_inst_compare(block, cg_op_fcmp, dest, source, operand CG_INST_DEBUG_ARGS)
  445. cg_inst_t * cg_create_inst_load(cg_block_t * block,
  446. cg_opcode_t op,
  447. cg_virtual_reg_t * dest,
  448. cg_virtual_reg_t * mem
  449. CG_INST_DEBUG_ARG_DECL);
  450. #define LDB(dest, mem) cg_create_inst_load(block, cg_op_ldb, dest, mem CG_INST_DEBUG_ARGS)
  451. #define LDH(dest, mem) cg_create_inst_load(block, cg_op_ldh, dest, mem CG_INST_DEBUG_ARGS)
  452. #define LDW(dest, mem) cg_create_inst_load(block, cg_op_ldw, dest, mem CG_INST_DEBUG_ARGS)
  453. cg_inst_t * cg_create_inst_store(cg_block_t * block,
  454. cg_opcode_t op,
  455. cg_virtual_reg_t * source,
  456. cg_virtual_reg_t * mem
  457. CG_INST_DEBUG_ARG_DECL);
  458. #define STB(source, mem) cg_create_inst_store(block, cg_op_stb, source, mem CG_INST_DEBUG_ARGS)
  459. #define STH(source, mem) cg_create_inst_store(block, cg_op_sth, source, mem CG_INST_DEBUG_ARGS)
  460. #define STW(source, mem) cg_create_inst_store(block, cg_op_stw, source, mem CG_INST_DEBUG_ARGS)
  461. cg_inst_t * cg_create_inst_load_immed(cg_block_t * block,
  462. cg_opcode_t op,
  463. cg_virtual_reg_t * dest,
  464. U32 value
  465. CG_INST_DEBUG_ARG_DECL);
  466. #define LDI(dest, value) cg_create_inst_load_immed(block, cg_op_ldi, dest, value CG_INST_DEBUG_ARGS)
  467. cg_inst_t * cg_create_inst_branch_label(cg_block_t * block,
  468. cg_opcode_t op,
  469. cg_block_ref_t * target
  470. CG_INST_DEBUG_ARG_DECL);
  471. #define BRA(target) cg_create_inst_branch_label(block, cg_op_bra, target CG_INST_DEBUG_ARGS)
  472. cg_inst_t * cg_create_inst_branch_cond(cg_block_t * block,
  473. cg_opcode_t op,
  474. cg_virtual_reg_t * flags,
  475. cg_block_ref_t * target
  476. CG_INST_DEBUG_ARG_DECL);
  477. #define BEQ(flags, target) cg_create_inst_branch_cond(block, cg_op_beq, flags, target CG_INST_DEBUG_ARGS)
  478. #define BGE(flags, target) cg_create_inst_branch_cond(block, cg_op_bge, flags, target CG_INST_DEBUG_ARGS)
  479. #define BLE(flags, target) cg_create_inst_branch_cond(block, cg_op_ble, flags, target CG_INST_DEBUG_ARGS)
  480. #define BGT(flags, target) cg_create_inst_branch_cond(block, cg_op_bgt, flags, target CG_INST_DEBUG_ARGS)
  481. #define BLT(flags, target) cg_create_inst_branch_cond(block, cg_op_blt, flags, target CG_INST_DEBUG_ARGS)
  482. #define BNE(flags, target) cg_create_inst_branch_cond(block, cg_op_bne, flags, target CG_INST_DEBUG_ARGS)
  483. cg_inst_t * cg_create_inst_phi(cg_block_t * block,
  484. cg_opcode_t op,
  485. cg_virtual_reg_t * dest,
  486. cg_virtual_reg_list_t * regs
  487. CG_INST_DEBUG_ARG_DECL);
  488. #define PHI(dest, regs) cg_create_inst_phi(block, cg_op_phi, dest, regs CG_INST_DEBUG_ARGS)
  489. cg_inst_t * cg_create_inst_call_proc(cg_block_t * block,
  490. cg_opcode_t op,
  491. cg_proc_t * proc,
  492. cg_virtual_reg_list_t * args
  493. CG_INST_DEBUG_ARG_DECL);
  494. #define CALL_PROC(proc, args) cg_create_inst_call_proc(block, cg_op_call, proc, args CG_INST_DEBUG_ARGS)
  495. cg_inst_t * cg_create_inst_call_func(cg_block_t * block,
  496. cg_opcode_t op,
  497. cg_virtual_reg_t * dest,
  498. cg_proc_t * proc,
  499. cg_virtual_reg_list_t * args
  500. CG_INST_DEBUG_ARG_DECL);
  501. #define CALL_FUNC(dest, proc, args) cg_create_inst_call_func(block, cg_op_call, dest, proc, args CG_INST_DEBUG_ARGS)
  502. cg_inst_t * cg_create_inst_ret(cg_block_t * block,
  503. cg_opcode_t op
  504. CG_INST_DEBUG_ARG_DECL);
  505. #define RET() cg_create_inst_ret(block, cg_op_ret CG_INST_DEBUG_ARGS)
  506. cg_inst_t * cg_create_inst_ret_value(cg_block_t * block,
  507. cg_opcode_t op,
  508. cg_virtual_reg_t * value
  509. CG_INST_DEBUG_ARG_DECL);
  510. #define RET_VALUE(value) cg_create_inst_ret_value(block, cg_op_ret, value CG_INST_DEBUG_ARGS)
  511. cg_block_ref_t * cg_block_ref_create(cg_proc_t * proc);
  512. /****************************************************************************/
  513. /* The intermediate code needs to be processed by the following */
  514. /* functions in this given order */
  515. /****************************************************************************/
  516. void cg_module_inst_def(cg_module_t * module);
  517. void cg_module_amode(cg_module_t * module);
  518. void cg_module_eliminate_dead_code(cg_module_t * module);
  519. void cg_module_unify_registers(cg_module_t * module);
  520. void cg_module_allocate_variables(cg_module_t * module);
  521. void cg_module_inst_use_chains(cg_module_t * module);
  522. void cg_module_reorder_instructions(cg_module_t * module);
  523. void cg_module_dataflow(cg_module_t * module);
  524. void cg_module_interferences(cg_module_t * module);
  525. void cg_module_dump(cg_module_t * module, FILE * out);
  526. #ifdef __cplusplus
  527. }
  528. #endif
  529. #endif //ndef CODEGEN_INSTRUCTION_H