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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_42/] [or1ksim/] [cpu/] [common/] [parse.c] - Diff between revs 134 and 138

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 134 Rev 138
Line 1... Line 1...
/* parce.c -- Architecture independent load and parsing of assembly
/* parce.c -- Architecture independent load
   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
Line 20... Line 20...
#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 "abstract.h"
#include "abstract.h"
#include "arch.h"
#include "arch.h"
#include "dmmu.h"
#include "dmmu.h"
#include "coff.h"
#include "coff.h"
 
#include "debug_unit.h"
#include "opcode/or32.h"
#include "opcode/or32.h"
 
#include "parse.h"
 
 
#define MAXLINE_LEN     18000
#define MAXLINE_LEN     18000
 
 
extern char *disassembled;
extern char *disassembled;
 
 
Line 227... Line 228...
 
 
/* Modified by CZ 26/05/01 */
/* Modified by CZ 26/05/01 */
/* Replaced several calls to translate(freemem) with vaddr */
/* Replaced several calls to translate(freemem) with vaddr */
/* Added new mode execution code */
/* Added new mode execution code */
/* Changed parameters so address can be passed as argument */
/* Changed parameters so address can be passed as argument */
void addprogram(char *insn, char *operands,unsigned int address,int* breakpoint)
void addprogram(unsigned long address, unsigned long insn, int* breakpoint)
{
{
        int h_insn_is_word_flag=0;
 
        char insn_first2_char[3];
        char insn_first2_char[3];
        int vaddr = GlobalMode ? translate(address,breakpoint) : translate(freemem,breakpoint);
        int vaddr = GlobalMode ? translate(address,breakpoint) : translate(freemem,breakpoint);
 
 
        debug("addprogram 1\n");
        debug("addprogram 1\n");
        if (!mem[vaddr].insn) {
 
          mem[vaddr].insn = (struct insn_entry *)malloc (sizeof (struct insn_entry));
 
          mem[vaddr].insn->insn_index = -1;
 
          mem[vaddr].insn->op1 = null_str;
 
          mem[vaddr].insn->op2 = null_str;
 
          mem[vaddr].insn->op3 = null_str;
 
          mem[vaddr].insn->op4 = null_str;
 
        } else if(!GlobalMode) {  /* Old mode */
 
                printf("internal error: reloading the same location\n");
 
                exit(1);
 
        } else /* New mode */
 
          {
 
            if(mem[vaddr].insn->op1 != null_str) free(mem[vaddr].insn->op1);
 
            if(mem[vaddr].insn->op2 != null_str) free(mem[vaddr].insn->op2);
 
            if(mem[vaddr].insn->op3 != null_str) free(mem[vaddr].insn->op3);
 
            if(mem[vaddr].insn->op4 != null_str) free(mem[vaddr].insn->op4);
 
            mem[vaddr].insn->insn_index = -1;
 
            mem[vaddr].insn->op1 = null_str;
 
            mem[vaddr].insn->op2 = null_str;
 
            mem[vaddr].insn->op3 = null_str;
 
            mem[vaddr].insn->op4 = null_str;
 
          }
 
 
 
        debug("addprogram 2\n");
 
 
 
#ifdef  OR16
 
 
 
        printf("half:%s:\n", insn);
 
        insn_first2_char[0]=insn[0];
 
        insn_first2_char[1]=insn[1];
 
        insn_first2_char[2]='\0';
 
        debug("addprogram 3\n");
 
 
 
        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
 
        debug("addprogram 4\n");
 
        debug("addprogram 5\n");
 
#endif
 
 
 
        /* MM: added instruction index */
 
        mem[vaddr].insn->insn_index = insn_index (insn);
 
        /* op1 */
 
        if (*operands) {
 
                mem[vaddr].insn->op1 = malloc(strlen(operands)+1);
 
                strcpy(mem[vaddr].insn->op1, operands);
 
        }
 
 
 
        debug("addprogram 6\n");
 
        debug("operands:%s\n", operands);
 
        if (strstr(operands, OPERAND_DELIM)) {
 
                debug("addprogram 6a\n");
 
                operands = strstr(mem[vaddr].insn->op1, OPERAND_DELIM);
 
                *operands = '\0';
 
                operands++;
 
        } else {
 
                debug("addprogram 6b\n");
 
          if(!GlobalMode)
 
            {
 
#ifdef OR16
 
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
 
#else
 
                freemem += 4;
 
#endif
 
            }
 
                return;
 
        }
 
 
 
        debug("addprogram 7\n");
 
        /* op2 */
 
        if (*operands) {
 
                mem[vaddr].insn->op2 = malloc(strlen(operands)+1);
 
                strcpy(mem[vaddr].insn->op2, operands);
 
        }
 
        if (strstr(operands, OPERAND_DELIM)) {
 
                operands = strstr(mem[vaddr].insn->op2, OPERAND_DELIM);
 
                *operands = '\0';
 
                operands++;
 
        } else {
 
          if(!GlobalMode)
 
            {
 
#ifdef OR16
 
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
 
#else
 
                freemem += 4;
 
#endif
 
            }
 
 
 
                return;
  *breakpoint += CheckDebugUnit(DebugStoreAddress,vaddr);  /* 22/06/01 MM*/
        }
  *breakpoint += CheckDebugUnit(DebugStoreData,insn);
 
 
        debug("addprogram 8\n");
 
        /* op3 */
 
        if (*operands) {
 
                mem[vaddr].insn->op3 = malloc(strlen(operands)+1);
 
                strcpy(mem[vaddr].insn->op3, operands);
 
        }
 
        if (strstr(operands, OPERAND_DELIM)) {
 
                operands = strstr(mem[vaddr].insn->op3, OPERAND_DELIM);
 
                *operands = '\0';
 
                operands++;
 
        } else {
 
          if(!GlobalMode)
 
            {
 
#ifdef OR16
 
                freemem += (h_insn_is_word_flag == 1) ? 2 : 4;
 
#else
 
                freemem += 4;
 
#endif
 
            }
 
                return;
 
        }
 
 
 
        /* op4 */
  setsim_mem32 (vaddr, insn);
        if (*operands) {
 
                mem[vaddr].insn->op4 = malloc(strlen(operands)+1);
 
                strcpy(mem[vaddr].insn->op4, operands);
 
        }
 
        if (strstr(operands, OPERAND_DELIM)) {
 
                operands = strstr(mem[vaddr].insn->op4, OPERAND_DELIM);
 
                *operands = '\0';
 
                operands++;
 
        }
 
 
 
        if(!GlobalMode)
        if(!GlobalMode)
          {
    freemem += insn_len (insn_decode (insn));
#ifdef OR16
 
                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,int* breakpoint)
 
{
 
        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)) {
 
                *strstr(item, LABELEND_CHAR) = '\0';
 
                addlabel(item, translate(freemem,breakpoint),breakpoint);
 
                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) {
 
                        int align = strtoul(item2, NULL, 0);
 
                        if (!(translate(freemem,breakpoint) % align))
 
                                return;
 
                        freemem &= -align;
 
                        freemem += align;
 
                        return;
 
                } else
 
                if (strcmp(item, ".org") == 0) {
 
                        int addr = strtoul(item2, NULL, 0);
 
                        freemem = addr;
 
                        return;
 
                } else
 
                if (strcmp(item, ".ascii") == 0) {
 
                        adddatastr(strstr(inputline, "\""),breakpoint);
 
                        return;
 
                } else
 
                if (strcmp(item, ".word") == 0) {
 
                        adddataword(item2,breakpoint);
 
                        return;
 
                } else
 
                if (strcmp(item, ".half") == 0) {
 
                        adddatahalf(item2,breakpoint);
 
                        return;
 
                } else
 
                if (strcmp(item, ".byte") == 0) {
 
                        adddatabyte(item2,breakpoint);
 
                        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. */
 
        debug("%x: ", translate(freemem,breakpoint));
 
        addprogram(item, item2,freemem,breakpoint);
 
 
 
        /* Also do static, single stats. */
 
        addsstats(item, 0, 1);
 
 
 
        return;
 
 
 
}
}
 
 
/* Load big-endian COFF file. At the moment it doesn't load symbols yet. */
/* Load big-endian COFF file. At the moment it doesn't load symbols yet. */
 
 
void readfile_coff(char *filename, short sections)
void readfile_coff(char *filename, short sections)
Line 566... Line 331...
                        perror("readfile_coff");
                        perror("readfile_coff");
                        exit(1);
                        exit(1);
                }
                }
                while (sectsize > 0 && (len = fread(&inputbuf, sizeof(inputbuf), 1, inputfs))) {
                while (sectsize > 0 && (len = fread(&inputbuf, sizeof(inputbuf), 1, inputfs))) {
                        insn = COFF_LONG_H(inputbuf);
                        insn = COFF_LONG_H(inputbuf);
                        len = disassemble_insn(insn);
                        len = insn_len (insn_decode (insn));
                        sprintf(item, "%u", insn);
                        if (len == 2)
                        adddataword(item,&breakpoint);
                          {
                        freemem -= len;
 
                        if (len == 2) {
 
                                fseek(inputfs, -2, SEEK_CUR);
                                fseek(inputfs, -2, SEEK_CUR);
                                debug("readfile_coff: %x 0x%x   ", sectsize, insn >> 16);
                                debug("readfile_coff: %x 0x%x   ", sectsize, insn >> 16);
                        }
                        }
                        else
                        else
                                debug("readfile_coff: %x 0x%x   ", sectsize, insn);
                                debug("readfile_coff: %x 0x%x   ", sectsize, insn);
                        debug("%s\n", disassembled);
                        addprogram (freemem, insn, &breakpoint);
                        strtoken(disassembled, item, 1); /* opcode */
 
                        strtoken(disassembled, item2, 2); /* all the remaining one/two/three operands */
 
                        addprogram(item, item2,freemem,&breakpoint);
 
                        sectsize -= len;
                        sectsize -= len;
                }
                }
        }
        }
        if (firstthree < 3) {
        if (firstthree < 3) {
                printf("One or more missing sections. At least");
                printf("One or more missing sections. At least");
Line 635... Line 395...
        fclose(inputfs);
        fclose(inputfs);
        printf("Finished loading symbols.\n");
        printf("Finished loading symbols.\n");
        return;
        return;
}
}
 
 
/* Load file and hand over every line to parse routine. */
 
 
 
