struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / as8051 / i51adr.c
blobf494fcecdba56623b084d4972958e6f38467dc31
1 /* i51adr.c */
3 /*
4 * Copyright (C) 1998-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 * This Assember Ported by
25 * John L. Hartman (JLH)
26 * jhartman at compuserve dot com
27 * noice at noicedebugger dot com
31 #include "asxxxx.h"
32 #include "i8051.h"
35 struct adsym reg51[] = { /* R0 thru R7 registers */
36 { "R0", R0 },
37 { "R1", R1 },
38 { "R2", R2 },
39 { "R3", R3 },
40 { "R4", R4 },
41 { "R5", R5 },
42 { "R6", R6 },
43 { "R7", R7 },
44 { "A", A },
45 { "DPTR", DPTR },
46 { "PC", PC },
47 { "C", C },
48 { "AB", AB },
49 { "", 0x00 }
52 /* Classify argument as to address mode */
53 int
54 addr(struct expr *esp)
56 int c;
57 unsigned rd;
59 if ((c = getnb()) == '#') {
60 /* Immediate mode */
61 expr(esp, 0);
62 esp->e_mode = S_IMMED;
64 else if (c == '@') {
65 /* choices are @R0, @R1, @DPTR, @A+PC, @A+DPTR */
66 switch (reg()) {
67 case R0:
68 esp->e_mode = S_AT_R;
69 esp->e_addr = R0;
70 break;
71 case R1:
72 esp->e_mode = S_AT_R;
73 esp->e_addr = R1;
74 break;
75 case DPTR:
76 esp->e_mode = S_AT_DP;
77 esp->e_addr = DPTR;
78 break;
79 case A:
80 if (getnb() == '+') {
81 rd = reg();
82 if (rd == PC) {
83 esp->e_mode = S_AT_APC;
84 esp->e_addr = 0;
85 } else if (rd == DPTR) {
86 esp->e_mode = S_AT_ADP;
87 esp->e_addr = 0;
88 } else {
89 xerr('a', "@A+DPTR and A,@A+PC are the allowed modes.");
91 } else
92 xerr('a', "Invalid Addressing Mode.");
93 break;
96 esp->e_flag = 0;
97 esp->e_base.e_ap = NULL;
99 else if (c == '*') {
100 if ((c = getnb()) == '/') {
101 /* Force inverted bit */
102 expr(esp, 0);
103 esp->e_mode = S_NOT_BIT;
104 } else {
105 unget(c);
106 /* Force direct page */
107 expr(esp, 0);
108 esp->e_mode = S_DIR;
110 if (esp->e_addr & ~0xFF)
111 xerr('d', "A Direct Page addressing error.");
113 else if (c == '/') {
114 /* Force inverted bit */
115 expr(esp, 0);
116 esp->e_mode = S_NOT_BIT;
118 else {
119 unget(c);
121 /* try for register: A, AB, R0-R7, DPTR, PC, Cy */
122 if ((esp->e_addr = admode(reg51)) != -1) {
123 switch (esp->e_addr) {
124 case A:
125 esp->e_mode = S_A;
126 break;
127 case AB:
128 esp->e_mode = S_RAB;
129 break;
130 case DPTR:
131 esp->e_mode = S_DPTR;
132 break;
133 case PC:
134 esp->e_mode = S_PC;
135 break;
136 case C:
137 esp->e_mode = S_C;
138 break;
139 default:
140 /* R0-R7 */
141 esp->e_mode = S_REG;
143 } else {
144 /* Must be an expression */
145 esp->e_addr = 0;
146 expr(esp, 0);
147 if ((!esp->e_flag)
148 && (esp->e_base.e_ap==NULL)
149 && !(esp->e_addr & ~0xFF)) {
150 esp->e_mode = S_DIR;
151 } else {
152 esp->e_mode = S_EXT;
156 return (esp->e_mode);
160 * Enter admode() to search a specific addressing mode table
161 * for a match. Return the addressing value on a match or
162 * -1 for no match.
165 admode(struct adsym *sp)
167 char *ptr;
168 int i;
170 unget(getnb());
171 i = 0;
172 while ( *(ptr = &sp[i].a_str[0]) ) {
173 if (srch(ptr)) {
174 return(sp[i].a_val);
176 i++;
178 return(-1);
182 * srch --- does string match ?
185 srch(char *str)
187 char *ptr;
188 ptr = ip;
190 while (*ptr && *str) {
191 if(ccase[*ptr & 0x007F] != ccase[*str & 0x007F])
192 break;
193 ptr++;
194 str++;
196 if (ccase[*ptr & 0x007F] == ccase[*str & 0x007F]) {
197 ip = ptr;
198 return(1);
201 if (!*str)
202 if (any(*ptr," \t\n,];")) {
203 ip = ptr;
204 return(1);
206 return(0);
210 * any --- does str contain c?
213 any(int c, char *str)
215 while (*str)
216 if(*str++ == c)
217 return(1);
218 return(0);
222 * Read a register name. Return register value, -1 if no register found
225 reg(void)
227 struct mne *mp;
228 char id[NCPS];
230 getid(id, -1);
231 if ((mp = mlookup(id))==NULL) {
232 aerr();
233 return (-1);
235 switch (mp->m_type) {
236 case S_A:
237 case S_AB:
238 case S_DPTR:
239 case S_PC:
240 case S_REG:
241 return ((int) mp->m_valu);
243 default:
244 return (-1);