
extern int target_flags;

enum reg_class
{ NO_REGS, BYTE_POINTER_REG, FUNNEL_COUNT_REG, QUOTIENT_REG,
  COUNT_REMAINING_REG, SPECIAL_REGS, GENERAL_REGS, ALL_REGS,
  LIM_REG_CLASSES };

extern int may_call_alloca;
extern int current_function_pretend_args_size;

extern	struct	_iobuf {
	int	_cnt;
	char	*_ptr;
	char	*_base;
	int	_bufsiz;
	short	_flag;
	char	_file;
} _iob[20 ];

struct _iobuf 	*fopen();
struct _iobuf 	*fdopen();
struct _iobuf 	*freopen();
long	ftell();
char	*gets();
char	*fgets();
char	*sprintf();

enum tree_code {

  ERROR_MARK,

  IDENTIFIER_NODE,

  OP_IDENTIFIER,

  TREE_LIST,

  VOID_TYPE,

  INTEGER_TYPE,

  REAL_TYPE,

  COMPLEX_TYPE,

  ENUMERAL_TYPE,

  BOOLEAN_TYPE,

  CHAR_TYPE,

  POINTER_TYPE,

  OFFSET_TYPE,

  REFERENCE_TYPE,

  METHOD_TYPE,

  FILE_TYPE,

  ARRAY_TYPE,

  SET_TYPE,

  STRING_TYPE,

  RECORD_TYPE,

  UNION_TYPE,

  FUNCTION_TYPE,

  LANG_TYPE,

  LABEL_STMT,

  GOTO_STMT,

  RETURN_STMT,

  EXPR_STMT,

  WITH_STMT,

  LET_STMT,

  IF_STMT,

  EXIT_STMT,

  CASE_STMT,

  LOOP_STMT,

  COMPOUND_STMT,

  ASM_STMT,

  INTEGER_CST,

  REAL_CST,

  COMPLEX_CST,

  STRING_CST,

  FUNCTION_DECL,
  LABEL_DECL,
  CONST_DECL,
  TYPE_DECL,
  VAR_DECL,
  PARM_DECL,
  RESULT_DECL,
  FIELD_DECL,

  COMPONENT_REF,

  INDIRECT_REF,

  OFFSET_REF,

  BUFFER_REF,

  ARRAY_REF,

  CONSTRUCTOR,

  COMPOUND_EXPR,

  MODIFY_EXPR,

  INIT_EXPR,

  NEW_EXPR,
  DELETE_EXPR,

  PUSH_EXPR,
  POP_EXPR,

  COND_EXPR,

  CALL_EXPR,

  METHOD_CALL_EXPR,

  WITH_CLEANUP_EXPR,

  PLUS_EXPR,
  MINUS_EXPR,
  MULT_EXPR,

  TRUNC_DIV_EXPR,

  CEIL_DIV_EXPR,

  FLOOR_DIV_EXPR,

  ROUND_DIV_EXPR,

  TRUNC_MOD_EXPR,
  CEIL_MOD_EXPR,
  FLOOR_MOD_EXPR,
  ROUND_MOD_EXPR,

  RDIV_EXPR,

  EXACT_DIV_EXPR,

  FIX_TRUNC_EXPR,
  FIX_CEIL_EXPR,
  FIX_FLOOR_EXPR,
  FIX_ROUND_EXPR,

  FLOAT_EXPR,

  EXPON_EXPR,

  NEGATE_EXPR,

  MIN_EXPR,
  MAX_EXPR,
  ABS_EXPR,
  FFS_EXPR,

  LSHIFT_EXPR,
  RSHIFT_EXPR,
  LROTATE_EXPR,
  RROTATE_EXPR,

  BIT_IOR_EXPR,
  BIT_XOR_EXPR,
  BIT_AND_EXPR,
  BIT_ANDTC_EXPR,
  BIT_NOT_EXPR,

  TRUTH_ANDIF_EXPR,
  TRUTH_ORIF_EXPR,
  TRUTH_AND_EXPR,
  TRUTH_OR_EXPR,
  TRUTH_NOT_EXPR,

  LT_EXPR,
  LE_EXPR,
  GT_EXPR,
  GE_EXPR,
  EQ_EXPR,
  NE_EXPR,

  IN_EXPR,
  SET_LE_EXPR,
  CARD_EXPR,
  RANGE_EXPR,

  CONVERT_EXPR,

  NOP_EXPR,

  SAVE_EXPR,

  RTL_EXPR,

  ADDR_EXPR,

  REFERENCE_EXPR,

  WRAPPER_EXPR,
  ANTI_WRAPPER_EXPR,

  ENTRY_VALUE_EXPR,

  COMPLEX_EXPR,

  CONJ_EXPR,

  REALPART_EXPR,
  IMAGPART_EXPR,

  PREDECREMENT_EXPR,
  PREINCREMENT_EXPR,
  POSTDECREMENT_EXPR,
  POSTINCREMENT_EXPR,

  LAST_AND_UNUSED_TREE_CODE

};

extern char *tree_code_type[];

extern int tree_code_length[];

enum machine_mode {

 VOIDmode,

 QImode,
 HImode,

 PSImode,
 SImode,
 PDImode,
 DImode,
 TImode,
 QFmode,
 HFmode,
 SFmode,
 DFmode,
 XFmode,
 TFmode,
 CQImode,
 CHImode,
 CSImode,
 CDImode,
 CTImode,
 CQFmode,
 CHFmode,
 CSFmode,
 CDFmode,
 CXFmode,
 CTFmode,

 BImode,

 BLKmode,

 EPmode,

MAX_MACHINE_MODE };

