static char rcsid[] = "$Id: F-intrinsic.c,v 1.41 2001/02/02 17:18:04 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"

static expv expv_intrinsic_minmax(enum expr_code opcode,expv v1,expv v2);

enum intrinsic_op {
    INTR_NONE = 0,
    INTR_CONV_INT,
    INTR_CONV_REAL,
    INTR_CONV_DREAL,
    INTR_CONV_COMPLEX,
    INTR_CONV_DCOMPLEX,
    INTR_CONV_ICHAR,
    INTR_CONV_CHAR,
    INTR_MIN,
    INTR_MAX,
    INTR_AINT,
    INTR_ANINT,
    INTR_NINT,
    INTR_ABS,
    INTR_MOD,
    INTR_SIGN,
    INTR_DIM,
    INTR_DPROD,
    INTR_LEN,
    INTR_INDEX,
    INTR_IMAG,
    INTR_CONJG,
    INTR_SQRT,
    INTR_EXP,
    INTR_LOG,
    INTR_LOG10,
    INTR_SIN,
    INTR_COS,
    INTR_TAN,
    INTR_ASIN,
    INTR_ACOS,
    INTR_ATAN,
    INTR_ATAN2,
    INTR_SINH,
    INTR_COSH,
    INTR_TANH,
    INTR_LGE,
    INTR_LGT,
    INTR_LLE,
    INTR_LLT,
    INTR_AND,
    INTR_OR,
    INTR_EOR,
    INTR_NOT,
    INTR_LSHIFT,
    INTR_RSHIFT,
    INTR_CONV_ADDR,
    INTR_TYPE_PREC,
#ifdef ENABLE_QREAL
    INTR_TYPE_EPS,
#endif /* ENABLE_QREAL */
    INTR_END
};

struct intrinsic_entry {
    char *name;
    char is_generic;
    enum intrinsic_op op;
    BASIC_DATA_TYPE runtime_type;
    BASIC_DATA_TYPE result_type;
    BASIC_DATA_TYPE arg_type;
    int nargs;
    char *fname;
    char *cname;	/* 'call by value' C function */
};

#define INTR_NAME(ep)	((ep)->name)
#define INTR_IS_GEN(ep)	((ep)->is_generic)
#define INTR_OP(ep)	((ep)->op)
#define INTR_RUNTIME_TYPE(ep)	((ep)->runtime_type)
#define INTR_RESULT_TYPE(ep)	((ep)->result_type)
#define INTR_ARG_TYPE(ep)	((ep)->arg_type)
#define INTR_N_ARG(ep)	((ep)->nargs)
#define INTR_F_NAME(ep)	((ep)->fname)
#define INTR_C_NAME(ep)	((ep)->cname)

extern struct intrinsic_entry intrinsic_table[];

void initialize_intrinsic()
{
    int i;
    SYMBOL sp;
    struct intrinsic_entry *ep;

    for(i = 0; intrinsic_table[i].op != INTR_END; i++){
	ep = &intrinsic_table[i];
	if(INTR_NAME(ep) == NULL) continue;
	sp = f_find_symbol(INTR_NAME(ep));
	SYM_TYPE(sp) = S_INTR;
	SYM_VAL(sp) = i;
    }
}

int
is_intrinsic_function(ID id)
{
    if(SYM_TYPE(ID_SYM(id)) == S_INTR) return TRUE;
    return FALSE;
}


#ifdef ENABLE_QREAL
static char *epsStr = NULL;
static int epsStrLen = 0;

static void	qRealEpsilon _ANSI_ARGS_((void));

static void
qRealEpsilon()
{
    if (epsStr == NULL) {
	mpf_t eps;
	mpf_init_set_d(eps, 1.0);
	mpf_div_2exp(eps, eps, (unsigned long int)(qRealPrec + OMNI_SIZEOF_QLIM_T * CHAR_BIT));
	epsStr = mpf2str(eps);
	epsStrLen = strlen(epsStr);
	mpf_clear(eps);
    }
}
#endif /* ENABLE_QREAL */

#define needConv(bt0, bt1) ((BASIC_IS_INT((bt0))) && (BASIC_IS_INT((bt1))) && ((bt0) != (bt1)))

