PageRenderTime 349ms CodeModel.GetById 101ms app.highlight 116ms RepoModel.GetById 125ms app.codeStats 1ms

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