/*
 * Copyright (c) 2005 - 2007, Nils R. Weller
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef ICODE_H
#define ICODE_H

struct statement;
struct vreg;
struct reg;
struct expr;
struct fcall_data;
struct store_data;
struct stack_block;
struct type;
struct function;
struct control;
struct label;
struct token;
struct decl;
struct inline_asm_stmt;

struct copystruct {
	struct vreg	*dest_vreg;
	struct vreg	*src_vreg;
	struct reg	*dest_preg;
	struct reg	*src_preg;
	struct reg	*dest_from_ptr;
	struct reg	*src_from_ptr;
	struct reg	*dest_from_ptr_struct;
	struct reg	*src_from_ptr_struct;
};

struct copyreg {
	struct reg	*src_preg;
	struct reg	*dest_preg;
	struct type	*src_type;
	struct type	*dest_type;
};

struct allocadata {
	struct reg		*result_reg;
	struct reg		*size_reg;
	struct stack_block	*addr;
};	

struct vlasizedata {
	struct reg		*size;
	struct stack_block	*blockaddr;
	int			offset;	
};
/* XXX used by conv_fp and extend_sign */
struct extendsign {
	struct reg	*dest_preg;
	struct reg	*src_preg; /* XXX conv_fp-only */
	struct type	*src_type;
	struct type	*dest_type;
};

#include <stddef.h>


struct allocstack {
	size_t		nbytes;
	struct vreg	*patchme;
};

struct icode_instr {
	int			type;
#define INSTR_SEQPOINT		1 /* pseudo */
#define INSTR_LABEL		2
#define INSTR_JUMP		3 /* Unconditional branch */
#define INSTR_CMP		5	
#define INSTR_EXTEND_SIGN	10 /* pseudo */	
#define INSTR_CONV_FP		11 /* pseudo */
#define INSTR_CALL		20
#define INSTR_CALLINDIR		21
#define INSTR_LOAD		30
#define INSTR_STORE		35
#define INSTR_WRITEBACK		37
#define INSTR_COPYINIT		40 /* pseudo */
#define INSTR_COPYSTRUCT	41 /* pseudo */
#define INSTR_ASM		42 /* pseudo */
#define INSTR_ALLOCA		43 /* pseudo */
#define INSTR_INTRINSIC_MEMCPY	44 /* pseudo */
#define INSTR_DEALLOCA		45 /* pseudo */

#define INSTR_BUILTIN_FRAME_ADDRESS	46 /* pseudo */

#define INSTR_ALLOC_VLA		50 /* pseudo */
#define INSTR_DEALLOC_VLA	51 /* pseudo */

#define INSTR_PUT_VLA_SIZE	52 /* pseudo */
#define INSTR_RETR_VLA_SIZE	53 /* pseudo */	

#define INSTR_LOAD_VLA		55

#define INSTR_PUSH		60
#define INSTR_FREESTACK		70
#define INSTR_ALLOCSTACK	71
#define INSTR_INDIR		80
#define INSTR_ADDROF		81
#define INSTR_DEC		89
#define INSTR_INC		90
#define INSTR_NEG		91
#define INSTR_SETREG		92
#define INSTR_XCHG		93
#define INSTR_MOV		100
#define INSTR_ADD		110
#define INSTR_SUB		111	
#define INSTR_MUL		112
#define INSTR_DIV		113
#define INSTR_MOD		114
#define INSTR_SHL		115
#define INSTR_SHR		116
#define INSTR_AND		117
#define INSTR_OR		118
#define INSTR_XOR		119
#define INSTR_NOT		120

#define INSTR_PREG_OR		121

#define INSTR_SETITEM		125 /* pseudo */
#define INSTR_UNIMPL		126 /* pseudo */ 
#define INSTR_DEBUG		130 /* pseudo */
#define INSTR_PROPVREG		131 /* pseudo */
#define INSTR_ADJ_ALLOCATED	132 /* pseudo */

#define INSTR_DBGINFO_LINE	135 /* debugging pseudo */

#define INSTR_BR_EQUAL		140
#define INSTR_BR_NEQUAL		141
#define INSTR_BR_GREATER	142
#define INSTR_BR_SMALLER	143
#define INSTR_BR_GREATEREQ	144
#define INSTR_BR_SMALLEREQ	145
	
#define INSTR_RET		160

#define INSTR_X86_FXCH		500
#define INSTR_X86_FFREE		501
#define INSTR_X86_FNSTCW	502
#define INSTR_X86_FLDCW		503
#define INSTR_X86_CDQ		520

#define INSTR_MIPS_MFC1		600
#define INSTR_MIPS_MTC1		601
#define INSTR_MIPS_CVT		602
#define INSTR_MIPS_TRUNC	603
#define INSTR_MIPS_MAKE_32BIT_MASK	604

#define INSTR_AMD64_CVTSI2SD	700
#define INSTR_AMD64_CVTSI2SS	701
#define INSTR_AMD64_CVTTSD2SI	702
#define INSTR_AMD64_CVTTSS2SI	703
#define INSTR_AMD64_CVTSD2SS	704
#define INSTR_AMD64_CVTSS2SD	705

#define INSTR_POWER_SRAWI	800
#define INSTR_POWER_RLWINM	801
#define INSTR_POWER_SLWI	802
#define INSTR_POWER_EXTSH	803
#define INSTR_POWER_RLDICL	804
#define INSTR_POWER_EXTSB	805
#define INSTR_POWER_EXTSW	806
#define INSTR_POWER_FCFID	807
#define INSTR_POWER_FRSP	808
#define INSTR_POWER_SET_LOAD_DOUBLE	810
#define INSTR_POWER_UNSET_LOAD_DOUBLE	811
#define INSTR_POWER_XORIS	820
#define INSTR_POWER_LIS		821
#define INSTR_POWER_LOADUP4	822
#define INSTR_POWER_FCTIWZ	823


#if 0
	void			*data;
	struct vreg		*then_vreg;
#endif
	/*
	 * Virtual and physical source/destination registers. The reason
	 * pregs need to be recorded as well is that vr->preg cannot be
	 * used in the backend because any vreg may have multiple pregs
	 * associated with it during its lifetime
	 */
	struct reg		**dest_pregs;
	struct vreg		*dest_vreg;
	struct reg		**src_pregs;
	struct vreg		*src_vreg;
	struct vreg		*src_parent_struct;
	struct vreg		*dest_parent_struct;
	struct reg		*src_ptr_preg;
	struct reg		*dest_ptr_preg;
	void			*dat;
	struct icode_instr	*next;
	unsigned long		seqno;
};

