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

Subversion Repositories or1k

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

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 18 lampret
#include "arch.h"
28 2 cvs
 
29
#define MAXLINE_LEN     18000
30
 
31
/* Unused mem memory marker. It is used when allocating program and data memory
32
   during parsing */
33
unsigned int freemem;
34
 
35
int nonempty(char *line)
36
{
37
        int i;
38
 
39
        for(i = 0; i < strlen(line); i++)
40
                if (!isspace(line[i]))
41
                        return(1);
42
        return(0);
43
}
44
 
45
int nondigit(char *line)
46
{
47
        int i;
48
 
49
        for(i = 0; i < strlen(line); i++)
50
                if (!isdigit(line[i]))
51
                        return(1);
52
        return(0);
53
}
54
 
55
char *strtoken(char *in, char *out, int which)
56
{
57
        char    *super;
58
        char    *sub;
59
        char    *newline;
60
 
61
        super = strdup(in);
62
        sub = strtok(super, " \t");
63
        while (sub && --which)
64
                sub = strtok(NULL, " \t");
65
        if (sub && !which) {
66
                if ((newline = strchr(sub, '\n')))
67
                        newline[0] = '\0';
68
                strcpy(out, sub);
69
        } else
70
                out[0] = '\0';
71
        free(super);
72
        if ((newline = strchr(out, '\r')))      /* get rid of CR */
73
                newline[0] = '\0';
74
        return(out);
75
}
76
 
77
void adddatastr(char *str)
78
{
79
        if (str)
80
                str++;
81
        else
82
                return;
83
 
84
        for(; *str && *str != '\"'; str++, freemem++)
85
                if (*str == '\\')
86
                        switch (*++str) {
87
                                case 'n': mem[freemem].data = '\n';
88
                                        break;
89
                                case 't': mem[freemem].data = '\t';
90
                                        break;
91
                                case 'r': mem[freemem].data = '\r';
92
                                        break;
93
                                case '0': mem[freemem].data = '\0';
94
                                        break;
95
                                default: break;
96
                        }
97
                else
98
                        mem[freemem].data = *str;
99
}
100
 
101 26 lampret
void adddataword(char *item)
102 2 cvs
{
103 26 lampret
        unsigned long num;
104 2 cvs
 
105 26 lampret
        if (isdigit(*item))
106
                num = atol(item);
107
        else
108
                num = eval_label(item);
109
 
110
        debug("adddataword: [0x%x] <= %x\n", freemem, num);
111
        mem[freemem].data = (char) (num >> 24);
112
        mem[freemem + 1].data = (char) (num >> 16);
113
        mem[freemem + 2].data = (char) (num >> 8);
114
        mem[freemem + 3].data = (char) (num);
115
 
116 2 cvs
        freemem += 4;
117
}
118
 
119 26 lampret
void adddatahalf(char *item)
120 2 cvs
{
121 26 lampret
        unsigned long num;
122 2 cvs
 
123 26 lampret
        if (isdigit(*item))
124
                num = atol(item);
125
        else
126
                num = eval_label(item);
127
 
128
        mem[freemem].data = (char) (num >> 8);
129
        mem[freemem + 1].data = (char) (num);
130
 
131 2 cvs
        freemem += 2;
132
}
133
 
134 26 lampret
void adddatabyte(char *item)
135 2 cvs
{
136 26 lampret
        unsigned long num;
137 2 cvs
 
138 26 lampret
        if (isdigit(*item))
139
                num = atol(item);
140
        else
141
                num = eval_label(item);
142
 
143
        mem[freemem].data = (char) (num);
144
 
145 2 cvs
        freemem++;
146
}
147
 
148
void adddataspace(char *num)
149
{
150
        freemem += atol(num);
151
}
152
 
153
void addlabel(char *label)
154
{
155
        if (strstr(label, LABELEND_CHAR)) {
156
                *strstr(label, LABELEND_CHAR) = '\0';
157
                strcpy(mem[freemem].label, label);
158
        }
159
 
160
        return;
161
}
162
 
