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