/*
 * 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 BACKEND_H
#define BACKEND_H

struct scope;
struct expr;
struct type;
struct decl;
struct reg;
struct vreg;
struct token;
struct function;
struct icode_instr;
struct icode_list;
struct scope;
struct stack_block;
struct initializer;
struct sym_entry;
struct fcall_data;
struct init_with_name;
struct inline_asm_io;
struct ty_string;
struct gas_token;
struct copystruct;
struct allocadata;

struct vlasizedata;

#include <stdio.h>
#include <stdarg.h>

extern int	optimizing;
extern char	*tunit_name;
extern size_t	tunit_size;


struct vreg	*get_parent_struct(struct vreg *);
size_t		calc_align_bytes(
			size_t offset,
			struct type *cur,
			struct type *next);
int is_immediate_vla_type(struct type *ty);
int
xlate_icode(struct function *f,
	struct icode_list *ilp,
	struct icode_instr **lastret);

struct vreg *
vreg_static_alloc(struct type *ty, struct initializer *init);

struct vreg *
vreg_stack_alloc(struct type *ty, struct icode_list *il, int on_frame,
		struct initializer *init);

struct initializer *
make_null_block(struct sym_entry *se,
		struct type *ty, struct type *
		struct_ty, int remaining);

struct init_with_name *
make_init_name(struct initializer *init);

size_t
get_sizeof_const(struct token *constant);

size_t
get_sizeof_elem_type(struct type *ty);

size_t
get_sizeof_decl(struct decl *, struct token *);

size_t
get_align_type(struct type *ty);

unsigned long
calc_offsets(struct vreg *);

int
generic_same_representation(struct type *dest, struct type *src);

/* as/gas-specific emitter functions. Work at least with x86 gas and SGI as */
void	as_align_for_type(FILE *o, struct type *);

void	as_print_string_init(FILE *o, size_t howmany, struct ty_string *str);


typedef int	(*init_func_t)(FILE *fd, struct scope *s);
typedef int	(*is_multi_reg_obj_func_t)(struct type *t);
typedef	int	(*gen_code_func_t)(void);
typedef int	(*gen_var_func_t)(struct decl *d, int is_glob, int inited);
typedef int	(*get_ptr_size_func_t)(void);
typedef struct type *(*get_size_t_func_t)(void);
typedef struct type *(*get_uintptr_t_func_t)(void);
typedef size_t	(*get_sizeof_basic_func_t)(int code);
typedef size_t	(*get_sizeof_type_func_t)(struct type *ty,
			struct token *tok); 
typedef size_t	(*get_sizeof_elem_type_func_t)(struct type *ty);
typedef size_t	(*get_sizeof_decl_func_t)(struct decl *d,
			struct token *tok); 
typedef size_t	(*get_sizeof_const_func_t)(struct token *t);
typedef struct vreg	*(*get_sizeof_vla_type_func_t)(struct type *,
		struct icode_list *);
typedef size_t	(*get_align_type_func_t)(struct type *ty);
typedef struct reg	(*reg_alloc_func_t)(void);
typedef int	(*reg_free_func_t)(void);
typedef void	(*invalidate_gprs_func_t)(struct icode_list *il,
		int saveregs);
typedef void	(*invalidate_except_func_t)(struct icode_list *il,
		int save, ...);
typedef struct reg	*(*alloc_gpr_func_t)(
	struct function *f,
	int size, 
	struct icode_list *,
	struct reg *dontwipe, int line);
typedef struct reg	*(*alloc_16_or_32bit_noesiedi_func_t)(
	struct function *f,
	size_t size, 
	struct icode_list *,
	struct reg *dontwipe);

typedef struct reg	*(*alloc_fpr_func_t)(
	struct function *f,
	int size, 
	struct icode_list *,
	struct reg *dontwipe);
typedef void	(*free_preg_func_t)(struct reg *, struct icode_list *);
typedef void	(*flush_func_t)(void);
typedef void	(*wbreg_func_t)(struct vreg *vr, struct reg *pr);
typedef void	(*icode_prepare_op_func_t)(
		struct vreg **dest,
		struct vreg **src,
		int op,
		struct icode_list *il);