expv 
compile_intrinsic_call(ID id,expr args)
{
    struct intrinsic_entry *ep;
    struct intrinsic_entry *eq = NULL;
    int nargs,i;
    expv v = NULL;
    expv a,arglist;
    expv left,right;
    list lp;
    enum expr_code opcode;
    TYPE_DESC tp = NULL;
    enum datatype dt;

    if(SYM_TYPE(ID_SYM(id)) != S_INTR) 
	fatal("compile_call_intrinsic: not intrinsic symbol");
    if(args == NULL) return NULL; /* error recovery */
    ep = &intrinsic_table[SYM_VAL(ID_SYM(id))];

    /* check argument */
    nargs = 0;
    dt = TYPE_UNKNOWN;
    FOR_ITEMS_IN_LIST(lp,args){
	nargs++;
	a = LIST_ITEM(lp);
	if(a == NULL) return NULL;  /* error recovery */
	tp = EXPV_TYPE(a);
	if(!IS_ELEMENT_TYPE(tp)){
	    error("intrinsic function argument must be scalar");
	    return NULL;
	}

	switch(TYPE_BASIC_TYPE(tp)){
	case TYPE_SHORT:
	case TYPE_INT:
	    if (dt == TYPE_UNKNOWN) {
		dt = TYPE_INT;
	    } else if (dt != TYPE_INT && dt != TYPE_LONGLONG) {
		error("intrinsic function arguments must have the same data type");
		return NULL;
	    }
	    break;
	case TYPE_LONGLONG:
	    /* If args have LONGLONG(s) and INT(s), use LONGLONG. */
	    if (dt == TYPE_UNKNOWN || dt == TYPE_INT) {
		dt = TYPE_LONGLONG;
	    } else if (dt != TYPE_INT && dt != TYPE_LONGLONG) {
		error("intrinsic function arguments must have the same data type");
		return NULL;
	    }
	    break;
	case TYPE_REAL:
	case TYPE_DREAL:
#ifdef ENABLE_QREAL
	case TYPE_QREAL:
#endif /* ENABLE_QREAL */
	case TYPE_COMPLEX:
	case TYPE_DCOMPLEX:
	case TYPE_LOGICAL:
	case TYPE_CHAR:
	    if (dt == TYPE_UNKNOWN) {
		dt = TYPE_BASIC_TYPE(tp);
	    } else if (dt != TYPE_BASIC_TYPE(tp)) {
		error("intrinsic function arguments must have the same data type");
		return NULL;
	    }
	    break;
	default:
	    fatal("unused type in intrinsics.");
	}
    }
    
    /* check number of argument */
    if (INTR_N_ARG(ep) > 0) {
	if(INTR_N_ARG(ep) != nargs){
	    error("bad number of intrinsic function arguments");
	    return NULL;
	}
    }

    /* check data type */
    if (INTR_ARG_TYPE(ep) != dt){
	if (INTR_IS_GEN(ep)) {
	    for (i = 0; intrinsic_table[i].op != INTR_END; i++) {
		eq = &intrinsic_table[i];
		if (INTR_OP(eq) == INTR_OP(ep) &&
		    INTR_ARG_TYPE(eq) == dt) break;
	    }
	    if (intrinsic_table[i].op == INTR_END) {
		error("specific name is not found for generic intrinsic function '%s'",
		      ID_NAME(id));
		return NULL;
	    }
	    ep = eq;
	} else {
	    error("bad data type argument in of specific intrinsic function '%s'",
		  ID_NAME(id));
	    return NULL;
	}
    }

#if 0
    if(ID_TYPE(id) != NULL && 
       (!IS_ELEMENT_TYPE(ID_TYPE(id)) ||
	TYPE_BASIC_TYPE(ID_TYPE(id)) != INTR_RESULT_TYPE(ep))){
	error("explicit type declaration mismatch intrinsic '%s'",
	      ID_NAME(id));
	return NULL;
    }
#else
    if(ID_TYPE(id) != NULL && 
       (!IS_ELEMENT_TYPE(ID_TYPE(id)))) {
	error("explicit type declaration mismatch intrinsic '%s'",
	      ID_NAME(id));
	return NULL;
    }
#endif

    switch(INTR_OP(ep)){
    case INTR_CONV_INT:	/* convertion to int */
    case INTR_CONV_REAL:
    case INTR_CONV_DREAL:
	a = EXPR_ARG1(args);
	switch(dt){
	case TYPE_COMPLEX:
	    v = expv_cons(CAST_EXPR,BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
			  expv_complex_real(type_REAL,a), NULL);
	    break;
	case TYPE_DCOMPLEX:
	    v = expv_cons(CAST_EXPR,BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
			  expv_complex_real(type_DREAL,a),NULL);
	    break;
#ifdef ENABLE_QREAL
	case TYPE_QREAL: {
	    switch (INTR_OP(ep)) {
		case INTR_CONV_INT:	{ tp = type_INT; break; }
		case INTR_CONV_REAL:	{ tp = type_REAL; break; }
		case INTR_CONV_DREAL:	{ tp = type_DREAL; break; }
		default: {
		    fatal("intrinsic qreal type conv. should not be here!");
		    return NULL;
		}
	    }
	    v = expv_type_conversion(tp, a);
	    break;
	}
#endif /* ENABLE_QREAL */
	default:
	    v = expv_cons(CAST_EXPR,BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
			  a,NULL);
	}
	break;

    case INTR_CONV_COMPLEX:
    case INTR_CONV_DCOMPLEX:
	if(nargs == 1){
	    a = EXPR_ARG1(args);
	    if(INTR_OP(ep) == INTR_CONV_COMPLEX)
		v = expv_complex_op(CAST_EXPR,type_COMPLEX,a,NULL);
	    else
		v = expv_complex_op(CAST_EXPR,type_DCOMPLEX,a,NULL);
	} else if(nargs == 2){
	    left = EXPR_ARG1(args);
	    right = EXPR_ARG2(args);
	    switch(dt){
	    case TYPE_COMPLEX:
		left = expv_complex_real(type_REAL,left);
		right = expv_complex_real(type_REAL,right);
		break;
	    case TYPE_DCOMPLEX:
		left = expv_complex_real(type_DREAL,left);
		right = expv_complex_real(type_DREAL,right);
		break;
	    case TYPE_REAL:
	    case TYPE_DREAL:
#ifdef ENABLE_QREAL
	    case TYPE_QREAL:
#endif /* ENABLE_QREAL */
	    case TYPE_INT:
#ifdef HAS_INT64
	    case TYPE_LONGLONG:
#endif /* HAS_INT64 */
		break;
	    default:
		fatal("can't convert to complex.");
		break;
	    }
	    if (INTR_OP(ep) == INTR_CONV_COMPLEX) {
		v = expv_c_cons(left, right, TRUE);
	    } else {
		v = expv_z_cons(left, right, TRUE);
	    }
	} else error("more than 2 arguments for cmplx/dcmplx");
	break;

    case INTR_IMAG:
	v = expv_complex_img(BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
			     EXPR_ARG1(args));
	break;


    case INTR_CONV_CHAR: {
	TYPE_DESC retType = type_char(1);
	expv t = allocate_temp(retType);
	expv tA = expv_get_address(t);
	expv newArgs = list0(LIST);
	newArgs = list_put_last(newArgs, tA);
	FOR_ITEMS_IN_LIST(lp, args) {
	    newArgs = list_put_last(newArgs, LIST_ITEM(lp));
	}
	output_expr_statement(expv_call_runtime(INTR_F_NAME(ep), retType, newArgs));
	v = t;
	break;
    }

    case INTR_CONV_ADDR: {
	v = expv_cons(CAST_EXPR, BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
		      expv_get_address(EXPR_ARG1(args)),
		      NULL);
	break;
    }

    case INTR_TYPE_PREC: {
	BASIC_DATA_TYPE bTyp = getBasicType(EXPV_TYPE(EXPR_ARG1(args)));
	int pSz = 0;
	if (bTyp == TYPE_LOGICAL) {
	    pSz = 1;
#ifdef ENABLE_QREAL
	} else if (bTyp == TYPE_QREAL) { 
	    pSz = qRealPrec;
#endif /* ENABLE_QREAL */
	} else {
	    pSz = basic_type_size(bTyp) * CHAR_BIT;
	}
	v = expv_int_term(INT_CONSTANT, BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
			  pSz);
	break;
    }

#ifdef ENABLE_QREAL
    case INTR_TYPE_EPS: {
	if (epsStr == NULL) {
	    qRealEpsilon();
	}
	v = expv_qreal_term(QREAL_CONSTANT, type_QREAL,
			    expv_str_term(STRING_CONSTANT,
					  type_char(epsStrLen),
					  epsStr));
	break;
    }
#endif /* ENABLE_QREAL */

    case INTR_MAX:
	opcode = LOG_GT_EXPR;
	goto minmax;
    case INTR_MIN:
	opcode = LOG_LT_EXPR;
    minmax: {
	expv v2;
	if(nargs < 2){
	    error("few arguments for max/min intrinsic function");
	    return NULL;
	}
	lp = EXPR_LIST(args);
	v = LIST_ITEM(lp);
	if (needConv(dt, TYPE_BASIC_TYPE(EXPV_TYPE(v)))) {
	    v = expv_type_conversion(BASIC_TYPE_DESC(dt), v);
	}
	for(lp = LIST_NEXT(lp); lp != NULL; lp = LIST_NEXT(lp)){
	    if (needConv(dt, TYPE_BASIC_TYPE(EXPV_TYPE(v)))) {
		v = expv_type_conversion(BASIC_TYPE_DESC(dt), v);
	    }
	    v2 = LIST_ITEM(lp);
	    if (needConv(dt, TYPE_BASIC_TYPE(EXPV_TYPE(v2)))) {
		v2 = expv_type_conversion(BASIC_TYPE_DESC(dt), v2);
	    }
	    v = expv_intrinsic_minmax(opcode, v, v2);
	}
	break;
    }

    case INTR_AND:
	v = expv_cons(BIT_AND_EXPR,BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
		      EXPR_ARG1(args),EXPR_ARG2(args));
	break;
    case INTR_OR:
	v = expv_cons(BIT_OR_EXPR,BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
		      EXPR_ARG1(args),EXPR_ARG2(args));
	break;
    case INTR_EOR:
	v = expv_cons(BIT_XOR_EXPR,BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
		      EXPR_ARG1(args),EXPR_ARG2(args));
	break;
    case INTR_NOT:
	v = expv_cons(BIT_NOT_EXPR,BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
		      EXPR_ARG1(args),NULL);
	break;
    case INTR_LSHIFT:
	v = expv_cons(LSHIFT_EXPR,BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
		      EXPR_ARG1(args),EXPR_ARG2(args));
	break;
    case INTR_RSHIFT:
	v = expv_cons(RSHIFT_EXPR,BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep)),
		      EXPR_ARG1(args),EXPR_ARG2(args));
	break;

    default: {
	/* setup argument for fortran calling sequence */
	TYPE_DESC retType = BASIC_TYPE_DESC(INTR_RESULT_TYPE(ep));
	TYPE_DESC runType = BASIC_TYPE_DESC(INTR_RUNTIME_TYPE(ep));
	expv retV = NULL;
	arglist = list0(LIST);
#ifdef ENABLE_QREAL
	if (INTR_RESULT_TYPE(ep) == TYPE_COMPLEX ||
	    INTR_RESULT_TYPE(ep) == TYPE_DCOMPLEX ||
	    INTR_RESULT_TYPE(ep) == TYPE_QREAL) {
#else
	if (INTR_RESULT_TYPE(ep) == TYPE_COMPLEX ||
	    INTR_RESULT_TYPE(ep) == TYPE_DCOMPLEX) {
#endif /* ENABLE_QREAL */
	    retV = allocate_temp(retType);
	    arglist = list_put_last(arglist, expv_get_address(retV));
	}
	FOR_ITEMS_IN_LIST(lp, args) {
	    v = LIST_ITEM(lp);
	    if (needConv(dt, TYPE_BASIC_TYPE(EXPV_TYPE(v)))) {
		v = expv_get_address(expv_type_conversion(BASIC_TYPE_DESC(dt), v));
	    } else {
		v = expv_get_address(v);
	    }
	    arglist = list_put_last(arglist, v);
	}
	if (INTR_ARG_TYPE(ep) == TYPE_CHAR) {
	    FOR_ITEMS_IN_LIST(lp, args) {
		v = LIST_ITEM(lp);
		v = expv_reduce(expv_char_len(v));
		arglist = list_put_last(arglist, v);
	    }
	}		
	if(INTR_F_NAME(ep) == NULL)
	    fatal("runtime for specific intrinsic function '%s' is not defined",ID_NAME(id));

	if (retV == NULL) {
	    v = expv_call_runtime(INTR_F_NAME(ep), runType, arglist);
	    if (retType != runType) {
		v = expv_cons(CAST_EXPR, retType, v, NULL);
	    }
	} else {
	    output_expr_statement(expv_call_runtime(INTR_F_NAME(ep), NULL, arglist));
	    v = retV;
	}
	break;
    }
    }
    return v;
}

