/* * Sources of the "COMPARE" group instructions */ /* $Header$ */ #include #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); }