URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
[/] [zipcpu/] [trunk/] [sw/] [zasm/] [zparser.cpp] - Rev 36
Go to most recent revision | Compare with Previous | Blame | View Log
//////////////////////////////////////////////////////////////////////////////// // // Filename: zparser.cpp // // Project: Zip CPU -- a small, lightweight, RISC CPU core // // Purpose: This file is really mis-named. At one time it was going to // be the parser for the Zip Assembler, zasm. Since then, I // discovered Flex and Bison and have written a parser using // those tools. The true parser may therefore be found in zasm.y. // This file, however, still contains some very valuable tools. // In particular, all of the routines used to build instructions // from the appropriate fields are kept in this file. For example, // op_noop() returns the instruction code for a NOOP instruction. // // Creator: Dan Gisselquist, Ph.D. // Gisselquist Tecnology, LLC // //////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2015, Gisselquist Technology, LLC // // 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 // by the Free Software Foundation, either version 3 of the License, or (at // your option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License along // with this program. (It's in the $(ROOT)/doc directory, run make with no // target there if the PDF file isn't present.) If not, see // <http://www.gnu.org/licenses/> for a copy. // // License: GPL, v3, as defined and found on www.gnu.org, // http://www.gnu.org/licenses/gpl.html // // //////////////////////////////////////////////////////////////////////////////// #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <strings.h> #include "zparser.h" #include "zopcodes.h" typedef ZPARSER::ZIPI ZIPI; // A Zip Instruction (i.e. uint32) #define IMMOP(OP,CND,IMM,A) (((OP&0x0f)<<28)|((A&0x0f)<<24)|((CND&0x07)<<21) \ | (IMM & 0x0fffff)) #define DBLREGOP(OP,CND,IMM,B,A) (((OP&0x0f)<<28)|((A&0x0f)<<24) \ |((CND&0x07)<<21)|(1<<20)|((B&0x0f)<<16) \ | (IMM & 0x0ffff)) ZIPI ZPARSER::op_cmp(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0x0, cnd, imm, b, a); } ZIPI ZPARSER::op_cmp(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0x0, cnd, imm, a); } ZIPI ZPARSER::op_tst(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0x1, cnd, imm, b, a); } ZIPI ZPARSER::op_tst(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0x1, cnd, imm, a); } ZIPI ZPARSER::op_mov(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { ZIPI in; in = (0x02 << 28)|((a&0x0f)<<24)|((cnd&0x07)<<21); in |= (a&0x10)<<16; in |= (b&0x0f)<<16; in |= (b&0x10)<<11; in |= imm & 0x07fff; return in; } ZIPI ZPARSER::op_ldi(ZIPIMM imm, ZIPREG a) const { ZIPI in; in = ((0x03)<<28) | ((a&0x0f)<<24) | (imm & ((1<<24)-1)); return in; } ZIPI ZPARSER::op_trap(ZIPCOND cnd, ZIPIMM imm) const { ZIPI in; if (cnd != ZIPC_ALWAYS) return op_ldilo(cnd, imm, ZIP_CC); else return op_ldi(imm, ZIP_CC); // in = ((0x4f)<<24)|((cnd&0x07)<<21)|(1<<20)|((0x0e)<<16); // in |= (imm & 0x0ffff); return in; } ZIPI ZPARSER::op_noop(void) const { return 0x4e000000; } ZIPI ZPARSER::op_break(void) const { return 0x4e000001; } ZIPI ZPARSER::op_ldihi(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { ZIPI in; in = ((0x4f)<<24)|((cnd&0x07)<<21)|(1<<20)|((a&0x0f)<<16); in |= (imm & 0x0ffff); return in; } ZIPI ZPARSER::op_ldilo(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { ZIPI in; in = ((0x4f)<<24)|((cnd&0x07)<<21)|(0<<20)|((a&0x0f)<<16); in |= (imm & 0x0ffff); return in; } ZIPI ZPARSER::op_mpyu(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return (0x04<<28)|((a&0x0f)<<24)|((cnd&0x7)<<21)|(0<<20)|((b&0x0f)<<16)|(imm & 0x0ffff); } ZIPI ZPARSER::op_mpyu(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return (0x04<<28)|((a&0x0f)<<24)|((cnd&0x7)<<21)|(0<<20)|((0x0f)<<16)|(imm & 0x0ffff); } ZIPI ZPARSER::op_mpys(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return (0x04<<28)|((a&0x0f)<<24)|((cnd&0x7)<<21)|(1<<20)|((b&0x0f)<<16)|(imm & 0x0ffff); } ZIPI ZPARSER::op_mpys(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return (0x04<<28)|((a&0x0f)<<24)|((cnd&0x7)<<21)|(1<<20)|((0x0f)<<16)|(imm & 0x0ffff); } ZIPI ZPARSER::op_rol(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0x5, cnd, imm, b, a); } ZIPI ZPARSER::op_rol(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0x5, cnd, imm, a); } ZIPI ZPARSER::op_lod(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0x6, cnd, imm, b, a); } ZIPI ZPARSER::op_lod(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0x6, cnd, imm, a); } ZIPI ZPARSER::op_sto(ZIPCOND cnd, ZIPREG v, ZIPIMM imm, ZIPREG b) const { return DBLREGOP(0x7, cnd, imm, b, v); } ZIPI ZPARSER::op_sto(ZIPCOND cnd, ZIPREG v, ZIPIMM imm) const { return IMMOP(0x7, cnd, imm, v); } ZIPI ZPARSER::op_sub(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0x8, cnd, imm, b, a); } ZIPI ZPARSER::op_sub(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { // While it seems like we might do well replacing a subtract immediate // with an add of the negative same, the conditions aren't the same // when doing so. Hence this is an invalid substitution. // return IMMOP(0xa, cnd, -imm, a); // Do an add of the negative of imm return IMMOP(0x8, cnd, imm, a); } ZIPI ZPARSER::op_and(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0x9, cnd, imm, b, a); } ZIPI ZPARSER::op_and(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0x9, cnd, imm, a); } ZIPI ZPARSER::op_add(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0xa, cnd, imm, b, a); } ZIPI ZPARSER::op_add(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0xa, cnd, imm, a); } ZIPI ZPARSER::op_or(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0xb, cnd, imm, b, a); } ZIPI ZPARSER::op_or(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0xb, cnd, imm, a); } ZIPI ZPARSER::op_xor(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0xc, cnd, imm, b, a); } ZIPI ZPARSER::op_xor(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0xc, cnd, imm, a); } ZIPI ZPARSER::op_lsl(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0xd, cnd, imm, b, a); } ZIPI ZPARSER::op_lsl(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0xd, cnd, imm, a); } ZIPI ZPARSER::op_asr(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0xe, cnd, imm, b, a); } ZIPI ZPARSER::op_asr(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0xe, cnd, imm, a); } ZIPI ZPARSER::op_lsr(ZIPCOND cnd, ZIPIMM imm, ZIPREG b, ZIPREG a) const { return DBLREGOP(0xf, cnd, imm, b, a); } ZIPI ZPARSER::op_lsr(ZIPCOND cnd, ZIPIMM imm, ZIPREG a) const { return IMMOP(0xf, cnd, imm, a); }
Go to most recent revision | Compare with Previous | Blame | View Log