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