URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [tags/] [stable_0_2_0_rc2/] [or1ksim/] [cpu/] [common/] [parse.c] - Rev 22
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" #include "arch.h" #define MAXLINE_LEN 18000 /* 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; } void adddataword(char *num) { 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) { #ifdef __HALF_WORD_INSN__ int h_insn_is_word_flag=0; char insn_first2_char[3]; strcpy(mem[freemem].insn, insn); insn_first2_char[0]=insn[0]; insn_first2_char[1]=insn[1]; insn_first2_char[2]='\0'; if(strcmp("h.", insn_first2_char) == 0) { if(strcmp("h.load32u", insn) == 0 || strcmp("h.load16u", insn) == 0 || strcmp("h.load8u", insn) == 0 || strcmp("h.stor32", insn) == 0 || strcmp("h.stor16", insn) == 0 || strcmp("h.stor8", insn) == 0 || strcmp("h.jal", insn) == 0 || /* strcmp("h.mtsr", insn) == 0 || strcmp("h.mfsr", insn) == 0 || */ strcmp("h.movi16ze", insn) == 0 || strcmp("h.immhi16u", insn) == 0 || strcmp("h.addi16s", insn) == 0 || strcmp("h.subi16s", insn) == 0 || strcmp("h.xori16", insn) == 0 || strcmp("h.ori16", insn) == 0 || strcmp("h.andi16", insn) == 0 ) h_insn_is_word_flag = 2; /* h.xxx insn AND occupy 4 bytes */ else h_insn_is_word_flag = 1; /* h.xxx insn AND occupy 2 bytes */ } else { h_insn_is_word_flag = 0; /* not h.xxx insn */ } #else strcpy(mem[freemem].insn, insn); #endif /* 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 { #ifdef __HALF_WORD_INSN__ freemem += (h_insn_is_word_flag == 1) ? 2 : 4; #else freemem += 4; #endif 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 { #ifdef __HALF_WORD_INSN__ freemem += (h_insn_is_word_flag == 1) ? 2 : 4; #else freemem += 4; #endif 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 { #ifdef __HALF_WORD_INSN__ freemem += (h_insn_is_word_flag == 1) ? 2 : 4; #else freemem += 4; #endif 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++; } #ifdef __HALF_WORD_INSN__ freemem += (h_insn_is_word_flag == 1) ? 2 : 4; #else freemem += 4; #endif 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); /* opcode */ strtoken(inputline, item2, 2); /* all the remaining one/two/three operands */ /* 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); return; }
Go to most recent revision | Compare with Previous | Blame | View Log