Back to index

cell-binutils  2.17cvs20070401
pyr.h
Go to the documentation of this file.
00001 /* pyramid.opcode.h -- gdb initial attempt.
00002 
00003    Copyright 2001 Free Software Foundation, Inc.
00004    
00005    This program is free software; you can redistribute it and/or modify
00006    it under the terms of the GNU General Public License as published by
00007    the Free Software Foundation; either version 2, or (at your option)
00008    any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013    GNU General Public License for more details.
00014 
00015    You should have received a copy of the GNU General Public License
00016    along with this program; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street - Fifth Floor,
00018    Boston, MA 02110-1301, USA.  */
00019    
00020 /* pyramid opcode table: wot to do with this
00021    particular opcode */
00022 
00023 struct pyr_datum
00024 {
00025   char              nargs;
00026   char *            args;   /* how to compile said opcode */
00027   unsigned long     mask;   /* Bit vector: which operand modes are valid
00028                                for this opcode */
00029   unsigned char     code;   /* op-code (always 6(?) bits */
00030 };
00031 
00032 typedef struct pyr_insn_format
00033 {
00034     unsigned int mode :4;
00035     unsigned int operator :8;
00036     unsigned int index_scale :2;
00037     unsigned int index_reg :6;
00038     unsigned int operand_1 :6;
00039     unsigned int operand_2:6;
00040 } pyr_insn_format;
00041        
00042 
00043 /* We store four bytes of opcode for all opcodes.
00044    Pyramid is sufficiently RISCy that:
00045       - insns are always an integral number of words;
00046       - the length of any insn can be told from the first word of
00047         the insn. (ie, if there are zero, one, or two words of
00048        immediate operand/offset).
00049 
00050    
00051    The args component is a string containing two characters for each
00052    operand of the instruction.  The first specifies the kind of operand;
00053    the second, the place it is stored. */
00054 
00055 /* Kinds of operands:
00056    mask        assembler syntax    description
00057    0x0001:  movw Rn,Rn             register to register
00058    0x0002:  movw K,Rn              quick immediate to register
00059    0x0004:  movw I,Rn              long immediate to register
00060    0x0008:  movw (Rn),Rn    register indirect to register
00061            movw (Rn)[x],Rn  register indirect to register
00062    0x0010:  movw I(Rn),Rn   offset register indirect to register
00063            movw I(Rn)[x],Rn offset register indirect, indexed, to register
00064 
00065    0x0020:  movw Rn,(Rn)    register to register indirect                
00066    0x0040:  movw K,(Rn)            quick immediate to register indirect         
00067    0x0080:  movw I,(Rn)            long immediate to register indirect          
00068    0x0100:  movw (Rn),(Rn)  register indirect to-register indirect       
00069    0x0100:  movw (Rn),(Rn)  register indirect to-register indirect       
00070    0x0200:  movw I(Rn),(Rn) register indirect+offset to register indirect
00071    0x0200:  movw I(Rn),(Rn) register indirect+offset to register indirect
00072 
00073    0x0400:  movw Rn,I(Rn)   register to register indirect+offset
00074    0x0800:  movw K,I(Rn)    quick immediate to register indirect+offset
00075    0x1000:  movw I,I(Rn)    long immediate to register indirect+offset
00076    0x1000:  movw (Rn),I(Rn) register indirect to-register indirect+offset
00077    0x1000:  movw I(Rn),I(Rn)       register indirect+offset to register indirect
00078                                    +offset
00079    0x0000:  (irregular)            ???
00080    
00081 
00082    Each insn has a four-bit field encoding the type(s) of its operands.
00083 */
00084 
00085 /* Some common combinations
00086    */
00087 
00088 /* the first 5,(0x1|0x2|0x4|0x8|0x10) ie (1|2|4|8|16), ie ( 32 -1)*/
00089 #define GEN_TO_REG (31)
00090 
00091 #define       UNKNOWN ((unsigned long)-1)
00092 #define ANY (GEN_TO_REG | (GEN_TO_REG << 5) | (GEN_TO_REG << 15))
00093 
00094 #define CONVERT (1|8|0x10|0x20|0x200)
00095 
00096 #define K_TO_REG (2)
00097 #define I_TO_REG (4)
00098 #define NOTK_TO_REG (GEN_TO_REG & ~K_TO_REG)
00099 #define NOTI_TO_REG (GEN_TO_REG & ~I_TO_REG)
00100 
00101 /* The assembler requires that this array be sorted as follows:
00102    all instances of the same mnemonic must be consecutive.
00103    All instances of the same mnemonic with the same number of operands
00104    must be consecutive.
00105  */
00106 
00107 struct pyr_opcode           /* pyr opcode text */
00108 {
00109   char *            name;   /* opcode name: lowercase string  [key]  */
00110   struct pyr_datum  datum;  /* rest of opcode table          [datum] */
00111 };
00112 
00113 #define pyr_how args
00114 #define pyr_nargs nargs
00115 #define pyr_mask mask
00116 #define pyr_name name
00117 
00118 struct pyr_opcode pyr_opcodes[] =
00119 {
00120   {"movb",    { 2, "", UNKNOWN,           0x11}, },
00121   {"movh",    { 2, "", UNKNOWN,           0x12} },
00122   {"movw",    { 2, "", ANY,               0x10} },
00123   {"movl",    { 2, "", ANY,               0x13} },
00124   {"mnegw",   { 2, "", (0x1|0x8|0x10),    0x14} },
00125   {"mnegf",   { 2, "", 0x1,               0x15} },
00126   {"mnegd",   { 2, "", 0x1,               0x16} },
00127   {"mcomw",   { 2, "", (0x1|0x8|0x10),    0x17} },
00128   {"mabsw",   { 2, "", (0x1|0x8|0x10),    0x18} },
00129   {"mabsf",   { 2, "", 0x1,               0x19} },
00130   {"mabsd",   { 2, "", 0x1,               0x1a} },
00131   {"mtstw",   { 2, "", (0x1|0x8|0x10),    0x1c} },
00132   {"mtstf",   { 2, "", 0x1,               0x1d} },
00133   {"mtstd",   { 2, "", 0x1,               0x1e} },
00134   {"mova",    { 2, "", 0x8|0x10,          0x1f} },
00135   {"movzbw",  { 2, "", (0x1|0x8|0x10),    0x20} },
00136   {"movzhw",  { 2, "", (0x1|0x8|0x10),    0x21} },
00137                             /* 2 insns out of order here */
00138   {"movbl",   { 2, "", 1,                 0x4f} },
00139   {"filbl",   { 2, "", 1,                 0x4e} },
00140 
00141   {"cvtbw",   { 2, "", CONVERT,           0x22} },
00142   {"cvthw",   { 2, "", CONVERT,           0x23} },
00143   {"cvtwb",   { 2, "", CONVERT,           0x24} },
00144   {"cvtwh",   { 2, "", CONVERT,           0x25} },
00145   {"cvtwf",   { 2, "", CONVERT,           0x26} },
00146   {"cvtwd",   { 2, "", CONVERT,           0x27} },
00147   {"cvtfw",   { 2, "", CONVERT,           0x28} },
00148   {"cvtfd",   { 2, "", CONVERT,           0x29} },
00149   {"cvtdw",   { 2, "", CONVERT,           0x2a} },
00150   {"cvtdf",   { 2, "", CONVERT,           0x2b} },
00151 
00152   {"addw",    { 2, "", GEN_TO_REG,        0x40} },
00153   {"addwc",   { 2, "", GEN_TO_REG,        0x41} },
00154   {"subw",    { 2, "", GEN_TO_REG,        0x42} },
00155   {"subwb",   { 2, "", GEN_TO_REG,        0x43} },
00156   {"rsubw",   { 2, "", GEN_TO_REG,        0x44} },
00157   {"mulw",    { 2, "", GEN_TO_REG,        0x45} },
00158   {"emul",    { 2, "", GEN_TO_REG,        0x47} },
00159   {"umulw",   { 2, "", GEN_TO_REG,        0x46} },
00160   {"divw",    { 2, "", GEN_TO_REG,        0x48} },
00161   {"ediv",    { 2, "", GEN_TO_REG,        0x4a} },
00162   {"rdivw",   { 2, "", GEN_TO_REG,        0x4b} },
00163   {"udivw",   { 2, "", GEN_TO_REG,        0x49} },
00164   {"modw",    { 2, "", GEN_TO_REG,        0x4c} },
00165   {"umodw",   { 2, "", GEN_TO_REG,        0x4d} },
00166 
00167 
00168   {"addf",    { 2, "", 1,                 0x50} },
00169   {"addd",    { 2, "", 1,                 0x51} },
00170   {"subf",    { 2, "", 1,                 0x52} },
00171   {"subd",    { 2, "", 1,                 0x53} },
00172   {"mulf",    { 2, "", 1,                 0x56} },
00173   {"muld",    { 2, "", 1,                 0x57} },
00174   {"divf",    { 2, "", 1,                 0x58} },
00175   {"divd",    { 2, "", 1,                 0x59} },
00176 
00177 
00178   {"cmpb",    { 2, "", UNKNOWN,           0x61} },
00179   {"cmph",    { 2, "", UNKNOWN,           0x62} },
00180   {"cmpw",    { 2, "", UNKNOWN,           0x60} },
00181   {"ucmpb",   { 2, "", UNKNOWN,           0x66} },
00182   /* WHY no "ucmph"??? */
00183   {"ucmpw",   { 2, "", UNKNOWN,           0x65} },
00184   {"xchw",    { 2, "", UNKNOWN,           0x0f} },
00185 
00186 
00187   {"andw",    { 2, "", GEN_TO_REG,        0x30} },
00188   {"orw",     { 2, "", GEN_TO_REG,        0x31} },
00189   {"xorw",    { 2, "", GEN_TO_REG,        0x32} },
00190   {"bicw",    { 2, "", GEN_TO_REG,        0x33} },
00191   {"lshlw",   { 2, "", GEN_TO_REG,        0x38} },
00192   {"ashlw",   { 2, "", GEN_TO_REG,        0x3a} },
00193   {"ashll",   { 2, "", GEN_TO_REG,        0x3c} },
00194   {"ashrw",   { 2, "", GEN_TO_REG,        0x3b} },
00195   {"ashrl",   { 2, "", GEN_TO_REG,        0x3d} },
00196   {"rotlw",   { 2, "", GEN_TO_REG,        0x3e} },
00197   {"rotrw",   { 2, "", GEN_TO_REG,        0x3f} },
00198 
00199   /* push and pop insns are "going away next release". */
00200   {"pushw",   { 2, "", GEN_TO_REG,        0x0c} },
00201   {"popw",    { 2, "", (0x1|0x8|0x10),    0x0d} },
00202   {"pusha",   { 2, "", (0x8|0x10),        0x0e} },
00203 
00204   {"bitsw",   { 2, "", UNKNOWN,           0x35} },
00205   {"bitcw",   { 2, "", UNKNOWN,           0x36} },
00206   /* some kind of ibra/dbra insns??*/
00207   {"icmpw",   { 2, "", UNKNOWN,           0x67} },
00208   {"dcmpw",   { 2, "", (1|4|0x20|0x80|0x400|0x1000),    0x69} },/*FIXME*/
00209   {"acmpw",   { 2, "", 1,                 0x6b} },
00210 
00211   /* Call is written as a 1-op insn, but is always (dis)assembled as a 2-op
00212      insn with a 2nd op of tr14.   The assembler will have to grok this.  */
00213   {"call",    { 2, "", GEN_TO_REG,        0x04} },
00214   {"call",    { 1, "", GEN_TO_REG,        0x04} },
00215 
00216   {"callk",   { 1, "", UNKNOWN,           0x06} },/* system call?*/
00217   /* Ret is usually written as a 0-op insn, but gets disassembled as a
00218      1-op insn. The operand is always tr15. */
00219   {"ret",     { 0, "", UNKNOWN,           0x09} },
00220   {"ret",     { 1, "", UNKNOWN,           0x09} },
00221   {"adsf",    { 2, "", (1|2|4),           0x08} },
00222   {"retd",    { 2, "", UNKNOWN,           0x0a} },
00223   {"btc",     { 2, "", UNKNOWN,           0x01} },
00224   {"bfc",     { 2, "", UNKNOWN,           0x02} },
00225   /* Careful: halt is 0x00000000. Jump must have some other (mode?)bit set?? */
00226   {"jump",    { 1, "", UNKNOWN,           0x00} },
00227   {"btp",     { 2, "", UNKNOWN,           0xf00} },
00228   /* read control-stack pointer is another 1-or-2 operand insn. */
00229   {"rcsp",    { 2, "", UNKNOWN,           0x01f} },
00230   {"rcsp",    { 1, "", UNKNOWN,           0x01f} }
00231 };
00232 
00233 /* end: pyramid.opcode.h */
00234 /* One day I will have to take the time to find out what operands
00235    are valid for these insns, and guess at what they mean.
00236 
00237    I can't imagine what the "I???" insns (iglob, etc) do.
00238 
00239    the arithmetic-sounding insns ending in "p" sound awfully like BCD
00240    arithmetic insns:
00241        dshlp -> Decimal SHift Left Packed
00242        dshrp -> Decimal SHift Right Packed
00243    and cvtlp would be convert long to packed.
00244    I have no idea how the operands are interpreted; but having them be
00245    a long register with (address, length) of an in-memory packed BCD operand
00246    would not be surprising.
00247    They are unlikely to be a packed bcd string: 64 bits of long give
00248    is only 15 digits+sign, which isn't enough for COBOL.
00249  */ 
00250 #if 0
00251   {"wcsp",    { 2, "", UNKNOWN,           0x00} }, /*write csp?*/
00252   /* The OSx Operating System Porting Guide claims SSL does things
00253      with tr12 (a register reserved to it) to do with static block-structure
00254      references.  SSL=Set Static Link?  It's "Going away next release". */
00255   {"ssl",     { 2, "", UNKNOWN,           0x00} },
00256   {"ccmps",   { 2, "", UNKNOWN,           0x00} },
00257   {"lcd",     { 2, "", UNKNOWN,           0x00} },
00258   {"uemul",   { 2, "", UNKNOWN,           0x00} }, /*unsigned emul*/
00259   {"srf",     { 2, "", UNKNOWN,           0x00} }, /*Gidget time???*/
00260   {"mnegp",   { 2, "", UNKNOWN,           0x00} }, /move-neg phys?*/
00261   {"ldp",     { 2, "", UNKNOWN,           0x00} }, /*load phys?*/
00262   {"ldti",    { 2, "", UNKNOWN,           0x00} },
00263   {"ldb",     { 2, "", UNKNOWN,           0x00} },
00264   {"stp",     { 2, "", UNKNOWN,           0x00} },
00265   {"stti",    { 2, "", UNKNOWN,           0x00} },
00266   {"stb",     { 2, "", UNKNOWN,           0x00} },
00267   {"stu",     { 2, "", UNKNOWN,           0x00} },
00268   {"addp",    { 2, "", UNKNOWN,           0x00} },
00269   {"subp",    { 2, "", UNKNOWN,           0x00} },
00270   {"mulp",    { 2, "", UNKNOWN,           0x00} },
00271   {"divp",    { 2, "", UNKNOWN,           0x00} },
00272   {"dshlp",   { 2, "", UNKNOWN,           0x00} },  /* dec shl packed? */
00273   {"dshrp",   { 2, "", UNKNOWN,           0x00} }, /* dec shr packed? */
00274   {"movs",    { 2, "", UNKNOWN,           0x00} }, /*move (string?)?*/
00275   {"cmpp",    { 2, "", UNKNOWN,           0x00} }, /* cmp phys?*/
00276   {"cmps",    { 2, "", UNKNOWN,           0x00} }, /* cmp (string?)?*/
00277   {"cvtlp",   { 2, "", UNKNOWN,           0x00} }, /* cvt long to p??*/
00278   {"cvtpl",   { 2, "", UNKNOWN,           0x00} }, /* cvt p to l??*/
00279   {"dintr",   { 2, "", UNKNOWN,           0x00} }, /* ?? intr ?*/
00280   {"rphysw",  { 2, "", UNKNOWN,           0x00} }, /* read phys word?*/
00281   {"wphysw",  { 2, "", UNKNOWN,           0x00} }, /* write phys word?*/
00282   {"cmovs",   { 2, "", UNKNOWN,           0x00} },
00283   {"rsubw",   { 2, "", UNKNOWN,           0x00} },
00284   {"bicpsw",  { 2, "", UNKNOWN,           0x00} }, /* clr bit in psw? */
00285   {"bispsw",  { 2, "", UNKNOWN,           0x00} }, /* set bit in psw? */
00286   {"eio",     { 2, "", UNKNOWN,           0x00} }, /* ?? ?io ? */
00287   {"callp",   { 2, "", UNKNOWN,           0x00} }, /* call phys?*/
00288   {"callr",   { 2, "", UNKNOWN,           0x00} },
00289   {"lpcxt",   { 2, "", UNKNOWN,           0x00} }, /*load proc context*/
00290   {"rei",     { 2, "", UNKNOWN,           0x00} }, /*ret from intrpt*/
00291   {"rport",   { 2, "", UNKNOWN,           0x00} }, /*read-port?*/
00292   {"rtod",    { 2, "", UNKNOWN,           0x00} }, /*read-time-of-day?*/
00293   {"ssi",     { 2, "", UNKNOWN,           0x00} },
00294   {"vtpa",    { 2, "", UNKNOWN,           0x00} }, /*virt-to-phys-addr?*/
00295   {"wicl",    { 2, "", UNKNOWN,           0x00} }, /* write icl ? */
00296   {"wport",   { 2, "", UNKNOWN,           0x00} }, /*write-port?*/
00297   {"wtod",    { 2, "", UNKNOWN,           0x00} }, /*write-time-of-day?*/
00298   {"flic",    { 2, "", UNKNOWN,           0x00} },
00299   {"iglob",   { 2, "", UNKNOWN,           0x00} }, /* I global? */
00300   {"iphys",   { 2, "", UNKNOWN,           0x00} }, /* I physical? */
00301   {"ipid",    { 2, "", UNKNOWN,           0x00} }, /* I pid? */
00302   {"ivect",   { 2, "", UNKNOWN,           0x00} }, /* I vector? */
00303   {"lamst",   { 2, "", UNKNOWN,           0x00} },
00304   {"tio",     { 2, "", UNKNOWN,           0x00} },
00305 #endif