static char rcsid[] = "$Id: F-machine-dep.c,v 1.16 2000/12/28 15:15:30 m-hirano Exp $";
/* 
 * $RWC_Release: Omni-1.6 $
 * $RWC_Copyright:
 *  Omni Compiler Software Version 1.5-1.6
 *  Copyright (C) 2002 PC Cluster Consortium
 *  
 *  This software is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version
 *  2.1 published by the Free Software Foundation.
 *  
 *  Omni Compiler Software Version 1.0-1.4
 *  Copyright (C) 1999, 2000, 2001.
 *   Tsukuba Research Center, Real World Computing Partnership, Japan.
 *  
 *  Please check the Copyright and License information in the files named
 *  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
 *  Software release kit.
 *  
 *  
 *  $
 */
#include "F-front.h"

int type_LOGICAL_SIZE = SIZEOF_UNSIGNED_INT;
char *type_LOGICAL_NAME = "int";
int type_POINTER_SIZE = SIZEOF_VOID_P;
int type_POINTER_ALIGN = SIZEOF_VOID_P;

#ifndef SIZEOF_UNSIGNED_LONG_LONG
#define SIZEOF_UNSIGNED_LONG_LONG (SIZEOF_UNSIGNED_INT * 2)
#endif /* !SIZEOF_UNSIGNED_LONG_LONG */

#ifndef LONGLONG_ALIGN
#define LONGLONG_ALIGN (LONG_ALIGN * 2)
#endif /* !LONGLONG_ALIGN */

int
basic_type_size(t)
     BASIC_DATA_TYPE t;
{
    switch (t) {
	case TYPE_SHORT:	return SIZEOF_UNSIGNED_SHORT;
	case TYPE_INT:		return SIZEOF_UNSIGNED_INT;
	case TYPE_REAL:		return SIZEOF_FLOAT;
	case TYPE_DREAL:	return SIZEOF_DOUBLE;
	case TYPE_COMPLEX:	return SIZEOF_FLOAT * 2;
	case TYPE_DCOMPLEX:	return SIZEOF_DOUBLE * 2;
	case TYPE_LOGICAL:	return SIZEOF_UNSIGNED_INT;
	case TYPE_CHAR:		return sizeof(char);
	case TYPE_LONGLONG:	return SIZEOF_UNSIGNED_LONG_LONG;
	case TYPE_QREAL: {
#ifdef ENABLE_QREAL
	    return SIZEOF_UNSIGNED_INT * 2 +	/* sizeof(_mp_prec) + sizeof(_mp_size) */
	    	OMNI_SIZEOF_QEXP_T +
#ifdef OMNI_QREAL_NEED_GAP_MEMBER
		OMNI_QREAL_GAP_SIZE +
#endif /* OMNI_QREAL_NEED_GAP_MEMBER */
		sizeof(mp_limb_t *) +
		OMNI_SIZEOF_QLIM_T * gmpLimbSize;
#else
	    error("quad/multiple precision real is not supported.");
	    break;
#endif /* ENABLE_QREAL */
	}
	default: {
	    error("can't get size of %s type", basic_type_name((int)t));
	    break;
	}
    }
    return -1;
}

int
basic_type_align(t)
     BASIC_DATA_TYPE t;
{
    switch (t) {
	case TYPE_SHORT:	return SHORT_ALIGN;
	case TYPE_INT:		return INT_ALIGN;
	case TYPE_REAL:		return FLOAT_ALIGN;
	case TYPE_COMPLEX:	return FLOAT_ALIGN;
	case TYPE_LOGICAL:	return INT_ALIGN;
	case TYPE_CHAR:		return CHAR_ALIGN;

	case TYPE_LONGLONG: {
#ifdef OMNI_CPU_I386
	    if (doubleAlign == TRUE) {
# ifdef I386_LONGLONG_ALIGN2
		return I386_LONGLONG_ALIGN2;
# else
		return LONGLONG_ALIGN;
# endif /* I386_LONGLONG_ALIGN2 */
	    } else {
		return LONGLONG_ALIGN;
	    }
#else
	    return LONGLONG_ALIGN;
#endif /* OMNI_CPU_I386 */
	}

	case TYPE_DCOMPLEX:
	case TYPE_DREAL: {
#ifdef OMNI_CPU_I386
	    if (doubleAlign == TRUE) {
# ifdef I386_DOUBLE_ALIGN2
		return I386_DOUBLE_ALIGN2;
# else
		return LONG_ALIGN*2;
# endif /* I386_DOUBLE_ALIGN2 */
	    } else {
		return DOUBLE_ALIGN;
	    }
	    break;
#else
	    return DOUBLE_ALIGN;
#endif /* OMNI_CPU_I386 */
	}

	case TYPE_QREAL: {
#ifdef ENABLE_QREAL
# ifdef OMNI_CPU_I386
	    if (doubleAlign == TRUE) {
#  if (OMNI_SIZEOF_QLIM_T == SIZEOF_UNSIGNED_LONG_LONG)
		return basic_type_align(TYPE_LONGLONG);
#  elif (OMNI_SIZEOF_QLIM_T == SIZEOF_UNSIGNED_LONG)
		return basic_type_align(TYPE_INT);
#  else
		return basic_type_align(TYPE_SHORT);
#  endif /* (OMNI_SIZEOF_QLIM_T == SIZEOF_UNSIGNED_LONG_LONG) ... */
	    } else {
		return OMNI_SIZEOF_QLIM_T;
	    }
# else
	    return OMNI_SIZEOF_QLIM_T;
# endif /* OMNI_CPU_I386 */
#else
	    error("quad/multiple precision real is not supported.");
	    break;
#endif /* ENABLE_QREAL */
	}

	default: {
	    error("can't get alignment of %s type", basic_type_name((int)t));
	    break;
	}
    }

    return -1;
}