enum built_in_function
{
  NOT_BUILT_IN,
  BUILT_IN_ALLOCA,
  BUILT_IN_ABS,
  BUILT_IN_FABS,
  BUILT_IN_LABS,
  BUILT_IN_FFS,
  BUILT_IN_DIV,
  BUILT_IN_LDIV,
  BUILT_IN_FFLOOR,
  BUILT_IN_FCEIL,
  BUILT_IN_FMOD,
  BUILT_IN_FREM,
  BUILT_IN_MEMCPY,
  BUILT_IN_MEMCMP,
  BUILT_IN_MEMSET,
  BUILT_IN_FSQRT,
  BUILT_IN_GETEXP,
  BUILT_IN_GETMAN,
  BUILT_IN_SAVEREGS,
  BUILT_IN_CLASSIFY_TYPE,

  BUILT_IN_NEW,
  BUILT_IN_VEC_NEW,
  BUILT_IN_DELETE,
  BUILT_IN_VEC_DELETE,
};

typedef union tree_node *tree;

struct tree_common
{
  int uid;
  union tree_node *chain;
  union tree_node *type;
  unsigned char code : 8;

  unsigned external_attr : 1;
  unsigned public_attr : 1;
  unsigned static_attr : 1;
  unsigned volatile_attr : 1;
  unsigned packed_attr : 1;
  unsigned readonly_attr : 1;
  unsigned literal_attr : 1;
  unsigned nonlocal_attr : 1;
  unsigned permanent_attr : 1;
  unsigned addressable_attr : 1;
  unsigned regdecl_attr : 1;
  unsigned this_vol_attr : 1;
  unsigned unsigned_attr : 1;
  unsigned asm_written_attr: 1;
  unsigned inline_attr : 1;
  unsigned used_attr : 1;
  unsigned lang_flag_1 : 1;
  unsigned lang_flag_2 : 1;
  unsigned lang_flag_3 : 1;
  unsigned lang_flag_4 : 1;

};

struct tree_int_cst
{
  char common[sizeof (struct tree_common)];
  long int_cst_low;
  long int_cst_high;
};

extern double ldexp ();

extern double atof ();

union real_extract
{
  double  d;
  int i[sizeof (double ) / sizeof (int)];
};

double  real_value_from_int_cst ();

struct tree_real_cst
{
  char common[sizeof (struct tree_common)];
  struct rtx_def *rtl;

  double  real_cst;
};

struct tree_string
{
  char common[sizeof (struct tree_common)];
  struct rtx_def *rtl;

  int length;
  char *pointer;
};

struct tree_complex
{
  char common[sizeof (struct tree_common)];
  struct rtx_def *rtl;

  union tree_node *real;
  union tree_node *imag;
};

struct tree_identifier
{
  char common[sizeof (struct tree_common)];
  int length;
  char *pointer;
};

struct tree_list
{
  char common[sizeof (struct tree_common)];
  union tree_node *purpose;
  union tree_node *value;
};

struct tree_exp
{
  char common[sizeof (struct tree_common)];
  int complexity;
  union tree_node *operands[1];
};

struct tree_type
{
  char common[sizeof (struct tree_common)];
  union tree_node *values;
  union tree_node *sep;
  union tree_node *size;

  enum machine_mode mode : 8;
  unsigned char size_unit;
  unsigned char align;
  unsigned char sep_unit;

  union tree_node *pointer_to;
  union tree_node *reference_to;
  int parse_info;
  int symtab_address;
  union tree_node *name;
  union tree_node *max;
  union tree_node *next_variant;
  union tree_node *main_variant;
  union tree_node *basetypes;
  union tree_node *noncopied_parts;

  struct lang_type *lang_specific;
};

struct tree_decl
{
  char common[sizeof (struct tree_common)];
  char *filename;
  int linenum;
  union tree_node *size;
  enum machine_mode mode : 8;
  unsigned char size_unit;
  unsigned char align;
  unsigned char voffset_unit;
  union tree_node *name;
  union tree_node *context;
  int offset;
  union tree_node *voffset;
  union tree_node *arguments;
  union tree_node *result;
  union tree_node *initial;
  char *print_name;
  char *assembler_name;
  struct rtx_def *rtl;

  int frame_size;
  struct rtx_def *saved_insns;

  int block_symtab_address;

  struct lang_decl *lang_specific;
};

struct tree_stmt
{
  char common[sizeof (struct tree_common)];
  char *filename;
  int linenum;
  union tree_node *body;
};

struct tree_if_stmt
{
  char common[sizeof (struct tree_common)];
  char *filename;
  int linenum;
  union tree_node *cond, *thenpart, *elsepart;
};

struct tree_bind_stmt
{
  char common[sizeof (struct tree_common)];
  char *filename;
  int linenum;
  union tree_node *body, *vars, *supercontext, *bind_size, *type_tags;
  union tree_node *subblocks;
};

struct tree_case_stmt
{
  char common[sizeof (struct tree_common)];
  char *filename;
  int linenum;
  union tree_node *index, *case_list;
};

union tree_node
{
  struct tree_common common;
  struct tree_int_cst int_cst;
  struct tree_real_cst real_cst;
  struct tree_string string;
  struct tree_complex complex;
  struct tree_identifier identifier;
  struct tree_decl decl;
  struct tree_type type;
  struct tree_list list;
  struct tree_exp exp;
  struct tree_stmt stmt;
  struct tree_if_stmt if_stmt;
  struct tree_bind_stmt bind_stmt;
  struct tree_case_stmt case_stmt;
};

extern char *oballoc ();
extern char *permalloc ();

extern tree make_node ();

extern tree copy_node ();

extern tree copy_list ();

extern tree get_identifier ();

extern tree build_int_2 ();
extern tree build_real ();
extern tree build_real_from_string ();
extern tree build_real_from_int_cst ();
extern tree build_complex ();
extern tree build_string ();
extern tree build ();
extern tree build_nt ();
extern tree build_tree_list ();
extern tree build_op_identifier ();
extern tree build_decl ();
extern tree build_let ();

