URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
[/] [zipcpu/] [trunk/] [sw/] [zasm/] [zopcodes.cpp] - Rev 47
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", 0xffffffff, 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