typedef struct vreg	*(*icode_make_cast_func_t)
	(struct vreg *src, struct type *to, struct icode_list *il);

typedef void	(*icode_make_structreloc_func_t)(struct copystruct *cs,
			struct icode_list *il);

typedef struct initializer *
	(*make_null_block_func_t)(
		struct sym_entry *se,
		struct type *t,
		struct type *struct_ty,
		int remaining);
typedef struct init_with_name	*
	(*make_init_name_func_t)(struct initializer *);
typedef void	(*debug_print_gprs_func_t)(void);	
typedef struct reg	*(*name_to_reg_func_t)(const char *name);
typedef struct reg	*
(*asmvreg_to_reg_func_t)(struct vreg **, int,
 struct inline_asm_io*, struct icode_list*, int faultin);
typedef char	*(*get_inlineasm_label_func_t)(const char *);
typedef void	(*do_ret_func_t)(struct function *, struct icode_instr *);

typedef struct reg	*(*get_abi_reg_func_t)(int index, struct type *ty);
typedef struct reg	*(*get_abi_ret_reg_func_t)(struct type *p);
typedef int		(*same_representation_func_t)(struct type *dest,
				struct type *src);


struct emitter;
struct reg;
struct copystruct;
struct copyreg;

#include "archdefs.h"

struct backend {
	int				arch;
	int				abi;
	int				multi_gpr_object;
	int				struct_align;
	init_func_t			init;
	is_multi_reg_obj_func_t		is_multi_reg_obj;
	get_ptr_size_func_t		get_ptr_size;
	get_size_t_func_t		get_size_t;
	get_uintptr_t_func_t		get_uintptr_t;
	get_sizeof_basic_func_t		get_sizeof_basic;
	get_sizeof_type_func_t		get_sizeof_type;
	get_sizeof_elem_type_func_t	get_sizeof_elem_type;
	get_sizeof_decl_func_t		get_sizeof_decl;
	get_sizeof_const_func_t		get_sizeof_const;
	get_sizeof_vla_type_func_t	get_sizeof_vla_type;
	get_align_type_func_t		get_align_type;
	gen_code_func_t			generate_program;
	struct emitter			*emit;
	struct reg			*esp;
	invalidate_gprs_func_t		invalidate_gprs;
	invalidate_except_func_t	invalidate_except;
	alloc_gpr_func_t		alloc_gpr;
	alloc_16_or_32bit_noesiedi_func_t	alloc_16_or_32bit_noesiedi;
	alloc_fpr_func_t		alloc_fpr;
	free_preg_func_t		free_preg;
	struct vreg			*(*icode_make_fcall)(
		struct fcall_data *,
		struct vreg **vrs,
		int nvrs,
		struct icode_list * 
	);
	int				(*icode_make_return)(
		struct vreg *vr, struct icode_list *il
	);
	flush_func_t			flushregs;
	icode_prepare_op_func_t		icode_prepare_op;
	icode_make_cast_func_t		icode_make_cast;
	icode_make_structreloc_func_t	icode_make_structreloc;
	make_null_block_func_t		make_null_block;
	make_init_name_func_t		make_init_name;
	debug_print_gprs_func_t		debug_print_gprs;
	name_to_reg_func_t		name_to_reg;
	asmvreg_to_reg_func_t		asmvreg_to_reg;
	get_inlineasm_label_func_t	get_inlineasm_label;
	do_ret_func_t			do_ret;
	get_abi_reg_func_t		get_abi_reg;
	get_abi_ret_reg_func_t		get_abi_ret_reg;
	same_representation_func_t	same_representation;
};

struct scope;
struct vreg;
struct inline_asm_stmt;
struct gas_token;
struct decl;
struct copystruct;
struct int_memcpy_data;
struct builtinframeaddressdata;

int	init_backend(FILE *fd, struct scope *s);
int	do_xlate(struct function *, struct icode_instr **);
struct reg	*generic_alloc_gpr(struct function *f,
	int size, struct icode_list *il, struct reg *dontwipe,
	struct reg *regset, int nregs, int *csave_map, int line);
