OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [cpu/] [common/] [parse.c] - Blame information for rev 6

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 cvs
/* parce.c -- Architecture independent load and parsing of assembly
2
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
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 2 of the License, or
9
(at your option) any later version.
10
 
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.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
#include <stdio.h>
21
#include <ctype.h>
22
#include <string.h>
23
#include <stdlib.h>
24
 
25
#include "parse.h"
26
#include "abstract.h"
27
 
28
#define MAXLINE_LEN     18000
29
 
30 6 lampret
/* Struct labelref that is used in linked list for fixing label refs
31
   after program is loaded to memory. */
32
 
33
struct st_labelref {
34
        struct st_labelref *next;
35
        unsigned long addr;
36
        char label[100];
37
} *labelref = NULL;
38
 
39 2 cvs
/* Unused mem memory marker. It is used when allocating program and data memory
40
   during parsing */
41
unsigned int freemem;
42
 
43
int nonempty(char *line)
44
{
45
        int i;
46
 
47
        for(i = 0; i < strlen(line); i++)
48
                if (!isspace(line[i]))
49
                        return(1);
50
        return(0);
51
}
52
 
53
int nondigit(char *line)
54
{
55
        int i;
56
 
57
        for(i = 0; i < strlen(line); i++)
58
                if (!isdigit(line[i]))
59
                        return(1);
60
        return(0);
61
}
62
 
63
char *strtoken(char *in, char *out, int which)
64
{
65
        char    *super;
66
        char    *sub;
67
        char    *newline;
68
 
69
        super = strdup(in);
70
        sub = strtok(super, " \t");
71
        while (sub && --which)
72
                sub = strtok(NULL, " \t");
73
        if (sub && !which) {
74
                if ((newline = strchr(sub, '\n')))
75
                        newline[0] = '\0';
76
                strcpy(out, sub);
77
        } else
78
                out[0] = '\0';
79
        free(super);
80
        if ((newline = strchr(out, '\r')))      /* get rid of CR */
81
                newline[0] = '\0';
82
        return(out);
83
}
84
 
85
void adddatastr(char *str)
86
{
87
        if (str)
88
                str++;
89
        else
90
                return;
91
 
92
        for(; *str && *str != '\"'; str++, freemem++)
93
                if (*str == '\\')
94
                        switch (*++str) {
95
                                case 'n': mem[freemem].data = '\n';
96
                                        break;
97
                                case 't': mem[freemem].data = '\t';
98
                                        break;
99
                                case 'r': mem[freemem].data = '\r';
100
                                        break;
101
                                case '0': mem[freemem].data = '\0';
102
                                        break;
103
                                default: break;
104
                        }
105
                else
106
                        mem[freemem].data = *str;
107
}
108
 
109 6 lampret
int is_str(char *str)
110
{
111
        char *c;
112
 
113
        for (c = str; *c != '\0'; c++)
114
                if (isalpha(*c))
115
                        return 1;
116
 
117
        return 0;
118
}
119
 
120
void handle_labelref(struct st_labelref *root)
121
{
122
        unsigned long label;
123
        struct st_labelref *tmp;
124
 
125
        while (root) {
126
                label = eval_label(root->label);
127
                mem[root->addr].data = (char) (label >> 24);
128
                mem[root->addr + 1].data = (char) (label >> 16);
129
                mem[root->addr + 2].data = (char) (label >> 8);
130
                mem[root->addr + 3].data = (char) (label);
131
 
132
                tmp = root->next;
133
                free(root);
134
                root = tmp;
135
        }
136
}
137
 
138 2 cvs
void adddataword(char *num)
139
{
140
 
141 6 lampret
        if (is_str(num)) {
142
                struct st_labelref *new = malloc(sizeof(struct st_labelref));
143
                strcpy(new->label, num);
144
                new->addr = freemem;
145
                new->next = labelref;
146
                labelref = new;
147
        } else {
148
                mem[freemem].data = (char) (atol(num) >> 24);
149
                mem[freemem + 1].data = (char) (atol(num) >> 16);
150
                mem[freemem + 2].data = (char) (atol(num) >> 8);
151
                mem[freemem + 3].data = (char) (atol(num));
152
        }
153
 
154 2 cvs
        freemem += 4;
155
}
156
 
157
void adddatahalf(char *num)
158
{
159
        mem[freemem].data = (char) (atol(num) >> 8);
160
        mem[freemem + 1].data = (char) (atol(num));
161
 
162
        freemem += 2;
163
}
164
 
165
void adddatabyte(char *num)
166
{
167
        mem[freemem].data = (char) (atol(num));
168
 
169
        freemem++;
170
}
171
 
172
void adddataspace(char *num)
173
{
174
        freemem += atol(num);
175
}
176
 
177
void addlabel(char *label)
178
{
179
        if (strstr(label, LABELEND_CHAR)) {
180
                *strstr(label, LABELEND_CHAR) = '\0';
181
                strcpy(mem[freemem].label, label);
182
        }
183
 
184
        return;
185
}
186
 
