2019-03-17 14:42:00 +00:00
|
|
|
/** @file
|
|
|
|
* Sources of the "COMPARE" group instructions
|
1988-06-22 16:57:09 +00:00
|
|
|
*/
|
|
|
|
|
1994-06-24 11:31:16 +00:00
|
|
|
/* $Id$ */
|
1988-06-22 16:57:09 +00:00
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
#include "em_abs.h"
|
1988-06-22 16:57:09 +00:00
|
|
|
#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"
|
2019-03-17 14:42:00 +00:00
|
|
|
#include "stack.h"
|
1988-06-22 16:57:09 +00:00
|
|
|
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
PRIVATE void compare_obj(size);
|
1988-06-22 16:57:09 +00:00
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoCMI(register size l)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* CMI w: Compare w byte integers, Push negative, zero, positive for <, = or > */
|
|
|
|
register long t = spop(arg_wi(l));
|
|
|
|
register long s = spop(l);
|
|
|
|
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoCMI(%ld)", l));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long)(t < s ? 1 : t > s ? -1 : 0));
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoCMF(register size l)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* CMF w: Compare w byte reals */
|
|
|
|
#ifndef NOFLOAT
|
|
|
|
double t = fpop(arg_wf(l));
|
|
|
|
double s = fpop(l);
|
|
|
|
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoCMF(%ld)", l));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long)(t < s ? 1 : t > s ? -1 : 0));
|
1991-12-17 15:28:58 +00:00
|
|
|
#else /* NOFLOAT */
|
1988-06-22 16:57:09 +00:00
|
|
|
nofloat();
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* NOFLOAT */
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoCMU(register size l)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* CMU w: Compare w byte unsigneds */
|
|
|
|
register unsigned long t = upop(arg_wi(l));
|
|
|
|
register unsigned long s = upop(l);
|
|
|
|
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoCMU(%ld)", l));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long)(t < s ? 1 : t > s ? -1 : 0));
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoCMS(register size l)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* CMS w: Compare w byte values, can only be used for bit for bit equality test */
|
|
|
|
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoCMS(%ld)", l));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
|
|
|
compare_obj(arg_w(l));
|
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoCMP(void)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* CMP -: Compare pointers */
|
|
|
|
register ptr t, s;
|
|
|
|
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoCMP()"));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
|
|
|
t = dppop();
|
|
|
|
s = dppop();
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long)(t < s ? 1 : t > s ? -1 : 0));
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoTLT(void)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* TLT -: True if less, i.e. iff top of stack < 0 */
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoTLT()"));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long)(wpop() < 0 ? 1 : 0));
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoTLE(void)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* TLE -: True if less or equal, i.e. iff top of stack <= 0 */
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoTLE()"));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long)(wpop() <= 0 ? 1 : 0));
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoTEQ(void)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* TEQ -: True if equal, i.e. iff top of stack = 0 */
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoTEQ()"));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long)(wpop() == 0 ? 1 : 0));
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoTNE(void)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* TNE -: True if not equal, i.e. iff top of stack non zero */
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoTNE()"));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long)(wpop() != 0 ? 1 : 0));
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoTGE(void)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* TGE -: True if greater or equal, i.e. iff top of stack >= 0 */
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoTGE()"));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long)(wpop() >= 0 ? 1 : 0));
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
2019-03-17 14:42:00 +00:00
|
|
|
void DoTGT(void)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
/* TGT -: True if greater, i.e. iff top of stack > 0 */
|
1990-06-21 12:16:31 +00:00
|
|
|
LOG(("@T6 DoTGT()"));
|
1988-06-22 16:57:09 +00:00
|
|
|
spoilFRA();
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long)(wpop() > 0 ? 1 : 0));
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************************************************
|
2019-03-17 14:42:00 +00:00
|
|
|
* 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.
|
1988-06-22 16:57:09 +00:00
|
|
|
********************************************************/
|
2019-03-17 14:42:00 +00:00
|
|
|
PRIVATE void compare_obj(size obj_size)
|
1988-06-22 16:57:09 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
1991-12-17 15:28:58 +00:00
|
|
|
#endif /* LOGGING */
|
1988-06-22 16:57:09 +00:00
|
|
|
if (stack_loc(addr1) != stack_loc(addr2)) {
|
|
|
|
comp_res = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
st_dec(2 * obj_size);
|
1989-11-13 15:36:12 +00:00
|
|
|
wpush((long) comp_res);
|
1988-06-22 16:57:09 +00:00
|
|
|
}
|