size_t	get_sizeof_type(struct type *, struct token *);
struct vreg	*get_sizeof_vla_type(struct type *, struct icode_list *);
size_t	generic_print_init_var(FILE *out, struct decl *d, size_t segoff,
	void (*print_init_expr)(struct type *, struct expr *),
		int skip_is_space);
void	generic_print_init_list(FILE *out, struct decl *, struct initializer *,
	void (*print_init_expr)(struct type *, struct expr *));
void	new_generic_print_init_list(FILE *out, struct decl *, struct initializer *,
	void (*print_init_expr)(struct type *, struct expr *));
void	relocate_struct_regs(struct copystruct *cs, struct reg *r0,
		struct reg *r1, struct reg *r2, struct icode_list *il);
void	copy_struct_regstack(struct decl *dec);
void	store_reg_to_stack_block(struct reg *, struct stack_block *);
unsigned long	align_for_cur_auto_var(struct type *ty, unsigned long off);

#include <stdarg.h>

typedef void	(*extern_decls_func_t)(void);
typedef	void	(*static_decls_func_t)(void);
typedef void	(*struct_defs_func_t)(void);
typedef void	(*strings_func_t)(void);
typedef void	(*comment_func_t)(const char *fmt, ...);
typedef void	(*dwarf2_line_func_t)(struct token *);
typedef void	(*dwarf2_files_func_t)(void);
typedef void	(*inlineasm_func_t)(struct inline_asm_stmt *);
typedef void	(*genunimpl_func_t)(void);
typedef void	(*empty_func_t)(void);
typedef void	(*label_func_t)(const char *label, int is_func);
typedef void	(*call_func_t)(const char *name);
typedef void	(*call_indir_func_t)(struct reg *r);
typedef void	(*func_intro_t)(struct function *f);
typedef void	(*func_outro_t)(void);
typedef void	(*define_func_t)(const char *name, const char *fmt, ...);
typedef void	(*push_func_t)(struct function *f, struct icode_instr *);
typedef void	(*allocstack_func_t)(struct function *f, size_t bytes);
typedef void	(*freestack_func_t)(struct function *f, size_t *bytes);
typedef void	(*adj_allocated_func_t)(struct function *f, int *bytes);
typedef void	(*inc_func_t)(struct icode_instr *);
typedef void	(*dec_func_t)(struct icode_instr *);
typedef void	(*load_func_t)(struct reg *r, struct vreg *vr);
typedef void	(*store_func_t)(struct vreg *dest, struct vreg *src);
typedef void	(*neg_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*sub_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*add_func_t)(struct reg **dest, struct icode_instr *src);
typedef void
(*div_func_t)(struct reg **dest, struct icode_instr *src, int);
typedef void	(*mod_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*mul_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*shl_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*shr_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*or_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*preg_or_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*and_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*xor_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*not_func_t)(struct reg **dest, struct icode_instr *src);
typedef void	(*cmp_func_t)(struct reg **dest, struct icode_instr *ii);
typedef void	(*extend_sign_func_t)(struct icode_instr *ii);
typedef void	(*conv_fp_func_t)(struct icode_instr *ii);
typedef void	(*branch_func_t)(struct icode_instr *ii);

#define SECTION_STACK 1 /* never used? */
#define SECTION_UNINIT 2
#define SECTION_INIT 3
#define SECTION_TEXT 4
#define SECTION_RODATA 5
typedef void	(*setsection_func_t)(int value);
typedef void	(*alloc_func_t)(size_t nbytes);
typedef void	(*ret_func_t)(struct icode_instr *ii);
typedef void	(*mov_func_t)(struct copyreg *cr);
typedef void	(*setreg_func_t)(struct reg *dest, int *value);
typedef void	(*xchg_func_t)(struct reg *r1, struct reg *r2);
typedef void	(*addrof_func_t)(struct reg *dest, struct vreg *src,
		struct vreg *structtop);