static expv
expv_intrinsic_minmax(enum expr_code opcode,expv v1,expv v2)
{
    expv t;

    if(!IS_CONSTANT(v1) && 
       !(EXPR_CODE(v1) == POINTER_REF && 
	 EXPR_CODE_IS_TERMINAL(EXPR_CODE(EXPV_LEFT(v1))))){
	t = allocate_temp(EXPV_TYPE(v1));
	output_expr_statement(expv_assignment(t,v1));
	v1 = t;
    }
    if(!IS_CONSTANT(v2) && 
       !(EXPR_CODE(v2) == POINTER_REF && 
	 EXPR_CODE_IS_TERMINAL(EXPR_CODE(EXPV_LEFT(v2))))){
	t = allocate_temp(EXPV_TYPE(v2));
	output_expr_statement(expv_assignment(t,v2));
	v2 = t;
    }
#ifdef ENABLE_QREAL
    if (TYPE_BASIC_TYPE(max_type(EXPV_TYPE(v1), EXPV_TYPE(v2))) == TYPE_QREAL) {
	expv cmp = NULL;
	expv cArgs = NULL;
	if (TYPE_BASIC_TYPE(EXPV_TYPE(v1)) != TYPE_QREAL) {
	    v1 = expv_type_conversion(type_QREAL, v1);
	}
	if (TYPE_BASIC_TYPE(EXPV_TYPE(v2)) != TYPE_QREAL) {
	    v2 = expv_type_conversion(type_QREAL, v2);
	}
	cArgs = list2(LIST, expv_get_address(v1), expv_get_address(v2));
	cmp = expv_cons(opcode, type_LOGICAL,
			expv_call_runtime("_QRcmp", type_LOGICAL, cArgs),
			expv_int_term(INT_CONSTANT, type_INT, 0));
	return expv_cons(CONDITIONAL_EXPR,
			 EXPV_TYPE(v1),
			 cmp,
			 expv_cons(LIST, EXPV_TYPE(v1), v1, v2));
    } else {
	return expv_cons(CONDITIONAL_EXPR,
			 EXPV_TYPE(v1),
			 expv_cons(opcode, EXPV_TYPE(v1), v1, v2),
			 expv_cons(LIST, EXPV_TYPE(v1), v1, v2));
    }
#else
    return expv_cons(CONDITIONAL_EXPR,
		     EXPV_TYPE(v1),
		     expv_cons(opcode, EXPV_TYPE(v1), v1, v2),
		     expv_cons(LIST, EXPV_TYPE(v1), v1, v2));
#endif /* ENABLE_QREAL */
}