struct icode_list {
	struct icode_instr	*head;
	struct icode_instr	*tail;
	struct vreg		*res;
};

unsigned long
get_label_count(void);

int
icode_list_length(struct icode_list *);

void
boolify_result(struct vreg *vr, struct icode_list *il);

int
pro_mote(struct vreg **, struct icode_list *, int eval);

/*
 * Functions for creating icode instructions
 */

void
icode_make_copystruct(
	struct vreg *dest,
	struct vreg *src,
	struct icode_list *il);

struct int_memcpy_data {
	struct reg	*dest_addr;
	struct reg	*src_addr;
	struct reg	*nbytes;
	struct reg	*temp_reg;
};

void
icode_make_intrinsic_memcpy(
	struct vreg *dest,
	struct vreg *src,
	struct vreg *nbytes,
	int may_call_lib,
	struct icode_list *il);

void
icode_make_alloca(struct reg *r, struct vreg *size_vr,
	struct stack_block *sb,
	struct icode_list *il);

void
icode_make_alloc_vla(struct stack_block *vla,
	struct icode_list *il);


void
icode_make_put_vla_size(struct reg *size, struct stack_block *sb, int idx,
	struct icode_list *il);	

void
icode_make_put_vla_whole_size(struct reg *size, struct stack_block *sb,
		        struct icode_list *il);

struct vreg *
icode_make_retr_vla_size(struct reg *size, struct stack_block *sb, int idx,
	struct icode_list *il);	


struct builtinframeaddressdata {
	struct reg	*result_reg;
	struct reg	*temp_reg;
	size_t		*count;
};