void readfile_assembly(char *filename)
 
{
 
        FILE *inputfs;
 
        char  inputbuf[MAXLINE_LEN];
 
        char  *status;
 
        int breakpoint = 0;
 
 
 
        if (!(inputfs = fopen(filename, "r"))) {
 
                perror("readfile_assembly");
 
                exit(1);
 
        }
 
 
 
        while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) {
 
                if (nonempty(inputbuf))
 
                        parseline(inputbuf,&breakpoint);
 
        }
 
        fclose(inputfs);
 
 
 
        return;
 
}
 
 
 
/* Identify file type and call appropriate readfile_X routine. It only
/* Identify file type and call appropriate readfile_X routine. It only
handles orX-coff-big executables at the moment. */
handles orX-coff-big executables at the moment. */
 
 
void identifyfile(char *filename)
void identifyfile(char *filename)
{
{
Line 697... Line 434...
                        readfile_coff(filename, COFF_SHORT_H(coffhdr.f_nscns));
                        readfile_coff(filename, COFF_SHORT_H(coffhdr.f_nscns));
                        readsyms_coff(filename, COFF_LONG_H(coffhdr.f_symptr), COFF_LONG_H(coffhdr.f_nsyms));
                        readsyms_coff(filename, COFF_LONG_H(coffhdr.f_symptr), COFF_LONG_H(coffhdr.f_nsyms));
                        return;
                        return;
                }
                }
                else {
                else {
                        printf("Not COFF, trying to load as assembly.\n");
                        printf("Not COFF, quiting.\n");
                        fclose(inputfs);
                        fclose(inputfs);
                        readfile_assembly(filename);
                        exit (1);
                        return;
 
                }
                }
        }
        }
        else {
        else {
                printf("yy %s", filename);
                printf("yy %s", filename);
                perror("identifyfile2");
                perror("identifyfile2");

powered by: WebSVN 2.1.0

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