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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zasm/] [zopcodes.cpp] - Rev 53

Go to most recent revision | Compare with Previous | Blame | View Log

////////////////////////////////////////////////////////////////////////////////
//
// Filename: 	zopcodes.cpp
//
// Project:	Zip CPU -- a small, lightweight, RISC CPU core
//
// Purpose:	A simple program to handle the disassembly and definition
//		of the various Zip Assembly opcodes.  The primary function
//		of this file is the zipi_to_string, or Zip Instruction to
//		string (disassemble) conversion.
//
// 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 <strings.h>
#include <string.h>
#include <assert.h>
 
#include "twoc.h"
#include "zopcodes.h"
 
const	char	*zop_regstr[] = {
	"R0", "R1", "R2", "R3",
	"R4", "R5", "R6", "R7",
	"R8", "R9", "R10","R11",
	"R12","SP", "CC", "PC",
	"uR0", "uR1", "uR2", "uR3",
	"uR4", "uR5", "uR6", "uR7",
	"uR8", "uR9", "uR10", "uR11",
	"uR12", "uSP", "uCC", "uPC",
	"sR0", "sR1", "sR2", "sR3",
	"sR4", "sR5", "sR6", "sR7",
	"sR8", "sR9", "sR10","sR11",
	"sR12","sSP", "sCC", "sPC"
};
 
const	char	*zop_ccstr[] = {
	"", ".Z", ".NE", ".GE", ".GT", ".LT", ".C", ".V"
};
 
const ZOPCODE	zoplist[] = {
	// Special case instructions.  These are general instructions, but with
	// special opcodes
	// Conditional branches
	"BUSY", 0xff1fffff, 0x2f0f7fff, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"BRA",  0xffff8000, 0x2f0f0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
	"BRZ",  0xffff8000, 0x2f2f0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
	"BNZ",  0xffff8000, 0x2f4f0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
	"BGE",  0xffff8000, 0x2f6f0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
	"BGT",  0xffff8000, 0x2f8f0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
	"BLT",  0xffff8000, 0x2faf0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
	"BRC",  0xffff8000, 0x2fcf0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
	"BRV",  0xffff8000, 0x2fef0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
	// CLR
	"CLRF",	0xff1f0000, 0xc0100000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xc1110000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xc2120000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xc3130000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xc4140000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xc5150000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xc6160000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xc7170000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xc8180000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xc9190000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xca1a0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xcb1b0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xcc1c0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xcd1d0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xce1e0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"CLRF",	0xff1f0000, 0xcf1f0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	//
	"CLR",  0xf0ffffff, 0x30000000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED,
	//
	"HALT",	0xff10007f, 0xbe000010, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	// The "wait" instruction is identical, with the only difference being
	// the interrrupt context of the processor.  Hence we allow both 
	// instructions here.
	"WAIT",	0xff10007f, 0xbe000010, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	//
	"INT",	0xff10007f, 0x9e00005f, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	// Return to user space
	"RTU",	0xff10007f, 0xbe000020, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	// JMP (possibly a conditional jump, if not covered by branches above)
	"JMP",  0xff108000, 0x2f000000, OPUNUSED,OPUNUSED, REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
	"JMP",  0xff108000, 0x2f008000, OPUNUSED,OPUNUSED, URGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
	"LJMP",	0xff100000, 0xaf000000, OPUNUSED,OPUNUSED, OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	// NOT
	"NOT",	0xf01fffff, 0xc00fffff, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	// General instructions
	"CMP",	0xf0100000, 0x00000000, OPUNUSED, REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"CMP",	0xf0100000, 0x00100000, OPUNUSED, REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	"TST",	0xf0100000, 0x10000000, OPUNUSED, REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"TST",	0xf0100000, 0x10100000, OPUNUSED, REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	// map bit = 1 (interrupts enabled) specifies user reg
	"MOV",  0xf0108000, 0x20000000, REGFIELD(24),OPUNUSED, REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
	"MOV",  0xf0108000, 0x20100000, URGFIELD(24),OPUNUSED, REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
	"MOV",  0xf0108000, 0x20008000, REGFIELD(24),OPUNUSED, URGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
	"MOV",  0xf0108000, 0x20108000, URGFIELD(24),OPUNUSED, URGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
	//
	"LDI",  0xf0000000, 0x30000000, REGFIELD(24),OPUNUSED, OPUNUSED, IMMFIELD(24,0), OPUNUSED,
	//
	"NOOP",  0xffffffff, 0x4e000000, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED,
	"BRK",   0xffffffff, 0x4e000001, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED,
	//
	"LDILO",0xff100000, 0x4f000000, REGFIELD(16),OPUNUSED, OPUNUSED, IMMFIELD(16,0), BITFIELD(3,21),
	"LDIHI",0xff100000, 0x4f100000, REGFIELD(16),OPUNUSED, OPUNUSED, IMMFIELD(16,0), BITFIELD(3,21),
	//
	"MPYU",	0xf01f0000, 0x400f0000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(15,0), BITFIELD(3,21),
	"MPYU",	0xf0100000, 0x40000000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
	"MPYS",	0xf01f0000, 0x401f0000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(15,0), BITFIELD(3,21),
	"MPYS",	0xf0100000, 0x40100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
	//
	"ROL",	0xf0100000, 0x50000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(5,0), BITFIELD(3,21),
	"ROL",	0xf0100000, 0x50100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(5,0), BITFIELD(3,21),
	//
	"RETN",	0xff1fffff, 0x6f1d0001, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
	"LOD",	0xf0100000, 0x60000000, REGFIELD(24), OPUNUSED, OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"LOD",	0xf0100000, 0x60100000, REGFIELD(24), OPUNUSED, REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	//
	"STO",	0xf0100000, 0x70000000, OPUNUSED, REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"STO",	0xf0100000, 0x70100000, OPUNUSED, REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	//
	"SUB",	0xf0100000, 0x80000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"SUB",	0xf0100000, 0x80100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	//
	"AND",	0xf0100000, 0x90000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"AND",	0xf0100000, 0x90100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	//
	"ADD",	0xf0100000, 0xa0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"ADD",	0xf0100000, 0xa0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	//
	"OR",	0xf0100000, 0xb0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"OR",	0xf0100000, 0xb0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	//
	"XOR",	0xf0100000, 0xc0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"XOR",	0xf0100000, 0xc0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	//
	"LSL",	0xf0100000, 0xd0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"LSL",	0xf0100000, 0xd0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	//
	"ASR",	0xf0100000, 0xe0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"ASR",	0xf0100000, 0xe0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	//
	"LSR",	0xf0100000, 0xf0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
	"LSR",	0xf0100000, 0xf0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
	// Illegal instruction !!
	"ILL",	0x00000000, 0x00000000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(32,0), OPUNUSED
};
 
