1987-03-10 17:51:10 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*/
|
1986-03-10 13:07:55 +00:00
|
|
|
/* $Header$ */
|
|
|
|
/* C O N V E R S I O N - C O D E G E N E R A T O R */
|
|
|
|
|
1986-09-24 13:53:16 +00:00
|
|
|
#include "nofloat.h"
|
1986-03-25 16:40:43 +00:00
|
|
|
#include <em.h>
|
1986-03-10 13:07:55 +00:00
|
|
|
#include "arith.h"
|
|
|
|
#include "type.h"
|
|
|
|
#include "sizes.h"
|
|
|
|
#include "Lpars.h"
|
|
|
|
|
|
|
|
#define T_SIGNED 1
|
|
|
|
#define T_UNSIGNED 2
|
1986-09-12 09:16:07 +00:00
|
|
|
#ifndef NOFLOAT
|
1986-03-10 13:07:55 +00:00
|
|
|
#define T_FLOATING 3
|
1986-09-12 09:16:07 +00:00
|
|
|
#endif NOFLOAT
|
1986-03-10 13:07:55 +00:00
|
|
|
|
|
|
|
/* 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)
|
1987-02-09 23:19:42 +00:00
|
|
|
register struct type *from_type, *to_type;
|
1986-03-10 13:07:55 +00:00
|
|
|
{
|
1987-02-09 23:19:42 +00:00
|
|
|
register arith from_size = from_type->tp_size;
|
|
|
|
register arith to_size = to_type->tp_size;
|
1987-03-25 23:14:43 +00:00
|
|
|
int from_fund = fundamental(from_type);
|
|
|
|
int to_fund = fundamental(to_type);
|
1986-03-10 13:07:55 +00:00
|
|
|
|
1988-07-05 18:06:00 +00:00
|
|
|
if ((int)to_size < (int)word_size) to_size = word_size;
|
|
|
|
if ((int)from_size == (int)to_size && from_fund == to_fund)
|
1987-03-25 23:14:43 +00:00
|
|
|
return;
|
|
|
|
switch (from_fund) {
|
1986-03-10 13:07:55 +00:00
|
|
|
case T_SIGNED:
|
1987-03-25 23:14:43 +00:00
|
|
|
switch (to_fund) {
|
1986-03-10 13:07:55 +00:00
|
|
|
case T_SIGNED:
|
|
|
|
C_loc(from_size);
|
1987-02-23 13:08:54 +00:00
|
|
|
C_loc(to_size);
|
1986-03-10 13:07:55 +00:00
|
|
|
C_cii();
|
|
|
|
break;
|
|
|
|
case T_UNSIGNED:
|
1986-09-12 09:16:07 +00:00
|
|
|
#ifndef NOFLOAT
|
1986-03-10 13:07:55 +00:00
|
|
|
case T_FLOATING:
|
1987-03-25 23:14:43 +00:00
|
|
|
#endif NOOFLOAT
|
1988-07-05 18:06:00 +00:00
|
|
|
if ((int)from_size < (int)word_size) {
|
1987-02-23 13:08:54 +00:00
|
|
|
C_loc(from_size);
|
|
|
|
C_loc(word_size);
|
|
|
|
C_cii();
|
|
|
|
from_size = word_size;
|
|
|
|
}
|
|
|
|
C_loc(from_size);
|
1987-02-09 23:19:42 +00:00
|
|
|
C_loc(to_size);
|
1987-03-25 23:14:43 +00:00
|
|
|
if (to_fund == T_UNSIGNED) C_ciu();
|
|
|
|
else C_cif();
|
1986-03-10 13:07:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case T_UNSIGNED:
|
1988-07-05 18:06:00 +00:00
|
|
|
if ((int)from_size < (int)word_size) from_size = word_size;
|
1987-02-23 13:08:54 +00:00
|
|
|
C_loc(from_size);
|
|
|
|
C_loc(to_size);
|
1987-03-25 23:14:43 +00:00
|
|
|
switch (to_fund) {
|
1986-03-10 13:07:55 +00:00
|
|
|
case T_SIGNED:
|
|
|
|
C_cui();
|
|
|
|
break;
|
|
|
|
case T_UNSIGNED:
|
|
|
|
C_cuu();
|
|
|
|
break;
|
1986-09-12 09:16:07 +00:00
|
|
|
#ifndef NOFLOAT
|
1986-03-10 13:07:55 +00:00
|
|
|
case T_FLOATING:
|
|
|
|
C_cuf();
|
|
|
|
break;
|
1986-09-12 09:16:07 +00:00
|
|
|
#endif NOFLOAT
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
break;
|
1986-09-12 09:16:07 +00:00
|
|
|
#ifndef NOFLOAT
|
1986-03-10 13:07:55 +00:00
|
|
|
case T_FLOATING:
|
1987-02-09 23:19:42 +00:00
|
|
|
C_loc(from_size);
|
1987-02-23 13:08:54 +00:00
|
|
|
C_loc(to_size);
|
1987-03-25 23:14:43 +00:00
|
|
|
switch (to_fund) {
|
1986-03-10 13:07:55 +00:00
|
|
|
case T_SIGNED:
|
|
|
|
C_cfi();
|
|
|
|
break;
|
|
|
|
case T_UNSIGNED:
|
|
|
|
C_cfu();
|
|
|
|
break;
|
|
|
|
case T_FLOATING:
|
|
|
|
C_cff();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
1986-09-12 09:16:07 +00:00
|
|
|
#endif NOFLOAT
|
1986-03-10 13:07:55 +00:00
|
|
|
default:
|
|
|
|
crash("(conversion) illegal type conversion");
|
|
|
|
}
|
1988-07-05 18:06:00 +00:00
|
|
|
if ((int)(to_type->tp_size) < (int)word_size
|
1987-11-23 13:48:09 +00:00
|
|
|
#ifndef NOFLOAT
|
|
|
|
&& to_fund != T_FLOATING
|
|
|
|
#endif NOFLOAT
|
|
|
|
) {
|
|
|
|
extern long full_mask[];
|
|
|
|
|
|
|
|
if (to_fund == T_SIGNED) {
|
|
|
|
C_loc(to_type->tp_size);
|
|
|
|
C_loc(word_size);
|
|
|
|
C_cii();
|
|
|
|
}
|
1988-01-11 14:06:20 +00:00
|
|
|
else {
|
|
|
|
C_loc((arith) full_mask[(int)(to_type->tp_size)]);
|
|
|
|
C_and(word_size);
|
|
|
|
}
|
1987-11-23 13:48:09 +00:00
|
|
|
}
|
1986-03-10 13:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* fundamental() returns in which category a given type falls:
|
|
|
|
signed, unsigned or floating
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
fundamental(tp)
|
1986-09-24 13:53:16 +00:00
|
|
|
register struct type *tp;
|
1986-03-10 13:07:55 +00:00
|
|
|
{
|
|
|
|
switch (tp->tp_fund) {
|
|
|
|
case CHAR:
|
|
|
|
case SHORT:
|
|
|
|
case INT:
|
1986-08-13 10:05:39 +00:00
|
|
|
case ERRONEOUS:
|
1986-03-10 13:07:55 +00:00
|
|
|
case LONG:
|
|
|
|
case ENUM:
|
|
|
|
return tp->tp_unsigned ? T_UNSIGNED : T_SIGNED;
|
1986-09-12 09:16:07 +00:00
|
|
|
#ifndef NOFLOAT
|
1986-03-10 13:07:55 +00:00
|
|
|
case FLOAT:
|
|
|
|
case DOUBLE:
|
|
|
|
return T_FLOATING;
|
1986-09-12 09:16:07 +00:00
|
|
|
#endif NOFLOAT
|
1986-03-10 13:07:55 +00:00
|
|
|
case POINTER: /* pointer : signed / unsigned ??? */
|
|
|
|
return T_SIGNED;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|