Pristine Ack-5.5
[Ack-5.5.git] / util / int / do_comp.c
1 /*
2  * Sources of the "COMPARE" group instructions
3  */
4
5 /* $Id: do_comp.c,v 2.6 1994/06/24 10:46:13 ceriel Exp $ */
6
7 #include        <em_abs.h>
8 #include        "logging.h"
9 #include        "nofloat.h"
10 #include        "global.h"
11 #include        "log.h"
12 #include        "warn.h"
13 #include        "mem.h"
14 #include        "shadow.h"
15 #include        "trap.h"
16 #include        "text.h"
17 #include        "fra.h"
18
19 #ifndef NOFLOAT
20 extern double fpop();
21 #endif  /* NOFLOAT */
22
23 PRIVATE compare_obj();
24
25 DoCMI(l)
26         register size l;
27 {
28         /* CMI w: Compare w byte integers, Push negative, zero, positive for <, = or > */
29         register long t = spop(arg_wi(l));
30         register long s = spop(l);
31
32         LOG(("@T6 DoCMI(%ld)", l));
33         spoilFRA();
34         wpush((long)(t < s ? 1 : t > s ? -1 : 0));
35 }
36
37 DoCMF(l)
38         register size l;
39 {
40         /* CMF w: Compare w byte reals */
41 #ifndef NOFLOAT
42         double t = fpop(arg_wf(l));
43         double s = fpop(l);
44
45         LOG(("@T6 DoCMF(%ld)", l));
46         spoilFRA();
47         wpush((long)(t < s ? 1 : t > s ? -1 : 0));
48 #else   /* NOFLOAT */
49         nofloat();
50 #endif  /* NOFLOAT */
51 }
52
53 DoCMU(l)
54         register size l;
55 {
56         /* CMU w: Compare w byte unsigneds */
57         register unsigned long t = upop(arg_wi(l));
58         register unsigned long s = upop(l);
59
60         LOG(("@T6 DoCMU(%ld)", l));
61         spoilFRA();
62         wpush((long)(t < s ? 1 : t > s ? -1 : 0));
63 }
64
65 DoCMS(l)
66         register size l;
67 {
68         /* CMS w: Compare w byte values, can only be used for bit for bit equality test */
69
70         LOG(("@T6 DoCMS(%ld)", l));
71         spoilFRA();
72         compare_obj(arg_w(l));
73 }
74
75 DoCMP()
76 {
77         /* CMP -: Compare pointers */
78         register ptr t, s;
79
80         LOG(("@T6 DoCMP()"));
81         spoilFRA();
82         t = dppop();
83         s = dppop();
84         wpush((long)(t < s ? 1 : t > s ? -1 : 0));
85 }
86
87 DoTLT()
88 {
89         /* TLT -: True if less, i.e. iff top of stack < 0 */
90         LOG(("@T6 DoTLT()"));
91         spoilFRA();
92         wpush((long)(wpop() < 0 ? 1 : 0));
93 }
94
95 DoTLE()
96 {
97         /* TLE -: True if less or equal, i.e. iff top of stack <= 0 */
98         LOG(("@T6 DoTLE()"));
99         spoilFRA();
100         wpush((long)(wpop() <= 0 ? 1 : 0));
101 }
102
103 DoTEQ()
104 {
105         /* TEQ -: True if equal, i.e. iff top of stack = 0 */
106         LOG(("@T6 DoTEQ()"));
107         spoilFRA();
108         wpush((long)(wpop() == 0 ? 1 : 0));
109 }
110
111 DoTNE()
112 {
113         /* TNE -: True if not equal, i.e. iff top of stack non zero */
114         LOG(("@T6 DoTNE()"));
115         spoilFRA();
116         wpush((long)(wpop() != 0 ? 1 : 0));
117 }
118
119 DoTGE()
120 {
121         /* TGE -: True if greater or equal, i.e. iff top of stack >= 0 */
122         LOG(("@T6 DoTGE()"));
123         spoilFRA();
124         wpush((long)(wpop() >= 0 ? 1 : 0));
125 }
126
127 DoTGT()
128 {
129         /* TGT -: True if greater, i.e. iff top of stack > 0 */
130         LOG(("@T6 DoTGT()"));
131         spoilFRA();
132         wpush((long)(wpop() > 0 ? 1 : 0));
133 }
134
135 /********************************************************
136  *              Compare objects                         *
137  *                                                      *
138  *      Two 'obj_size' sized objects are bytewise       *
139  *      compared; as soon as one byte is different      *
140  *      1 is returned, otherwise 0. No type checking    *
141  *      is performed. Checking for undefined bytes      *
142  *      is done when LOGGING is defined.                *
143  ********************************************************/
144
145 PRIVATE compare_obj(obj_size)
146         size obj_size;
147 {
148         register ptr addr1;             /* ADDRess in object highest on st. */
149         register ptr addr2;             /* ADDRess in object deeper in st. */
150         register int comp_res = 0;      /* COMPare RESult */
151
152         for (   addr1 = SP, addr2 = SP + obj_size;
153                 addr1 < SP + obj_size;
154                 addr1++, addr2++
155         ) {
156 #ifdef  LOGGING
157                 if (!st_sh(addr1) || !st_sh(addr2)) {
158                         warning(WUNCMP);
159                         /* Let's say undefined's are not equal: */
160                         comp_res = 1;
161                         break;
162                 }
163 #endif  /* LOGGING */
164                 if (stack_loc(addr1) != stack_loc(addr2)) {
165                         comp_res = 1;
166                         break;
167                 }
168         }
169         st_dec(2 * obj_size);
170         wpush((long) comp_res);
171 }