extern tree make_signed_type ();
extern tree make_unsigned_type ();
extern void fixup_unsigned_type ();
extern tree build_pointer_type ();
extern tree build_reference_type ();
extern tree build_index_type ();
extern tree build_array_type ();
extern tree build_function_type ();
extern tree build_method_type ();
extern tree build_offset_type ();
extern tree array_type_nelts ();

extern tree build_binary_op ();
extern tree build_indirect_ref ();
extern tree build_unary_op ();

extern tree build_type_variant ();

extern void layout_type ();

extern tree type_hash_canon ();

extern void layout_decl ();

extern tree fold ();

extern tree combine ();

extern tree convert ();
extern tree convert_units ();
extern tree size_in_bytes ();
extern tree genop ();
extern tree build_int ();
extern tree get_pending_sizes ();

extern tree sizetype;

extern tree chainon ();

extern tree tree_cons (), perm_tree_cons (), temp_tree_cons ();
extern tree saveable_tree_cons ();

extern tree tree_last ();

extern tree nreverse ();

extern int list_length ();

extern int integer_zerop ();

extern int integer_onep ();

extern int integer_all_onesp ();

extern int type_unsigned_p ();

extern int staticp ();

extern int lvalue_or_else ();

extern tree save_expr ();

extern tree stabilize_reference ();

extern tree get_unwidened ();

extern tree get_narrower ();

extern tree type_for_size ();

extern tree unsigned_type ();

extern tree signed_type ();

extern tree get_floating_type ();

extern char *function_cannot_inline_p ();

extern tree integer_zero_node;

extern tree integer_one_node;

extern tree size_zero_node;

extern tree size_one_node;

extern tree null_pointer_node;

extern tree error_mark_node;

extern tree void_type_node;

extern tree integer_type_node;

extern tree unsigned_type_node;

extern tree char_type_node;

extern char *input_filename;

extern int lineno;

extern int pedantic;

extern int immediate_size_expand;

extern tree current_function_decl;

extern int current_function_calls_setjmp;

extern int all_types_permanent;

extern tree expand_start_stmt_expr ();
extern tree expand_end_stmt_expr ();
extern void expand_expr_stmt (), clear_last_expr ();
extern void expand_label (), expand_goto (), expand_asm ();
extern void expand_start_cond (), expand_end_cond ();
extern void expand_start_else (), expand_end_else ();
extern void expand_start_loop (), expand_start_loop_continue_elsewhere ();
extern void expand_loop_continue_here ();
extern void expand_end_loop ();
extern int expand_continue_loop ();
extern int expand_exit_loop (), expand_exit_loop_if_false ();
extern int expand_exit_something ();

extern void expand_start_delayed_expr ();
extern tree expand_end_delayed_expr ();
extern void expand_emit_delayed_expr ();

extern void expand_null_return (), expand_return ();
extern void expand_start_bindings (), expand_end_bindings ();
extern void expand_start_case (), expand_end_case ();
extern int pushcase (), pushcase_range ();
extern void expand_start_function (), expand_end_function ();

enum rtx_code  {

  UNKNOWN ,

  NIL ,

  EXPR_LIST ,

  INSN_LIST ,

  MATCH_OPERAND ,

  MATCH_DUP ,

  MATCH_OPERATOR ,

  DEFINE_INSN ,

  DEFINE_PEEPHOLE ,

  DEFINE_COMBINE ,

  DEFINE_EXPAND ,

  SEQUENCE ,

  ADDRESS ,

  INSN ,

  JUMP_INSN ,

  CALL_INSN ,

  BARRIER ,

  CODE_LABEL ,

  NOTE ,

  INLINE_HEADER ,

  PARALLEL ,

  ASM_INPUT ,

  ASM_OPERANDS ,

  ADDR_VEC ,

  ADDR_DIFF_VEC ,

  SET ,

  USE ,

  CLOBBER ,

  CALL ,

  RETURN ,

  CONST_INT ,

  CONST_DOUBLE ,

  CONST ,

  PC ,

  REG ,

  SUBREG ,

  STRICT_LOW_PART ,

  MEM ,

  LABEL_REF ,

  SYMBOL_REF ,

  CC0 ,

  QUEUED ,

  IF_THEN_ELSE ,

  COMPARE ,

  PLUS ,

  MINUS ,

  NEG ,

  MULT ,

  DIV ,

  MOD ,

  UMULT ,
  UDIV ,
  UMOD ,

  AND ,

  IOR ,

  XOR ,

  NOT ,

  LSHIFT ,
  ASHIFT ,
  ROTATE ,

  ASHIFTRT ,
  LSHIFTRT ,
  ROTATERT ,

  PRE_DEC ,
  PRE_INC ,
  POST_DEC ,
  POST_INC ,

  NE ,
  EQ ,
  GE ,
  GT ,
  LE ,
  LT ,
  GEU ,
  GTU ,
  LEU ,
  LTU ,

  SIGN_EXTEND ,

  ZERO_EXTEND ,

  TRUNCATE ,

  FLOAT_EXTEND ,
  FLOAT_TRUNCATE ,

  FLOAT ,

  FIX ,

  UNSIGNED_FLOAT ,

  UNSIGNED_FIX ,

  ABS ,

  SQRT ,

  FFS ,

  SIGN_EXTRACT ,

  ZERO_EXTRACT ,

  LAST_AND_UNUSED_RTX_CODE};

extern int rtx_length[];

extern char *rtx_name[];

extern char *rtx_format[];

extern char *mode_name[];

enum mode_class { MODE_RANDOM, MODE_INT, MODE_FLOAT,
		  MODE_COMPLEX_INT, MODE_COMPLEX_FLOAT, MODE_FUNCTION };

extern enum mode_class mode_class[];

extern int mode_size[];

extern int mode_unit_size[];

extern enum machine_mode mode_wider_mode[];

typedef union rtunion_def
{
  int rtint;
  char *rtstr;
  struct rtx_def *rtx;
  struct rtvec_def *rtvec;
  enum machine_mode rttype;
} rtunion;

