struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / asgb / gbadr.c
blobbd1ac3e036026d3dd9062344c7f9bfc9a5da3f98
1 /* gbadr.c */
3 /*
4 * Copyright (C) 1989-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
25 /* TODO: check if differences/extension still needed*/
28 * Extensions: P. Felber
30 * they seem to be:
31 * (indx&0xFF) related
32 * any() related
33 * hl+ and hl-
36 #include "asxxxx.h"
37 #include "gb.h"
40 * Read an address specifier. Pack the
41 * address information into the supplied
42 * `expr' structure. Return the mode of
43 * the address.
45 * This addr(esp) routine performs the following addressing decoding:
47 * address mode flag addr base
48 * #n S_IMMED 0 n NULL
49 * label s_type ---- s_addr s_area
50 * [REG] S_IND+icode 0 0 NULL
51 * [label] S_INDM ---- s_addr s_area
52 * offset[REG] S_IND+icode ---- offset ----
54 int
55 addr(esp)
56 struct expr *esp;
58 int c, mode, indx;
59 char *p;
61 /* fix order of '<', '>', and '#' */
62 p = ip;
63 if (((c = getnb()) == '<') || (c == '>')) {
64 p = ip-1;
65 if (getnb() == '#') {
66 *p = *(ip-1);
67 *(ip-1) = c;
70 ip = p;
72 if ((c = getnb()) == '#') {
73 expr(esp, 0);
74 esp->e_mode = S_IMMED;
75 } else
76 if (c == LFIND) {
77 if ((indx = admode(R8)) != 0) {
78 mode = S_INDB;
79 } else
80 if ((indx = admode(R16)) != 0) {
81 mode = S_INDR;
82 } else
83 if ((indx = admode(R16X)) != 0) {
84 mode = S_R16X;
85 aerr();
86 } else {
87 mode = S_INDM;
88 expr(esp, 0);
89 esp->e_mode = mode;
91 if (indx) {
92 esp->e_mode = (mode + indx)&0xFF;
93 esp->e_base.e_ap = NULL;
95 if ((c = getnb()) != RTIND)
96 xerr('q', "Missing ')'.");
97 } else {
98 unget(c);
99 if ((indx = admode(R8)) != 0) {
100 mode = S_R8;
101 } else
102 if ((indx = admode(R16)) != 0) {
103 mode = S_R16;
104 } else
105 if ((indx = admode(R16X)) != 0) {
106 mode = S_R16X;
107 } else {
108 mode = S_USER;
109 expr(esp, 0);
110 esp->e_mode = mode;
112 if (indx) {
113 esp->e_addr = indx&0xFF;
114 esp->e_mode = mode;
115 esp->e_base.e_ap = NULL;
117 if ((c = getnb()) == LFIND) {
118 if ((indx=admode(R16))!=0) {
119 esp->e_mode = S_INDR + (indx&0xFF);
120 } else {
121 aerr();
123 if ((c = getnb()) != RTIND)
124 qerr();
125 } else {
126 unget(c);
129 return (esp->e_mode);
133 * When building a table that has variations of a common
134 * symbol always start with the most complex symbol first.
135 * for example if x, x+, and x++ are in the same table
136 * the order should be x++, x+, and then x. The search
137 * order is then most to least complex.
141 * When searching symbol tables that contain characters
142 * not of type LTR16, eg with '-' or '+', always search
143 * the more complex symbol tables first. For example:
144 * searching for x+ will match the first part of x++,
145 * a false match if the table with x+ is searched
146 * before the table with x++.
150 * Enter admode() to search a specific addressing mode table
151 * for a match. Return the addressing value on a match or
152 * zero for no match.
155 admode(sp)
156 struct adsym *sp;
158 char *ptr;
159 int i;
160 char *ips;
162 ips = ip;
163 unget(getnb());
165 i = 0;
166 while ( *(ptr = &sp[i].a_str[0]) ) {
167 if (srch(ptr)) {
168 return(sp[i].a_val);
170 i++;
172 ip = ips;
173 return(0);
177 * srch --- does string match ?
180 srch(str)
181 char *str;
183 char *ptr;
184 ptr = ip;
186 while (*ptr && *str) {
187 if (ccase[*ptr & 0x007F] != ccase[*str & 0x007F])
188 break;
189 ptr++;
190 str++;
192 if (ccase[*ptr & 0x007F] == ccase[*str & 0x007F]) {
193 ip = ptr;
194 return(1);
197 if (!*str)
198 if (!(ctype[*ptr & 0x007F] & LTR16) && (*ptr & 0x007F) != '-' && (*ptr & 0x007F) != '+') {
199 ip = ptr;
200 return(1);
202 return(0);
206 * Registers
209 struct adsym R8[] = {
210 { "b", B|0400 },
211 { "c", C|0400 },
212 { "d", D|0400 },
213 { "e", E|0400 },
214 { "h", H|0400 },
215 { "l", L|0400 },
216 { "a", A|0400 },
217 { "", 0000 }
220 struct adsym R16[] = {
221 { "bc", BC|0400 },
222 { "de", DE|0400 },
223 { "hl", HL|0400 },
224 { "sp", SP|0400 },
225 { "hl-", HLD|0400},
226 { "hl+", HLI|0400},
227 { "hld", HLD|0400},
228 { "hli", HLI|0400},
229 { "", 0000 }
232 struct adsym R16X[] = {
233 { "af", AF|0400 },
234 { "", 0000 }
238 * Conditional definitions
241 struct adsym CND[] = {
242 { "NZ", NZ|0400 },
243 { "Z", Z |0400 },
244 { "NC", NC|0400 },
245 { "C", CS|0400 },
246 { "", 0000 }