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

Subversion Repositories openarty

[/] [openarty/] [trunk/] [sw/] [host/] [zopcodes.cpp] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 51 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    zopcodes.cpp
4
//
5
// Project:     OpenArty, an entirely open SoC based upon the Arty platform
6
//
7
// 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_double_string, or Zip Instruction to a
10
//      pair of strings (disassemble) conversion.  The pair of strings is
11
//      necessary since Zip instruction words may contain two separate
12
//      instructions.
13
//
14
// Creator:     Dan Gisselquist, Ph.D.
15
//              Gisselquist Technology, LLC
16
//
17
////////////////////////////////////////////////////////////////////////////////
18
//
19
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
20
//
21
// This program is free software (firmware): you can redistribute it and/or
22
// modify it under the terms of  the GNU General Public License as published
23
// by the Free Software Foundation, either version 3 of the License, or (at
24
// your option) any later version.
25
//
26
// This program is distributed in the hope that it will be useful, but WITHOUT
27
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
28
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
29
// for more details.
30
//
31
// You should have received a copy of the GNU General Public License along
32
// with this program.  (It's in the $(ROOT)/doc directory.  Run make with no
33
// target there if the PDF file isn't present.)  If not, see
34
// <http://www.gnu.org/licenses/> for a copy.
35
//
36
// License:     GPL, v3, as defined and found on www.gnu.org,
37
//              http://www.gnu.org/licenses/gpl.html
38
//
39
//
40
////////////////////////////////////////////////////////////////////////////////
41
//
42
//
43
#include <stdio.h>
44
#include <strings.h>
45
#include <string.h>
46
#include <assert.h>
47
#include <ctype.h>
48
 
49
#include "twoc.h"
50
#include "zopcodes.h"
51
 
52
const   char    *zip_regstr[] = {
53
        "R0", "R1", "R2", "R3",
54
        "R4", "R5", "R6", "R7",
55
        "R8", "R9", "R10","R11",
56
        "R12","SP", "CC", "PC",
57
        "uR0", "uR1", "uR2", "uR3",
58
        "uR4", "uR5", "uR6", "uR7",
59
        "uR8", "uR9", "uR10", "uR11",
60
        "uR12", "uSP", "uCC", "uPC",
61
        "sR0", "sR1", "sR2", "sR3",
62
        "sR4", "sR5", "sR6", "sR7",
63
        "sR8", "sR9", "sR10","sR11",
64
        "sR12","sSP", "sCC", "sPC", "rILL"
65
};
66
 
67
const   char    *zip_ccstr[8] = {
68
        "",  ".Z",  ".LT", ".C",
69
        ".V",".NZ", ".GE", ".NC"
70
};
71
 