typedef struct rtx_def
{

  enum rtx_code code : 16;

  enum machine_mode mode : 8;

  unsigned int jump : 1;

  unsigned int call : 1;

  unsigned int unchanging : 1;

  unsigned int volatil : 1;

  unsigned int in_struct : 1;

  unsigned int used : 1;

  unsigned integrated : 1;

  rtunion fld[1];
} *rtx;

typedef struct rtvec_def{
  unsigned num_elem;
  rtunion elem[1];
} *rtvec;

enum reg_note { REG_DEAD = 1, REG_INC = 2, REG_EQUIV = 3, REG_WAS_0 = 4,
		REG_EQUAL = 5, REG_RETVAL = 6, REG_LIBCALL = 7,
		REG_NONNEG = 8, REG_UNSET = 9 };

extern char *reg_note_name[];

extern char *note_insn_name[];

extern rtx rtx_alloc ();
extern rtvec rtvec_alloc ();
extern rtx find_reg_note ();
extern rtx gen_rtx ();
extern rtx copy_rtx ();
extern rtvec gen_rtvec ();
extern rtvec gen_rtvec_v ();
extern rtx gen_reg_rtx ();
extern rtx gen_label_rtx ();
extern rtx gen_inline_header_rtx ();
extern rtx gen_lowpart ();
extern rtx gen_highpart ();
extern int subreg_lowpart_p ();
extern rtx make_safe_from ();
extern rtx memory_address ();
extern rtx get_insns ();
extern rtx get_last_insn ();
extern rtx start_sequence ();
extern rtx gen_sequence ();
extern rtx expand_expr ();
extern rtx output_constant_def ();
extern rtx immed_real_const ();
extern rtx immed_real_const_1 ();
extern rtx immed_double_const ();
extern rtx force_const_double_mem ();
extern rtx force_const_mem ();
extern rtx get_parm_real_loc ();
extern rtx assign_stack_local ();
extern rtx protect_from_queue ();
extern void emit_queue ();
extern rtx emit_move_insn ();
extern rtx emit_insn ();
extern rtx emit_jump_insn ();
extern rtx emit_call_insn ();
extern rtx emit_call_insn_before ();
extern rtx emit_insn_before ();
extern rtx emit_insn_after ();
extern rtx emit_label ();
extern rtx emit_barrier ();
extern rtx emit_barrier_after ();
extern rtx emit_note ();
extern rtx emit_line_note ();
extern rtx emit_line_note_force ();
extern rtx prev_real_insn ();
extern rtx next_real_insn ();
extern rtx next_nondeleted_insn ();
extern rtx plus_constant ();
extern rtx find_equiv_reg ();
extern rtx delete_insn ();
extern rtx adj_offsettable_operand ();

extern int max_parallel;

extern int asm_noperands ();
extern char *decode_asm_operands ();

extern enum reg_class reg_preferred_class ();

extern rtx get_first_nonparm_insn ();

extern rtx pc_rtx;
extern rtx cc0_rtx;
extern rtx const0_rtx;
extern rtx const1_rtx;
extern rtx fconst0_rtx;
extern rtx dconst0_rtx;

extern rtx stack_pointer_rtx;
extern rtx frame_pointer_rtx;
extern rtx arg_pointer_rtx;
extern rtx struct_value_rtx;
extern rtx struct_value_incoming_rtx;
extern rtx static_chain_rtx;
extern rtx static_chain_incoming_rtx;

tree sizetype;

tree size_zero_node;

tree size_one_node;

tree permanent_type_chain;

tree temporary_type_chain;

tree permanent_type_end;
tree temporary_type_end;

void
chain_type (t)
     tree t;
{
  if (((t)->type.main_variant)  != t)
    return;
  if (((t)->common.chain)  != 0)
    return;
  if (((t)->common.permanent_attr) )
    {

      if (t == permanent_type_end)
	return;

      if (permanent_type_chain == 0)
	permanent_type_chain = t;
      else
	((permanent_type_end)->common.chain)  = t;
      permanent_type_end = t;
    }
  else
    {
      if (t == temporary_type_end)
	return;
      if (temporary_type_chain == 0)
	temporary_type_chain = t;
      else
	((temporary_type_end)->common.chain)  = t;
      temporary_type_end = t;
    }
}

tree
get_permanent_types ()
{
  register tree tem = permanent_type_chain;
  permanent_type_chain = 0;
  permanent_type_end = 0;
  return tem;
}

tree
get_temporary_types ()
{
  register tree tem = temporary_type_chain;
  temporary_type_chain = 0;
  temporary_type_end = 0;
  return tem;
}

static tree pending_sizes;

int immediate_size_expand;

tree
get_pending_sizes ()
{
  tree chain = pending_sizes;
  pending_sizes = 0;
  return chain;
}

static tree
variable_size (size)
     tree size;
{
  size = save_expr (size);

  if (global_bindings_p ())
    {
      error ("variable-size type declared outside of any function");
      return build_int (1);
    }

  if (immediate_size_expand)
    expand_expr (size, 0, VOIDmode, 0);
  else
    pending_sizes = tree_cons (0, size, pending_sizes);

  return size;
}

static
enum machine_mode
agg_mode (size)
     unsigned int size;
{
  register int units = size / 8 ;
  register enum machine_mode t, val;

  if (size % 8  != 0)
    return BLKmode;

  if (size >  (8  * mode_size[(int)(DImode)])  )
    return BLKmode;

  val = BLKmode;
  for (t = QImode; 	(mode_class[(int)(t)])  == MODE_INT;
       t = (enum machine_mode) ((int) t + 1))
    if (	(mode_size[(int)(t)])  == units)
      val = t;

  return val;
}