void
icode_make_builtin_frame_address(struct reg *r, struct reg *r2, size_t *n,
	struct icode_list *il);	

void
icode_make_allocstack(struct vreg *vr, size_t size, struct icode_list *il);

void
icode_make_copyreg(struct reg *dest, struct reg *src,
		struct type *desttype, struct type *srctype,
		struct icode_list *il);

struct icode_instr *
icode_make_setreg(struct reg *r, int value);

struct icode_instr *
icode_make_neg(struct vreg *vr);

void
icode_make_xchg(struct reg *r1, struct reg *r2, struct icode_list *il);

struct icode_instr *
icode_make_branch(struct icode_instr *dest, int btype, struct vreg *vr);

struct icode_instr *
icode_make_jump(struct icode_instr *label);

struct icode_instr *
icode_make_sub(struct vreg *dest, struct vreg *src);

struct icode_instr *
icode_make_add(struct vreg *dest, struct vreg *src);

struct icode_instr *
icode_make_mul(struct vreg *dest, struct vreg *src);

struct icode_instr *
icode_make_div(struct vreg *dest, struct vreg *src);

struct icode_instr *
icode_make_shl(struct vreg *dest, struct vreg *src);

struct icode_instr *
icode_make_shr(struct vreg *dest, struct vreg *src);

struct icode_instr *
icode_make_mod(struct vreg *dest, struct vreg *src);

struct icode_instr *
icode_make_or(struct vreg *dest, struct vreg *src);

void
icode_make_preg_or(struct reg *dest, struct reg *src, struct icode_list *il);

struct icode_instr *
icode_make_and(struct vreg *dest, struct vreg *src);

struct icode_instr *
icode_make_indir(struct reg *);

void
icode_make_copyinit(struct decl *, struct icode_list *);

void
icode_make_asm(struct inline_asm_stmt *, struct icode_list *);

struct icode_instr *
icode_make_store_indir(struct vreg *dest, struct vreg *src);

struct icode_instr *
icode_make_call(const char *name);


struct icode_instr *
icode_make_call_indir(struct reg *r);

struct icode_instr *
icode_make_push(struct vreg *vr, struct icode_list *il);

struct icode_instr *
icode_make_xor(struct vreg *dest, struct vreg *src);

struct icode_instr *
icode_make_not(struct vreg *vr);

struct icode_instr *
icode_make_setitem(struct vreg *vr);

struct icode_instr *
icode_make_propvreg(struct vreg *vr);

struct icode_instr *
icode_make_load(struct reg *r, struct vreg *parent_struct);

extern int	unimpl_instr;

void
icode_make_unimpl(struct icode_list *il);

struct icode_instr *
icode_make_debug(const char *msg, ...);


void
icode_make_dbginfo_line(struct statement *stmt, struct icode_list *il);

void
do_add_sub(struct vreg **left, struct vreg **right,
	int op, struct token *optok, struct icode_list *il, int eval);

void
icode_make_store(struct function *f, struct vreg *dest,
	struct vreg *src, struct icode_list *il);

struct icode_instr *
icode_make_freestack(size_t bytes);

struct icode_instr *
icode_make_adj_allocated(int bytes);

#if 0
struct icode_instr *
icode_make_seqpoint(struct var_access *stores);
#endif

struct icode_instr *
icode_make_indir(struct reg *r);

struct icode_instr *
icode_make_addrof(struct vreg *vr, struct icode_list *il);

struct icode_instr *
icode_make_inc(struct vreg *vr);

struct icode_instr *
icode_make_dec(struct vreg *vr);

struct icode_instr *
icode_make_label(const char *tmpl);
		
struct icode_instr *
icode_make_ret(struct vreg *vr);

struct icode_instr *
icode_make_cmp(struct vreg *dest, struct vreg *src);

void
icode_make_extend_sign(struct vreg *vr, struct type *to, struct type *from,
	struct icode_list *il);

void
icode_make_conv_fp(struct reg *destr, struct reg *srcr, struct type *to,
	struct type *from,
	struct icode_list *il);

void
icode_make_x86_fxch(struct reg *r, struct reg *r2, struct icode_list *il);

