1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 string_op: proc(node_pt,refs,p_code);
29
30 dcl node_pt ptr,
31 refs(3) ptr,
32 p_code fixed bin(15);
33
34 dcl (cg_stat$double_temp,cg_stat$long_string_temp) ptr ext static,
35 cg_stat$for_test_called bit(1) ext static;
36
37 dcl (p,p1,p2,p3,q2,q3,ref(3) defined(refs)) ptr,
38 for_test bit(1) aligned,
39 doing_andnot bit(1) aligned,
40 code fixed bin(2),
41 atom(2:3) bit(1) aligned,
42 (s2,s3,op,k,l_op,load_double,op_code,n,which_andnot) fixed bin(15);
43
44 dcl load entry(ptr,fixed bin(15)),
45 c_a entry(fixed bin(31),fixed bin) returns(ptr),
46 aq_man$clear_q entry,
47 string_temp entry(ptr,ptr,ptr) returns(ptr),
48 expmac$eis entry(fixed bin(15),ptr),
49 expmac$zero entry(fixed bin(15)),
50 expmac entry(fixed bin(15),ptr),
51 expmac$one entry(fixed bin(15),ptr,fixed bin(15)),
52 prepare_operand entry(ptr,fixed bin,bit(1) aligned) returns(ptr),
53 adjust_ref_count entry(ptr,fixed bin),
54 compile_exp entry(ptr),
55 (compile_exp$save,compile_exp$save_exp) entry(ptr) returns(ptr);
56
57 dcl (bit,fixed,min,null,string,substr) builtin;
58
59 dcl ( and init(1),
60 not init(4)) fixed bin int static;
61
62 dcl ( era init(52),
63 move_not_bits init(335),
64 comp_bits init(148),
65 move_xor init(341),
66 ora init(46),
67 move_or init(304),
68 ana init(40),
69 and_for_test init(615),
70 move_and init(264),
71 move_andnot(0:1) init(391,392),
72 test_not init(338),
73 test_xor init(344),
74 test_or init(331),
75 test_and init(267),
76 test_andnot(0:1) init(261,262),
77 staq init(6)) fixed bin(15) int static;
78
79 %include cgsystem;
80 %include reference;
81 %include operator;
82 %include machine_state;
83 %include op_codes;
84 %include nodes;
85 ^L
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 ^L
132
133 begin: p = node_pt;
134 q2 = p -> operand(2);
135 code = p_code;
136
137 op_code = fixed(substr(p -> operator.op_code,6,4),4);
138
139 p1 = ref(1);
140 p2 = ref(2);
141
142 if op_code ^= not
143 then do;
144 q3 = p -> operand(3);
145 p3 = ref(3);
146 end;
147
148 for_test = cg_stat$for_test_called;
149 doing_andnot = "0"b;
150
151
152
153 if p2 -> reference.long_ref | p2 -> reference.varying_ref then s2 = 3;
154 else s2 = 2*fixed(p2 -> reference.c_length > bits_per_word,1);
155
156 goto switch(op_code);
157
158
159
160 switch(4):
161 not_op: if code ^= 0
162 then
163
164
165
166
167 if s2 <= 2
168 then do;
169 call load(p2,s2);
170 complement: call expmac$one((era),c_a((p2 -> reference.c_length),5),s2);
171 end;
172 else do;
173 comp_long: p1 = string_temp(p,p2,null);
174 if for_test then l_op = test_not; else l_op = move_not_bits;
175 call expmac$eis(l_op,p2);
176 end;
177
178 else do;
179
180
181
182
183 call compile_exp(q2);
184 if s2 > 2 then go to comp_long;
185 else goto complement;
186 end;
187
188 goto string_done;
189
190
191
192 switch(3):
193 xor_op: op = era;
194 call check_lengths;
195 if for_test then l_op = test_xor; else l_op = move_xor;
196 load_double = 2;
197 goto set_s3;
198
199
200
201 switch(2):
202 or_op: op = ora;
203 call check_lengths;
204 if for_test then l_op = test_or; else l_op = move_or;
205 load_double = 2;
206 goto set_s3;
207
208
209
210 switch(1):
211 and_op: if for_test
212 then do;
213 op = and_for_test;
214 l_op = test_and;
215 end;
216 else do;
217 op = ana;
218 l_op = move_and;
219 end;
220
221 set_s3: if p3 -> reference.long_ref | p3 -> reference.varying_ref then s3 = 3;
222 else s3 = 2*fixed(p3 -> reference.c_length > bits_per_word,1);
223
224 if op_code = and
225 then do;
226 load_double = 2*fixed(s2 = s3,1);
227
228
229
230
231 if can_do_andnot(which_andnot)
232 then do;
233 atom(2) = code >= 2;
234 atom(3) = mod(code,2) ^= 0;
235
236 if which_andnot = 0
237 then call setup_andnot(p2,q2,s2,atom(2));
238 else call setup_andnot(p3,q3,s3,atom(3));
239
240 code = fixed(atom(2) || atom(3), 2);
241
242 call check_lengths;
243
244 if for_test
245 then l_op = test_andnot(which_andnot);
246 else l_op = move_andnot(which_andnot);
247
248 doing_andnot = "1"b;
249 end;
250 end;
251
252
253
254
255
256 goto ao_sw(code);
257
258
259
260
261 ao_sw(3):
262 ao_aa: if p3 -> reference.value_in.a then call flip_rands;
263
264 if s2 < s3 then call flip_rands;
265
266
267
268 if s2 > 2 then goto ao_aa_l;
269
270
271
272
273 call load(p2,load_double);
274 ao_aa_1: if op_code = and & s3 < s2 then call aq_man$clear_q;
275 call expmac$one(op,p3,s3);
276
277 goto string_done;
278
279
280
281 ao_aa_l: p1 = string_temp(p,p2,p3);
282
283 ao_aa_l1: if s3 > 2 | op_code = and | ^ p1 -> reference.aligned_for_store_ref | for_test
284 then do;
285
286
287
288 call long_op;
289 end;
290 else do;
291
292
293
294
295 call load(p3,2);
296 ao_aa_l3:
297 if p1 -> reference.temp_ref
298 then if ^ p1 -> reference.shared
299 then p1 -> reference.ref_count = p1 -> reference.ref_count + 1;
300 call expmac$one(op+3,p1,s3);
301 machine_state.indicators = -1;
302 end;
303
304 goto string_done;
305
306
307
308 ao_sw(2):
309 ao_ae: call flip_rands;
310
311
312
313 ao_sw(1):
314 ao_ea: if s2 > 2
315 then do;
316
317
318
319
320 if p1 -> reference.length = null
321 | (p2 -> reference.length = p3 -> reference.length
322 & ^ p2 -> reference.varying_ref
323 & ^ p3 -> reference.varying_ref)
324 then call compile_exp(q2);
325 else p2 = compile_exp$save(q2);
326 go to ao_aa_l;
327 end;
328
329
330
331 if s3 > 2
332 then do;
333
334
335
336
337 p2 = compile_exp$save_exp(q2);
338 call flip_rands;
339 goto ao_aa_l;
340 end;
341
342
343
344 if ^ p3 -> reference.aligned_ref then p3 = compile_exp$save(p3);
345 call compile_exp(q2);
346 if s2 < s3 | (s3 ^= s2 & op_code = and) then call aq_man$clear_q;
347 call expmac$one(op,p3,s3);
348
349 goto string_done;
350
351
352
353 ao_sw(0):
354 ao_ee: if s2 < s3 then call flip_rands;
355
356
357
358 if s3 > 2 then goto ao_ee_1;
359
360
361
362 if s2 > 2 then go to ao_ee_1;
363
364
365
366 p3 = compile_exp$save(q3);
367 call compile_exp(q2);
368 goto ao_aa_1;
369
370
371
372
373 ao_ee_1: if p2 -> reference.length ^= p3 -> reference.length
374 | p2 -> reference.varying_ref
375 | p3 -> reference.varying_ref
376 then do;
377
378
379
380 p3 = compile_exp$save(q3);
381
382
383
384 p2 = compile_exp$save(q2);
385
386
387
388
389
390 goto ao_aa_l;
391 end;
392
393 if p2 -> reference.c_length < p3 -> reference.c_length then call flip_rands;
394
395
396
397 p3 = compile_exp$save(q3);
398 call compile_exp(q2);
399 p1 = string_temp(p,p2,p3);
400 call long_op;
401
402
403
404 string_done:
405 if ^ p1 -> reference.long_ref
406 then a_reg.size = p1 -> reference.c_length;
407 return;
408 ^L
409 can_do_andnot: proc(which_andnot) returns(bit(1) aligned);
410
411
412
413 dcl which_andnot fixed bin(15);
414
415
416 dcl i fixed bin;
417 dcl q ptr;
418
419 if p1 -> reference.long_ref
420 then do i = 2 to 3;
421 q = p -> operand(i);
422 if q -> node.type = operator_node
423 then if q -> operator.op_code = not_bits
424 then if ^ q -> operand(1) -> reference.evaluated
425 then if q -> operand(1) -> reference.ref_count <= 1
426 then do;
427 which_andnot = i - 2;
428 return("1"b);
429 end;
430 end;
431
432 return("0"b);
433
434 end ;
435 ^L
436 setup_andnot: proc(p_new,q,s,atom);
437
438
439
440 dcl p_new ptr,
441 q ptr,
442 s fixed bin(15),
443 atom bit(1) aligned;
444
445 q = p -> operand(which_andnot+2) -> operand(2);
446
447 p_new = prepare_operand(q,1,atom);
448
449 if p_new -> reference.long_ref | p_new -> reference.varying_ref
450 then s = 3;
451 else s = 2 * fixed(p_new -> reference.c_length > bits_per_word, 1);
452
453 call adjust_ref_count((p -> operand(which_andnot+2) -> operand(1)), -1);
454
455 end ;
456 ^L
457 flip_rands: proc;
458
459 dcl p ptr, s fixed;
460
461 p = p2; p2 = p3; p3 = p;
462 p = q2; q2 = q3; q3 = p;
463 s = s2; s2 = s3; s3 = s;
464
465 if doing_andnot
466 then do;
467 which_andnot = mod(which_andnot+1,2);
468 if for_test
469 then l_op = test_andnot(which_andnot);
470 else l_op = move_andnot(which_andnot);
471 end;
472
473 end ;
474
475
476 check_lengths: proc;
477
478 if p1 -> reference.long_ref
479 then if for_test
480 then if p2 -> reference.length ^= p3 -> reference.length
481 | p2 -> reference.c_length ^= p3 -> reference.c_length
482 | p2 -> reference.varying_ref
483 | p3 -> reference.varying_ref
484 then for_test, cg_stat$for_test_called = "0"b;
485
486 end ;
487
488
489 long_op: proc;
490
491 call expmac$eis(l_op,p3);
492
493 end ;
494
495 end ;