tree
build_int (v)
     int v;
{
  register tree t;

  static tree size_table[33];

  if (v < 33 && size_table[v] != 0)
    return size_table[v];
  if (v < 33)
    {
      int temp = allocation_temporary_p ();

      if (temp)
	end_temporary_allocation ();
      t = build_int_2 (v, 0);
      ((t)->common.type)  = sizetype;
      size_table[v] = t;
      if (temp)
	resume_temporary_allocation ();
    }
  else
    {
      t = build_int_2 (v, 0);
      ((t)->common.type)  = sizetype;
    }
  return t;
}

tree
genop (opc, op1, op2)
     enum tree_code opc;
     tree op1, op2;
{

  if (((enum tree_code) (op1)->common.code)  == INTEGER_CST && ((enum tree_code) (op2)->common.code)  == INTEGER_CST)
    {

      if (opc == PLUS_EXPR
	  && ((op1)->int_cst.int_cst_low)  == 0
	  && ((op1)->int_cst.int_cst_high)  == 0)
	return op2;
      if (opc == MINUS_EXPR
	  && ((op2)->int_cst.int_cst_low)  == 0
	  && ((op2)->int_cst.int_cst_high)  == 0)
	return op1;
      if (opc == MULT_EXPR
	  && ((op1)->int_cst.int_cst_low)  == 1
	  && ((op1)->int_cst.int_cst_high)  == 0)
	return op2;
      if (opc == CEIL_DIV_EXPR
	  && ((op1)->int_cst.int_cst_low)  == ((op2)->int_cst.int_cst_low)
	  && ((op1)->int_cst.int_cst_high)  == ((op2)->int_cst.int_cst_high) )
	return size_one_node;

      return combine (opc, op1, op2);
    }

  if (op1 == error_mark_node || op2 == error_mark_node)
    return error_mark_node;

  return fold (build (opc, sizetype, op1, op2));
}

tree
convert_units (size, inunits, outunits)
   tree size;
   register int inunits, outunits;
{
  register tree t;

  if (inunits == outunits)
    return size;

  if (0 == (inunits % outunits))
    return genop (MULT_EXPR, size, build_int (inunits / outunits));

  if (0 == (outunits % inunits))
    {

      if (((enum tree_code) (size)->common.code)  == MULT_EXPR
	  && ((enum tree_code) (((size)->exp.operands[ 1]) )->common.code)  == INTEGER_CST
	  && 0 == (outunits / inunits) % ((((size)->exp.operands[ 1]) )->int_cst.int_cst_low)
	  && ((enum tree_code) (((size)->exp.operands[ 0]) )->common.code)  == CEIL_DIV_EXPR
	  && tree_int_cst_equal (((size)->exp.operands[ 1]) ,
				 ((((size)->exp.operands[ 0]) )->exp.operands[ 1]) ))
	size = ((((size)->exp.operands[ 0]) )->exp.operands[ 0]) ;
      return genop (CEIL_DIV_EXPR, size, build_int (outunits / inunits));
    }

  t = genop (MULT_EXPR, size,
	     build_int (inunits));
  return genop (CEIL_DIV_EXPR, t,
		build_int (outunits));
}

void
layout_decl (decl, known_align)
     tree decl;
     unsigned known_align;
{
  register tree type = ((decl)->common.type) ;
  register enum tree_code code = ((enum tree_code) (decl)->common.code) ;
  int spec_size = ((decl)->decl.size_unit) ;
  int bitsize;

  if (code == CONST_DECL)
    return;

  if (code != VAR_DECL && code != PARM_DECL && code != RESULT_DECL
      && code != FIELD_DECL && code != TYPE_DECL)
    abort ();

  if (type == error_mark_node)
    {
      type = void_type_node;
      spec_size = 0;
    }
  if (((type)->type.size_unit)  == 0)
    abort ();

  ((decl)->decl.mode)  = ((type)->type.mode) ;
  ((decl)->decl.size)  = ((type)->type.size) ;
  ((decl)->decl.size_unit)  = ((type)->type.size_unit) ;
  ((decl)->common.unsigned_attr)  = ((type)->common.unsigned_attr) ;

  if (code == FIELD_DECL && ((decl)->common.packed_attr) )
    {

      if (! (((enum tree_code) (type)->common.code)  == INTEGER_TYPE
	     || ((enum tree_code) (type)->common.code)  == ENUMERAL_TYPE))
	abort ();

      if (spec_size == 0)
	abort ();

      ((decl)->decl.mode)  = BImode;

      ((decl)->decl.size)  = size_one_node;
      ((decl)->decl.size_unit)  = spec_size;
    }

  else if (((type)->type.align)  > ((decl)->decl.align) )
    ((decl)->decl.align)  = ((type)->type.align) ;

  if (((decl)->decl.size) )
    bitsize = ((((decl)->decl.size) )->int_cst.int_cst_low)  * ((decl)->decl.size_unit) ;

  if ((((decl)->decl.mode)  == BLKmode
       || ((decl)->decl.mode)  == BImode)

      && ((type)->type.mode)  != BLKmode
      && ((type)->type.size)  != 0
      && ((enum tree_code) (((type)->type.size) )->common.code)  == INTEGER_CST)
    {
      register enum machine_mode xmode = agg_mode (bitsize);

      if (xmode != BLKmode
	  && known_align % ((32 ) < ( ((1) > ( ((mode_unit_size[(int)(xmode)])  * 8 )) ? (1) : ( ((mode_unit_size[(int)(xmode)])  * 8 ))) ) ? (32 ) : ( ((1) > ( ((mode_unit_size[(int)(xmode)])  * 8 )) ? (1) : ( ((mode_unit_size[(int)(xmode)])  * 8 ))) ))   == 0)
	{
	  ((decl)->decl.align)  = ((((32 ) < ( ((1) > ( ((mode_unit_size[(int)(xmode)])  * 8 )) ? (1) : ( ((mode_unit_size[(int)(xmode)])  * 8 ))) ) ? (32 ) : ( ((1) > ( ((mode_unit_size[(int)(xmode)])  * 8 )) ? (1) : ( ((mode_unit_size[(int)(xmode)])  * 8 ))) ))  ) > (
				   ((decl)->decl.align) ) ? (((32 ) < ( ((1) > ( ((mode_unit_size[(int)(xmode)])  * 8 )) ? (1) : ( ((mode_unit_size[(int)(xmode)])  * 8 ))) ) ? (32 ) : ( ((1) > ( ((mode_unit_size[(int)(xmode)])  * 8 )) ? (1) : ( ((mode_unit_size[(int)(xmode)])  * 8 ))) ))  ) : (
				   ((decl)->decl.align) )) ;

	  ((decl)->decl.mode)  = xmode;
	  ((decl)->decl.size)  = build_int (	(mode_size[(int)(xmode)]) );
	  ((decl)->decl.size_unit)  = 8 ;
	  bitsize =  (8  * mode_size[(int)(xmode)]) ;
	}
    }

  if (((decl)->decl.size)  != 0
      && (((enum tree_code) (type)->common.code)  == RECORD_TYPE
	  || ((enum tree_code) (type)->common.code)  == UNION_TYPE
	  || ((enum tree_code) (type)->common.code)  == ARRAY_TYPE))
    {

      if (((	(mode_size[(int)( ((type)->type.mode) )])  + 4  - 1) / 4 )  * 32
	  < bitsize)
	((decl)->common.addressable_attr)  = 1;
    }

  if (((decl)->decl.size)  != 0 && ! ((((decl)->decl.size) )->common.literal_attr) )
    ((decl)->decl.size)  = variable_size (((decl)->decl.size) );
}

