Pristine Ack-5.5
[Ack-5.5.git] / mach / sparc / ce / EM_table.x
1 /* lfr ret should little endian */
2
3 #define const13(x) ((x) > -4096 && (x) < 4096)
4 #define NULL 0
5 #include "mach_em.h"
6
7 define(`RETH_LD',`reg_o1')
8 define(`RETL_LD',`reg_o0')
9 define(`RETH_ST',`reg_i1')
10 define(`RETL_ST',`reg_i0')
11 define(`LIN_NO',`%g6')
12 define(`FIL_NAM',`%g7')
13
14 define(`BP_OFFSET',`'WINDOWSIZE)
15 define(`'`EM_BSIZE',EM_BSIZE)
16 define(STACK_CLICK,4)
17
18 #if RESOLV_debug
19 define(Comment0)
20 define(Comment)
21 define(Comment2)
22 #else
23 define(Comment0,; `'`)' ; `'`/* */'"    ! $1"           ; code_combiner`'`(' )
24 define(Comment, ; `'`)' ; `'`/* */'"    ! $1 $2"        ; code_combiner`'`(' )
25 define(Comment2,; `'`)' ; `'`/* */'"    ! $1 $2 $3"     ; code_combiner`'`(' )
26 #endif
27
28 define(MAX_INT, 0x7fffffff)
29 define(E_EM_CUF, 100)
30 define(E_EM_CFF, 101)
31 define(E_EM_CFI, 102)
32 define(E_EM_CFU, 103)
33 #define MAX_UNROLL      16
34 #undef FAST_LIN_LNI_FIL
35
36
37 define( narg4,
38 C_$1_narg       ==>
39 `       {
40                 reg_t a;
41                 int n;
42                 
43                 Comment0( $1_narg );
44                 if (type_of_tos() == T_cst)
45                 {
46                         n= pop_const(NULL);
47                         C_$1 (n);
48                 }
49                 else
50                 {
51                         a= pop_reg();
52                         force_alloc_output();
53                         "cmp    $a, 4";
54                         "be     1f";
55                         "set    EILLINS, $reg_o0";
56                         "call   trp";
57                         "nop";
58                 "1:";
59                         free_reg(a);
60                         free_output();
61                 C_$1 (4);
62                 }
63         }.
64 '
65 )
66
67
68 /******************************************************************************/
69 /*                                                                            */
70 /*                      Group 1 : Load instructions                           */
71 /*                                                                            */
72 /******************************************************************************/
73
74 /*      %fp : frame pointer
75  *      %sp : stack pointer
76  *      RETH_XX: High part of return value
77  *      RETL_XX: Low part of return value
78  *      LIN_NO : lin_no
79  *      FIL_NAM: Fil_nam
80  */
81
82 C_loc           ==>
83                         Comment( loc , $1 );
84                         push_const($1).
85
86
87 C_lol           ==>
88                 Comment( lol , $1 );
89                 {
90                         reg_t S1;
91
92                         if (S1 = find_local($1, NULL)) {
93                                 soft_alloc_reg(S1);
94                                 push_reg(S1);
95                         } else {
96                                 soft_alloc_reg(reg_lb);
97                                 push_reg(reg_lb);
98                                 inc_tos($1);
99                                 push_const(4);
100                                 C_los(EM_WSIZE);
101                         }
102                 }.
103
104
105 C_loe..         ==>
106                 Comment2( loe.. , $1, $2 );
107                 {
108 #ifdef FAST_LIN_LNI_FIL
109                         if ((int*)($1) == (int*)"hol0")
110                                 if ($2 == 0)
111                                         push_reg(reg_lin);
112                                 else if ($2 == 4)
113                                         push_reg(reg_fil);
114                                 else
115                                         arg_error("loe.. hol0+", $2);
116                         else {
117 #endif
118                                 push_ext($1);
119                                 inc_tos($2);
120                                 push_const(4);
121                                 C_los(EM_WSIZE);
122 #ifdef FAST_LIN_LNI_FIL
123                         }
124 #endif
125                 }
126                 .
127
128 C_lil           ==>
129                 Comment( lil , $1 );
130                 {
131                         reg_t S1;
132                         reg_t S2;
133
134                         if (S1 = find_local($1, NULL)) {
135                                 S2 = alloc_reg();
136                                 "ld     [$S1], $S2";
137                                 push_reg(S2);
138                         } else {
139                                 soft_alloc_reg(reg_lb);
140                                 push_reg(reg_lb);
141                                 inc_tos($1);
142                                 push_const(4);
143                                 C_los(EM_WSIZE);
144                                 push_const(4);
145                                 C_los(EM_WSIZE);
146                         }
147                 }.
148
149 C_lof           ==>
150                         Comment( lof , $1 );
151                         inc_tos($1);
152                         push_const(4);
153                         C_los(EM_WSIZE).
154
155 C_lal           ==>
156                         Comment( lal , $1 );
157                         soft_alloc_reg(reg_lb);
158                         push_reg(reg_lb);
159                         inc_tos($1).
160
161 C_lae..         ==>
162                         Comment2( lae.. , $1, $2 );
163                         push_ext($1);
164                         inc_tos($2).
165
166 C_lxl
167         $1 == 0 ==>
168                         Comment( lxl , $1 );
169                         soft_alloc_reg(reg_lb);
170                         push_reg(reg_lb).
171         $1 == 1 ==>
172                         Comment( lxl , $1 );
173                         soft_alloc_reg(reg_lb);
174                         push_reg(reg_lb);
175                         inc_tos(EM_BSIZE);
176                         push_const(4);
177                         C_los(EM_WSIZE).
178         default ==>
179                         Comment( lxl , $1 );
180                         {
181                                 reg_t a;
182                                 reg_t b;
183                                 reg_t c;
184                                 const_str_t n_str;
185
186                                 a = alloc_reg();
187                                 b = alloc_reg();
188                                 c = alloc_reg();
189                                 sprint(n_str, "%d", $1);
190                                 "set    $n_str, $a";
191                                 "mov    $reg_lb, $b";
192                         "1:     ld      [$b + EM_BSIZE], $c";
193                                 "deccc  $a";
194                                 "bnz    1b";
195                                 "mov    $c, $b";
196                                 push_reg(b);
197                                 free_reg(a);
198                                 free_reg(c);
199                         }.
200
201 C_lxa   ==>
202         C_lxl($1);
203         inc_tos(EM_BSIZE).
204
205 C_loi
206         ( $1 == 1 ) ||
207         ( $1 == 2 ) ||
208         ( $1 % 4 == 0 ) ==>
209                         Comment( loi , $1 );
210                         push_const($1);
211                         C_los(EM_WSIZE).
212
213         default         ==>
214                                 arg_error( "loi", $1).
215
216 C_los
217         $1 == 4  ==>
218         {
219                 reg_t a;
220                 reg_t b;
221                 reg_t c;
222                 int i;
223                 char *LD;
224                 arith size;
225                 const_str_t n;
226                 const_str_t size_str;
227
228                 Comment( los, $1);
229                 if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL) {
230                         size = pop_const(size_str);
231                         if (size <= 4) {
232                                 switch (size) {
233                                 case 1: LD = "ldub"; break;
234                                 case 2: LD = "lduh"; break;
235                                 case 4: LD = "ld"; break;
236                                 default: arg_error("C_los", size);
237                                 }
238                                 b = alloc_reg();
239                                 if (type_of_tos() & T_reg2)
240                                 {
241                                         a= pop_reg_reg(&c);
242                                         "$LD    [$a+$c], $b";
243                                         free_reg(a);
244                                         free_reg(c);
245                                 }
246                                 else
247                                 {
248                                         a = pop_reg_c13(n);
249                                         "$LD    [$a+$n], $b";
250                                         free_reg(a);
251                                 }
252                                 push_reg(b);
253                         } else if (size <= MAX_UNROLL) {    /* SUB-OPTIMAL */
254                                 inc_tos(size-4);
255                                 for (i = 0; i < size; i += 4) {
256                                         b = alloc_reg();
257                                         if (type_of_tos() & T_reg2)
258                                         {
259                                                 a= pop_reg_reg(&c);
260                                                 "ld     [$a+$c], $b";
261                                                 push_reg(b);
262                                                 push_reg(a);
263                                                 inc_tos_reg(c);
264                                         }
265                                         else
266                                         {
267                                                 a = pop_reg_c13(n);
268                                                 "ld     [$a+$n], $b";
269                                                 push_reg(b);
270                                                 if (n[0] == '-' || isdigit(n[0]))
271                                                 {
272                                                         push_reg(a);
273                                                         inc_tos(atoi(n));
274                                                 }
275                                                 else
276                                                 {
277                                                         b= alloc_reg();
278                                                         "add    $a, $n, $b";
279                                                         push_reg(b);
280                                                         free_reg(a);
281                                                 }
282                                         }
283                                         inc_tos(-4);
284                                 }
285                                 pop_nop(1);
286                         } else
287                                 arg_error ("loi",  size);
288                 }
289                 else {
290                         a = alloc_reg();        /* count */
291                         pop_reg_as(a);
292                         b = pop_reg();  /* addr */
293                         c = alloc_reg();
294                         flush_cache();
295                         "sub    $reg_sp, $a, $reg_sp"   /* HACK */
296                 "1:      deccc  4, $a"
297                         "ld     [$b+$a], $c"
298                         "bnz    1b"
299                         "st     $c, [$reg_sp+$a]"       /* delay */
300                         free_reg(a);
301                         free_reg(b);
302                         free_reg(c);
303                 }
304         }.
305         default ==>
306                 arg_error("C_los", $1).
307
308
309 narg4(los)
310
311 C_ldl           ==>
312                 Comment( ldl , $1 );
313                 {
314                         reg_t S1;
315                         reg_t S2;
316
317                         if (S1 = find_local($1, &S2)) {
318                                 soft_alloc_reg(S1);
319                                 soft_alloc_reg(S2);
320                                 push_double_reg(S1);
321                         } else {
322                                 soft_alloc_reg(reg_lb);
323                                 push_reg(reg_lb);
324                                 inc_tos($1);
325                                 push_const(8);
326                                 C_los(EM_WSIZE);
327                         }
328                 }.
329
330
331 C_lde..         ==>
332                         Comment2( lde.. , $1, $2 );
333                         push_ext($1);
334                         inc_tos($2);
335                         push_const(8);
336                         C_los(EM_WSIZE).
337
338 C_ldf           ==>
339                         Comment( ldf , $1 );
340                         inc_tos($1);
341                         push_const(8);
342                         C_los(EM_WSIZE).
343
344 C_lpi           ==>
345                         Comment( lpi , $1 );
346                         push_ext($1).
347
348
349 /******************************************************************************/
350 /*                                                                            */
351 /*                      Group 2 : Store instructions                          */
352 /*                                                                            */
353 /******************************************************************************/
354
355 C_stl           ==>
356                 Comment( stl , $1 );
357                 {
358                         reg_t S1;
359
360                         if ((S1 = find_local($1, NULL))) {
361                                 pop_reg_as(S1);
362                         } else {
363                                 soft_alloc_reg(reg_lb);
364                                 push_reg(reg_lb);
365                                 inc_tos($1);
366                                 push_const(4);
367                                 C_sts(EM_WSIZE);
368                         }
369                 }.
370
371 C_ste..         ==>
372                         Comment2( ste.. , $1, $2 );
373                         push_ext($1);
374                         inc_tos($2);
375                         push_const(4);
376                         C_sts(EM_WSIZE).
377
378
379 C_sil           ==>
380                 Comment( sil , $1 );
381                 {
382                         reg_t S1;
383                         reg_t S2;
384
385                         if (S1 = find_local($1, NULL)) {
386                                 S2 = pop_reg();
387                                 "st     $S2, [$S1]";
388                                 free_reg(S2);
389                         } else {
390                                 soft_alloc_reg(reg_lb);
391                                 push_reg(reg_lb);
392                                 inc_tos($1);
393                                 push_const(4);
394                                 C_los(EM_WSIZE);
395                                 push_const(4);
396                                 C_sts(EM_WSIZE);
397                         }
398                 }.
399
400 C_stf           ==>
401                         Comment( stf , $1 );
402                         inc_tos($1);
403                         push_const(4);
404                         C_sts(EM_WSIZE).
405
406 C_sti
407         ( $1 == 1) ||
408         ( $1 == 2) ||
409         ( $1 % 4 == 0 ) ==>
410                         Comment( sti, $1 );
411                         push_const($1);
412                         C_sts(EM_WSIZE).
413
414         default         ==>
415                                 arg_error( "sti", $1).
416
417
418 C_sts
419         $1 == 4  ==>
420         {
421                 reg_t a;
422                 reg_t b;
423                 reg_t c;
424                 reg_t d;
425
426                 arith size;
427                 const_str_t n;
428                 const_str_t size_str;
429                 int i;
430                 char *ST;
431
432                 Comment( sts, $1);
433                 if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL) {
434
435                         size = pop_const(size_str);
436                         if (size <= 4) {
437
438                                 switch (size) {
439                                 case 1: ST = "stb"; break;
440                                 case 2: ST = "sth"; break;
441                                 case 4: ST = "st"; break;
442                                 default: arg_error("C_sti", size);
443                                 }
444                                 c= NULL;
445                                 if (type_of_tos() & T_reg2)
446                                         a= pop_reg_reg(&c);
447                                 else
448                                         a = pop_reg_c13(n);
449                                 if (type_of_tos() == T_float) {
450                                         b= pop_float();
451                                         if (size < 4) {
452                                                 "st     $b,[%fp+64]";
453                                                 free_reg(b);
454                                                 b= alloc_reg();
455                                                 "ld     [%fp+64],$b";
456                                         }
457                                 }
458                                 else
459                                         b = pop_reg();
460                                 if (c)
461                                 {
462                                         "$ST    $b, [$a+$c]";
463                                         free_reg(c);
464                                 }
465                                 else
466                                         "$ST    $b, [$a+$n]";
467                                 free_reg(a);
468                                 free_reg(b);
469                         } else if (size <= MAX_UNROLL) {
470                                 for (i = 0; i < size; i+=4) {
471                                         c= NULL;
472                                         if (type_of_tos() & T_reg2)
473                                                 a= pop_reg_reg(&c);
474                                         else
475                                                 a = pop_reg_c13(n);
476                                         if (type_of_tos() == T_float)
477                                                 b= pop_float();
478                                         else
479                                                 b = pop_reg();
480                                         if (c)
481                                                 "st     $b, [$a+$c]";
482                                         else
483                                                 "st     $b, [$a+$n]";
484                                         free_reg(b);
485                                         if (c)
486                                         {
487                                                 push_reg(a);
488                                                 inc_tos_reg(c);
489                                         }
490                                         else if (n[0] == '-' || isdigit(n[0]))
491                                         {
492                                                 push_reg(a);
493                                                 inc_tos(atoi(n));
494                                         }
495                                         else
496                                         {
497                                                 b= alloc_reg();
498                                                 "add    $a, $n, $b";
499                                                 push_reg(b);
500                                                 free_reg(a);
501                                         }
502                                         inc_tos(4);
503                                 }
504                                 pop_nop(1);
505                         } else
506                                 arg_error ("sti", size);
507                 }
508                 else {
509                         force_alloc_output();
510                         d = pop_reg();          /* size */
511                         a = pop_reg();          /* address */
512                         flush_cache();
513                         b = alloc_reg();
514                         c = alloc_reg();
515                         "cmp    $d, 4";
516                         "bg,a   8f";
517                         "andcc  $d, 3, %g0";    /* delay slot */
518                         "be,a   4f";
519                         "ld     [$reg_sp], $b"; /* delay slot */
520                         "cmp    $d, 1";
521                         "be,a   1f";
522                         "ld     [$reg_sp], $b"; /* delay slot */
523                         "bl     0f";
524                         "cmp    $d, 2";
525                         "be     2f";
526                         "ld     [$reg_sp], $b"; /* delay slot */
527                 "3:      set    EILLINS, %o0";
528                         "call   trp";
529                         "nop";
530                         "b      0f";
531                         "nop";
532                 "1:";
533                         "inc    STACK_CLICK, $reg_sp";
534                         "b      0f";
535                         "stb    $b, [$a]";      /* delay slot */
536                 "2:";
537                         "inc    STACK_CLICK, $reg_sp";
538                         "b      0f";
539                         "sth    $b, [$a]";      /* delay slot */
540                 "4:";
541                         "inc    STACK_CLICK, $reg_sp";
542                         "b      0f";
543                         "st     $b, [$a]";      /* delay slot */
544                 "8:";
545                         "bne    3b";
546                         "nop";
547                         "mov    $d, $b";
548                 "9:      deccc  4, $b";
549                         "ld     [$reg_sp+$b], $c";
550                         "bnz    9b";
551                         "st     $c, [$a+$b]";   /* delay slot */
552                         "add    $reg_sp, $d, $reg_sp"   /* HACK */
553                 "0:"
554                         free_reg(a);
555                         free_reg(b);
556                         free_reg(c);
557                         free_reg(d);
558                         free_output();
559                 }
560         }.
561         default         ==>
562                                 arg_error( "sts", $1).
563
564 narg4(sts)
565
566 C_sdl           ==>
567                 Comment( sdl , $1 );
568                 {
569                         reg_t S1;
570                         reg_t S2;
571
572                         S1 = find_local($1, NULL);
573                         if (S1) 
574                                 pop_double_reg_as(S1);
575                         else {
576                                 soft_alloc_reg(reg_lb);
577                                 push_reg(reg_lb);
578                                 inc_tos($1);
579                                 push_const(8);
580                                 C_sts(EM_WSIZE);
581                         }
582                 }.
583
584 C_sde..         ==>
585                         Comment2( sde.. , $1, $2 );
586                         push_ext($1);
587                         inc_tos($2);
588                         push_const(8);
589                         C_sts(EM_WSIZE).
590
591 C_sdf           ==>
592                         Comment( sdf , $1 );
593                         inc_tos($1);
594                         push_const(8);
595                         C_sts(EM_WSIZE).
596
597
598 /******************************************************************************/
599 /*                                                                            */
600 /*              Group 3 : Integer arithmetic                                  */
601 /*                                                                            */
602 /******************************************************************************/
603
604
605 C_adi
606         $1 == 4 ==>
607                         Comment( adi , $1 );
608                         if ((type_of_tos()) == T_cst) {
609                                 arith n;
610
611                                 n = pop_const(NULL);
612                                 inc_tos(n);
613                         } else {
614                                 reg_t a;
615                                 reg_t b;
616                                 reg_t c;
617
618                                 a = pop_reg();
619                                 inc_tos_reg(a);
620                         }.
621         default ==>
622                                 arg_error( "adi", $1).
623
624 narg4(adi)
625
626 C_sbi
627         $1 == 4 ==>
628                         Comment( sbi , $1 );
629                         if ((type_of_tos()) == T_cst) {
630                                 arith n;
631
632                                 n = pop_const(NULL);
633                                 inc_tos(-n);
634                         } else {
635                                 reg_t a;
636                                 reg_t b;
637                                 reg_t c;
638
639                                 a = pop_reg();
640                                 b = pop_reg();
641                                 c = alloc_reg();
642                                 "sub    $b, $a, $c";
643                                 free_reg(a);
644                                 free_reg(b);
645                                 push_reg(c);
646                         }.
647         default ==>
648                                 arg_error( "sbi", $1).
649
650 narg4(sbi)
651
652 C_mli
653         $1 == 4 ==>
654         {
655                 unsigned int n0;
656                 unsigned int n1;
657                 reg_t orig;
658                 reg_t a;
659                 reg_t b;
660                 reg_t c;
661                 unsigned int n;
662                 const_str_t n_str;
663
664                 Comment( mli , $1 );
665
666                 if (type_of_tos() == T_cst) {
667                         n = pop_const(NULL);
668                         orig = pop_reg();
669                         c = reg_g0;
670                         while (n) {
671                                 for (n0 = 0; !(n & 1); n>>=1)
672                                         ++n0;
673                                 for (n1 = 0; n & 1; n>>=1)
674                                         ++n1;
675
676                                 if (n0) {
677                                         a = alloc_reg();
678                                         sprint(n_str, "%d", n0);
679                                         "sll    $orig, $n_str, $a";
680                                         free_reg(orig);
681                                         orig = a;
682                                 }
683                                 if (n1 == 1) {
684                                         if (c == reg_g0) {
685                                                 soft_alloc_reg(orig);
686                                                 c = orig;
687                                         } else {
688                                                 a = alloc_reg();
689                                                 "add    $c, $orig, $a";
690                                                 free_reg(c);
691                                                 c = a;
692                                         }
693                                         n <<= n1;
694                                 } else {
695                                         a = alloc_reg();
696                                         sprint(n_str, "%d", n1);
697                                         "sll    $orig, $n_str, $a";
698                                         b = alloc_reg();
699                                         "sub    $a, $orig, $b";
700                                         free_reg(orig);
701                                         orig = a;
702                                         if (c == reg_g0)
703                                                 c = b;
704                                         else {
705                                                 a = alloc_reg();
706                                                 "add    $c, $b, $a";
707                                                 free_reg(b);
708                                                 free_reg(c);
709                                                 c = a;
710                                         }
711                                 }
712                         }
713                         push_reg(c);
714                         free_reg(orig);
715                 } else {
716                         force_alloc_output();
717                         pop_reg_as(reg_o0);
718                         pop_reg_as(reg_o1);
719                         "call   mli4";
720                         "nop"                   /* delay */
721                         free_output();
722                         forced_alloc_reg(reg_o0);
723                         push_reg(reg_o0);
724                 }
725         }.
726         default ==>
727                         arg_error( "mli", $1).
728
729 narg4(mli)
730
731 C_dvi
732         $1 == 4 ==>
733         {
734                 reg_t a;
735                 reg_t b;
736                 int n;
737                 int n_exp;
738                 const_str_t n_exp_str;
739
740                 Comment( dvi , $1 );
741 #if MATH_DIVIDE
742                 if (type_of_tos() == T_cst &&
743                         power_of_2(top_const(), &n_exp))
744                 {
745                         sprint (n_exp_str, "%d", n_exp);
746                         n= pop_const(NULL);
747                         a= pop_reg();
748                         b= alloc_reg();
749                         "sra    $a, $n_exp_str, $b";
750                         free_reg(a);
751                         push_reg(b);
752                 }
753                 else
754 #endif
755                 {
756                         force_alloc_output();
757                         pop_reg_as(reg_o1);     /* denominator */
758                         pop_reg_as(reg_o0);     /* numerator */
759 #if MATH_DIVIDE
760                         "call   mathdvi4";
761 #else
762                         "call   dvi4";
763 #endif
764                         "nop"
765                         free_output();
766                         forced_alloc_reg(reg_o0);
767                         push_reg(reg_o0);
768                 }
769         }.
770         default ==>
771                         arg_error( "dvi", $1).
772
773 narg4(dvi)
774
775 C_rmi
776         $1 == 4 ==>
777                         Comment( rmi , $1 );
778                         {
779                                 force_alloc_output();
780                                 pop_reg_as(reg_o1);     /* denominator */
781                                 pop_reg_as(reg_o0);     /* numerator */
782 #if MATH_DIVIDE
783                                 "call   mathdvi4";
784 #else
785                                 "call   dvi4";
786 #endif
787                                 "nop"
788                                 free_output();
789                                 forced_alloc_reg(reg_o1);
790                                 push_reg(reg_o1);
791                         }.
792         default ==>
793                         arg_error( "rmi", $1).
794
795 narg4(rmi)
796
797 C_ngi
798         $1 == 4 ==>
799                         Comment( ngi , $1 );
800                         {
801                                 reg_t a;
802                                 reg_t b;
803
804                                 a = pop_reg();
805                                 b = alloc_reg();
806                                 "sub    %g0, $a, $b";
807                                 push_reg(b);
808                                 free_reg(a);
809                         }.
810         default ==>
811                         arg_error( "ngi", $1).
812
813 narg4(ngi)
814
815 C_sli
816         $1 == 4 ==>
817                         Comment( sli , $1 );
818                         {
819                                 reg_t a;
820                                 reg_t b;
821                                 reg_t c;
822
823                                 b = alloc_reg();
824                                 if ((type_of_tos() == T_cst) &&
825                                         (const13(top_const()))) {
826                                         const_str_t n;
827
828                                         pop_const(n);
829                                         a = pop_reg();
830                                         "sll    $a, $n, $b";
831                                 } else {
832                                         c = pop_reg();
833                                         a = pop_reg();
834                                         "sll    $a, $c, $b";
835                                         free_reg(c);
836                                 }
837                                 free_reg(a);
838                                 push_reg(b);
839                         }.
840         default ==>
841                         arg_error( "sli", $1).
842
843 narg4(sli)
844
845 C_sri
846         $1 == 4         ==>
847                         Comment( sri , $1 );
848                         {
849                                 reg_t a;
850                                 reg_t b;
851                                 reg_t c;
852
853                                 b = alloc_reg();
854                                 if ((type_of_tos() == T_cst) &&
855                                         (const13(top_const()))) {
856                                         const_str_t n;
857
858                                         pop_const(n);
859                                         a = pop_reg();
860                                         "sra    $a, $n, $b";
861                                 } else {
862                                         c = pop_reg();
863                                         a = pop_reg();
864                                         "sra    $a, $c, $b";
865                                         free_reg(c);
866                                 }
867                                 free_reg(a);
868                                 push_reg(b);
869                         }.
870         default ==>
871                         arg_error( "sri", $1).
872
873 narg4(sri)
874
875 /******************************************************************************/
876 /*                                                                            */
877 /*              Group 4 : Unsigned arithmetic                                 */
878 /*                                                                            */
879 /******************************************************************************/
880
881 C_adu           ==>
882                         Comment( adu , $1 );
883                         C_adi( w).
884
885 narg4(adu)
886
887 C_sbu           ==>
888                         Comment( sbu , $1 );
889                         C_sbi( w).
890
891 narg4(sbu)
892
893 C_mlu
894         $1 == 4 ==>
895                 Comment( mlu , $1 );
896                 C_mli($1).
897 /*
898                 {
899                         force_alloc_output();
900                         pop_reg_as(reg_o0);
901                         pop_reg_as(reg_o1);
902                         "call   mlu4";
903                         "nop"
904                         free_output();
905                         forced_alloc_reg(reg_o0);
906                         push_reg(reg_o0);
907                 }.
908 */
909         default ==>
910                         arg_error( "mlu", $1).
911
912 narg4(mlu)
913
914 C_dvu
915         $1 == 4 ==>
916         {
917                 reg_t a;
918                 reg_t b;
919                 unsigned n;
920                 int n_exp;
921                 const_str_t n_exp_str;
922
923                 Comment( dvu , $1 );
924                 if (type_of_tos() == T_cst &&
925                         uns_power_of_2(top_const(), &n_exp))
926                 {
927                         sprint (n_exp_str, "%d", n_exp);
928                         n= pop_const(NULL);
929                         a= pop_reg();
930                         b= alloc_reg();
931                         "srl    $a, $n_exp_str, $b";
932                         free_reg(a);
933                         push_reg(b);
934                 }
935                 else
936                 {
937                         force_alloc_output();
938                         pop_reg_as(reg_o1);     /* denominator */
939                         pop_reg_as(reg_o0);     /* numerator */
940                         "call   dvu4";
941                         "nop"
942                         free_output();
943                         forced_alloc_reg(reg_o0);
944                         push_reg(reg_o0);
945                 }
946         }.
947         default ==>
948                         arg_error( "dvu", $1).
949
950 narg4(dvu)
951
952 C_rmu
953         $1 == 4 ==>
954                 Comment( rmu , $1 );
955                 {
956                         force_alloc_output();
957                         pop_reg_as(reg_o1);
958                         pop_reg_as(reg_o0);
959                         "call   dvu4";
960                         "nop"
961                         free_output();
962                         forced_alloc_reg(reg_o1);
963                         push_reg(reg_o1);
964                 }.
965         default ==>
966                         arg_error( "rmu", $1).
967
968 narg4(rmu)
969
970 C_slu           ==>
971                         Comment( slu , $1 );
972                         C_sli($1).
973
974 narg4(slu)
975
976 C_sru
977         $1 == 4 ==>
978                         {
979                                 reg_t a;
980                                 reg_t b;
981                                 reg_t c;
982
983                                 Comment( sru , $1 );
984                                 b = alloc_reg();
985                                 if ((type_of_tos() == T_cst) &&
986                                         (const13(top_const()))) {
987                                         const_str_t n;
988
989                                         pop_const(n);
990                                         a = pop_reg();
991                                         "srl    $a, $n, $b";
992                                 } else {
993                                         c = pop_reg();
994                                         a = pop_reg();
995                                         "srl    $a, $c, $b";
996                                         free_reg(c);
997                                 }
998                                 free_reg(a);
999                                 push_reg(b);
1000                         }.
1001         default ==>
1002                         arg_error( "sru", $1).
1003
1004 narg4(sru)
1005
1006 /******************************************************************************/
1007 /*                                                                            */
1008 /*              Group 5 : Floating point arithmetic                           */
1009 /*                                                                            */
1010 /******************************************************************************/
1011
1012 C_adf           ==>
1013         {
1014                 Comment( adf, $1);
1015                 push_const($1);
1016                 C_adf_narg();
1017         }.
1018
1019 C_adf_narg      ==>
1020         {       
1021                 reg_t f1;
1022                 reg_t f2;
1023                 reg_t f3;
1024                 int n;
1025
1026                 Comment0( adf_narg);
1027                 if (type_of_tos() == T_cst)
1028                 {
1029                         n= pop_const(NULL);
1030                         if (n == EM_WSIZE)
1031                         {
1032                                 f1= pop_float();
1033                                 f2= pop_float();
1034                                 f3= alloc_float();
1035                                 "fadds  $f2, $f1, $f3";
1036                                 free_reg(f1);
1037                                 free_reg(f2);
1038                                 push_reg(f3);
1039                         }
1040                         else if (n == EM_DSIZE)
1041                         {
1042                                 f1= pop_double(NULL);
1043                                 f2= pop_double(NULL);
1044                                 f3= alloc_double(NULL);
1045                                 "faddd  $f1, $f2, $f3";
1046                                 free_double_reg(f1);
1047                                 free_double_reg(f2);
1048                                 push_double_reg(f3);
1049                         }
1050                         else
1051                                 arg_error ("unimp adf", n);
1052                 }
1053                 else
1054                         not_implemented ("adf_narg");
1055         }.
1056
1057 C_sbf           ==>
1058         {
1059                 Comment( sbf, $1);
1060                 push_const($1);
1061                 C_sbf_narg();
1062         }.
1063
1064 C_sbf_narg      ==>
1065         {       
1066                 reg_t f1;
1067                 reg_t f2;
1068                 reg_t f3;
1069                 int n;
1070
1071                 Comment0( sbf_narg);
1072                 if (type_of_tos() == T_cst)
1073                 {
1074                         n= pop_const(NULL);
1075                         if (n == EM_WSIZE)
1076                         {
1077                                 f1= pop_float();
1078                                 f2= pop_float();
1079                                 f3= alloc_float();
1080                                 "fsubs  $f2, $f1, $f3";
1081                                 free_reg(f1);
1082                                 free_reg(f2);
1083                                 push_reg(f3);
1084                         }
1085                         else if (n == EM_DSIZE)
1086                         {
1087                                 f1= pop_double(NULL);
1088                                 f2= pop_double(NULL);
1089                                 f3= alloc_double(NULL);
1090                                 "fsubd  $f2, $f1, $f3";
1091                                 free_double_reg(f1);
1092                                 free_double_reg(f2);
1093                                 push_double_reg(f3);
1094                         }
1095                         else
1096                                 arg_error ("unimp sbf", n);
1097                 }
1098                 else
1099                         not_implemented ("sbf_narg");
1100         }.
1101
1102 C_mlf           ==>
1103         {
1104                 Comment( mlf, $1);
1105                 push_const($1);
1106                 C_mlf_narg();
1107         }.
1108
1109 C_mlf_narg      ==>
1110         {       
1111                 reg_t f1;
1112                 reg_t f2;
1113                 reg_t f3;
1114                 int n;
1115
1116                 Comment0( mlf_narg);
1117                 if (type_of_tos() == T_cst)
1118                 {
1119                         n= pop_const(NULL);
1120                         if (n == EM_WSIZE)
1121                         {
1122                                 f1= pop_float();
1123                                 f2= pop_float();
1124                                 f3= alloc_float();
1125                                 "fmuls  $f2, $f1, $f3";
1126                                 free_reg(f1);
1127                                 free_reg(f2);
1128                                 push_reg(f3);
1129                         }
1130                         else if (n == EM_DSIZE)
1131                         {
1132                                 f1= pop_double(NULL);
1133                                 f2= pop_double(NULL);
1134                                 f3= alloc_double(NULL);
1135                                 "fmuld  $f2, $f1, $f3";
1136                                 free_double_reg(f1);
1137                                 free_double_reg(f2);
1138                                 push_double_reg(f3);
1139                         }
1140                         else
1141                                 arg_error ("unimp mlf", n);
1142                 }
1143                 else
1144                         not_implemented ("mlf_narg");
1145         }.
1146
1147 C_dvf           ==>
1148         {
1149                 Comment( dvf, $1);
1150                 push_const($1);
1151                 C_dvf_narg();
1152         }.
1153
1154 C_dvf_narg      ==>
1155         {       
1156                 reg_t f1;
1157                 reg_t f2;
1158                 reg_t f3;
1159                 int n;
1160
1161                 Comment0( dvf_narg);
1162                 if (type_of_tos() == T_cst)
1163                 {
1164                         n= pop_const(NULL);
1165                         if (n == EM_WSIZE)
1166                         {
1167                                 f1= pop_float();
1168                                 f2= pop_float();
1169                                 f3= alloc_float();
1170                                 "fdivs  $f2, $f1, $f3";
1171                                 free_reg(f1);
1172                                 free_reg(f2);
1173                                 push_reg(f3);
1174                         }
1175                         else if (n == EM_DSIZE)
1176                         {
1177                                 f1= pop_double(NULL);
1178                                 f2= pop_double(NULL);
1179                                 f3= alloc_double(NULL);
1180                                 "fdivd  $f2, $f1, $f3";
1181                                 free_double_reg(f1);
1182                                 free_double_reg(f2);
1183                                 push_double_reg(f3);
1184                         }
1185                         else
1186                                 arg_error ("unimp dvf", n);
1187                 }
1188                 else
1189                         not_implemented ("dvf_narg");
1190         }.
1191
1192 C_ngf           ==>
1193         {
1194                 Comment( ngf, $1);
1195                 push_const($1);
1196                 C_ngf_narg();
1197         }.
1198
1199 C_ngf_narg      ==>
1200         {       
1201                 reg_t f1;
1202                 reg_t f2;
1203                 int n;
1204
1205                 Comment0( ngf_narg);
1206                 if (type_of_tos() == T_cst)
1207                 {
1208                         n= pop_const(NULL);
1209                         if (n == EM_WSIZE || n == EM_DSIZE)
1210                         {
1211                                 f1= pop_float();
1212                                 f2= alloc_float();
1213                                 "fnegs  $f1, $f2";
1214                                 free_reg(f1);
1215                                 push_reg(f2);
1216                         }
1217                         else
1218                                 arg_error ("unimp ngf", n);
1219                 }
1220                 else
1221                         not_implemented ("ngf_narg");
1222         }.
1223
1224 C_fif           ==>
1225         Comment( fif, $1);
1226         push_const($1);
1227         C_fif_narg().
1228
1229 C_fif_narg      ==>
1230         {
1231                 int n;
1232                 reg_t a;
1233                 reg_t b;
1234                 reg_t c;
1235                 reg_t d;
1236
1237                 Comment0( fif_narg );
1238                 if (type_of_tos() == T_cst)
1239                 {
1240                         n= pop_const(NULL);
1241
1242                         if (n==4)
1243                         {
1244                                 "! unimplemented fif 4";
1245                                 "st     %g0, [%g0]"; /* unimp */
1246                         }
1247                         else if (n==8)
1248                         {
1249                                 flush_cache();
1250                                 "call   fif8";
1251                                 "nop";
1252                         }
1253                         else
1254                                 arg_error ("fif", n);
1255                 }
1256                 else
1257                 {
1258                         a= alloc_reg();
1259                         flush_cache();
1260                         force_alloc_output();
1261                         b= alloc_reg();
1262                         c= alloc_reg();
1263                         d= pop_reg();
1264                         "cmp    8, $d";
1265                         "be     8f";
1266                         "nop";
1267                         "cmp    4, $d";
1268                         "bne    0f";
1269                         "nop";
1270                 "4:";
1271                         "! unimplemented fif 4";
1272                         "st     %g0, [%g0]";
1273                         "b      1f";
1274                 "0:";
1275                         "set    EILLINS, $reg_o0";
1276                         "call   trp";
1277                         "nop";
1278                         "b      1f";
1279                 "8:";
1280                         "call   fif8";
1281                         "nop";
1282                 "1:";
1283                         free_reg(a);
1284                         free_reg(b);
1285                         free_reg(c);
1286                         free_reg(d);
1287                         free_output();
1288                 }
1289         }.
1290
1291
1292 C_fef           ==>
1293         Comment( fef, $1);
1294         push_const($1);
1295         C_fef_narg().
1296
1297 C_fef_narg      ==>
1298         {
1299                 int n;
1300                 reg_t a;
1301                 reg_t b;
1302                 reg_t c;
1303                 reg_t d;
1304                 reg_t e;
1305
1306                 Comment0( fef_narg );
1307                 if (type_of_tos() == T_cst)
1308                 {
1309                         n= pop_const(NULL);
1310
1311                         if (n==4)
1312                         {
1313                                 "! unimplemented fef 4";
1314                                 "st     %g0, [%g0]"; /* unimp */
1315                         }
1316                         else if (n==8)
1317                         {
1318                                 flush_cache();
1319                                 "call   fef8";
1320                                 "nop";
1321                         }
1322                         else
1323                                 arg_error ("fef", n);
1324                 }
1325                 else
1326                 {
1327                         a= alloc_reg();
1328                         flush_cache();
1329                         force_alloc_output();
1330                         b= alloc_reg();
1331                         c= alloc_reg();
1332                         d= pop_reg();
1333                         "cmp    8, $d";
1334                         "be     8f";
1335                         "nop";
1336                         "cmp    4, $d";
1337                         "bne    0f";
1338                         "nop";
1339                 "4:";
1340                         "! unimplemented fef 4";
1341                         "st     %g0, [%g0]";
1342                         "b      1f";
1343                 "0:";
1344                         "set    EILLINS, $reg_o0";
1345                         "call   trp";
1346                         "nop";
1347                         "b      1f";
1348                 "8:";
1349                         "call   fef8";
1350                         "nop";
1351                 "1:";
1352                         free_reg(a);
1353                         free_reg(b);
1354                         free_reg(c);
1355                         free_reg(d);
1356                         free_output();
1357                 }
1358         }.
1359
1360 /******************************************************************************/
1361 /*                                                                            */
1362 /*              Group 6 : Pointer arithmetic                                  */
1363 /*                                                                            */
1364 /******************************************************************************/
1365
1366 C_adp           ==>
1367                         Comment( adp , $1 );
1368                         inc_tos($1).
1369
1370 C_ads
1371         $1 == 4 ==>
1372                         Comment( ads , $1 );
1373                         if ((type_of_tos()) == T_cst) {
1374                                 arith n;
1375
1376                                 n = pop_const(NULL);
1377                                 inc_tos(n);
1378                         } else {
1379                                 reg_t a;
1380                                 reg_t b;
1381                                 reg_t c;
1382
1383                                 a = pop_reg();
1384                                 inc_tos_reg(a);
1385                         }.
1386         default         ==>
1387                                 arg_error( "ads", $1).
1388
1389 narg4(ads)
1390
1391 C_sbs
1392         $1 == 4 ==>
1393                         Comment( sbs , $1 );
1394
1395                         if ((type_of_tos()) == T_cst) {
1396                                 arith n;
1397
1398                                 n = pop_const(NULL);
1399                                 inc_tos(-n);
1400                         } else {
1401                                 reg_t a;
1402                                 reg_t b;
1403                                 reg_t c;
1404
1405                                 a = pop_reg();
1406                                 b = pop_reg();
1407                                 c = alloc_reg();
1408                                 "sub    $b, $a, $c";
1409                                 free_reg(a);
1410                                 free_reg(b);
1411                                 push_reg(c);
1412                         }.
1413         default ==>
1414                         arg_error( "sbs", $1).
1415
1416 narg4(sbs)
1417
1418 /******************************************************************************/
1419 /*                                                                            */
1420 /*              Group 7 : Increment/decrement/zero                            */
1421 /*                                                                            */
1422 /******************************************************************************/
1423
1424 C_inc           ==>
1425                         Comment0( inc  );
1426                         inc_tos(1).
1427
1428 C_inl           ==>
1429                 Comment( inl , $1 );
1430                 {
1431                         reg_t S1;
1432
1433                         if (S1 = find_local($1, NULL)) {
1434                                 change_reg(S1);
1435                                 "inc    1, $S1";
1436                         } else {
1437                                 soft_alloc_reg(reg_lb);
1438                                 push_reg(reg_lb);
1439                                 inc_tos($1);
1440                                 C_loi(4);
1441                                 C_inc();
1442                                 soft_alloc_reg(reg_lb);
1443                                 push_reg(reg_lb);
1444                                 inc_tos($1);
1445                                 C_sti(4);
1446                         }
1447                 }.
1448
1449 C_ine..         ==>
1450                 { 
1451                         char *ename;
1452                         const_str_t evalue;
1453                         reg_t a;
1454                         reg_t b;
1455
1456                         Comment2( ine.. , $1, $2 );
1457                         a= alloc_reg();
1458                         b= alloc_reg();
1459
1460                         ename= $1;
1461                         sprint(evalue, "%d", $2);
1462                         "sethi  %hi($ename+$evalue), $a";
1463                         "ld     [$a+%lo($ename+$evalue)], $b";
1464                         "inc    $b";
1465                         "st     $b, [$a+%lo($ename+$evalue)]"
1466                         free_reg(a);
1467                         free_reg(b);
1468                 }.
1469
1470
1471 C_dec           ==>
1472                         Comment0( dec );
1473                         inc_tos(-1).
1474
1475 C_del           ==>
1476                 Comment( del , $1 );
1477                 {
1478                         reg_t S1;
1479
1480                         if (S1 = find_local($1, NULL)) {
1481                                 change_reg(S1);
1482                                 "dec    1, $S1";
1483                         } else {
1484                                 soft_alloc_reg(reg_lb);
1485                                 push_reg(reg_lb);
1486                                 inc_tos($1);
1487                                 C_loi(4);
1488                                 C_dec();
1489                                 soft_alloc_reg(reg_lb);
1490                                 push_reg(reg_lb);
1491                                 inc_tos($1);
1492                                 C_sti(4);
1493                         }
1494                 }.
1495
1496 C_dee..         ==>
1497                 { 
1498                         char *ename;
1499                         const_str_t evalue;
1500                         reg_t a;
1501                         reg_t b;
1502
1503                         Comment2( dee.. , $1, $2 );
1504                         a= alloc_reg();
1505                         b= alloc_reg();
1506
1507                         ename= $1;
1508                         sprint(evalue, "%d", $2);
1509                         "sethi  %hi($ename+$evalue), $a";
1510                         "ld     [$a+%lo($ename+$evalue)], $b";
1511                         "dec    $b";
1512                         "st     $b, [$a+%lo($ename+$evalue)]"
1513                         free_reg(a);
1514                         free_reg(b);
1515                 }.
1516
1517 C_zrl           ==>
1518                 Comment( zrl , $1 );
1519                 {
1520                         reg_t S1;
1521
1522                         if (S1 = find_local($1, NULL)) {
1523                                 change_reg(S1);
1524                                 "mov    0, $S1";
1525                         } else {
1526                                 push_const(0);
1527                                 soft_alloc_reg(reg_lb);
1528                                 push_reg(reg_lb);
1529                                 inc_tos($1);
1530                                 C_sti(4);
1531                         }
1532                 }.
1533
1534 C_zre..         ==>
1535                 { 
1536                         char *ename;
1537                         const_str_t evalue;
1538                         reg_t a;
1539
1540                         Comment2( zre.. , $1, $2 );
1541                         a= alloc_reg();
1542
1543                         ename= $1;
1544                         sprint(evalue, "%d", $2);
1545                         "sethi  %hi($ename+$evalue), $a";
1546                         "st     %g0, [$a+%lo($ename+$evalue)]"
1547                         free_reg(a);
1548                 }.
1549
1550 C_zrf           ==>
1551                         Comment( zrf , $1 );
1552                         push_const($1);
1553                         C_zrf_narg().
1554
1555 C_zrf_narg      ==>
1556                         Comment0( zrf_narg );
1557                         C_zer_narg().
1558
1559
1560 C_zer           ==>
1561                         Comment( zer, $1);
1562                         push_const($1);
1563                         C_zer_narg().
1564
1565 C_zer_narg      ==>
1566         {
1567                 reg_t a;
1568                 int n;
1569                 const_str_t n_str;
1570
1571                 Comment0( zer_narg);
1572
1573                 if (type_of_tos() == T_cst && top_const() <= 8)
1574                 {
1575                         n= pop_const(n_str);
1576                         if (n == 4)
1577                                 push_const(0);
1578                         else if (n == 8)
1579                         {
1580                                 push_const(0);
1581                                 push_const(0);
1582                         }
1583                         else
1584                                 arg_error ("zer", n);
1585                 }
1586                 else
1587                 {
1588                         a= alloc_reg();
1589                         pop_reg_as(a);
1590                         flush_cache();
1591                         "sub    $reg_sp, $a, $reg_sp";
1592                 "1:"
1593                         "deccc  4, $a";         /* hack */
1594                         "st     %g0, [$reg_sp+$a]";
1595                         "bne    1b";
1596                         "nop";
1597                         free_reg(a);
1598                 }
1599         }.
1600
1601 /******************************************************************************/
1602 /*                                                                            */
1603 /*              Group 8 : Convert                                             */
1604 /*                                                                            */
1605 /******************************************************************************/
1606
1607 /* cii, ciu, cuu, cui are assumed to be called with legal arguments only */
1608
1609 C_cii           ==>
1610         {
1611                 reg_t a;        /* target obj size */
1612                 reg_t b;        /* src obj size */
1613                 int n1;         /* target obj size */
1614                 int n2;         /* src obj size */
1615                 const_str_t n1_str;
1616
1617                 Comment0( cii );
1618                 a= NULL;
1619                 b= NULL;
1620
1621                 if (type_of_tos() != T_cst)
1622                 {
1623                         a= alloc_reg();
1624                         pop_reg_as(a);
1625                         b= pop_reg();
1626                 }
1627                 else
1628                 {
1629                         n1= pop_const(n1_str);
1630                         if (type_of_tos() != T_cst)
1631                         {
1632                                 a= alloc_reg();
1633                                 "set    $n1_str, $a";
1634                                 b= pop_reg();
1635                         }
1636                         else
1637                                 n2= pop_const(NULL);
1638                 }
1639
1640                 if (!a)
1641                 {
1642                         a = pop_reg();
1643                         if (n1 > EM_WSIZE)
1644                                 arg_error ("unimp cii", n1);
1645                         if (n2 > EM_WSIZE)
1646                                 arg_error ("unimp cii", n2);
1647                         if (n2 < EM_WSIZE) {
1648                                 b = alloc_reg();
1649                                 if (n2 == 1)
1650                                 {
1651                                         "sll    $a, 24, $b";
1652                                         "sra    $b, 24, $b";
1653                                 }
1654                                 else if (n2 == 2)
1655                                 {
1656                                         "sll    $a, 16, $b";
1657                                         "sra    $b, 16, $b";
1658                                 }
1659                                 free_reg(a);
1660                                 push_reg(b);
1661                         }
1662                         else
1663                                 push_reg(a);
1664                 } else {
1665                         flush_cache();
1666                         "cmp    $a, $b";
1667                         "ble    4f";
1668                         "nop";                  /* delay slot */
1669                         "cmp    $b, 1";
1670                         "bne    2f";
1671                         "nop";                  /* delay slot */
1672                 "1:";
1673                         "b      3f";
1674                         "ldsb   [$reg_sp+3], $a";       /* delay slot */
1675                 "2:"
1676                         "ldsh   [$reg_sp+2], $a";
1677                 "3:";
1678                         "st     $a, [$reg_sp]";
1679                 "4:";
1680                         free_reg(a);
1681                         free_reg(b);
1682                 }
1683         }.
1684
1685
1686 C_cuu           ==>
1687                         Comment0( cuu  );
1688                         pop_nop(2).
1689
1690 C_ciu           ==>
1691                         Comment0( ciu );
1692                         pop_nop(2).
1693
1694 C_cui           ==>
1695                         Comment0( cui );
1696                         pop_nop(2).
1697
1698 C_cfi           ==>
1699         {
1700                 reg_t a;        /* target (int) size */
1701                 reg_t b;        /* src (float) size */
1702                 reg_t s1;
1703                 reg_t s2;
1704                 reg_t d1;
1705                 reg_t d2;
1706                 int n1;         /* target (int) size */
1707                 int n2;         /* src (float) size */
1708                 const_str_t n1_str;
1709
1710                 Comment0( cfi );
1711                 a= NULL;
1712                 b= NULL;
1713                 if (type_of_tos() != T_cst)
1714                 {
1715                         a= pop_reg();
1716                         b= pop_reg();
1717                 }
1718                 else
1719                 {
1720                         n1= pop_const (n1_str);
1721                         if (type_of_tos() != T_cst)
1722                         {
1723                                 a= alloc_reg();
1724                                 "set    $n1_str, $a";
1725                                 b= pop_reg();
1726                         }
1727                         else
1728                                 n2= pop_const(NULL);
1729                 }
1730
1731                 if (!a)
1732                 {
1733                         if (n1 != EM_WSIZE)
1734                                 arg_error ("unimp cfi", n1);
1735                         if (n2 == EM_WSIZE)
1736                         {
1737                                 s1= pop_float();
1738                                 d1= alloc_float();
1739                                 "fstoi  $s1, $d1";
1740                                 free_reg(s1);
1741                                 push_reg(d1);
1742                         }
1743                         else if (n2 == EM_DSIZE)
1744                         {
1745                                 s1= pop_double(NULL);
1746                                 d1= alloc_float();
1747                                 "fdtoi  $s1, $d1";
1748                                 free_double_reg(s1);
1749                                 push_reg(d1);
1750                         }
1751                         else
1752                                 arg_error ("unimp cfi", n2);
1753                 }
1754                 else
1755                 {
1756
1757                         d1= alloc_float();
1758                         flush_cache();
1759                         force_alloc_output();
1760                         "cmp    $a, 4";
1761                         "bne    0f";
1762                         "nop";
1763                         "cmp    $b, 4";
1764                         "be     4f";
1765                         "nop";
1766                         "cmp    $b, 8";
1767                         "bne    0f";
1768                         "nop";
1769                 "8:";
1770                         "ld     [$reg_sp], %f0";
1771                         "ld     [$reg_sp+STACK_CLICK], %f1";
1772                         "fdtoi  %f0, $d1";
1773                         "b      1f";
1774                         "inc    2*STACK_CLICK, $reg_sp"; /* delay slot */
1775                 "4:";
1776                         "ld     [$reg_sp+2*STACK_CLICK], %f0";
1777                         "fstoi  %f0, $d1";
1778                         "b      1f";
1779                         "inc    STACK_CLICK, $reg_sp"; /* delay slot */
1780                 "0:";
1781                         "set    E_EM_CFI, %o0";
1782                         "call   trp";
1783                         "nop";
1784                 "1:";
1785                         free_reg(a);
1786                         free_reg(b);
1787                         push_reg(d1);
1788                         free_output();
1789                 }
1790         }.
1791
1792 C_cfu           ==>
1793         {
1794                 reg_t a;        /* target (int) size */
1795                 reg_t b;        /* src (float) size */
1796                 int n1;         /* target (int) size */
1797                 int n2;         /* src (float) size */
1798                 const_str_t n1_str;
1799
1800                 Comment0( cfu );
1801                 a= NULL;
1802                 b= NULL;
1803                 if (type_of_tos() != T_cst)
1804                 {
1805                         a= pop_reg();
1806                         b= pop_reg();
1807                 }
1808                 else
1809                 {
1810                         n1= pop_const (n1_str);
1811                         if (type_of_tos() != T_cst)
1812                         {
1813                                 a= alloc_reg();
1814                                 "set    $n1_str, $a";
1815                                 b= pop_reg();
1816                         }
1817                         else
1818                                 n2= pop_const(NULL);
1819                 }
1820
1821                 if (!a)
1822                 {
1823                         if (n1 != EM_WSIZE)
1824                                 arg_error ("unimp cfu", n1);
1825                         force_alloc_output();
1826                         flush_cache();
1827                         if (n2 == EM_WSIZE)
1828                         {
1829                                 "call cfu4";
1830                                 "nop";
1831                         }
1832                         else if (n2 == EM_DSIZE)
1833                         {
1834                                 "call cfu8";
1835                                 "nop";
1836                         }
1837                         else
1838                                 arg_error ("unimp cfu", n2);
1839                         soft_alloc_reg(reg_o0);
1840                         free_output();
1841                         push_reg(reg_o0);
1842                 }
1843                 else
1844                 {
1845                         flush_cache();
1846                         force_alloc_output();
1847                         "cmp    $a, 4";
1848                         "bne    0f";
1849                         "nop";
1850                         "cmp    $b, 4";
1851                         "be     4f";
1852                         "nop";
1853                         "cmp    $b, 8";
1854                         "bne    0f";
1855                         "nop";
1856                 "8:";
1857                         "call   cfu8";
1858                         "nop";
1859                         "b      1f";
1860                 "4:";
1861                         "call   cfu4";
1862                         "nop";
1863                         "b      1f";
1864                 "0:";
1865                         "set    E_EM_CFU, %o0";
1866                         "call   trp";
1867                         "nop";
1868                 "1:";
1869                         free_reg(a);
1870                         free_reg(b);
1871                         soft_alloc_reg(reg_o0);
1872                         free_output();
1873                         push_reg(reg_o0);
1874                 }
1875         }.
1876
1877 C_cff           ==>
1878         {
1879                 reg_t a;        /* target (int) size */
1880                 reg_t b;        /* src (float) size */
1881                 int n1;         /* target (int) size */
1882                 int n2;         /* src (float) size */
1883                 const_str_t n1_str;
1884
1885                 Comment0( cff );
1886                 a= NULL;
1887                 b= NULL;
1888                 if (type_of_tos() != T_cst)
1889                 {
1890                         a= pop_reg();
1891                         b= pop_reg();
1892                 }
1893                 else
1894                 {
1895                         n1= pop_const (n1_str);
1896                         if (type_of_tos() != T_cst)
1897                         {
1898                                 a= alloc_reg();
1899                                 "set    $n1_str, $a";
1900                                 b= pop_reg();
1901                         }
1902                         else
1903                                 n2= pop_const(NULL);
1904                 }
1905
1906                 if (!a)
1907                 {
1908                         if (n1 == EM_WSIZE)
1909                         {
1910                                 if (n2 == EM_DSIZE)
1911                                 {
1912                                         a= pop_double(NULL);
1913                                         b= alloc_float();
1914                                         "fdtos  $a, $b";
1915                                         free_double_reg(a);
1916                                         push_reg(b);
1917                                 } else if (n2 != EM_WSIZE)
1918                                         arg_error ("unimp cff", n2);
1919                         }
1920                         else if (n1 == EM_DSIZE)
1921                         {
1922                                 if (n2 == EM_WSIZE)
1923                                 {
1924                                         a= pop_float();
1925                                         b= alloc_double(NULL);
1926                                         "fstod  $a, $b";
1927                                         free_reg(a);
1928                                         push_double_reg(b);
1929                                 } else if (n2 != EM_DSIZE)
1930                                         arg_error ("unimp cff", n2);
1931                         }
1932                         else
1933                                 arg_error ("unimp cff", n1);
1934                 }
1935                 else
1936                 {
1937
1938                         flush_cache();
1939                         force_alloc_output();
1940                         "cmp    $b, $a";
1941                         "be     1f";
1942                         "nop";          /* delay slot */
1943                         "cmp    $b, 4";
1944                         "be     4f";
1945                         "nop";
1946                         "cmp    $b, 8";
1947                         "be     8f";
1948                         "nop";
1949                 "0:"
1950                         "set    E_EM_CFF, %o0";
1951                         "call   trp";
1952                         "nop";
1953                 "4:";
1954                         "cmp    $a, 8";
1955                         "bne    0b";
1956                         "nop";
1957                         "ld     [$reg_sp], %f0";
1958                         "fstod  %f0, %f2";
1959                         "dec    STACK_CLICK, $reg_sp";
1960                         "st     %f2, [$reg_sp]";
1961                         "st     %f3, [$reg_sp+STACK_CLICK]";
1962                         "b      1f";
1963                         "nop";
1964                 "8:";
1965                         "cmp    $a, 4";
1966                         "bne    0b";
1967                         "nop";
1968                         "ld     [$reg_sp], %f0";
1969                         "ld     [$reg_sp+STACK_CLICK], %f1";
1970                         "fdtos  %f0, %f2";
1971                         "inc    STACK_CLICK, $reg_sp";
1972                         "st     %f2, [$reg_sp]";
1973                 "1:";
1974                         free_reg(a);
1975                         free_reg(b);
1976                         free_output();
1977                 }
1978         }.
1979
1980 C_cif           ==>
1981         {
1982                 reg_t a;        /* target (float) size */
1983                 reg_t b;        /* src (int) size */
1984                 int n1;         /* target (float) size */
1985                 int n2;         /* src (int) size */
1986                 reg_t r1;
1987                 reg_t f1;
1988                 const_str_t n1_str;
1989
1990                 Comment0( cif );
1991                 a= NULL;
1992                 b= NULL;
1993                 if (type_of_tos() != T_cst)
1994                 {
1995                         a= pop_reg();
1996                         b= pop_reg();
1997                 }
1998                 else
1999                 {
2000                         n1= pop_const (n1_str);
2001                         if (type_of_tos() != T_cst)
2002                         {
2003                                 a= alloc_reg();
2004                                 "set    $n1_str, $a";
2005                                 b= pop_reg();
2006                         }
2007                         else
2008                                 n2= pop_const(NULL);
2009                 }
2010
2011                 if (!a)
2012                 {
2013                         if (n2 != EM_WSIZE)
2014                                 arg_error ("unimp cif", n2);
2015                         else
2016                         {
2017                                 if (n1 == EM_WSIZE)
2018                                 {
2019                                         r1= pop_float();
2020                                         f1= alloc_float();
2021                                         "fitos  $r1, $f1";
2022                                         free_reg(r1);
2023                                         push_reg(f1);
2024
2025                                 }
2026                                 else if (n1 == EM_DSIZE)
2027                                 {
2028                                         r1= pop_float();
2029                                         f1= alloc_double(NULL);
2030                                         "fitod  $r1, $f1";
2031                                         free_reg(r1);
2032                                         push_double_reg(f1);
2033                                 }
2034                                 else
2035                                         arg_error ("unimp cif", n1);
2036                         }
2037                 }
2038                 else
2039                 {
2040                         flush_cache();
2041                         force_alloc_output();
2042                         "cmp    $a, 4";
2043                         "be     4f";
2044                         "nop";          /* delay slot */
2045                         "cmp    $a, 8";
2046                         "be     8f";
2047                         "nop";          /* delay slot */
2048                 "1:"
2049                         "set    E_EM_CUF, %o0";
2050                         "call   trp";
2051                         "nop";
2052                 "4:";
2053                         "cmp    $b, 4";
2054                         "bne    1b";
2055                         "nop";          /* delay slot */
2056                         "ld     [$reg_sp], %f0";
2057                         "fitos  %f0, %f1";
2058                         "b      0f";
2059                         "st     %f1, [$reg_sp]";        /* delay slot */
2060                 "8:";
2061                         "dec    STACK_CLICK, $reg_sp";
2062                         "cmp    $b, 4";
2063                         "bne    1b";
2064                         "nop";          /* delay slot */
2065                         "ld     [$reg_sp+STACK_CLICK], %f0";
2066                         "fitod  %f0, %f2";
2067                         "st     %f2, [$reg_sp]";
2068                         "b      0f";
2069                         "st     %f3, [$reg_sp+STACK_CLICK]"; /* delay slot */
2070                 "0:";
2071                         free_reg(a);
2072                         free_reg(b);
2073                         free_output();
2074                 }
2075         }.
2076
2077
2078 C_cuf           ==>
2079         {
2080                 reg_t a;        /* target (float) size */
2081                 reg_t b;        /* src (int) size */
2082                 reg_t c;
2083                 reg_t fs1;
2084                 reg_t fs2;
2085                 reg_t fd1;
2086                 reg_t fd2;
2087                 int n1;         /* target (float) size */
2088                 int n2;         /* src (int) size */
2089                 const_str_t n1_str;
2090
2091                 Comment0( cuf );
2092                 a= NULL;
2093                 b= NULL;
2094                 if (type_of_tos() != T_cst)
2095                 {
2096                         a= pop_reg();
2097                         b= pop_reg();
2098                 }
2099                 else
2100                 {
2101                         n1= pop_const (n1_str);
2102                         if (type_of_tos() != T_cst)
2103                         {
2104                                 a= alloc_reg();
2105                                 "set    $n1_str, $a";
2106                                 b= pop_reg();
2107                         }
2108                         else
2109                                 n2= pop_const(NULL);
2110                 }
2111
2112                 if (!a)
2113                 {
2114                         if (n2 != EM_WSIZE)
2115                                 arg_error ("unimp cuf", n2);
2116                         else
2117                         {
2118                                 if (n1 == EM_WSIZE)
2119                                 {
2120                                         fs1= pop_float();
2121                                         fs2= alloc_float();
2122                                         a= alloc_reg();
2123                                         "fitos  $fs1, $fs2";
2124                                         "sethi  %hi(Fs0), $a";
2125                                         "ld     [$a+%lo(Fs0)], $fs1";
2126                                         "fcmpes $fs2, $fs1";
2127                                         "nop";
2128                                         "fbge   0f";
2129                                         "nop";
2130                                         "sethi  %hi(Fs80000000), $a";
2131                                         "ld     [$a+%lo(Fs80000000)], $fs1";
2132                                         "fadds  $fs1, $fs2, $fs2";
2133                                 "0:";
2134                                         push_reg(fs2);
2135                                         free_reg(fs1);
2136                                         free_reg(a);
2137                                 }
2138                                 else if (n1 == EM_DSIZE)
2139                                 {
2140                                         fs1= pop_float();
2141                                         fd1= alloc_double(NULL);
2142                                         fd2= alloc_double(NULL);
2143                                         a= alloc_reg();
2144                                         "fitod  $fs1, $fd2";
2145                                         "sethi  %hi(Fd0), $a";
2146                                         "ldd    [$a+%lo(Fd0)], $fd1";
2147                                         "fcmped $fd2, $fd1";
2148                                         "nop";
2149                                         "fbge   0f";
2150                                         "nop";
2151                                         "sethi  %hi(Fd80000000), $a";
2152                                         "ldd    [$a+%lo(Fd80000000)], $fd1";
2153                                         "faddd  $fd1, $fd2, $fd2";
2154                                 "0:";
2155                                         free_reg(fs1);
2156                                         free_double_reg(fd1);
2157                                         push_double_reg(fd2);
2158                                         free_reg(a);
2159                                 }
2160                                 else
2161                                         arg_error ("unimp cuf", n1);
2162                         }
2163                 }
2164                 else
2165                 {
2166 #if 0
2167                         flush_cache();
2168
2169                         "cmp    $a, 4";
2170                         "be     4f";
2171                         "nop";          /* delay slot */
2172                         "cmp    $a, 8";
2173                         "be     8f";
2174                         "nop";          /* delay slot */
2175                 "1:"
2176                         "set    E_EM_CUF, %o0";
2177                         "set    fatal, %g1";
2178                         "jmp    %g1";
2179                         "nop";
2180                 "4:";
2181                         "cmp    $b, 4";
2182                         "bne    1b";
2183                         "nop";          /* delay slot */
2184                         "ld     [$reg_sp], $c";
2185                         "tst    $c";
2186                         "bl     5f";
2187                         "nop";          /* delay slot */
2188                         "ld     [$reg_sp], %f0";
2189                         "fitos  %f0, %f1";
2190                         "b      0f";
2191                         "st     %f1, [$reg_sp]";        /* delay slot */
2192                 "5:";
2193                         "set    MAX_INT, $b";
2194                         "sub    $c, $b, $a";
2195                         "st     $a, [$reg_sp]";
2196                         "ld     [$reg_sp], %f0";
2197                         "st     $b, [$reg_sp]";
2198                         "ld     [$reg_sp], %f1";
2199                         "fitos  %f0, %f2";
2200                         "fitos  %f1, %f3";
2201                         "fadds  %f2, %f3, %f0";
2202                         "b      0f";
2203                         "st     %f0, [$reg_sp]";                /* delay slot */
2204                 "8:";
2205                         "dec    STACK_CLICK, $reg_sp";
2206                         "cmp    $b, 4";
2207                         "bne    1b";
2208                         "nop";          /* delay slot */
2209                         "ld     [$reg_sp+STACK_CLICK], $c";
2210                         "tst    $c";
2211                         "bl     9f";
2212                         "nop";          /* delay slot */
2213                         "ld     [$reg_sp+STACK_CLICK], %f0";
2214                         "fitod  %f0, %f2";
2215                         "st     %f2, [$reg_sp]";
2216                         "b      0f";
2217                         "st     %f3, [$reg_sp+STACK_CLICK]";    /* delay slot */
2218                 "9:";
2219                         "set    MAX_INT, $b";
2220                         "sub    $c, $b, $a";
2221                         "st     $a, [$reg_sp+STACK_CLICK]";
2222                         "ld     [$reg_sp+STACK_CLICK], %f0";
2223                         "st     $b, [$reg_sp+STACK_CLICK]";
2224                         "ld     [$reg_sp+STACK_CLICK], %f1";
2225                         "fitod  %f0, %f2";
2226                         "fitod  %f1, %f4";
2227                         "fadds  %f2, %f4, %f0";
2228                         "st     %f0, [$reg_sp]";
2229                         "b      0f";
2230                         "st     %f1, [$reg_sp+STACK_CLICK]";    /* delay slot */
2231                 "0:";
2232                         free_reg(a);
2233                         free_reg(b);
2234                         free_reg(c);
2235 #else
2236         not_implemented ("cuf");
2237 #endif
2238                 }
2239         }.
2240 /******************************************************************************/
2241 /*                                                                            */
2242 /*              Group 9 : Logical                                             */
2243 /*                                                                            */
2244 /******************************************************************************/
2245
2246 C_and           ==>
2247         Comment( and, $1);
2248         push_const($1);
2249         C_and_narg().
2250
2251 C_and_narg      ==>
2252         {
2253                 reg_t a;
2254                 reg_t b;
2255                 reg_t c;
2256                 reg_t d;
2257                 reg_t e;
2258                 reg_t f;
2259                 const_str_t a_cst_str;
2260                 const_str_t b_cst_str;
2261                 const_str_t c_cst_str;
2262                 const_str_t d_cst_str;
2263                 int n;
2264                 const_str_t n_str;
2265
2266                 Comment0( and_narg );
2267                 if (type_of_tos() == T_cst)
2268                 {
2269                         n= pop_const(n_str);
2270                         if (n == EM_WSIZE)
2271                         {
2272                                 if (type_of_tos() == T_cst && const13(top_const()))
2273                                 {
2274                                         a= NULL;
2275                                         pop_const (a_cst_str);
2276                                 }
2277                                 else
2278                                         a= pop_reg();
2279                                 if (type_of_tos() == T_cst && const13(top_const()))
2280                                 {
2281                                         b= NULL;
2282                                         pop_const (b_cst_str);
2283                                 }
2284                                 else
2285                                         b= pop_reg();
2286                                 if (!a && !b)
2287                                 {
2288                                         a= alloc_reg();
2289                                         "mov    $a_cst_str, $a";        
2290                                 }
2291                                 c= alloc_reg();
2292                                 if (a)
2293                                         if (b)
2294                                                 "and    $a, $b, $c";
2295                                         else
2296                                                 "and    $a, $b_cst_str, $c";
2297                                 else
2298                                         "and    $b, $a_cst_str, $c";
2299                                 free_reg(a);
2300                                 free_reg(b);
2301                                 push_reg(c);
2302                         }
2303                         else if (n == EM_DSIZE)
2304                         {
2305                                 if (type_of_tos() == T_cst && const13(top_const()))
2306                                 {
2307                                         a= NULL;
2308                                         pop_const (a_cst_str);
2309                                 }
2310                                 else
2311                                         a= pop_reg();
2312                                 if (type_of_tos() == T_cst && const13(top_const()))
2313                                 {
2314                                         b= NULL;
2315                                         pop_const (b_cst_str);
2316                                 }
2317                                 else
2318                                         b= pop_reg();
2319                                 if (type_of_tos() == T_cst && const13(top_const()))
2320                                 {
2321                                         c= NULL;
2322                                         pop_const (c_cst_str);
2323                                 }
2324                                 else
2325                                         c= pop_reg();
2326                                 if (type_of_tos() == T_cst && const13(top_const()))
2327                                 {
2328                                         d= NULL;
2329                                         pop_const (d_cst_str);
2330                                 }
2331                                 else
2332                                         d= pop_reg();
2333                                 if (!b && !d)
2334                                 {
2335                                         b= alloc_reg();
2336                                         "mov    $b_cst_str, $b";        
2337                                 }
2338                                 e= alloc_reg();
2339                                 if (b)
2340                                         if (d)
2341                                                 "and    $b, $d, $e";
2342                                         else
2343                                                 "and    $b, $d_cst_str, $e";
2344                                 else
2345                                         "and    $d, $b_cst_str, $e";
2346                                 free_reg(b);
2347                                 free_reg(d);
2348                                 push_reg(e);
2349                                 if (!a && !c)
2350                                 {
2351                                         a= alloc_reg();
2352                                         "mov    $a_cst_str, $a";        
2353                                 }
2354                                 e= alloc_reg();
2355                                 if (a)
2356                                         if (c)
2357                                                 "and    $a, $c, $e";
2358                                         else
2359                                                 "and    $a, $c_cst_str, $e";
2360                                 else
2361                                         "and    $c, $a_cst_str, $e";
2362                                 free_reg(a);
2363                                 free_reg(c);
2364                                 push_reg(e);
2365                         }
2366                         else if (!(n % EM_WSIZE))
2367                         {
2368                                 a= alloc_reg();
2369                                 b= alloc_reg();
2370                                 c= alloc_reg();
2371                                 d= alloc_reg();
2372                                 e= alloc_reg();
2373                                 f= alloc_reg();
2374                                 flush_cache();
2375
2376                                 "set    $n_str, $a";
2377                                 "add    $reg_sp, $a, $b";
2378                                 "mov    $a, $c";
2379                         "1:";
2380                                 "deccc  4, $c";
2381                                 "ld     [$reg_sp+$c], $d";
2382                                 "ld     [$b+$c], $e";
2383                                 "and    $d, $e, $f";
2384                                 "bnz    1b";
2385                                 "st     $f, [$b+$c]";   /* delay slot */
2386                                 "add    $reg_sp, $a, $reg_sp";
2387                                 free_reg(a);
2388                                 free_reg(b);
2389                                 free_reg(c);
2390                                 free_reg(d);
2391                                 free_reg(e);
2392                                 free_reg(f);
2393                         }
2394                         else
2395                                 arg_error ("unimp and", n);
2396                 }
2397                 else
2398                 {
2399                         a= pop_reg();
2400                         b= alloc_reg();
2401                         c= alloc_reg();
2402                         d= alloc_reg();
2403                         e= alloc_reg();
2404                         f= alloc_reg();
2405                         flush_cache();
2406
2407                         "add    $reg_sp, $a, $b";
2408                         "mov    $a, $c";
2409                 "1:";
2410                         "deccc  4, $c";
2411                         "ld     [$reg_sp+$c], $d";
2412                         "ld     [$b+$c], $e";
2413                         "and    $d, $e, $f";
2414                         "bnz    1b";
2415                         "st     $f, [$b+$c]";   /* delay slot */
2416                         "add    $reg_sp, $a, $reg_sp";
2417                         free_reg(a);
2418                         free_reg(b);
2419                         free_reg(c);
2420                         free_reg(d);
2421                         free_reg(e);
2422                         free_reg(f);
2423                         
2424                 }
2425         }.
2426
2427 C_ior           ==>
2428         Comment( ior, $1);
2429         push_const($1);
2430         C_ior_narg().
2431
2432 C_ior_narg      ==>
2433         {
2434                 reg_t a;
2435                 reg_t b;
2436                 reg_t c;
2437                 reg_t d;
2438                 reg_t e;
2439                 reg_t f;
2440                 const_str_t a_cst_str;
2441                 const_str_t b_cst_str;
2442                 const_str_t c_cst_str;
2443                 const_str_t d_cst_str;
2444                 int n;
2445                 const_str_t n_str;
2446
2447                 Comment0( ior_narg );
2448                 if (type_of_tos() == T_cst)
2449                 {
2450                         n= pop_const(n_str);
2451                         if (n == EM_WSIZE)
2452                         {
2453                                 if (type_of_tos() == T_cst && const13(top_const()))
2454                                 {
2455                                         a= NULL;
2456                                         pop_const (a_cst_str);
2457                                 }
2458                                 else
2459                                         a= pop_reg();
2460                                 if (type_of_tos() == T_cst && const13(top_const()))
2461                                 {
2462                                         b= NULL;
2463                                         pop_const (b_cst_str);
2464                                 }
2465                                 else
2466                                         b= pop_reg();
2467                                 if (!a && !b)
2468                                 {
2469                                         a= alloc_reg();
2470                                         "mov    $a_cst_str, $a";        
2471                                 }
2472                                 c= alloc_reg();
2473                                 if (a)
2474                                         if (b)
2475                                                 "or     $a, $b, $c";
2476                                         else
2477                                                 "or     $a, $b_cst_str, $c";
2478                                 else
2479                                         "or     $b, $a_cst_str, $c";
2480                                 free_reg(a);
2481                                 free_reg(b);
2482                                 push_reg(c);
2483                         }
2484                         else if (n == EM_DSIZE)
2485                         {
2486                                 if (type_of_tos() == T_cst && const13(top_const()))
2487                                 {
2488                                         a= NULL;
2489                                         pop_const (a_cst_str);
2490                                 }
2491                                 else
2492                                         a= pop_reg();
2493                                 if (type_of_tos() == T_cst && const13(top_const()))
2494                                 {
2495                                         b= NULL;
2496                                         pop_const (b_cst_str);
2497                                 }
2498                                 else
2499                                         b= pop_reg();
2500                                 if (type_of_tos() == T_cst && const13(top_const()))
2501                                 {
2502                                         c= NULL;
2503                                         pop_const (c_cst_str);
2504                                 }
2505                                 else
2506                                         c= pop_reg();
2507                                 if (type_of_tos() == T_cst && const13(top_const()))
2508                                 {
2509                                         d= NULL;
2510                                         pop_const (d_cst_str);
2511                                 }
2512                                 else
2513                                         d= pop_reg();
2514                                 if (!b && !d)
2515                                 {
2516                                         b= alloc_reg();
2517                                         "mov    $b_cst_str, $b";        
2518                                 }
2519                                 e= alloc_reg();
2520                                 if (b)
2521                                         if (d)
2522                                                 "or     $b, $d, $e";
2523                                         else
2524                                                 "or     $b, $d_cst_str, $e";
2525                                 else
2526                                         "or     $d, $b_cst_str, $e";
2527                                 free_reg(b);
2528                                 free_reg(d);
2529                                 push_reg(e);
2530                                 if (!a && !c)
2531                                 {
2532                                         a= alloc_reg();
2533                                         "mov    $a_cst_str, $a";        
2534                                 }
2535                                 e= alloc_reg();
2536                                 if (a)
2537                                         if (c)
2538                                                 "or     $a, $c, $e";
2539                                         else
2540                                                 "or     $a, $c_cst_str, $e";
2541                                 else
2542                                         "or     $c, $a_cst_str, $e";
2543                                 free_reg(a);
2544                                 free_reg(c);
2545                                 push_reg(e);
2546                         }
2547                         else if (!(n % EM_WSIZE))
2548                         {
2549                                 a= alloc_reg();
2550                                 b= alloc_reg();
2551                                 c= alloc_reg();
2552                                 d= alloc_reg();
2553                                 e= alloc_reg();
2554                                 f= alloc_reg();
2555                                 flush_cache();
2556
2557                                 "set    $n_str, $a";
2558                                 "add    $reg_sp, $a, $b";
2559                                 "mov    $a, $c";
2560                         "1:";
2561                                 "deccc  4, $c";
2562                                 "ld     [$reg_sp+$c], $d";
2563                                 "ld     [$b+$c], $e";
2564                                 "or     $d, $e, $f";
2565                                 "bnz    1b";
2566                                 "st     $f, [$b+$c]";   /* delay slot */
2567                                 "add    $reg_sp, $a, $reg_sp";
2568                                 free_reg(a);
2569                                 free_reg(b);
2570                                 free_reg(c);
2571                                 free_reg(d);
2572                                 free_reg(e);
2573                                 free_reg(f);
2574                         }
2575                         else
2576                                 arg_error ("unimp ior", n);
2577                 }
2578                 else
2579                 {
2580                         a= pop_reg();
2581                         b= alloc_reg();
2582                         c= alloc_reg();
2583                         d= alloc_reg();
2584                         e= alloc_reg();
2585                         f= alloc_reg();
2586                         flush_cache();
2587
2588                         "add    $reg_sp, $a, $b";
2589                         "mov    $a, $c";
2590                 "1:";
2591                         "deccc  4, $c";
2592                         "ld     [$reg_sp+$c], $d";
2593                         "ld     [$b+$c], $e";
2594                         "or     $d, $e, $f";
2595                         "bnz    1b";
2596                         "st     $f, [$b+$c]";   /* delay slot */
2597                         "add    $reg_sp, $a, $reg_sp";
2598                         free_reg(a);
2599                         free_reg(b);
2600                         free_reg(c);
2601                         free_reg(d);
2602                         free_reg(e);
2603                         free_reg(f);
2604                 }
2605         }.
2606
2607
2608
2609 C_xor           ==>
2610         Comment( xor, $1);
2611         push_const($1);
2612         C_xor_narg().
2613
2614 C_xor_narg      ==>
2615         {
2616                 reg_t a;
2617                 reg_t b;
2618                 reg_t c;
2619                 reg_t d;
2620                 reg_t e;
2621                 reg_t f;
2622                 const_str_t a_cst_str;
2623                 const_str_t b_cst_str;
2624                 const_str_t c_cst_str;
2625                 const_str_t d_cst_str;
2626                 int n;
2627                 const_str_t n_str;
2628
2629                 Comment0( xor_narg );
2630                 if (type_of_tos() == T_cst)
2631                 {
2632                         n= pop_const(n_str);
2633                         if (n == EM_WSIZE)
2634                         {
2635                                 if (type_of_tos() == T_cst && const13(top_const()))
2636                                 {
2637                                         a= NULL;
2638                                         pop_const (a_cst_str);
2639                                 }
2640                                 else
2641                                         a= pop_reg();
2642                                 if (type_of_tos() == T_cst && const13(top_const()))
2643                                 {
2644                                         b= NULL;
2645                                         pop_const (b_cst_str);
2646                                 }
2647                                 else
2648                                         b= pop_reg();
2649                                 if (!a && !b)
2650                                 {
2651                                         a= alloc_reg();
2652                                         "mov    $a_cst_str, $a";        
2653                                 }
2654                                 c= alloc_reg();
2655                                 if (a)
2656                                         if (b)
2657                                                 "xor    $a, $b, $c";
2658                                         else
2659                                                 "xor    $a, $b_cst_str, $c";
2660                                 else
2661                                         "xor    $b, $a_cst_str, $c";
2662                                 free_reg(a);
2663                                 free_reg(b);
2664                                 push_reg(c);
2665                         }
2666                         else if (n == EM_DSIZE)
2667                         {
2668                                 if (type_of_tos() == T_cst && const13(top_const()))
2669                                 {
2670                                         a= NULL;
2671                                         pop_const (a_cst_str);
2672                                 }
2673                                 else
2674                                         a= pop_reg();
2675                                 if (type_of_tos() == T_cst && const13(top_const()))
2676                                 {
2677                                         b= NULL;
2678                                         pop_const (b_cst_str);
2679                                 }
2680                                 else
2681                                         b= pop_reg();
2682                                 if (type_of_tos() == T_cst && const13(top_const()))
2683                                 {
2684                                         c= NULL;
2685                                         pop_const (c_cst_str);
2686                                 }
2687                                 else
2688                                         c= pop_reg();
2689                                 if (type_of_tos() == T_cst && const13(top_const()))
2690                                 {
2691                                         d= NULL;
2692                                         pop_const (d_cst_str);
2693                                 }
2694                                 else
2695                                         d= pop_reg();
2696                                 if (!b && !d)
2697                                 {
2698                                         b= alloc_reg();
2699                                         "mov    $b_cst_str, $b";        
2700                                 }
2701                                 e= alloc_reg();
2702                                 if (b)
2703                                         if (d)
2704                                                 "xor    $b, $d, $e";
2705                                         else
2706                                                 "xor    $b, $d_cst_str, $e";
2707                                 else
2708                                         "xor    $d, $b_cst_str, $e";
2709                                 free_reg(b);
2710                                 free_reg(d);
2711                                 push_reg(e);
2712                                 if (!a && !c)
2713                                 {
2714                                         a= alloc_reg();
2715                                         "mov    $a_cst_str, $a";        
2716                                 }
2717                                 e= alloc_reg();
2718                                 if (a)
2719                                         if (c)
2720                                                 "xor    $a, $c, $e";
2721                                         else
2722                                                 "xor    $a, $c_cst_str, $e";
2723                                 else
2724                                         "xor    $c, $a_cst_str, $e";
2725                                 free_reg(a);
2726                                 free_reg(c);
2727                                 push_reg(e);
2728                         }
2729                         else if (!(n % EM_WSIZE))
2730                         {
2731                                 a= alloc_reg();
2732                                 b= alloc_reg();
2733                                 c= alloc_reg();
2734                                 d= alloc_reg();
2735                                 e= alloc_reg();
2736                                 f= alloc_reg();
2737                                 flush_cache();
2738
2739                                 "set    $n_str, $a";
2740                                 "add    $reg_sp, $a, $b";
2741                                 "mov    $a, $c";
2742                         "1:";
2743                                 "deccc  4, $c";
2744                                 "ld     [$reg_sp+$c], $d";
2745                                 "ld     [$b+$c], $e";
2746                                 "xor    $d, $e, $f";
2747                                 "bnz    1b";
2748                                 "st     $f, [$b+$c]";   /* delay slot */
2749                                 "add    $reg_sp, $a, $reg_sp";
2750                                 free_reg(a);
2751                                 free_reg(b);
2752                                 free_reg(c);
2753                                 free_reg(d);
2754                                 free_reg(e);
2755                                 free_reg(f);
2756                         }
2757                         else
2758                                 arg_error ("unimp xor", n);
2759                 }
2760                 else
2761                 {
2762                         a= pop_reg();
2763                         b= alloc_reg();
2764                         c= alloc_reg();
2765                         d= alloc_reg();
2766                         e= alloc_reg();
2767                         f= alloc_reg();
2768                         flush_cache();
2769
2770                         "add    $reg_sp, $a, $b";
2771                         "mov    $a, $c";
2772                 "1:";
2773                         "deccc  4, $c";
2774                         "ld     [$reg_sp+$c], $d";
2775                         "ld     [$b+$c], $e";
2776                         "xor    $d, $e, $f";
2777                         "bnz    1b";
2778                         "st     $f, [$b+$c]";   /* delay slot */
2779                         "add    $reg_sp, $a, $reg_sp";
2780                         free_reg(a);
2781                         free_reg(b);
2782                         free_reg(c);
2783                         free_reg(d);
2784                         free_reg(e);
2785                         free_reg(f);
2786                 }
2787         }.
2788
2789
2790
2791 C_com           ==>
2792         Comment( com, $1);
2793         push_const($1);
2794         C_com_narg().
2795
2796 C_com_narg      ==>
2797         {
2798                 reg_t a;
2799                 reg_t b;
2800                 reg_t c;
2801                 reg_t d;
2802                 int n;
2803                 int i;
2804                 const_str_t i_str;
2805
2806                 Comment0( com_narg );
2807                 if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL)
2808                 {
2809                         n= pop_const(NULL);
2810                         if (n == 4)
2811                         {
2812                                 a= pop_reg();
2813                                 b= alloc_reg();
2814                                 "not    $a, $b";
2815                                 free_reg(a);
2816                                 push_reg(b);
2817                         }
2818                         else if (n == 8)
2819                         {
2820                                 a= pop_reg();
2821                                 b= pop_reg();
2822                                 c= alloc_reg();
2823                                 d= alloc_reg();
2824                                 "not    $a, $c";
2825                                 "not    $b, $d";
2826                                 push_reg(d);
2827                                 push_reg(c);
2828                                 free_reg(b);
2829                                 free_reg(a);
2830                         }
2831                         else if (n>0 && !(n % 4))
2832                         {
2833                                 flush_cache();
2834                                 a= alloc_reg();
2835                                 b= alloc_reg();
2836                                 for (i= 0; i< n; i += 4)
2837                                 {
2838                                         sprint(i_str, "%d", i);
2839                                         "ld     [$reg_sp+$i_str], $a";
2840                                         "not    $a, $b";
2841                                         "st     $b, [$reg_sp+$i_str]";
2842                                 }
2843                                 free_reg(b);
2844                                 free_reg(a);
2845                         }
2846                         else
2847                                 arg_error ("com", n);
2848                 }
2849                 else
2850                 {
2851                         a= alloc_reg();
2852                         pop_reg_as(a);
2853                         b= alloc_reg();
2854                         c= alloc_reg();
2855                         flush_cache();
2856                 "1:";
2857                         "deccc  4, $a";
2858                         "ld     [$reg_sp+$a], $b";
2859                         "not    $a, $c";
2860                         "bnz    1b";
2861                         "st     $c, [$reg_sp+$a]";
2862                         free_reg(a);
2863                         free_reg(b);
2864                         free_reg(c);
2865                 }
2866         }.
2867
2868 C_rol
2869         $1 == 4         ==>
2870         {
2871                 reg_t a;
2872                 reg_t b;
2873                 reg_t c;
2874                 reg_t d;
2875                 int n;
2876                 const_str_t n_str;
2877
2878                 Comment( rol, $1);
2879
2880                 if (type_of_tos() == T_cst)
2881                 {
2882                         n= pop_const(NULL);
2883                         if (n<0)
2884                                 arg_error("rol 4:", n);
2885                         else
2886                         {
2887                                 n= n % 32;
2888                                 if (n)
2889                                 {
2890                                         a= pop_reg();
2891                                         b= alloc_reg();
2892                                         c= alloc_reg();
2893                                         sprint(n_str, "%d", n);
2894                                         "sll    $a, $n_str, $b";
2895                                         sprint(n_str, "%d", 32-n);
2896                                         "srl    $a, $n_str, $c";
2897                                         "or     $b, $c, $c";
2898                                         free_reg(a);
2899                                         free_reg(b);
2900                                         push_reg(c);
2901                                 }
2902                         }
2903                 }
2904                 else
2905                 {
2906                         a= pop_reg();
2907                         b= pop_reg();
2908                         c= alloc_reg();
2909                         d= alloc_reg();
2910                         "and    $a, 31, $c";
2911                         "mov    32, $d";
2912                         "sub    $d, $c, $d";
2913                         "sll    $b, $c, $c";
2914                         "srl    $b, $d, $d";
2915                         "or     $c, $d, $d";
2916                         free_reg(a);
2917                         free_reg(b);
2918                         free_reg(c);
2919                         push_reg(d);
2920                 }
2921         }.
2922         default         ==>
2923                                 arg_error( "rol", $1).
2924
2925 narg4(rol)
2926
2927 C_ror
2928         $1 == 4         ==>
2929         {
2930                 reg_t a;
2931                 reg_t b;
2932                 reg_t c;
2933                 reg_t d;
2934                 int n;
2935                 const_str_t n_str;
2936
2937                 Comment( ror, $1);
2938
2939                 if (type_of_tos() == T_cst)
2940                 {
2941                         n= pop_const(NULL);
2942                         if (n<0)
2943                                 arg_error("ror 4:", n);
2944                         else
2945                         {
2946                                 n= n % 32;
2947                                 if (n)
2948                                 {
2949                                         a= pop_reg();
2950                                         b= alloc_reg();
2951                                         c= alloc_reg();
2952                                         sprint(n_str, "%d", n);
2953                                         "srl    $a, $n_str, $b";
2954                                         sprint(n_str, "%d", 32-n);
2955                                         "sll    $a, $n_str, $c";
2956                                         "or     $b, $c, $c";
2957                                         free_reg(a);
2958                                         free_reg(b);
2959                                         push_reg(c);
2960                                 }
2961                         }
2962                 }
2963                 else
2964                 {
2965                         a= pop_reg();
2966                         b= pop_reg();
2967                         c= alloc_reg();
2968                         d= alloc_reg();
2969                         "and    $a, 31, $c";
2970                         "mov    32, $d";
2971                         "sub    $d, $c, $d";
2972                         "srl    $b, $c, $c";
2973                         "sll    $b, $d, $d";
2974                         "or     $c, $d, $d";
2975                         free_reg(a);
2976                         free_reg(b);
2977                         free_reg(c);
2978                         push_reg(d);
2979                 }
2980         }.
2981         default         ==>
2982                                 arg_error( "ror", $1).
2983
2984 narg4(ror)
2985
2986 /******************************************************************************/
2987 /*                                                                            */
2988 /*              Group 10 : Sets                                               */
2989 /*                                                                            */
2990 /******************************************************************************/
2991
2992 C_inn           ==>
2993         Comment( inn, $1);
2994         push_const($1);
2995         C_inn_narg().
2996
2997 C_inn_narg      ==>
2998         {
2999                 reg_t a;
3000                 reg_t b;
3001                 reg_t c;
3002                 reg_t d;
3003                 int i;
3004                 int n;
3005                 const_str_t i_str;
3006                 const_str_t n_str;
3007
3008                 Comment0(inn_narg);
3009                 if (type_of_tos() == T_cst && const13(top_const()))
3010                 {
3011                         n= pop_const(n_str);
3012                         if (n == EM_WSIZE)
3013                         {
3014                                 if (type_of_tos() == T_cst)
3015                                 {
3016                                         i= pop_const (i_str);
3017                                         if (i >= n*8)
3018                                                 push_const(0);
3019                                         else
3020                                         {
3021                                                 a= pop_reg();
3022                                                 b= alloc_reg();
3023                                                 "srl    $a, $i_str, $b";
3024                                                 "and    $b, 1, $b";
3025                                                 free_reg(a);
3026                                                 push_reg(b);
3027                                         }
3028                                 }
3029                                 else
3030                                 {
3031                                         a= pop_reg();
3032                                         b= pop_reg();
3033                                         c= alloc_reg();
3034                                         "srl    $b, $a, $c";
3035                                         "and    $c, 1, $c";
3036                                         push_reg(c);
3037                                         free_reg(b);
3038                                         free_reg(a);
3039                                 }
3040                         }
3041                         else if (n == 2*EM_WSIZE)
3042                         {
3043                                 if (type_of_tos() == T_cst)
3044                                 {
3045                                         i= pop_const (i_str);
3046                                         if (i >= n*8)
3047                                                 push_const(0);
3048                                         else
3049                                         {
3050                                                 if (i>= EM_WSIZE*8)
3051                                                 {
3052                                                         i -= EM_WSIZE*8;
3053                                                         pop_nop(1);
3054                                                         a= pop_reg();
3055                                                 }
3056                                                 else
3057                                                 {
3058                                                         a= pop_reg();
3059                                                         pop_nop(1);
3060                                                 }
3061                                                 b= alloc_reg();
3062                                                 c= alloc_reg();
3063                                                 "srl    $a, $i_str, $b";
3064                                                 "and    $b, 1, $c";
3065                                                 free_reg(a);
3066                                                 free_reg(b);
3067                                                 push_reg(c);
3068                                         }
3069                                 }
3070                                 else
3071                                 {
3072                                         a= pop_reg();
3073                                         flush_cache();
3074                                         b= alloc_reg();
3075                                         c= alloc_reg();
3076                                         d= alloc_reg();
3077                                         flush_cache();
3078                                         "andn   $a, 31, $b";
3079                                         "and    $a, 31, $c";
3080                                         "srl    $b, 3, $d";
3081                                         "ld     [$reg_sp+$d], $b";
3082                                         "inc    $n_str, $reg_sp";
3083                                         "srl    $b, $c, $d";
3084                                         "and    $d, 1, $b";
3085                                         free_reg(a);
3086                                         push_reg(b);
3087                                         free_reg(c);
3088                                         free_reg(d);
3089                                 }
3090                         }
3091                         else if (n % EM_WSIZE)
3092                                 arg_error ("inn", n);
3093                         else
3094                         {
3095                                 a= pop_reg();
3096                                 flush_cache();
3097                                 b= alloc_reg();
3098                                 c= alloc_reg();
3099                                 d= alloc_reg();
3100                                 flush_cache();
3101                                 "andn   $a, 31, $b";
3102                                 "and    $a, 31, $c";
3103                                 "srl    $b, 3, $d";
3104                                 "ld     [$reg_sp+$d], $b";
3105                                 "inc    $n_str, $reg_sp";
3106                                 "srl    $b, $c, $d";
3107                                 "and    $d, 1, $b";
3108                                 free_reg(a);
3109                                 push_reg(b);
3110                                 free_reg(c);
3111                                 free_reg(d);
3112                         }
3113                 }
3114                 else
3115                         not_implemented ("inn_narg");
3116         }.
3117
3118 C_set   ==>     Comment( set, $1);
3119                 push_const($1);
3120                 C_set_narg().
3121
3122 C_set_narg      ==>
3123         {
3124                 reg_t a;
3125                 reg_t b;
3126                 reg_t c;
3127                 reg_t d;
3128                 int n;
3129                 const_str_t n_str;
3130
3131                 Comment0( set_narg );
3132
3133                 if (type_of_tos() == T_cst) {
3134                         n = pop_const(n_str);
3135                         if (n == EM_WSIZE) {
3136                                 b = alloc_reg();
3137                                 c = alloc_reg();
3138                                 a = pop_reg();
3139                                 "set    1, $c";
3140                                 "sll    $c, $a, $b";
3141                                 free_reg(a);
3142                                 free_reg(c);
3143                                 push_reg(b);
3144                         } else {
3145                                 a= alloc_reg();
3146                                 b= pop_reg();
3147                                 c= alloc_reg();
3148                                 d= alloc_reg();
3149                                 flush_cache();
3150                                 sprint(n_str, "%d", n);
3151                                 "set    $n_str, $a";
3152                                 "sub    $reg_sp, $a, $reg_sp";
3153                         "1:";
3154                                 "deccc  4, $a";
3155                                 "bnz    1b";
3156                                 "st     %g0, [$reg_sp+$a]";     /* HACK delay */
3157                                 "andn   $b, 31, $c";
3158                                 "and    $b, 31, $d";
3159                                 "srl    $c, 3, $c";
3160                                 "set    1, $a";
3161                                 "sll    $a, $d, $d";
3162                                 "st     $d, [$reg_sp+$c]";
3163                                 free_reg(a);
3164                                 free_reg(b);
3165                                 free_reg(c);
3166                                 free_reg(d);
3167                         }
3168                 } else {
3169                         a= alloc_reg();
3170                         pop_reg_as(a);
3171                         b= pop_reg();
3172                         flush_cache();
3173                         c= alloc_reg();
3174                         d= alloc_reg();
3175                         "sub    $reg_sp, $a, $reg_sp";
3176                 "1:";
3177                         "deccc  4, $a";
3178                         "bnz    1b";
3179                         "st     %g0, [$reg_sp+$a]";     /* HACK delay */
3180                         "andn   $b, 31, $c";
3181                         "and    $b, 31, $d";
3182                         "srl    $c, 3, $c";
3183                         "set    1, $a";
3184                         "sll    $a, $d, $d";
3185                         "st     $d, [$reg_sp+$c]";
3186                         free_reg(a);
3187                         free_reg(b);
3188                         free_reg(c);
3189                         free_reg(d);
3190                 }
3191         }.
3192
3193
3194 /******************************************************************************/
3195 /*                                                                            */
3196 /*              Group 11 : Array                                              */
3197 /*                                                                            */
3198 /******************************************************************************/
3199
3200 C_lar
3201         ($1 == 4) ==>
3202                         Comment(lar, $1);
3203                         force_alloc_output();
3204                         pop_reg_as(reg_o0);
3205                         pop_reg_as(reg_o1);
3206                         pop_reg_as(reg_o2);
3207                         flush_cache();
3208                         "call lar";
3209                         "nop";
3210                         free_output().
3211         default ==>
3212                         arg_error ("arg error lar", $1).
3213
3214 narg4(lar)
3215
3216 C_sar
3217         ($1 == 4) ==>
3218                         Comment( sar , $1 );
3219                         force_alloc_output();
3220                         pop_reg_as(reg_o0);
3221                         pop_reg_as(reg_o1);
3222                         pop_reg_as(reg_o2);
3223                         flush_cache();
3224                         "call   sar";
3225                         "nop"
3226                         free_output().
3227         default ==>
3228                         arg_error ("arg error sar", $1).
3229
3230 narg4(sar)
3231
3232 C_aar
3233         ($1 == 4) ==>
3234                         Comment(aar, $1);
3235                         force_alloc_output();
3236                         pop_reg_as(reg_o0);
3237                         pop_reg_as(reg_o1);
3238                         pop_reg_as(reg_o2);
3239                         flush_cache();
3240                         "call   aar";
3241                         "nop";
3242                         soft_alloc_reg(reg_o0);
3243                         free_output();
3244                         push_reg(reg_o0).
3245         default ==>
3246                         arg_error ("arg error aar", $1).
3247
3248 narg4(aar)
3249
3250 /******************************************************************************/
3251 /*                                                                            */
3252 /*              Group 12 : Compare                                            */
3253 /*                                                                            */
3254 /******************************************************************************/
3255
3256 C_cmi
3257         $1 == 4         ==>
3258         {
3259                 reg_t a;
3260                 reg_t b;
3261                 reg_t c;
3262                 const_str_t d;
3263
3264                 Comment( cmi, $1 );
3265
3266                 if (type_of_tos() == T_cst && const13(top_const()))
3267                 {
3268                         pop_const(d);
3269                         a= pop_reg();
3270                         b= alloc_reg();
3271                         "cmp    $a, $d";
3272                         "be,a   1f";
3273                         "mov    0, $b"; /* delay slot */
3274                         "bg,a   1f";
3275                         "mov    1, $b"; /* delay slot */
3276                         "mov    -1, $b";
3277                 "1:";
3278                         free_reg(a);
3279                         push_reg(b);
3280                 }
3281                 else
3282                 {
3283                         a= pop_reg();
3284                         b= NULL;
3285                         c= alloc_reg();
3286                         if (type_of_tos() == T_cst)
3287                         {
3288                                 pop_const(d);
3289                                 "cmp    $a, $d";
3290                         }
3291                         else
3292                         {
3293                                 b= pop_reg();
3294                                 "cmp    $a, $b";
3295                         }
3296                         "be,a   1f";
3297                         "mov    0, $c"; /* delay slot */
3298                         "bg,a   1f";
3299                         "mov    -1, $c"; /* delay slot */
3300                         "mov    1, $c";
3301                 "1:";
3302                         free_reg(a);
3303                         if (b)
3304                                 free_reg(b);
3305                         push_reg(c);
3306                 }
3307         }.
3308         default         ==>
3309                 arg_error ("unimp cmi", $1).
3310
3311 narg4(cmi)
3312
3313 C_cmu   ==>
3314                 Comment( cmu, $1 );
3315                 push_const($1);
3316                 C_cmu_narg().
3317
3318 C_cmu_narg      ==>
3319         {
3320                 int n;
3321                 reg_t a;
3322                 reg_t b;
3323                 reg_t c;
3324                 const_str_t d;
3325
3326                 Comment0( cmu_narg );
3327                 if (type_of_tos() == T_cst)
3328                 {
3329                         n= pop_const(NULL);
3330                         if (n != EM_WSIZE)
3331                                 arg_error ("unimp cmu", n);
3332                         else
3333                         {
3334                                 if (type_of_tos() == T_cst &&
3335                                         const13(top_const()))
3336                                 {
3337                                         pop_const(d);
3338                                         a= pop_reg();
3339                                         b= alloc_reg();
3340                                         "cmp    $a, $d";
3341                                         "be,a   1f";
3342                                         "mov    0, $b"; /* delay slot */
3343                                         "bgu,a  1f";
3344                                         "mov    1, $b"; /* delay slot */
3345                                         "mov    -1, $b";
3346                                 "1:";
3347                                         free_reg(a);
3348                                         push_reg(b);
3349                                 }
3350                                 else
3351                                 {
3352                                         a= pop_reg();
3353                                         b= NULL;
3354                                         c= alloc_reg();
3355                                         if (type_of_tos() == T_cst &&
3356                                                 const13(top_const()))
3357                                         {
3358                                                 pop_const(d);
3359                                                 "cmp    $a, $d";
3360                                         }
3361                                         else
3362                                         {
3363                                                 b= pop_reg();
3364                                                 "cmp    $a, $b";
3365                                         }
3366                                         "be,a   1f";
3367                                         "mov    0, $c"; /* delay slot */
3368                                         "bgu,a  1f";
3369                                         "mov    -1, $c"; /* delay slot */
3370                                         "mov    1, $c";
3371                                 "1:";
3372                                         free_reg(a);
3373                                         if (b)
3374                                                 free_reg(b);
3375                                         push_reg(c);
3376                                 }
3377                         }
3378                 }
3379                 else
3380                         not_implemented ("cmu_narg");
3381         }.
3382
3383 C_cms   ==>
3384                 Comment( cms, $1 );
3385                 push_const($1);
3386                 C_cms_narg().
3387
3388 C_cms_narg      ==>
3389         {
3390                 int n;
3391                 reg_t a;
3392                 reg_t b;
3393                 reg_t c;
3394                 reg_t d;
3395                 reg_t e;
3396                 const_str_t b_str;
3397                 const_str_t n_str;
3398
3399                 Comment0( cms_narg );
3400                 if (type_of_tos() == T_cst && top_const() <= EM_WSIZE)
3401                 {
3402                         n= pop_const(n_str);
3403                         if (n == EM_WSIZE)
3404                         {
3405                                 b= NULL;
3406                                 c= alloc_reg();
3407                                 if (type_of_tos() == T_cst &&
3408                                     const13(top_const()))
3409                                 {
3410                                         pop_const(b_str);
3411                                         a= pop_reg();
3412                                         "cmp    $a, $b_str";
3413                                 }
3414                                 else
3415                                 {
3416                                         a= pop_reg();
3417                                         b= pop_reg();
3418                                         "cmp    $a, $b";
3419                                 }
3420                                 "be,a   1f";
3421                                 "mov    0, $c";
3422                                 "mov    1, $c";
3423                         "1:";
3424                                 free_reg(a);
3425                                 if (b)
3426                                         free_reg(b);
3427                                 push_reg(c);
3428                         }
3429                         else if (n % EM_WSIZE)
3430                                 arg_error ("unimp cms", n);
3431                 }
3432                 else
3433                 {
3434                         a= pop_reg();
3435                         flush_cache();
3436                         b= alloc_reg();
3437                         c= alloc_reg();
3438                         d= alloc_reg();
3439
3440                         "add    $reg_sp, $a, $b";
3441                         "dec    4, $b";
3442                 "1:";
3443                         "ld     [$b], $c";
3444                         "ld     [$b+$a], $d";
3445                         "cmp    $d, $c";
3446                         "bne,a  2f";
3447                         "mov    1, $b"; /* delay slot */
3448                         "cmp    $b, $reg_sp";
3449                         "bg     1b";
3450                         "dec    4, $b"; /* delay slot */
3451                         "mov    0, $b";
3452                 "2:";
3453                         "add    $reg_sp, $a, $reg_sp";
3454                         "add    $reg_sp, $a, $reg_sp";
3455
3456                         free_reg(a);
3457                         push_reg(b);
3458                         free_reg(c);
3459                         free_reg(d);
3460                 }
3461         }.
3462
3463 C_cmp           ==>
3464                         Comment0( cmp );
3465                         C_cmu( (arith)4).
3466
3467 C_tlt   ==>
3468                 Comment0( tlt );
3469                 {
3470                         reg_t a;
3471                         reg_t b;
3472
3473                         a = pop_reg();
3474                         b= alloc_reg();
3475                         "       tst     $a";
3476                         "       bl,a    1f";
3477                         "       mov     1, $b";         /* delay slot */
3478                         "       set     0, $b";
3479                         "1:";
3480                         free_reg(a);
3481                         push_reg(b);
3482                 }.
3483
3484 C_tle   ==>
3485                 Comment0( tle );
3486                 {
3487                         reg_t a;
3488                         reg_t b;
3489
3490                         a = pop_reg();
3491                         b= alloc_reg();
3492                         "tst    $a";
3493                         "ble,a  1f";
3494                         "mov    1, $b";         /* delay slot */
3495                         "set    0, $b";
3496                 "1:";
3497                         free_reg(a);
3498                         push_reg(b);
3499                 }.
3500
3501 C_tge   ==>
3502                 Comment0( tge );
3503                 {
3504                         reg_t a;
3505                         reg_t b;
3506
3507                         a = pop_reg();
3508                         b = alloc_reg();
3509                         "       tst     $a";
3510                         "       bge,a   1f";
3511                         "       mov     1, $b";         /* delay slot */
3512                         "       set     0, $b";
3513                         "1:";
3514                         free_reg(a);
3515                         push_reg(b);
3516                 }.
3517
3518 C_tgt   ==>
3519                 Comment0( tgt );
3520                 {
3521                         reg_t a;
3522                         reg_t b;
3523
3524                         a = pop_reg();
3525                         b = alloc_reg();
3526                         "       tst     $a";
3527                         "       bg,a    1f";
3528                         "       mov     1, $b";         /* delay slot */
3529                         "       set     0, $b";
3530                         "1:";
3531                         free_reg(a);
3532                         push_reg(b);
3533                 }.
3534
3535 C_tne   ==>
3536                 Comment0( tne );
3537                 {
3538                         reg_t a;
3539                         reg_t b;
3540
3541                         a = pop_reg();
3542                         b = alloc_reg();
3543                         "       tst     $a";
3544                         "       bne,a   1f";
3545                         "       mov     1, $b";         /* delay slot */
3546                         "       set     0, $b";         /* sup optimal */
3547                         "1:";
3548                         free_reg(a);
3549                         push_reg(b);
3550                 }.
3551
3552 C_teq   ==>
3553                 Comment0( teq );
3554                 {
3555                         reg_t a;
3556                         reg_t b;
3557
3558                         a = pop_reg();
3559                         b = alloc_reg();
3560                         "       tst     $a";
3561                         "       be,a    1f";
3562                         "       mov     1, $b";         /* delay slot */
3563                         "       set     0, $b";
3564                         "1:";
3565                         free_reg(a);
3566                         push_reg(b);
3567                 }.
3568 C_cmf           ==>
3569         Comment( cmf, $1);
3570         push_const($1);
3571         C_cmf_narg().
3572
3573 C_cmf_narg      ==>
3574         {
3575                 reg_t a;
3576                 reg_t b;
3577                 reg_t c;
3578                 int n;
3579
3580                 Comment0( cmf_narg);
3581                 if (type_of_tos() == T_cst)
3582                 {
3583                         n= pop_const(NULL);
3584                         if (n == EM_FSIZE)
3585                         {
3586                                 a= pop_float();
3587                                 b= pop_float();
3588                                 c= alloc_reg();
3589                                 "fcmpes $b, $a";
3590                                 "nop";
3591                                 "fbe,a  1f";
3592                                 "mov    0, $c";
3593                                 "fbl,a  1f";
3594                                 "mov    -1, $c";
3595                                 "mov    1, $c";
3596                         "1:";
3597                                 free_reg(a);
3598                                 free_reg(b);
3599                                 push_reg(c);
3600                         }
3601                         else if (n == EM_DSIZE)
3602                         {
3603                                 a= pop_double(NULL);
3604                                 b= pop_double(NULL);
3605                                 c= alloc_reg();
3606                                 "fcmped $b, $a";
3607                                 "nop";
3608                                 "fbe,a  1f";
3609                                 "mov    0, $c";
3610                                 "fbl,a  1f";
3611                                 "mov    -1, $c";
3612                                 "mov    1, $c";
3613                         "1:";
3614                                 free_double_reg(a);
3615                                 free_double_reg(b);
3616                                 push_reg(c);
3617                         }
3618                         else
3619                                 arg_error ("cmf", n);
3620                 }
3621                 else
3622                         not_implemented ("cmf_narg");
3623         }.
3624
3625 /******************************************************************************/
3626 /*                                                                            */
3627 /*              Group 13 : Branch                                             */
3628 /*                                                                            */
3629 /******************************************************************************/
3630
3631 C_bra           ==>
3632                         Comment( bra , $1 );
3633                         {
3634                                 char *lbl;
3635
3636                                 flush_cache();
3637                                 lbl = $1;
3638                                 "b      $lbl";
3639                                 "nop";          /* delay slot */
3640                         }.
3641
3642 C_bge   ==>
3643                 Comment( bge , $1 );
3644                 {
3645                         char *lbl = $1;
3646                         reg_t a;
3647                         reg_t b;
3648                         const_str_t n_str;
3649
3650                         a= NULL;
3651                         if (type_of_tos() == T_cst &&
3652                                 const13(top_const()))
3653                                 pop_const(n_str);
3654                         else
3655                                 a = pop_reg();
3656                         b = pop_reg();
3657                         flush_cache();
3658                         if (a)
3659                                 "cmp    $b, $a";
3660                         else
3661                                 "cmp    $b, $n_str";
3662                         "bge    $lbl";
3663                         "nop"           /* delay slot */
3664                         free_reg(a);
3665                         free_reg(b);
3666                 }.
3667
3668 C_bne   ==>
3669                 Comment( bne , $1 );
3670                 {
3671                         char *lbl = $1;
3672                         reg_t a;
3673                         reg_t b;
3674                         const_str_t n_str;
3675
3676                         a= NULL;
3677                         if (type_of_tos() == T_cst &&
3678                                 const13(top_const()))
3679                                 pop_const(n_str);
3680                         else
3681                                 a = pop_reg();
3682                         b = pop_reg();
3683                         flush_cache();
3684                         if (a)
3685                                 "cmp    $b, $a";
3686                         else
3687                                 "cmp    $b, $n_str";
3688                         "bne    $lbl";
3689                         "nop"           /* delay slot */
3690                         free_reg(a);
3691                         free_reg(b);
3692                 }.
3693
3694 C_beq   ==>
3695                 Comment( beq , $1 );
3696                 {
3697                         char *lbl = $1;
3698                         reg_t a;
3699                         reg_t b;
3700                         const_str_t n_str;
3701
3702                         a= NULL;
3703                         if (type_of_tos() == T_cst &&
3704                                 const13(top_const()))
3705                                 pop_const(n_str);
3706                         else
3707                                 a = pop_reg();
3708                         b = pop_reg();
3709                         flush_cache();
3710                         if (a)
3711                                 "cmp    $b, $a";
3712                         else
3713                                 "cmp    $b, $n_str";
3714                         "beq    $lbl";
3715                         "nop"           /* delay slot */
3716                         free_reg(a);
3717                         free_reg(b);
3718                 }.
3719
3720 C_ble   ==>
3721                 Comment( ble , $1 );
3722                 {
3723                         char *lbl = $1;
3724                         reg_t a;
3725                         reg_t b;
3726                         const_str_t n_str;
3727
3728                         a= NULL;
3729                         if (type_of_tos() == T_cst &&
3730                                 const13(top_const()))
3731                                 pop_const(n_str);
3732                         else
3733                                 a = pop_reg();
3734                         b = pop_reg();
3735                         flush_cache();
3736                         if (a)
3737                                 "cmp    $b, $a";
3738                         else
3739                                 "cmp    $b, $n_str";
3740                         "ble    $lbl";
3741                         "nop"           /* delay slot */
3742                         free_reg(a);
3743                         free_reg(b);
3744                 }.
3745
3746 C_blt   ==>
3747                 Comment( blt , $1 );
3748                 {
3749                         char *lbl = $1;
3750                         reg_t a;
3751                         reg_t b;
3752                         const_str_t n_str;
3753
3754                         a= NULL;
3755                         if (type_of_tos() == T_cst &&
3756                                 const13(top_const()))
3757                                 pop_const(n_str);
3758                         else
3759                                 a = pop_reg();
3760                         b = pop_reg();
3761                         flush_cache();
3762                         if (a)
3763                                 "cmp    $b, $a";
3764                         else
3765                                 "cmp    $b, $n_str";
3766                         "bl     $lbl";
3767                         "nop"           /* delay slot */
3768                         free_reg(a);
3769                         free_reg(b);
3770                 }.
3771
3772 C_bgt   ==>
3773                 Comment( bgt , $1 );
3774                 {
3775                         char *lbl = $1;
3776                         reg_t a;
3777                         reg_t b;
3778                         const_str_t n_str;
3779
3780                         a= NULL;
3781                         if (type_of_tos() == T_cst &&
3782                                 const13(top_const()))
3783                                 pop_const(n_str);
3784                         else
3785                                 a = pop_reg();
3786                         b = pop_reg();
3787                         flush_cache();
3788                         if (a)
3789                                 "cmp    $b, $a";
3790                         else
3791                                 "cmp    $b, $n_str";
3792                         "bg     $lbl";
3793                         "nop"           /* delay slot */
3794                         free_reg(a);
3795                         free_reg(b);
3796                 }.
3797
3798 C_zlt   ==>
3799                 Comment( zlt , $1 );
3800                 {
3801                         char *lbl = $1;
3802                         reg_t a;
3803
3804                         a = pop_reg();
3805                         flush_cache();
3806                         "tst    $a";
3807                         "bl     $lbl";
3808                         "nop";          /* delay slot */
3809                         free_reg(a);
3810                 }
3811                 .
3812
3813 C_zle   ==>
3814                 Comment( zle , $1 );
3815                 {
3816                         char *lbl = $1;
3817                         reg_t a;
3818
3819                         a = pop_reg();
3820                         flush_cache();
3821                         "tst    $a";
3822                         "ble    $lbl";
3823                         "nop";          /* delay slot */
3824                         free_reg(a);
3825                 }
3826                 .
3827
3828 C_zeq   ==>
3829                 Comment( zeq , $1 );
3830                 {
3831                         char *lbl = $1;
3832                         reg_t a;
3833
3834                         a = pop_reg();
3835                         flush_cache();
3836                         "tst    $a";
3837                         "be     $lbl";
3838                         "nop";          /* delay slot */
3839                         free_reg(a);
3840                 }
3841                 .
3842
3843 C_zne   ==>
3844                 Comment( zne , $1 );
3845                 {
3846                         char *lbl = $1;
3847                         reg_t a;
3848
3849                         a = pop_reg();
3850                         flush_cache();
3851                         "tst    $a";
3852                         "bne    $lbl";
3853                         "nop";          /* delay slot */
3854                         free_reg(a);
3855                 }
3856                 .
3857
3858 C_zge   ==>
3859                 Comment( zge , $1 );
3860                 {
3861                         char *lbl = $1;
3862                         reg_t a;
3863
3864                         a = pop_reg();
3865                         flush_cache();
3866                         "tst    $a";
3867                         "bge    $lbl";
3868                         "nop";          /* delay slot */
3869                         free_reg(a);
3870                 }
3871                 .
3872
3873 C_zgt   ==>
3874                 Comment( zgt , $1 );
3875                 {
3876                         char *lbl = $1;
3877                         reg_t a;
3878
3879                         a = pop_reg();
3880                         flush_cache();
3881                         "tst    $a";
3882                         "bg     $lbl";
3883                         "nop";          /* delay slot */
3884                         free_reg(a);
3885                 }
3886                 .
3887 /******************************************************************************/
3888 /*                                                                            */
3889 /*                      Group 14 : Procedure call instructions                */
3890 /*                                                                            */
3891 /******************************************************************************/
3892
3893 C_cai           ==>
3894                         Comment0( cai );
3895                         {
3896                                 reg_t a;
3897
3898                                 a= pop_reg();
3899                                 flush_cache();
3900                                 "call   $a";
3901                                 "nop";          /* delay slot */
3902                                 free_reg(a);
3903                         }.
3904
3905 C_cal           ==>
3906                         Comment( cal , $1 );
3907                         {
3908                                 char *lbl = $1;
3909                                 flush_cache();
3910                                 "call   $lbl";
3911                                 "nop";          /* delay slot */
3912                         }.
3913
3914 C_lfr
3915         $1 == 4         ==>
3916         {
3917                 Comment( lfr , $1 );
3918                 forced_alloc_reg(RETL_LD);
3919                 push_reg(RETL_LD);
3920         }.
3921         $1 == 8         ==>
3922         {
3923                 Comment( lfr , $1 );
3924                 forced_alloc_reg(RETL_LD);
3925                 forced_alloc_reg(RETH_LD);
3926                 push_reg(RETH_LD);
3927                 push_reg(RETL_LD);
3928         }.
3929         default         ==>
3930                 arg_error( "lfr", $1).
3931
3932 C_ret
3933         $1 == 0         ==>
3934         {
3935                 Comment( ret , $1 );
3936                 load_float_regs();
3937                 if (debug)
3938                         free_all_reg_vars();
3939                 "restore";
3940                 "retl";
3941                 "add    %sp, $reg_gap, %sp";
3942                 if (debug)
3943                         alloc_all_reg_vars();
3944         }.
3945         $1 == 4         ==>
3946         {
3947                 Comment( ret , $1 );
3948                 soft_alloc_reg(RETL_ST);
3949                 pop_reg_as(RETL_ST);
3950                 free_reg(RETL_ST);
3951                 load_float_regs();
3952                 if (debug)
3953                         free_all_reg_vars();
3954                 "restore";
3955                 "retl";
3956                 "add    %sp, $reg_gap, %sp";
3957                 if (debug)
3958                         alloc_all_reg_vars();
3959         }.
3960         $1 == 8         ==>
3961         {
3962                 Comment( ret , $1 );
3963                 soft_alloc_reg(RETL_ST);
3964                 soft_alloc_reg(RETH_ST);
3965                 pop_reg_as(RETL_ST);
3966                 pop_reg_as(RETH_ST);
3967                 free_reg(RETL_ST);
3968                 free_reg(RETH_ST);
3969                 load_float_regs();
3970                 if (debug)
3971                         free_all_reg_vars();
3972                 "restore";
3973                 "retl";
3974                 "add    %sp, $reg_gap, %sp";
3975                 if (debug)
3976                         alloc_all_reg_vars();
3977         }.
3978         default         ==>
3979                                 arg_error( "ret", $1).
3980
3981 /******************************************************************************/
3982 /*                                                                            */
3983 /*                      Group 15 : Miscellaneous instructions                 */
3984 /*                                                                            */
3985 /******************************************************************************/
3986
3987 C_asp           ==>
3988         Comment( asp , $1 );
3989         push_const($1);
3990         C_ass(EM_WSIZE).
3991
3992
3993 C_ass
3994         $1 == 4         ==>
3995         {
3996                 int n;
3997                 const_str_t n_str;
3998                 reg_t a;
3999
4000                 if (type_of_tos() == T_cst)
4001                 {
4002                         n= pop_const(n_str);
4003                         if (n % EM_WSIZE)
4004                                 arg_error ("asp", n);
4005                         else
4006                                 if (n>=0)
4007                                         pop_nop (n/4);
4008                                 else
4009                                 {
4010                                         flush_cache();
4011                                         if (const13(n))
4012                                                 "inc    $n_str, $reg_sp";
4013                                         else
4014                                         {
4015                                                 a= alloc_reg();
4016                                                 "set    $n_str, $a"
4017                                                 "add    $reg_sp, $a, $reg_sp";
4018                                                 free_reg(a);
4019                                         }
4020                                 }
4021                 }
4022                 else
4023                 {
4024                         a= pop_reg();
4025                         flush_cache();
4026                         "add    $reg_sp, $a, $reg_sp";
4027                         free_reg(a);
4028                 }
4029         }.
4030         default         ==>
4031                                 arg_error( "ass", $1).
4032
4033
4034 narg4(ass)
4035
4036 C_blm           ==>
4037         Comment( blm, $1);
4038         push_const($1);
4039         C_bls (EM_WSIZE).
4040
4041 C_bls
4042         $1 == 4 ==>
4043         {
4044                 reg_t a;
4045                 reg_t b;
4046                 reg_t c;
4047                 reg_t d;
4048                 reg_t e;
4049                 reg_t ao_reg;
4050                 reg_t bo_reg;
4051                 int n;
4052                 int i;
4053                 const_str_t n_str;
4054                 const_str_t ac_str;
4055                 const_str_t bc_str;
4056                 
4057                 Comment( bls , $1 );
4058                 if (type_of_tos() == T_cst)
4059                 {
4060                         n= pop_const(n_str);
4061                         if (n % EM_WSIZE)
4062                                 arg_error ("blm", n);
4063                         else if (n <= MAX_UNROLL)
4064                         {
4065                                 c= alloc_reg();
4066                                 for (i=0; i<n; i += EM_WSIZE)
4067                                 {
4068                                         if (type_of_tos() & T_reg2) /* dest */
4069                                                 a= pop_reg_reg (&ao_reg);
4070                                         else
4071                                         {
4072                                                 ao_reg= NULL;
4073                                                 a= pop_reg_c13(ac_str);
4074                                         }
4075                                         if (type_of_tos() & T_reg2) /* src */
4076                                                 b= pop_reg_reg (&bo_reg);
4077                                         else
4078                                         {
4079                                                 bo_reg= NULL;
4080                                                 b= pop_reg_c13(bc_str);
4081                                         }
4082                                         if (bo_reg)
4083                                                 "ld     [$b+$bo_reg], $c";
4084                                         else
4085                                                 "ld     [$b+$bc_str], $c";
4086                                         if (ao_reg)
4087                                                 "st     $c, [$a+$ao_reg]";
4088                                         else
4089                                                 "st     $c, [$a+$ac_str]";
4090                                         if (bo_reg)
4091                                         {
4092                                                 push_reg(b);
4093                                                 inc_tos_reg(bo_reg);
4094                                         }
4095                                         else if (bc_str[0] == '-' ||
4096                                                 isdigit(bc_str[0]))
4097                                         {
4098                                                 push_reg(b);
4099                                                 inc_tos(atoi(bc_str));
4100                                         }
4101                                         else
4102                                         {
4103                                                 "add    $b, $bc_str, $c";
4104                                                 push_reg(c);
4105                                                 free_reg(b);
4106                                                 c= alloc_reg();
4107                                         }
4108                                         inc_tos(4);
4109                                         if (ao_reg)
4110                                         {
4111                                                 push_reg(a);
4112                                                 inc_tos_reg(ao_reg);
4113                                         }
4114                                         else if (ac_str[0] == '-' ||
4115                                                 isdigit(ac_str[0]))
4116                                         {
4117                                                 push_reg(a);
4118                                                 inc_tos(atoi(ac_str));
4119                                         }
4120                                         else
4121                                         {
4122                                                 "add    $a, $ac_str, $c";
4123                                                 push_reg(c);
4124                                                 free_reg(a);
4125                                                 c= alloc_reg();
4126                                         }
4127                                         inc_tos(4);
4128                                 }
4129                                 pop_nop(2);
4130                                 free_reg(c);
4131                         }
4132                         else
4133                         {
4134                                 a= pop_reg();   /* dest */
4135                                 b= pop_reg();   /* src */
4136                                 c= alloc_reg();
4137                                 d= alloc_reg();
4138                                 e = alloc_reg();
4139                                 "set    $n_str-4, $c";
4140                                 "set    -4, $e";
4141                         "1:";
4142                                 "inc    4, $e";
4143                                 "ld     [$b+$e], $d";
4144                                 "cmp    $e,$c";
4145                                 "bnz    1b";
4146                                 "st     $d, [$a+$e]";
4147                                 free_reg(a);
4148                                 free_reg(b);
4149                                 free_reg(c);
4150                                 free_reg(d);
4151                                 free_reg(e);
4152                         }
4153                 }
4154                 else
4155                 {
4156
4157                         c= alloc_reg(); /* size */
4158                         pop_reg_as(c);
4159                         a= pop_reg();   /* dest */
4160                         b= pop_reg();   /* src */
4161                         d= alloc_reg();
4162                         e= alloc_reg();
4163                         "ba     2f";
4164                         "clr    $e";
4165                 "1:";
4166                         "st     $d, [$a+$e]";
4167                         "inc    4, $e";
4168                 "2:";
4169                         "cmp    $e, $c"
4170                         "bnz    1b";
4171                         "ld     [$b+$e], $d";
4172                         free_reg(a);
4173                         free_reg(b);
4174                         free_reg(c);
4175                         free_reg(d);
4176                         free_reg(e);
4177                 }
4178         }.
4179
4180         default         ==>
4181                                 arg_error( "bls", $1).
4182
4183 narg4(bls)
4184
4185 C_csa
4186         $1 == 4 ==>
4187                 Comment( csa , $1 );
4188                 {
4189                         force_alloc_output();
4190                         pop_reg_as(reg_o0);
4191                         pop_reg_as(reg_o1);
4192                         flush_cache();
4193                         free_output();
4194                         "set    csa, $reg_tmp";
4195                         "jmp    $reg_tmp";
4196                         "nop";
4197                 }.
4198         default ==>
4199                 arg_error( "csa", $1).
4200
4201 narg4(csa)
4202
4203 C_csb
4204         $1 == 4         ==>
4205                         Comment( csb , $1 );
4206                         {
4207                                 force_alloc_output();
4208                                 pop_reg_as(reg_o0);
4209                                 pop_reg_as(reg_o1);
4210                                 flush_cache();
4211                                 free_output();
4212                                 "set    csb, $reg_tmp";
4213                                 "jmp    $reg_tmp";
4214                                 "nop";
4215                         }.
4216         default         ==>
4217                                 arg_error( "csb", $1).
4218
4219 narg4(csb)
4220
4221 C_dch           ==>
4222         {
4223                 reg_t a;
4224                 reg_t b;
4225                 reg_t c;
4226
4227                 Comment0( dch );
4228                 a= pop_reg();           /* some LB */
4229                 b= alloc_reg();
4230                 c= alloc_reg();
4231                 "ta     3";             /* flush register windows */
4232                 "add    $a, 7, $b";
4233                 "andn   $b, 7, $c";     /* and it's %fp */
4234                 "ld     [$c+4], $b";    /* the previous LB */
4235                 free_reg(a);
4236                 push_reg(b);
4237                 free_reg(c);
4238         }.
4239
4240 C_dup   ==>
4241                 Comment( dup, $1);
4242                 push_const($1);
4243                 C_dus(EM_WSIZE).
4244
4245 C_dus
4246         $1 == 4 ==>
4247         {
4248                 int n;
4249                 int i;
4250                 const_str_t n_str;
4251                 const_str_t i_str;
4252                 reg_t a;
4253                 reg_t b;
4254                 reg_t c;
4255
4256                 Comment( dus, $1);
4257
4258                 if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL)
4259                 {
4260                         n= pop_const(n_str);
4261                         if (n == 4 || n == 8 || n<=32)
4262                                 dup_tos(n/4);
4263                         else if (n<0 || n % 4)
4264                                 arg_error ("dup", n);
4265                         else
4266                         {
4267                                 flush_cache();
4268                                 a= alloc_reg();
4269                                 "sub    $reg_sp, $n_str, $reg_sp";
4270                                 for (i=0; i<n; i += 4)
4271                                 {
4272                                         sprint(i_str, "%d", i);
4273                                         "ld     [$reg_sp+$i_str+$n_str], $a";
4274                                         "st     $a, [$reg_sp+$i_str]";
4275                                 }
4276                                 free_reg(a);
4277                         }
4278                 }
4279                 else
4280                 {
4281                         a= pop_reg();
4282                         flush_cache();
4283                         b= alloc_reg();
4284                         c= alloc_reg();
4285                         "mov    $a, $b";
4286                 "1:";
4287                         "dec    STACK_CLICK, $reg_sp";
4288                         "ld     [$reg_sp+ $a], $c";
4289                         "deccc  4, $b";
4290                         "bne    1b";
4291                         "st     $c, [$reg_sp+ $a]"; /* delay slot */
4292                         free_reg(a);
4293                         free_reg(b);
4294                         free_reg(c);
4295                 }
4296         }.
4297         default         ==>
4298                                 arg_error( "dus", $1).
4299
4300 narg4(dus)
4301
4302 C_exg           ==>
4303         Comment( exg, $1 );
4304         push_const($1);
4305         C_exg_narg().
4306
4307 C_exg_narg      ==>
4308         {
4309                 reg_t a;
4310                 reg_t b;
4311                 reg_t c;
4312                 reg_t d;
4313                 int n;
4314                 int i;
4315                 const_str_t i_str;
4316                 const_str_t in_str;
4317
4318                 Comment0( exg_narg );
4319                 if (type_of_tos() == T_cst && top_const() <= MAX_UNROLL)
4320                 {
4321                         n= pop_const(NULL);
4322                         if (n==4)
4323                         {
4324                                         a= pop_reg();
4325                                         b= pop_reg();
4326                                         push_reg(a);
4327                                         push_reg(b);
4328                         }
4329                         else if (n==8)
4330                         {
4331                                 a= pop_reg();
4332                                 b= pop_reg();
4333                                 c= pop_reg();
4334                                 d= pop_reg();
4335                                 push_reg(b);
4336                                 push_reg(a);
4337                                 push_reg(d);
4338                                 push_reg(c);
4339                         }
4340                         else if (n>0 && !(n % 4))
4341                         {
4342                                 a= alloc_reg();
4343                                 b= alloc_reg();
4344                                 flush_cache();
4345                                 for (i=0; i<n; i += 4)
4346                                 {
4347                                         sprint(i_str, "%d", i);
4348                                         sprint(in_str, "%d", i+n);
4349                                         "ld     [$reg_sp+$i_str], $a";
4350                                         "ld     [$reg_sp+$in_str], $b";
4351                                         "st     $b, [$reg_sp+$i_str]";
4352                                         "st     $a, [$reg_sp+$in_str]";
4353                                 }
4354                                 free_reg(a);
4355                                 free_reg(b);
4356                         }
4357                         else
4358                                 arg_error ("exg", n);
4359                 }
4360                 else
4361                 {
4362                         a= pop_reg();
4363                         flush_cache();
4364                         b= alloc_reg();
4365                         c= alloc_reg();
4366                         d= alloc_reg();
4367                         "add    $reg_sp, $a, $b";
4368                 "1:";
4369                         "dec    4, $b";
4370                         "cmp    $reg_sp, $b";
4371                         "ld     [$b], $c";
4372                         "ld     [$b+$a], $d";
4373                         "st     $d, [$b]";
4374                         "bne    1b";
4375                         "st     $c, [$b+$a]";   /* delay slot */
4376                         free_reg(a);
4377                         free_reg(b);
4378                         free_reg(c);
4379                         free_reg(d);
4380                 }
4381         }.
4382
4383 C_fil..         ==>
4384                         Comment2( fil , $1 , $2);
4385 #ifdef FAST_LIN_LNI_FIL
4386                         {
4387                                 char *lbl = $1;
4388                                 int n = $2;
4389
4390                                 "set    $lbl+$n, $reg_fil"
4391                         }.
4392 #else
4393                         push_ext($1);
4394                         inc_tos($2);
4395                         push_ext("filn");
4396                         push_const(4);
4397                         C_sts(EM_WSIZE).
4398 #endif
4399
4400
4401 C_gto..         ==>
4402         {
4403                 char *ext;
4404                 reg_t a;
4405                 reg_t b;
4406                 reg_t c;
4407                 reg_t d;
4408
4409                 Comment2( gto , $1 , $2 );
4410
4411                 flush_cache();
4412                 a= reg_g1;
4413                 b= reg_g2;
4414                 c= reg_g3;
4415                 d= reg_g5;
4416                 forced_alloc_reg(a);
4417                 forced_alloc_reg(b);
4418                 forced_alloc_reg(c);
4419                 forced_alloc_reg(d);
4420                 ext= $1;
4421                 push_ext(ext);
4422                 inc_tos($2);
4423                 pop_reg_as(a);
4424                 "ld     [$a+8], $b";
4425                 "mov    $reg_o0, $c";
4426                 "mov    $reg_o1, $d";
4427         "1:";
4428                 "cmp    $b, $reg_lb";
4429                 "bne,a  1b";
4430                 "restore";
4431                 "ld     [$a+4], $reg_sp";
4432                 "ld     [$a], $b";
4433                 "mov    $c, $reg_o0";
4434                 "jmp    $b";
4435                 "mov    $d, $reg_o1";   /* delay slot */
4436                 free_reg(a);
4437                 free_reg(b);
4438                 free_reg(c);
4439                 free_reg(d);
4440         }.
4441
4442 C_lim           ==>
4443                         Comment0( lim  );
4444                         push_ext("trpim");
4445                         C_loi(4).
4446
4447 C_lin           ==>
4448                         Comment( lin , $1 );
4449 #ifdef FAST_LIN_LNI_FIL
4450                         {
4451                                 const_str_t n_str;
4452                                 sprint(n_str, "%d", $1);
4453                                 "set    $n_str, $reg_fil";
4454                         }.
4455 #else
4456                         push_const($1);
4457                         push_ext("lino");
4458                         push_const(4);
4459                         C_sts(EM_WSIZE).
4460 #endif
4461
4462 C_lni           ==>
4463 #ifdef FAST_LIN_LNI_FIL
4464                         Comment0( lni );
4465                         "inc    $reg_fil".
4466 #else
4467                         {
4468                                 reg_t a;
4469                                 reg_t b;
4470
4471                                 Comment0( lni );
4472                                 a = alloc_reg();
4473                                 b = alloc_reg();
4474                                 "sethi  %hi(lino), $a";
4475                                 "ld     [$a+%lo(lino)], $b";
4476                                 "inc    $b";
4477                                 "st     $b, [$a+%lo(lino)]"
4478                                 free_reg(a);
4479                                 free_reg(b);
4480                         }.
4481 #endif
4482
4483
4484 C_lor
4485         $1 == 0         ==>
4486                                 Comment( lor , $1 );
4487                                 soft_alloc_reg(reg_lb);
4488                                 push_reg(reg_lb).
4489         $1 == 1         ==>
4490         {
4491                 reg_t a;
4492
4493                 Comment( lor , $1 );
4494                 a= alloc_reg();
4495                 flush_cache();
4496                 "mov    $reg_sp, $a";
4497                 push_reg(a);
4498         }.
4499         $1 == 2         ==>
4500                                 Comment( lor , $1 );
4501                                 {
4502                                         reg_t a;
4503                                         reg_t b;
4504
4505                                         a= alloc_reg();
4506                                         b= alloc_reg();
4507                                         "set    reghp, $a";
4508                                         "ld     [$a], $b";
4509                                         push_reg(b);
4510                                         free_reg(a);
4511                                 }.
4512
4513         default         ==>
4514                                 arg_error( "lor", $1).
4515
4516
4517 C_lpb           ==>
4518                         Comment0( lpb );
4519                         C_adp( (arith)EM_BSIZE).
4520
4521
4522 C_mon           ==>
4523                         Comment0( mon );
4524                         force_alloc_output();
4525                         pop_reg_as(reg_o0);
4526                         "call mon";
4527                         "nop";
4528                         free_output().
4529
4530 C_nop   ==>
4531                         Comment0( nop );
4532                         flush_cache();
4533                         .
4534
4535
4536 C_rck
4537         $1 == 4         ==>
4538         {
4539                 reg_t a;
4540                 reg_t b;
4541                 reg_t c;
4542
4543                 Comment( rck , $1 );
4544                 force_alloc_output();
4545                 a= pop_reg();
4546                 b= pop_reg();
4547                 soft_alloc_reg(b);
4548                 push_reg(b);
4549                 c= alloc_reg();
4550                 "ld     [$a], $c";
4551                 "cmp    $b, $c";
4552                 "bl     1f";
4553                 "ld     [$a+4], $c";
4554                 "cmp    $b, $c";
4555                 "ble    2f";
4556                 "nop";
4557         "1:";
4558                 "set    ERANGE, $reg_o0";
4559                 "call   trp";
4560                 "nop";
4561         "2:";
4562                 free_reg(a);
4563                 free_reg(b);
4564                 free_reg(c);
4565                 free_output();
4566         }.
4567         default         ==>
4568                 arg_error( "rck", $1).
4569
4570 narg4(rck)
4571
4572 C_rtt           ==>
4573                         Comment0( rtt );
4574                         C_ret( (arith)0).
4575
4576
4577 C_sig           ==>
4578                         Comment0( sig );
4579                         {
4580                                 reg_t a;
4581                                 reg_t b;
4582                                 reg_t c;
4583
4584                                 a= pop_reg();
4585                                 b= alloc_reg();
4586                                 c= alloc_reg();
4587                                 "set    trppc, $b";
4588                                 "ld     [$b], $c";
4589                                 "st     $a, [$b]";
4590                                 free_reg(a);
4591                                 free_reg(b);
4592                                 push_reg(c);
4593                         }.
4594
4595
4596 C_sim           ==>
4597                         Comment0( sim );
4598                         {
4599                                 reg_t a;
4600                                 reg_t b;
4601
4602                                 a= pop_reg();
4603                                 b= alloc_reg();
4604                                 "set    trpim, $b";
4605                                 "st     $a, [$b]";
4606                                 free_reg(a);
4607                                 free_reg(b);
4608                         }.
4609
4610
4611 C_str
4612         $1 == 0         ==>
4613                                 Comment( str , $1 );
4614                                 flush_cache();
4615                                 "ld     [$reg_sp], $reg_lb";
4616                                 "add    $reg_lb, 4, %fp";
4617                                 "and    %fp, -8, %fp";
4618                                 "inc    STACK_CLICK, $reg_sp"
4619                                 .
4620         $1 == 1         ==>
4621         {
4622                 Comment( str , $1 );
4623                 flush_cache();
4624                 "ld [$reg_sp], $reg_sp";
4625         }.
4626         $1 == 2         ==>
4627         {
4628                 Comment( str , $1 );
4629                 force_alloc_output();
4630                 pop_reg_as(reg_o0);
4631                 "call   strhp";
4632                 "nop";
4633                 free_output();
4634         }.
4635         default         ==>
4636                                 arg_error( "str", $1).
4637
4638
4639 C_trp           ==>
4640                         Comment0( trp );
4641                         force_alloc_output();
4642                         pop_reg_as(reg_o0);
4643                         flush_cache();
4644                         "call   trp";
4645                         "nop";
4646                         free_output().
4647
4648 /*****************************************************************************/
4649
4650 ..icon
4651         $2 == 1         ==>
4652                                 Comment( ..icon , $1 );
4653                                 gen1( (ONE_BYTE) atoi( $1)).
4654         $2 == 2         ==>
4655                                 Comment( ..icon , $1 );
4656                                 gen2( (TWO_BYTES) atoi( $1)).
4657         $2 == 4         ==>
4658                                 Comment( ..icon , $1 );
4659                                 gen4( (FOUR_BYTES) atol( $1)).
4660         default         ==>
4661                                 arg_error( "icon", $2).
4662
4663 ..ucon
4664         $2 == 1         ==>
4665                                 Comment( ..ucon , $1 );
4666                                 gen1( (ONE_BYTE) atoi( $1)).
4667         $2 == 2         ==>
4668                                 Comment( ..ucon , $1 );
4669                                 gen2( (TWO_BYTES) atoi( $1)).
4670         $2 == 4         ==>
4671                                 Comment( ..ucon , $1 );
4672                                 gen4( (FOUR_BYTES) atol( $1)).
4673         default         ==>
4674                                 arg_error( "icon", $2).
4675
4676 ..fcon                  ==>
4677                                 Comment( ..fcon , $1 );
4678                                 con_float($1, $2).
4679
4680 /*****************************************************************************/
4681
4682 C_prolog                ==>
4683         Comment0( prolog );
4684         init_cache();
4685         "sub    $reg_sp, (EM_BSIZE-4), %g1";
4686         "and    %g1, -8, %sp";
4687         "mov    $reg_sp, %g1";
4688         "save   %sp, $reg_gap, %sp";
4689         "st     %g0, [%sp+BP_OFFSET]";
4690         "sub    %g1, EM_BSIZE, $reg_lb";
4691         init_reg_man();
4692         forced_alloc_reg(reg_sp);
4693         forced_alloc_reg(reg_lb);
4694         forced_alloc_reg(reg_gap);
4695 #ifdef FAST_LIN_LNI_FIL
4696         reg_lin = alloc_reg();
4697         reg_fil = alloc_reg();
4698 #endif
4699         .
4700 C_jump                  ==>
4701         {
4702                 char *l;
4703
4704                 Comment( jump , $1 );
4705                 l= $1;
4706                 "b      $l";
4707                 "nop";  /* delay slot */
4708         }.
4709
4710 C_locals                ==>
4711         {
4712                 Comment( locals , $1 );
4713
4714                 soft_alloc_reg(reg_lb);
4715                 push_reg(reg_lb);
4716                 inc_tos(-($1));
4717                 pop_reg_as(reg_sp);
4718         }.