| 1 | /* mmix-opc.c -- MMIX opcode table | 
|---|
| 2 | Copyright (C) 2001 Free Software Foundation, Inc. | 
|---|
| 3 | Written by Hans-Peter Nilsson (hp@bitrange.com) | 
|---|
| 4 |  | 
|---|
| 5 | This file is part of GDB, GAS, and the GNU binutils. | 
|---|
| 6 |  | 
|---|
| 7 | GDB, GAS, and the GNU binutils are free software; you can redistribute | 
|---|
| 8 | them and/or modify them under the terms of the GNU General Public | 
|---|
| 9 | License as published by the Free Software Foundation; either version 2, | 
|---|
| 10 | or (at your option) any later version. | 
|---|
| 11 |  | 
|---|
| 12 | GDB, GAS, and the GNU binutils are distributed in the hope that they | 
|---|
| 13 | will be useful, but WITHOUT ANY WARRANTY; without even the implied | 
|---|
| 14 | warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See | 
|---|
| 15 | the GNU General Public License for more details. | 
|---|
| 16 |  | 
|---|
| 17 | You should have received a copy of the GNU General Public License | 
|---|
| 18 | along with this file; see the file COPYING.  If not, write to the Free | 
|---|
| 19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */ | 
|---|
| 20 |  | 
|---|
| 21 | #include <stdio.h> | 
|---|
| 22 | #include "opcode/mmix.h" | 
|---|
| 23 | #include "symcat.h" | 
|---|
| 24 |  | 
|---|
| 25 | /* Register-name-table for special registers.  */ | 
|---|
| 26 | const struct mmix_spec_reg mmix_spec_regs[] = | 
|---|
| 27 | { | 
|---|
| 28 | /* Keep rJ at top; it's the most frequently used one.  */ | 
|---|
| 29 | {"rJ", 4}, | 
|---|
| 30 | {"rA", 21}, | 
|---|
| 31 | {"rB", 0}, | 
|---|
| 32 | {"rC", 8}, | 
|---|
| 33 | {"rD", 1}, | 
|---|
| 34 | {"rE", 2}, | 
|---|
| 35 | {"rF", 22}, | 
|---|
| 36 | {"rG", 19}, | 
|---|
| 37 | {"rH", 3}, | 
|---|
| 38 | {"rI", 12}, | 
|---|
| 39 | {"rK", 15}, | 
|---|
| 40 | {"rL", 20}, | 
|---|
| 41 | {"rM", 5}, | 
|---|
| 42 | {"rN", 9}, | 
|---|
| 43 | {"rO", 10}, | 
|---|
| 44 | {"rP", 23}, | 
|---|
| 45 | {"rQ", 16}, | 
|---|
| 46 | {"rR", 6}, | 
|---|
| 47 | {"rS", 11}, | 
|---|
| 48 | {"rT", 13}, | 
|---|
| 49 | {"rU", 17}, | 
|---|
| 50 | {"rV", 18}, | 
|---|
| 51 | {"rW", 24}, | 
|---|
| 52 | {"rX", 25}, | 
|---|
| 53 | {"rY", 26}, | 
|---|
| 54 | {"rZ", 27}, | 
|---|
| 55 | {"rBB", 7}, | 
|---|
| 56 | {"rTT", 14}, | 
|---|
| 57 | {"rWW", 28}, | 
|---|
| 58 | {"rXX", 29}, | 
|---|
| 59 | {"rYY", 30}, | 
|---|
| 60 | {"rZZ", 31}, | 
|---|
| 61 | {NULL, 0} | 
|---|
| 62 | }; | 
|---|
| 63 |  | 
|---|
| 64 | /* Opcode-table.  In order to cut down on redundant contents, we use helper | 
|---|
| 65 | macros.  */ | 
|---|
| 66 |  | 
|---|
| 67 | /* All bits in the opcode-byte are significant.  Add "| ..." expressions | 
|---|
| 68 | to add zero-bits.  */ | 
|---|
| 69 | #undef O | 
|---|
| 70 | #define O(m) ((m) << 24), ((~(m) & 255) << 24) | 
|---|
| 71 |  | 
|---|
| 72 | /* Bits 7..1 of the opcode are significant.  */ | 
|---|
| 73 | #undef Z | 
|---|
| 74 | #define Z(m) ((m) << 24), ((~(m) & 254) << 24) | 
|---|
| 75 |  | 
|---|
| 76 | /* For easier overview of the table.  */ | 
|---|
| 77 | #define N mmix_type_normal | 
|---|
| 78 | #define B mmix_type_branch | 
|---|
| 79 | #define C mmix_type_condbranch | 
|---|
| 80 | #define MB mmix_type_memaccess_byte | 
|---|
| 81 | #define MW mmix_type_memaccess_wyde | 
|---|
| 82 | #define MT mmix_type_memaccess_tetra | 
|---|
| 83 | #define MO mmix_type_memaccess_octa | 
|---|
| 84 | #define M mmix_type_memaccess_block | 
|---|
| 85 | #define J mmix_type_jsr | 
|---|
| 86 | #define P mmix_type_pseudo | 
|---|
| 87 |  | 
|---|
| 88 | #define OP(y) XCONCAT2 (mmix_operands_,y) | 
|---|
| 89 |  | 
|---|
| 90 | /* Groups of instructions specified here must, if all are matching the | 
|---|
| 91 | same instruction, be consecutive, in order more-specific to | 
|---|
| 92 | less-specific match.  */ | 
|---|
| 93 |  | 
|---|
| 94 | const struct mmix_opcode mmix_opcodes[] = | 
|---|
| 95 | { | 
|---|
| 96 | {"trap",     O (0),          OP (xyz_opt),           J}, | 
|---|
| 97 | {"fcmp",     O (1),          OP (regs),              N}, | 
|---|
| 98 | {"flot",     Z (8),          OP (roundregs_z),       N}, | 
|---|
| 99 |  | 
|---|
| 100 | {"fun",      O (2),          OP (regs),              N}, | 
|---|
| 101 | {"feql",     O (3),          OP (regs),              N}, | 
|---|
| 102 | {"flotu",    Z (10),         OP (roundregs_z),       N}, | 
|---|
| 103 |  | 
|---|
| 104 | {"fadd",     O (4),          OP (regs),              N}, | 
|---|
| 105 | {"fix",      O (5),          OP (roundregs),         N}, | 
|---|
| 106 | {"sflot",    Z (12),         OP (roundregs_z),       N}, | 
|---|
| 107 |  | 
|---|
| 108 | {"fsub",     O (6),          OP (regs),              N}, | 
|---|
| 109 | {"fixu",     O (7),          OP (roundregs),         N}, | 
|---|
| 110 | {"sflotu",   Z (14),         OP (roundregs_z),       N}, | 
|---|
| 111 |  | 
|---|
| 112 | {"fmul",     O (16),         OP (regs),              N}, | 
|---|
| 113 | {"fcmpe",    O (17),         OP (regs),              N}, | 
|---|
| 114 | {"mul",      Z (24),         OP (regs_z),            N}, | 
|---|
| 115 |  | 
|---|
| 116 | {"fune",     O (18),         OP (regs),              N}, | 
|---|
| 117 | {"feqle",    O (19),         OP (regs),              N}, | 
|---|
| 118 | {"mulu",     Z (26),         OP (regs_z),            N}, | 
|---|
| 119 |  | 
|---|
| 120 | {"fdiv",     O (20),         OP (regs),              N}, | 
|---|
| 121 | {"fsqrt",    O (21),         OP (roundregs),         N}, | 
|---|
| 122 | {"div",      Z (28),         OP (regs_z),            N}, | 
|---|
| 123 |  | 
|---|
| 124 | {"frem",     O (22),         OP (regs),              N}, | 
|---|
| 125 | {"fint",     O (23),         OP (roundregs),         N}, | 
|---|
| 126 | {"divu",     Z (30),         OP (regs_z),            N}, | 
|---|
| 127 |  | 
|---|
| 128 | {"add",      Z (0x20),       OP (regs_z),            N}, | 
|---|
| 129 | {"2addu",    Z (0x28),       OP (regs_z),            N}, | 
|---|
| 130 |  | 
|---|
| 131 | {"addu",     Z (0x22),       OP (regs_z),            N}, | 
|---|
| 132 | /* Synonym for ADDU.  Put after ADDU, since we don't prefer it for | 
|---|
| 133 | disassembly.  It's supposed to be used for addresses, so we make it | 
|---|
| 134 | a memory block reference for purposes of assembly.  */ | 
|---|
| 135 | {"lda",      Z (0x22),       OP (regs_z_opt),        M}, | 
|---|
| 136 | {"4addu",    Z (0x2a),       OP (regs_z),            N}, | 
|---|
| 137 |  | 
|---|
| 138 | {"sub",      Z (0x24),       OP (regs_z),            N}, | 
|---|
| 139 | {"8addu",    Z (0x2c),       OP (regs_z),            N}, | 
|---|
| 140 |  | 
|---|
| 141 | {"subu",     Z (0x26),       OP (regs_z),            N}, | 
|---|
| 142 | {"16addu",   Z (0x2e),       OP (regs_z),            N}, | 
|---|
| 143 |  | 
|---|
| 144 | {"cmp",      Z (0x30),       OP (regs_z),            N}, | 
|---|
| 145 | {"sl",       Z (0x38),       OP (regs_z),            N}, | 
|---|
| 146 |  | 
|---|
| 147 | {"cmpu",     Z (0x32),       OP (regs_z),            N}, | 
|---|
| 148 | {"slu",      Z (0x3a),       OP (regs_z),            N}, | 
|---|
| 149 |  | 
|---|
| 150 | {"neg",      Z (0x34),       OP (neg),               N}, | 
|---|
| 151 | {"sr",       Z (0x3c),       OP (regs_z),            N}, | 
|---|
| 152 |  | 
|---|
| 153 | {"negu",     Z (0x36),       OP (neg),               N}, | 
|---|
| 154 | {"sru",      Z (0x3e),       OP (regs_z),            N}, | 
|---|
| 155 |  | 
|---|
| 156 | {"bn",       Z (0x40),       OP (regaddr),           C}, | 
|---|
| 157 | {"bnn",      Z (0x48),       OP (regaddr),           C}, | 
|---|
| 158 |  | 
|---|
| 159 | {"bz",       Z (0x42),       OP (regaddr),           C}, | 
|---|
| 160 | {"bnz",      Z (0x4a),       OP (regaddr),           C}, | 
|---|
| 161 |  | 
|---|
| 162 | {"bp",       Z (0x44),       OP (regaddr),           C}, | 
|---|
| 163 | {"bnp",      Z (0x4c),       OP (regaddr),           C}, | 
|---|
| 164 |  | 
|---|
| 165 | {"bod",      Z (0x46),       OP (regaddr),           C}, | 
|---|
| 166 | {"bev",      Z (0x4e),       OP (regaddr),           C}, | 
|---|
| 167 |  | 
|---|
| 168 | {"pbn",      Z (0x50),       OP (regaddr),           C}, | 
|---|
| 169 | {"pbnn",     Z (0x58),       OP (regaddr),           C}, | 
|---|
| 170 |  | 
|---|
| 171 | {"pbz",      Z (0x52),       OP (regaddr),           C}, | 
|---|
| 172 | {"pbnz",     Z (0x5a),       OP (regaddr),           C}, | 
|---|
| 173 |  | 
|---|
| 174 | {"pbp",      Z (0x54),       OP (regaddr),           C}, | 
|---|
| 175 | {"pbnp",     Z (0x5c),       OP (regaddr),           C}, | 
|---|
| 176 |  | 
|---|
| 177 | {"pbod",     Z (0x56),       OP (regaddr),           C}, | 
|---|
| 178 | {"pbev",     Z (0x5e),       OP (regaddr),           C}, | 
|---|
| 179 |  | 
|---|
| 180 | {"csn",      Z (0x60),       OP (regs_z),            N}, | 
|---|
| 181 | {"csnn",     Z (0x68),       OP (regs_z),            N}, | 
|---|
| 182 |  | 
|---|
| 183 | {"csz",      Z (0x62),       OP (regs_z),            N}, | 
|---|
| 184 | {"csnz",     Z (0x6a),       OP (regs_z),            N}, | 
|---|
| 185 |  | 
|---|
| 186 | {"csp",      Z (0x64),       OP (regs_z),            N}, | 
|---|
| 187 | {"csnp",     Z (0x6c),       OP (regs_z),            N}, | 
|---|
| 188 |  | 
|---|
| 189 | {"csod",     Z (0x66),       OP (regs_z),            N}, | 
|---|
| 190 | {"csev",     Z (0x6e),       OP (regs_z),            N}, | 
|---|
| 191 |  | 
|---|
| 192 | {"zsn",      Z (0x70),       OP (regs_z),            N}, | 
|---|
| 193 | {"zsnn",     Z (0x78),       OP (regs_z),            N}, | 
|---|
| 194 |  | 
|---|
| 195 | {"zsz",      Z (0x72),       OP (regs_z),            N}, | 
|---|
| 196 | {"zsnz",     Z (0x7a),       OP (regs_z),            N}, | 
|---|
| 197 |  | 
|---|
| 198 | {"zsp",      Z (0x74),       OP (regs_z),            N}, | 
|---|
| 199 | {"zsnp",     Z (0x7c),       OP (regs_z),            N}, | 
|---|
| 200 |  | 
|---|
| 201 | {"zsod",     Z (0x76),       OP (regs_z),            N}, | 
|---|
| 202 | {"zsev",     Z (0x7e),       OP (regs_z),            N}, | 
|---|
| 203 |  | 
|---|
| 204 | {"ldb",      Z (0x80),       OP (regs_z_opt),        MB}, | 
|---|
| 205 | {"ldt",      Z (0x88),       OP (regs_z_opt),        MT}, | 
|---|
| 206 |  | 
|---|
| 207 | {"ldbu",     Z (0x82),       OP (regs_z_opt),        MB}, | 
|---|
| 208 | {"ldtu",     Z (0x8a),       OP (regs_z_opt),        MT}, | 
|---|
| 209 |  | 
|---|
| 210 | {"ldw",      Z (0x84),       OP (regs_z_opt),        MW}, | 
|---|
| 211 | {"ldo",      Z (0x8c),       OP (regs_z_opt),        MO}, | 
|---|
| 212 |  | 
|---|
| 213 | {"ldwu",     Z (0x86),       OP (regs_z_opt),        MW}, | 
|---|
| 214 | {"ldou",     Z (0x8e),       OP (regs_z_opt),        MO}, | 
|---|
| 215 |  | 
|---|
| 216 | {"ldsf",     Z (0x90),       OP (regs_z_opt),        MT}, | 
|---|
| 217 |  | 
|---|
| 218 | /* This doesn't seem to access memory, just the TLB.  */ | 
|---|
| 219 | {"ldvts",    Z (0x98),       OP (regs_z_opt),        M}, | 
|---|
| 220 |  | 
|---|
| 221 | {"ldht",     Z (0x92),       OP (regs_z_opt),        MT}, | 
|---|
| 222 |  | 
|---|
| 223 | /* Neither does this per-se.  */ | 
|---|
| 224 | {"preld",    Z (0x9a),       OP (x_regs_z),          N}, | 
|---|
| 225 |  | 
|---|
| 226 | {"cswap",    Z (0x94),       OP (regs_z_opt),        MO}, | 
|---|
| 227 | {"prego",    Z (0x9c),       OP (x_regs_z),          N}, | 
|---|
| 228 |  | 
|---|
| 229 | {"ldunc",    Z (0x96),       OP (regs_z_opt),        MO}, | 
|---|
| 230 | {"go",       Z (0x9e),       OP (regs_z_opt),        B}, | 
|---|
| 231 |  | 
|---|
| 232 | {"stb",      Z (0xa0),       OP (regs_z_opt),        MB}, | 
|---|
| 233 | {"stt",      Z (0xa8),       OP (regs_z_opt),        MT}, | 
|---|
| 234 |  | 
|---|
| 235 | {"stbu",     Z (0xa2),       OP (regs_z_opt),        MB}, | 
|---|
| 236 | {"sttu",     Z (0xaa),       OP (regs_z_opt),        MT}, | 
|---|
| 237 |  | 
|---|
| 238 | {"stw",      Z (0xa4),       OP (regs_z_opt),        MW}, | 
|---|
| 239 | {"sto",      Z (0xac),       OP (regs_z_opt),        MO}, | 
|---|
| 240 |  | 
|---|
| 241 | {"stwu",     Z (0xa6),       OP (regs_z_opt),        MW}, | 
|---|
| 242 | {"stou",     Z (0xae),       OP (regs_z_opt),        MO}, | 
|---|
| 243 |  | 
|---|
| 244 | {"stsf",     Z (0xb0),       OP (regs_z_opt),        MT}, | 
|---|
| 245 | {"syncd",    Z (0xb8),       OP (x_regs_z),          M}, | 
|---|
| 246 |  | 
|---|
| 247 | {"stht",     Z (0xb2),       OP (regs_z_opt),        MT}, | 
|---|
| 248 | {"prest",    Z (0xba),       OP (x_regs_z),          M}, | 
|---|
| 249 |  | 
|---|
| 250 | {"stco",     Z (0xb4),       OP (x_regs_z),          MO}, | 
|---|
| 251 | {"syncid",   Z (0xbc),       OP (x_regs_z),          M}, | 
|---|
| 252 |  | 
|---|
| 253 | {"stunc",    Z (0xb6),       OP (regs_z_opt),        MO}, | 
|---|
| 254 | {"pushgo",   Z (0xbe),       OP (pushgo),            J}, | 
|---|
| 255 |  | 
|---|
| 256 | /* Synonym for OR with a zero Z.  */ | 
|---|
| 257 | {"set",      O (0xc1) | 
|---|
| 258 | | 0xff,       OP (set),               N}, | 
|---|
| 259 |  | 
|---|
| 260 | {"or",       Z (0xc0),       OP (regs_z),            N}, | 
|---|
| 261 | {"and",      Z (0xc8),       OP (regs_z),            N}, | 
|---|
| 262 |  | 
|---|
| 263 | {"orn",      Z (0xc2),       OP (regs_z),            N}, | 
|---|
| 264 | {"andn",     Z (0xca),       OP (regs_z),            N}, | 
|---|
| 265 |  | 
|---|
| 266 | {"nor",      Z (0xc4),       OP (regs_z),            N}, | 
|---|
| 267 | {"nand",     Z (0xcc),       OP (regs_z),            N}, | 
|---|
| 268 |  | 
|---|
| 269 | {"xor",      Z (0xc6),       OP (regs_z),            N}, | 
|---|
| 270 | {"nxor",     Z (0xce),       OP (regs_z),            N}, | 
|---|
| 271 |  | 
|---|
| 272 | {"bdif",     Z (0xd0),       OP (regs_z),            N}, | 
|---|
| 273 | {"mux",      Z (0xd8),       OP (regs_z),            N}, | 
|---|
| 274 |  | 
|---|
| 275 | {"wdif",     Z (0xd2),       OP (regs_z),            N}, | 
|---|
| 276 | {"sadd",     Z (0xda),       OP (regs_z),            N}, | 
|---|
| 277 |  | 
|---|
| 278 | {"tdif",     Z (0xd4),       OP (regs_z),            N}, | 
|---|
| 279 | {"mor",      Z (0xdc),       OP (regs_z),            N}, | 
|---|
| 280 |  | 
|---|
| 281 | {"odif",     Z (0xd6),       OP (regs_z),            N}, | 
|---|
| 282 | {"mxor",     Z (0xde),       OP (regs_z),            N}, | 
|---|
| 283 |  | 
|---|
| 284 | {"seth",     O (0xe0),       OP (reg_yz),            N}, | 
|---|
| 285 | {"setmh",    O (0xe1),       OP (reg_yz),            N}, | 
|---|
| 286 | {"orh",      O (0xe8),       OP (reg_yz),            N}, | 
|---|
| 287 | {"ormh",     O (0xe9),       OP (reg_yz),            N}, | 
|---|
| 288 |  | 
|---|
| 289 | {"setml",    O (0xe2),       OP (reg_yz),            N}, | 
|---|
| 290 | {"setl",     O (0xe3),       OP (reg_yz),            N}, | 
|---|
| 291 | {"orml",     O (0xea),       OP (reg_yz),            N}, | 
|---|
| 292 | {"orl",      O (0xeb),       OP (reg_yz),            N}, | 
|---|
| 293 |  | 
|---|
| 294 | {"inch",     O (0xe4),       OP (reg_yz),            N}, | 
|---|
| 295 | {"incmh",    O (0xe5),       OP (reg_yz),            N}, | 
|---|
| 296 | {"andnh",    O (0xec),       OP (reg_yz),            N}, | 
|---|
| 297 | {"andnmh",   O (0xed),       OP (reg_yz),            N}, | 
|---|
| 298 |  | 
|---|
| 299 | {"incml",    O (0xe6),       OP (reg_yz),            N}, | 
|---|
| 300 | {"incl",     O (0xe7),       OP (reg_yz),            N}, | 
|---|
| 301 | {"andnml",   O (0xee),       OP (reg_yz),            N}, | 
|---|
| 302 | {"andnl",    O (0xef),       OP (reg_yz),            N}, | 
|---|
| 303 |  | 
|---|
| 304 | {"jmp",      Z (0xf0),       OP (jmp),               B}, | 
|---|
| 305 | {"pop",      O (0xf8),       OP (pop),               B}, | 
|---|
| 306 | {"resume",   O (0xf9) | 
|---|
| 307 | | 0xffff00,   OP (resume),            B}, | 
|---|
| 308 |  | 
|---|
| 309 | {"pushj",    Z (0xf2),       OP (pushj),             J}, | 
|---|
| 310 | {"save",     O (0xfa) | 
|---|
| 311 | | 0xffff,     OP (save),              M}, | 
|---|
| 312 | {"unsave",   O (0xfb) | 
|---|
| 313 | | 0xffff00,   OP (unsave),            M}, | 
|---|
| 314 |  | 
|---|
| 315 | {"geta",     Z (0xf4),       OP (regaddr),           N}, | 
|---|
| 316 | {"sync",     O (0xfc),       OP (sync),              N}, | 
|---|
| 317 | {"swym",     O (0xfd),       OP (xyz_opt),           N}, | 
|---|
| 318 |  | 
|---|
| 319 | {"put", Z (0xf6) | 0xff00,   OP (put),               N}, | 
|---|
| 320 | {"get", O (0xfe) | 0xffe0,   OP (get),               N}, | 
|---|
| 321 | {"trip",     O (0xff),       OP (xyz_opt),           J}, | 
|---|
| 322 |  | 
|---|
| 323 | /* We have mmixal pseudos in the ordinary instruction table so we can | 
|---|
| 324 | avoid the "set" vs. ".set" ambiguity that would be the effect if we | 
|---|
| 325 | had pseudos handled "normally" and defined NO_PSEUDO_DOT. | 
|---|
| 326 |  | 
|---|
| 327 | Note that IS and GREG are handled fully by md_start_line_hook, so | 
|---|
| 328 | they're not here.  */ | 
|---|
| 329 | {"loc",      ~0, ~0,         OP (loc),               P}, | 
|---|
| 330 | {"prefix",   ~0, ~0,         OP (prefix),            P}, | 
|---|
| 331 | {"byte",     ~0, ~0,         OP (byte),              P}, | 
|---|
| 332 | {"wyde",     ~0, ~0,         OP (wyde),              P}, | 
|---|
| 333 | {"tetra",    ~0, ~0,         OP (tetra),             P}, | 
|---|
| 334 | {"octa",     ~0, ~0,         OP (octa),              P}, | 
|---|
| 335 | {"local",    ~0, ~0,         OP (local),             P}, | 
|---|
| 336 | {"bspec",    ~0, ~0,         OP (bspec),             P}, | 
|---|
| 337 | {"espec",    ~0, ~0,         OP (espec),             P}, | 
|---|
| 338 |  | 
|---|
| 339 | {NULL, ~0, ~0, OP (none), N} | 
|---|
| 340 | }; | 
|---|