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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_61/] [or1ksim/] [cpu/] [common/] [parse.c] - Diff between revs 22 and 26

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 22 Rev 26
/* parce.c -- Architecture independent load and parsing of assembly
/* parce.c -- Architecture independent load and parsing of assembly
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
 
This file is part of OpenRISC 1000 Architectural Simulator.
This file is part of OpenRISC 1000 Architectural Simulator.
 
 
This program is free software; you can redistribute it and/or modify
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
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
(at your option) any later version.
 
 
This program is distributed in the hope that it will be useful,
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
GNU General Public License for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 
#include <stdio.h>
#include <stdio.h>
#include <ctype.h>
#include <ctype.h>
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <stdlib.h>
 
 
#include "parse.h"
#include "parse.h"
#include "abstract.h"
#include "abstract.h"
#include "arch.h"
#include "arch.h"
 
 
#define MAXLINE_LEN     18000
#define MAXLINE_LEN     18000
 
 
/* Unused mem memory marker. It is used when allocating program and data memory
/* Unused mem memory marker. It is used when allocating program and data memory
   during parsing */
   during parsing */
unsigned int freemem;
unsigned int freemem;
 
 
int nonempty(char *line)
int nonempty(char *line)
{
{
        int i;
        int i;
 
 
        for(i = 0; i < strlen(line); i++)
        for(i = 0; i < strlen(line); i++)
                if (!isspace(line[i]))
                if (!isspace(line[i]))
                        return(1);
                        return(1);
        return(0);
        return(0);
}
}
 
 
int nondigit(char *line)
int nondigit(char *line)
{
{
        int i;
        int i;
 
 
        for(i = 0; i < strlen(line); i++)
        for(i = 0; i < strlen(line); i++)
                if (!isdigit(line[i]))
                if (!isdigit(line[i]))
                        return(1);
                        return(1);
        return(0);
        return(0);
}
}
 
 
char *strtoken(char *in, char *out, int which)
char *strtoken(char *in, char *out, int which)
{
{
        char    *super;
        char    *super;
        char    *sub;
        char    *sub;
        char    *newline;
        char    *newline;
 
 
        super = strdup(in);
        super = strdup(in);
        sub = strtok(super, " \t");
        sub = strtok(super, " \t");
        while (sub && --which)
        while (sub && --which)
                sub = strtok(NULL, " \t");
                sub = strtok(NULL, " \t");
        if (sub && !which) {
        if (sub && !which) {
                if ((newline = strchr(sub, '\n')))
                if ((newline = strchr(sub, '\n')))
                        newline[0] = '\0';
                        newline[0] = '\0';
                strcpy(out, sub);
                strcpy(out, sub);
        } else
        } else
                out[0] = '\0';
                out[0] = '\0';
        free(super);
        free(super);
        if ((newline = strchr(out, '\r')))      /* get rid of CR */
        if ((newline = strchr(out, '\r')))      /* get rid of CR */
                newline[0] = '\0';
                newline[0] = '\0';
        return(out);
        return(out);
}
}
 
 
void adddatastr(char *str)
void adddatastr(char *str)
{
{
        if (str)
        if (str)
                str++;
                str++;
        else
        else
                return;
                return;
 
 
        for(; *str && *str != '\"'; str++, freemem++)
        for(; *str && *str != '\"'; str++, freemem++)
                if (*str == '\\')
                if (*str == '\\')
                        switch (*++str) {
                        switch (*++str) {
                                case 'n': mem[freemem].data = '\n';
                                case 'n': mem[freemem].data = '\n';
                                        break;
                                        break;
                                case 't': mem[freemem].data = '\t';
                                case 't': mem[freemem].data = '\t';
                                        break;
                                        break;
                                case 'r': mem[freemem].data = '\r';
                                case 'r': mem[freemem].data = '\r';
                                        break;
                                        break;
                                case '0': mem[freemem].data = '\0';
                                case '0': mem[freemem].data = '\0';
                                        break;
                                        break;
                                default: break;
                                default: break;
                        }
                        }
                else
                else
                        mem[freemem].data = *str;
                        mem[freemem].data = *str;
}
}
 
 
void adddataword(char *num)
void adddataword(char *item)
{
{
        mem[freemem].data = (char) (atol(num) >> 24);
        unsigned long num;
        mem[freemem + 1].data = (char) (atol(num) >> 16);
 
        mem[freemem + 2].data = (char) (atol(num) >> 8);
        if (isdigit(*item))
        mem[freemem + 3].data = (char) (atol(num));
                num = atol(item);
 
        else
 
                num = eval_label(item);
 
 
 
        debug("adddataword: [0x%x] <= %x\n", freemem, num);
 
        mem[freemem].data = (char) (num >> 24);
 
        mem[freemem + 1].data = (char) (num >> 16);
 
        mem[freemem + 2].data = (char) (num >> 8);
 
        mem[freemem + 3].data = (char) (num);
 
 
        freemem += 4;
        freemem += 4;
}
}
 
 
void adddatahalf(char *num)
void adddatahalf(char *item)
{
{
        mem[freemem].data = (char) (atol(num) >> 8);
        unsigned long num;
        mem[freemem + 1].data = (char) (atol(num));
 
 
        if (isdigit(*item))
 
                num = atol(item);
 
        else
 
                num = eval_label(item);
 
 
 
        mem[freemem].data = (char) (num >> 8);
 
        mem[freemem + 1].data = (char) (num);
 
 
        freemem += 2;
        freemem += 2;
}
}
 
 
void adddatabyte(char *num)
void adddatabyte(char *item)
{
{
        mem[freemem].data = (char) (atol(num));
        unsigned long num;
 
 
 
        if (isdigit(*item))
 
                num = atol(item);
 
        else
 
                num = eval_label(item);
 
 
 
        mem[freemem].data = (char) (num);
 
 
        freemem++;
        freemem++;
}
}
 
 
void adddataspace(char *num)
void adddataspace(char *num)
{
{
        freemem += atol(num);
        freemem += atol(num);
}
}
 
 
void addlabel(char *label)
void addlabel(char *label)
{
{
        if (strstr(label, LABELEND_CHAR)) {
        if (strstr(label, LABELEND_CHAR)) {
                *strstr(label, LABELEND_CHAR) = '\0';
                *strstr(label, LABELEND_CHAR) = '\0';
                strcpy(mem[freemem].label, label);
                strcpy(mem[freemem].label, label);
        }
        }
 
 
        return;
        return;
}
}
 
 
void addprogram(char *insn, char *operands)
void addprogram(char *insn, char *operands)
{
{
#ifdef  __HALF_WORD_INSN__
#ifdef  __HALF_WORD_INSN__
        int h_insn_is_word_flag=0;
        int h_insn_is_word_flag=0;
        char insn_first2_char[3];
        char insn_first2_char[3];
 
 
        strcpy(mem[freemem].insn, insn);
        strcpy(mem[freemem].insn, insn);
        insn_first2_char[0]=insn[0];
        insn_first2_char[0]=insn[0];
        insn_first2_char[1]=insn[1];
        insn_first2_char[1]=insn[1];
        insn_first2_char[2]='\0';
        insn_first2_char[2]='\0';
 
 
        if(strcmp("h.", insn_first2_char) == 0) {
        if(strcmp("h.", insn_first2_char) == 0) {
                if(strcmp("h.load32u", insn) == 0 ||
                if(strcmp("h.load32u", insn) == 0 ||
                   strcmp("h.load16u", insn) == 0 ||
                   strcmp("h.load16u", insn) == 0 ||
                   strcmp("h.load8u", insn) == 0 ||
                   strcmp("h.load8u", insn) == 0 ||
                   strcmp("h.stor32", insn) == 0 ||
                   strcmp("h.stor32", insn) == 0 ||
                   strcmp("h.stor16", insn) == 0 ||
                   strcmp("h.stor16", insn) == 0 ||
                   strcmp("h.stor8", insn) == 0 ||
                   strcmp("h.stor8", insn) == 0 ||
                   strcmp("h.jal", insn) == 0 ||
                   strcmp("h.jal", insn) == 0 ||
                   /* strcmp("h.mtsr", insn) == 0 ||
                   /* strcmp("h.mtsr", insn) == 0 ||
                   strcmp("h.mfsr", insn) == 0 || */
                   strcmp("h.mfsr", insn) == 0 || */
                   strcmp("h.movi16ze", insn) == 0 ||
                   strcmp("h.movi16ze", insn) == 0 ||
                   strcmp("h.immhi16u", insn) == 0 ||
                   strcmp("h.immhi16u", insn) == 0 ||
                   strcmp("h.addi16s", insn) == 0 ||
                   strcmp("h.addi16s", insn) == 0 ||
                   strcmp("h.subi16s", insn) == 0 ||
                   strcmp("h.subi16s", insn) == 0 ||
                   strcmp("h.xori16", insn) == 0 ||
                   strcmp("h.xori16", insn) == 0 ||
                   strcmp("h.ori16", insn) == 0 ||
                   strcmp("h.ori16", insn) == 0 ||
                   strcmp("h.andi16", insn) == 0
                   strcmp("h.andi16", insn) == 0
                  )
                  )
                        h_insn_is_word_flag = 2; /* h.xxx insn AND occupy 4 bytes */
                        h_insn_is_word_flag = 2; /* h.xxx insn AND occupy 4 bytes */
                else
                else
                        h_insn_is_word_flag = 1; /* h.xxx insn AND occupy 2 bytes */
                        h_insn_is_word_flag = 1; /* h.xxx insn AND occupy 2 bytes */
        }
        }
        else {
        else {
                        h_insn_is_word_flag = 0; /* not h.xxx insn */
                        h_insn_is_word_flag = 0; /* not h.xxx insn */
        }
        }
#else
#else
        strcpy(mem[freemem].insn, insn);
        strcpy(mem[freemem].insn, insn);
#endif
#endif
 
 
        /* op1 */
        /* op1 */
        if (*operands)
        if (*operands)
                strcpy(mem[freemem].op1, operands);
                strcpy(mem[freemem].op1, operands);
        if (strstr(mem[freemem].op1, OPERAND_DELIM)) {
        if (strstr(mem[freemem].op1, OPERAND_DELIM)) {
                operands = strstr(mem[freemem].op1, OPERAND_DELIM);
                operands = strstr(mem[freemem].op1, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        } else {
        } else {
#ifdef __HALF_WORD_INSN__
#ifdef __HALF_WORD_INSN__
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
#else
#else
                freemem += 4;
                freemem += 4;
#endif
#endif
                return;
                return;
        }
        }
 
 
        /* op2 */
        /* op2 */
        if (*operands)
        if (*operands)
                strcpy(mem[freemem].op2, operands);
                strcpy(mem[freemem].op2, operands);
        if (strstr(mem[freemem].op2, OPERAND_DELIM)) {
        if (strstr(mem[freemem].op2, OPERAND_DELIM)) {
                operands = strstr(mem[freemem].op2, OPERAND_DELIM);
                operands = strstr(mem[freemem].op2, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        } else {
        } else {
#ifdef __HALF_WORD_INSN__
#ifdef __HALF_WORD_INSN__
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
#else
#else
                freemem += 4;
                freemem += 4;
#endif
#endif
                return;
                return;
        }
        }
 
 
        /* op3 */
        /* op3 */
        if (*operands)
        if (*operands)
                strcpy(mem[freemem].op3, operands);
                strcpy(mem[freemem].op3, operands);
        if (strstr(mem[freemem].op3, OPERAND_DELIM)) {
        if (strstr(mem[freemem].op3, OPERAND_DELIM)) {
                operands = strstr(mem[freemem].op3, OPERAND_DELIM);
                operands = strstr(mem[freemem].op3, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        } else {
        } else {
#ifdef __HALF_WORD_INSN__
#ifdef __HALF_WORD_INSN__
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
#else
#else
                freemem += 4;
                freemem += 4;
#endif
#endif
                return;
                return;
        }
        }
 
 
        /* op4 */
        /* op4 */
        if (*operands)
        if (*operands)
                strcpy(mem[freemem].op4, operands);
                strcpy(mem[freemem].op4, operands);
        if (strstr(mem[freemem].op4, OPERAND_DELIM)) {
        if (strstr(mem[freemem].op4, OPERAND_DELIM)) {
                operands = strstr(mem[freemem].op4, OPERAND_DELIM);
                operands = strstr(mem[freemem].op4, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        }
        }
 
 
#ifdef __HALF_WORD_INSN__
#ifdef __HALF_WORD_INSN__
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
#else
#else
                freemem += 4;
                freemem += 4;
#endif
#endif
        return;
        return;
}
}
 
 
/* Non-architecture dependent parsing: stripping comments, filling
/* Non-architecture dependent parsing: stripping comments, filling
   abstract memory */
   abstract memory */
 
 
void parseline(char *inputline)
void parseline(char *inputline)
{
{
        char item[MAXLINE_LEN];
        char item[MAXLINE_LEN];
        char item2[MAXLINE_LEN];
        char item2[MAXLINE_LEN];
        int  i = 0;
        int  i = 0;
 
 
        /* Strip comments: simply terminate line where
        /* Strip comments: simply terminate line where
           the first comment character appears. */
           the first comment character appears. */
 
 
        debug("PARSING: %s", inputline);
        debug("PARSING: %s", inputline);
        while (inputline[i] != '\0')
        while (inputline[i] != '\0')
                if (inputline[i] == COMMENT_CHAR) {
                if (inputline[i] == COMMENT_CHAR) {
                        inputline[i] = '\0';
                        inputline[i] = '\0';
                        break;
                        break;
                } else
                } else
                        i++;
                        i++;
 
 
        /* Get the first item from this line */
        /* Get the first item from this line */
        strtoken(inputline, item, 1);   /* opcode */
        strtoken(inputline, item, 1);   /* opcode */
        strtoken(inputline, item2, 2);  /* all the remaining one/two/three operands */
        strtoken(inputline, item2, 2);  /* all the remaining one/two/three operands */
 
 
        /* Is this item empty? Nothing to process, so return. */
        /* Is this item empty? Nothing to process, so return. */
        if (strlen(item) == 0)
        if (strlen(item) == 0)
                return;
                return;
 
 
        /* Is this item a label? If yes, add it to the label table and return immediately. */
        /* Is this item a label? If yes, add it to the label table and return immediately. */
        if (strstr(item, LABELEND_CHAR)) {
        if (strstr(item, LABELEND_CHAR)) {
                addlabel(item);
                addlabel(item);
                return;
                return;
        }
        }
 
 
        /* Is this item a .directive? If yes, check for some supported
        /* Is this item a .directive? If yes, check for some supported
           and then return (even if unsupported found). */
           and then return (even if unsupported found). */
        if (item[0] == DIRECTIVE_CHAR) {
        if (item[0] == DIRECTIVE_CHAR) {
                if ((strcmp(item, ".align") == 0) && (freemem % 4)) {
                if ((strcmp(item, ".align") == 0) && (freemem % 4)) {
                        freemem &= -4;  /* e.g. 0xfffffffc */
                        freemem &= -4;  /* e.g. 0xfffffffc */
                        freemem += 4;   /* always align to word */
                        freemem += 4;   /* always align to word */
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".ascii") == 0) {
                if (strcmp(item, ".ascii") == 0) {
                        adddatastr(strstr(inputline, "\""));
                        adddatastr(strstr(inputline, "\""));
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".word") == 0) {
                if (strcmp(item, ".word") == 0) {
                        adddataword(item2);
                        adddataword(item2);
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".half") == 0) {
                if (strcmp(item, ".half") == 0) {
                        adddatahalf(item2);
                        adddatahalf(item2);
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".byte") == 0) {
                if (strcmp(item, ".byte") == 0) {
                        adddatabyte(item2);
                        adddatabyte(item2);
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".space") == 0) {
                if (strcmp(item, ".space") == 0) {
                        adddataspace(item2);
                        adddataspace(item2);
                        return;
                        return;
                } else  /* .directive but not one of the supported */
                } else  /* .directive but not one of the supported */
                        return;
                        return;
        }
        }
 
 
        /* This item can only be an instruction. Get all operands
        /* This item can only be an instruction. Get all operands
           and add everything to mem array but as a program. */
           and add everything to mem array but as a program. */
        addprogram(item, item2);
        addprogram(item, item2);
 
 
        /* Also do static, single stats. */
        /* Also do static, single stats. */
        addsstats(item, 0, 1);
        addsstats(item, 0, 1);
 
 
        return;
        return;
 
 
}
}
 
 
/* Load file and hand over every line to parse routine. */
/* Load file and hand over every line to parse routine. */
 
 
void readfile(char *filename)
void readfile(char *filename)
{
{
        FILE *inputfs;
        FILE *inputfs;
        char  inputbuf[MAXLINE_LEN];
        char  inputbuf[MAXLINE_LEN];
        char  *status;
        char  *status;
 
 
        if ((inputfs = fopen(filename, "r"))) {
        if ((inputfs = fopen(filename, "r"))) {
                while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) {
                while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) {
                        if (nonempty(inputbuf))
                        if (nonempty(inputbuf))
                                parseline(inputbuf);
                                parseline(inputbuf);
                }
                }
                fclose(inputfs);
                fclose(inputfs);
        }
        }
        else
        else
                perror("readfile");
                perror("readfile");
 
 
        return;
        return;
}
}
 
 
 
 
void loadcode(char *filename)
void loadcode(char *filename)
{
{
        freemem = 0;
        freemem = 0;
        memset(mem, 0, sizeof(mem));
        memset(mem, 0, sizeof(mem));
        readfile(filename);
        readfile(filename);
        return;
        return;
}
}
 
 

powered by: WebSVN 2.1.0

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