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

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zasm/] [zopcodes.cpp] - Blame information for rev 26

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

Line No. Rev Author Line
1 2 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    zopcodes.cpp
4
//
5
// Project:     Zip CPU -- a small, lightweight, RISC CPU core
6
//
7 13 dgisselq
// Purpose:     A simple program to handle the disassembly and definition
8
//              of the various Zip Assembly opcodes.  The primary function
9
//              of this file is the zipi_to_string, or Zip Instruction to
10
//              string (disassemble) conversion.
11 2 dgisselq
//
12
// Creator:     Dan Gisselquist, Ph.D.
13
//              Gisselquist Tecnology, LLC
14
//
15
////////////////////////////////////////////////////////////////////////////////
16
//
17
// Copyright (C) 2015, Gisselquist Technology, LLC
18
//
19
// This program is free software (firmware): you can redistribute it and/or
20
// modify it under the terms of  the GNU General Public License as published
21
// by the Free Software Foundation, either version 3 of the License, or (at
22
// your option) any later version.
23
//
24
// This program is distributed in the hope that it will be useful, but WITHOUT
25
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
26
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
27
// for more details.
28
//
29
// You should have received a copy of the GNU General Public License along
30
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
31
// target there if the PDF file isn't present.)  If not, see
32
// <http://www.gnu.org/licenses/> for a copy.
33
//
34
// License:     GPL, v3, as defined and found on www.gnu.org,
35
//              http://www.gnu.org/licenses/gpl.html
36
//
37
//
38
////////////////////////////////////////////////////////////////////////////////
39
 
40
#include <stdio.h>
41
#include <strings.h>
42
#include <string.h>
43
#include <assert.h>
44
 
45
#include "twoc.h"
46
#include "zopcodes.h"
47
 
48
const   char    *zop_regstr[] = {
49
        "R0", "R1", "R2", "R3",
50
        "R4", "R5", "R6", "R7",
51
        "R8", "R9", "R10","R11",
52
        "R12","SP", "CC", "PC",
53
        "uR0", "uR1", "uR2", "uR3",
54
        "uR4", "uR5", "uR6", "uR7",
55
        "uR8", "uR9", "uR10", "uR11",
56
        "uR12", "uSP", "uCC", "uPC",
57
        "sR0", "sR1", "sR2", "sR3",
58
        "sR4", "sR5", "sR6", "sR7",
59
        "sR8", "sR9", "sR10","sR11",
60
        "sR12","sSP", "sCC", "sPC"
61
};
62
 
63
const   char    *zop_ccstr[] = {
64
        "", ".Z", ".NE", ".GE", ".GT", ".LT", ".C", ".V"
65
};
66
 
