1*5f210c2aSfgsch /* pyramid.opcode.h -- gdb initial attempt. 2*5f210c2aSfgsch 3*5f210c2aSfgsch Copyright 2001 Free Software Foundation, Inc. 4*5f210c2aSfgsch 5*5f210c2aSfgsch This program is free software; you can redistribute it and/or modify 6*5f210c2aSfgsch it under the terms of the GNU General Public License as published by 7*5f210c2aSfgsch the Free Software Foundation; either version 2, or (at your option) 8*5f210c2aSfgsch any later version. 9*5f210c2aSfgsch 10*5f210c2aSfgsch This program is distributed in the hope that it will be useful, 11*5f210c2aSfgsch but WITHOUT ANY WARRANTY; without even the implied warranty of 12*5f210c2aSfgsch MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*5f210c2aSfgsch GNU General Public License for more details. 14*5f210c2aSfgsch 15*5f210c2aSfgsch You should have received a copy of the GNU General Public License 16*5f210c2aSfgsch along with this program; if not, write to the Free Software 17*5f210c2aSfgsch Foundation, Inc., 59 Temple Place - Suite 330, 18*5f210c2aSfgsch Boston, MA 02111-1307, USA. */ 192159047fSniklas 202159047fSniklas /* pyramid opcode table: wot to do with this 212159047fSniklas particular opcode */ 222159047fSniklas 232159047fSniklas struct pyr_datum 242159047fSniklas { 252159047fSniklas char nargs; 262159047fSniklas char * args; /* how to compile said opcode */ 272159047fSniklas unsigned long mask; /* Bit vector: which operand modes are valid 282159047fSniklas for this opcode */ 292159047fSniklas unsigned char code; /* op-code (always 6(?) bits */ 302159047fSniklas }; 312159047fSniklas 32*5f210c2aSfgsch typedef struct pyr_insn_format 33*5f210c2aSfgsch { 342159047fSniklas unsigned int mode :4; 352159047fSniklas unsigned int operator :8; 362159047fSniklas unsigned int index_scale :2; 372159047fSniklas unsigned int index_reg :6; 382159047fSniklas unsigned int operand_1 :6; 392159047fSniklas unsigned int operand_2:6; 402159047fSniklas } pyr_insn_format; 412159047fSniklas 422159047fSniklas 432159047fSniklas /* We store four bytes of opcode for all opcodes. 442159047fSniklas Pyramid is sufficiently RISCy that: 452159047fSniklas - insns are always an integral number of words; 462159047fSniklas - the length of any insn can be told from the first word of 472159047fSniklas the insn. (ie, if there are zero, one, or two words of 482159047fSniklas immediate operand/offset). 492159047fSniklas 502159047fSniklas 512159047fSniklas The args component is a string containing two characters for each 522159047fSniklas operand of the instruction. The first specifies the kind of operand; 532159047fSniklas the second, the place it is stored. */ 542159047fSniklas 552159047fSniklas /* Kinds of operands: 562159047fSniklas mask assembler syntax description 572159047fSniklas 0x0001: movw Rn,Rn register to register 582159047fSniklas 0x0002: movw K,Rn quick immediate to register 592159047fSniklas 0x0004: movw I,Rn long immediate to register 602159047fSniklas 0x0008: movw (Rn),Rn register indirect to register 612159047fSniklas movw (Rn)[x],Rn register indirect to register 622159047fSniklas 0x0010: movw I(Rn),Rn offset register indirect to register 632159047fSniklas movw I(Rn)[x],Rn offset register indirect, indexed, to register 642159047fSniklas 652159047fSniklas 0x0020: movw Rn,(Rn) register to register indirect 662159047fSniklas 0x0040: movw K,(Rn) quick immediate to register indirect 672159047fSniklas 0x0080: movw I,(Rn) long immediate to register indirect 682159047fSniklas 0x0100: movw (Rn),(Rn) register indirect to-register indirect 692159047fSniklas 0x0100: movw (Rn),(Rn) register indirect to-register indirect 702159047fSniklas 0x0200: movw I(Rn),(Rn) register indirect+offset to register indirect 712159047fSniklas 0x0200: movw I(Rn),(Rn) register indirect+offset to register indirect 722159047fSniklas 732159047fSniklas 0x0400: movw Rn,I(Rn) register to register indirect+offset 742159047fSniklas 0x0800: movw K,I(Rn) quick immediate to register indirect+offset 752159047fSniklas 0x1000: movw I,I(Rn) long immediate to register indirect+offset 762159047fSniklas 0x1000: movw (Rn),I(Rn) register indirect to-register indirect+offset 772159047fSniklas 0x1000: movw I(Rn),I(Rn) register indirect+offset to register indirect 782159047fSniklas +offset 792159047fSniklas 0x0000: (irregular) ??? 802159047fSniklas 812159047fSniklas 822159047fSniklas Each insn has a four-bit field encoding the type(s) of its operands. 832159047fSniklas */ 842159047fSniklas 852159047fSniklas /* Some common combinations 862159047fSniklas */ 872159047fSniklas 882159047fSniklas /* the first 5,(0x1|0x2|0x4|0x8|0x10) ie (1|2|4|8|16), ie ( 32 -1)*/ 892159047fSniklas #define GEN_TO_REG (31) 902159047fSniklas 912159047fSniklas #define UNKNOWN ((unsigned long)-1) 922159047fSniklas #define ANY (GEN_TO_REG | (GEN_TO_REG << 5) | (GEN_TO_REG << 15)) 932159047fSniklas 942159047fSniklas #define CONVERT (1|8|0x10|0x20|0x200) 952159047fSniklas 962159047fSniklas #define K_TO_REG (2) 972159047fSniklas #define I_TO_REG (4) 982159047fSniklas #define NOTK_TO_REG (GEN_TO_REG & ~K_TO_REG) 992159047fSniklas #define NOTI_TO_REG (GEN_TO_REG & ~I_TO_REG) 1002159047fSniklas 1012159047fSniklas /* The assembler requires that this array be sorted as follows: 1022159047fSniklas all instances of the same mnemonic must be consecutive. 1032159047fSniklas All instances of the same mnemonic with the same number of operands 1042159047fSniklas must be consecutive. 1052159047fSniklas */ 1062159047fSniklas 1072159047fSniklas struct pyr_opcode /* pyr opcode text */ 1082159047fSniklas { 1092159047fSniklas char * name; /* opcode name: lowercase string [key] */ 1102159047fSniklas struct pyr_datum datum; /* rest of opcode table [datum] */ 1112159047fSniklas }; 1122159047fSniklas 1132159047fSniklas #define pyr_how args 1142159047fSniklas #define pyr_nargs nargs 1152159047fSniklas #define pyr_mask mask 1162159047fSniklas #define pyr_name name 1172159047fSniklas 1182159047fSniklas struct pyr_opcode pyr_opcodes[] = 1192159047fSniklas { 1202159047fSniklas {"movb", { 2, "", UNKNOWN, 0x11}, }, 1212159047fSniklas {"movh", { 2, "", UNKNOWN, 0x12} }, 1222159047fSniklas {"movw", { 2, "", ANY, 0x10} }, 1232159047fSniklas {"movl", { 2, "", ANY, 0x13} }, 1242159047fSniklas {"mnegw", { 2, "", (0x1|0x8|0x10), 0x14} }, 1252159047fSniklas {"mnegf", { 2, "", 0x1, 0x15} }, 1262159047fSniklas {"mnegd", { 2, "", 0x1, 0x16} }, 1272159047fSniklas {"mcomw", { 2, "", (0x1|0x8|0x10), 0x17} }, 1282159047fSniklas {"mabsw", { 2, "", (0x1|0x8|0x10), 0x18} }, 1292159047fSniklas {"mabsf", { 2, "", 0x1, 0x19} }, 1302159047fSniklas {"mabsd", { 2, "", 0x1, 0x1a} }, 1312159047fSniklas {"mtstw", { 2, "", (0x1|0x8|0x10), 0x1c} }, 1322159047fSniklas {"mtstf", { 2, "", 0x1, 0x1d} }, 1332159047fSniklas {"mtstd", { 2, "", 0x1, 0x1e} }, 1342159047fSniklas {"mova", { 2, "", 0x8|0x10, 0x1f} }, 1352159047fSniklas {"movzbw", { 2, "", (0x1|0x8|0x10), 0x20} }, 1362159047fSniklas {"movzhw", { 2, "", (0x1|0x8|0x10), 0x21} }, 1372159047fSniklas /* 2 insns out of order here */ 1382159047fSniklas {"movbl", { 2, "", 1, 0x4f} }, 1392159047fSniklas {"filbl", { 2, "", 1, 0x4e} }, 1402159047fSniklas 1412159047fSniklas {"cvtbw", { 2, "", CONVERT, 0x22} }, 1422159047fSniklas {"cvthw", { 2, "", CONVERT, 0x23} }, 1432159047fSniklas {"cvtwb", { 2, "", CONVERT, 0x24} }, 1442159047fSniklas {"cvtwh", { 2, "", CONVERT, 0x25} }, 1452159047fSniklas {"cvtwf", { 2, "", CONVERT, 0x26} }, 1462159047fSniklas {"cvtwd", { 2, "", CONVERT, 0x27} }, 1472159047fSniklas {"cvtfw", { 2, "", CONVERT, 0x28} }, 1482159047fSniklas {"cvtfd", { 2, "", CONVERT, 0x29} }, 1492159047fSniklas {"cvtdw", { 2, "", CONVERT, 0x2a} }, 1502159047fSniklas {"cvtdf", { 2, "", CONVERT, 0x2b} }, 1512159047fSniklas 1522159047fSniklas {"addw", { 2, "", GEN_TO_REG, 0x40} }, 1532159047fSniklas {"addwc", { 2, "", GEN_TO_REG, 0x41} }, 1542159047fSniklas {"subw", { 2, "", GEN_TO_REG, 0x42} }, 1552159047fSniklas {"subwb", { 2, "", GEN_TO_REG, 0x43} }, 1562159047fSniklas {"rsubw", { 2, "", GEN_TO_REG, 0x44} }, 1572159047fSniklas {"mulw", { 2, "", GEN_TO_REG, 0x45} }, 1582159047fSniklas {"emul", { 2, "", GEN_TO_REG, 0x47} }, 1592159047fSniklas {"umulw", { 2, "", GEN_TO_REG, 0x46} }, 1602159047fSniklas {"divw", { 2, "", GEN_TO_REG, 0x48} }, 1612159047fSniklas {"ediv", { 2, "", GEN_TO_REG, 0x4a} }, 1622159047fSniklas {"rdivw", { 2, "", GEN_TO_REG, 0x4b} }, 1632159047fSniklas {"udivw", { 2, "", GEN_TO_REG, 0x49} }, 1642159047fSniklas {"modw", { 2, "", GEN_TO_REG, 0x4c} }, 1652159047fSniklas {"umodw", { 2, "", GEN_TO_REG, 0x4d} }, 1662159047fSniklas 1672159047fSniklas 1682159047fSniklas {"addf", { 2, "", 1, 0x50} }, 1692159047fSniklas {"addd", { 2, "", 1, 0x51} }, 1702159047fSniklas {"subf", { 2, "", 1, 0x52} }, 1712159047fSniklas {"subd", { 2, "", 1, 0x53} }, 1722159047fSniklas {"mulf", { 2, "", 1, 0x56} }, 1732159047fSniklas {"muld", { 2, "", 1, 0x57} }, 1742159047fSniklas {"divf", { 2, "", 1, 0x58} }, 1752159047fSniklas {"divd", { 2, "", 1, 0x59} }, 1762159047fSniklas 1772159047fSniklas 1782159047fSniklas {"cmpb", { 2, "", UNKNOWN, 0x61} }, 1792159047fSniklas {"cmph", { 2, "", UNKNOWN, 0x62} }, 1802159047fSniklas {"cmpw", { 2, "", UNKNOWN, 0x60} }, 1812159047fSniklas {"ucmpb", { 2, "", UNKNOWN, 0x66} }, 1822159047fSniklas /* WHY no "ucmph"??? */ 1832159047fSniklas {"ucmpw", { 2, "", UNKNOWN, 0x65} }, 1842159047fSniklas {"xchw", { 2, "", UNKNOWN, 0x0f} }, 1852159047fSniklas 1862159047fSniklas 1872159047fSniklas {"andw", { 2, "", GEN_TO_REG, 0x30} }, 1882159047fSniklas {"orw", { 2, "", GEN_TO_REG, 0x31} }, 1892159047fSniklas {"xorw", { 2, "", GEN_TO_REG, 0x32} }, 1902159047fSniklas {"bicw", { 2, "", GEN_TO_REG, 0x33} }, 1912159047fSniklas {"lshlw", { 2, "", GEN_TO_REG, 0x38} }, 1922159047fSniklas {"ashlw", { 2, "", GEN_TO_REG, 0x3a} }, 1932159047fSniklas {"ashll", { 2, "", GEN_TO_REG, 0x3c} }, 1942159047fSniklas {"ashrw", { 2, "", GEN_TO_REG, 0x3b} }, 1952159047fSniklas {"ashrl", { 2, "", GEN_TO_REG, 0x3d} }, 1962159047fSniklas {"rotlw", { 2, "", GEN_TO_REG, 0x3e} }, 1972159047fSniklas {"rotrw", { 2, "", GEN_TO_REG, 0x3f} }, 1982159047fSniklas 1992159047fSniklas /* push and pop insns are "going away next release". */ 2002159047fSniklas {"pushw", { 2, "", GEN_TO_REG, 0x0c} }, 2012159047fSniklas {"popw", { 2, "", (0x1|0x8|0x10), 0x0d} }, 2022159047fSniklas {"pusha", { 2, "", (0x8|0x10), 0x0e} }, 2032159047fSniklas 2042159047fSniklas {"bitsw", { 2, "", UNKNOWN, 0x35} }, 2052159047fSniklas {"bitcw", { 2, "", UNKNOWN, 0x36} }, 2062159047fSniklas /* some kind of ibra/dbra insns??*/ 2072159047fSniklas {"icmpw", { 2, "", UNKNOWN, 0x67} }, 2082159047fSniklas {"dcmpw", { 2, "", (1|4|0x20|0x80|0x400|0x1000), 0x69} },/*FIXME*/ 2092159047fSniklas {"acmpw", { 2, "", 1, 0x6b} }, 2102159047fSniklas 2112159047fSniklas /* Call is written as a 1-op insn, but is always (dis)assembled as a 2-op 2122159047fSniklas insn with a 2nd op of tr14. The assembler will have to grok this. */ 2132159047fSniklas {"call", { 2, "", GEN_TO_REG, 0x04} }, 2142159047fSniklas {"call", { 1, "", GEN_TO_REG, 0x04} }, 2152159047fSniklas 2162159047fSniklas {"callk", { 1, "", UNKNOWN, 0x06} },/* system call?*/ 2172159047fSniklas /* Ret is usually written as a 0-op insn, but gets disassembled as a 2182159047fSniklas 1-op insn. The operand is always tr15. */ 2192159047fSniklas {"ret", { 0, "", UNKNOWN, 0x09} }, 2202159047fSniklas {"ret", { 1, "", UNKNOWN, 0x09} }, 2212159047fSniklas {"adsf", { 2, "", (1|2|4), 0x08} }, 2222159047fSniklas {"retd", { 2, "", UNKNOWN, 0x0a} }, 2232159047fSniklas {"btc", { 2, "", UNKNOWN, 0x01} }, 2242159047fSniklas {"bfc", { 2, "", UNKNOWN, 0x02} }, 2252159047fSniklas /* Careful: halt is 0x00000000. Jump must have some other (mode?)bit set?? */ 2262159047fSniklas {"jump", { 1, "", UNKNOWN, 0x00} }, 2272159047fSniklas {"btp", { 2, "", UNKNOWN, 0xf00} }, 2282159047fSniklas /* read control-stack pointer is another 1-or-2 operand insn. */ 2292159047fSniklas {"rcsp", { 2, "", UNKNOWN, 0x01f} }, 2302159047fSniklas {"rcsp", { 1, "", UNKNOWN, 0x01f} } 2312159047fSniklas }; 2322159047fSniklas 2332159047fSniklas /* end: pyramid.opcode.h */ 2342159047fSniklas /* One day I will have to take the time to find out what operands 2352159047fSniklas are valid for these insns, and guess at what they mean. 2362159047fSniklas 2372159047fSniklas I can't imagine what the "I???" insns (iglob, etc) do. 2382159047fSniklas 2392159047fSniklas the arithmetic-sounding insns ending in "p" sound awfully like BCD 2402159047fSniklas arithmetic insns: 2412159047fSniklas dshlp -> Decimal SHift Left Packed 2422159047fSniklas dshrp -> Decimal SHift Right Packed 2432159047fSniklas and cvtlp would be convert long to packed. 2442159047fSniklas I have no idea how the operands are interpreted; but having them be 2452159047fSniklas a long register with (address, length) of an in-memory packed BCD operand 2462159047fSniklas would not be surprising. 2472159047fSniklas They are unlikely to be a packed bcd string: 64 bits of long give 2482159047fSniklas is only 15 digits+sign, which isn't enough for COBOL. 2492159047fSniklas */ 2502159047fSniklas #if 0 2512159047fSniklas {"wcsp", { 2, "", UNKNOWN, 0x00} }, /*write csp?*/ 2522159047fSniklas /* The OSx Operating System Porting Guide claims SSL does things 2532159047fSniklas with tr12 (a register reserved to it) to do with static block-structure 2542159047fSniklas references. SSL=Set Static Link? It's "Going away next release". */ 2552159047fSniklas {"ssl", { 2, "", UNKNOWN, 0x00} }, 2562159047fSniklas {"ccmps", { 2, "", UNKNOWN, 0x00} }, 2572159047fSniklas {"lcd", { 2, "", UNKNOWN, 0x00} }, 2582159047fSniklas {"uemul", { 2, "", UNKNOWN, 0x00} }, /*unsigned emul*/ 2592159047fSniklas {"srf", { 2, "", UNKNOWN, 0x00} }, /*Gidget time???*/ 2602159047fSniklas {"mnegp", { 2, "", UNKNOWN, 0x00} }, /move-neg phys?*/ 2612159047fSniklas {"ldp", { 2, "", UNKNOWN, 0x00} }, /*load phys?*/ 2622159047fSniklas {"ldti", { 2, "", UNKNOWN, 0x00} }, 2632159047fSniklas {"ldb", { 2, "", UNKNOWN, 0x00} }, 2642159047fSniklas {"stp", { 2, "", UNKNOWN, 0x00} }, 2652159047fSniklas {"stti", { 2, "", UNKNOWN, 0x00} }, 2662159047fSniklas {"stb", { 2, "", UNKNOWN, 0x00} }, 2672159047fSniklas {"stu", { 2, "", UNKNOWN, 0x00} }, 2682159047fSniklas {"addp", { 2, "", UNKNOWN, 0x00} }, 2692159047fSniklas {"subp", { 2, "", UNKNOWN, 0x00} }, 2702159047fSniklas {"mulp", { 2, "", UNKNOWN, 0x00} }, 2712159047fSniklas {"divp", { 2, "", UNKNOWN, 0x00} }, 2722159047fSniklas {"dshlp", { 2, "", UNKNOWN, 0x00} }, /* dec shl packed? */ 2732159047fSniklas {"dshrp", { 2, "", UNKNOWN, 0x00} }, /* dec shr packed? */ 2742159047fSniklas {"movs", { 2, "", UNKNOWN, 0x00} }, /*move (string?)?*/ 2752159047fSniklas {"cmpp", { 2, "", UNKNOWN, 0x00} }, /* cmp phys?*/ 2762159047fSniklas {"cmps", { 2, "", UNKNOWN, 0x00} }, /* cmp (string?)?*/ 2772159047fSniklas {"cvtlp", { 2, "", UNKNOWN, 0x00} }, /* cvt long to p??*/ 2782159047fSniklas {"cvtpl", { 2, "", UNKNOWN, 0x00} }, /* cvt p to l??*/ 2792159047fSniklas {"dintr", { 2, "", UNKNOWN, 0x00} }, /* ?? intr ?*/ 2802159047fSniklas {"rphysw", { 2, "", UNKNOWN, 0x00} }, /* read phys word?*/ 2812159047fSniklas {"wphysw", { 2, "", UNKNOWN, 0x00} }, /* write phys word?*/ 2822159047fSniklas {"cmovs", { 2, "", UNKNOWN, 0x00} }, 2832159047fSniklas {"rsubw", { 2, "", UNKNOWN, 0x00} }, 2842159047fSniklas {"bicpsw", { 2, "", UNKNOWN, 0x00} }, /* clr bit in psw? */ 2852159047fSniklas {"bispsw", { 2, "", UNKNOWN, 0x00} }, /* set bit in psw? */ 2862159047fSniklas {"eio", { 2, "", UNKNOWN, 0x00} }, /* ?? ?io ? */ 2872159047fSniklas {"callp", { 2, "", UNKNOWN, 0x00} }, /* call phys?*/ 2882159047fSniklas {"callr", { 2, "", UNKNOWN, 0x00} }, 2892159047fSniklas {"lpcxt", { 2, "", UNKNOWN, 0x00} }, /*load proc context*/ 2902159047fSniklas {"rei", { 2, "", UNKNOWN, 0x00} }, /*ret from intrpt*/ 2912159047fSniklas {"rport", { 2, "", UNKNOWN, 0x00} }, /*read-port?*/ 2922159047fSniklas {"rtod", { 2, "", UNKNOWN, 0x00} }, /*read-time-of-day?*/ 2932159047fSniklas {"ssi", { 2, "", UNKNOWN, 0x00} }, 2942159047fSniklas {"vtpa", { 2, "", UNKNOWN, 0x00} }, /*virt-to-phys-addr?*/ 2952159047fSniklas {"wicl", { 2, "", UNKNOWN, 0x00} }, /* write icl ? */ 2962159047fSniklas {"wport", { 2, "", UNKNOWN, 0x00} }, /*write-port?*/ 2972159047fSniklas {"wtod", { 2, "", UNKNOWN, 0x00} }, /*write-time-of-day?*/ 2982159047fSniklas {"flic", { 2, "", UNKNOWN, 0x00} }, 2992159047fSniklas {"iglob", { 2, "", UNKNOWN, 0x00} }, /* I global? */ 3002159047fSniklas {"iphys", { 2, "", UNKNOWN, 0x00} }, /* I physical? */ 3012159047fSniklas {"ipid", { 2, "", UNKNOWN, 0x00} }, /* I pid? */ 3022159047fSniklas {"ivect", { 2, "", UNKNOWN, 0x00} }, /* I vector? */ 3032159047fSniklas {"lamst", { 2, "", UNKNOWN, 0x00} }, 3042159047fSniklas {"tio", { 2, "", UNKNOWN, 0x00} }, 3052159047fSniklas #endif 306