163
void addprogram(char *insn, char *operands)
164
{
165 18 lampret
#ifdef  __HALF_WORD_INSN__
166
        int h_insn_is_word_flag=0;
167
        char insn_first2_char[3];
168
 
169 2 cvs
        strcpy(mem[freemem].insn, insn);
170 18 lampret
        insn_first2_char[0]=insn[0];
171
        insn_first2_char[1]=insn[1];
172
        insn_first2_char[2]='\0';
173 2 cvs
 
174 18 lampret
        if(strcmp("h.", insn_first2_char) == 0) {
175
                if(strcmp("h.load32u", insn) == 0 ||
176
                   strcmp("h.load16u", insn) == 0 ||
177
                   strcmp("h.load8u", insn) == 0 ||
178
                   strcmp("h.stor32", insn) == 0 ||
179
                   strcmp("h.stor16", insn) == 0 ||
180
                   strcmp("h.stor8", insn) == 0 ||
181
                   strcmp("h.jal", insn) == 0 ||
182 22 lampret
                   /* strcmp("h.mtsr", insn) == 0 ||
183
                   strcmp("h.mfsr", insn) == 0 || */
184 18 lampret
                   strcmp("h.movi16ze", insn) == 0 ||
185
                   strcmp("h.immhi16u", insn) == 0 ||
186
                   strcmp("h.addi16s", insn) == 0 ||
187
                   strcmp("h.subi16s", insn) == 0 ||
188
                   strcmp("h.xori16", insn) == 0 ||
189
                   strcmp("h.ori16", insn) == 0 ||
190
                   strcmp("h.andi16", insn) == 0
191
                  )
192
                        h_insn_is_word_flag = 2; /* h.xxx insn AND occupy 4 bytes */
193
                else
194
                        h_insn_is_word_flag = 1; /* h.xxx insn AND occupy 2 bytes */
195
        }
196
        else {
197
                        h_insn_is_word_flag = 0; /* not h.xxx insn */
198
        }
199
#else
200
        strcpy(mem[freemem].insn, insn);
201
#endif
202
 
203 2 cvs
        /* op1 */
204
        if (*operands)
205
                strcpy(mem[freemem].op1, operands);
206
        if (strstr(mem[freemem].op1, OPERAND_DELIM)) {
207
                operands = strstr(mem[freemem].op1, OPERAND_DELIM);
208
                *operands = '\0';
209
                operands++;
210
        } else {
211 18 lampret
#ifdef __HALF_WORD_INSN__
212
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
213
#else
214 2 cvs
                freemem += 4;
215 18 lampret
#endif
216 2 cvs
                return;
217
        }
218
 
219
        /* op2 */
220
        if (*operands)
221
                strcpy(mem[freemem].op2, operands);
222
        if (strstr(mem[freemem].op2, OPERAND_DELIM)) {
223
                operands = strstr(mem[freemem].op2, OPERAND_DELIM);
224
                *operands = '\0';
225
                operands++;
226
        } else {
227 18 lampret
#ifdef __HALF_WORD_INSN__
228
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
229
#else
230 2 cvs
                freemem += 4;
231 18 lampret
#endif
232 2 cvs
                return;
233
        }
234
 
235
        /* op3 */
236
        if (*operands)
237
                strcpy(mem[freemem].op3, operands);
238
        if (strstr(mem[freemem].op3, OPERAND_DELIM)) {
239
                operands = strstr(mem[freemem].op3, OPERAND_DELIM);
240
                *operands = '\0';
241
                operands++;
242
        } else {
243 18 lampret
#ifdef __HALF_WORD_INSN__
244
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
245
#else
246 2 cvs
                freemem += 4;
247 18 lampret
#endif
248 2 cvs
                return;
249
        }
250
 
251
        /* op4 */
252
        if (*operands)
253
                strcpy(mem[freemem].op4, operands);
254
        if (strstr(mem[freemem].op4, OPERAND_DELIM)) {
255
                operands = strstr(mem[freemem].op4, OPERAND_DELIM);
256
                *operands = '\0';
257
                operands++;
258
        }
259
 
260 18 lampret
#ifdef __HALF_WORD_INSN__
261
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
262
#else
263
                freemem += 4;
264
#endif
265 2 cvs
        return;
266
}
267
 
