Home | History | Annotate | Download | only in opcode
      1 /* pyramid.opcode.h -- gdb initial attempt.
      2 
      3    Copyright (C) 2001-2016 Free Software Foundation, Inc.
      4 
      5    This program is free software; you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation; either version 3, or (at your option)
      8    any later version.
      9 
     10    This program is distributed in the hope that it will be useful,
     11    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13    GNU General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public License
     16    along with this program; if not, write to the Free Software
     17    Foundation, Inc., 51 Franklin Street - Fifth Floor,
     18    Boston, MA 02110-1301, USA.  */
     19 
     20 /* pyramid opcode table: wot to do with this
     21    particular opcode */
     22 
     23 struct pyr_datum
     24 {
     25   char              nargs;
     26   char *            args;	/* how to compile said opcode */
     27   unsigned long     mask;	/* Bit vector: which operand modes are valid
     28 				   for this opcode */
     29   unsigned char     code;	/* op-code (always 6(?) bits */
     30 };
     31 
     32 typedef struct pyr_insn_format
     33 {
     34     unsigned int mode :4;
     35     unsigned int operator :8;
     36     unsigned int index_scale :2;
     37     unsigned int index_reg :6;
     38     unsigned int operand_1 :6;
     39     unsigned int operand_2:6;
     40 } pyr_insn_format;
     41 
     42 
     43 /* We store four bytes of opcode for all opcodes.
     44    Pyramid is sufficiently RISCy that:
     45       - insns are always an integral number of words;
     46       - the length of any insn can be told from the first word of
     47         the insn. (ie, if there are zero, one, or two words of
     48 	immediate operand/offset).
     49 
     50 
     51    The args component is a string containing two characters for each
     52    operand of the instruction.  The first specifies the kind of operand;
     53    the second, the place it is stored. */
     54 
     55 /* Kinds of operands:
     56    mask	 assembler syntax	description
     57    0x0001:  movw Rn,Rn		register to register
     58    0x0002:  movw K,Rn		quick immediate to register
     59    0x0004:  movw I,Rn		long immediate to register
     60    0x0008:  movw (Rn),Rn	register indirect to register
     61    	    movw (Rn)[x],Rn	register indirect to register
     62    0x0010:  movw I(Rn),Rn	offset register indirect to register
     63    	    movw I(Rn)[x],Rn	offset register indirect, indexed, to register
     64 
     65    0x0020:  movw Rn,(Rn)	register to register indirect
     66    0x0040:  movw K,(Rn)		quick immediate to register indirect
     67    0x0080:  movw I,(Rn)		long immediate to register indirect
     68    0x0100:  movw (Rn),(Rn)	register indirect to-register indirect
     69    0x0100:  movw (Rn),(Rn)	register indirect to-register indirect
     70    0x0200:  movw I(Rn),(Rn)	register indirect+offset to register indirect
     71    0x0200:  movw I(Rn),(Rn)	register indirect+offset to register indirect
     72 
     73    0x0400:  movw Rn,I(Rn)	register to register indirect+offset
     74    0x0800:  movw K,I(Rn)	quick immediate to register indirect+offset
     75    0x1000:  movw I,I(Rn)	long immediate to register indirect+offset
     76    0x1000:  movw (Rn),I(Rn)	register indirect to-register indirect+offset
     77    0x1000:  movw I(Rn),I(Rn)	register indirect+offset to register indirect
     78    					+offset
     79    0x0000:  (irregular)		???
     80 
     81 
     82    Each insn has a four-bit field encoding the type(s) of its operands.
     83 */
     84 
     85 /* Some common combinations
     86    */
     87 
     88 /* the first 5,(0x1|0x2|0x4|0x8|0x10) ie (1|2|4|8|16), ie ( 32 -1)*/
     89 #define GEN_TO_REG (31)
     90 
     91 #define	UNKNOWN ((unsigned long)-1)
     92 #define ANY (GEN_TO_REG | (GEN_TO_REG << 5) | (GEN_TO_REG << 15))
     93 
     94 #define CONVERT (1|8|0x10|0x20|0x200)
     95 
     96 #define K_TO_REG (2)
     97 #define I_TO_REG (4)
     98 #define NOTK_TO_REG (GEN_TO_REG & ~K_TO_REG)
     99 #define NOTI_TO_REG (GEN_TO_REG & ~I_TO_REG)
    100 
    101 /* The assembler requires that this array be sorted as follows:
    102    all instances of the same mnemonic must be consecutive.
    103    All instances of the same mnemonic with the same number of operands
    104    must be consecutive.
    105  */
    106 
    107 struct pyr_opcode		/* pyr opcode text */
    108 {
    109   char *            name;	/* opcode name: lowercase string  [key]  */
    110   struct pyr_datum  datum;	/* rest of opcode table          [datum] */
    111 };
    112 
    113 #define pyr_how args
    114 #define pyr_nargs nargs
    115 #define pyr_mask mask
    116 #define pyr_name name
    117 
    118 struct pyr_opcode pyr_opcodes[] =
    119 {
    120   {"movb",	{ 2, "", UNKNOWN,		0x11}, },
    121   {"movh",	{ 2, "", UNKNOWN,		0x12} },
    122   {"movw",	{ 2, "", ANY,			0x10} },
    123   {"movl",	{ 2, "", ANY,			0x13} },
    124   {"mnegw",	{ 2, "", (0x1|0x8|0x10),	0x14} },
    125   {"mnegf",	{ 2, "", 0x1,			0x15} },
    126   {"mnegd",	{ 2, "", 0x1,			0x16} },
    127   {"mcomw",	{ 2, "", (0x1|0x8|0x10),	0x17} },
    128   {"mabsw",	{ 2, "", (0x1|0x8|0x10),	0x18} },
    129   {"mabsf",	{ 2, "", 0x1,			0x19} },
    130   {"mabsd",	{ 2, "", 0x1,			0x1a} },
    131   {"mtstw",	{ 2, "", (0x1|0x8|0x10),	0x1c} },
    132   {"mtstf",	{ 2, "", 0x1,			0x1d} },
    133   {"mtstd",	{ 2, "", 0x1,			0x1e} },
    134   {"mova",	{ 2, "", 0x8|0x10,		0x1f} },
    135   {"movzbw",	{ 2, "", (0x1|0x8|0x10),	0x20} },
    136   {"movzhw",	{ 2, "", (0x1|0x8|0x10),	0x21} },
    137 				/* 2 insns out of order here */
    138   {"movbl",	{ 2, "", 1,			0x4f} },
    139   {"filbl",	{ 2, "", 1,			0x4e} },
    140 
    141   {"cvtbw",	{ 2, "", CONVERT,		0x22} },
    142   {"cvthw",	{ 2, "", CONVERT,		0x23} },
    143   {"cvtwb",	{ 2, "", CONVERT,		0x24} },
    144   {"cvtwh",	{ 2, "", CONVERT,		0x25} },
    145   {"cvtwf",	{ 2, "", CONVERT,		0x26} },
    146   {"cvtwd",	{ 2, "", CONVERT,		0x27} },
    147   {"cvtfw",	{ 2, "", CONVERT,		0x28} },
    148   {"cvtfd",	{ 2, "", CONVERT,		0x29} },
    149   {"cvtdw",	{ 2, "", CONVERT,		0x2a} },
    150   {"cvtdf",	{ 2, "", CONVERT,		0x2b} },
    151 
    152   {"addw",	{ 2, "", GEN_TO_REG,		0x40} },
    153   {"addwc",	{ 2, "", GEN_TO_REG,		0x41} },
    154   {"subw",	{ 2, "", GEN_TO_REG,		0x42} },
    155   {"subwb",	{ 2, "", GEN_TO_REG,		0x43} },
    156   {"rsubw",	{ 2, "", GEN_TO_REG,		0x44} },
    157   {"mulw",	{ 2, "", GEN_TO_REG,		0x45} },
    158   {"emul",	{ 2, "", GEN_TO_REG,		0x47} },
    159   {"umulw",	{ 2, "", GEN_TO_REG,		0x46} },
    160   {"divw",	{ 2, "", GEN_TO_REG,		0x48} },
    161   {"ediv",	{ 2, "", GEN_TO_REG,		0x4a} },
    162   {"rdivw",	{ 2, "", GEN_TO_REG,		0x4b} },
    163   {"udivw",	{ 2, "", GEN_TO_REG,		0x49} },
    164   {"modw",	{ 2, "", GEN_TO_REG,		0x4c} },
    165   {"umodw",	{ 2, "", GEN_TO_REG,		0x4d} },
    166 
    167 
    168   {"addf",	{ 2, "", 1,			0x50} },
    169   {"addd",	{ 2, "", 1,			0x51} },
    170   {"subf",	{ 2, "", 1,			0x52} },
    171   {"subd",	{ 2, "", 1,			0x53} },
    172   {"mulf",	{ 2, "", 1,			0x56} },
    173   {"muld",	{ 2, "", 1,			0x57} },
    174   {"divf",	{ 2, "", 1,			0x58} },
    175   {"divd",	{ 2, "", 1,			0x59} },
    176 
    177 
    178   {"cmpb",	{ 2, "", UNKNOWN,		0x61} },
    179   {"cmph",	{ 2, "", UNKNOWN,		0x62} },
    180   {"cmpw",	{ 2, "", UNKNOWN,		0x60} },
    181   {"ucmpb",	{ 2, "", UNKNOWN,		0x66} },
    182   /* WHY no "ucmph"??? */
    183   {"ucmpw",	{ 2, "", UNKNOWN,		0x65} },
    184   {"xchw",	{ 2, "", UNKNOWN,		0x0f} },
    185 
    186 
    187   {"andw",	{ 2, "", GEN_TO_REG,		0x30} },
    188   {"orw",	{ 2, "", GEN_TO_REG,		0x31} },
    189   {"xorw",	{ 2, "", GEN_TO_REG,		0x32} },
    190   {"bicw",	{ 2, "", GEN_TO_REG,		0x33} },
    191   {"lshlw",	{ 2, "", GEN_TO_REG,		0x38} },
    192   {"ashlw",	{ 2, "", GEN_TO_REG,		0x3a} },
    193   {"ashll",	{ 2, "", GEN_TO_REG,		0x3c} },
    194   {"ashrw",	{ 2, "", GEN_TO_REG,		0x3b} },
    195   {"ashrl",	{ 2, "", GEN_TO_REG,		0x3d} },
    196   {"rotlw",	{ 2, "", GEN_TO_REG,		0x3e} },
    197   {"rotrw",	{ 2, "", GEN_TO_REG,		0x3f} },
    198 
    199   /* push and pop insns are "going away next release". */
    200   {"pushw",	{ 2, "", GEN_TO_REG,		0x0c} },
    201   {"popw",	{ 2, "", (0x1|0x8|0x10),	0x0d} },
    202   {"pusha",	{ 2, "", (0x8|0x10),		0x0e} },
    203 
    204   {"bitsw",	{ 2, "", UNKNOWN,		0x35} },
    205   {"bitcw",	{ 2, "", UNKNOWN,		0x36} },
    206   /* some kind of ibra/dbra insns??*/
    207   {"icmpw",	{ 2, "", UNKNOWN,		0x67} },
    208   {"dcmpw",	{ 2, "", (1|4|0x20|0x80|0x400|0x1000),	0x69} },/*FIXME*/
    209   {"acmpw",	{ 2, "", 1,			0x6b} },
    210 
    211   /* Call is written as a 1-op insn, but is always (dis)assembled as a 2-op
    212      insn with a 2nd op of tr14.   The assembler will have to grok this.  */
    213   {"call",	{ 2, "", GEN_TO_REG,		0x04} },
    214   {"call",	{ 1, "", GEN_TO_REG,		0x04} },
    215 
    216   {"callk",	{ 1, "", UNKNOWN,		0x06} },/* system call?*/
    217   /* Ret is usually written as a 0-op insn, but gets disassembled as a
    218      1-op insn. The operand is always tr15. */
    219   {"ret",	{ 0, "", UNKNOWN,		0x09} },
    220   {"ret",	{ 1, "", UNKNOWN,		0x09} },
    221   {"adsf",	{ 2, "", (1|2|4),		0x08} },
    222   {"retd",	{ 2, "", UNKNOWN,		0x0a} },
    223   {"btc",	{ 2, "", UNKNOWN,		0x01} },
    224   {"bfc",	{ 2, "", UNKNOWN,		0x02} },
    225   /* Careful: halt is 0x00000000. Jump must have some other (mode?)bit set?? */
    226   {"jump",	{ 1, "", UNKNOWN,		0x00} },
    227   {"btp",	{ 2, "", UNKNOWN,		0xf00} },
    228   /* read control-stack pointer is another 1-or-2 operand insn. */
    229   {"rcsp",	{ 2, "", UNKNOWN,		0x01f} },
    230   {"rcsp",	{ 1, "", UNKNOWN,		0x01f} }
    231 };
    232 
    233 /* end: pyramid.opcode.h */
    234 /* One day I will have to take the time to find out what operands
    235    are valid for these insns, and guess at what they mean.
    236 
    237    I can't imagine what the "I???" insns (iglob, etc) do.
    238 
    239    the arithmetic-sounding insns ending in "p" sound awfully like BCD
    240    arithmetic insns:
    241    	dshlp -> Decimal SHift Left Packed
    242 	dshrp -> Decimal SHift Right Packed
    243    and cvtlp would be convert long to packed.
    244    I have no idea how the operands are interpreted; but having them be
    245    a long register with (address, length) of an in-memory packed BCD operand
    246    would not be surprising.
    247    They are unlikely to be a packed bcd string: 64 bits of long give
    248    is only 15 digits+sign, which isn't enough for COBOL.
    249  */
    250 #if 0
    251   {"wcsp",	{ 2, "", UNKNOWN,		0x00} }, /*write csp?*/
    252   /* The OSx Operating System Porting Guide claims SSL does things
    253      with tr12 (a register reserved to it) to do with static block-structure
    254      references.  SSL=Set Static Link?  It's "Going away next release". */
    255   {"ssl",	{ 2, "", UNKNOWN,		0x00} },
    256   {"ccmps",	{ 2, "", UNKNOWN,		0x00} },
    257   {"lcd",	{ 2, "", UNKNOWN,		0x00} },
    258   {"uemul",	{ 2, "", UNKNOWN,		0x00} }, /*unsigned emul*/
    259   {"srf",	{ 2, "", UNKNOWN,		0x00} }, /*Gidget time???*/
    260   {"mnegp",	{ 2, "", UNKNOWN,		0x00} }, /move-neg phys?*/
    261   {"ldp",	{ 2, "", UNKNOWN,		0x00} }, /*load phys?*/
    262   {"ldti",	{ 2, "", UNKNOWN,		0x00} },
    263   {"ldb",	{ 2, "", UNKNOWN,		0x00} },
    264   {"stp",	{ 2, "", UNKNOWN,		0x00} },
    265   {"stti",	{ 2, "", UNKNOWN,		0x00} },
    266   {"stb",	{ 2, "", UNKNOWN,		0x00} },
    267   {"stu",	{ 2, "", UNKNOWN,		0x00} },
    268   {"addp",	{ 2, "", UNKNOWN,		0x00} },
    269   {"subp",	{ 2, "", UNKNOWN,		0x00} },
    270   {"mulp",	{ 2, "", UNKNOWN,		0x00} },
    271   {"divp",	{ 2, "", UNKNOWN,		0x00} },
    272   {"dshlp",	{ 2, "", UNKNOWN,		0x00} },  /* dec shl packed? */
    273   {"dshrp",	{ 2, "", UNKNOWN,		0x00} }, /* dec shr packed? */
    274   {"movs",	{ 2, "", UNKNOWN,		0x00} }, /*move (string?)?*/
    275   {"cmpp",	{ 2, "", UNKNOWN,		0x00} }, /* cmp phys?*/
    276   {"cmps",	{ 2, "", UNKNOWN,		0x00} }, /* cmp (string?)?*/
    277   {"cvtlp",	{ 2, "", UNKNOWN,		0x00} }, /* cvt long to p??*/
    278   {"cvtpl",	{ 2, "", UNKNOWN,		0x00} }, /* cvt p to l??*/
    279   {"dintr",	{ 2, "", UNKNOWN,		0x00} }, /* ?? intr ?*/
    280   {"rphysw",	{ 2, "", UNKNOWN,		0x00} }, /* read phys word?*/
    281   {"wphysw",	{ 2, "", UNKNOWN,		0x00} }, /* write phys word?*/
    282   {"cmovs",	{ 2, "", UNKNOWN,		0x00} },
    283   {"rsubw",	{ 2, "", UNKNOWN,		0x00} },
    284   {"bicpsw",	{ 2, "", UNKNOWN,		0x00} }, /* clr bit in psw? */
    285   {"bispsw",	{ 2, "", UNKNOWN,		0x00} }, /* set bit in psw? */
    286   {"eio",	{ 2, "", UNKNOWN,		0x00} }, /* ?? ?io ? */
    287   {"callp",	{ 2, "", UNKNOWN,		0x00} }, /* call phys?*/
    288   {"callr",	{ 2, "", UNKNOWN,		0x00} },
    289   {"lpcxt",	{ 2, "", UNKNOWN,		0x00} }, /*load proc context*/
    290   {"rei",	{ 2, "", UNKNOWN,		0x00} }, /*ret from intrpt*/
    291   {"rport",	{ 2, "", UNKNOWN,		0x00} }, /*read-port?*/
    292   {"rtod",	{ 2, "", UNKNOWN,		0x00} }, /*read-time-of-day?*/
    293   {"ssi",	{ 2, "", UNKNOWN,		0x00} },
    294   {"vtpa",	{ 2, "", UNKNOWN,		0x00} }, /*virt-to-phys-addr?*/
    295   {"wicl",	{ 2, "", UNKNOWN,		0x00} }, /* write icl ? */
    296   {"wport",	{ 2, "", UNKNOWN,		0x00} }, /*write-port?*/
    297   {"wtod",	{ 2, "", UNKNOWN,		0x00} }, /*write-time-of-day?*/
    298   {"flic",	{ 2, "", UNKNOWN,		0x00} },
    299   {"iglob",	{ 2, "", UNKNOWN,		0x00} }, /* I global? */
    300   {"iphys",	{ 2, "", UNKNOWN,		0x00} }, /* I physical? */
    301   {"ipid",	{ 2, "", UNKNOWN,		0x00} }, /* I pid? */
    302   {"ivect",	{ 2, "", UNKNOWN,		0x00} }, /* I vector? */
    303   {"lamst",	{ 2, "", UNKNOWN,		0x00} },
    304   {"tio",	{ 2, "", UNKNOWN,		0x00} },
    305 #endif
    306