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 67 and 123

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

Rev 67 Rev 123
/* 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"
#include "dmmu.h"
#include "dmmu.h"
#include "coff.h"
#include "coff.h"
 
#include "or32.h"
 
 
#define MAXLINE_LEN     18000
#define MAXLINE_LEN     18000
 
 
extern char *disassembled;
extern char *disassembled;
 
 
/* 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;
 
 
/* Translation table provided by microkernel. Only used if simulating microkernel. */
/* Translation table provided by microkernel. Only used if simulating microkernel. */
static unsigned long transl_table;
static unsigned long transl_table;
 
 
/* Used to signal whether during loading of programs a translation fault occured. */
/* Used to signal whether during loading of programs a translation fault occured. */
static unsigned long transl_error;
static unsigned long transl_error;
 
 
 
 
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);
}
}
 
 
/* Used only by the simulator loader to translate logical addresses int ophysical.
/* Used only by the simulator loader to translate logical addresses int ophysical.
   If loadcode() is called with valid virtphy_transl pointer to a table of
   If loadcode() is called with valid virtphy_transl pointer to a table of
   translations then translate() performs translation otherwise phy address is
   translations then translate() performs translation otherwise phy address is
   equal to logical. */
   equal to logical. */
static unsigned int translate(unsigned int laddr)
static unsigned int translate(unsigned int laddr,int* breakpoint)
{
{
        int i;
        int i;
 
 
        /* No translation (i.e. when loading kernel into simulator)
        /* No translation (i.e. when loading kernel into simulator)
/*      printf("transl_table=%x  laddr=%x\n", transl_table, laddr);
/*      printf("transl_table=%x  laddr=%x\n", transl_table, laddr);
        printf("laddr=%x\n", laddr);*/
        printf("laddr=%x\n", laddr);*/
        if (transl_table == 0)
        if (transl_table == 0)
                return laddr;
                return laddr;
 
 
        /* Try to find our translation in the table. */
        /* Try to find our translation in the table. */
        for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
        for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
                if ((laddr & ~(PAGE_SIZE - 1)) == evalsim_mem32(transl_table + i)) {
                if ((laddr & ~(PAGE_SIZE - 1)) == evalsim_mem32(transl_table + i,breakpoint)) {
                        setsim_mem32(transl_table + i + 8, -2); /* Page modified */
                        setsim_mem32(transl_table + i + 8, -2); /* Page modified */
                        printf("found paddr=%x\n", evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
                        printf("found paddr=%x\n", evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (PAGE_SIZE - 1)));
                        return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1));
                        return (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (unsigned long)(PAGE_SIZE - 1));
                }
                }
 
 
        /* Allocate new phy page for us. */
        /* Allocate new phy page for us. */
        for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
        for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
                if (evalsim_mem32(transl_table + i + 8) == 0) {
                if (evalsim_mem32(transl_table + i + 8,breakpoint) == 0) {
                        setsim_mem32(transl_table + i, laddr & ~(PAGE_SIZE - 1)); /* VPN */
                        setsim_mem32(transl_table + i, laddr & ~(PAGE_SIZE - 1)); /* VPN */
                        setsim_mem32(transl_table + i + 4, (i/16) * PAGE_SIZE); /* PPN */
                        setsim_mem32(transl_table + i + 4, (i/16) * PAGE_SIZE); /* PPN */
                        setsim_mem32(transl_table + i + 8, -2); /* Page modified */
                        setsim_mem32(transl_table + i + 8, -2); /* Page modified */
                        printf("newly allocated ppn=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4));
                        printf("newly allocated ppn=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint));
                        printf("newly allocated .ppn=%x\n", (unsigned long)transl_table + i + 4);
                        printf("newly allocated .ppn=%x\n", (unsigned long)transl_table + i + 4);
                        printf("newly allocated ofs=%x\n", (unsigned long)(laddr & (PAGE_SIZE - 1)));
                        printf("newly allocated ofs=%x\n", (unsigned long)(laddr & (PAGE_SIZE - 1)));
                        printf("newly allocated paddr=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (PAGE_SIZE - 1)));
                        printf("newly allocated paddr=%x\n", (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (PAGE_SIZE - 1)));
                        return (unsigned long)evalsim_mem32(transl_table + i + 4) | (laddr & (unsigned long)(PAGE_SIZE - 1));
                        return (unsigned long)evalsim_mem32(transl_table + i + 4,breakpoint) | (laddr & (unsigned long)(PAGE_SIZE - 1));
                }
                }
        /* If we come this far then all phy memory is used and we can't find our page
        /* If we come this far then all phy memory is used and we can't find our page
           nor allocate new page. */
           nor allocate new page. */
        transl_error = 1;
        transl_error = 1;
 
 
        printf("can't translate\n", laddr);
        printf("can't translate\n", laddr);
        exit(1);
        exit(1);
        return -1;
        return -1;
}
}
 
 
void adddatastr(char *str)
void adddatastr(char *str,int* breakpoint)
{
{
        if (str)
        if (str)
                str++;
                str++;
        else
        else
                return;
                return;
 
 
        for(; *str && *str != '\"'; str++, translate(freemem++))
        for(; *str && *str != '\"'; str++, translate(freemem++,breakpoint))
                if (*str == '\\')
                if (*str == '\\')
                        switch (*++str) {
                        switch (*++str) {
                                case 'n': mem[translate(freemem)].data = '\n';
                                case 'n': mem[translate(freemem,breakpoint)].data = '\n';
                                        break;
                                        break;
                                case 't': mem[translate(freemem)].data = '\t';
                                case 't': mem[translate(freemem,breakpoint)].data = '\t';
                                        break;
                                        break;
                                case 'r': mem[translate(freemem)].data = '\r';
                                case 'r': mem[translate(freemem,breakpoint)].data = '\r';
                                        break;
                                        break;
                                case '0': mem[translate(freemem)].data = '\0';
                                case '0': mem[translate(freemem,breakpoint)].data = '\0';
                                        break;
                                        break;
                                default: break;
                                default: break;
                        }
                        }
                else
                else
                        mem[translate(freemem)].data = *str;
                        mem[translate(freemem,breakpoint)].data = *str;
}
}
 
 
void adddataword(char *item)
/* Modified by CZ 26/05/01 */
 
/* Added code for new mode operation */
 
void adddataword(char *item,int* breakpoint)
{
{
        unsigned long num;
        unsigned long num;
 
 
        if (isdigit(*item))
        if (isdigit(*item))
                num = strtoul(item, NULL, 0);
                num = strtoul(item, NULL, 0);
        else
        else
                num = eval_label(item);
                num = eval_label(item);
 
 
        debug("adddataword: [0x%x] <= %x\n", translate(freemem), num);
        debug("adddataword: [0x%x] <= %x\n", translate(freemem,breakpoint), num);
        mem[translate(freemem)].data = (char) (num >> 24);
        mem[translate(freemem,breakpoint)].data = (char) (num >> 24);
        mem[translate(freemem + 1)].data = (char) (num >> 16);
        mem[translate(freemem + 1,breakpoint)].data = (char) (num >> 16);
        mem[translate(freemem + 2)].data = (char) (num >> 8);
        mem[translate(freemem + 2,breakpoint)].data = (char) (num >> 8);
        mem[translate(freemem + 3)].data = (char) (num);
        mem[translate(freemem + 3,breakpoint)].data = (char) (num);
 
 
 
        if(!GlobalMode)
        freemem += 4;
        freemem += 4;
}
}
 
 
void adddatahalf(char *item)
void adddatahalf(char *item,int* breakpoint)
{
{
        unsigned long num;
        unsigned long num;
 
 
        if (isdigit(*item))
        if (isdigit(*item))
                num = strtoul(item, NULL, 0);
                num = strtoul(item, NULL, 0);
        else
        else
                num = eval_label(item);
                num = eval_label(item);
 
 
        mem[translate(freemem)].data = (char) (num >> 8);
        mem[translate(freemem,breakpoint)].data = (char) (num >> 8);
        mem[translate(freemem + 1)].data = (char) (num);
        mem[translate(freemem + 1,breakpoint)].data = (char) (num);
 
 
        freemem += 2;
        freemem += 2;
}
}
 
 
void adddatabyte(char *item)
void adddatabyte(char *item,int* breakpoint)
{
{
        unsigned long num;
        unsigned long num;
 
 
        if (isdigit(*item))
        if (isdigit(*item))
                num = strtoul(item, NULL, 0);
                num = strtoul(item, NULL, 0);
        else
        else
                num = eval_label(item);
                num = eval_label(item);
 
 
        mem[translate(freemem)].data = (char) (num);
        mem[translate(freemem,breakpoint)].data = (char) (num);
 
 
        freemem++;
        freemem++;
}
}
 
 
void adddataspace(char *num)
void adddataspace(char *num)
{
{
        freemem += atol(num);
        freemem += atol(num);
}
}
 
 
void addlabel(char *label, unsigned long freemem)
void addlabel(char *label, unsigned long freemem,int* breakpoint)
{
{
        struct label_entry **tmp;
        struct label_entry **tmp;
 
 
        debug("Adding label %s at 0x%x\n", label, translate(freemem));
        debug("Adding label %s at 0x%x\n", label, translate(freemem,breakpoint));
        tmp = &mem[translate(freemem)].label;
        tmp = &mem[translate(freemem,breakpoint)].label;
        for (; *tmp; tmp = &((*tmp)->next));
        for (; *tmp; tmp = &((*tmp)->next));
        *tmp = malloc(sizeof(**tmp));
        *tmp = malloc(sizeof(**tmp));
        (*tmp)->name = malloc(strlen(label)+1);
        (*tmp)->name = malloc(strlen(label)+1);
        strcpy((*tmp)->name, label);
        strcpy((*tmp)->name, label);
        (*tmp)->next = NULL;
        (*tmp)->next = NULL;
 
 
        return;
        return;
}
}
 
 
char null_str[1] = "\0";
char null_str[1] = "\0";
 
 
void addprogram(char *insn, char *operands)
/* Modified by CZ 26/05/01 */
 
/* Replaced several calls to translate(freemem) with vaddr */
 
/* Added new mode execution code */
 
/* Changed parameters so address can be passed as argument */
 
void addprogram(char *insn, char *operands,unsigned int address,int* breakpoint)
{
{
        int h_insn_is_word_flag=0;
        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);
 
 
        debug("addprogram 1\n");
        debug("addprogram 1\n");
        if (!mem[translate(freemem)].insn) {
        if (!mem[vaddr].insn) {
                mem[translate(freemem)].insn = malloc(sizeof(*mem[translate(freemem)].insn));
          mem[vaddr].insn = (struct insn_entry *)malloc (sizeof (struct insn_entry));
                mem[translate(freemem)].insn->insn = null_str;
          mem[vaddr].insn->insn_index = -1;
                mem[translate(freemem)].insn->op1 = null_str;
          mem[vaddr].insn->op1 = null_str;
                mem[translate(freemem)].insn->op2 = null_str;
          mem[vaddr].insn->op2 = null_str;
                mem[translate(freemem)].insn->op3 = null_str;
          mem[vaddr].insn->op3 = null_str;
                mem[translate(freemem)].insn->op4 = null_str;
          mem[vaddr].insn->op4 = null_str;
        } else {
        } else if(!GlobalMode) {  /* Old mode */
                printf("internal error: reloading the same location\n");
                printf("internal error: reloading the same location\n");
                exit(1);
                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");
 
 
 
        mem[translate(freemem)].insn->insn = malloc(strlen(insn)+1);
        debug("addprogram 2\n");
 
 
#ifdef  OR16
#ifdef  OR16
 
 
        strcpy(mem[translate(freemem)].insn->insn, insn);
 
        printf("half:%s:\n", insn);
        printf("half:%s:\n", 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';
        debug("addprogram 3\n");
        debug("addprogram 3\n");
 
 
        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
        debug("addprogram 4\n");
        debug("addprogram 4\n");
        strcpy(mem[translate(freemem)].insn->insn, insn);
 
        debug("addprogram 5\n");
        debug("addprogram 5\n");
#endif
#endif
 
 
 
        /* MM: added instruction index */
 
        mem[vaddr].insn->insn_index = insn_index (insn);
        /* op1 */
        /* op1 */
        if (*operands) {
        if (*operands) {
                mem[translate(freemem)].insn->op1 = malloc(strlen(operands)+1);
                mem[vaddr].insn->op1 = malloc(strlen(operands)+1);
                strcpy(mem[translate(freemem)].insn->op1, operands);
                strcpy(mem[vaddr].insn->op1, operands);
        }
        }
 
 
        debug("addprogram 6\n");
        debug("addprogram 6\n");
        debug("operands:%s\n", operands);
        debug("operands:%s\n", operands);
        if (strstr(operands, OPERAND_DELIM)) {
        if (strstr(operands, OPERAND_DELIM)) {
                debug("addprogram 6a\n");
                debug("addprogram 6a\n");
                operands = strstr(mem[translate(freemem)].insn->op1, OPERAND_DELIM);
                operands = strstr(mem[vaddr].insn->op1, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        } else {
        } else {
                debug("addprogram 6b\n");
                debug("addprogram 6b\n");
 
          if(!GlobalMode)
 
            {
#ifdef OR16
#ifdef OR16
                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;
        }
        }
 
 
        debug("addprogram 7\n");
        debug("addprogram 7\n");
        /* op2 */
        /* op2 */
        if (*operands) {
        if (*operands) {
                mem[translate(freemem)].insn->op2 = malloc(strlen(operands)+1);
                mem[vaddr].insn->op2 = malloc(strlen(operands)+1);
                strcpy(mem[translate(freemem)].insn->op2, operands);
                strcpy(mem[vaddr].insn->op2, operands);
        }
        }
        if (strstr(operands, OPERAND_DELIM)) {
        if (strstr(operands, OPERAND_DELIM)) {
                operands = strstr(mem[translate(freemem)].insn->op2, OPERAND_DELIM);
                operands = strstr(mem[vaddr].insn->op2, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        } else {
        } else {
 
          if(!GlobalMode)
 
            {
#ifdef OR16
#ifdef OR16
                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;
        }
        }
 
 
        debug("addprogram 8\n");
        debug("addprogram 8\n");
        /* op3 */
        /* op3 */
        if (*operands) {
        if (*operands) {
                mem[translate(freemem)].insn->op3 = malloc(strlen(operands)+1);
                mem[vaddr].insn->op3 = malloc(strlen(operands)+1);
                strcpy(mem[translate(freemem)].insn->op3, operands);
                strcpy(mem[vaddr].insn->op3, operands);
        }
        }
        if (strstr(operands, OPERAND_DELIM)) {
        if (strstr(operands, OPERAND_DELIM)) {
                operands = strstr(mem[translate(freemem)].insn->op3, OPERAND_DELIM);
                operands = strstr(mem[vaddr].insn->op3, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        } else {
        } else {
 
          if(!GlobalMode)
 
            {
#ifdef OR16
#ifdef OR16
                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) {
                mem[translate(freemem)].insn->op4 = malloc(strlen(operands)+1);
                mem[vaddr].insn->op4 = malloc(strlen(operands)+1);
                strcpy(mem[translate(freemem)].insn->op4, operands);
                strcpy(mem[vaddr].insn->op4, operands);
        }
        }
        if (strstr(operands, OPERAND_DELIM)) {
        if (strstr(operands, OPERAND_DELIM)) {
                operands = strstr(mem[translate(freemem)].insn->op4, OPERAND_DELIM);
                operands = strstr(mem[vaddr].insn->op4, OPERAND_DELIM);
                *operands = '\0';
                *operands = '\0';
                operands++;
                operands++;
        }
        }
 
 
 
        if(!GlobalMode)
 
          {
#ifdef OR16
#ifdef OR16
                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,int* breakpoint)
{
{
        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)) {
                *strstr(item, LABELEND_CHAR) = '\0';
                *strstr(item, LABELEND_CHAR) = '\0';
                addlabel(item, translate(freemem));
                addlabel(item, translate(freemem,breakpoint),breakpoint);
                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) {
                if (strcmp(item, ".align") == 0) {
                        int align = strtoul(item2, NULL, 0);
                        int align = strtoul(item2, NULL, 0);
                        if (!(translate(freemem) % align))
                        if (!(translate(freemem,breakpoint) % align))
                                return;
                                return;
                        freemem &= -align;
                        freemem &= -align;
                        freemem += align;
                        freemem += align;
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".org") == 0) {
                if (strcmp(item, ".org") == 0) {
                        int addr = strtoul(item2, NULL, 0);
                        int addr = strtoul(item2, NULL, 0);
                        freemem = addr;
                        freemem = addr;
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".ascii") == 0) {
                if (strcmp(item, ".ascii") == 0) {
                        adddatastr(strstr(inputline, "\""));
                        adddatastr(strstr(inputline, "\""),breakpoint);
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".word") == 0) {
                if (strcmp(item, ".word") == 0) {
                        adddataword(item2);
                        adddataword(item2,breakpoint);
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".half") == 0) {
                if (strcmp(item, ".half") == 0) {
                        adddatahalf(item2);
                        adddatahalf(item2,breakpoint);
                        return;
                        return;
                } else
                } else
                if (strcmp(item, ".byte") == 0) {
                if (strcmp(item, ".byte") == 0) {
                        adddatabyte(item2);
                        adddatabyte(item2,breakpoint);
                        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. */
        debug("%x: ", translate(freemem));
        debug("%x: ", translate(freemem,breakpoint));
        addprogram(item, item2);
        addprogram(item, item2,freemem,breakpoint);
 
 
        /* Also do static, single stats. */
        /* Also do static, single stats. */
        addsstats(item, 0, 1);
        addsstats(item, 0, 1);
 
 
        return;
        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)
{
{
        FILE *inputfs;
        FILE *inputfs;
        char inputbuf[4];
        char inputbuf[4];
        unsigned long insn;
        unsigned long insn;
        signed long sectsize;
        signed long sectsize;
        COFF_AOUTHDR coffaouthdr;
        COFF_AOUTHDR coffaouthdr;
        struct COFF_scnhdr coffscnhdr;
        struct COFF_scnhdr coffscnhdr;
        int  len;
        int  len;
        char item[MAXLINE_LEN];
        char item[MAXLINE_LEN];
        char item2[MAXLINE_LEN];
        char item2[MAXLINE_LEN];
        int  firstthree = 0;
        int  firstthree = 0;
 
        int breakpoint = 0;
 
 
        if (!(inputfs = fopen(filename, "r"))) {
        if (!(inputfs = fopen(filename, "r"))) {
                perror("readfile_coff");
                perror("readfile_coff");
                exit(1);
                exit(1);
        }
        }
 
 
        if (fseek(inputfs, sizeof(struct COFF_filehdr), SEEK_SET) == -1) {
        if (fseek(inputfs, sizeof(struct COFF_filehdr), SEEK_SET) == -1) {
                fclose(inputfs);
                fclose(inputfs);
                perror("readfile_coff");
                perror("readfile_coff");
                exit(1);
                exit(1);
        }
        }
 
 
        if (fread(&coffaouthdr, sizeof(coffaouthdr), 1, inputfs) != 1) {
        if (fread(&coffaouthdr, sizeof(coffaouthdr), 1, inputfs) != 1) {
                fclose(inputfs);
                fclose(inputfs);
                perror("readfile_coff");
                perror("readfile_coff");
                exit(1);
                exit(1);
        }
        }
 
 
        while(sections--) {
        while(sections--) {
                long scnhdr_pos = sizeof(struct COFF_filehdr) + sizeof(coffaouthdr)
                long scnhdr_pos = sizeof(struct COFF_filehdr) + sizeof(coffaouthdr)
                                + sizeof(struct COFF_scnhdr) * firstthree;
                                + sizeof(struct COFF_scnhdr) * firstthree;
                if (fseek(inputfs, scnhdr_pos, SEEK_SET) == -1) {
                if (fseek(inputfs, scnhdr_pos, SEEK_SET) == -1) {
                        fclose(inputfs);
                        fclose(inputfs);
                        perror("readfile_coff");
                        perror("readfile_coff");
                        exit(1);
                        exit(1);
                }
                }
                if (fread(&coffscnhdr, sizeof(struct COFF_scnhdr), 1, inputfs) != 1) {
                if (fread(&coffscnhdr, sizeof(struct COFF_scnhdr), 1, inputfs) != 1) {
                        fclose(inputfs);
                        fclose(inputfs);
                        perror("readfile_coff");
                        perror("readfile_coff");
                        exit(1);
                        exit(1);
                }
                }
                printf("Section: %s,", coffscnhdr.s_name);
                printf("Section: %s,", coffscnhdr.s_name);
                printf(" vaddr: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_vaddr));
                printf(" vaddr: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_vaddr));
                printf(" size: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_size));
                printf(" size: 0x%.8x,", COFF_LONG_H(coffscnhdr.s_size));
                printf(" scnptr: 0x%.8x\n", COFF_LONG_H(coffscnhdr.s_scnptr));
                printf(" scnptr: 0x%.8x\n", COFF_LONG_H(coffscnhdr.s_scnptr));
 
 
                sectsize = COFF_LONG_H(coffscnhdr.s_size);
                sectsize = COFF_LONG_H(coffscnhdr.s_size);
                /* A couple of sanity checks. */
                /* A couple of sanity checks. */
                if (translate(COFF_LONG_H(coffscnhdr.s_vaddr)) < MEMORY_START) {
                if (translate(COFF_LONG_H(coffscnhdr.s_vaddr),&breakpoint) < MEMORY_START) {
                        printf("Section %s starts out of ", coffscnhdr.s_name);
                        printf("Section %s starts out of ", coffscnhdr.s_name);
                        printf("memory (at %x)\n", COFF_LONG_H(coffscnhdr.s_vaddr));
                        printf("memory (at %x)\n", COFF_LONG_H(coffscnhdr.s_vaddr));
                        exit(1);
                        exit(1);
                }
                }
                if (translate(COFF_LONG_H(coffscnhdr.s_vaddr) + sectsize) >
                if (translate(COFF_LONG_H(coffscnhdr.s_vaddr) + sectsize,&breakpoint) >
                    MEMORY_START + MEMORY_LEN) {
                    MEMORY_START + MEMORY_LEN) {
                        printf("Section %s ends out of ", coffscnhdr.s_name);
                        printf("Section %s ends out of ", coffscnhdr.s_name);
                        printf("memory.\n");
                        printf("memory.\n");
                        exit(1);
                        exit(1);
                }
                }
                if (++firstthree == 1 && strcmp(coffscnhdr.s_name, ".text") != 0) {
                if (++firstthree == 1 && strcmp(coffscnhdr.s_name, ".text") != 0) {
                        printf("First section should be .text (%s instead)\n", coffscnhdr.s_name);
                        printf("First section should be .text (%s instead)\n", coffscnhdr.s_name);
                        exit(1);
                        exit(1);
                }
                }
                if (firstthree == 2 && strcmp(coffscnhdr.s_name, ".data") != 0) {
                if (firstthree == 2 && strcmp(coffscnhdr.s_name, ".data") != 0) {
                        printf("Second section should be .data (%s instead)\n", coffscnhdr.s_name);
                        printf("Second section should be .data (%s instead)\n", coffscnhdr.s_name);
                        exit(1);
                        exit(1);
                }
                }
                if (firstthree == 3 && strcmp(coffscnhdr.s_name, ".bss") != 0) {
                if (firstthree == 3 && strcmp(coffscnhdr.s_name, ".bss") != 0) {
                        printf("Third section should be .bss (%s instead)\n", coffscnhdr.s_name);
                        printf("Third section should be .bss (%s instead)\n", coffscnhdr.s_name);
                        exit(1);
                        exit(1);
                }
                }
 
 
                /* loading section */
                /* loading section */
                freemem = COFF_LONG_H(coffscnhdr.s_vaddr);
                freemem = COFF_LONG_H(coffscnhdr.s_vaddr);
                debug("Starting to load at 0x%x", freemem);
                debug("Starting to load at 0x%x", freemem);
                if (fseek(inputfs, COFF_LONG_H(coffscnhdr.s_scnptr), SEEK_SET) == -1) {
                if (fseek(inputfs, COFF_LONG_H(coffscnhdr.s_scnptr), SEEK_SET) == -1) {
                        fclose(inputfs);
                        fclose(inputfs);
                        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 = disassemble_insn(insn);
                        sprintf(item, "%u", insn);
                        sprintf(item, "%u", insn);
                        adddataword(item);
                        adddataword(item,&breakpoint);
                        freemem -= len;
                        freemem -= len;
                        if (len == 2) {
                        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);
                        debug("%s\n", disassembled);
                        strtoken(disassembled, item, 1); /* opcode */
                        strtoken(disassembled, item, 1); /* opcode */
                        strtoken(disassembled, item2, 2); /* all the remaining one/two/three operands */
                        strtoken(disassembled, item2, 2); /* all the remaining one/two/three operands */
                        addprogram(item, item2);
                        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");
                printf(" three sections expected (.text, .data, .bss).\n");
                printf(" three sections expected (.text, .data, .bss).\n");
                exit(1);
                exit(1);
        }
        }
        if (firstthree > 3) {
        if (firstthree > 3) {
                printf("Warning: one or more extra sections. These");
                printf("Warning: one or more extra sections. These");
                printf(" sections were handled as .data sections.\n");
                printf(" sections were handled as .data sections.\n");
        }
        }
 
 
        fclose(inputfs);
        fclose(inputfs);
        printf("Finished loading COFF.\n");
        printf("Finished loading COFF.\n");
        return;
        return;
}
}
 
 
/* Load symbols from big-endian COFF file. */
/* Load symbols from big-endian COFF file. */
 
 
void readsyms_coff(char *filename, unsigned long symptr, long syms)
void readsyms_coff(char *filename, unsigned long symptr, long syms)
{
{
        FILE *inputfs;
        FILE *inputfs;
        struct COFF_syment coffsymhdr;
        struct COFF_syment coffsymhdr;
 
        int breakpoint = 0;
 
 
        if (!(inputfs = fopen(filename, "r"))) {
        if (!(inputfs = fopen(filename, "r"))) {
                perror("readsyms_coff");
                perror("readsyms_coff");
                exit(1);
                exit(1);
        }
        }
 
 
        if (fseek(inputfs, symptr, SEEK_SET) == -1) {
        if (fseek(inputfs, symptr, SEEK_SET) == -1) {
                fclose(inputfs);
                fclose(inputfs);
                perror("readsyms_coff");
                perror("readsyms_coff");
                exit(1);
                exit(1);
        }
        }
 
 
        while(syms--) {
        while(syms--) {
                if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
                if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
                        fclose(inputfs);
                        fclose(inputfs);
                        perror("readsyms_coff");
                        perror("readsyms_coff");
                        exit(1);
                        exit(1);
                }
                }
                debug("Symbol: %s,", coffsymhdr.e.e_name);
                debug("Symbol: %s,", coffsymhdr.e.e_name);
                debug(" val: 0x%.8x,", COFF_LONG_H(coffsymhdr.e_value));
                debug(" val: 0x%.8x,", COFF_LONG_H(coffsymhdr.e_value));
                debug(" auxs: %c\n", coffsymhdr.e_numaux);
                debug(" auxs: %c\n", coffsymhdr.e_numaux);
                if (strlen(coffsymhdr.e.e_name) && strlen(coffsymhdr.e.e_name) < 9)
                if (strlen(coffsymhdr.e.e_name) && strlen(coffsymhdr.e.e_name) < 9)
                        addlabel(coffsymhdr.e.e_name, COFF_LONG_H(coffsymhdr.e_value));
                        addlabel(coffsymhdr.e.e_name, COFF_LONG_H(coffsymhdr.e_value),&breakpoint);
        }
        }
 
 
        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. */
/* Load file and hand over every line to parse routine. */
 
 
void readfile_assembly(char *filename)
void readfile_assembly(char *filename)
{
{
        FILE *inputfs;
        FILE *inputfs;
        char  inputbuf[MAXLINE_LEN];
        char  inputbuf[MAXLINE_LEN];
        char  *status;
        char  *status;
 
        int breakpoint = 0;
 
 
        if (!(inputfs = fopen(filename, "r"))) {
        if (!(inputfs = fopen(filename, "r"))) {
                perror("readfile_assembly");
                perror("readfile_assembly");
                exit(1);
                exit(1);
        }
        }
 
 
        while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) {
        while ((status = fgets(inputbuf, sizeof(inputbuf), inputfs))) {
                if (nonempty(inputbuf))
                if (nonempty(inputbuf))
                        parseline(inputbuf);
                        parseline(inputbuf,&breakpoint);
        }
        }
        fclose(inputfs);
        fclose(inputfs);
 
 
        return;
        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)
{
{
        FILE *inputfs;
        FILE *inputfs;
        struct COFF_filehdr coffhdr;
        struct COFF_filehdr coffhdr;
        size_t len;
        size_t len;
 
 
        if (!(inputfs = fopen(filename, "r"))) {
        if (!(inputfs = fopen(filename, "r"))) {
                fprintf(stderr, "xx %s", filename);
                fprintf(stderr, "xx %s", filename);
                perror("identifyfile1");
                perror("identifyfile1");
                fflush(stdout);
                fflush(stdout);
                fflush(stderr);
                fflush(stderr);
                exit(1);
                exit(1);
        }
        }
 
 
        if (fread(&coffhdr, sizeof(coffhdr), 1, inputfs) == 1) {
        if (fread(&coffhdr, sizeof(coffhdr), 1, inputfs) == 1) {
                if (COFF_SHORT_H(coffhdr.f_magic) == 0x17a) {
                if (COFF_SHORT_H(coffhdr.f_magic) == 0x17a) {
                        unsigned long opthdr_size;
                        unsigned long opthdr_size;
                        printf("COFF magic: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_magic));
                        printf("COFF magic: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_magic));
                        printf("COFF flags: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_flags));
                        printf("COFF flags: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_flags));
                        printf("COFF symptr: 0x%.8x\n", COFF_LONG_H(coffhdr.f_symptr));
                        printf("COFF symptr: 0x%.8x\n", COFF_LONG_H(coffhdr.f_symptr));
                        if ((COFF_SHORT_H(coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC) {
                        if ((COFF_SHORT_H(coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC) {
                                printf("This COFF is not an executable.\n");
                                printf("This COFF is not an executable.\n");
                                exit(1);
                                exit(1);
                        }
                        }
                        opthdr_size = COFF_SHORT_H(coffhdr.f_opthdr);
                        opthdr_size = COFF_SHORT_H(coffhdr.f_opthdr);
                        if (opthdr_size != sizeof(COFF_AOUTHDR)) {
                        if (opthdr_size != sizeof(COFF_AOUTHDR)) {
                                printf("COFF optional header is missing or not recognized.\n");
                                printf("COFF optional header is missing or not recognized.\n");
                                printf("COFF f_opthdr: 0x%.2x\n", opthdr_size);
                                printf("COFF f_opthdr: 0x%.2x\n", opthdr_size);
                                exit(1);
                                exit(1);
                        }
                        }
                        fclose(inputfs);
                        fclose(inputfs);
                        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, trying to load as assembly.\n");
                        fclose(inputfs);
                        fclose(inputfs);
                        readfile_assembly(filename);
                        readfile_assembly(filename);
                        return;
                        return;
                }
                }
        }
        }
        else {
        else {
                printf("yy %s", filename);
                printf("yy %s", filename);
                perror("identifyfile2");
                perror("identifyfile2");
        }
        }
 
 
        fclose(inputfs);
        fclose(inputfs);
 
 
        return;
        return;
}
}
 
 
 
 
/* Loads file to memory starting at address startaddr and returns freemem. */
/* Loads file to memory starting at address startaddr and returns freemem. */
unsigned long loadcode(char *filename, unsigned long startaddr, unsigned long virtphy_transl)
unsigned long loadcode(char *filename, unsigned long startaddr, unsigned long virtphy_transl)
{
{
 
  int breakpoint = 0;
 
 
        transl_error = 0;
        transl_error = 0;
        transl_table = virtphy_transl;
        transl_table = virtphy_transl;
        freemem = startaddr;
        freemem = startaddr;
        printf("loadcode: filename %s  startaddr=%x  virtphy_transl=%x", filename, startaddr, virtphy_transl);
        printf("loadcode: filename %s  startaddr=%x  virtphy_transl=%x", filename, startaddr, virtphy_transl);
        identifyfile(filename);
        identifyfile(filename);
        if (transl_error)
        if (transl_error)
                return -1;
                return -1;
        else
        else
                return translate(freemem);
                return translate(freemem,&breakpoint);
}
}
 
 

powered by: WebSVN 2.1.0

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