271 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Sources of the "COMPARE" group instructions
 | |
|  */
 | |
| 
 | |
| /* $Header$ */
 | |
| 
 | |
| #include	<em_abs.h>
 | |
| #include	"logging.h"
 | |
| #include	"nofloat.h"
 | |
| #include	"global.h"
 | |
| #include	"log.h"
 | |
| #include	"warn.h"
 | |
| #include	"mem.h"
 | |
| #include	"shadow.h"
 | |
| #include	"trap.h"
 | |
| #include	"text.h"
 | |
| #include	"fra.h"
 | |
| 
 | |
| #ifndef	NOFLOAT
 | |
| extern double fpop();
 | |
| #endif	NOFLOAT
 | |
| 
 | |
| PRIVATE compare_obj();
 | |
| 
 | |
| DoCMIl2(arg)
 | |
| 	size arg;
 | |
| {
 | |
| 	/* CMI w: Compare w byte integers, Push negative, zero, positive for <, = or > */
 | |
| 	register size l = (L_arg_2() * arg);
 | |
| 	register long t = spop(arg_wi(l));
 | |
| 	register long s = spop(l);
 | |
| 
 | |
| 	LOG(("@T6 DoCMIl2(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(t < s ? 1 : t > s ? -1 : 0));
 | |
| }
 | |
| 
 | |
| DoCMIm(arg)
 | |
| 	size arg;
 | |
| {
 | |
| 	/* CMI w: Compare w byte integers, Push negative, zero, positive for <, = or > */
 | |
| 	register size l = arg_wi(arg);
 | |
| 	register long t = spop(l);
 | |
| 	register long s = spop(l);
 | |
| 
 | |
| 	LOG(("@T6 DoCMIm(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(t < s ? 1 : t > s ? -1 : 0));
 | |
| }
 | |
| 
 | |
| DoCMIz()
 | |
| {
 | |
| 	/* CMI w: Compare w byte integers, Push negative, zero, positive for <, = or > */
 | |
| 	register size l = uwpop();
 | |
| 	register long t = spop(arg_wi(l));
 | |
| 	register long s = spop(l);
 | |
| 
 | |
| 	LOG(("@T6 DoCMIz(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(t < s ? 1 : t > s ? -1 : 0));
 | |
| }
 | |
| 
 | |
| DoCMFl2(arg)
 | |
| 	size arg;
 | |
| {
 | |
| 	/* CMF w: Compare w byte reals */
 | |
| #ifndef	NOFLOAT
 | |
| 	register size l = (L_arg_2() * arg);
 | |
| 	double t = fpop(arg_wf(l));
 | |
| 	double s = fpop(l);
 | |
| 
 | |
| 	LOG(("@T6 DoCMFl2(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(t < s ? 1 : t > s ? -1 : 0));
 | |
| #else	NOFLOAT
 | |
| 	arg = arg;
 | |
| 	nofloat();
 | |
| #endif	NOFLOAT
 | |
| }
 | |
| 
 | |
| DoCMFs(hob, wfac)
 | |
| 	long hob;
 | |
| 	size wfac;
 | |
| {
 | |
| 	/* CMF w: Compare w byte reals */
 | |
| #ifndef	NOFLOAT
 | |
| 	register size l = (S_arg(hob) * wfac);
 | |
| 	double t = fpop(arg_wf(l));
 | |
| 	double s = fpop(l);
 | |
| 
 | |
| 	LOG(("@T6 DoCMFs(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(t < s ? 1 : t > s ? -1 : 0));
 | |
| #else	NOFLOAT
 | |
| 	hob = hob;
 | |
| 	wfac = wfac;
 | |
| 	nofloat();
 | |
| #endif	NOFLOAT
 | |
| }
 | |
| 
 | |
| DoCMFz()
 | |
| {
 | |
| 	/* CMF w: Compare w byte reals */
 | |
| #ifndef	NOFLOAT
 | |
| 	register size l = uwpop();
 | |
| 	double t = fpop(arg_wf(l));
 | |
| 	double s = fpop(l);
 | |
| 
 | |
| 	LOG(("@T6 DoCMFz(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(t < s ? 1 : t > s ? -1 : 0));
 | |
| #else	NOFLOAT
 | |
| 	nofloat();
 | |
| #endif	NOFLOAT
 | |
| }
 | |
| 
 | |
| DoCMUl2(arg)
 | |
| 	size arg;
 | |
| {
 | |
| 	/* CMU w: Compare w byte unsigneds */
 | |
| 	register size l = (L_arg_2() * arg);
 | |
| 	register unsigned long t = upop(arg_wi(l));
 | |
| 	register unsigned long s = upop(l);
 | |
| 
 | |
| 	LOG(("@T6 DoCMUl2(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(t < s ? 1 : t > s ? -1 : 0));
 | |
| }
 | |
| 
 | |
| DoCMUz()
 | |
| {
 | |
| 	/* CMU w: Compare w byte unsigneds */
 | |
| 	register size l = uwpop();
 | |
| 	register unsigned long t = upop(arg_wi(l));
 | |
| 	register unsigned long s = upop(l);
 | |
| 
 | |
| 	LOG(("@T6 DoCMUz(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(t < s ? 1 : t > s ? -1 : 0));
 | |
| }
 | |
| 
 | |
| DoCMSl2(arg)
 | |
| 	size arg;
 | |
| {
 | |
| 	/* CMS w: Compare w byte values, can only be used for bit for bit equality test */
 | |
| 	register size l = (L_arg_2() * arg);
 | |
| 
 | |
| 	LOG(("@T6 DoCMSl2(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	compare_obj(arg_w(l));
 | |
| }
 | |
| 
 | |
| DoCMSs(hob, wfac)
 | |
| 	long hob;
 | |
| 	size wfac;
 | |
| {
 | |
| 	/* CMS w: Compare w byte values, can only be used for bit for bit equality test */
 | |
| 	register size l = (S_arg(hob) * wfac);
 | |
| 
 | |
| 	LOG(("@T6 DoCMSs(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	compare_obj(arg_w(l));
 | |
| }
 | |
| 
 | |
| DoCMSz()
 | |
| {
 | |
| 	/* CMS w: Compare w byte values, can only be used for bit for bit equality test */
 | |
| 	register size l = uwpop();
 | |
| 
 | |
| 	LOG(("@T6 DoCMSz(%ld)", l));
 | |
| 	spoilFRA();
 | |
| 	compare_obj(arg_w(l));
 | |
| }
 | |
| 
 | |
| DoCMPz()
 | |
| {
 | |
| 	/* CMP -: Compare pointers */
 | |
| 	register ptr t, s;
 | |
| 
 | |
| 	LOG(("@T6 DoCMPz()"));
 | |
| 	spoilFRA();
 | |
| 	t = dppop();
 | |
| 	s = dppop();
 | |
| 	wpush((long)(t < s ? 1 : t > s ? -1 : 0));
 | |
| }
 | |
| 
 | |
| DoTLTz()
 | |
| {
 | |
| 	/* TLT -: True if less, i.e. iff top of stack < 0 */
 | |
| 	LOG(("@T6 DoTLTz()"));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(wpop() < 0 ? 1 : 0));
 | |
| }
 | |
| 
 | |
| DoTLEz()
 | |
| {
 | |
| 	/* TLE -: True if less or equal, i.e. iff top of stack <= 0 */
 | |
| 	LOG(("@T6 DoTLEz()"));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(wpop() <= 0 ? 1 : 0));
 | |
| }
 | |
| 
 | |
| DoTEQz()
 | |
| {
 | |
| 	/* TEQ -: True if equal, i.e. iff top of stack = 0 */
 | |
| 	LOG(("@T6 DoTEQz()"));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(wpop() == 0 ? 1 : 0));
 | |
| }
 | |
| 
 | |
| DoTNEz()
 | |
| {
 | |
| 	/* TNE -: True if not equal, i.e. iff top of stack non zero */
 | |
| 	LOG(("@T6 DoTNEz()"));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(wpop() != 0 ? 1 : 0));
 | |
| }
 | |
| 
 | |
| DoTGEz()
 | |
| {
 | |
| 	/* TGE -: True if greater or equal, i.e. iff top of stack >= 0 */
 | |
| 	LOG(("@T6 DoTGEz()"));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(wpop() >= 0 ? 1 : 0));
 | |
| }
 | |
| 
 | |
| DoTGTz()
 | |
| {
 | |
| 	/* TGT -: True if greater, i.e. iff top of stack > 0 */
 | |
| 	LOG(("@T6 DoTGTz()"));
 | |
| 	spoilFRA();
 | |
| 	wpush((long)(wpop() > 0 ? 1 : 0));
 | |
| }
 | |
| 
 | |
| /********************************************************
 | |
|  *		Compare objects				*
 | |
|  *							*
 | |
|  *	Two 'obj_size' sized objects are bytewise	*
 | |
|  *	compared; as soon as one byte is different	*
 | |
|  *	1 is returned, otherwise 0. No type checking	*
 | |
|  *	is performed. Checking for undefined bytes	*
 | |
|  *	is done when LOGGING is defined.		*
 | |
|  ********************************************************/
 | |
| 
 | |
| PRIVATE compare_obj(obj_size)
 | |
| 	size obj_size;
 | |
| {
 | |
| 	register ptr addr1;		/* ADDRess in object highest on st. */
 | |
| 	register ptr addr2;		/* ADDRess in object deeper in st. */
 | |
| 	register int comp_res = 0;	/* COMPare RESult */
 | |
| 
 | |
| 	for (	addr1 = SP, addr2 = SP + obj_size;
 | |
| 		addr1 < SP + obj_size;
 | |
| 		addr1++, addr2++
 | |
| 	) {
 | |
| #ifdef	LOGGING
 | |
| 		if (!st_sh(addr1) || !st_sh(addr2)) {
 | |
| 			warning(WUNCMP);
 | |
| 			/* Let's say undefined's are not equal: */
 | |
| 			comp_res = 1;
 | |
| 			break;
 | |
| 		}
 | |
| #endif	LOGGING
 | |
| 		if (stack_loc(addr1) != stack_loc(addr2)) {
 | |
| 			comp_res = 1;
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 	st_dec(2 * obj_size);
 | |
| 	wpush((long) comp_res);
 | |
| }
 |