Pristine Ack-5.5
[Ack-5.5.git] / util / ego / share / stack_chg.c
1 /* $Id: stack_chg.c,v 1.6 1994/06/24 10:30:57 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  */
6 /* S T A C K _ C H A N G E . C */
7
8
9 #include <stdio.h>
10 #include <em_spec.h>
11 #include <em_mnem.h>
12 #include "types.h"
13 #include "debug.h"
14 #include "global.h"
15
16 #include "pop_push.h"
17
18 #define IS_LOC(l)       (l!=(line_p) 0 && INSTR(l)==op_loc && TYPE(l)==OPSHORT)
19
20 int stack_change(l,sign)
21         line_p l;
22         char sign;
23 {
24         /* Interpret the string in the third column of the em_table file */
25
26         char *s;
27         bool argdef;
28         short arg = 0;
29         int sum = 0;
30         line_p p = PREV(l);
31         line_p pp = (p == (line_p) 0 ? (line_p) 0 : PREV(p));
32         short i = INSTR(l);
33
34         if (i < sp_fmnem || i > sp_lmnem) {
35                 return 0;
36         }
37         if (TYPE(l) == OPSHORT) {
38                 arg = SHORT(l);
39                 if (arg < ws) {
40                         /* E.g. a LOI 1 loads word-size bytes,
41                          * not 1 byte!
42                          */
43                         arg = ws;
44                 }
45                 argdef = TRUE;
46         } else {
47                 argdef = FALSE;
48         }
49         s = pop_push[i];
50         if (*s == '0') return 0;
51         while (*s != '\0') {
52                 if (*s++ == sign) {
53                         switch(*s) {
54                                 case 'w':
55                                         sum +=  ws;
56                                         break;
57                                 case 'd':
58                                         sum += 2 * ws;
59                                         break;
60                                 case 'p':
61                                         sum += ps;
62                                         break;
63                                 case 'a':
64                                         if (!argdef) return -1;
65                                         sum +=  arg;
66                                         break;
67                                 case 'x':
68                                         if (IS_LOC(p)) {
69                                                 sum += SHORT(p);
70                                                 break;
71                                         } else {
72                                                 return -1;
73                                         }
74                                 case 'y':
75                                         if (IS_LOC(pp)) {
76                                                 sum += SHORT(pp);
77                                                 break;
78                                         } else {
79                                                 return -1;
80                                         }
81                                 case '?':
82                                         return -1;
83                                 default:
84                                         assert(FALSE);
85                         }
86                 }
87                 s++;
88         }
89         return sum;
90 }
91
92
93
94 line_change(l,ok_out,pop_out,push_out)
95         line_p l;
96         bool *ok_out;
97         int *pop_out,*push_out;
98 {
99         short pop,push;
100
101         pop = stack_change(l,'-');
102         push = stack_change(l,'+');
103         *ok_out = (pop != -1 && push != -1);
104         *pop_out = pop;
105         *push_out = push;
106 }
107
108