1 /* pyramid.opcode.h -- gdb initial attempt. 2 3 Copyright (C) 2001-2016 Free Software Foundation, Inc. 4 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) 8 any later version. 9 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. 14 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. */ 19 20 /* pyramid opcode table: wot to do with this 21 particular opcode */ 22 23 struct pyr_datum 24 { 25 char nargs; 26 char * args; /* how to compile said opcode */ 27 unsigned long mask; /* Bit vector: which operand modes are valid 28 for this opcode */ 29 unsigned char code; /* op-code (always 6(?) bits */ 30 }; 31 32 typedef struct pyr_insn_format 33 { 34 unsigned int mode :4; 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; 40 } pyr_insn_format; 41 42 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). 49 50 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. */ 54 55 /* Kinds of operands: 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 64 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 72 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 78 +offset 79 0x0000: (irregular) ??? 80 81 82 Each insn has a four-bit field encoding the type(s) of its operands. 83 */ 84 85 /* Some common combinations 86 */ 87 88 /* the first 5,(0x1|0x2|0x4|0x8|0x10) ie (1|2|4|8|16), ie ( 32 -1)*/ 89 #define GEN_TO_REG (31) 90 91 #define UNKNOWN ((unsigned long)-1) 92 #define ANY (GEN_TO_REG | (GEN_TO_REG << 5) | (GEN_TO_REG << 15)) 93 94 #define CONVERT (1|8|0x10|0x20|0x200) 95 96 #define K_TO_REG (2) 97 #define I_TO_REG (4) 98 #define NOTK_TO_REG (GEN_TO_REG & ~K_TO_REG) 99 #define NOTI_TO_REG (GEN_TO_REG & ~I_TO_REG) 100 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 104 must be consecutive. 105 */ 106 107 struct pyr_opcode /* pyr opcode text */ 108 { 109 char * name; /* opcode name: lowercase string [key] */ 110 struct pyr_datum datum; /* rest of opcode table [datum] */ 111 }; 112 113 #define pyr_how args 114 #define pyr_nargs nargs 115 #define pyr_mask mask 116 #define pyr_name name 117 118 struct pyr_opcode pyr_opcodes[] = 119 { 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} }, 140 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} }, 151 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} }, 166 167 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} }, 176 177 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} }, 185 186 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} }, 198 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} }, 203 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} }, 210 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} }, 215 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} } 231 }; 232 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. 236 237 I can't imagine what the "I???" insns (iglob, etc) do. 238 239 the arithmetic-sounding insns ending in "p" sound awfully like BCD 240 arithmetic insns: 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. 249 */ 250 #if 0 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} }, 305 #endif 306