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