struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / asrab / rabadr.c
blobc34c6db6417d2cfae902b7d2fbada598b2a1178b
1 /* rabadr.c */
3 /*
4 * Copyright (C) 1989-2009 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
24 * ported to the Rabbit2000 by
25 * Ulrich Raich and Razaq Ijoduola
26 * PS Division
27 * CERN
28 * CH-1211 Geneva-23
29 * email: Ulrich dot Raich at cern dot ch
33 * xerr messages and order fix Copyright (C) 1989-2021 Alan R. Baldwin
34 * from ASxxxx 5.40
38 * Extensions: P. Felber
40 * Altered by Leland Morrison to support rabbit 2000
41 * and rabbit 4000 instruction sets (2011)
44 #include "asxxxx.h"
45 #include "rab.h"
48 * Read an address specifier. Pack the
49 * address information into the supplied
50 * `expr' structure. Return the mode of
51 * the address.
53 * This addr(esp) routine performs the following addressing decoding:
55 * address mode flag addr base
56 * #n S_IMMED 0 n NULL
57 * label s_type ---- s_addr s_area
58 * [REG] S_IND+icode 0 0 NULL
59 * [label] S_INDM ---- s_addr s_area
60 * offset[REG] S_IND+icode ---- offset ----
62 int
63 addr(esp)
64 struct expr *esp;
66 int c, mode, indx;
67 char *p;
69 /* fix order of '<', '>', and '#' */
70 p = ip;
71 if (((c = getnb()) == '<') || (c == '>')) {
72 p = ip-1;
73 if (getnb() == '#') {
74 *p = *(ip-1);
75 *(ip-1) = c;
78 ip = p;
80 if ((c = getnb()) == '#') {
81 expr(esp, 0);
82 esp->e_mode = S_IMMED;
83 #if 0
84 /* ljm - leading digit is used for offset for dd(ix|iy|sp) */
85 } else if ((c == '-') || ((c >= '0') && (c <= '9'))) {
86 unget(c);
87 expr(esp, 0);
88 esp->e_mode = S_IMMED;
89 #endif
90 } else
91 if (c == LFIND) {
92 /* ljm comment -
93 * '(' number ')'
94 * or '(' register=[hl,ix,iy,sp,bc,de] ')'
95 * ref to memory, scan the next 'symbol' to see if
96 * it is a register or an absolute address
98 if ((indx = admode(R8)) != 0) {
99 mode = S_INDB;
100 } else
101 if ((indx = admode(R8X)) != 0) {
102 mode = S_R8X;
103 aerr();
104 } else
105 if ((indx = admode(R16AF_ALT)) != 0) {
106 mode = S_R16AF_ALT;
107 aerr();
108 } else
109 if ((indx = admode(R16AF)) != 0) {
110 mode = S_R16AF;
111 aerr();
112 } else
113 if ((indx = admode(R16)) != 0) {
114 mode = S_INDR;
115 } else {
116 mode = S_INDM;
117 expr(esp, 0);
118 esp->e_mode = mode;
120 if (indx) {
121 esp->e_mode = (mode + indx)&0xFF;
122 esp->e_base.e_ap = NULL;
124 /* ljm comment -
125 * flag an error if the closing paren is absent
127 if ((c = getnb()) != RTIND) {
128 xerr('q', "Missing ')'.");
130 } else {
131 unget(c);
132 /* ljm -
133 * cases:
134 * register
135 * symbol
136 * symbol(register)
137 * number
138 * number(register)
140 * scan the list(s) of registers to see if the
141 * name matches the name of one of the processor
142 * registers
144 if ((indx = admode(R8)) != 0) {
145 mode = S_R8;
146 } else
147 if ((indx = admode(R8X)) != 0) {
148 mode = S_R8X;
149 } else
150 if ((indx = admode(R16AF_ALT)) != 0) {
151 mode = S_R16AF_ALT;
152 } else
153 if ((indx = admode(R16AF)) != 0) {
154 mode = S_R16AF;
155 } else
156 if ((indx = admode(R16_ALT)) != 0) {
157 mode = S_R16_ALT;
158 } else
159 if ((indx = admode(R16)) != 0) {
160 mode = S_R16;
161 } else
162 if ((indx = admode(R32_JKHL)) != 0) {
163 mode = S_R32_JKHL;
164 } else
165 if ((indx = admode(R32_BCDE)) != 0) {
166 mode = S_R32_BCDE;
167 } else
168 if ((indx = admode(RXPC)) != 0) {
169 mode = S_RXPC;
170 } else {
171 mode = S_USER;
172 expr(esp, 0);
173 esp->e_mode = mode;
175 if (indx) {
176 esp->e_addr = indx&0xFF;
177 esp->e_mode = mode;
178 esp->e_base.e_ap = NULL;
180 if ((c = getnb()) == LFIND) {
181 indx = admode(R16);
182 if ((indx&0xFF)==IX || (indx&0xFF)==IY ||
183 (indx&0xFF)==SP)
185 esp->e_mode = S_INDR + (indx&0xFF);
186 } else if ( (indx&0xFF)==HL ) {
187 esp->e_mode = S_IDHL_OFFSET;
188 } else {
189 xerr('a', "BC, DE, HL, SP, IX, or IY required.");
191 if ((c = getnb()) != RTIND)
192 xerr('q', "Missing ')'.");
193 } else {
194 unget(c);
197 return (esp->e_mode);
201 * Enter admode() to search a specific addressing mode table
202 * for a match. Return the addressing value on a match or
203 * zero for no match.
206 admode(sp)
207 struct adsym *sp;
209 char *ptr;
210 int i;
211 char *ips;
213 ips = ip;
214 unget(getnb());
216 i = 0;
217 while ( *(ptr = &sp[i].a_str[0]) ) {
218 if (srch(ptr)) {
219 return(sp[i].a_val);
221 i++;
223 ip = ips;
224 return(0);
228 * srch --- does string match ?
231 srch(str)
232 char *str;
234 char *ptr;
235 ptr = ip;
237 while (*ptr && *str) {
238 if (ccase[*ptr & 0x007F] != ccase[*str & 0x007F])
239 break;
240 ptr++;
241 str++;
243 if (ccase[*ptr & 0x007F] == ccase[*str & 0x007F]) {
244 ip = ptr;
245 return(1);
248 if (!*str) {
249 if (!(ctype[*ptr & 0x007F] & LTR16)) {
250 ip = ptr;
251 return(1);
254 return(0);
258 * Registers
261 struct adsym R8[] = {
262 { "b", B|0400 },
263 { "c", C|0400 },
264 { "d", D|0400 },
265 { "e", E|0400 },
266 { "h", H|0400 },
267 { "l", L|0400 },
268 { "a", A|0400 },
269 { "", 0000 }
272 struct adsym R8X[] = {
273 { "eir", EIR|0400},
274 { "iir", IIR|0400},
275 { "", 0000 }
278 struct adsym R8IP[] = {
279 { "ip", IP|0400 },
280 { "", 0000 }
283 struct adsym R16[] = {
284 { "bc", BC|0400 },
285 { "de", DE|0400 },
286 { "hl", HL|0400 },
287 { "sp", SP|0400 },
288 { "ix", IX|0400 },
289 { "iy", IY|0400 },
290 { "", 0000 }
293 struct adsym R16_ALT[] = {
294 { "bc'", BC|0400 },
295 { "de'", DE|0400 },
296 { "hl'", HL|0400 },
297 { "", 0000 }
300 struct adsym R16AF[] = {
301 { "af", AF|0400 },
302 { "", 0000 }
305 struct adsym R16AF_ALT[] = {
306 { "af'", AF|0400 },
307 { "", 0000 }
310 struct adsym R32_BCDE[] = {
311 { "bcde", BCDE|0400 },
312 { "", 0000 }
315 struct adsym R32_JKHL[] = {
316 { "jkhl", JKHL|0400 },
317 { "", 0000 }
320 struct adsym RXPC[] = {
321 { "xpc", 1|0400 },
322 { "", 0000 }
326 * Conditional definitions
329 struct adsym CND[] = {
330 { "NZ", NZ|0400 },
331 { "Z", Z |0400 },
332 { "NC", NC|0400 },
333 { "C", CS|0400 },
334 { "LZ", PO|0400 },
335 { "LO", PE|0400 },
336 { "P", P |0400 },
337 { "M", M |0400 },
338 { "", 0000 }
341 struct adsym ALT_CND[] = {
342 { "GT", CC_GT|0400 },
343 { "GTU", CC_GTU|0400 },
344 { "LT", CC_LT|0400 },
345 { "V", CC_V |0400 },
346 { "NZ", CC_NZ|0400 },
347 { "Z", CC_Z |0400 },
348 { "NC", CC_NC|0400 },
349 { "C", CC_C |0400 },
350 { "", 0000 }