187
void addprogram(char *insn, char *operands)
188
{
189
 
190
        strcpy(mem[freemem].insn, insn);
191
 
192
        /* op1 */
193
        if (*operands)
194
                strcpy(mem[freemem].op1, operands);
195
        if (strstr(mem[freemem].op1, OPERAND_DELIM)) {
196
                operands = strstr(mem[freemem].op1, OPERAND_DELIM);
197
                *operands = '\0';
198
                operands++;
199
        } else {
200
                freemem += 4;
201
                return;
202
        }
203
 
204
        /* op2 */
205
        if (*operands)
206
                strcpy(mem[freemem].op2, operands);
207
        if (strstr(mem[freemem].op2, OPERAND_DELIM)) {
208
                operands = strstr(mem[freemem].op2, OPERAND_DELIM);
209
                *operands = '\0';
210
                operands++;
211
        } else {
212
                freemem += 4;
213
                return;
214
        }
215
 
216
        /* op3 */
217
        if (*operands)
218
                strcpy(mem[freemem].op3, operands);
219
        if (strstr(mem[freemem].op3, OPERAND_DELIM)) {
220
                operands = strstr(mem[freemem].op3, OPERAND_DELIM);
221
                *operands = '\0';
222
                operands++;
223
        } else {
224
                freemem += 4;
225
                return;
226
        }
227
 
228
        /* op4 */
229
        if (*operands)
230
                strcpy(mem[freemem].op4, operands);
231
        if (strstr(mem[freemem].op4, OPERAND_DELIM)) {
232
                operands = strstr(mem[freemem].op4, OPERAND_DELIM);
233
                *operands = '\0';
234
                operands++;
235
        }
236
 
237
        freemem += 4;
238
        return;
239
}
240
 
241
/* Non-architecture dependent parsing: stripping comments, filling
242
   abstract memory */
243
 
244
void parseline(char *inputline)
245
{
246
        char item[MAXLINE_LEN];
247
        char item2[MAXLINE_LEN];
248
        int  i = 0;
249
 
250
        /* Strip comments: simply terminate line where
251
           the first comment character appears. */
252
 
253
        debug("PARSING: %s", inputline);
254
        while (inputline[i] != '\0')
255
                if (inputline[i] == COMMENT_CHAR) {
256
                        inputline[i] = '\0';
257
                        break;
258
                } else
259
                        i++;
260
 
261
        /* Get the first item from this line */
262
        strtoken(inputline, item, 1);
263
        strtoken(inputline, item2, 2);
264
 
265
        /* Is this item empty? Nothing to process, so return. */
266
        if (strlen(item) == 0)
267
                return;
268
 
269
        /* Is this item a label? If yes, add it to the label
270
           table and return immediately. */
271
        if (strstr(item, LABELEND_CHAR)) {
272
                addlabel(item);
273
                return;
274
        }
275
 
276
        /* Is this item a .directive? If yes, check for some supported
277
           and then return (even if unsupported found). */
278
        if (item[0] == DIRECTIVE_CHAR) {
279
                if ((strcmp(item, ".align") == 0) && (freemem % 4)) {
280
                        freemem &= -4;  /* e.g. 0xfffffffc */
281
                        freemem += 4;   /* always align to word */
282
                        return;
283
                } else
284
                if (strcmp(item, ".ascii") == 0) {
285
                        adddatastr(strstr(inputline, "\""));
286
                        return;
287
                } else
288
                if (strcmp(item, ".word") == 0) {
289
                        adddataword(item2);
290
                        return;
291
                } else
292
                if (strcmp(item, ".half") == 0) {
293
                        adddatahalf(item2);
294
                        return;
295
                } else
296
                if (strcmp(item, ".byte") == 0) {
297
                        adddatabyte(item2);
298
                        return;
299
                } else
300
                if (strcmp(item, ".space") == 0) {
301
                        adddataspace(item2);
302
                        return;
303
                } else  /* .directive but not one of the supported */
304
                        return;
305
        }
306
 
307
        /* This item can only be an instruction. Get all operands
308
           and add everything to mem array but as a program. */
309
        addprogram(item, item2);
310
 
311
        /* Also do static, single stats. */
312
        addsstats(item, 0, 1);
313
 
314
        return;
315
 
316
}
317
 
318
/* Load file and hand over every line to parse routine. */
319
 
320
void readfile(char *filename)
321
{
322
        FILE *inputfs;
323
        char  inputbuf[MAXLINE_LEN];
324
        char  *status;
325
 
326
        if ((inputfs = fopen(filename, "r"))) {
327
                while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) {
328
                        if (nonempty(inputbuf))
329
                                parseline(inputbuf);
330
                }
331
                fclose(inputfs);
332
        }
333
        else
334
                perror("readfile");
335
 
336
        return;
337
}
338
 
339
 
340
void loadcode(char *filename)
341
{
342
        freemem = 0;
343
        memset(mem, 0, sizeof(mem));
344
        readfile(filename);
345 6 lampret
        handle_labelref(labelref);
346 2 cvs
        return;
347
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.