1 /* pyramid.opcode.h -- gdb initial attempt.
3 Copyright 2001, 2010 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street - Fifth Floor,
18 Boston, MA 02110-1301, USA. */
20 /* pyramid opcode table: wot to do with this
26 char * args
; /* how to compile said opcode */
27 unsigned long mask
; /* Bit vector: which operand modes are valid
29 unsigned char code
; /* op-code (always 6(?) bits */
32 typedef struct pyr_insn_format
35 unsigned int operator :8;
36 unsigned int index_scale
:2;
37 unsigned int index_reg
:6;
38 unsigned int operand_1
:6;
39 unsigned int operand_2
:6;
43 /* We store four bytes of opcode for all opcodes.
44 Pyramid is sufficiently RISCy that:
45 - insns are always an integral number of words;
46 - the length of any insn can be told from the first word of
47 the insn. (ie, if there are zero, one, or two words of
48 immediate operand/offset).
51 The args component is a string containing two characters for each
52 operand of the instruction. The first specifies the kind of operand;
53 the second, the place it is stored. */
56 mask assembler syntax description
57 0x0001: movw Rn,Rn register to register
58 0x0002: movw K,Rn quick immediate to register
59 0x0004: movw I,Rn long immediate to register
60 0x0008: movw (Rn),Rn register indirect to register
61 movw (Rn)[x],Rn register indirect to register
62 0x0010: movw I(Rn),Rn offset register indirect to register
63 movw I(Rn)[x],Rn offset register indirect, indexed, to register
65 0x0020: movw Rn,(Rn) register to register indirect
66 0x0040: movw K,(Rn) quick immediate to register indirect
67 0x0080: movw I,(Rn) long immediate to register indirect
68 0x0100: movw (Rn),(Rn) register indirect to-register indirect
69 0x0100: movw (Rn),(Rn) register indirect to-register indirect
70 0x0200: movw I(Rn),(Rn) register indirect+offset to register indirect
71 0x0200: movw I(Rn),(Rn) register indirect+offset to register indirect
73 0x0400: movw Rn,I(Rn) register to register indirect+offset
74 0x0800: movw K,I(Rn) quick immediate to register indirect+offset
75 0x1000: movw I,I(Rn) long immediate to register indirect+offset
76 0x1000: movw (Rn),I(Rn) register indirect to-register indirect+offset
77 0x1000: movw I(Rn),I(Rn) register indirect+offset to register indirect
79 0x0000: (irregular) ???
82 Each insn has a four-bit field encoding the type(s) of its operands.
85 /* Some common combinations
88 /* the first 5,(0x1|0x2|0x4|0x8|0x10) ie (1|2|4|8|16), ie ( 32 -1)*/
89 #define GEN_TO_REG (31)
91 #define UNKNOWN ((unsigned long)-1)
92 #define ANY (GEN_TO_REG | (GEN_TO_REG << 5) | (GEN_TO_REG << 15))
94 #define CONVERT (1|8|0x10|0x20|0x200)
98 #define NOTK_TO_REG (GEN_TO_REG & ~K_TO_REG)
99 #define NOTI_TO_REG (GEN_TO_REG & ~I_TO_REG)
101 /* The assembler requires that this array be sorted as follows:
102 all instances of the same mnemonic must be consecutive.
103 All instances of the same mnemonic with the same number of operands
107 struct pyr_opcode
/* pyr opcode text */
109 char * name
; /* opcode name: lowercase string [key] */
110 struct pyr_datum datum
; /* rest of opcode table [datum] */
114 #define pyr_nargs nargs
115 #define pyr_mask mask
116 #define pyr_name name
118 struct pyr_opcode pyr_opcodes
[] =
120 {"movb", { 2, "", UNKNOWN
, 0x11}, },
121 {"movh", { 2, "", UNKNOWN
, 0x12} },
122 {"movw", { 2, "", ANY
, 0x10} },
123 {"movl", { 2, "", ANY
, 0x13} },
124 {"mnegw", { 2, "", (0x1|0x8|0x10), 0x14} },
125 {"mnegf", { 2, "", 0x1, 0x15} },
126 {"mnegd", { 2, "", 0x1, 0x16} },
127 {"mcomw", { 2, "", (0x1|0x8|0x10), 0x17} },
128 {"mabsw", { 2, "", (0x1|0x8|0x10), 0x18} },
129 {"mabsf", { 2, "", 0x1, 0x19} },
130 {"mabsd", { 2, "", 0x1, 0x1a} },
131 {"mtstw", { 2, "", (0x1|0x8|0x10), 0x1c} },
132 {"mtstf", { 2, "", 0x1, 0x1d} },
133 {"mtstd", { 2, "", 0x1, 0x1e} },
134 {"mova", { 2, "", 0x8|0x10, 0x1f} },
135 {"movzbw", { 2, "", (0x1|0x8|0x10), 0x20} },
136 {"movzhw", { 2, "", (0x1|0x8|0x10), 0x21} },
137 /* 2 insns out of order here */
138 {"movbl", { 2, "", 1, 0x4f} },
139 {"filbl", { 2, "", 1, 0x4e} },
141 {"cvtbw", { 2, "", CONVERT
, 0x22} },
142 {"cvthw", { 2, "", CONVERT
, 0x23} },
143 {"cvtwb", { 2, "", CONVERT
, 0x24} },
144 {"cvtwh", { 2, "", CONVERT
, 0x25} },
145 {"cvtwf", { 2, "", CONVERT
, 0x26} },
146 {"cvtwd", { 2, "", CONVERT
, 0x27} },
147 {"cvtfw", { 2, "", CONVERT
, 0x28} },
148 {"cvtfd", { 2, "", CONVERT
, 0x29} },
149 {"cvtdw", { 2, "", CONVERT
, 0x2a} },
150 {"cvtdf", { 2, "", CONVERT
, 0x2b} },
152 {"addw", { 2, "", GEN_TO_REG
, 0x40} },
153 {"addwc", { 2, "", GEN_TO_REG
, 0x41} },
154 {"subw", { 2, "", GEN_TO_REG
, 0x42} },
155 {"subwb", { 2, "", GEN_TO_REG
, 0x43} },
156 {"rsubw", { 2, "", GEN_TO_REG
, 0x44} },
157 {"mulw", { 2, "", GEN_TO_REG
, 0x45} },
158 {"emul", { 2, "", GEN_TO_REG
, 0x47} },
159 {"umulw", { 2, "", GEN_TO_REG
, 0x46} },
160 {"divw", { 2, "", GEN_TO_REG
, 0x48} },
161 {"ediv", { 2, "", GEN_TO_REG
, 0x4a} },
162 {"rdivw", { 2, "", GEN_TO_REG
, 0x4b} },
163 {"udivw", { 2, "", GEN_TO_REG
, 0x49} },
164 {"modw", { 2, "", GEN_TO_REG
, 0x4c} },
165 {"umodw", { 2, "", GEN_TO_REG
, 0x4d} },
168 {"addf", { 2, "", 1, 0x50} },
169 {"addd", { 2, "", 1, 0x51} },
170 {"subf", { 2, "", 1, 0x52} },
171 {"subd", { 2, "", 1, 0x53} },
172 {"mulf", { 2, "", 1, 0x56} },
173 {"muld", { 2, "", 1, 0x57} },
174 {"divf", { 2, "", 1, 0x58} },
175 {"divd", { 2, "", 1, 0x59} },
178 {"cmpb", { 2, "", UNKNOWN
, 0x61} },
179 {"cmph", { 2, "", UNKNOWN
, 0x62} },
180 {"cmpw", { 2, "", UNKNOWN
, 0x60} },
181 {"ucmpb", { 2, "", UNKNOWN
, 0x66} },
182 /* WHY no "ucmph"??? */
183 {"ucmpw", { 2, "", UNKNOWN
, 0x65} },
184 {"xchw", { 2, "", UNKNOWN
, 0x0f} },
187 {"andw", { 2, "", GEN_TO_REG
, 0x30} },
188 {"orw", { 2, "", GEN_TO_REG
, 0x31} },
189 {"xorw", { 2, "", GEN_TO_REG
, 0x32} },
190 {"bicw", { 2, "", GEN_TO_REG
, 0x33} },
191 {"lshlw", { 2, "", GEN_TO_REG
, 0x38} },
192 {"ashlw", { 2, "", GEN_TO_REG
, 0x3a} },
193 {"ashll", { 2, "", GEN_TO_REG
, 0x3c} },
194 {"ashrw", { 2, "", GEN_TO_REG
, 0x3b} },
195 {"ashrl", { 2, "", GEN_TO_REG
, 0x3d} },
196 {"rotlw", { 2, "", GEN_TO_REG
, 0x3e} },
197 {"rotrw", { 2, "", GEN_TO_REG
, 0x3f} },
199 /* push and pop insns are "going away next release". */
200 {"pushw", { 2, "", GEN_TO_REG
, 0x0c} },
201 {"popw", { 2, "", (0x1|0x8|0x10), 0x0d} },
202 {"pusha", { 2, "", (0x8|0x10), 0x0e} },
204 {"bitsw", { 2, "", UNKNOWN
, 0x35} },
205 {"bitcw", { 2, "", UNKNOWN
, 0x36} },
206 /* some kind of ibra/dbra insns??*/
207 {"icmpw", { 2, "", UNKNOWN
, 0x67} },
208 {"dcmpw", { 2, "", (1|4|0x20|0x80|0x400|0x1000), 0x69} },/*FIXME*/
209 {"acmpw", { 2, "", 1, 0x6b} },
211 /* Call is written as a 1-op insn, but is always (dis)assembled as a 2-op
212 insn with a 2nd op of tr14. The assembler will have to grok this. */
213 {"call", { 2, "", GEN_TO_REG
, 0x04} },
214 {"call", { 1, "", GEN_TO_REG
, 0x04} },
216 {"callk", { 1, "", UNKNOWN
, 0x06} },/* system call?*/
217 /* Ret is usually written as a 0-op insn, but gets disassembled as a
218 1-op insn. The operand is always tr15. */
219 {"ret", { 0, "", UNKNOWN
, 0x09} },
220 {"ret", { 1, "", UNKNOWN
, 0x09} },
221 {"adsf", { 2, "", (1|2|4), 0x08} },
222 {"retd", { 2, "", UNKNOWN
, 0x0a} },
223 {"btc", { 2, "", UNKNOWN
, 0x01} },
224 {"bfc", { 2, "", UNKNOWN
, 0x02} },
225 /* Careful: halt is 0x00000000. Jump must have some other (mode?)bit set?? */
226 {"jump", { 1, "", UNKNOWN
, 0x00} },
227 {"btp", { 2, "", UNKNOWN
, 0xf00} },
228 /* read control-stack pointer is another 1-or-2 operand insn. */
229 {"rcsp", { 2, "", UNKNOWN
, 0x01f} },
230 {"rcsp", { 1, "", UNKNOWN
, 0x01f} }
233 /* end: pyramid.opcode.h */
234 /* One day I will have to take the time to find out what operands
235 are valid for these insns, and guess at what they mean.
237 I can't imagine what the "I???" insns (iglob, etc) do.
239 the arithmetic-sounding insns ending in "p" sound awfully like BCD
241 dshlp -> Decimal SHift Left Packed
242 dshrp -> Decimal SHift Right Packed
243 and cvtlp would be convert long to packed.
244 I have no idea how the operands are interpreted; but having them be
245 a long register with (address, length) of an in-memory packed BCD operand
246 would not be surprising.
247 They are unlikely to be a packed bcd string: 64 bits of long give
248 is only 15 digits+sign, which isn't enough for COBOL.
251 {"wcsp", { 2, "", UNKNOWN
, 0x00} }, /*write csp?*/
252 /* The OSx Operating System Porting Guide claims SSL does things
253 with tr12 (a register reserved to it) to do with static block-structure
254 references. SSL=Set Static Link? It's "Going away next release". */
255 {"ssl", { 2, "", UNKNOWN
, 0x00} },
256 {"ccmps", { 2, "", UNKNOWN
, 0x00} },
257 {"lcd", { 2, "", UNKNOWN
, 0x00} },
258 {"uemul", { 2, "", UNKNOWN
, 0x00} }, /*unsigned emul*/
259 {"srf", { 2, "", UNKNOWN
, 0x00} }, /*Gidget time???*/
260 {"mnegp", { 2, "", UNKNOWN
, 0x00} }, /move
-neg phys
?*/
261 {"ldp", { 2, "", UNKNOWN
, 0x00} }, /*load phys?*/
262 {"ldti", { 2, "", UNKNOWN
, 0x00} },
263 {"ldb", { 2, "", UNKNOWN
, 0x00} },
264 {"stp", { 2, "", UNKNOWN
, 0x00} },
265 {"stti", { 2, "", UNKNOWN
, 0x00} },
266 {"stb", { 2, "", UNKNOWN
, 0x00} },
267 {"stu", { 2, "", UNKNOWN
, 0x00} },
268 {"addp", { 2, "", UNKNOWN
, 0x00} },
269 {"subp", { 2, "", UNKNOWN
, 0x00} },
270 {"mulp", { 2, "", UNKNOWN
, 0x00} },
271 {"divp", { 2, "", UNKNOWN
, 0x00} },
272 {"dshlp", { 2, "", UNKNOWN
, 0x00} }, /* dec shl packed? */
273 {"dshrp", { 2, "", UNKNOWN
, 0x00} }, /* dec shr packed? */
274 {"movs", { 2, "", UNKNOWN
, 0x00} }, /*move (string?)?*/
275 {"cmpp", { 2, "", UNKNOWN
, 0x00} }, /* cmp phys?*/
276 {"cmps", { 2, "", UNKNOWN
, 0x00} }, /* cmp (string?)?*/
277 {"cvtlp", { 2, "", UNKNOWN
, 0x00} }, /* cvt long to p??*/
278 {"cvtpl", { 2, "", UNKNOWN
, 0x00} }, /* cvt p to l??*/
279 {"dintr", { 2, "", UNKNOWN
, 0x00} }, /* ?? intr ?*/
280 {"rphysw", { 2, "", UNKNOWN
, 0x00} }, /* read phys word?*/
281 {"wphysw", { 2, "", UNKNOWN
, 0x00} }, /* write phys word?*/
282 {"cmovs", { 2, "", UNKNOWN
, 0x00} },
283 {"rsubw", { 2, "", UNKNOWN
, 0x00} },
284 {"bicpsw", { 2, "", UNKNOWN
, 0x00} }, /* clr bit in psw? */
285 {"bispsw", { 2, "", UNKNOWN
, 0x00} }, /* set bit in psw? */
286 {"eio", { 2, "", UNKNOWN
, 0x00} }, /* ?? ?io ? */
287 {"callp", { 2, "", UNKNOWN
, 0x00} }, /* call phys?*/
288 {"callr", { 2, "", UNKNOWN
, 0x00} },
289 {"lpcxt", { 2, "", UNKNOWN
, 0x00} }, /*load proc context*/
290 {"rei", { 2, "", UNKNOWN
, 0x00} }, /*ret from intrpt*/
291 {"rport", { 2, "", UNKNOWN
, 0x00} }, /*read-port?*/
292 {"rtod", { 2, "", UNKNOWN
, 0x00} }, /*read-time-of-day?*/
293 {"ssi", { 2, "", UNKNOWN
, 0x00} },
294 {"vtpa", { 2, "", UNKNOWN
, 0x00} }, /*virt-to-phys-addr?*/
295 {"wicl", { 2, "", UNKNOWN
, 0x00} }, /* write icl ? */
296 {"wport", { 2, "", UNKNOWN
, 0x00} }, /*write-port?*/
297 {"wtod", { 2, "", UNKNOWN
, 0x00} }, /*write-time-of-day?*/
298 {"flic", { 2, "", UNKNOWN
, 0x00} },
299 {"iglob", { 2, "", UNKNOWN
, 0x00} }, /* I global? */
300 {"iphys", { 2, "", UNKNOWN
, 0x00} }, /* I physical? */
301 {"ipid", { 2, "", UNKNOWN
, 0x00} }, /* I pid? */
302 {"ivect", { 2, "", UNKNOWN
, 0x00} }, /* I vector? */
303 {"lamst", { 2, "", UNKNOWN
, 0x00} },
304 {"tio", { 2, "", UNKNOWN
, 0x00} },