Initial entry
This commit is contained in:
271
util/int/do_comp.c
Normal file
271
util/int/do_comp.c
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* 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();
|
||||
npush((long)(t < s ? 1 : t > s ? -1 : 0), wsize);
|
||||
}
|
||||
|
||||
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();
|
||||
npush((long)(t < s ? 1 : t > s ? -1 : 0), wsize);
|
||||
}
|
||||
|
||||
DoCMIz()
|
||||
{
|
||||
/* CMI w: Compare w byte integers, Push negative, zero, positive for <, = or > */
|
||||
register size l = upop(wsize);
|
||||
register long t = spop(arg_wi(l));
|
||||
register long s = spop(l);
|
||||
|
||||
LOG(("@T6 DoCMIz(%ld)", l));
|
||||
spoilFRA();
|
||||
npush((long)(t < s ? 1 : t > s ? -1 : 0), wsize);
|
||||
}
|
||||
|
||||
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();
|
||||
npush((long)(t < s ? 1 : t > s ? -1 : 0), wsize);
|
||||
#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();
|
||||
npush((long)(t < s ? 1 : t > s ? -1 : 0), wsize);
|
||||
#else NOFLOAT
|
||||
hob = hob;
|
||||
wfac = wfac;
|
||||
nofloat();
|
||||
#endif NOFLOAT
|
||||
}
|
||||
|
||||
DoCMFz()
|
||||
{
|
||||
/* CMF w: Compare w byte reals */
|
||||
#ifndef NOFLOAT
|
||||
register size l = upop(wsize);
|
||||
double t = fpop(arg_wf(l));
|
||||
double s = fpop(l);
|
||||
|
||||
LOG(("@T6 DoCMFz(%ld)", l));
|
||||
spoilFRA();
|
||||
npush((long)(t < s ? 1 : t > s ? -1 : 0), wsize);
|
||||
#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();
|
||||
npush((long)(t < s ? 1 : t > s ? -1 : 0), wsize);
|
||||
}
|
||||
|
||||
DoCMUz()
|
||||
{
|
||||
/* CMU w: Compare w byte unsigneds */
|
||||
register size l = upop(wsize);
|
||||
register unsigned long t = upop(arg_wi(l));
|
||||
register unsigned long s = upop(l);
|
||||
|
||||
LOG(("@T6 DoCMUz(%ld)", l));
|
||||
spoilFRA();
|
||||
npush((long)(t < s ? 1 : t > s ? -1 : 0), wsize);
|
||||
}
|
||||
|
||||
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 = upop(wsize);
|
||||
|
||||
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();
|
||||
npush((long)(t < s ? 1 : t > s ? -1 : 0), wsize);
|
||||
}
|
||||
|
||||
DoTLTz()
|
||||
{
|
||||
/* TLT -: True if less, i.e. iff top of stack < 0 */
|
||||
LOG(("@T6 DoTLTz()"));
|
||||
spoilFRA();
|
||||
npush((long)(wpop() < 0 ? 1 : 0), wsize);
|
||||
}
|
||||
|
||||
DoTLEz()
|
||||
{
|
||||
/* TLE -: True if less or equal, i.e. iff top of stack <= 0 */
|
||||
LOG(("@T6 DoTLEz()"));
|
||||
spoilFRA();
|
||||
npush((long)(wpop() <= 0 ? 1 : 0), wsize);
|
||||
}
|
||||
|
||||
DoTEQz()
|
||||
{
|
||||
/* TEQ -: True if equal, i.e. iff top of stack = 0 */
|
||||
LOG(("@T6 DoTEQz()"));
|
||||
spoilFRA();
|
||||
npush((long)(wpop() == 0 ? 1 : 0), wsize);
|
||||
}
|
||||
|
||||
DoTNEz()
|
||||
{
|
||||
/* TNE -: True if not equal, i.e. iff top of stack non zero */
|
||||
LOG(("@T6 DoTNEz()"));
|
||||
spoilFRA();
|
||||
npush((long)(wpop() != 0 ? 1 : 0), wsize);
|
||||
}
|
||||
|
||||
DoTGEz()
|
||||
{
|
||||
/* TGE -: True if greater or equal, i.e. iff top of stack >= 0 */
|
||||
LOG(("@T6 DoTGEz()"));
|
||||
spoilFRA();
|
||||
npush((long)(wpop() >= 0 ? 1 : 0), wsize);
|
||||
}
|
||||
|
||||
DoTGTz()
|
||||
{
|
||||
/* TGT -: True if greater, i.e. iff top of stack > 0 */
|
||||
LOG(("@T6 DoTGTz()"));
|
||||
spoilFRA();
|
||||
npush((long)(wpop() > 0 ? 1 : 0), wsize);
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
* 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);
|
||||
npush((long) comp_res, wsize);
|
||||
}
|
||||
Reference in New Issue
Block a user