struct intrinsic_entry intrinsic_table[] = {
    {"int", 	1, INTR_CONV_INT, TYPE_INT,TYPE_INT,	TYPE_INT,	1 },
    {"ifix", 	0, INTR_CONV_INT, TYPE_INT,TYPE_INT,	TYPE_REAL,	1 },
    {"idint", 	0, INTR_CONV_INT, TYPE_INT,TYPE_INT,	TYPE_DREAL,	1 },
#ifdef ENABLE_QREAL
    {NULL, 	0, INTR_CONV_INT, TYPE_INT,TYPE_INT,	TYPE_QREAL,	1},
#endif /* ENABLE_QREAL */
    {NULL, 	0, INTR_CONV_INT, TYPE_INT,TYPE_INT,	TYPE_COMPLEX,	1},
    {NULL, 	0, INTR_CONV_INT, TYPE_INT,TYPE_INT,	TYPE_DCOMPLEX,	1},
#ifdef HAS_INT64
    {NULL, 	0, INTR_CONV_INT, TYPE_INT,TYPE_INT,	TYPE_LONGLONG,	1},
#endif /* HAS_INT64 */

    {"real", 	1,INTR_CONV_REAL, TYPE_REAL,TYPE_REAL,	TYPE_REAL,	1 },
    {"float", 	1,INTR_CONV_REAL, TYPE_REAL,TYPE_REAL,	TYPE_REAL,	1 },
    {"sngl", 	1,INTR_CONV_REAL, TYPE_REAL,TYPE_REAL,	TYPE_DREAL,	1 },
#ifdef ENABLE_QREAL
    {NULL, 	0,INTR_CONV_REAL, TYPE_REAL,TYPE_REAL,	TYPE_QREAL,	1 },
#endif /* ENABLE_QREAL */
    {NULL, 	0,INTR_CONV_REAL, TYPE_REAL,TYPE_REAL,	TYPE_INT,	1 },
#ifdef HAS_INT64
    {NULL, 	0,INTR_CONV_REAL, TYPE_REAL,TYPE_REAL,	TYPE_LONGLONG,	1 },
#endif /* HAS_INT64 */
    {NULL, 	0,INTR_CONV_REAL, TYPE_REAL,TYPE_REAL,	TYPE_COMPLEX,	1 },
    {NULL, 	0,INTR_CONV_REAL, TYPE_REAL,TYPE_REAL,	TYPE_DCOMPLEX,	1 },

    {"dble", 	1,INTR_CONV_DREAL, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1 },
    {"dfloat",	1,INTR_CONV_DREAL, TYPE_DREAL,TYPE_DREAL,	TYPE_REAL,	1 },
#ifdef ENABLE_QREAL
    {NULL, 	0,INTR_CONV_DREAL, TYPE_DREAL,TYPE_DREAL,	TYPE_QREAL,	1 },
#endif /* ENABLE_QREAL */
    {NULL, 	0,INTR_CONV_DREAL, TYPE_DREAL,TYPE_DREAL,	TYPE_INT,	1 },
#ifdef HAS_INT64
    {NULL, 	0,INTR_CONV_DREAL, TYPE_DREAL,TYPE_DREAL,	TYPE_LONGLONG,	1 },
#endif /* HAS_INT64 */
    {NULL, 	0,INTR_CONV_DREAL, TYPE_DREAL,TYPE_DREAL,	TYPE_COMPLEX,	1 },
    {NULL, 	0,INTR_CONV_DREAL, TYPE_DREAL,TYPE_DREAL,	TYPE_DCOMPLEX,	1 },