const int	nzoplist = (sizeof(zoplist)/sizeof(ZOPCODE));
 
static	int	getbits(const ZIPI ins, const int which) {
	if (which & 0x40000000) {
		// printf("SBITS: %08x, %08x = %08lx\n", ins, which,
			// sbits(ins>>(which & 0x03f), (which>>8)&0x03f));
		return sbits(ins>>(which & 0x03f), (which>>8)&0x03f);
	} else if (which &0x03f) {
		return ubits(ins>>(which & 0x03f), (which>>8)&0x03f)
			+ ((which>>16)&0x0ff);
	} else
		return which;
}
 
void	zipi_to_string(const ZIPI ins, char *line) {
	for(int i=0; i<nzoplist; i++)
		assert(((~zoplist[i].s_mask)&zoplist[i].s_val)==0);
	for(int i=0; i<nzoplist; i++) {
		// printf("%2d: %6s %08x & %08x == %08x\n",
			// i, zoplist[i].s_opstr, ins,
			// zoplist[i].s_mask, zoplist[i].s_val);
		if ((ins & zoplist[i].s_mask) == zoplist[i].s_val) {
			sprintf(line, "  %s", zoplist[i].s_opstr);
			if (zoplist[i].s_cf != OPUNUSED) {
				int bv = getbits(ins, zoplist[i].s_cf);
				strcat(line, zop_ccstr[bv]);
			} sprintf(line, "%-13s", line);
 
			// Treat stores special
			if (strncasecmp("STO",zoplist[i].s_opstr, 3)==0) {
				int ra = getbits(ins, zoplist[i].s_ra);
				strcat(line, zop_regstr[ra]);
				strcat(line, ",");
 
				if (zoplist[i].s_i != OPUNUSED) {
					int	imv = 0;
					imv = getbits(ins, zoplist[i].s_i);
					if ((imv != 0)&&(zoplist[i].s_rb != OPUNUSED))
						sprintf(&line[strlen(line)],
							"$%d", imv);
					else if (imv != 0)
						sprintf(&line[strlen(line)],
							"($%d)", imv);
				} if (zoplist[i].s_rb != OPUNUSED) {
					int rb = getbits(ins, zoplist[i].s_rb);
					sprintf(&line[strlen(line)],
						"(%s)", zop_regstr[rb]);
				}
 
			} else {
				bool memop = (strncasecmp("LOD",
						zoplist[i].s_opstr, 3)==0);
				if (zoplist[i].s_i != OPUNUSED) {
					int	imv = 0;
					imv = getbits(ins, zoplist[i].s_i);
					if ((imv != 0)||(zoplist[i].s_rb == OPUNUSED))
						sprintf(&line[strlen(line)],
							"$%d%s", imv,
							((!memop)&&(zoplist[i].s_rb!=OPUNUSED))?"+":"");
				} if (zoplist[i].s_rb != OPUNUSED) {
					int rb = getbits(ins, zoplist[i].s_rb);
					if (memop)
						sprintf(&line[strlen(line)],
							"(%s)", zop_regstr[rb]);
					else
						strcat(line, zop_regstr[rb]);
				} if(((zoplist[i].s_i != OPUNUSED)||(zoplist[i].s_rb != OPUNUSED))
					&&((zoplist[i].s_ra != OPUNUSED)||(zoplist[i].s_result != OPUNUSED)))
					strcat(line, ",");
 
				if (zoplist[i].s_ra != OPUNUSED) {
					int ra = getbits(ins, zoplist[i].s_ra);
					strcat(line, zop_regstr[ra]);
				} else if (zoplist[i].s_result != OPUNUSED) {
					int ra = getbits(ins, zoplist[i].s_result);
					strcat(line, zop_regstr[ra]);
				}
 
			}
			break;
		}
	}
}
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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