static void
layout_record (rec)
     tree rec;
{
  register tree field;

  int record_align = ((32 ) > ( ((rec)->type.align) ) ? (32 ) : ( ((rec)->type.align) )) ;

  tree pending_statics = (tree) 0  ;

  register int const_size = 0;
  register tree var_size = 0;
  register int size_unit = 8 ;

  for (field = ((rec)->type.values) ; field; field = ((field)->common.chain) )
    {
      register int desired_align;

      if (((enum tree_code) (field)->common.code)  == VAR_DECL)
	{
	  pending_statics = tree_cons (0 , field, pending_statics);
	  continue;
	}

      if (((enum tree_code) (field)->common.code)  == CONST_DECL || ((enum tree_code) (field)->common.code)  == TYPE_DECL)
	continue;

      layout_decl (field, var_size ? size_unit : const_size);
      desired_align = ((field)->decl.align) ;

      record_align = ((record_align) > ( desired_align) ? (record_align) : ( desired_align)) ;

      if (const_size % desired_align != 0
	  || (size_unit % desired_align != 0
	      && var_size))
	{

	  if (var_size == 0
	      || size_unit % desired_align == 0)
	    const_size
	      = (((const_size) + ( desired_align) - 1) / ( desired_align))  * desired_align;
	  else
	    {
	      var_size
		= genop (PLUS_EXPR, var_size,
			 build_int ((((const_size) + ( size_unit) - 1) / ( size_unit)) ));
	      const_size = 0;
	      var_size = convert_units (var_size, size_unit, desired_align);
	      size_unit = desired_align;
	    }
	}

      ((field)->decl.offset)  = const_size;
      ((field)->decl.voffset)   = var_size;
      ((field)->decl.voffset_unit)  = size_unit;

      if (((field)->decl.name)  == 0
	  && ((enum tree_code) (((field)->common.type) )->common.code)  == UNION_TYPE)
	{
	  tree uelt = ((((field)->common.type) )->type.values) ;
	  for (; uelt; uelt = ((uelt)->common.chain) )
	    {
	      ((uelt)->decl.context)  = ((field)->decl.context) ;
	      ((uelt)->decl.offset)  = ((field)->decl.offset) ;
	      ((uelt)->decl.voffset)   = ((field)->decl.voffset)  ;
	      ((uelt)->decl.voffset_unit)  = ((field)->decl.voffset_unit) ;
	    }
	}

      {
        register tree dsize = ((field)->decl.size) ;

	if (((dsize)->common.literal_attr) )
	  const_size += ((dsize)->int_cst.int_cst_low)  * ((field)->decl.size_unit) ;
	else if (var_size == 0)
	  {
	    var_size = dsize;
	    size_unit = ((field)->decl.size_unit) ;
	  }
	else
	  {
	    register int tunits = ((size_unit) < ( ((field)->decl.size_unit) ) ? (size_unit) : ( ((field)->decl.size_unit) )) ;
	    var_size
	      = genop (PLUS_EXPR,
		       convert_units (var_size, size_unit, tunits),
		       convert_units (dsize, ((field)->decl.size_unit) , tunits));
	  }
      }
    }

  if (var_size == 0)
    ((rec)->type.size)
      = build_int (((((((const_size) + ( record_align) - 1) / ( record_align))  * record_align) + (
			 size_unit) - 1) / (
			 size_unit)) );

  else
    {
      if (const_size)
	var_size
	  = genop (PLUS_EXPR, var_size,
		   build_int ((((const_size) + ( size_unit) - 1) / ( size_unit)) ));
      ((rec)->type.size)
	= convert_units (var_size,
			 size_unit,
			 record_align);
      size_unit = record_align;
    }

  ((rec)->type.size)  = convert_units (((rec)->type.size) , size_unit,
				   8 );
  ((rec)->type.size_unit)  = 8 ;
  ((rec)->type.align)  = ((32 ) < ( record_align) ? (32 ) : ( record_align)) ;

  for (field = pending_statics; field; field = ((field)->common.chain) )
    layout_decl (((field)->list.value) , 0);
}

