Back to index

cell-binutils  2.17cvs20070401
v850-opc.c
Go to the documentation of this file.
00001 /* Assemble V850 instructions.
00002    Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005
00003    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 of the License, or
00008    (at your option) 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, Boston,
00018    MA 02110-1301, USA.  */
00019 
00020 #include "sysdep.h"
00021 #include "opcode/v850.h"
00022 #include <stdio.h>
00023 #include "opintl.h"
00024 
00025 /* Regular opcodes.  */
00026 #define OP(x)        ((x & 0x3f) << 5)
00027 #define OP_MASK             OP (0x3f)
00028 
00029 /* Conditional branch opcodes.  */
00030 #define BOP(x)              ((0x0b << 7) | (x & 0x0f))
00031 #define BOP_MASK     ((0x0f << 7) | 0x0f)
00032 
00033 /* One-word opcodes.  */
00034 #define one(x)              ((unsigned int) (x))
00035 
00036 /* Two-word opcodes.  */
00037 #define two(x,y)     ((unsigned int) (x) | ((unsigned int) (y) << 16))
00038 
00039 /* The functions used to insert and extract complicated operands.  */
00040 
00041 /* Note: There is a conspiracy between these functions and
00042    v850_insert_operand() in gas/config/tc-v850.c.  Error messages
00043    containing the string 'out of range' will be ignored unless a
00044    specific command line option is given to GAS.  */
00045 
00046 static const char * not_valid    = N_ ("displacement value is not in range and is not aligned");
00047 static const char * out_of_range = N_ ("displacement value is out of range");
00048 static const char * not_aligned  = N_ ("displacement value is not aligned");
00049 
00050 static const char * immediate_out_of_range = N_ ("immediate value is out of range");
00051 
00052 static unsigned long
00053 insert_d9 (unsigned long insn, long value, const char ** errmsg)
00054 {
00055   if (value > 0xff || value < -0x100)
00056     {
00057       if ((value % 2) != 0)
00058        * errmsg = _("branch value not in range and to odd offset");
00059       else
00060        * errmsg = _("branch value out of range");
00061     }
00062   else if ((value % 2) != 0)
00063     * errmsg = _("branch to odd offset");
00064 
00065   return insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3);
00066 }
00067 
00068 static unsigned long
00069 extract_d9 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
00070 {
00071   unsigned long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3);
00072 
00073   if ((insn & 0x8000) != 0)
00074     ret -= 0x0200;
00075 
00076   return ret;
00077 }
00078 
00079 static unsigned long
00080 insert_d22 (unsigned long insn, long value, const char ** errmsg)
00081 {
00082   if (value > 0x1fffff || value < -0x200000)
00083     {
00084       if ((value % 2) != 0)
00085        * errmsg = _("branch value not in range and to an odd offset");
00086       else
00087        * errmsg = _("branch value out of range");
00088     }
00089   else if ((value % 2) != 0)
00090     * errmsg = _("branch to odd offset");
00091 
00092   return insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16);
00093 }
00094 
00095 static unsigned long
00096 extract_d22 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
00097 {
00098   signed long ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16);
00099 
00100   return (unsigned long) ((ret << 10) >> 10);
00101 }
00102 
00103 static unsigned long
00104 insert_d16_15 (unsigned long insn, long value, const char ** errmsg)
00105 {
00106   if (value > 0x7fff || value < -0x8000)
00107     {
00108       if ((value % 2) != 0)
00109        * errmsg = _(not_valid);
00110       else
00111        * errmsg = _(out_of_range);
00112     }
00113   else if ((value % 2) != 0)
00114     * errmsg = _(not_aligned);
00115 
00116   return insn | ((value & 0xfffe) << 16);
00117 }
00118 
00119 static unsigned long
00120 extract_d16_15 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
00121 {
00122   signed long ret = (insn & 0xfffe0000);
00123 
00124   return ret >> 16;
00125 }
00126 
00127 static unsigned long
00128 insert_d8_7 (unsigned long insn, long value, const char ** errmsg)
00129 {
00130   if (value > 0xff || value < 0)
00131     {
00132       if ((value % 2) != 0)
00133        * errmsg = _(not_valid);
00134       else
00135        * errmsg = _(out_of_range);
00136     }
00137   else if ((value % 2) != 0)
00138     * errmsg = _(not_aligned);
00139 
00140   value >>= 1;
00141 
00142   return insn | (value & 0x7f);
00143 }
00144 
00145 static unsigned long
00146 extract_d8_7 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
00147 {
00148   unsigned long ret = (insn & 0x7f);
00149 
00150   return ret << 1;
00151 }
00152 
00153 static unsigned long
00154 insert_d8_6 (unsigned long insn, long value, const char ** errmsg)
00155 {
00156   if (value > 0xff || value < 0)
00157     {
00158       if ((value % 4) != 0)
00159        *errmsg = _(not_valid);
00160       else
00161        * errmsg = _(out_of_range);
00162     }
00163   else if ((value % 4) != 0)
00164     * errmsg = _(not_aligned);
00165 
00166   value >>= 1;
00167 
00168   return insn | (value & 0x7e);
00169 }
00170 
00171 static unsigned long
00172 extract_d8_6 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
00173 {
00174   unsigned long ret = (insn & 0x7e);
00175 
00176   return ret << 1;
00177 }
00178 
00179 static unsigned long
00180 insert_d5_4 (unsigned long insn, long value, const char ** errmsg)
00181 {
00182   if (value > 0x1f || value < 0)
00183     {
00184       if (value & 1)
00185        * errmsg = _(not_valid);
00186       else
00187        *errmsg = _(out_of_range);
00188     }
00189   else if (value & 1)
00190     * errmsg = _(not_aligned);
00191 
00192   value >>= 1;
00193 
00194   return insn | (value & 0x0f);
00195 }
00196 
00197 static unsigned long
00198 extract_d5_4 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
00199 {
00200   unsigned long ret = (insn & 0x0f);
00201 
00202   return ret << 1;
00203 }
00204 
00205 static unsigned long
00206 insert_d16_16 (unsigned long insn, signed long value, const char ** errmsg)
00207 {
00208   if (value > 0x7fff || value < -0x8000)
00209     * errmsg = _(out_of_range);
00210 
00211   return insn | ((value & 0xfffe) << 16) | ((value & 1) << 5);
00212 }
00213 
00214 static unsigned long
00215 extract_d16_16 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
00216 {
00217   signed long ret = insn & 0xfffe0000;
00218 
00219   ret >>= 16;
00220 
00221   ret |= ((insn & 0x20) >> 5);
00222 
00223   return ret;
00224 }
00225 
00226 static unsigned long
00227 insert_i9 (unsigned long insn, signed long value, const char ** errmsg)
00228 {
00229   if (value > 0xff || value < -0x100)
00230     * errmsg = _(immediate_out_of_range);
00231 
00232   return insn | ((value & 0x1e0) << 13) | (value & 0x1f);
00233 }
00234 
00235 static unsigned long
00236 extract_i9 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
00237 {
00238   signed long ret = insn & 0x003c0000;
00239 
00240   ret <<= 10;
00241   ret >>= 23;
00242 
00243   ret |= (insn & 0x1f);
00244 
00245   return ret;
00246 }
00247 
00248 static unsigned long
00249 insert_u9 (unsigned long insn, long v, const char ** errmsg)
00250 {
00251   unsigned long value = (unsigned long) v;
00252 
00253   if (value > 0x1ff)
00254     * errmsg = _(immediate_out_of_range);
00255 
00256   return insn | ((value & 0x1e0) << 13) | (value & 0x1f);
00257 }
00258 
00259 static unsigned long
00260 extract_u9 (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
00261 {
00262   unsigned long ret = insn & 0x003c0000;
00263 
00264   ret >>= 13;
00265 
00266   ret |= (insn & 0x1f);
00267 
00268   return ret;
00269 }
00270 
00271 static unsigned long
00272 insert_spe (unsigned long insn, long v, const char ** errmsg)
00273 {
00274   unsigned long value = (unsigned long) v;
00275 
00276   if (value != 3)
00277     * errmsg = _("invalid register for stack adjustment");
00278 
00279   return insn & (~ 0x180000);
00280 }
00281 
00282 static unsigned long
00283 extract_spe (unsigned long insn ATTRIBUTE_UNUSED,
00284             int * invalid ATTRIBUTE_UNUSED)
00285 {
00286   return 3;
00287 }
00288 
00289 static unsigned long
00290 insert_i5div (unsigned long insn, long v, const char ** errmsg)
00291 {
00292   unsigned long value = (unsigned long) v;
00293 
00294   if (value > 0x1ff)
00295     {
00296       if (value & 1)
00297        * errmsg = _("immediate value not in range and not even");
00298       else
00299        * errmsg = _(immediate_out_of_range);
00300     }
00301   else if (value & 1)
00302     * errmsg = _("immediate value must be even");
00303 
00304   value = 32 - value;
00305 
00306   return insn | ((value & 0x1e) << 17);
00307 }
00308 
00309 static unsigned long
00310 extract_i5div (unsigned long insn, int * invalid ATTRIBUTE_UNUSED)
00311 {
00312   unsigned long ret = insn & 0x3c0000;
00313 
00314   ret >>= 17;
00315 
00316   ret = 32 - ret;
00317 
00318   return ret;
00319 }
00320 
00321 
00322 /* Warning: code in gas/config/tc-v850.c examines the contents of this array.
00323    If you change any of the values here, be sure to look for side effects in
00324    that code.  */
00325 const struct v850_operand v850_operands[] =
00326 {
00327 #define UNUSED       0
00328   { 0, 0, NULL, NULL, 0 },
00329 
00330 /* The R1 field in a format 1, 6, 7, or 9 insn.  */
00331 #define R1    (UNUSED + 1)
00332   { 5, 0, NULL, NULL, V850_OPERAND_REG },
00333 
00334 /* As above, but register 0 is not allowed.  */
00335 #define R1_NOTR0 (R1 + 1)
00336   { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
00337 
00338 /* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn.  */
00339 #define R2    (R1_NOTR0 + 1)
00340   { 5, 11, NULL, NULL, V850_OPERAND_REG },
00341 
00342 /* As above, but register 0 is not allowed.  */
00343 #define R2_NOTR0 (R2 + 1)
00344   { 5, 11, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
00345 
00346 /* The imm5 field in a format 2 insn.  */
00347 #define I5    (R2_NOTR0 + 1)
00348   { 5, 0, NULL, NULL, V850_OPERAND_SIGNED },
00349 
00350 /* The unsigned imm5 field in a format 2 insn.  */
00351 #define I5U   (I5 + 1)
00352   { 5, 0, NULL, NULL, 0 },
00353 
00354 /* The imm16 field in a format 6 insn.  */
00355 #define I16   (I5U + 1)
00356   { 16, 16, NULL, NULL, V850_OPERAND_SIGNED },
00357 
00358 /* The signed disp7 field in a format 4 insn.  */
00359 #define D7    (I16 + 1)
00360   { 7, 0, NULL, NULL, 0},
00361 
00362 /* The disp16 field in a format 6 insn.  */
00363 #define D16_15       (D7 + 1)
00364   { 15, 17, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED },
00365 
00366 /* The 3 bit immediate field in format 8 insn.  */
00367 #define B3    (D16_15 + 1)
00368   { 3, 11, NULL, NULL, 0 },
00369 
00370 /* The 4 bit condition code in a setf instruction */
00371 #define CCCC  (B3 + 1)
00372   { 4, 0, NULL, NULL, V850_OPERAND_CC },
00373 
00374 /* The unsigned DISP8 field in a format 4 insn.  */
00375 #define D8_7  (CCCC + 1)
00376   { 7, 0, insert_d8_7, extract_d8_7, 0 },
00377 
00378 /* The unsigned DISP8 field in a format 4 insn.  */
00379 #define D8_6  (D8_7 + 1)
00380   { 6, 1, insert_d8_6, extract_d8_6, 0 },
00381 
00382 /* System register operands.  */
00383 #define SR1   (D8_6 + 1)
00384   { 5, 0, NULL, NULL, V850_OPERAND_SRG },
00385 
00386 /* EP Register.  */
00387 #define EP    (SR1 + 1)
00388   { 0, 0, NULL, NULL, V850_OPERAND_EP },
00389 
00390 /* The imm16 field (unsigned) in a format 6 insn.  */
00391 #define I16U  (EP + 1)
00392   { 16, 16, NULL, NULL, 0},
00393 
00394 /* The R2 field as a system register.  */
00395 #define SR2   (I16U + 1)
00396   { 5, 11, NULL, NULL, V850_OPERAND_SRG },
00397 
00398 /* The disp16 field in a format 8 insn.  */
00399 #define D16   (SR2 + 1)
00400   { 16, 16, NULL, NULL, V850_OPERAND_SIGNED },
00401 
00402 /* The DISP9 field in a format 3 insn, relaxable.  */
00403 #define D9_RELAX     (D16 + 1)
00404   { 9, 0, insert_d9, extract_d9, V850_OPERAND_RELAX | V850_OPERAND_SIGNED | V850_OPERAND_DISP },
00405 
00406 /* The DISP22 field in a format 4 insn, relaxable.
00407    This _must_ follow D9_RELAX; the assembler assumes that the longer
00408    version immediately follows the shorter version for relaxing.  */
00409 #define D22   (D9_RELAX + 1)
00410   { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED | V850_OPERAND_DISP },
00411 
00412 /* The signed disp4 field in a format 4 insn.  */
00413 #define D4    (D22 + 1)
00414   { 4, 0, NULL, NULL, 0},
00415 
00416 /* The unsigned disp5 field in a format 4 insn.  */
00417 #define D5_4  (D4 + 1)
00418   { 4, 0, insert_d5_4, extract_d5_4, 0 },
00419 
00420 /* The disp16 field in an format 7 unsigned byte load insn.  */
00421 #define D16_16       (D5_4 + 1)
00422   { -1, 0xfffe0020, insert_d16_16, extract_d16_16, 0 },
00423 
00424 /* Third register in conditional moves.  */
00425 #define R3    (D16_16 + 1)
00426   { 5, 27, NULL, NULL, V850_OPERAND_REG },
00427 
00428 /* Condition code in conditional moves.  */
00429 #define MOVCC (R3 + 1)
00430   { 4, 17, NULL, NULL, V850_OPERAND_CC },
00431 
00432 /* The imm9 field in a multiply word.  */
00433 #define I9    (MOVCC + 1)
00434   { 9, 0, insert_i9, extract_i9, V850_OPERAND_SIGNED },
00435 
00436 /* The unsigned imm9 field in a multiply word.  */
00437 #define U9    (I9 + 1)
00438   { 9, 0, insert_u9, extract_u9, 0 },
00439 
00440 /* A list of registers in a prepare/dispose instruction.  */
00441 #define LIST12       (U9 + 1)
00442   { -1, 0xffe00001, NULL, NULL, V850E_PUSH_POP },
00443 
00444 /* The IMM6 field in a call instruction.  */
00445 #define I6    (LIST12 + 1)
00446   { 6, 0, NULL, NULL, 0 },
00447 
00448 /* The 16 bit immediate following a 32 bit instruction.  */
00449 #define IMM16 (I6 + 1)
00450   { 16, 16, NULL, NULL, V850_OPERAND_SIGNED | V850E_IMMEDIATE16 },
00451 
00452 /* The 32 bit immediate following a 32 bit instruction.  */
00453 #define IMM32 (IMM16 + 1)
00454   { 0, 0, NULL, NULL, V850E_IMMEDIATE32 },
00455 
00456 /* The imm5 field in a push/pop instruction.  */
00457 #define IMM5  (IMM32 + 1)
00458   { 5, 1, NULL, NULL, 0 },
00459 
00460 /* Reg2 in dispose instruction.  */
00461 #define R2DISPOSE    (IMM5 + 1)
00462   { 5, 16, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 },
00463 
00464 /* Stack pointer in prepare instruction.  */
00465 #define SP    (R2DISPOSE + 1)
00466   { 2, 19, insert_spe, extract_spe, V850_OPERAND_REG },
00467 
00468 /* The IMM5 field in a divide N step instruction.  */
00469 #define I5DIV (SP + 1)
00470   { 9, 0, insert_i5div, extract_i5div, V850_OPERAND_SIGNED },
00471 
00472   /* The list of registers in a PUSHMH/POPMH instruction.  */
00473 #define LIST18_H (I5DIV + 1)
00474   { -1, 0xfff8000f, NULL, NULL, V850E_PUSH_POP },
00475 
00476   /* The list of registers in a PUSHML/POPML instruction.  */
00477 #define LIST18_L (LIST18_H + 1)
00478   /* The setting of the 4th bit is a flag to disassmble() in v850-dis.c.  */
00479   { -1, 0xfff8001f, NULL, NULL, V850E_PUSH_POP },
00480 };
00481 
00482 
00483 /* Reg - Reg instruction format (Format I).  */
00484 #define IF1   {R1, R2}
00485 
00486 /* Imm - Reg instruction format (Format II).  */
00487 #define IF2   {I5, R2}
00488 
00489 /* Conditional branch instruction format (Format III).  */
00490 #define IF3   {D9_RELAX}
00491 
00492 /* 3 operand instruction (Format VI).  */
00493 #define IF6   {I16, R1, R2}
00494 
00495 /* 3 operand instruction (Format VI).  */
00496 #define IF6U  {I16U, R1, R2}
00497 
00498 
00499 
00500 /* The opcode table.
00501 
00502    The format of the opcode table is:
00503 
00504    NAME              OPCODE               MASK                 { OPERANDS }     MEMOP    PROCESSOR
00505 
00506    NAME is the name of the instruction.
00507    OPCODE is the instruction opcode.
00508    MASK is the opcode mask; this is used to tell the disassembler
00509      which bits in the actual opcode must match OPCODE.
00510    OPERANDS is the list of operands.
00511    MEMOP specifies which operand (if any) is a memory operand.
00512    PROCESSORS specifies which CPU(s) support the opcode.
00513 
00514    The disassembler reads the table in order and prints the first
00515    instruction which matches, so this table is sorted to put more
00516    specific instructions before more general instructions.  It is also
00517    sorted by major opcode.
00518 
00519    The table is also sorted by name.  This is used by the assembler.
00520    When parsing an instruction the assembler finds the first occurance
00521    of the name of the instruciton in this table and then attempts to
00522    match the instruction's arguments with description of the operands
00523    associated with the entry it has just found in this table.  If the
00524    match fails the assembler looks at the next entry in this table.
00525    If that entry has the same name as the previous entry, then it
00526    tries to match the instruction against that entry and so on.  This
00527    is how the assembler copes with multiple, different formats of the
00528    same instruction.  */
00529 
00530 const struct v850_opcode v850_opcodes[] =
00531 {
00532 { "breakpoint",      0xffff,                     0xffff,                     {UNUSED},            0, PROCESSOR_ALL },
00533 { "dbtrap",   one (0xf840),        one (0xffff),        {UNUSED},            0, PROCESSOR_V850E1 },
00534 
00535 { "jmp",      one (0x0060),        one (0xffe0),        {R1},                1, PROCESSOR_ALL },
00536 
00537 /* Load/store instructions.  */
00538 { "sld.bu",     one (0x0060),             one (0x07f0),               {D4,   EP,   R2_NOTR0},     1, PROCESSOR_V850E1 },
00539 { "sld.bu",     one (0x0060),             one (0x07f0),               {D4,   EP,   R2_NOTR0},     1, PROCESSOR_V850E },
00540 
00541 { "sld.hu",     one (0x0070),             one (0x07f0),               {D5_4, EP,   R2_NOTR0},     1, PROCESSOR_V850E1 },
00542 { "sld.hu",     one (0x0070),             one (0x07f0),               {D5_4, EP,   R2_NOTR0},     1, PROCESSOR_V850E },
00543 
00544 { "sld.b",    one (0x0300),        one (0x0780),        {D7,   EP,   R2},    1, PROCESSOR_V850E1 },
00545 { "sld.b",    one (0x0300),        one (0x0780),        {D7,   EP,   R2},    1, PROCESSOR_V850E },
00546 { "sld.b",    one (0x0300),        one (0x0780),        {D7,   EP,   R2},    1, PROCESSOR_V850 },
00547 
00548 { "sld.h",    one (0x0400),        one (0x0780),        {D8_7, EP,   R2},    1, PROCESSOR_V850E1 },
00549 { "sld.h",    one (0x0400),        one (0x0780),        {D8_7, EP,   R2},    1, PROCESSOR_V850E },
00550 { "sld.h",    one (0x0400),        one (0x0780),        {D8_7, EP,   R2},    1, PROCESSOR_V850 },
00551 { "sld.w",    one (0x0500),        one (0x0781),        {D8_6, EP,   R2},    1, PROCESSOR_ALL },
00552 { "sst.b",    one (0x0380),        one (0x0780),        {R2,   D7,   EP},    2, PROCESSOR_ALL },
00553 { "sst.h",    one (0x0480),        one (0x0780),        {R2,   D8_7, EP},    2, PROCESSOR_ALL },
00554 { "sst.w",    one (0x0501),        one (0x0781),        {R2,   D8_6, EP},    2, PROCESSOR_ALL },
00555 
00556 { "prepare",    two (0x0780, 0x0003),     two (0xffc0, 0x001f),       {LIST12, IMM5, SP},  0, PROCESSOR_NOT_V850 },
00557 { "prepare",    two (0x0780, 0x000b),     two (0xffc0, 0x001f),       {LIST12, IMM5, IMM16},      0, PROCESSOR_NOT_V850 },
00558 { "prepare",    two (0x0780, 0x0013),     two (0xffc0, 0x001f),       {LIST12, IMM5, IMM16},      0, PROCESSOR_NOT_V850 },
00559 { "prepare",    two (0x0780, 0x001b),     two (0xffc0, 0x001f),       {LIST12, IMM5, IMM32},      0, PROCESSOR_NOT_V850 },
00560 { "prepare",    two (0x0780, 0x0001),     two (0xffc0, 0x001f),       {LIST12, IMM5},      0, PROCESSOR_NOT_V850 },
00561 { "dispose",  one (0x0640),           one (0xffc0),            {IMM5, LIST12, R2DISPOSE},0, PROCESSOR_NOT_V850 },
00562 { "dispose",  two (0x0640, 0x0000),   two (0xffc0, 0x001f),    {IMM5, LIST12},      0, PROCESSOR_NOT_V850 },
00563 
00564 { "ld.b",     two (0x0700, 0x0000),       two (0x07e0, 0x0000),       {D16, R1, R2},              1, PROCESSOR_ALL },
00565 { "ld.h",     two (0x0720, 0x0000),       two (0x07e0, 0x0001),       {D16_15, R1, R2},    1, PROCESSOR_ALL },
00566 { "ld.w",     two (0x0720, 0x0001),       two (0x07e0, 0x0001),       {D16_15, R1, R2},    1, PROCESSOR_ALL },
00567 { "ld.bu",    two (0x0780, 0x0001),   two (0x07c0, 0x0001),    {D16_16, R1, R2_NOTR0},     1, PROCESSOR_NOT_V850 },
00568 { "ld.hu",    two (0x07e0, 0x0001),   two (0x07e0, 0x0001),    {D16_15, R1, R2_NOTR0},     1, PROCESSOR_NOT_V850 },
00569 { "st.b",     two (0x0740, 0x0000),       two (0x07e0, 0x0000),       {R2, D16, R1},              2, PROCESSOR_ALL },
00570 { "st.h",     two (0x0760, 0x0000),       two (0x07e0, 0x0001),       {R2, D16_15, R1},    2, PROCESSOR_ALL },
00571 { "st.w",     two (0x0760, 0x0001),       two (0x07e0, 0x0001),       {R2, D16_15, R1},    2, PROCESSOR_ALL },
00572 
00573 /* Byte swap/extend instructions.  */
00574 { "zxb",      one (0x0080),        one (0xffe0),               {R1_NOTR0},          0, PROCESSOR_NOT_V850 },
00575 { "zxh",      one (0x00c0),        one (0xffe0),               {R1_NOTR0},          0, PROCESSOR_NOT_V850 },
00576 { "sxb",      one (0x00a0),        one (0xffe0),               {R1_NOTR0},          0, PROCESSOR_NOT_V850 },
00577 { "sxh",      one (0x00e0),        one (0xffe0),        {R1_NOTR0},          0, PROCESSOR_NOT_V850 },
00578 { "bsh",      two (0x07e0, 0x0342),       two (0x07ff, 0x07ff),       {R2, R3},            0, PROCESSOR_NOT_V850 },
00579 { "bsw",      two (0x07e0, 0x0340),       two (0x07ff, 0x07ff),       {R2, R3},            0, PROCESSOR_NOT_V850 },
00580 { "hsw",      two (0x07e0, 0x0344),       two (0x07ff, 0x07ff),       {R2, R3},            0, PROCESSOR_NOT_V850 },
00581 
00582 /* Jump table instructions.  */
00583 { "switch",   one (0x0040),        one (0xffe0),               {R1},                1, PROCESSOR_NOT_V850 },
00584 { "callt",    one (0x0200),        one (0xffc0),               {I6},                0, PROCESSOR_NOT_V850 },
00585 { "ctret",    two (0x07e0, 0x0144),       two (0xffff, 0xffff),       {0},                 0, PROCESSOR_NOT_V850 },
00586 
00587 /* Arithmetic operation instructions.  */
00588 { "setf",     two (0x07e0, 0x0000),       two (0x07f0, 0xffff),       {CCCC, R2},          0, PROCESSOR_ALL },
00589 { "cmov",     two (0x07e0, 0x0320),       two (0x07e0, 0x07e1),       {MOVCC, R1, R2, R3},        0, PROCESSOR_NOT_V850 },
00590 { "cmov",     two (0x07e0, 0x0300),       two (0x07e0, 0x07e1),       {MOVCC, I5, R2, R3},        0, PROCESSOR_NOT_V850 },
00591 
00592 { "mul",      two (0x07e0, 0x0220),       two (0x07e0, 0x07ff),       {R1, R2, R3},               0, PROCESSOR_NOT_V850 },
00593 { "mul",      two (0x07e0, 0x0240),       two (0x07e0, 0x07c3),       {I9, R2, R3},               0, PROCESSOR_NOT_V850 },
00594 { "mulu",     two (0x07e0, 0x0222),       two (0x07e0, 0x07ff),       {R1, R2, R3},               0, PROCESSOR_NOT_V850 },
00595 { "mulu",     two (0x07e0, 0x0242),       two (0x07e0, 0x07c3),       {U9, R2, R3},               0, PROCESSOR_NOT_V850 },
00596 
00597 { "div",      two (0x07e0, 0x02c0),       two (0x07e0, 0x07ff),       {R1, R2, R3},               0, PROCESSOR_NOT_V850 },
00598 { "divu",     two (0x07e0, 0x02c2),       two (0x07e0, 0x07ff),       {R1, R2, R3},               0, PROCESSOR_NOT_V850 },
00599 { "divhu",    two (0x07e0, 0x0282),   two (0x07e0, 0x07ff),    {R1, R2, R3},               0, PROCESSOR_NOT_V850 },
00600 { "divh",     two (0x07e0, 0x0280),   two (0x07e0, 0x07ff),    {R1, R2, R3},               0, PROCESSOR_NOT_V850 },
00601 { "divh",     OP  (0x02),          OP_MASK,             {R1, R2_NOTR0},             0, PROCESSOR_ALL },
00602 
00603 { "nop",      one (0x00),          one (0xffff),        {0},                 0, PROCESSOR_ALL },
00604 { "mov",      OP  (0x10),          OP_MASK,             {I5, R2_NOTR0},             0, PROCESSOR_ALL },
00605 { "mov",      one (0x0620),        one (0xffe0),        {IMM32, R1_NOTR0},   0, PROCESSOR_NOT_V850 },
00606 { "mov",        OP  (0x00),        OP_MASK,             {R1, R2_NOTR0},             0, PROCESSOR_ALL },
00607 { "movea",    OP  (0x31),          OP_MASK,             {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
00608 { "movhi",    OP  (0x32),          OP_MASK,             {I16U, R1, R2_NOTR0},       0, PROCESSOR_ALL },
00609 { "add",      OP  (0x0e),          OP_MASK,             IF1,                 0, PROCESSOR_ALL },
00610 { "add",      OP  (0x12),          OP_MASK,             IF2,                 0, PROCESSOR_ALL },
00611 { "addi",     OP  (0x30),          OP_MASK,             IF6,                 0, PROCESSOR_ALL },
00612 { "sub",      OP  (0x0d),          OP_MASK,             IF1,                 0, PROCESSOR_ALL },
00613 { "subr",     OP  (0x0c),          OP_MASK,             IF1,                 0, PROCESSOR_ALL },
00614 { "mulh",     OP  (0x17),          OP_MASK,             {I5, R2_NOTR0},             0, PROCESSOR_ALL },
00615 { "mulh",     OP  (0x07),          OP_MASK,             {R1, R2_NOTR0},             0, PROCESSOR_ALL },
00616 { "mulhi",    OP  (0x37),          OP_MASK,             {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
00617 { "cmp",      OP  (0x0f),          OP_MASK,             IF1,                 0, PROCESSOR_ALL },
00618 { "cmp",      OP  (0x13),          OP_MASK,             IF2,                 0, PROCESSOR_ALL },
00619 
00620 /* Saturated operation instructions.  */
00621 { "satadd",   OP (0x11),           OP_MASK,             {I5, R2_NOTR0},             0, PROCESSOR_ALL },
00622 { "satadd",   OP (0x06),           OP_MASK,             {R1, R2_NOTR0},             0, PROCESSOR_ALL },
00623 { "satsub",   OP (0x05),           OP_MASK,             {R1, R2_NOTR0},             0, PROCESSOR_ALL },
00624 { "satsubi",  OP (0x33),           OP_MASK,             {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL },
00625 { "satsubr",  OP (0x04),           OP_MASK,             {R1, R2_NOTR0},             0, PROCESSOR_ALL },
00626 
00627 /* Logical operation instructions.  */
00628 { "tst",      OP (0x0b),           OP_MASK,             IF1,                 0, PROCESSOR_ALL },
00629 { "or",              OP (0x08),           OP_MASK,             IF1,                 0, PROCESSOR_ALL },
00630 { "ori",      OP (0x34),           OP_MASK,             IF6U,                0, PROCESSOR_ALL },
00631 { "and",      OP (0x0a),           OP_MASK,             IF1,                 0, PROCESSOR_ALL },
00632 { "andi",     OP (0x36),           OP_MASK,             IF6U,                0, PROCESSOR_ALL },
00633 { "xor",      OP (0x09),           OP_MASK,             IF1,                 0, PROCESSOR_ALL },
00634 { "xori",     OP (0x35),           OP_MASK,             IF6U,                0, PROCESSOR_ALL },
00635 { "not",      OP (0x01),           OP_MASK,             IF1,                 0, PROCESSOR_ALL },
00636 { "sar",      OP (0x15),           OP_MASK,             {I5U, R2},           0, PROCESSOR_ALL },
00637 { "sar",      two (0x07e0, 0x00a0),       two (0x07e0, 0xffff),       {R1,  R2},           0, PROCESSOR_ALL },
00638 { "shl",      OP  (0x16),          OP_MASK,             {I5U, R2},           0, PROCESSOR_ALL },
00639 { "shl",      two (0x07e0, 0x00c0),       two (0x07e0, 0xffff),       {R1,  R2},           0, PROCESSOR_ALL },
00640 { "shr",      OP  (0x14),          OP_MASK,             {I5U, R2},           0, PROCESSOR_ALL },
00641 { "shr",      two (0x07e0, 0x0080),       two (0x07e0, 0xffff),       {R1,  R2},           0, PROCESSOR_ALL },
00642 { "sasf",       two (0x07e0, 0x0200),     two (0x07f0, 0xffff),       {CCCC, R2},          0, PROCESSOR_NOT_V850 },
00643 
00644 /* Branch instructions.  */
00645        /* Signed integer.  */
00646 { "bgt",      BOP (0xf),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00647 { "bge",      BOP (0xe),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00648 { "blt",      BOP (0x6),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00649 { "ble",      BOP (0x7),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00650        /* Unsigned integer.  */
00651 { "bh",              BOP (0xb),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00652 { "bnh",      BOP (0x3),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00653 { "bl",              BOP (0x1),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00654 { "bnl",      BOP (0x9),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00655        /* Common.  */
00656 { "be",              BOP (0x2),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00657 { "bne",      BOP (0xa),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00658        /* Others.  */
00659 { "bv",              BOP (0x0),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00660 { "bnv",      BOP (0x8),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00661 { "bn",              BOP (0x4),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00662 { "bp",              BOP (0xc),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00663 { "bc",              BOP (0x1),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00664 { "bnc",      BOP (0x9),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00665 { "bz",              BOP (0x2),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00666 { "bnz",      BOP (0xa),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00667 { "br",              BOP (0x5),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00668 { "bsa",      BOP (0xd),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00669 
00670 /* Branch macros.
00671 
00672    We use the short form in the opcode/mask fields.  The assembler
00673    will twiddle bits as necessary if the long form is needed.  */
00674 
00675        /* Signed integer.  */
00676 { "jgt",      BOP (0xf),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00677 { "jge",      BOP (0xe),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00678 { "jlt",      BOP (0x6),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00679 { "jle",      BOP (0x7),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00680        /* Unsigned integer.  */
00681 { "jh",              BOP (0xb),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00682 { "jnh",      BOP (0x3),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00683 { "jl",              BOP (0x1),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00684 { "jnl",      BOP (0x9),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00685        /* Common.  */
00686 { "je",              BOP (0x2),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00687 { "jne",      BOP (0xa),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00688        /* Others.  */
00689 { "jv",              BOP (0x0),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00690 { "jnv",      BOP (0x8),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00691 { "jn",              BOP (0x4),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00692 { "jp",              BOP (0xc),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00693 { "jc",              BOP (0x1),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00694 { "jnc",      BOP (0x9),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00695 { "jz",              BOP (0x2),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00696 { "jnz",      BOP (0xa),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00697 { "jsa",      BOP (0xd),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00698 { "jbr",      BOP (0x5),           BOP_MASK,            IF3,                 0, PROCESSOR_ALL },
00699 
00700 { "jr",              one (0x0780),        two (0xffc0, 0x0001),       {D22},                      0, PROCESSOR_ALL },
00701 { "jarl",     one (0x0780),        two (0x07c0, 0x0001),       {D22, R2},           0, PROCESSOR_ALL },
00702 
00703 /* Bit manipulation instructions.  */
00704 { "set1",     two (0x07c0, 0x0000),       two (0xc7e0, 0x0000),       {B3, D16, R1},              2, PROCESSOR_ALL },
00705 { "set1",     two (0x07e0, 0x00e0),       two (0x07e0, 0xffff),       {R2, R1},            2, PROCESSOR_NOT_V850 },
00706 { "not1",     two (0x47c0, 0x0000),       two (0xc7e0, 0x0000),       {B3, D16, R1},              2, PROCESSOR_ALL },
00707 { "not1",     two (0x07e0, 0x00e2),       two (0x07e0, 0xffff),       {R2, R1},            2, PROCESSOR_NOT_V850 },
00708 { "clr1",     two (0x87c0, 0x0000),       two (0xc7e0, 0x0000),       {B3, D16, R1},              2, PROCESSOR_ALL },
00709 { "clr1",     two (0x07e0, 0x00e4),       two (0x07e0, 0xffff),   {R2, R1},                2, PROCESSOR_NOT_V850 },
00710 { "tst1",     two (0xc7c0, 0x0000),       two (0xc7e0, 0x0000),       {B3, D16, R1},              2, PROCESSOR_ALL },
00711 { "tst1",     two (0x07e0, 0x00e6),       two (0x07e0, 0xffff),       {R2, R1},            2, PROCESSOR_NOT_V850 },
00712 
00713 /* Special instructions.  */
00714 { "di",              two (0x07e0, 0x0160),       two (0xffff, 0xffff),       {0},                 0, PROCESSOR_ALL },
00715 { "ei",              two (0x87e0, 0x0160),       two (0xffff, 0xffff),       {0},                 0, PROCESSOR_ALL },
00716 { "halt",     two (0x07e0, 0x0120),       two (0xffff, 0xffff),       {0},                 0, PROCESSOR_ALL },
00717 { "reti",     two (0x07e0, 0x0140),       two (0xffff, 0xffff),       {0},                 0, PROCESSOR_ALL },
00718 { "trap",     two (0x07e0, 0x0100),       two (0xffe0, 0xffff),       {I5U},                      0, PROCESSOR_ALL },
00719 { "ldsr",     two (0x07e0, 0x0020),       two (0x07e0, 0xffff),       {R1, SR2},           0, PROCESSOR_ALL },
00720 { "stsr",     two (0x07e0, 0x0040),       two (0x07e0, 0xffff),       {SR1, R2},           0, PROCESSOR_ALL },
00721 { "dbret",    two (0x07e0, 0x0146),       two (0xffff, 0xffff),       {UNUSED},            0, PROCESSOR_V850E1 },
00722 { 0, 0, 0, {0}, 0, 0 },
00723 
00724 } ;
00725 
00726 const int v850_num_opcodes =
00727   sizeof (v850_opcodes) / sizeof (v850_opcodes[0]);