typedef void	(*copyinit_func_t)(struct decl *dec);
typedef void	(*copystruct_func_t)(struct copystruct *cs);
typedef void	(*intrinsic_memcpy_func_t)(struct int_memcpy_data *cs);
typedef void	(*zerostack_func_t)(struct stack_block *addr, size_t nbytes);
typedef void	(*alloca_func_t)(struct allocadata *ad);
typedef void	(*dealloca_func_t)(struct stack_block *sb, struct reg *r);
typedef void	(*alloc_vla_func_t)(struct stack_block *ad);
typedef void	(*dealloc_vla_func_t)(struct stack_block *sb, struct reg *r);
typedef void	(*put_vla_size_func_t)(struct vlasizedata *data);
typedef void	(*retr_vla_size_func_t)(struct vlasizedata *data);
typedef void	(*load_vla_func_t)(struct reg *r, struct stack_block *sb);
typedef void	(*builtin_frame_address_func_t)(struct builtinframeaddressdata *);
typedef void	(*struct_inits_func_t)(void);
typedef void	(*save_ret_addr_func_t)(struct function *,
		struct stack_block *);
typedef void
(*check_ret_addr_func_t)(struct function *, struct stack_block *);
typedef void	(*print_mem_operand_func_t)(struct vreg *, struct token *);


struct emitter {
	init_func_t		init;
	strings_func_t		strings;
	extern_decls_func_t	extern_decls;
	static_decls_func_t	static_decls;
	struct_defs_func_t	struct_defs;
	comment_func_t		comment;
	dwarf2_line_func_t	dwarf2_line;
	dwarf2_files_func_t	dwarf2_files;
	inlineasm_func_t	inlineasm;
	genunimpl_func_t	genunimpl;
	empty_func_t		empty;
	label_func_t		label;
	call_func_t		call;
	call_indir_func_t	callindir;
	func_intro_t		intro;
	func_outro_t		outro;
	define_func_t		define;
	push_func_t		push;
	allocstack_func_t	allocstack;
	freestack_func_t	freestack;
	adj_allocated_func_t	adj_allocated;
	inc_func_t		inc;
	dec_func_t		dec;
	load_func_t		load;
	store_func_t		store;
	setsection_func_t	setsection;
	alloc_func_t		alloc;
	neg_func_t		neg;
	sub_func_t		sub;
	add_func_t		add;
	div_func_t		div;
	mod_func_t		mod;
	mul_func_t		mul;
	shl_func_t		shl;
	shr_func_t		shr;
	or_func_t		or;
	preg_or_func_t		preg_or;
	and_func_t		and;
	xor_func_t		xor;
	not_func_t		not;
	ret_func_t		ret;
	cmp_func_t		cmp;
	extend_sign_func_t	extend_sign;
	conv_fp_func_t		conv_fp;
	branch_func_t		branch;
	mov_func_t		mov;
	setreg_func_t		setreg;
	xchg_func_t		xchg;
	addrof_func_t		addrof;
	copyinit_func_t		copyinit;
	copystruct_func_t	copystruct;
	intrinsic_memcpy_func_t	intrinsic_memcpy;
	zerostack_func_t	zerostack;
	alloca_func_t		alloca_;
	dealloca_func_t		dealloca;
	alloc_vla_func_t	alloc_vla;
	dealloc_vla_func_t	dealloc_vla;
	put_vla_size_func_t	put_vla_size;
	retr_vla_size_func_t	retr_vla_size;
	load_vla_func_t		load_vla;
	builtin_frame_address_func_t	frame_address;
	struct_inits_func_t	struct_inits;
	save_ret_addr_func_t	save_ret_addr;
	check_ret_addr_func_t	check_ret_addr;
	print_mem_operand_func_t	print_mem_operand;
};

extern struct backend	*backend;
extern struct emitter	*emit;
extern struct reg	*tmpgpr;
extern struct reg	*tmpgpr2;
extern struct reg	*tmpfpr;
extern int		host_endianness;
extern struct init_with_name	*init_list_head;
extern struct init_with_name	*init_list_tail;
extern int	backend_warn_inv;


struct allocation {
	int	unused;
};

#define ALLOC_GPR(func, size, il, dontwipe) \
	backend->alloc_gpr((func), (size), (il), (dontwipe), __LINE__) 

#include "x86_gen.h"
#include "mips_gen.h"
#include "amd64_gen.h"
#include "power_gen.h"
#include "sparc_gen.h"
#include "reg.h"
#include "stack.h"

#endif



syntax highlighted by Code2HTML, v. 0.9.1