void
icode_make_x86_ffree(struct reg *r, struct icode_list *il);

void
icode_make_x86_store_x87cw(struct vreg *vr, struct icode_list *il);

void
icode_make_x86_load_x87cw(struct vreg *vr, struct icode_list *il);

void
icode_make_x86_cdq(struct icode_list *il);

void
icode_make_mips_mtc1(struct reg *dest, struct vreg *src,
struct icode_list *il);

void
icode_make_mips_cvt(struct vreg *dest, struct vreg *src,
struct icode_list *il);

void
icode_make_mips_trunc(struct vreg *dest, struct vreg *src,
struct icode_list *il);

void
icode_make_mips_make_32bit_mask(struct reg *r, struct icode_list *il);

void
icode_make_mips_mfc1(struct reg *dest, struct vreg *src,
struct icode_list *il);

void
icode_make_power_srawi(struct reg *dest, struct reg *src, int bits,
struct icode_list *il); 

void
icode_make_power_rldicl(struct reg *dest, struct reg *src, int bits,
struct icode_list *il);

void
icode_make_power_fcfid(struct reg *dest, struct reg *src,
struct icode_list *il);		

void
icode_make_power_frsp(struct reg *dest, struct icode_list *il);

void
icode_make_power_rlwinm(struct reg *dest, struct reg *src, int value,
struct icode_list *il);

void
icode_make_power_slwi(struct reg *dest, struct reg *src, int bits,
struct icode_list *il);

void
icode_make_power_extsb(struct reg *dest, struct icode_list *il);

void
icode_make_power_extsh(struct reg *dest, struct icode_list *il);

void
icode_make_power_extsw(struct reg *dest, struct icode_list *il);

void
icode_make_power_xoris(struct reg *, int, struct icode_list *il);

void
icode_make_power_lis(struct reg *, int, struct icode_list *il);

void
icode_make_power_loadup4(struct reg *r, struct vreg *vr,
struct icode_list *il);

void
icode_make_power_fctiwz(struct reg *r, struct icode_list *il);

void
icode_make_power_extsh(struct reg *r, struct icode_list *il);

void
icode_make_amd64_cvtsi2sd(struct reg *dest, struct vreg *src,
struct icode_list *il);

void
icode_make_amd64_cvtsi2ss(struct reg *dest, struct vreg *src,
struct icode_list *il);

void
icode_make_amd64_cvttsd2si(struct reg *dest, struct reg *src,
struct icode_list *il);

void
icode_make_amd64_cvttss2si(struct reg *dest, struct reg *src,
struct icode_list *il);

void
icode_make_amd64_cvtsd2ss(struct reg *r, struct icode_list *il);

void
icode_make_amd64_cvtss2sd(struct reg *r, struct icode_list *il);

struct icode_instr *
icode_make_writeback(struct function *f, struct vreg *vr);

struct type *
promote(struct vreg **left, struct vreg **right, 
	int op0, struct token *optok, struct icode_list *il, int eval);


void init_to_icode(struct decl *d, struct icode_list *il);

/*
 * Compile an expression to icode
 */
struct vreg *
expr_to_icode(struct expr *e, struct vreg *lvalue, struct icode_list *il,
		int purpose, int eval);

struct vreg *
fcall_to_icode(struct fcall_data *, struct icode_list *, struct token *t,
		int eval);

struct stack_block *
vla_decl_to_icode(struct type *ty, struct icode_list *il);

struct icode_instr *
compare_vreg_with_zero(struct vreg *vr, struct icode_list *il);

/*
 * Functions to manipulate icode lists
 */
struct icode_list *
alloc_icode_list(void);



void	
append_icode_list(struct icode_list *, struct icode_instr *);

void
merge_icode_lists(struct icode_list *dest, struct icode_list *src);

void
put_label_scope(struct label *l);

void
put_expr_scope(struct expr *e);

void
put_ctrl_scope(struct control *c);

struct icode_list *
ctrl_to_icode(struct control *);

struct icode_list *
xlate_to_icode(struct statement *slist, int inv_gprs_first);

#endif



syntax highlighted by Code2HTML, v. 0.9.1