    {"cmplx", 	1,INTR_CONV_COMPLEX, TYPE_COMPLEX,TYPE_COMPLEX,	TYPE_COMPLEX,	-1 },
    {NULL, 	0,INTR_CONV_COMPLEX, TYPE_COMPLEX,TYPE_COMPLEX,	TYPE_INT,	-1 },
#ifdef HAS_INT64
    {NULL, 	0,INTR_CONV_COMPLEX, TYPE_COMPLEX,TYPE_COMPLEX,	TYPE_LONGLONG,	-1 },
#endif /* HAS_INT64 */
    {NULL, 	0,INTR_CONV_COMPLEX, TYPE_COMPLEX,TYPE_COMPLEX,	TYPE_REAL,	-1 },
    {NULL, 	0,INTR_CONV_COMPLEX, TYPE_COMPLEX,TYPE_COMPLEX,	TYPE_DREAL,	-1 },
#ifdef ENABLE_QREAL
    {NULL, 	0,INTR_CONV_COMPLEX, TYPE_COMPLEX,TYPE_COMPLEX,	TYPE_QREAL,	-1 },
#endif /* ENABLE_QREAL */
    {NULL, 	0,INTR_CONV_COMPLEX, TYPE_COMPLEX,TYPE_COMPLEX,	TYPE_DCOMPLEX,	-1 },

    {"dcmplx", 	1,INTR_CONV_DCOMPLEX, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_DCOMPLEX,	-1 },
    {NULL, 	0,INTR_CONV_DCOMPLEX, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_INT,	-1 },
#ifdef HAS_INT64
    {NULL, 	0,INTR_CONV_DCOMPLEX, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_LONGLONG,	-1 },
#endif /* HAS_INT64 */
    {NULL, 	0,INTR_CONV_DCOMPLEX, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_REAL,	-1 },
    {NULL, 	0,INTR_CONV_DCOMPLEX, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_DREAL,	-1 },
#ifdef ENABLE_QREAL
    {NULL, 	0,INTR_CONV_DCOMPLEX, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_QREAL,	-1 },
#endif /* ENABLE_QREAL */
    {NULL, 	0,INTR_CONV_DCOMPLEX, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_COMPLEX,	-1 },

    {"ichar", 	0,INTR_CONV_ICHAR, TYPE_INT,TYPE_INT,	TYPE_CHAR,	1, "c2i"},
    {"char", 	0,INTR_CONV_CHAR, TYPE_CHAR,TYPE_CHAR,	TYPE_INT,	1, "i2c"},
    /* {"iachar", 	0,INTR_CONV, TYLONG }, */
    /* {"achar", 	0,INTR_CONV, TYCHAR }, */
    
    {"max", 	1,INTR_MAX, TYPE_UNKNOWN,TYPE_UNKNOWN,	TYPE_UNKNOWN,	-1 },
#ifdef HAS_INT64
    {"max0", 	1,INTR_MAX, TYPE_INT,TYPE_INT,	TYPE_INT, -1 },
    {NULL,	0,INTR_MAX, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG, -1 },
    {"amax0", 	1,INTR_MAX, TYPE_REAL,TYPE_REAL,	TYPE_INT, -1 },
    {NULL, 	0,INTR_MAX, TYPE_REAL,TYPE_REAL,	TYPE_LONGLONG, -1 },
    {"max1", 	1,INTR_MAX, TYPE_INT,TYPE_INT,	TYPE_REAL, -1 },
    {NULL, 	0,INTR_MAX, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_REAL, -1 },
#else
    {"max0", 	0,INTR_MAX, TYPE_INT,TYPE_INT,	TYPE_INT, -1 },
    {"amax0", 	0,INTR_MAX, TYPE_REAL,TYPE_REAL,TYPE_INT, -1 },
    {"max1", 	0,INTR_MAX, TYPE_INT,TYPE_INT,	TYPE_REAL, -1 },
#endif /* HAS_INT64 */
    {"amax1", 	0,INTR_MAX, TYPE_REAL,TYPE_REAL,	TYPE_REAL, -1 },
#ifdef ENABLE_QREAL
    {"dmax1", 	1,INTR_MAX, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL, -1 },
    {NULL, 	0,INTR_MAX, TYPE_QREAL,TYPE_QREAL,	TYPE_QREAL, -1 },
#else
    {"dmax1", 	0,INTR_MAX, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL, -1 },
#endif /* ENABLE_QREAL */
    
    {"min", 	1,INTR_MIN, TYPE_UNKNOWN,TYPE_UNKNOWN,	TYPE_UNKNOWN, -1 },
#ifdef HAS_INT64
    {"min0", 	1,INTR_MIN, TYPE_INT,TYPE_INT,	TYPE_INT,-1 },
    {NULL,	0,INTR_MIN, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG, -1 },
    {"amin0", 	1,INTR_MIN, TYPE_REAL,TYPE_REAL,	TYPE_INT,-1 },
    {NULL, 	0,INTR_MIN, TYPE_REAL,TYPE_REAL,	TYPE_LONGLONG,-1 },
    {"min1", 	1,INTR_MIN, TYPE_INT,TYPE_INT,	TYPE_REAL,-1 },
    {NULL, 	0,INTR_MIN, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_REAL,-1 },
#else
    {"min0", 	0,INTR_MIN, TYPE_INT,TYPE_INT,	TYPE_INT,-1 },
    {"amin0", 	0,INTR_MIN, TYPE_REAL,TYPE_REAL,	TYPE_INT,-1 },
    {"min1", 	0,INTR_MIN, TYPE_INT,TYPE_INT,	TYPE_REAL,-1 },
#endif /* HAS_INT64 */
    {"amin1", 	0,INTR_MIN, TYPE_REAL,TYPE_REAL,	TYPE_REAL,-1 },
#ifdef ENABLE_QREAL
    {"dmin1", 	1,INTR_MIN, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,-1 },
    {NULL, 	0,INTR_MIN, TYPE_QREAL,TYPE_DREAL,	TYPE_QREAL,-1 },
#else
    {"dmin1", 	0,INTR_MIN, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,-1 },
#endif /* ENABLE_QREAL */
    
