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