Pristine Ack-5.5
[Ack-5.5.git] / util / int / do_logic.c
1 /*
2  * Sources of the "LOGICAL" group instructions
3  */
4
5 /* $Id: do_logic.c,v 2.6 1994/06/24 10:46:37 ceriel Exp $ */
6
7 #include        <em_abs.h>
8 #include        "logging.h"
9 #include        "global.h"
10 #include        "log.h"
11 #include        "warn.h"
12 #include        "mem.h"
13 #include        "shadow.h"
14 #include        "trap.h"
15 #include        "text.h"
16 #include        "fra.h"
17
18 #ifdef  LOGGING
19 extern int must_test;
20 #endif  /* LOGGING */
21
22 #ifdef  LOGGING
23 #define check_def(p,l)  if (!st_sh(p) || !st_sh(p+l)) {warning(WUNLOG);}
24 #else
25 #define check_def(p,l)
26 #endif  /* LOGGING */
27
28 DoAND(l)
29         register size l;
30 {
31         /* AND w: Boolean and on two groups of w bytes */
32         /* size of objects to be compared (in bytes) on top of stack */
33         register ptr p;
34
35         LOG(("@X6 DoAND(%ld)", l));
36         spoilFRA();
37         l = arg_w(l);
38         for (p = SP; p < (SP + l); p++) {
39                 check_def(p, l);
40                 stack_loc(p + l) &= stack_loc(p);
41         }
42         st_dec(l);
43 }
44
45 DoIOR(l)
46         register size l;
47 {
48         /* IOR w: Boolean inclusive or on two groups of w bytes */
49         register ptr p;
50
51         LOG(("@X6 DoIOR(%ld)", l));
52         spoilFRA();
53         l = arg_w(l);
54         for (p = SP; p < (SP + l); p++) {
55                 check_def(p, l);
56                 stack_loc(p + l) |= stack_loc(p);
57         }
58         st_dec(l);
59 }
60
61 DoXOR(l)
62         register size l;
63 {
64         /* XOR w: Boolean exclusive or on two groups of w bytes */
65         register ptr p;
66
67         LOG(("@X6 DoXOR(%ld)", l));
68         spoilFRA();
69         l = arg_w(l);
70         for (p = SP; p < (SP + l); p++) {
71                 check_def(p, l);
72                 stack_loc(p + l) ^= stack_loc(p);
73         }
74         st_dec(l);
75 }
76
77 DoCOM(l)
78         register size l;
79 {
80         /* COM w: Complement (one's complement of top w bytes) */
81         register ptr p;
82
83         LOG(("@X6 DoCOM(%ld)", l));
84         spoilFRA();
85         l = arg_w(l);
86         for (p = SP; p < (SP + l); p++) {
87                 check_def(p, 0);
88                 stack_loc(p) = ~stack_loc(p);
89         }
90 }
91
92 DoROL(l)
93         register size l;
94 {
95         /* ROL w: Rotate left a group of w bytes */
96         register long s, t = uwpop();
97         register long signbit;
98
99         LOG(("@X6 DoROL(%ld)", l));
100         spoilFRA();
101         signbit = (arg_wi(l) == 2) ? SIGNBIT2 : SIGNBIT4;
102         s = upop(l);
103         
104 #ifdef  LOGGING
105         if (must_test) {
106                 /* check shift distance */
107                 if (t < 0) {
108                         warning(WSHNEG);
109                         t = 0;
110                 }
111                 if (t >= l*8) {
112                         warning(WSHLARGE);
113                         t = l*8 - 1;
114                 }
115         }
116 #endif  /* LOGGING */
117         
118         /* calculate result */
119         while (t--) {
120                 s = (s & signbit) ? ((s<<1) | BIT(0)) : (s<<1);
121         }
122         npush(s, l);
123 }
124
125 DoROR(l)
126         register size l;
127 {
128         /* ROR w: Rotate right a group of w bytes */
129         register long s, t = uwpop();
130         register long signbit;
131
132         LOG(("@X6 DoROR(%ld)", l));
133         spoilFRA();
134         signbit = (arg_wi(l) == 2) ? SIGNBIT2 : SIGNBIT4;
135         s = upop(l);
136         
137 #ifdef  LOGGING
138         if (must_test) {
139                 /* check shift distance */
140                 if (t < 0) {
141                         warning(WSHNEG);
142                         t = 0;
143                 }
144                 if (t >= l*8) {
145                         warning(WSHLARGE);
146                         t = l*8 - 1;
147                 }
148         }
149 #endif  /* LOGGING */
150         
151         /* calculate result */
152         while (t--) {
153                 /* the >> in C does sign extension, the ROR does not */
154                 if (s & BIT(0))
155                         s = (s >> 1) | signbit;
156                 else    s = (s >> 1) & ~signbit;
157         }
158         npush(s, l);
159 }