    {"aint", 	1,INTR_AINT, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_int"},
#ifdef ENABLE_QREAL
    {"dint", 	1,INTR_AINT, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_int"},
    {NULL, 	0,INTR_AINT, TYPE_QREAL,TYPE_QREAL,	TYPE_QREAL,	1,"_QRaint"},
#else
    {"dint", 	0,INTR_AINT, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_int"},
#endif /* ENABLE_QREAL */

    {"anint", 	1,INTR_ANINT, TYPE_DREAL,TYPE_REAL,	TYPE_REAL, 	1,"r_nint"},
#ifdef ENABLE_QREAL
    {"dnint", 	1,INTR_ANINT, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL, 	1,"d_nint"},
    {NULL, 	0,INTR_ANINT, TYPE_QREAL,TYPE_QREAL,	TYPE_QREAL, 	1,"_QRanint"},
#else
    {"dnint", 	0,INTR_ANINT, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL, 	1,"d_nint"},
#endif /* ENABLE_QREAL */

    {"nint", 	1,INTR_NINT, TYPE_INT,TYPE_INT,	TYPE_REAL, 	1,"i_nint"},
#ifdef ENABLE_QREAL
    {"idnint", 	1,INTR_NINT, TYPE_INT,TYPE_INT,	TYPE_DREAL,	1,"i_dnnt"},
    {NULL, 	0,INTR_NINT, TYPE_INT,TYPE_INT,	TYPE_QREAL,	1,"_QRnint"},
#else
    {"idnint", 	0,INTR_NINT, TYPE_INT,TYPE_INT,	TYPE_DREAL,	1,"i_dnnt"},
#endif /* ENABLE_QREAL */

    {"abs", 	1,INTR_ABS, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_abs"},
#ifdef HAS_INT64
    {"iabs", 	1,INTR_ABS, TYPE_INT,TYPE_INT,		TYPE_INT,	1,"i_abs"},
    {NULL, 	0,INTR_ABS, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG,	1,"li_abs"},
#else
    {"iabs", 	0,INTR_ABS, TYPE_INT,TYPE_INT,		TYPE_INT,	1,"i_abs"},
#endif /* HAS_INT64 */
#ifdef ENABLE_QREAL
    {"dabs", 	1,INTR_ABS, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_abs"},
    {NULL, 	0,INTR_ABS, TYPE_QREAL,TYPE_QREAL,	TYPE_QREAL,	1,"_QRabs"},
#else
    {"dabs", 	0,INTR_ABS, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_abs"},
#endif /* ENABLE_QREAL */
    {"cabs", 	0,INTR_ABS, TYPE_DREAL,TYPE_REAL,	TYPE_COMPLEX, 	1,"c_abs"},
    {"zabs", 	0,INTR_ABS, TYPE_DREAL,TYPE_DREAL,	TYPE_DCOMPLEX,	1,"z_abs"},
    {"cdabs", 	0,INTR_ABS, TYPE_DREAL,TYPE_DREAL,	TYPE_DCOMPLEX,	1,"z_abs"},
    
    {"mod", 	1,INTR_MOD, TYPE_INT,TYPE_INT,		TYPE_INT,	2,"i_mod"},
#ifdef HAS_INT64
    {NULL,	0,INTR_MOD, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG,	2,"li_mod"},
#endif /* HAS_INT64 */
    {"amod", 	0,INTR_MOD, TYPE_DREAL,TYPE_REAL,	TYPE_REAL, 	2,"r_mod"},
#ifdef ENABLE_QREAL
    {"dmod", 	1,INTR_MOD, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	2,"d_mod"},
    {NULL, 	0,INTR_MOD, TYPE_QREAL,TYPE_QREAL,	TYPE_QREAL,	2,"_QRmod"},
#else
    {"dmod", 	0,INTR_MOD, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	2,"d_mod"},
#endif /* ENABLE_QREAL */

    {"sign", 	1,INTR_SIGN, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	2,"r_sign"},
#ifdef HAS_INT64
    {"isign", 	1,INTR_SIGN, TYPE_INT,TYPE_INT,		TYPE_INT,	2,"i_sign"},
    {NULL, 	0,INTR_SIGN, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG,	2,"li_sign"},
#else
    {"isign", 	0,INTR_SIGN, TYPE_INT,TYPE_INT,		TYPE_INT,	2,"i_sign"},
#endif /* HAS_INT64 */
#ifdef ENABLE_QREAL
    {"dsign", 	1,INTR_SIGN, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	2,"d_sign"},
    {NULL, 	0,INTR_SIGN, TYPE_QREAL,TYPE_QREAL,	TYPE_QREAL,	2,"_QRsign"},
#else
    {"dsign", 	0,INTR_SIGN, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	2,"d_sign"},
#endif /* ENABLE_QREAL */

    {"dim", 	1,INTR_DIM, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	2,"r_dim"},
#ifdef HAS_INT64
    {"idim", 	1,INTR_DIM, TYPE_INT,TYPE_INT,		TYPE_INT,	2,"i_dim"},
    {NULL, 	0,INTR_DIM, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG,	2,"li_dim"},
#else
    {"idim", 	0,INTR_DIM, TYPE_INT,TYPE_INT,		TYPE_INT,	2,"i_dim"},
#endif /* HAS_INT64 */
#ifdef ENABLE_QREAL
    {"ddim", 	1,INTR_DIM, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	2,"d_dim"},
    {NULL, 	0,INTR_DIM, TYPE_QREAL,TYPE_QREAL,	TYPE_QREAL,	2,"_QRdim"},
#else
    {"ddim", 	0,INTR_DIM, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	2,"d_dim"},
#endif /* ENABLE_QREAL */

    {"dprod", 	0,INTR_DPROD, TYPE_DREAL,TYPE_DREAL,	TYPE_REAL, 	2,"d_prod"},
    
    {"len", 	0,INTR_LEN, TYPE_INT,TYPE_INT,	TYPE_CHAR,	1,"i_len"},

    {"index", 	0,INTR_INDEX,TYPE_INT,TYPE_INT,	TYPE_CHAR,	2,"i_indx"},
    
    {"imag", 	1,INTR_IMAG, TYPE_DREAL,TYPE_REAL,	TYPE_COMPLEX,	1,"r_imag"},
    {"aimag", 	0,INTR_IMAG, TYPE_DREAL,TYPE_REAL,	TYPE_COMPLEX,	1,"r_imag"},
    {"dimag", 	0,INTR_IMAG, TYPE_DREAL,TYPE_DREAL,	TYPE_DCOMPLEX,	1,"d_imag"},
    
    {"conjg", 	1,INTR_CONJG, TYPE_COMPLEX,TYPE_COMPLEX,	TYPE_COMPLEX,	1,"r_cnjg"},
    {"dconjg", 	0,INTR_CONJG, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_DCOMPLEX,	1,"d_cnjg"},
    
    {"sqrt", 	1,INTR_SQRT, TYPE_DREAL,TYPE_REAL,		TYPE_REAL, 	1,"r_sqrt"},
#ifdef ENABLE_QREAL
    {"dsqrt", 	1,INTR_SQRT, TYPE_DREAL,TYPE_DREAL,		TYPE_DREAL,	1,"d_sqrt"},
    {NULL, 	0,INTR_SQRT, TYPE_QREAL,TYPE_QREAL,		TYPE_QREAL,	1,"_QRsqrt"},
#else
    {"dsqrt", 	0,INTR_SQRT, TYPE_DREAL,TYPE_DREAL,		TYPE_DREAL,	1,"d_sqrt"},
#endif /* ENABLE_QREAL */
    {"csqrt", 	0,INTR_SQRT, TYPE_COMPLEX,TYPE_COMPLEX,		TYPE_COMPLEX,	1,"c_sqrt"},
    {"zsqrt", 	0,INTR_SQRT, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_DCOMPLEX,	1,"z_sqrt"},
    
    {"exp", 	1,INTR_EXP, TYPE_DREAL,TYPE_REAL,		TYPE_REAL,	1,"r_exp"},
    {"dexp", 	0,INTR_EXP, TYPE_DREAL,TYPE_DREAL,		TYPE_DREAL,	1,"d_exp"},
    {"cexp", 	0,INTR_EXP, TYPE_COMPLEX,TYPE_COMPLEX,		TYPE_COMPLEX,	1,"c_exp"},
    {"zexp", 	0,INTR_EXP, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_DCOMPLEX,	1,"z_exp"},
    
    {"log", 	1,INTR_LOG, TYPE_UNKNOWN,TYPE_UNKNOWN,	 TYPE_UNKNOWN, 1},
    {"alog", 	0,INTR_LOG, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_log"},
    {"dlog", 	0,INTR_LOG, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_log"},
    {"clog", 	0,INTR_LOG, TYPE_COMPLEX,TYPE_COMPLEX,	TYPE_COMPLEX,	1,"c_log"},
    {"zlog", 	0,INTR_LOG, TYPE_DCOMPLEX,TYPE_DCOMPLEX,TYPE_DCOMPLEX,1,"z_log"},
    
    {"log10", 	1,INTR_LOG10, TYPE_UNKNOWN,TYPE_UNKNOWN,	TYPE_UNKNOWN, 1},
    {"alog10", 	0,INTR_LOG10, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_lg10"},
    {"dlog10", 	0,INTR_LOG10, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_lg10"},
    
    {"sin", 	1,INTR_SIN, TYPE_DREAL,TYPE_REAL,		TYPE_REAL,	1,"r_sin"},
    {"dsin", 	0,INTR_SIN, TYPE_DREAL,TYPE_DREAL,		TYPE_DREAL,	1,"d_sin"},
    {"csin", 	0,INTR_SIN, TYPE_COMPLEX,TYPE_COMPLEX,		TYPE_COMPLEX,	1,"c_sin"},
    {"zsin", 	0,INTR_SIN, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_DCOMPLEX,	1,"z_sin"},
    
    {"cos", 	1,INTR_COS, TYPE_DREAL,TYPE_REAL,		TYPE_REAL,	1,"r_cos"},
    {"dcos", 	0,INTR_COS, TYPE_DREAL,TYPE_DREAL,		TYPE_DREAL,	1,"d_cos"},
    {"ccos", 	0,INTR_COS, TYPE_COMPLEX,TYPE_COMPLEX,		TYPE_COMPLEX,	1,"c_cos"},
    {"zcos", 	0,INTR_COS, TYPE_DCOMPLEX,TYPE_DCOMPLEX,	TYPE_DCOMPLEX,	1,"z_cos"},
    
    {"tan", 	1,INTR_TAN, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_tan"},
    {"dtan", 	0,INTR_TAN, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_tan"},
    
    {"asin", 	1,INTR_ASIN, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_asin"},
    {"dasin", 	0,INTR_ASIN, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_asin"},
    
    {"acos", 	1,INTR_ACOS, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_acos"},
    {"dacos", 	0,INTR_ACOS, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_acos"},

    {"atan", 	1,INTR_ATAN, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_atan"},
    {"datan", 	0,INTR_ATAN, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_atan"},

    {"atan2", 	1,INTR_ATAN2, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	2,"r_atn2"},
    {"datan2", 	0,INTR_ATAN2, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	2,"d_atn2"},
    
    {"sinh", 	1,INTR_SINH, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_sinh"},
    {"dsinh", 	0,INTR_SINH, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_sinh"},

    {"cosh", 	1,INTR_COSH, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_cosh"},
    {"dcosh", 	0,INTR_COSH, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_cosh"},

    {"tanh", 	1,INTR_TANH, TYPE_DREAL,TYPE_REAL,	TYPE_REAL,	1,"r_tanh"},
    {"dtanh", 	0,INTR_TANH, TYPE_DREAL,TYPE_DREAL,	TYPE_DREAL,	1,"d_tanh"},
    
    {"lge",	0,INTR_LGE, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_CHAR,	2,"l_ge"},
    {"lgt",	0,INTR_LGT, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_CHAR,	2,"l_gt"},
    {"lle",	0,INTR_LLE, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_CHAR,	2,"l_le"},
    {"llt",	0,INTR_LLT, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_CHAR,	2,"l_lt"},

#ifdef HAS_INT64
    {"and",	1,INTR_AND, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_LOGICAL,	2},
    {"iand",	1,INTR_AND, TYPE_INT,TYPE_INT,		TYPE_INT,	2},
    {NULL,	0,INTR_AND, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG,	2},

    {"or",	1,INTR_OR, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_LOGICAL,	2},
    {"ior",	1,INTR_OR, TYPE_INT,TYPE_INT,		TYPE_INT,	2},
    {NULL,	0,INTR_OR, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_LONGLONG,	2},
    
    {"eor",	1,INTR_EOR, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_LOGICAL,	2},
    {"ieor",	1,INTR_EOR, TYPE_INT,TYPE_INT,		TYPE_INT,	2},
    {NULL,	0,INTR_EOR, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG,	2},

    {"not",	1,INTR_NOT, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_LOGICAL,	1},
    {"inot",	1,INTR_NOT, TYPE_INT,TYPE_INT,		TYPE_INT,	1},
    {NULL,	0,INTR_NOT, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG,	1},

    {"lshift",	1,INTR_LSHIFT, TYPE_INT,TYPE_INT,	TYPE_INT,	2},
    {NULL,	0,INTR_LSHIFT, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG,	2},

    {"rshift",	1,INTR_RSHIFT, TYPE_INT,TYPE_INT,	TYPE_INT,	2},
    {NULL,	0,INTR_RSHIFT, TYPE_LONGLONG,TYPE_LONGLONG,TYPE_LONGLONG,	2},
#else
    {"and",	1,INTR_AND, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_LOGICAL,	2},
    {"iand",	0,INTR_AND, TYPE_INT,TYPE_INT,		TYPE_INT,	2},

    {"or",	1,INTR_OR, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_LOGICAL,	2},
    {"ior",	0,INTR_OR, TYPE_INT,TYPE_INT,		TYPE_INT,	2},
    
    {"eor",	1,INTR_EOR, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_LOGICAL,	2},
    {"ieor",	0,INTR_EOR, TYPE_INT,TYPE_INT,		TYPE_INT,	2},

    {"not",	1,INTR_NOT, TYPE_LOGICAL,TYPE_LOGICAL,	TYPE_LOGICAL,	1},
    {"inot",	0,INTR_NOT, TYPE_INT,TYPE_INT,		TYPE_INT,	1},

    {"lshift",	0,INTR_LSHIFT, TYPE_INT,TYPE_INT,	TYPE_INT,	2},
    {"rshift",	0,INTR_RSHIFT, TYPE_INT,TYPE_INT,	TYPE_INT,	2},
#endif /* HAS_INT64 */

#if defined(ADDR_IS_64) && defined(HAS_INT64)
    {"loc",	1, INTR_CONV_ADDR, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_INT,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_SHORT,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_LONGLONG,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_REAL,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_DREAL,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_LOGICAL,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_COMPLEX,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_DCOMPLEX,	1 },
#ifdef ENABLE_QREAL
    {NULL,	0, INTR_CONV_ADDR, TYPE_LONGLONG,TYPE_LONGLONG,	TYPE_QREAL,	1 },
#endif /* ENABLE_QREAL */
#else
    {"loc",	1, INTR_CONV_ADDR, TYPE_INT,TYPE_INT,	TYPE_INT,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_INT,TYPE_INT,	TYPE_SHORT,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_INT,TYPE_INT,	TYPE_REAL,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_INT,TYPE_INT,	TYPE_DREAL,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_INT,TYPE_INT,	TYPE_LOGICAL,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_INT,TYPE_INT,	TYPE_COMPLEX,	1 },
    {NULL,	0, INTR_CONV_ADDR, TYPE_INT,TYPE_INT,	TYPE_DCOMPLEX,	1 },
#ifdef ENABLE_QREAL
    {NULL,	0, INTR_CONV_ADDR, TYPE_INT,TYPE_INT,	TYPE_QREAL,	1 },
#endif /* ENABLE_QREAL */
#endif /* ADDR_IS_64 && HAS_INT64 */

    {"precof",	1, INTR_TYPE_PREC, TYPE_INT,TYPE_INT,	TYPE_INT,	1 },
#ifdef HAS_INT64
    {NULL,	0, INTR_TYPE_PREC, TYPE_INT,TYPE_INT,	TYPE_LONGLONG,	1 },
#endif /* HAS_INT64 */
    {NULL,	0, INTR_TYPE_PREC, TYPE_INT,TYPE_INT,	TYPE_LOGICAL,	1 },
    {NULL,	0, INTR_TYPE_PREC, TYPE_INT,TYPE_INT,	TYPE_SHORT,	1 },
    {NULL,	0, INTR_TYPE_PREC, TYPE_INT,TYPE_INT,	TYPE_CHAR,	1 },
    {NULL,	0, INTR_TYPE_PREC, TYPE_INT,TYPE_INT,	TYPE_REAL,	1 },
    {NULL,	0, INTR_TYPE_PREC, TYPE_INT,TYPE_INT,	TYPE_DREAL,	1 },
    {NULL,	0, INTR_TYPE_PREC, TYPE_INT,TYPE_INT,	TYPE_COMPLEX,	1 },
    {NULL,	0, INTR_TYPE_PREC, TYPE_INT,TYPE_INT,	TYPE_DCOMPLEX,	1 },
#ifdef ENABLE_QREAL
    {NULL,	0, INTR_TYPE_PREC, TYPE_INT,TYPE_INT,	TYPE_QREAL,	1 },
#endif /* ENABLE_QREAL */

#ifdef ENABLE_QREAL
    {"mpeps",	1, INTR_TYPE_EPS, TYPE_QREAL, TYPE_QREAL, TYPE_QREAL, 1 },
    {"qeps",	1, INTR_TYPE_EPS, TYPE_QREAL, TYPE_QREAL, TYPE_QREAL, 1 },
#endif /* ENABLE_QREAL */

    {NULL,	0,INTR_END}  /* end */
};