67
const ZOPCODE   zoplist[] = {
68
        // Special case instructions.  These are general instructions, but with
69
        // special opcodes
70
        // Conditional branches
71 13 dgisselq
        "BUSY", 0xffffffff, 0x2f0f7fff, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
72 2 dgisselq
        "BRA",  0xffff8000, 0x2f0f0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
73
        "BRZ",  0xffff8000, 0x2f2f0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
74
        "BNZ",  0xffff8000, 0x2f4f0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
75
        "BGE",  0xffff8000, 0x2f6f0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
76
        "BGT",  0xffff8000, 0x2f8f0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
77
        "BLT",  0xffff8000, 0x2faf0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
78
        "BRC",  0xffff8000, 0x2fcf0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
79
        "BRV",  0xffff8000, 0x2fef0000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(15,0), OPUNUSED,
80
        // CLR
81
        "CLRF", 0xff1f0000, 0xc0100000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
82
        "CLRF", 0xff1f0000, 0xc1110000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
83
        "CLRF", 0xff1f0000, 0xc2120000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
84
        "CLRF", 0xff1f0000, 0xc3130000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
85
        "CLRF", 0xff1f0000, 0xc4140000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
86
        "CLRF", 0xff1f0000, 0xc5150000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
87
        "CLRF", 0xff1f0000, 0xc6160000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
88
        "CLRF", 0xff1f0000, 0xc7170000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
89
        "CLRF", 0xff1f0000, 0xc8180000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
90
        "CLRF", 0xff1f0000, 0xc9190000, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
91
        "CLRF", 0xff1f0000, 0xca1a0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
92
        "CLRF", 0xff1f0000, 0xcb1b0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
93
        "CLRF", 0xff1f0000, 0xcc1c0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
94
        "CLRF", 0xff1f0000, 0xcd1d0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
95
        "CLRF", 0xff1f0000, 0xce1e0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
96
        "CLRF", 0xff1f0000, 0xcf1f0000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
97
        //
98
        "CLR",  0xf0ffffff, 0x30000000, REGFIELD(24),OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED,
99
        //
100
        "HALT", 0xff10007f, 0xbe000010, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
101
        // The "wait" instruction is identical, with the only difference being
102
        // the interrrupt context of the processor.  Hence we allow both 
103
        // instructions here.
104
        "WAIT", 0xff10007f, 0xbe000010, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
105
        //
106
        "INT",  0xff10007f, 0x9e00005f, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
107
        // Return to user space
108
        "RTU",  0xff10007f, 0xbe000020, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
109
        // JMP (possibly a conditional jump, if not covered by branches above)
110
        "JMP",  0xff108000, 0x2f000000, OPUNUSED,OPUNUSED, REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
111
        "JMP",  0xff108000, 0x2f008000, OPUNUSED,OPUNUSED, URGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
112
        "LJMP", 0xff100000, 0xaf000000, OPUNUSED,OPUNUSED, OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
113
        // NOT
114
        "NOT",  0xf01fffff, 0xc00fffff, REGFIELD(24), OPUNUSED, OPUNUSED, OPUNUSED, BITFIELD(3,21),
115
        // General instructions
116
        "CMP",  0xf0100000, 0x00000000, OPUNUSED, REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
117
        "CMP",  0xf0100000, 0x00100000, OPUNUSED, REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
118
        "TST",  0xf0100000, 0x10000000, OPUNUSED, REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
119
        "TST",  0xf0100000, 0x10100000, OPUNUSED, REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
120
        // map bit = 1 (interrupts enabled) specifies user reg
121
        "MOV",  0xf0108000, 0x20000000, REGFIELD(24),OPUNUSED, REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
122
        "MOV",  0xf0108000, 0x20100000, URGFIELD(24),OPUNUSED, REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
123
        "MOV",  0xf0108000, 0x20008000, REGFIELD(24),OPUNUSED, URGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
124
        "MOV",  0xf0108000, 0x20108000, URGFIELD(24),OPUNUSED, URGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
125
        //
126
        "LDI",  0xf0000000, 0x30000000, REGFIELD(24),OPUNUSED, OPUNUSED, IMMFIELD(24,0), OPUNUSED,
127
        //
128
        "NOOP",  0xffffffff, 0x4e000000, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED,
129
        "BRK",   0xffffffff, 0x4e000001, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED, OPUNUSED,
130
        //
131
        "LDILO",0xff100000, 0x4f000000, REGFIELD(16),OPUNUSED, OPUNUSED, IMMFIELD(16,0), BITFIELD(3,21),
132
        "LDIHI",0xff100000, 0x4f100000, REGFIELD(16),OPUNUSED, OPUNUSED, IMMFIELD(16,0), BITFIELD(3,21),
133
        //
134 26 dgisselq
        "MPYU", 0xf01f0000, 0x400f0000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(15,0), BITFIELD(3,21),
135
        "MPYU", 0xf0100000, 0x40000000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
136
        "MPYS", 0xf01f0000, 0x401f0000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(15,0), BITFIELD(3,21),
137
        "MPYS", 0xf0100000, 0x40100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(15,0), BITFIELD(3,21),
138 8 dgisselq
        //
139
        "ROL",  0xf0100000, 0x50000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(5,0), BITFIELD(3,21),
140
        "ROL",  0xf0100000, 0x50100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(5,0), BITFIELD(3,21),
141
        //
142 2 dgisselq
        "LOD",  0xf0100000, 0x60000000, REGFIELD(24), OPUNUSED, OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
143
        "LOD",  0xf0100000, 0x60100000, REGFIELD(24), OPUNUSED, REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
144
        //
145
        "STO",  0xf0100000, 0x70000000, OPUNUSED, REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
146
        "STO",  0xf0100000, 0x70100000, OPUNUSED, REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
147
        //
148
        "SUB",  0xf0100000, 0x80000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
149
        "SUB",  0xf0100000, 0x80100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
150
        //
151
        "AND",  0xf0100000, 0x90000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
152
        "AND",  0xf0100000, 0x90100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
153
        //
154
        "ADD",  0xf0100000, 0xa0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
155
        "ADD",  0xf0100000, 0xa0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
156
        //
157
        "OR",   0xf0100000, 0xb0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
158
        "OR",   0xf0100000, 0xb0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
159
        //
160
        "XOR",  0xf0100000, 0xc0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
161
        "XOR",  0xf0100000, 0xc0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
162
        //
163
        "LSL",  0xf0100000, 0xd0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
164
        "LSL",  0xf0100000, 0xd0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
165
        //
166
        "ASR",  0xf0100000, 0xe0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
167
        "ASR",  0xf0100000, 0xe0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
168
        //
169
        "LSR",  0xf0100000, 0xf0000000, REGFIELD(24), REGFIELD(24), OPUNUSED, IMMFIELD(19,0), BITFIELD(3,21),
170
        "LSR",  0xf0100000, 0xf0100000, REGFIELD(24), REGFIELD(24), REGFIELD(16), IMMFIELD(16,0), BITFIELD(3,21),
171
        // Illegal instruction !!
172
        "ILL",  0x00000000, 0x00000000, OPUNUSED, OPUNUSED, OPUNUSED, IMMFIELD(32,0), OPUNUSED
173
};
174
 
