URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [tags/] [nog_patch_42/] [or1ksim/] [cpu/] [common/] [parse.c] - Rev 6
Go to most recent revision | Compare with Previous | Blame | View Log
/* parce.c -- Architecture independent load and parsing of assembly Copyright (C) 1999 Damjan Lampret, lampret@opencores.org This file is part of OpenRISC 1000 Architectural Simulator. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #include "parse.h" #include "abstract.h" #define MAXLINE_LEN 18000 /* Struct labelref that is used in linked list for fixing label refs after program is loaded to memory. */ struct st_labelref { struct st_labelref *next; unsigned long addr; char label[100]; } *labelref = NULL; /* Unused mem memory marker. It is used when allocating program and data memory during parsing */ unsigned int freemem; int nonempty(char *line) { int i; for(i = 0; i < strlen(line); i++) if (!isspace(line[i])) return(1); return(0); } int nondigit(char *line) { int i; for(i = 0; i < strlen(line); i++) if (!isdigit(line[i])) return(1); return(0); } char *strtoken(char *in, char *out, int which) { char *super; char *sub; char *newline; super = strdup(in); sub = strtok(super, " \t"); while (sub && --which) sub = strtok(NULL, " \t"); if (sub && !which) { if ((newline = strchr(sub, '\n'))) newline[0] = '\0'; strcpy(out, sub); } else out[0] = '\0'; free(super); if ((newline = strchr(out, '\r'))) /* get rid of CR */ newline[0] = '\0'; return(out); } void adddatastr(char *str) { if (str) str++; else return; for(; *str && *str != '\"'; str++, freemem++) if (*str == '\\') switch (*++str) { case 'n': mem[freemem].data = '\n'; break; case 't': mem[freemem].data = '\t'; break; case 'r': mem[freemem].data = '\r'; break; case '0': mem[freemem].data = '\0'; break; default: break; } else mem[freemem].data = *str; } int is_str(char *str) { char *c; for (c = str; *c != '\0'; c++) if (isalpha(*c)) return 1; return 0; } void handle_labelref(struct st_labelref *root) { unsigned long label; struct st_labelref *tmp; while (root) { label = eval_label(root->label); mem[root->addr].data = (char) (label >> 24); mem[root->addr + 1].data = (char) (label >> 16); mem[root->addr + 2].data = (char) (label >> 8); mem[root->addr + 3].data = (char) (label); tmp = root->next; free(root); root = tmp; } } void adddataword(char *num) { if (is_str(num)) { struct st_labelref *new = malloc(sizeof(struct st_labelref)); strcpy(new->label, num); new->addr = freemem; new->next = labelref; labelref = new; } else { mem[freemem].data = (char) (atol(num) >> 24); mem[freemem + 1].data = (char) (atol(num) >> 16); mem[freemem + 2].data = (char) (atol(num) >> 8); mem[freemem + 3].data = (char) (atol(num)); } freemem += 4; } void adddatahalf(char *num) { mem[freemem].data = (char) (atol(num) >> 8); mem[freemem + 1].data = (char) (atol(num)); freemem += 2; } void adddatabyte(char *num) { mem[freemem].data = (char) (atol(num)); freemem++; } void adddataspace(char *num) { freemem += atol(num); } void addlabel(char *label) { if (strstr(label, LABELEND_CHAR)) { *strstr(label, LABELEND_CHAR) = '\0'; strcpy(mem[freemem].label, label); } return; } void addprogram(char *insn, char *operands) { strcpy(mem[freemem].insn, insn); /* op1 */ if (*operands) strcpy(mem[freemem].op1, operands); if (strstr(mem[freemem].op1, OPERAND_DELIM)) { operands = strstr(mem[freemem].op1, OPERAND_DELIM); *operands = '\0'; operands++; } else { freemem += 4; return; } /* op2 */ if (*operands) strcpy(mem[freemem].op2, operands); if (strstr(mem[freemem].op2, OPERAND_DELIM)) { operands = strstr(mem[freemem].op2, OPERAND_DELIM); *operands = '\0'; operands++; } else { freemem += 4; return; } /* op3 */ if (*operands) strcpy(mem[freemem].op3, operands); if (strstr(mem[freemem].op3, OPERAND_DELIM)) { operands = strstr(mem[freemem].op3, OPERAND_DELIM); *operands = '\0'; operands++; } else { freemem += 4; return; } /* op4 */ if (*operands) strcpy(mem[freemem].op4, operands); if (strstr(mem[freemem].op4, OPERAND_DELIM)) { operands = strstr(mem[freemem].op4, OPERAND_DELIM); *operands = '\0'; operands++; } freemem += 4; return; } /* Non-architecture dependent parsing: stripping comments, filling abstract memory */ void parseline(char *inputline) { char item[MAXLINE_LEN]; char item2[MAXLINE_LEN]; int i = 0; /* Strip comments: simply terminate line where the first comment character appears. */ debug("PARSING: %s", inputline); while (inputline[i] != '\0') if (inputline[i] == COMMENT_CHAR) { inputline[i] = '\0'; break; } else i++; /* Get the first item from this line */ strtoken(inputline, item, 1); strtoken(inputline, item2, 2); /* Is this item empty? Nothing to process, so return. */ if (strlen(item) == 0) return; /* Is this item a label? If yes, add it to the label table and return immediately. */ if (strstr(item, LABELEND_CHAR)) { addlabel(item); return; } /* Is this item a .directive? If yes, check for some supported and then return (even if unsupported found). */ if (item[0] == DIRECTIVE_CHAR) { if ((strcmp(item, ".align") == 0) && (freemem % 4)) { freemem &= -4; /* e.g. 0xfffffffc */ freemem += 4; /* always align to word */ return; } else if (strcmp(item, ".ascii") == 0) { adddatastr(strstr(inputline, "\"")); return; } else if (strcmp(item, ".word") == 0) { adddataword(item2); return; } else if (strcmp(item, ".half") == 0) { adddatahalf(item2); return; } else if (strcmp(item, ".byte") == 0) { adddatabyte(item2); return; } else if (strcmp(item, ".space") == 0) { adddataspace(item2); return; } else /* .directive but not one of the supported */ return; } /* This item can only be an instruction. Get all operands and add everything to mem array but as a program. */ addprogram(item, item2); /* Also do static, single stats. */ addsstats(item, 0, 1); return; } /* Load file and hand over every line to parse routine. */ void readfile(char *filename) { FILE *inputfs; char inputbuf[MAXLINE_LEN]; char *status; if ((inputfs = fopen(filename, "r"))) { while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) { if (nonempty(inputbuf)) parseline(inputbuf); } fclose(inputfs); } else perror("readfile"); return; } void loadcode(char *filename) { freemem = 0; memset(mem, 0, sizeof(mem)); readfile(filename); handle_labelref(labelref); return; }
Go to most recent revision | Compare with Previous | Blame | View Log