3657d3c4980b689cdb5f6643dca1c6342d28dafc
[fw/sdcc] / as / mcs51 / i51adr.c
1 /* i51adr.c */
2
3 /*
4  * (C) Copyright 1989,1990
5  * All Rights Reserved
6  *
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10  *
11  * Ported from 8085 to 8051 by John Hartman 30-Apr-1995
12  * Continued, 29-May-95
13  */
14
15 #include <stdio.h>
16 #include <setjmp.h>
17 #include "asm.h"
18 #include "i8051.h"
19
20 extern int admode (struct adsym *);
21
22 struct adsym reg51[] = {        /* R0 thru R7 registers */
23 {       "R0",   R0},
24 {       "R1",   R1},
25 {       "R2",   R2},
26 {       "R3",   R3},
27 {       "R4",   R4},
28 {       "R5",   R5},
29 {       "R6",   R6},
30 {       "R7",   R7},
31 {       "A",    A},
32 {       "DPTR", DPTR},
33 {       "PC",   PC},
34 {       "C",    C},
35 {       "AB",   AB},
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}
50 };
51
52 /*  Classify argument as to address mode */
53 int
54 addr(esp)
55 register struct expr *esp;
56 {
57         register int c;
58         register unsigned rd;
59
60         if ((c = getnb()) == '#') {
61                 /*  Immediate mode */
62                 expr(esp, 0);
63                 esp->e_mode = S_IMMED;
64         }
65         else if (c == '@') {
66                 /* choices are @R0, @R1, @DPTR, @A+PC, @A+DPTR */
67                 switch (reg()) {
68                 case R0:
69                         esp->e_mode = S_AT_R;
70                         esp->e_addr = R0;
71                         break;
72                 case R1:
73                         esp->e_mode = S_AT_R;
74                         esp->e_addr = R1;
75                         break;
76                 case DPTR:
77                         esp->e_mode = S_AT_DP;
78                         esp->e_addr = DPTR;
79                         break;
80                 case A:
81                         if (getnb() == '+') {
82                                 rd = reg();
83                                 if (rd == PC) {
84                                         esp->e_mode = S_AT_APC;
85                                         esp->e_addr = 0;
86                                 } else if (rd == DPTR) {
87                                         esp->e_mode = S_AT_ADP;
88                                         esp->e_addr = 0;
89                                 } else {
90                                         aerr();
91                                 }
92                         } else
93                                 aerr();
94                         break;
95                 }
96
97                 esp->e_flag = 0;
98                 esp->e_base.e_ap = NULL;
99         }
100         else if (c == '*') {
101                 /* Force direct page */
102                 expr(esp, 0);
103                 esp->e_mode = S_DIR;
104                 if (esp->e_addr & ~0xFF)
105                         err('d');
106         }
107         else if (c == '/') {
108                 /* Force inverted bit  */
109                 expr(esp, 0);
110                 esp->e_mode = S_NOT_BIT;
111                 if (esp->e_addr & ~0xFF)
112                         err('d');
113         }
114         else {
115                 unget(c);
116
117                 /* try for register: A, AB, R0-R7, DPTR, PC, Cy */
118                 if ((esp->e_addr = admode(reg51)) != -1) {
119                         switch (esp->e_addr) {
120                         case A:
121                                 esp->e_mode = S_A;
122                                 break;
123                         case AB:
124                                 esp->e_mode = S_RAB;
125                                 break;
126                         case DPTR:
127                                 esp->e_mode = S_DPTR;
128                                 break;
129                         case PC:
130                                 esp->e_mode = S_PC;
131                                 break;
132                         case C:
133                                 esp->e_mode = S_C;
134                                 break;
135                         default:
136                                 /* R0-R7 */
137                                 esp->e_mode = S_REG;
138                         }
139                 } else {
140                         /* Must be an expression */
141                         expr(esp, 0);
142                         if ((!esp->e_flag)
143                                 && (esp->e_base.e_ap==NULL)
144                                 && !(esp->e_addr & ~0xFF)) {
145                                 esp->e_mode = S_DIR;
146                         } else {
147                                 esp->e_mode = S_EXT;
148                         }
149                 }
150         }
151         return (esp->e_mode);
152 }
153
154
155 /*
156  *      any --- does str contain c?
157  */
158 int
159 any(c,str)
160 char    c, *str;
161 {
162         while (*str)
163                 if(*str++ == c)
164                         return(1);
165         return(0);
166 }
167
168 int
169 srch(str)
170 register char *str;
171 {
172         register const char *ptr;
173         ptr = ip;
174
175 #if     CASE_SENSITIVE
176         while (*ptr && *str) {
177                 if(*ptr != *str)
178                         break;
179                 ptr++;
180                 str++;
181         }
182         if (*ptr == *str) {
183                 ip = ptr;
184                 return(1);
185         }
186 #else
187         while (*ptr && *str) {
188                 if(ccase[*ptr] != ccase[*str])
189                         break;
190                 ptr++;
191                 str++;
192         }
193         if (ccase[*ptr] == ccase[*str]) {
194                 ip = ptr;
195                 return(1);
196         }
197 #endif
198
199         if (!*str)
200                 if (any(*ptr," \t\n,];")) {
201                         ip = ptr;
202                         return(1);
203                 }
204         return(0);
205 }
206
207 /*
208  * Enter admode() to search a specific addressing mode table
209  * for a match. Return the addressing value on a match or
210  * -1 for no match.
211  */
212 int
213 admode(sp)
214 register struct adsym *sp;
215 {
216         register char *ptr;
217         register int i;
218         unget(getnb());
219         i = 0;
220         while ( *(ptr = (char *) &sp[i]) ) {
221                 if (srch(ptr)) {
222                         return(sp[i].a_val);
223                 }
224                 i++;
225         }
226         return(-1);
227 }
228
229 /*
230  *      srch --- does string match ?
231  */
232
233 /*
234  * Read a register name.  Return register value, -1 if no register found
235  */
236 int
237 reg()
238 {
239         register struct mne *mp;
240         char id[NCPS];
241
242         getid(id, -1);
243         if ((mp = mlookup(id))==NULL) {
244                 aerr();
245                 return (-1);
246         }
247         switch (mp->m_type) {
248         case S_A:
249         case S_AB:
250         case S_DPTR:
251         case S_PC:
252         case S_REG:
253                 return (mp->m_valu);
254
255         default:
256                 return (-1);
257         }
258 }