175
const int       nzoplist = (sizeof(zoplist)/sizeof(ZOPCODE));
176
 
177
static  int     getbits(const ZIPI ins, const int which) {
178
        if (which & 0x40000000) {
179
                // printf("SBITS: %08x, %08x = %08lx\n", ins, which,
180
                        // sbits(ins>>(which & 0x03f), (which>>8)&0x03f));
181
                return sbits(ins>>(which & 0x03f), (which>>8)&0x03f);
182
        } else if (which &0x03f) {
183
                return ubits(ins>>(which & 0x03f), (which>>8)&0x03f)
184
                        + ((which>>16)&0x0ff);
185
        } else
186
                return which;
187
}
188
 
189
void    zipi_to_string(const ZIPI ins, char *line) {
190
        for(int i=0; i<nzoplist; i++)
191
                assert(((~zoplist[i].s_mask)&zoplist[i].s_val)==0);
192
        for(int i=0; i<nzoplist; i++) {
193
                // printf("%2d: %6s %08x & %08x == %08x\n",
194
                        // i, zoplist[i].s_opstr, ins,
195
                        // zoplist[i].s_mask, zoplist[i].s_val);
196
                if ((ins & zoplist[i].s_mask) == zoplist[i].s_val) {
197 17 dgisselq
                        sprintf(line, "  %s", zoplist[i].s_opstr);
198 2 dgisselq
                        if (zoplist[i].s_cf != OPUNUSED) {
199
                                int bv = getbits(ins, zoplist[i].s_cf);
200
                                strcat(line, zop_ccstr[bv]);
201 17 dgisselq
                        } sprintf(line, "%-13s", line);
202 2 dgisselq
 
203
                        // Treat stores special
204
                        if (strncasecmp("STO",zoplist[i].s_opstr, 3)==0) {
205
                                int ra = getbits(ins, zoplist[i].s_ra);
206
                                strcat(line, zop_regstr[ra]);
207
                                strcat(line, ",");
208
 
209
                                if (zoplist[i].s_i != OPUNUSED) {
210
                                        int     imv = 0;
211
                                        imv = getbits(ins, zoplist[i].s_i);
212
                                        if ((imv != 0)&&(zoplist[i].s_rb != OPUNUSED))
213
                                                sprintf(&line[strlen(line)],
214
                                                        "$%d", imv);
215
                                        else if (imv != 0)
216
                                                sprintf(&line[strlen(line)],
217
                                                        "($%d)", imv);
218
                                } if (zoplist[i].s_rb != OPUNUSED) {
219
                                        int rb = getbits(ins, zoplist[i].s_rb);
220
                                        sprintf(&line[strlen(line)],
221
                                                "(%s)", zop_regstr[rb]);
222
                                }
223
 
224
                        } else {
225
                                bool memop = (strncasecmp("LOD",
226
                                                zoplist[i].s_opstr, 3)==0);
227
                                if (zoplist[i].s_i != OPUNUSED) {
228
                                        int     imv = 0;
229
                                        imv = getbits(ins, zoplist[i].s_i);
230
                                        if ((imv != 0)||(zoplist[i].s_rb == OPUNUSED))
231
                                                sprintf(&line[strlen(line)],
232
                                                        "$%d%s", imv,
233
                                                        ((!memop)&&(zoplist[i].s_rb!=OPUNUSED))?"+":"");
234
                                } if (zoplist[i].s_rb != OPUNUSED) {
235
                                        int rb = getbits(ins, zoplist[i].s_rb);
236
                                        if (memop)
237
                                                sprintf(&line[strlen(line)],
238
                                                        "(%s)", zop_regstr[rb]);
239
                                        else
240
                                                strcat(line, zop_regstr[rb]);
241
                                } if(((zoplist[i].s_i != OPUNUSED)||(zoplist[i].s_rb != OPUNUSED))
242
                                        &&((zoplist[i].s_ra != OPUNUSED)||(zoplist[i].s_result != OPUNUSED)))
243
                                        strcat(line, ",");
244
 
245
                                if (zoplist[i].s_ra != OPUNUSED) {
246
                                        int ra = getbits(ins, zoplist[i].s_ra);
247
                                        strcat(line, zop_regstr[ra]);
248
                                } else if (zoplist[i].s_result != OPUNUSED) {
249
                                        int ra = getbits(ins, zoplist[i].s_result);
250
                                        strcat(line, zop_regstr[ra]);
251
                                }
252
 
253
                        }
254
                        break;
255
                }
256
        }
257
}
258
 

powered by: WebSVN 2.1.0

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