123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /*
- * 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);
- }
|