struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / as6500 / r65adr.c
blob828046acf996c28ad0eb2e9dc7a20ce8a7dd6096
1 /* r65adr.c */
3 /*
4 * Copyright (C) 1995-2021 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
26 * With Contributions from
28 * Marko Makela
29 * Sillitie 10 A
30 * 01480 Vantaa
31 * Finland
32 * Internet: Marko dot Makela at Helsinki dot Fi
33 * EARN/BitNet: msmakela at finuh
36 #include "asxxxx.h"
37 #include "r6500.h"
39 int
40 addr(esp)
41 struct expr *esp;
43 int c;
44 char *p;
46 /* fix order of '<', '>', and '#' */
47 p = ip;
48 if (((c = getnb()) == '<') || (c == '>')) {
49 p = ip-1;
50 if (getnb() == '#') {
51 *p = *(ip-1);
52 *(ip-1) = c;
55 ip = p;
57 if ((c = getnb()) == '#') {
58 expr(esp, 0);
59 esp->e_mode = S_IMMED;
60 } else
61 if (c == '*') {
62 expr(esp, 0);
63 esp->e_mode = S_DIR; /* ___ *arg */
64 if (more()) {
65 comma(1);
66 switch(admode(axy)) {
67 case S_X:
68 esp->e_mode = S_DINDX; /* ___ *arg,X */
69 break;
70 case S_Y:
71 esp->e_mode = S_DINDY; /* ___ *arg,Y */
72 break;
73 default:
74 aerr();
75 break;
78 } else if (c == '[') {
79 if ((c = getnb()) != '*') {
80 unget(c);
82 expr(esp, 0);
83 if ((c = getnb()) == ']') {
84 if (more()) {
85 comma(1);
86 if (admode(axy) != S_Y)
87 qerr();
88 esp->e_mode = S_IPSTY;
89 } else {
90 esp->e_mode = S_IND;
92 } else {
93 unget(c);
94 comma(1);
95 if (admode(axy) != S_X)
96 qerr();
97 esp->e_mode = S_IPREX;
98 if (getnb() != ']')
99 qerr();
101 } else {
102 unget(c);
103 switch(admode(axy)) {
104 case S_A:
105 esp->e_mode = S_ACC; /* ___ A */
106 break;
107 case S_X: /* ___ X Is Illegal */
108 case S_Y: /* ___ Y Is Illegal */
109 aerr();
110 break;
111 default:
112 if (!more()) {
113 esp->e_mode = S_ACC; /* ___ BLANK -> ___ A */
114 } else {
115 expr(esp, 0);
116 if (more()) {
117 comma(1);
118 switch(admode(axy)) {
119 case S_X: /* ___ arg,X */
120 if ((!esp->e_flag)
121 && (esp->e_base.e_ap==NULL)
122 && !(esp->e_addr & ~0xFF)) {
123 esp->e_mode = S_DINDX;
124 } else {
125 if ((!esp->e_flag)
126 && (zpg != NULL)
127 && (esp->e_base.e_ap==zpg)) {
128 esp->e_mode = S_DINDX;
129 } else {
130 esp->e_mode = S_INDX;
133 break;
134 case S_Y: /* ___ arg,Y */
135 if ((!esp->e_flag)
136 && (esp->e_base.e_ap==NULL)
137 && !(esp->e_addr & ~0xFF)) {
138 esp->e_mode = S_DINDY;
139 } else {
140 if ((!esp->e_flag)
141 && (zpg != NULL)
142 && (esp->e_base.e_ap==zpg)) {
143 esp->e_mode = S_DINDY;
144 } else {
145 esp->e_mode = S_INDY;
148 break;
149 default:
150 aerr();
151 break;
153 } else {
154 if ((!esp->e_flag)
155 && (esp->e_base.e_ap==NULL)
156 && !(esp->e_addr & ~0xFF)) {
157 esp->e_mode = S_DIR;
158 } else {
159 if ((!esp->e_flag)
160 && (zpg != NULL)
161 && (esp->e_base.e_ap==zpg)) {
162 esp->e_mode = S_DIR;
163 } else {
164 esp->e_mode = S_EXT;
171 return (esp->e_mode);
175 * When building a table that has variations of a common
176 * symbol always start with the most complex symbol first.
177 * for example if x, x+, and x++ are in the same table
178 * the order should be x++, x+, and then x. The search
179 * order is then most to least complex.
183 * When searching symbol tables that contain characters
184 * not of type LTR16, eg with '-' or '+', always search
185 * the more complex symbol tables first. For example:
186 * searching for x+ will match the first part of x++,
187 * a false match if the table with x+ is searched
188 * before the table with x++.
192 * Enter admode() to search a specific addressing mode table
193 * for a match. Return the addressing value on a match or
194 * zero for no match.
197 admode(sp)
198 struct adsym *sp;
200 char *ptr;
201 int i;
202 char *ips;
204 ips = ip;
205 unget(getnb());
207 i = 0;
208 while ( *(ptr = &sp[i].a_str[0]) ) {
209 if (srch(ptr)) {
210 return(sp[i].a_val);
212 i++;
214 ip = ips;
215 return(0);
219 * srch --- does string match ?
222 srch(str)
223 char *str;
225 char *ptr;
226 ptr = ip;
228 while (*ptr && *str) {
229 if(ccase[*ptr & 0x007F] != ccase[*str & 0x007F])
230 break;
231 ptr++;
232 str++;
234 if (ccase[*ptr & 0x007F] == ccase[*str & 0x007F]) {
235 ip = ptr;
236 return(1);
239 if (!*str)
240 if (!(ctype[*ptr & 0x007F] & LTR16)) {
241 ip = ptr;
242 return(1);
244 return(0);
247 struct adsym axy[] = { /* a, x, or y registers */
248 { "a", S_A },
249 { "x", S_X },
250 { "y", S_Y },
251 { "", 0x00 }