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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zasm/] [asmdata.h] - Diff between revs 97 and 126

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

Rev 97 Rev 126
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    asmdata.h
// Filename:    asmdata.h
//
//
// Project:     Zip CPU -- a small, lightweight, RISC CPU core
// Project:     Zip CPU -- a small, lightweight, RISC CPU core
//
//
// Purpose:     Data structures for the assembler.  In particular, this file
// Purpose:     Data structures for the assembler.  In particular, this file
//              declares: Abstract Syntax Trees (ASTs) to store operations for
//              declares: Abstract Syntax Trees (ASTs) to store operations for
//              later calculation, ASMLINEs or assembled lines (which may or
//              later calculation, ASMLINEs or assembled lines (which may or
//              may not be defined, depending upon symbol table status),
//              may not be defined, depending upon symbol table status),
//              symbol table access and the final output object file together
//              symbol table access and the final output object file together
//              with its necessary relocations.  Yes, linking is done, but as
//              with its necessary relocations.  Yes, linking is done, but as
//              part of the assembler and not part of a separate linker.
//              part of the assembler and not part of a separate linker.
//
//
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015, Gisselquist Technology, LLC
//
//
// This program is free software (firmware): you can redistribute it and/or
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
//
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// for more details.
//
//
// You should have received a copy of the GNU General Public License along
// You should have received a copy of the GNU General Public License along
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
// target there if the PDF file isn't present.)  If not, see
// target there if the PDF file isn't present.)  If not, see
// <http://www.gnu.org/licenses/> for a copy.
// <http://www.gnu.org/licenses/> for a copy.
//
//
// License:     GPL, v3, as defined and found on www.gnu.org,
// License:     GPL, v3, as defined and found on www.gnu.org,
//              http://www.gnu.org/licenses/gpl.html
//              http://www.gnu.org/licenses/gpl.html
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#ifndef ASMDATA_H
#ifndef ASMDATA_H
#define ASMDATA_H
#define ASMDATA_H
 
 
#include <stdio.h>
#include <stdio.h>
#include <string>
#include <string>
#include <list>
#include <list>
#include "zopcodes.h"
#include "zopcodes.h"
#include "zparser.h"
#include "zparser.h"
 
 
extern  "C" char        *linecp;
extern  "C" char        *linecp;
extern  int     yylineno;
extern  int     yylineno;
 
 
typedef enum {
typedef enum {
//      TST     OPCND
//      TST     OPCND
        // Dual operand instructions that take conditions
        // Dual operand instructions that take conditions
        OP_CMP, OP_TST, OP_MOV, OP_LDIHI, OP_LDILO, OP_MPYU, OP_MPYS, OP_ROL,
        OP_CMP, OP_TST, OP_MOV, OP_LDIHI, OP_LDILO, OP_MPYU, OP_MPYS, OP_ROL,
                OP_SUB, OP_AND, OP_ADD, OP_OR, OP_XOR,
                OP_SUB, OP_AND, OP_ADD, OP_OR, OP_XOR,
                OP_LSL, OP_ASR, OP_LSR,
                OP_LSL, OP_ASR, OP_LSR,
 
        // New multiplies
 
        OP_MPY, OP_MPYSHI, OP_MPYUHI,
        // New bit-wise operations
        // New bit-wise operations
        OP_BREV, OP_POPC,
        OP_BREV, OP_POPC,
        // New divide instruction
        // New divide instruction
        OP_DIVU, OP_DIVS,
        OP_DIVU, OP_DIVS,
        // New floating point instructions
        // New floating point instructions
        OP_FPADD, OP_FPSUB, OP_FPMUL, OP_FPDIV, OP_FPCVT, OP_FPINT,
        OP_FPADD, OP_FPSUB, OP_FPMUL, OP_FPDIV, OP_FPCVT, OP_FPINT,
        // Memory operands/operators
        // Memory operands/operators
        OP_LOD, OP_STO,
        OP_LOD, OP_STO,
        // Dual operand instructions that do not take conditions
        // Dual operand instructions that do not take conditions
        OP_LDI,
        OP_LDI,
        // Single operand instructions that can take conditions
        // Single operand instructions that can take conditions
        OP_CLRF, OP_JMP, OP_NOT,
        OP_CLRF, OP_JMP, OP_NOT,
        // Branch operands
        // Branch operands
        OP_BRA, OP_BLT, OP_BZ, OP_BNZ, OP_BGT, OP_BGE, OP_BRC, OP_BRV,
        OP_BRA, OP_BLT, OP_BZ, OP_BNZ, OP_BGT, OP_BGE, OP_BRC, OP_BRV,
        // Single operand instructions that have no explicit conditions
        // Single operand instructions that have no explicit conditions
        OP_CLR, OP_TRAP, OP_NEG,
        OP_CLR, OP_TRAP, OP_NEG,
        // BAREOPs that can have conditions
        // BAREOPs that can have conditions
        OP_HALT,  OP_RTU, OP_BUSY, OP_RETN,
        OP_HALT,  OP_RTU, OP_BUSY, OP_RETN,
        // BAREOPs without conditions
        // BAREOPs without conditions
        OP_BREAK, OP_NOOP, OP_LOCK, OP_LJMP,
        OP_BREAK, OP_NOOP, OP_LOCK, OP_LJMP,
        // Error condition--undefined operand
        // Error condition--undefined operand
        OP_NONE
        OP_NONE
} LEXOPCODE;
} LEXOPCODE;
 
 
#define DEFAULT_LINE    0x76000000
#define DEFAULT_LINE    0x76000000
 
 
class   ASMLINE {
class   ASMLINE {
public:
public:
        char    m_state;
        char    m_state;
        int     m_lineno;
        int     m_lineno;
        virtual bool    isdefined(void) { return true; };
        virtual bool    isdefined(void) { return true; };
        virtual ~ASMLINE(void) {};
        virtual ~ASMLINE(void) {};
        virtual int     nlines(void) { return 0; }
        virtual int     nlines(void) { return 0; }
        virtual unsigned int    eval(const int lno) { return DEFAULT_LINE; }
        virtual unsigned int    eval(const int lno) { return DEFAULT_LINE; }
        virtual void    dump(FILE *fp) = 0;
        virtual void    dump(FILE *fp) = 0;
};
};
 
 
class   AST { // The actual expression tree
class   AST { // The actual expression tree
public:
public:
        // node type is one of:
        // node type is one of:
        // 'B' a branch with two sides
        // 'B' a branch with two sides
        // 'N' a number
        // 'N' a number
        // 'I' an identifier
        // 'I' an identifier
        // 'A' ?? an address ?? would we need this?
        // 'A' ?? an address ?? would we need this?
        virtual ~AST(void) {}
        virtual ~AST(void) {}
        char    m_node_type;
        char    m_node_type;
        virtual bool    isdefined(void) = 0;
        virtual bool    isdefined(void) = 0;
        virtual int     eval(void) = 0;
        virtual int     eval(void) = 0;
        virtual void    reduce(void) = 0;
        virtual void    reduce(void) = 0;
        virtual void    dump(FILE *fp) = 0;
        virtual void    dump(FILE *fp) = 0;
};
};
 
 
/*
/*
class   ULINE : public ASMLINE  { // Unprocessed line of assembly
class   ULINE : public ASMLINE  { // Unprocessed line of assembly
public:
public:
        std::string     m_file, m_text;
        std::string     m_file, m_text;
        int             m_lineno;
        int             m_lineno;
        ULINE(const int line, const std::string file,
        ULINE(const int line, const std::string file,
                const std::string text) : m_file(file), m_text(text),
                const std::string text) : m_file(file), m_text(text),
                                        m_lineno(line) { m_state = 'U'; }
                                        m_lineno(line) { m_state = 'U'; }
        class TLINE     *eval(void);
        class TLINE     *eval(void);
        int             nlines(void) { return 0; };
        int             nlines(void) { return 0; };
        virtual bool    isdefined(void) { return false; };
        virtual bool    isdefined(void) { return false; };
};
};
*/
*/
 
 
class   ILINE : public ASMLINE { // Instruction line
class   ILINE : public ASMLINE { // Instruction line
public:
public:
        ZIPI    m_in;
        ZIPI    m_in;
        ILINE(const ZIPI in) : m_in(in) { m_state = 'I'; m_lineno = yylineno; };
        ILINE(const ZIPI in) : m_in(in) { m_state = 'I'; m_lineno = yylineno; };
        virtual bool    isdefined(void) { return true; };
        virtual bool    isdefined(void) { return true; };
        virtual int     nlines(void) { return 1; }
        virtual int     nlines(void) { return 1; }
        virtual unsigned int    eval(const int lno);
        virtual unsigned int    eval(const int lno);
        void    dump(FILE *fp) { fprintf(fp, "IN: %08x\n", m_in); }
        void    dump(FILE *fp) { fprintf(fp, "IN: %08x\n", m_in); }
};
};
 
 
class   VLINE : public ASMLINE { // Void line
class   VLINE : public ASMLINE { // Void line
public:
public:
        VLINE(void) { m_state = 'V'; m_lineno = yylineno; };
        VLINE(void) { m_state = 'V'; m_lineno = yylineno; };
        virtual bool    isdefined(void) { return true; };
        virtual bool    isdefined(void) { return true; };
        virtual int     nlines(void) { return 0; }
        virtual int     nlines(void) { return 0; }
        virtual unsigned int    eval(const int lno);
        virtual unsigned int    eval(const int lno);
        void    dump(FILE *fp) { fprintf(fp, "void\n"); }
        void    dump(FILE *fp) { fprintf(fp, "void\n"); }
};
};
 
 
class   DLINE : public ASMLINE { // Data line
class   DLINE : public ASMLINE { // Data line
public:
public:
        ZIPI    m_data;
        ZIPI    m_data;
        DLINE(const ZIPI dat) : m_data(dat) { m_state = 'D'; m_lineno = yylineno; };
        DLINE(const ZIPI dat) : m_data(dat) { m_state = 'D'; m_lineno = yylineno; };
        virtual bool    isdefined(void) { return true; };
        virtual bool    isdefined(void) { return true; };
        virtual int     nlines(void) { return 1; }
        virtual int     nlines(void) { return 1; }
        virtual unsigned int    eval(const int lno);
        virtual unsigned int    eval(const int lno);
        void    dump(FILE *fp) { fprintf(fp, "\tWORD\t%08d\n", m_data); }
        void    dump(FILE *fp) { fprintf(fp, "\tWORD\t%08d\n", m_data); }
};
};
 
 
class   LLINE : public ASMLINE { // List line -- one line that has turned into
class   LLINE : public ASMLINE { // List line -- one line that has turned into
                // many
                // many
public:
public:
        int     m_nlines;
        int     m_nlines;
        ASMLINE **m_lines;
        ASMLINE **m_lines;
        LLINE(void) : m_nlines(0), m_lines(NULL) { m_state = 'L'; m_lineno = yylineno; };
        LLINE(void) : m_nlines(0), m_lines(NULL) { m_state = 'L'; m_lineno = yylineno; };
        void addline(ASMLINE *line) ;
        void addline(ASMLINE *line) ;
        virtual bool    isdefined(void);
        virtual bool    isdefined(void);
        ~LLINE(void);
        ~LLINE(void);
        virtual int     nlines(void) { return m_nlines; }
        virtual int     nlines(void) { return m_nlines; }
        virtual unsigned int    eval(const int lno);
        virtual unsigned int    eval(const int lno);
        void    dump(FILE *fp) {
        void    dump(FILE *fp) {
                for(int i=0; i<m_nlines; i++)
                for(int i=0; i<m_nlines; i++)
                        m_lines[i]->dump(fp);
                        m_lines[i]->dump(fp);
        }
        }
};
};
 
 
class   TLINE : public ASMLINE { // Expression tree
class   TLINE : public ASMLINE { // Expression tree
public:
public:
        LEXOPCODE               m_opcode;
        LEXOPCODE               m_opcode;
        ZPARSER::ZIPCOND        m_cond;
        ZPARSER::ZIPCOND        m_cond;
        AST                     *m_imm;
        AST                     *m_imm;
        ZPARSER::ZIPREG         m_opb, m_opa;
        ZPARSER::ZIPREG         m_opb, m_opa;
 
 
        TLINE(void) : m_opcode(OP_NONE), m_cond(ZPARSER::ZIPC_ALWAYS),
        TLINE(void) : m_opcode(OP_NONE), m_cond(ZPARSER::ZIPC_ALWAYS),
                        m_imm(NULL), m_opa(ZPARSER::ZIP_Rnone), m_opb(ZPARSER::ZIP_Rnone)
                        m_imm(NULL), m_opa(ZPARSER::ZIP_Rnone), m_opb(ZPARSER::ZIP_Rnone)
                        { m_state = 'T'; m_lineno = yylineno; };
                        { m_state = 'T'; m_lineno = yylineno; };
        virtual bool    isdefined(void) {
        virtual bool    isdefined(void) {
                if (m_imm != NULL) {
                if (m_imm != NULL) {
                        bool answer = m_imm->isdefined();
                        bool answer = m_imm->isdefined();
                        return answer;
                        return answer;
                } else return true;
                } else return true;
        }
        }
        ASMLINE *eval(void);
        ASMLINE *eval(void);
        ~TLINE(void) { if (m_imm) delete m_imm; }
        ~TLINE(void) { if (m_imm) delete m_imm; }
        virtual int     nlines(void); //  { return 1; }
        virtual int     nlines(void); //  { return 1; }
        virtual unsigned int    eval(const int lno);
        virtual unsigned int    eval(const int lno);
        void    dump(FILE *fp);
        void    dump(FILE *fp);
};
};
 
 
class   AST_BRANCH : public AST { // The actual expression tree
class   AST_BRANCH : public AST { // The actual expression tree
public:
public:
        int     m_op; // An operator
        int     m_op; // An operator
        AST     *m_left, *m_right;
        AST     *m_left, *m_right;
 
 
        AST_BRANCH(int op, AST *l, AST *r)
        AST_BRANCH(int op, AST *l, AST *r)
                : m_op(op), m_left(l), m_right(r) { m_node_type = 'B';
                : m_op(op), m_left(l), m_right(r) { m_node_type = 'B';
                }
                }
        ~AST_BRANCH(void) {
        ~AST_BRANCH(void) {
                if (m_left)
                if (m_left)
                        delete  m_left;
                        delete  m_left;
                if (m_right)
                if (m_right)
                        delete  m_right;
                        delete  m_right;
        }
        }
 
 
        bool    isdefined(void) {
        bool    isdefined(void) {
                return ((m_left)&&(m_right)
                return ((m_left)&&(m_right)
                                &&(m_left->isdefined())
                                &&(m_left->isdefined())
                                &&(m_right->isdefined()));
                                &&(m_right->isdefined()));
        }
        }
 
 
        int     eval(void);
        int     eval(void);
        void    reduce(void);
        void    reduce(void);
        void    dump(FILE *fp) {
        void    dump(FILE *fp) {
                fprintf(fp, "(");
                fprintf(fp, "(");
                m_left->dump(fp);
                m_left->dump(fp);
                fprintf(fp, ") %c (", m_node_type);
                fprintf(fp, ") %c (", m_node_type);
                m_right->dump(fp);
                m_right->dump(fp);
                fprintf(fp, ")");
                fprintf(fp, ")");
        }
        }
};
};
 
 
class   AST_NUMBER : public AST { // A number at the base of the tree
class   AST_NUMBER : public AST { // A number at the base of the tree
public:
public:
        int     m_val;
        int     m_val;
        AST_NUMBER(int val) : m_val(val) { m_node_type = 'N'; }
        AST_NUMBER(int val) : m_val(val) { m_node_type = 'N'; }
        bool    isdefined(void) { return true; }
        bool    isdefined(void) { return true; }
        int     eval(void);
        int     eval(void);
        void    reduce(void);
        void    reduce(void);
        void    dump(FILE *fp) { fprintf(fp, "%d", m_val); }
        void    dump(FILE *fp) { fprintf(fp, "%d", m_val); }
};
};
 
 
class   AST_IDENTIFIER : public AST { // An identifier within the expression tree
class   AST_IDENTIFIER : public AST { // An identifier within the expression tree
public:
public:
        std::string     m_id;
        std::string     m_id;
        AST_IDENTIFIER(const char *id) : m_id(id) { m_node_type = 'I'; }
        AST_IDENTIFIER(const char *id) : m_id(id) { m_node_type = 'I'; }
        AST_IDENTIFIER(AST *ida, const char *idb);
        AST_IDENTIFIER(AST *ida, const char *idb);
        bool    isdefined(void);
        bool    isdefined(void);
        int     eval(void);
        int     eval(void);
        void    reduce(void);
        void    reduce(void);
        void    dump(FILE *fp) { fprintf(fp, "%s", m_id.c_str()); }
        void    dump(FILE *fp) { fprintf(fp, "%s", m_id.c_str()); }
};
};
 
 
class   AST_LABEL : public AST { // An address label within the expression tree
class   AST_LABEL : public AST { // An address label within the expression tree
        // This is special, because it cannot be evaluated without knowing
        // This is special, because it cannot be evaluated without knowing
        // the PC value at this address
        // the PC value at this address
public:
public:
        std::string     m_label;
        std::string     m_label;
        AST_LABEL(const char *id) : m_label(id) { m_node_type = 'L'; }
        AST_LABEL(const char *id) : m_label(id) { m_node_type = 'L'; }
        bool    isdefined(void);
        bool    isdefined(void);
        int     eval(void);
        int     eval(void);
        void    reduce(void);
        void    reduce(void);
        void    dump(FILE *fp) { fprintf(fp, "%s", m_label.c_str()); }
        void    dump(FILE *fp) { fprintf(fp, "%s", m_label.c_str()); }
};
};
 
 
class   SAVED_ASMLINE {
class   SAVED_ASMLINE {
public:
public:
        unsigned int    m_pc;
        unsigned int    m_pc;
        ASMLINE         *m_ln;
        ASMLINE         *m_ln;
        SAVED_ASMLINE(const unsigned int pc, ASMLINE *ln) : m_pc(pc), m_ln(ln)
        SAVED_ASMLINE(const unsigned int pc, ASMLINE *ln) : m_pc(pc), m_ln(ln)
                {}
                {}
};
};
 
 
class   OBJFILE {
class   OBJFILE {
        typedef std::list<SAVED_ASMLINE> SVDTBL;
        typedef std::list<SAVED_ASMLINE> SVDTBL;
 
 
        SVDTBL          m_tbl;
        SVDTBL          m_tbl;
        unsigned int    m_pc;
        unsigned int    m_pc;
        FILE            *m_fp;
        FILE            *m_fp;
 
 
public:
public:
        OBJFILE(void) { m_fp = NULL; m_pc = 0; }
        OBJFILE(void) { m_fp = NULL; m_pc = 0; }
        void open(const char *fname);
        void open(const char *fname);
        void close(void) { fclose(m_fp); };
        void close(void) { fclose(m_fp); };
        unsigned int pc(void) { return m_pc; }
        unsigned int pc(void) { return m_pc; }
        void    operator+=(ASMLINE *ln);
        void    operator+=(ASMLINE *ln);
        bool    reduce(void);
        bool    reduce(void);
};
};
 
 
// The file we are building
// The file we are building
extern  OBJFILE objcode;
extern  OBJFILE objcode;
 
 
// Functions for accessing and defining elements in our symbol table
// Functions for accessing and defining elements in our symbol table
extern  bool    stb_isdefined(const char *key);
extern  bool    stb_isdefined(const char *key);
extern  int     stb_value(const char *key);
extern  int     stb_value(const char *key);
extern  void    stb_define(const char *key, AST *value);
extern  void    stb_define(const char *key, AST *value);
extern  void    gbl_define(const char *key, AST *value);
extern  void    gbl_define(const char *key, AST *value);
extern  bool    stb_isdefined(const std::string &key); //  { return stb_isdefined(key.c_str()); }
extern  bool    stb_isdefined(const std::string &key); //  { return stb_isdefined(key.c_str()); }
extern  int     stb_value(const std::string &key); //  { return stb_value(key.c_str()); }
extern  int     stb_value(const std::string &key); //  { return stb_value(key.c_str()); }
extern  void    stb_define(const std::string &key, AST *value); //  { return stb_define(key.c_str(), value); }
extern  void    stb_define(const std::string &key, AST *value); //  { return stb_define(key.c_str(), value); }
extern  void    gbl_define(const std::string &key, AST *value); //  { return stb_define(key.c_str(), value); }
extern  void    gbl_define(const std::string &key, AST *value); //  { return stb_define(key.c_str(), value); }
extern  void    create_new_context(void); // Create a new symbol table context
extern  void    create_new_context(void); // Create a new symbol table context
 
 
 
 
#endif // ASMDATA_H
#endif // ASMDATA_H
 
 

powered by: WebSVN 2.1.0

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