static void
layout_union (rec)
     tree rec;
{
  register tree field;

  int union_align = 32 ;

  register int const_size = 0;
  register tree var_size = 0;

  for (field = ((rec)->type.values) ; field; field = ((field)->common.chain) )
    {

      if (((enum tree_code) (field)->common.code)  == CONST_DECL || ((enum tree_code) (field)->common.code)  == TYPE_DECL)
	continue;

      layout_decl (field, 0);
      ((field)->decl.offset)  = 0;
      ((field)->decl.voffset)   = 0;
      ((field)->decl.voffset_unit)  = 8 ;

      union_align = ((union_align) > ( ((field)->decl.align) ) ? (union_align) : ( ((field)->decl.align) )) ;

      if (((((field)->decl.size) )->common.literal_attr) )
	const_size = ((const_size) > (
			  ((((field)->decl.size) )->int_cst.int_cst_low)
			  * ((field)->decl.size_unit) ) ? (const_size) : (
			  ((((field)->decl.size) )->int_cst.int_cst_low)
			  * ((field)->decl.size_unit) )) ;

      else if (var_size == 0)
	var_size = convert_units (((field)->decl.size) ,
				  ((field)->decl.size_unit) ,
				  8 );
      else
	var_size = genop (MAX_EXPR,
			  convert_units (((field)->decl.size) ,
					 ((field)->decl.size_unit) ,
					 8 ),
			  var_size);
    }

  if (0  == var_size)
    ((rec)->type.size)  = build_int ((((const_size) + ( 8 ) - 1) / ( 8 )) );
  else if (const_size == 0)
    ((rec)->type.size)  = var_size;
  else
    ((rec)->type.size)  = genop (MAX_EXPR, var_size,
			     build_int ((((const_size) + ( 8 ) - 1) / ( 8 )) ));

  union_align = ((32 ) < ( union_align) ? (32 ) : ( union_align)) ;
  ((rec)->type.align)  = ((((rec)->type.align) ) > ( union_align) ? (((rec)->type.align) ) : ( union_align)) ;

  ((rec)->type.size)
    = convert_units (((rec)->type.size) , 8 , ((rec)->type.align) );
  ((rec)->type.size_unit)  = ((rec)->type.align) ;
}

