1 /* mmix-opc.c -- MMIX opcode table 2 Copyright (C) 2001, 2003 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) ((unsigned long) (m) << 24UL), ((~(unsigned long) (m) & 255) << 24) 71 72 /* Bits 7..1 of the opcode are significant. */ 73 #undef Z 74 #define Z(m) ((unsigned long) (m) << 24), ((~(unsigned long) (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 (GO_INSN_BYTE), 231 OP (regs_z_opt), B}, 232 233 {"stb", Z (0xa0), OP (regs_z_opt), MB}, 234 {"stt", Z (0xa8), OP (regs_z_opt), MT}, 235 236 {"stbu", Z (0xa2), OP (regs_z_opt), MB}, 237 {"sttu", Z (0xaa), OP (regs_z_opt), MT}, 238 239 {"stw", Z (0xa4), OP (regs_z_opt), MW}, 240 {"sto", Z (0xac), OP (regs_z_opt), MO}, 241 242 {"stwu", Z (0xa6), OP (regs_z_opt), MW}, 243 {"stou", Z (0xae), OP (regs_z_opt), MO}, 244 245 {"stsf", Z (0xb0), OP (regs_z_opt), MT}, 246 {"syncd", Z (0xb8), OP (x_regs_z), M}, 247 248 {"stht", Z (0xb2), OP (regs_z_opt), MT}, 249 {"prest", Z (0xba), OP (x_regs_z), M}, 250 251 {"stco", Z (0xb4), OP (x_regs_z), MO}, 252 {"syncid", Z (0xbc), OP (x_regs_z), M}, 253 254 {"stunc", Z (0xb6), OP (regs_z_opt), MO}, 255 {"pushgo", Z (PUSHGO_INSN_BYTE), 256 OP (pushgo), J}, 257 258 /* Synonym for OR with a zero Z. */ 259 {"set", O (0xc1) 260 | 0xff, OP (set), N}, 261 262 {"or", Z (0xc0), OP (regs_z), N}, 263 {"and", Z (0xc8), OP (regs_z), N}, 264 265 {"orn", Z (0xc2), OP (regs_z), N}, 266 {"andn", Z (0xca), OP (regs_z), N}, 267 268 {"nor", Z (0xc4), OP (regs_z), N}, 269 {"nand", Z (0xcc), OP (regs_z), N}, 270 271 {"xor", Z (0xc6), OP (regs_z), N}, 272 {"nxor", Z (0xce), OP (regs_z), N}, 273 274 {"bdif", Z (0xd0), OP (regs_z), N}, 275 {"mux", Z (0xd8), OP (regs_z), N}, 276 277 {"wdif", Z (0xd2), OP (regs_z), N}, 278 {"sadd", Z (0xda), OP (regs_z), N}, 279 280 {"tdif", Z (0xd4), OP (regs_z), N}, 281 {"mor", Z (0xdc), OP (regs_z), N}, 282 283 {"odif", Z (0xd6), OP (regs_z), N}, 284 {"mxor", Z (0xde), OP (regs_z), N}, 285 286 {"seth", O (0xe0), OP (reg_yz), N}, 287 {"setmh", O (0xe1), OP (reg_yz), N}, 288 {"orh", O (0xe8), OP (reg_yz), N}, 289 {"ormh", O (0xe9), OP (reg_yz), N}, 290 291 {"setml", O (0xe2), OP (reg_yz), N}, 292 {"setl", O (SETL_INSN_BYTE), 293 OP (reg_yz), N}, 294 {"orml", O (0xea), OP (reg_yz), N}, 295 {"orl", O (0xeb), OP (reg_yz), N}, 296 297 {"inch", O (INCH_INSN_BYTE), 298 OP (reg_yz), N}, 299 {"incmh", O (INCMH_INSN_BYTE), 300 OP (reg_yz), N}, 301 {"andnh", O (0xec), OP (reg_yz), N}, 302 {"andnmh", O (0xed), OP (reg_yz), N}, 303 304 {"incml", O (INCML_INSN_BYTE), 305 OP (reg_yz), N}, 306 {"incl", O (0xe7), OP (reg_yz), N}, 307 {"andnml", O (0xee), OP (reg_yz), N}, 308 {"andnl", O (0xef), OP (reg_yz), N}, 309 310 {"jmp", Z (0xf0), OP (jmp), B}, 311 {"pop", O (0xf8), OP (pop), B}, 312 {"resume", O (0xf9) 313 | 0xffff00, OP (resume), B}, 314 315 {"pushj", Z (0xf2), OP (pushj), J}, 316 {"save", O (0xfa) 317 | 0xffff, OP (save), M}, 318 {"unsave", O (0xfb) 319 | 0xffff00, OP (unsave), M}, 320 321 {"geta", Z (0xf4), OP (regaddr), N}, 322 {"sync", O (0xfc), OP (sync), N}, 323 {"swym", O (SWYM_INSN_BYTE), 324 OP (xyz_opt), N}, 325 326 {"put", Z (0xf6) | 0xff00, OP (put), N}, 327 {"get", O (0xfe) | 0xffe0, OP (get), N}, 328 {"trip", O (0xff), OP (xyz_opt), J}, 329 330 /* We have mmixal pseudos in the ordinary instruction table so we can 331 avoid the "set" vs. ".set" ambiguity that would be the effect if we 332 had pseudos handled "normally" and defined NO_PSEUDO_DOT. 333 334 Note that IS and GREG are handled fully by md_start_line_hook, so 335 they're not here. */ 336 {"loc", ~0, ~0, OP (loc), P}, 337 {"prefix", ~0, ~0, OP (prefix), P}, 338 {"byte", ~0, ~0, OP (byte), P}, 339 {"wyde", ~0, ~0, OP (wyde), P}, 340 {"tetra", ~0, ~0, OP (tetra), P}, 341 {"octa", ~0, ~0, OP (octa), P}, 342 {"local", ~0, ~0, OP (local), P}, 343 {"bspec", ~0, ~0, OP (bspec), P}, 344 {"espec", ~0, ~0, OP (espec), P}, 345 346 {NULL, ~0, ~0, OP (none), N} 347 }; 348