72
static const ZOPCODE    zip_oplist_raw[] = {
73
        // Special case instructions.  These are general instructions, but with
74
        // special opcodes
75
        // Conditional branches
76
        //      0.1111.0111.ccc.0.111.10iiiii--
77
        //      0111 1011 11cc c011 110i iiii iiii iiii
78
        { "BUSY", 0xffc7ffff, 0x7883ffff, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
79
        { "BZ",  0xfffc0000, 0x78880000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
80
        { "BLT", 0xfffc0000, 0x78900000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
81
        { "BC",  0xfffc0000, 0x78980000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
82
        { "BV",  0xfffc0000, 0x78a00000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
83
        { "BNZ",  0xfffc0000, 0x78a80000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
84
        { "BGE",  0xfffc0000, 0x78b00000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
85
        { "BNC",  0xfffc0000, 0x78b80000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_OPUNUSED },
86
        { "BRA",  0xffc40000, 0x78800000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
87
        // Changes/updates to CC, based upon LDI
88
        { "TRAP", 0xfffffff0, 0x76000000, ZIP_OPUNUSED,ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
89
        { "TRAP", 0xff800000, 0x76000000, ZIP_OPUNUSED,ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
90
        // BREV based traps
91
        { "TRAP", 0xffc7ffff, 0x72000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
92
        // LDILO based traps
93
        { "TRAP",0xffc4ffff, 0x72400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
94
        { "TRAP",0xffc40000, 0x72400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
95
        // CLR -- a LDI of zero
96
        //      0.rrrr.1100.iiiiiii--
97
        //      0rrr r110 0...
98
        { "CLR",  0x87ffffff, 0x06000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
99
        // BREV based clears
100
        { "CLR", 0x87c7ffff, 0x02000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
101
        // HALT
102
        //      0.1110.00011.ccc.0.0000000000010
103
        //      0111.0000.11cc.c000.0000.0000.0000.0010
104
        { "HALT", 0xffc7ffff, 0x70c00010, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
105
        // The "wait" instruction is identical, with the only difference being
106
        // the interrrupt context of the processor.  Well, almost.  To
107
        // facilitate waits from supervisor mode, the wait instruction
108
        // explicitly forces the CPU into user mode.
109
        { "WAIT", 0xffc7ffff, 0x70c00030, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
110
        // 1.0011.11000.000.0000...... 5f ? A carefully chosen illegal insn ??
111
        // "INT", 0xff10007f, 0x9e00005f, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19),
112
        // Return to user space
113
        { "RTU", 0xffc7ffff, 0x70c00020, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
114
        // The return instruction: JMP R0 (possibly conditional) = MOV R0,PC
115
        { "RTN", 0xffc7ffff, 0x7b400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
116
        // JMP (possibly a conditional jump, if not covered by branches above)
117
        // 0.1111.01101.ccc.a.rrrr.biiiiiiiiiiiiiiii
118
        // 0111.1011.01cc.c0rr.rrbi.iiii.iiii.iiii              MOV x,PC
119
        { "JMP",  0xffc40000, 0x7b400000, ZIP_OPUNUSED,ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) },
120
        // 0.1111.1100.ii.iiii.iiii.iiii.iiii.iiii.iiii
121
        // 0111.1110.0iii.iiii.iiii.iiii.iiii.iiii              LDI x,PC
122
        { "JMPI", 0xff800000, 0x7e000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(23,0), ZIP_OPUNUSED },
123
        // 0.1111.10010.000.1.1111.000000000000000
124
        // 0111.1100.1000.0111.11ii.iiii.iiii.iiii              LOD (PC),PC
125
        { "LJMP", 0xffffffff, 0x7c87c000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
126
        // NOT : XOR w/ -1
127
        //      0.rrrr.00100.ccc.0111.11111111111
128
        //      0rrr.r001.00cc.c011.f.f.f.f
129
        // { "NOT", 0x87c7ffff, 0x0103ffff, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
130
        // General instructions
131
        // 0rrr.rooo.oocc.cxrr.rrii.iiii.iiii.iiii
132
        { "SUB", 0x87c40000, 0x00000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
133
        { "SUB", 0x87c40000, 0x00040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
134
        //
135
        { "AND", 0x87c40000, 0x00400000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
136
        { "AND", 0x87c40000, 0x00440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
137
        //
138
        { "ADD", 0x87c40000, 0x00800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
139
        { "ADD", 0x87c40000, 0x00840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
140
        //
141
        { "OR", 0x87c40000, 0x00c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
142
        { "OR", 0x87c40000, 0x00c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
143
        //
144
        { "XOR", 0x87c40000, 0x01000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
145
        { "XOR", 0x87c40000, 0x01040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
146
        //
147
        { "LSR", 0x87c40000, 0x01400000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
148
        { "LSR", 0x87c40000, 0x01440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
149
        //
150
        { "LSL", 0x87c40000, 0x01800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
151
        { "LSL", 0x87c40000, 0x01840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
152
        //
153
        { "ASR", 0x87c40000, 0x01c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
154
        { "ASR", 0x87c40000, 0x01c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
155
        //
156
        { "BREV",0x87c40000, 0x02000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
157
        { "BREV",0x87c40000, 0x02040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
158
        //
159
        { "LDILO",0x87c40000, 0x02400000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
160
        { "LDILO",0x87c40000, 0x02440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
161
        //
162
        //
163
        { "MPYUHI", 0x87c40000, 0x02800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
164
        { "MPYUHI", 0x87c40000, 0x02840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
165
        //
166
        { "MPYSHI", 0x87c40000, 0x02c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
167
        { "MPYSHI", 0x87c40000, 0x02c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
168
        //
169
        { "MPY", 0x87c40000, 0x03000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
170
        { "MPY", 0x87c40000, 0x03040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
171
        //
172
        { "MOV", 0x87c42000, 0x03400000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) },
173
        { "MOV", 0x87c42000, 0x03440000, ZIP_URGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) },
174
        { "MOV", 0x87c42000, 0x03402000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_URGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) },
175
        { "MOV", 0x87c42000, 0x03442000, ZIP_URGFIELD(27), ZIP_OPUNUSED, ZIP_URGFIELD(14), ZIP_IMMFIELD(13,0), ZIP_BITFIELD(3,19) },
176
        //
177
        { "DIVU", 0x87c40000, 0x03800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
178
        { "DIVU", 0x87c40000, 0x03840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
179
        //
180
        { "DIVS", 0x87c40000, 0x03c00000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
181
        { "DIVS", 0x87c40000, 0x03c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
182
        //
183
        { "CMP", 0x87c40000, 0x04000000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
184
        { "CMP", 0x87c40000, 0x04040000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
185
        { "TST", 0x87c40000, 0x04400000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
186
        { "TST", 0x87c40000, 0x04440000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
187
        //
188
        { "LW", 0x87c40000, 0x04800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
189
        { "LW", 0x87c40000, 0x04840000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
190
        //
191
        { "SW", 0x87c40000, 0x04c00000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
192
        { "SW", 0x87c40000, 0x04c40000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
193
        //
194
        { "LH", 0x87c40000, 0x05000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
195
        { "LH", 0x87c40000, 0x05040000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
196
        //
197
        { "SH", 0x87c40000, 0x05400000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
198
        { "SH", 0x87c40000, 0x05440000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
199
        //
200
        { "LB", 0x87c40000, 0x05800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
201
        { "LB", 0x87c40000, 0x05840000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
202
        //
203
        { "SB", 0x87c40000, 0x05c00000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
204
        { "SB", 0x87c40000, 0x05c40000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
205
        //
206
        // 0rrr.r101.1
207
        { "LDI",  0x87800000, 0x06000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(23,0), ZIP_OPUNUSED },
208
        // 0111.x111.00.xxxxxxxx
209
        { "BRK",   0xf7ffffff, 0x77000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
210
        { "BRK",   0xf7c00000, 0x77000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED },
211
        { "LOCK",  0xf7ffffff, 0x77400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
212
        { "LOCK",  0xf7c00000, 0x77400000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED },
213
        // 0.111x.00000.xxx.xxx.xxxx.xxxx.xxxx.xxxx
214
        // 0111.x111.11.xxx.xxx.xxxx.xxxx.xxxx.xxxx
215
        // SNOOP = SIM w/ no argument(s)
216
        { "SIM",  0xf7ffffff, 0x77800000, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
217
        { "SEXIT",0xf7ffffff, 0x77800100, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
218
        { "SEXIT",0xf7fffff0, 0x77800310, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
219
        { "SEXIT",0xf7ffffe0, 0x77800300, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
220
        { "SEXIT",0xf7ffff00, 0x77800100, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED },
221
        { "SDUMP",0xf7ffffff, 0x778002ff, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
222
        { "SDUMP",0xf7fffff0, 0x77800200, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
223
        { "SDUMP",0xf7fffff0, 0x77800210, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
224
        { "SOUT", 0xf7fffff0, 0x77800230, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
225
        { "SOUT", 0xf7ffffe0, 0x77800220, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
226
        { "SOUT", 0xf7ffff00, 0x77800400, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED },
227
        { "SDUMP",0xf7ffff00, 0x77800200, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED },
228
        { "SIM",  0xf7c00000, 0x77800000, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED },
229
        { "NOOP", 0xf7ffffff, 0x77c00000, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
230
        { "NEXIT",0xf7ffffff, 0x77c00100, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
231
        { "NEXIT",0xf7ffff00, 0x77c00100, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED },
232
        { "NEXIT",0xf7fffff0, 0x77c00310, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
233
        { "NEXIT",0xf7ffffe0, 0x77c00300, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
234
        { "NDUMP",0xf7ffffff, 0x77c002ff, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
235
        { "NDUMP",0xf7fffff0, 0x77c00200, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
236
        { "NDUMP",0xf7fffff0, 0x77c00210, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
237
 
238
        { "NOUT", 0xf7fffff0, 0x77c00230, ZIP_OPUNUSED, ZIP_URGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
239
        { "NOUT", 0xf7ffffe0, 0x77c00220, ZIP_OPUNUSED, ZIP_REGFIELD(0), ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
240
        { "NOUT", 0xf7ffff00, 0x77c00400, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD( 8,0), ZIP_OPUNUSED },
241
        { "NDUMP",0xf7ffff00, 0x77c00200, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_OPUNUSED,       ZIP_OPUNUSED },
242
        { "NSIM", 0xf7c00000, 0x77c00000, ZIP_OPUNUSED, ZIP_OPUNUSED,    ZIP_OPUNUSED, ZIP_IMMFIELD(22,0), ZIP_OPUNUSED },
243
        //
244
        //
245
        // 0rrr.r11f.ffcc.cxrr.rrii.iiii.iiii.iiii
246
        { "FPADD",0x87c43fff, 0x06840000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
247
        { "FPSUB",0x87c43fff, 0x06c40000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
248
        { "FPMPY",0x87c43fff, 0x07040000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
249
        { "FPDIV",0x87c43fff, 0x07440000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(14), ZIP_OPUNUSED, ZIP_BITFIELD(3,19) },
250
        { "FPI2F",0x87c40000, 0x07800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(18,0), ZIP_BITFIELD(3,19) },
251
        { "FPI2F",0x87c40000, 0x07840000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
252
        { "FPF2I",0x87c40000, 0x07c40000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(14), ZIP_IMMFIELD(14,0), ZIP_BITFIELD(3,19) },
253
        //
254
        //
255
        //
256
        //
257
        //
258
        //      16-bit instructions, high side
259
        //
260
        // 
261
        //      1.1111.00010.xcc.0iiii.xxxx.xxxxx.xxxxx
262
        //      1111.1000.10xc.c0ii.iixx.xxxx.xxxx.xxxx
263
        // Mask, val, result, Ra, Rb, I, condition (no conditions for OP_UNDER_TEST)
264
        // BRA: 1.1111.011.0.sssssss
265
        { "BRA", 0xff800000, 0xf9000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
266
        // CLR: 1.rrrr.110.00000000
267
        { "CLR", 0x87ff0000, 0x86000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
268
        // RTN: 1.1111.111.0.0000.000, MOV R0,Pc
269
        { "RTN", 0xffff0000, 0xff800000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
270
        // JMP: 1.1111.111.0.rrrrsss
271
        { "JMP", 0xff800000, 0xff000000, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
272
        // LJSR: 1.000_0.011_.0.111_1.001 ?.1111.110.1.1111.000
273
        // { "LJSR",0xffffffff, 0x83797ef8, ZIP_REGFIELD(27),ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
274
        //
275
        // 1.rrrr.000.0.sssssss
276
        // 1rrr.r000.0sss.ssss
277
        { "SUB", 0x87800000, 0x80000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
278
        // 1.rrrr.000.1.rrrrsss
279
        { "SUB", 0x87800000, 0x80800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
280
        //
281
        // 1.rrrr.001.0.sssssss
282
        // 1.rrrr.001.1.rrrrsss
283
        { "AND", 0x87800000, 0x81000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
284
        { "AND", 0x87800000, 0x81800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
285
        //
286
        // 1.rrrr.010.0.sssssss
287
        // 1.rrrr.010.1.rrrrsss
288
        { "ADD", 0x87800000, 0x82000000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
289
        { "ADD", 0x87800000, 0x82800000, ZIP_REGFIELD(27), ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
290
        //
291
        // 1.rrrr.011.a.rrrrsss
292
        { "CMP", 0x87800000, 0x83000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
293
        { "CMP", 0x87800000, 0x83800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
294
        //
295
        // 1.rrrr.100.0.sssssss
296
        // 1.rrrr.100.1.rrrrsss
297
        { "LW", 0x87800000, 0x84000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_SP, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
298
        { "LW", 0x87800000, 0x84800000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
299
        // 1.rrrr.101.ssssssss
300
        { "SW", 0x87000000, 0x85000000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_SP, ZIP_IMMFIELD(7,16), ZIP_OPUNUSED },
301
        // 1.rrrr.110.0.sssssss
302
        { "SW", 0x87800000, 0x85800000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
303
        // 1.rrrr.110.iiiiiiii
304
        { "LDI", 0x87000000, 0x86000000, ZIP_REGFIELD(27), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(8,16), ZIP_OPUNUSED },
305
        // 1.rrrr.111.1.sssssss
306
        { "MOV", 0x87800000, 0x87800000, ZIP_OPUNUSED, ZIP_REGFIELD(27), ZIP_REGFIELD(19), ZIP_IMMFIELD(3,16), ZIP_OPUNUSED },
307
        // 1.rrrr.111.1.rrrrsss
308
        // Illegal instruction !!
309
        { "ILLV", 0x80000000, 0x80000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(32,16), ZIP_OPUNUSED },
310
        // Global illegal instruction
311
        { "ILL", 0x00000000, 0x00000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(32,0), ZIP_OPUNUSED }
312
};
313
 
314
static const ZOPCODE    zip_opbottomlist_raw[] = {
315
        //
316
        //
317
        //
318
        //      16-bit instructions, low side ... treat these as special
319
        //
320
        //
321
        // Mask, val, result, Ra, Rb, I, condition (no conditions for OP_UNDER_TEST)
322
        // BRA: 1.xxx_xxxx_xxxx_xxxx_?.111_1.011.0.sssssss
323
        { "BRA", 0x80007f80, 0x80007900, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
324
        // CLR: 1.xxx_xxxx_xxxx_xxxx_?.rrr_r.101.0000_0000
325
        { "CLR", 0x800007ff, 0x80000600, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
326
        // RTN: 1.1111.111.0.0000.000, MOV R0,Pc
327
        { "RTN", 0x80007fff, 0x80007f80, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED },
328
        // JMP: 1.1111.111.0.rrrrsss
329
        { "JMP", 0x80007f80, 0x80007f00, ZIP_REGFIELD(11),ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
330
        // LJMP: 1.xxx_xxxx_xxxx_xxxx_?.111_1.100._1.111_1.000
331
        { "LJMP", 0x80007fff, 0x80007cf8, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
332
        //
333
        // 1.rrrr.000.0.sssssss
334
        { "SUB", 0x80000780, 0x80000000, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
335
        // 1.rrrr.000.1.rrrrsss
336
        { "SUB", 0x80000780, 0x80000080, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
337
        //
338
        // 1.rrrr.001.0.sssssss
339
        // 1.rrrr.001.1.rrrrsss
340
        { "AND", 0x80000780, 0x80000100, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
341
        { "AND", 0x80000780, 0x80000180, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
342
        //
343
        // 1.rrrr.010.0.sssssss
344
        // 1.rrrr.010.1.rrrrsss
345
        { "ADD", 0x80000780, 0x80000200, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
346
        { "ADD", 0x80000780, 0x80000280, ZIP_REGFIELD(11), ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
347
        //
348
        // 1.rrrr.011.a.rrrrsss
349
        { "CMP", 0x80000780, 0x80000300, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
350
        { "CMP", 0x80000780, 0x80000380, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
351
        //
352
        // 1.rrrr.100.0.sssssss
353
        // 1.rrrr.100.1.rrrrsss
354
        { "LW", 0x80000780, 0x80000400, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_SP, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
355
        { "LW", 0x80000780, 0x80000480, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
356
        // 1.rrrr.101.ssssssss
357
        { "SW", 0x80000780, 0x80000500, ZIP_OPUNUSED, ZIP_REGFIELD(11), ZIP_SP, ZIP_IMMFIELD(7,0), ZIP_OPUNUSED },
358
        { "SW", 0x80000780, 0x80000580, ZIP_OPUNUSED, ZIP_REGFIELD(11), ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
359
        // 1.rrr_r.110.ssssssss
360
        { "LDI", 0x80000700, 0x80000600, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(8,0), ZIP_OPUNUSED },
361
        // 1.rrr_r.111_.x.rrr_rsss
362
        { "MOV", 0x80000780, 0x80000780, ZIP_REGFIELD(11), ZIP_OPUNUSED, ZIP_REGFIELD(3), ZIP_IMMFIELD(3,0), ZIP_OPUNUSED },
363
        //
364
        //
365
        // Illegal instruction !!
366
        { "ILLV",       0x80000000, 0x80000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(15,0), ZIP_OPUNUSED },
367
        { "ILL",        0x00000000, 0x00000000, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_OPUNUSED, ZIP_IMMFIELD(15,0), ZIP_OPUNUSED }
368
};
369
 
370
const ZOPCODE   *zip_oplist = zip_oplist_raw,
371
                *zip_opbottomlist = zip_opbottomlist_raw;
372
 
373
const int       nzip_oplist = (sizeof(zip_oplist_raw)/sizeof(ZOPCODE));
374
const int       nzip_opbottom = (sizeof(zip_opbottomlist_raw)/sizeof(ZOPCODE));
375
 
376
 
377
static inline   int
378
TWOWORD_LOAD(uint32_t one, uint32_t two) {
379
        // BREV followed by LODILO
380
        if (((one&0x87c40000)==0x02000000)&&((two&0x87c40000)==0x02400000)
381
                // Must be to the same register too, and on the same condition
382
                &&(((one^two)&0xf8380000)==0))
383
                return 1;
384
        return 0;
385
}
386
 
387
static  inline  int
388
OFFSET_PC_MOV(uint32_t ins) {
389
        // 0.xxxx.01101.ccc.0.1111.0.iiiiiiiiiiiii
390
        // 0xxx.x011.01cc.c011.110i.iiii.iiii.iiii
391
        //
392
        return ((ins & 0x87c7e000)==0x0343c000);
393
}
394
 
395
static  inline  int
396
TWOWORD_LJMP(uint32_t iword) {
397
        // LJMP a long jump instruction, for which the address of the target
398
        // is found in the next word
399
        if (iword==0x7c87c000)
400
                return 1;
401
        // Now, the CIS form ... an
402
        // Unconditional LJMP in the second half word
403
        if ((iword&0x80007fff)==0x80007cf8)
404
                return 1;
405
        return 0;
406
}
407
 
408
 
409
static  inline  int
410
TWOWORD_JSR(uint32_t iword, uint32_t nxtword) {
411
        // First word moves the return address to R0
412
        if (iword != 0x0343c001)
413
                return 0;
414
        // Second word is a BRA statement to ... anywhere
415
        // 0.1111.00010.ccc.0.iiiiiiiiiiiiiiiiii
416
        // 0111.1000.10cc.c0ii.iiii.iiii.iiii.iiii
417
        if ((nxtword&0xffc40000) == 0x78800000)
418
                return 1;
419
        return 0;
420
}
421
 
422
static  inline  int
423
THREEWORD_LJSR(uint32_t iword, uint32_t nxtword) {
424
        // First word moves the return address to R0
425
        if (iword!=0x0343c002)
426
                return 0;
427
        // Second word is an LJMP statement
428
        if (nxtword==0x7c87c000)
429
                return 1;
430
        return 0;
431
}
432
 
433
static  inline  int
434
CIS_JSR(uint32_t iword __attribute__((unused)) ) {
435
        // MOV 1(PC) | LOD (PC),PC
436
        //
437
        // 1.0000.111.1.1111.001
438
        //                      1.1111.100.1.1111.000
439
        if (iword == 0x87f9fcf8)
440
                return 1;
441
        // There is no code for this without CIS_OP_UNDER_TEST
442
        return 0;
443
}
444
 
445
static inline   int
446
POSSIBLE_TWOWORD_BEGINNING(uint32_t iword) {
447
        // Unconditional LJMP
448
        if (TWOWORD_LJMP(iword))
449
                return 1;
450
        // MOV 1(PC),PC
451
        if (iword == 0x0343c001)
452
                return 1;
453
        // MOV 2(PC),PC
454
        if (iword == 0x0343c002)
455
                return 1;
456
        if (CIS_JSR(iword))
457
                return 1;
458
        // The conditional LJMP is three words, which we don't handle ...
459
        // Any BREV command could be the beginning of a twoword instruction
460
        //
461
        // Of course, the point here is to determine whether we should (or need
462
        // to) read a second word from our read-memory function.  Reading a 
463
        // second word, given that the first is a BREV, isn't a problem since a
464
        // program can't end on/with a BREV instruction.
465
        //
466
        // BREV #,Rx
467
        if ((iword&0x87c40000)==0x02000000)
468
                return 1;
469
        return 0;
470
}
471
 
472
 
473
static uint32_t
474
zip_bitreverse(uint32_t v) {
475
        uint32_t r=0, b;
476
        for(b=0; b<32; b++, v>>=1)
477
                r = (r<<1)|(v&1);
478
        return r;
479
}
480
 
481
static inline   uint32_t
482
TWOWORD_VALUE(uint32_t one, uint32_t two) {
483
        return ((two&0x0ffff)|(zip_bitreverse(one&0x0ffff)));
484
}
485
 
486
static long
487
zip_sbits(const long val, const int bits) {
488
        long    r;
489
 
490
        r = val & ((1l<<bits)-1);
491
        if (r & (1l << (bits-1)))
492
                r |= (-1l << bits);
493
        return r;
494
}
495
static unsigned long
496
zip_ubits(const long val, const int bits) {
497
        unsigned long r = val & ((1l<<bits)-1);
498
        return r;
499
}
500
 
501
static  int
502
zip_getbits(const ZIPI ins, const int which)
503
{
504
        if (which & 0x40000000) {
505
                return zip_sbits(ins>>(which & 0x03f), (which>>8)&0x03f);
506
        } else { // if (which &0x03f)
507
                return zip_ubits(ins>>(which & 0x03f), (which>>8)&0x03f)
508
                        + ((which>>16)&0x0ff);
509
        }
510
}
511
 
512
static  void
513
zipi_to_halfstring(const uint32_t addr, const ZIPI ins, char *line, const ZOPCODE *listp) {
514
 
515
        if (OFFSET_PC_MOV(ins)) {
516
                int     cv = zip_getbits(ins, ZIP_BITFIELD(3,19));
517
                int     dv = zip_getbits(ins, ZIP_REGFIELD(27));
518
                int     iv = zip_sbits(ins, 13);
519
                uint32_t        ref;
520
 
521
                ref = (iv<<2) + addr + 4;
522
 
523
                sprintf(line, "%s%s", "MOV", zip_ccstr[cv]);
524
                sprintf(line, "%-11s", line);
525
                sprintf(line, "%s0x%08x", line, ref);
526
                sprintf(line, "%s,%s", line, zip_regstr[dv]);
527
 
528
                return;
529
        }
530
 
531
        int     i;
532
        for(i=0; i<nzip_oplist; i++) {
533
                if (((~zip_oplist[i].s_mask)&zip_oplist[i].s_val)!=0) {
534
                        printf("Instruction %d, %s, fails consistency check\n",
535
                                i, zip_oplist[i].s_opstr);
536
                        printf("%08x & %08x = %08x != %08x\n",
537
                                zip_oplist[i].s_mask,
538
                                zip_oplist[i].s_val,
539
                                (~zip_oplist[i].s_mask)&zip_oplist[i].s_val,
540
                                0);
541
                        assert(((~zip_oplist[i].s_mask)&zip_oplist[i].s_val)==0);
542
                }
543
        } line[0] = '\0';
544
        for(i=0; (listp[i].s_mask != 0); i++) {
545
                // printf("%2d: %6s %08x & %08x == %08x\n",
546
                        // i, zip_oplist[i].s_opstr, ins,
547
                        // zip_oplist[i].s_mask, zip_oplist[i].s_val);
548
                if ((ins & listp[i].s_mask) == listp[i].s_val) {
549
                        // Write the opcode onto our line
550
                        sprintf(line, "%s", listp[i].s_opstr);
551
                        if (listp[i].s_cf != ZIP_OPUNUSED) {
552
                                int bv = zip_getbits(ins, listp[i].s_cf);
553
                                strcat(line, zip_ccstr[bv]);
554
                        } sprintf(line, "%-11s", line); // Pad it to 11 chars
555
 
556
                        int     ra = -1, rb = -1, rr = -1, imv = 0;
557
 
558
                        if (listp[i].s_result != ZIP_OPUNUSED)
559
                                rr = zip_getbits(ins, listp[i].s_result);
560
                        if (listp[i].s_ra != ZIP_OPUNUSED)
561
                                ra = zip_getbits(ins, listp[i].s_ra);
562
                        if (listp[i].s_rb != ZIP_OPUNUSED)
563
                                rb = zip_getbits(ins, listp[i].s_rb);
564
                        if (listp[i].s_i != ZIP_OPUNUSED)
565
                                imv = zip_getbits(ins, listp[i].s_i);
566
 
567
                        if ((listp[i].s_rb != ZIP_OPUNUSED)&&(rb == 15))
568
                                imv <<= 2;
569
 
570
                        // Treat stores special
571
                        if ((strncasecmp("SW",listp[i].s_opstr, 2)==0)
572
                                ||(strncasecmp("SH",listp[i].s_opstr, 2)==0)
573
                                ||(strncasecmp("SB",listp[i].s_opstr, 2)==0)) {
574
                                strcat(line, zip_regstr[ra]);
575
                                strcat(line, ",");
576
 
577
                                if (listp[i].s_i != ZIP_OPUNUSED) {
578
                                        if (listp[i].s_rb == ZIP_OPUNUSED)
579
                                                sprintf(&line[strlen(line)],
580
                                                        "($%d)", imv);
581
                                        else if (imv != 0)
582
                                                sprintf(&line[strlen(line)],
583
                                                        "$%d", imv);
584
                                } if (listp[i].s_rb != ZIP_OPUNUSED) {
585
                                        sprintf(&line[strlen(line)],
586
                                                "(%s)", zip_regstr[rb]);
587
                                }
588
                        // Treat long jumps special
589
                        } else if (strncasecmp("LJMP",listp[i].s_opstr, 3)==0) {
590
                        // Treat relative jumps (branches) specially as well
591
                        } else if ((toupper(listp[i].s_opstr[0]=='B'))
592
                                &&(strcasecmp(listp[i].s_opstr,"BUSY")!=0)
593
                                &&(strcasecmp(listp[i].s_opstr,"BREV")!=0)
594
                                &&(strcasecmp(listp[i].s_opstr,"BRK")!=0)
595
                                &&(addr != 0)) {
596
                                // Branch instruction: starts with B and isn't
597
                                // BREV (bit reverse), BRK (break), or 
598
                                // BUSY
599
                                uint32_t target = addr;
600
 
601
                                target += zip_getbits(ins, listp[i].s_i)+4;
602
                                sprintf(&line[strlen(line)], "@0x%08x", target);
603
                        } else {
604
                                int memop = 0;
605
                                if (('L'==toupper(listp[i].s_opstr[0]))
606
                                        &&(('W'==toupper(listp[i].s_opstr[1]))
607
                                         ||('H'==toupper(listp[i].s_opstr[1]))
608
                                         ||('B'==toupper(listp[i].s_opstr[1])))
609
                                        &&(!listp[i].s_opstr[2]))
610
                                        memop = 1;
611
 
612
                                if (listp[i].s_i != ZIP_OPUNUSED) {
613
                                        if((memop)&&(listp[i].s_rb == ZIP_OPUNUSED))
614
                                                sprintf(&line[strlen(line)],
615
                                                        "($%d)", imv);
616
                                        else if((memop)&&(imv != 0))
617
                                                sprintf(&line[strlen(line)],
618
                                                        "%d", imv);
619
                                        else if((!memop)&&((imv != 0)||(listp[i].s_rb == ZIP_OPUNUSED)))
620
                                                sprintf(&line[strlen(line)],
621
                                                        "$%d%s", imv,
622
                                                        (listp[i].s_rb!=ZIP_OPUNUSED)?"+":"");
623
                                } if (listp[i].s_rb != ZIP_OPUNUSED) {
624
                                        if (memop)
625
                                                sprintf(&line[strlen(line)],
626
                                                        "(%s)", zip_regstr[rb]);
627
                                        else
628
                                                strcat(line, zip_regstr[rb]);
629
                                } if(((listp[i].s_i != ZIP_OPUNUSED)||(listp[i].s_rb != ZIP_OPUNUSED))
630
                                        &&((listp[i].s_ra != ZIP_OPUNUSED)||(listp[i].s_result != ZIP_OPUNUSED)))
631
                                        strcat(line, ",");
632
 
633
                                if (listp[i].s_ra != ZIP_OPUNUSED) {
634
                                        strcat(line, zip_regstr[ra]);
635
                                } else if (listp[i].s_result != ZIP_OPUNUSED) {
636
                                        strcat(line, zip_regstr[rr]);
637
                                }
638
                        }
639
                        break;
640
                }
641
        } if (line[0] == '\0') {
642
                sprintf(line, "ILL %08x", ins);
643
        }
644
}
645
 
646
void
647
zipi_to_double_string(const uint32_t addr, const ZIPI ins, char *la, char *lb) {
648
        zipi_to_halfstring(addr, ins, la, zip_oplist);
649
        if (lb) {
650
                if (ins & 0x80000000) {
651
                        zipi_to_halfstring(addr, ins, lb, zip_opbottomlist);
652
                } else lb[0] = '\0';
653
        }
654
}
655
 
656
unsigned int    zop_early_branch(const unsigned int pc, const ZIPI insn) {
657
        if ((insn & 0xf8000000) != 0x78000000)
658
                return pc+4;
659
        if ((insn & 0xffc60000) == 0x78800000)  // BRA high bit clear
660
                return (pc + 4 + ((insn & 0x3ffff)<<2));
661
        if ((insn & 0xffc60000) == 0x78820000)  // BRA high bit set (negative)
662
                return (pc + 4 + ((0x40000 - (insn & 0x3ffff))<<2));
663
        return pc+4;
664
}
665
 
666
 

powered by: WebSVN 2.1.0

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