void
layout_type (type)
     tree type;
{
  int old;
  int temporary = 0;

  if (type == 0)
    abort ();

  if (((type)->type.size) )
    return;

  old  = suspend_momentary ();
  if (((type)->common.permanent_attr)  && allocation_temporary_p ())
    {
      temporary = 1;
      end_temporary_allocation ();
    }

  chain_type (type);

  switch (((enum tree_code) (type)->common.code) )
    {
    case LANG_TYPE:

      abort ();

    case VOID_TYPE:
      ((type)->type.size)  = size_zero_node;
      ((type)->type.size_unit)  = 8 ;
      ((type)->type.align)  = 1;
      ((type)->type.mode)  = VOIDmode;
      break;

    case INTEGER_TYPE:
    case ENUMERAL_TYPE:
      if (((((type)->type.sep) )->int_cst.int_cst_high)  >= 0)
	((type)->common.unsigned_attr)  = 1;

      {
	enum machine_mode mode, t;

	mode = BLKmode;
	for (t = QImode; 	(mode_class[(int)(t)])  == MODE_INT;
	     t = (enum machine_mode) ((int) t + 1))
	  if ( (8  * mode_size[(int)(t)])  == ((type)->type.sep_unit) )
	    mode = t;

	((type)->type.mode)  = mode;
      }
      ((type)->type.size)  = build_int (	(mode_size[(int)(((type)->type.mode) )]) );
      ((type)->type.size_unit)  = 8 ;
      ((type)->type.align)  = ((32 ) < ( ((1) > ( ((mode_unit_size[(int)(((type)->type.mode) )])  * 8 )) ? (1) : ( ((mode_unit_size[(int)(((type)->type.mode) )])  * 8 ))) ) ? (32 ) : ( ((1) > ( ((mode_unit_size[(int)(((type)->type.mode) )])  * 8 )) ? (1) : ( ((mode_unit_size[(int)(((type)->type.mode) )])  * 8 ))) ))  ;
      break;

    case REAL_TYPE:
      {
	register int prec = ((type)->type.sep_unit) ;
	if (prec <=  (8  * mode_size[(int)(SFmode)]) )
	  ((type)->type.mode)  = SFmode;
	else if (prec <=  (8  * mode_size[(int)(DFmode)]) )
	  ((type)->type.mode)  = DFmode;
	else if (prec <=  (8  * mode_size[(int)(TFmode)]) )
	  ((type)->type.mode)  = TFmode;
	else
	  abort ();
      }
      ((type)->type.size)  = build_int (	(mode_size[(int)(((type)->type.mode) )]) );
      ((type)->type.size_unit)  = 8 ;
      ((type)->type.align)  = ((32 ) < ( ((1) > ( ((mode_unit_size[(int)(((type)->type.mode) )])  * 8 )) ? (1) : ( ((mode_unit_size[(int)(((type)->type.mode) )])  * 8 ))) ) ? (32 ) : ( ((1) > ( ((mode_unit_size[(int)(((type)->type.mode) )])  * 8 )) ? (1) : ( ((mode_unit_size[(int)(((type)->type.mode) )])  * 8 ))) ))  ;
      break;

    case POINTER_TYPE:
    case REFERENCE_TYPE:
      ((type)->type.mode)  = SImode ;
      ((type)->type.size)  = build_int (32  / 8 );
      ((type)->type.size_unit)  = 8 ;
      ((type)->type.align)  = 32 ;
      ((type)->common.unsigned_attr)  = 1;
      ((type)->type.sep_unit)  = 32 ;
      break;

    case ARRAY_TYPE:
      {
	register tree index = ((type)->type.values) ;
	register tree length;
	register tree element = ((type)->common.type) ;

	build_pointer_type (element);

	if (index == 0)
	  length = 0;
	else
	  length = genop (PLUS_EXPR, size_one_node,
			  genop (MINUS_EXPR, ((index)->type.max) ,
				 ((index)->type.sep) ));

	if (((type)->common.packed_attr) )
	  abort ();

	((type)->type.size_unit)  = ((element)->type.size_unit) ;
	if (length && ((element)->type.size) )
	  ((type)->type.size)  = genop (MULT_EXPR, ((element)->type.size) , length);
	((type)->type.sep)  = ((element)->type.size) ;
	((type)->type.sep_unit)  = ((element)->type.size_unit) ;
	((type)->type.align)  = ((((element)->type.align) ) > ( 8 ) ? (((element)->type.align) ) : ( 8 )) ;
	((type)->type.mode)  = BLKmode;
	if (((type)->type.size)  != 0
	    && ((enum tree_code) (((type)->type.size) )->common.code)  == INTEGER_CST

	    && ((((type)->common.type) )->type.mode)  != BLKmode

	    && (((type)->type.align)  >= 32
		|| ((type)->type.align)  >= (((((type)->type.size) )->int_cst.int_cst_low)
					 * ((type)->type.size_unit) ))

	    )
	  {
	    ((type)->type.mode)
	      = agg_mode (((((type)->type.size) )->int_cst.int_cst_low)
			  * ((type)->type.size_unit) );
	  }
	break;
      }

    case RECORD_TYPE:
      layout_record (type);
      ((type)->type.mode)  = BLKmode;
      if (((enum tree_code) (((type)->type.size) )->common.code)  == INTEGER_CST

	  && (((type)->type.align)  >= 32
	      || ((type)->type.align)  >= (((((type)->type.size) )->int_cst.int_cst_low)
				       * ((type)->type.size_unit) ))

	  )
	{
	  tree field;

	  for (field = ((type)->type.values) ; field; field = ((field)->common.chain) )
	    {
	      if (((((field)->common.type) )->type.mode)  == BLKmode)
		goto record_lose;

	      if (((field)->decl.offset)  / 32
		  != ((((((field)->decl.size) )->int_cst.int_cst_low)  * ((field)->decl.size_unit)
		       + ((field)->decl.offset)  - 1)
		      / 32 ))
		goto record_lose;
	    }

	  ((type)->type.mode)
	    = agg_mode (((((type)->type.size) )->int_cst.int_cst_low)
			* ((type)->type.size_unit) );
	record_lose: ;
	}
      break;

    case UNION_TYPE:
      layout_union (type);
      ((type)->type.mode)  = BLKmode;
      if (((enum tree_code) (((type)->type.size) )->common.code)  == INTEGER_CST

	  && (((type)->type.align)  >= 32
	      || ((type)->type.align)  >= (((((type)->type.size) )->int_cst.int_cst_low)
				       * ((type)->type.size_unit) ))

	  )
	{
	  tree field;

	  for (field = ((type)->type.values) ; field; field = ((field)->common.chain) )
	    if (((((field)->common.type) )->type.mode)  == BLKmode)
	      goto union_lose;

	  ((type)->type.mode)
	    = agg_mode (((((type)->type.size) )->int_cst.int_cst_low)
			* ((type)->type.size_unit) );
	union_lose: ;
	}
      break;

    case FUNCTION_TYPE:
    case METHOD_TYPE:
      ((type)->type.mode)  = EPmode;
      ((type)->type.size)  = build_int (2 * 32  / 8 );
      ((type)->type.size_unit)  = 8 ;
      ((type)->type.align)  = 32 ;
      break;

    default:
      abort ();
    }

  if (((type)->type.size)  != 0 && ! ((((type)->type.size) )->common.literal_attr) )
    ((type)->type.size)  = variable_size (((type)->type.size) );

  if (((type)->type.next_variant)
      || type != ((type)->type.main_variant) )
    {
      tree variant;

      tree size = ((type)->type.size) ;
      int size_unit = ((type)->type.size_unit) ;
      int align = ((type)->type.align) ;
      enum machine_mode mode = ((type)->type.mode) ;

      for (variant = ((type)->type.main_variant) ;
	   variant;
	   variant = ((variant)->type.next_variant) )
	{
	  ((variant)->type.size)  = size;
	  ((variant)->type.size_unit)  = size_unit;
	  ((variant)->type.align)  = align;
	  ((variant)->type.mode)  = mode;
	}
    }

  if (temporary)
    resume_temporary_allocation ();
  resume_momentary (old);
}

tree
make_signed_type (precision)
     int precision;
{
  register tree type = make_node (INTEGER_TYPE);

  ((type)->type.sep_unit)  = precision;

  ((type)->type.sep)
    = build_int_2 ((precision-32  > 0 ? 0 : (-1)<<(precision-1)),
		   (-1)<<(precision-32 -1 > 0
			  ? precision-32 -1
			  : 0));
  ((type)->type.max)
    = build_int_2 ((precision-32  > 0 ? -1 : (1<<(precision-1))-1),
		   (precision-32 -1 > 0
		    ? (1<<(precision-32 -1))-1
		    : 0));

  ((((type)->type.sep) )->common.type)  = type;
  ((((type)->type.max) )->common.type)  = type;

  if (sizetype == 0)
    sizetype = type;

  layout_type (type);

  return type;
}

tree
make_unsigned_type (precision)
     int precision;
{
  register tree type = make_node (INTEGER_TYPE);

  ((type)->type.sep_unit)  = precision;

  if (sizetype == 0)
    sizetype = type;

  fixup_unsigned_type (type);
  return type;
}

void
fixup_unsigned_type (type)
     tree type;
{
  register int precision = ((type)->type.sep_unit) ;

  ((type)->type.sep)  = build_int_2 (0, 0);
  ((type)->type.max)
    = build_int_2 (precision-32  >= 0 ? -1 : (1<<precision)-1,
		   precision-32  > 0
		   ? ((unsigned) ~0
		      >> (32  - (precision - 32 )))
		   : 0);
  ((((type)->type.sep) )->common.type)  = type;
  ((((type)->type.max) )->common.type)  = type;

  layout_type (type);
}
