122 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* $Header$ */
 | 
						|
/*	C O N V E R S I O N - C O D E  G E N E R A T O R	*/
 | 
						|
 | 
						|
#include	"nofloat.h"
 | 
						|
#include	<em.h>
 | 
						|
#include	"arith.h"
 | 
						|
#include	"type.h"
 | 
						|
#include	"sizes.h"
 | 
						|
#include	"Lpars.h"
 | 
						|
 | 
						|
#define	T_SIGNED		1
 | 
						|
#define	T_UNSIGNED		2
 | 
						|
#ifndef NOFLOAT
 | 
						|
#define	T_FLOATING		3
 | 
						|
#endif NOFLOAT
 | 
						|
 | 
						|
/*	conversion() generates the EM code for a conversion between
 | 
						|
	the types char, short, int, long, float, double and pointer.
 | 
						|
	In case of integral type, the notion signed / unsigned is
 | 
						|
	taken into account.
 | 
						|
	The EM code to obtain this conversion looks like:
 | 
						|
		LOC sizeof(from_type)
 | 
						|
		LOC sizeof(to_type)
 | 
						|
		C??
 | 
						|
*/
 | 
						|
 | 
						|
conversion(from_type, to_type)
 | 
						|
	struct type *from_type, *to_type;
 | 
						|
{
 | 
						|
	arith from_size;
 | 
						|
	arith to_size;
 | 
						|
 | 
						|
	if (from_type == to_type)	/* a little optimisation */
 | 
						|
		return;
 | 
						|
	from_size = from_type->tp_size;
 | 
						|
	to_size = to_type->tp_size;
 | 
						|
	switch (fundamental(from_type))	{
 | 
						|
	case T_SIGNED:
 | 
						|
		switch (fundamental(to_type))	{
 | 
						|
		case T_SIGNED:
 | 
						|
			C_loc(from_size);
 | 
						|
			C_loc(to_size < word_size ? word_size : to_size);
 | 
						|
			C_cii();
 | 
						|
			break;
 | 
						|
		case T_UNSIGNED:
 | 
						|
			C_loc(from_size < word_size ? word_size : from_size);
 | 
						|
			C_loc(to_size < word_size ? word_size : to_size);
 | 
						|
			C_ciu();
 | 
						|
			break;
 | 
						|
#ifndef NOFLOAT
 | 
						|
		case T_FLOATING:
 | 
						|
			C_loc(from_size < word_size ? word_size : from_size);
 | 
						|
			C_loc(to_size < word_size ? word_size : to_size);
 | 
						|
			C_cif();
 | 
						|
			break;
 | 
						|
#endif NOFLOAT
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	case T_UNSIGNED:
 | 
						|
		C_loc(from_size < word_size ? word_size : from_size);
 | 
						|
		C_loc(to_size < word_size ? word_size : to_size);
 | 
						|
		switch (fundamental(to_type))	{
 | 
						|
		case T_SIGNED:
 | 
						|
			C_cui();
 | 
						|
			break;
 | 
						|
		case T_UNSIGNED:
 | 
						|
			C_cuu();
 | 
						|
			break;
 | 
						|
#ifndef NOFLOAT
 | 
						|
		case T_FLOATING:
 | 
						|
			C_cuf();
 | 
						|
			break;
 | 
						|
#endif NOFLOAT
 | 
						|
		}
 | 
						|
		break;
 | 
						|
#ifndef NOFLOAT
 | 
						|
	case T_FLOATING:
 | 
						|
		C_loc(from_size < word_size ? word_size : from_size);
 | 
						|
		C_loc(to_size < word_size ? word_size : to_size);
 | 
						|
		switch (fundamental(to_type))	{
 | 
						|
		case T_SIGNED:
 | 
						|
			C_cfi();
 | 
						|
			break;
 | 
						|
		case T_UNSIGNED:
 | 
						|
			C_cfu();
 | 
						|
			break;
 | 
						|
		case T_FLOATING:
 | 
						|
			C_cff();
 | 
						|
			break;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
#endif NOFLOAT
 | 
						|
	default:
 | 
						|
		crash("(conversion) illegal type conversion");
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/*	fundamental() returns in which category a given type falls:
 | 
						|
	signed, unsigned or floating
 | 
						|
*/
 | 
						|
int
 | 
						|
fundamental(tp)
 | 
						|
	register struct type *tp;
 | 
						|
{
 | 
						|
	switch (tp->tp_fund)	{
 | 
						|
	case CHAR:
 | 
						|
	case SHORT:
 | 
						|
	case INT:
 | 
						|
	case ERRONEOUS:
 | 
						|
	case LONG:
 | 
						|
	case ENUM:
 | 
						|
		return tp->tp_unsigned ? T_UNSIGNED : T_SIGNED;
 | 
						|
#ifndef NOFLOAT
 | 
						|
	case FLOAT:
 | 
						|
	case DOUBLE:
 | 
						|
		return T_FLOATING;
 | 
						|
#endif NOFLOAT
 | 
						|
	case POINTER:	/* pointer : signed / unsigned	???	*/
 | 
						|
		return T_SIGNED;
 | 
						|
	}
 | 
						|
	return 0;
 | 
						|
}
 |