268
/* Non-architecture dependent parsing: stripping comments, filling
269
   abstract memory */
270
 
271
void parseline(char *inputline)
272
{
273
        char item[MAXLINE_LEN];
274
        char item2[MAXLINE_LEN];
275
        int  i = 0;
276
 
277
        /* Strip comments: simply terminate line where
278
           the first comment character appears. */
279
 
280
        debug("PARSING: %s", inputline);
281
        while (inputline[i] != '\0')
282
                if (inputline[i] == COMMENT_CHAR) {
283
                        inputline[i] = '\0';
284
                        break;
285
                } else
286
                        i++;
287
 
288
        /* Get the first item from this line */
289 18 lampret
        strtoken(inputline, item, 1);   /* opcode */
290
        strtoken(inputline, item2, 2);  /* all the remaining one/two/three operands */
291 2 cvs
 
292
        /* Is this item empty? Nothing to process, so return. */
293
        if (strlen(item) == 0)
294
                return;
295
 
296 18 lampret
        /* Is this item a label? If yes, add it to the label table and return immediately. */
297 2 cvs
        if (strstr(item, LABELEND_CHAR)) {
298
                addlabel(item);
299
                return;
300
        }
301
 
302
        /* Is this item a .directive? If yes, check for some supported
303
           and then return (even if unsupported found). */
304
        if (item[0] == DIRECTIVE_CHAR) {
305
                if ((strcmp(item, ".align") == 0) && (freemem % 4)) {
306
                        freemem &= -4;  /* e.g. 0xfffffffc */
307
                        freemem += 4;   /* always align to word */
308
                        return;
309
                } else
310
                if (strcmp(item, ".ascii") == 0) {
311
                        adddatastr(strstr(inputline, "\""));
312
                        return;
313
                } else
314
                if (strcmp(item, ".word") == 0) {
315
                        adddataword(item2);
316
                        return;
317
                } else
318
                if (strcmp(item, ".half") == 0) {
319
                        adddatahalf(item2);
320
                        return;
321
                } else
322
                if (strcmp(item, ".byte") == 0) {
323
                        adddatabyte(item2);
324
                        return;
325
                } else
326
                if (strcmp(item, ".space") == 0) {
327
                        adddataspace(item2);
328
                        return;
329
                } else  /* .directive but not one of the supported */
330
                        return;
331
        }
332
 
333
        /* This item can only be an instruction. Get all operands
334
           and add everything to mem array but as a program. */
335
        addprogram(item, item2);
336
 
337
        /* Also do static, single stats. */
338
        addsstats(item, 0, 1);
339
 
340
        return;
341
 
342
}
343
 
344
/* Load file and hand over every line to parse routine. */
345
 
346
void readfile(char *filename)
347
{
348
        FILE *inputfs;
349
        char  inputbuf[MAXLINE_LEN];
350
        char  *status;
351
 
352
        if ((inputfs = fopen(filename, "r"))) {
353
                while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) {
354
                        if (nonempty(inputbuf))
355
                                parseline(inputbuf);
356
                }
357
                fclose(inputfs);
358
        }
359
        else
360
                perror("readfile");
361
 
362
        return;
363
}
364
 
365
 
366
void loadcode(char *filename)
367
{
368
        freemem = 0;
369
        memset(mem, 0, sizeof(mem));
370
        readfile(filename);
371
        return;
372
}

powered by: WebSVN 2.1.0

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