1 /* Assemble V850 instructions. 2 Copyright 1996, 1997, 1998, 2000 Free Software Foundation, Inc. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 17 18 #include "sysdep.h" 19 #include "opcode/v850.h" 20 #include <stdio.h> 21 #include "opintl.h" 22 23 /* regular opcode */ 24 #define OP(x) ((x & 0x3f) << 5) 25 #define OP_MASK OP (0x3f) 26 27 /* conditional branch opcode */ 28 #define BOP(x) ((0x0b << 7) | (x & 0x0f)) 29 #define BOP_MASK ((0x0f << 7) | 0x0f) 30 31 /* one-word opcodes */ 32 #define one(x) ((unsigned int) (x)) 33 34 /* two-word opcodes */ 35 #define two(x,y) ((unsigned int) (x) | ((unsigned int) (y) << 16)) 36 37 38 39 /* The functions used to insert and extract complicated operands. */ 40 41 /* Note: There is a conspiracy between these functions and 42 v850_insert_operand() in gas/config/tc-v850.c. Error messages 43 containing the string 'out of range' will be ignored unless a 44 specific command line option is given to GAS. */ 45 46 static const char * not_valid = N_ ("displacement value is not in range and is not aligned"); 47 static const char * out_of_range = N_ ("displacement value is out of range"); 48 static const char * not_aligned = N_ ("displacement value is not aligned"); 49 50 static const char * immediate_out_of_range = N_ ("immediate value is out of range"); 51 52 static unsigned long 53 insert_d9 (insn, value, errmsg) 54 unsigned long insn; 55 long value; 56 const char ** errmsg; 57 { 58 if (value > 0xff || value < -0x100) 59 { 60 if ((value % 2) != 0) 61 * errmsg = _("branch value not in range and to odd offset"); 62 else 63 * errmsg = _("branch value out of range"); 64 } 65 else if ((value % 2) != 0) 66 * errmsg = _("branch to odd offset"); 67 68 return (insn | ((value & 0x1f0) << 7) | ((value & 0x0e) << 3)); 69 } 70 71 static unsigned long 72 extract_d9 (insn, invalid) 73 unsigned long insn; 74 int * invalid; 75 { 76 unsigned long ret = ((insn & 0xf800) >> 7) | ((insn & 0x0070) >> 3); 77 78 if ((insn & 0x8000) != 0) 79 ret -= 0x0200; 80 81 return ret; 82 } 83 84 static unsigned long 85 insert_d22 (insn, value, errmsg) 86 unsigned long insn; 87 long value; 88 const char ** errmsg; 89 { 90 if (value > 0x1fffff || value < -0x200000) 91 { 92 if ((value % 2) != 0) 93 * errmsg = _("branch value not in range and to an odd offset"); 94 else 95 * errmsg = _("branch value out of range"); 96 } 97 else if ((value % 2) != 0) 98 * errmsg = _("branch to odd offset"); 99 100 return (insn | ((value & 0xfffe) << 16) | ((value & 0x3f0000) >> 16)); 101 } 102 103 static unsigned long 104 extract_d22 (insn, invalid) 105 unsigned long insn; 106 int * invalid; 107 { 108 signed long ret = ((insn & 0xfffe0000) >> 16) | ((insn & 0x3f) << 16); 109 110 return (unsigned long) ((ret << 10) >> 10); 111 } 112 113 static unsigned long 114 insert_d16_15 (insn, value, errmsg) 115 unsigned long insn; 116 long value; 117 const char ** errmsg; 118 { 119 if (value > 0x7fff || value < -0x8000) 120 { 121 if ((value % 2) != 0) 122 * errmsg = _(not_valid); 123 else 124 * errmsg = _(out_of_range); 125 } 126 else if ((value % 2) != 0) 127 * errmsg = _(not_aligned); 128 129 return insn | ((value & 0xfffe) << 16); 130 } 131 132 static unsigned long 133 extract_d16_15 (insn, invalid) 134 unsigned long insn; 135 int * invalid; 136 { 137 signed long ret = (insn & 0xfffe0000); 138 139 return ret >> 16; 140 } 141 142 static unsigned long 143 insert_d8_7 (insn, value, errmsg) 144 unsigned long insn; 145 long value; 146 const char ** errmsg; 147 { 148 if (value > 0xff || value < 0) 149 { 150 if ((value % 2) != 0) 151 * errmsg = _(not_valid); 152 else 153 * errmsg = _(out_of_range); 154 } 155 else if ((value % 2) != 0) 156 * errmsg = _(not_aligned); 157 158 value >>= 1; 159 160 return (insn | (value & 0x7f)); 161 } 162 163 static unsigned long 164 extract_d8_7 (insn, invalid) 165 unsigned long insn; 166 int * invalid; 167 { 168 unsigned long ret = (insn & 0x7f); 169 170 return ret << 1; 171 } 172 173 static unsigned long 174 insert_d8_6 (insn, value, errmsg) 175 unsigned long insn; 176 long value; 177 const char ** errmsg; 178 { 179 if (value > 0xff || value < 0) 180 { 181 if ((value % 4) != 0) 182 *errmsg = _(not_valid); 183 else 184 * errmsg = _(out_of_range); 185 } 186 else if ((value % 4) != 0) 187 * errmsg = _(not_aligned); 188 189 value >>= 1; 190 191 return (insn | (value & 0x7e)); 192 } 193 194 static unsigned long 195 extract_d8_6 (insn, invalid) 196 unsigned long insn; 197 int * invalid; 198 { 199 unsigned long ret = (insn & 0x7e); 200 201 return ret << 1; 202 } 203 204 static unsigned long 205 insert_d5_4 (insn, value, errmsg) 206 unsigned long insn; 207 long value; 208 const char ** errmsg; 209 { 210 if (value > 0x1f || value < 0) 211 { 212 if (value & 1) 213 * errmsg = _(not_valid); 214 else 215 *errmsg = _(out_of_range); 216 } 217 else if (value & 1) 218 * errmsg = _(not_aligned); 219 220 value >>= 1; 221 222 return (insn | (value & 0x0f)); 223 } 224 225 static unsigned long 226 extract_d5_4 (insn, invalid) 227 unsigned long insn; 228 int * invalid; 229 { 230 unsigned long ret = (insn & 0x0f); 231 232 return ret << 1; 233 } 234 235 static unsigned long 236 insert_d16_16 (insn, value, errmsg) 237 unsigned long insn; 238 signed long value; 239 const char ** errmsg; 240 { 241 if (value > 0x7fff || value < -0x8000) 242 * errmsg = _(out_of_range); 243 244 return (insn | ((value & 0xfffe) << 16) | ((value & 1) << 5)); 245 } 246 247 static unsigned long 248 extract_d16_16 (insn, invalid) 249 unsigned long insn; 250 int * invalid; 251 { 252 signed long ret = insn & 0xfffe0000; 253 254 ret >>= 16; 255 256 ret |= ((insn & 0x20) >> 5); 257 258 return ret; 259 } 260 261 static unsigned long 262 insert_i9 (insn, value, errmsg) 263 unsigned long insn; 264 signed long value; 265 const char ** errmsg; 266 { 267 if (value > 0xff || value < -0x100) 268 * errmsg = _(immediate_out_of_range); 269 270 return insn | ((value & 0x1e0) << 13) | (value & 0x1f); 271 } 272 273 static unsigned long 274 extract_i9 (insn, invalid) 275 unsigned long insn; 276 int * invalid; 277 { 278 signed long ret = insn & 0x003c0000; 279 280 ret <<= 10; 281 ret >>= 23; 282 283 ret |= (insn & 0x1f); 284 285 return ret; 286 } 287 288 static unsigned long 289 insert_u9 (insn, value, errmsg) 290 unsigned long insn; 291 unsigned long value; 292 const char ** errmsg; 293 { 294 if (value > 0x1ff) 295 * errmsg = _(immediate_out_of_range); 296 297 return insn | ((value & 0x1e0) << 13) | (value & 0x1f); 298 } 299 300 static unsigned long 301 extract_u9 (insn, invalid) 302 unsigned long insn; 303 int * invalid; 304 { 305 unsigned long ret = insn & 0x003c0000; 306 307 ret >>= 13; 308 309 ret |= (insn & 0x1f); 310 311 return ret; 312 } 313 314 static unsigned long 315 insert_spe (insn, value, errmsg) 316 unsigned long insn; 317 unsigned long value; 318 const char ** errmsg; 319 { 320 if (value != 3) 321 * errmsg = _("invalid register for stack adjustment"); 322 323 return insn & (~ 0x180000); 324 } 325 326 static unsigned long 327 extract_spe (insn, invalid) 328 unsigned long insn; 329 int * invalid; 330 { 331 return 3; 332 } 333 334 static unsigned long 335 insert_i5div (insn, value, errmsg) 336 unsigned long insn; 337 unsigned long value; 338 const char ** errmsg; 339 { 340 if (value > 0x1ff) 341 { 342 if (value & 1) 343 * errmsg = _("immediate value not in range and not even"); 344 else 345 * errmsg = _(immediate_out_of_range); 346 } 347 else if (value & 1) 348 * errmsg = _("immediate value must be even"); 349 350 value = 32 - value; 351 352 return insn | ((value & 0x1e) << 17); 353 } 354 355 static unsigned long 356 extract_i5div (insn, invalid) 357 unsigned long insn; 358 int * invalid; 359 { 360 unsigned long ret = insn & 0x3c0000; 361 362 ret >>= 17; 363 364 ret = 32 - ret; 365 366 return ret; 367 } 368 369 370 /* Warning: code in gas/config/tc-v850.c examines the contents of this array. 371 If you change any of the values here, be sure to look for side effects in 372 that code. */ 373 const struct v850_operand v850_operands[] = 374 { 375 #define UNUSED 0 376 { 0, 0, NULL, NULL, 0 }, 377 378 /* The R1 field in a format 1, 6, 7, or 9 insn. */ 379 #define R1 (UNUSED + 1) 380 { 5, 0, NULL, NULL, V850_OPERAND_REG }, 381 382 /* As above, but register 0 is not allowed. */ 383 #define R1_NOTR0 (R1 + 1) 384 { 5, 0, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 }, 385 386 /* The R2 field in a format 1, 2, 4, 5, 6, 7, 9 insn. */ 387 #define R2 (R1_NOTR0 + 1) 388 { 5, 11, NULL, NULL, V850_OPERAND_REG }, 389 390 /* As above, but register 0 is not allowed. */ 391 #define R2_NOTR0 (R2 + 1) 392 { 5, 11, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 }, 393 394 /* The imm5 field in a format 2 insn. */ 395 #define I5 (R2_NOTR0 + 1) 396 { 5, 0, NULL, NULL, V850_OPERAND_SIGNED }, 397 398 /* The unsigned imm5 field in a format 2 insn. */ 399 #define I5U (I5 + 1) 400 { 5, 0, NULL, NULL, 0 }, 401 402 /* The imm16 field in a format 6 insn. */ 403 #define I16 (I5U + 1) 404 { 16, 16, NULL, NULL, V850_OPERAND_SIGNED }, 405 406 /* The signed disp7 field in a format 4 insn. */ 407 #define D7 (I16 + 1) 408 { 7, 0, NULL, NULL, 0}, 409 410 /* The disp16 field in a format 6 insn. */ 411 #define D16_15 (D7 + 1) 412 { 15, 17, insert_d16_15, extract_d16_15, V850_OPERAND_SIGNED }, 413 414 /* The 3 bit immediate field in format 8 insn. */ 415 #define B3 (D16_15 + 1) 416 { 3, 11, NULL, NULL, 0 }, 417 418 /* The 4 bit condition code in a setf instruction */ 419 #define CCCC (B3 + 1) 420 { 4, 0, NULL, NULL, V850_OPERAND_CC }, 421 422 /* The unsigned DISP8 field in a format 4 insn. */ 423 #define D8_7 (CCCC + 1) 424 { 7, 0, insert_d8_7, extract_d8_7, 0 }, 425 426 /* The unsigned DISP8 field in a format 4 insn. */ 427 #define D8_6 (D8_7 + 1) 428 { 6, 1, insert_d8_6, extract_d8_6, 0 }, 429 430 /* System register operands. */ 431 #define SR1 (D8_6 + 1) 432 { 5, 0, NULL, NULL, V850_OPERAND_SRG }, 433 434 /* EP Register. */ 435 #define EP (SR1 + 1) 436 { 0, 0, NULL, NULL, V850_OPERAND_EP }, 437 438 /* The imm16 field (unsigned) in a format 6 insn. */ 439 #define I16U (EP + 1) 440 { 16, 16, NULL, NULL, 0}, 441 442 /* The R2 field as a system register. */ 443 #define SR2 (I16U + 1) 444 { 5, 11, NULL, NULL, V850_OPERAND_SRG }, 445 446 /* The disp16 field in a format 8 insn. */ 447 #define D16 (SR2 + 1) 448 { 16, 16, NULL, NULL, V850_OPERAND_SIGNED }, 449 450 /* The DISP9 field in a format 3 insn, relaxable. */ 451 #define D9_RELAX (D16 + 1) 452 { 9, 0, insert_d9, extract_d9, V850_OPERAND_RELAX | V850_OPERAND_SIGNED | V850_OPERAND_DISP }, 453 454 /* The DISP22 field in a format 4 insn, relaxable. 455 This _must_ follow D9_RELAX; the assembler assumes that the longer 456 version immediately follows the shorter version for relaxing. */ 457 #define D22 (D9_RELAX + 1) 458 { 22, 0, insert_d22, extract_d22, V850_OPERAND_SIGNED | V850_OPERAND_DISP }, 459 460 /* The signed disp4 field in a format 4 insn. */ 461 #define D4 (D22 + 1) 462 { 4, 0, NULL, NULL, 0}, 463 464 /* The unsigned disp5 field in a format 4 insn. */ 465 #define D5_4 (D4 + 1) 466 { 4, 0, insert_d5_4, extract_d5_4, 0 }, 467 468 /* The disp16 field in an format 7 unsigned byte load insn. */ 469 #define D16_16 (D5_4 + 1) 470 { -1, 0xfffe0020, insert_d16_16, extract_d16_16, 0 }, 471 472 /* Third register in conditional moves. */ 473 #define R3 (D16_16 + 1) 474 { 5, 27, NULL, NULL, V850_OPERAND_REG }, 475 476 /* Condition code in conditional moves. */ 477 #define MOVCC (R3 + 1) 478 { 4, 17, NULL, NULL, V850_OPERAND_CC }, 479 480 /* The imm9 field in a multiply word. */ 481 #define I9 (MOVCC + 1) 482 { 9, 0, insert_i9, extract_i9, V850_OPERAND_SIGNED }, 483 484 /* The unsigned imm9 field in a multiply word. */ 485 #define U9 (I9 + 1) 486 { 9, 0, insert_u9, extract_u9, 0 }, 487 488 /* A list of registers in a prepare/dispose instruction. */ 489 #define LIST12 (U9 + 1) 490 { -1, 0xffe00001, NULL, NULL, V850E_PUSH_POP }, 491 492 /* The IMM6 field in a call instruction. */ 493 #define I6 (LIST12 + 1) 494 { 6, 0, NULL, NULL, 0 }, 495 496 /* The 16 bit immediate following a 32 bit instruction. */ 497 #define IMM16 (I6 + 1) 498 { 16, 16, NULL, NULL, V850_OPERAND_SIGNED | V850E_IMMEDIATE16 }, 499 500 /* The 32 bit immediate following a 32 bit instruction. */ 501 #define IMM32 (IMM16 + 1) 502 { 0, 0, NULL, NULL, V850E_IMMEDIATE32 }, 503 504 /* The imm5 field in a push/pop instruction. */ 505 #define IMM5 (IMM32 + 1) 506 { 5, 1, NULL, NULL, 0 }, 507 508 /* Reg2 in dispose instruction. */ 509 #define R2DISPOSE (IMM5 + 1) 510 { 5, 16, NULL, NULL, V850_OPERAND_REG | V850_NOT_R0 }, 511 512 /* Stack pointer in prepare instruction. */ 513 #define SP (R2DISPOSE + 1) 514 { 2, 19, insert_spe, extract_spe, V850_OPERAND_REG }, 515 516 /* The IMM5 field in a divide N step instruction. */ 517 #define I5DIV (SP + 1) 518 { 9, 0, insert_i5div, extract_i5div, V850_OPERAND_SIGNED }, 519 520 /* The list of registers in a PUSHMH/POPMH instruction. */ 521 #define LIST18_H (I5DIV + 1) 522 { -1, 0xfff8000f, NULL, NULL, V850E_PUSH_POP }, 523 524 /* The list of registers in a PUSHML/POPML instruction. */ 525 #define LIST18_L (LIST18_H + 1) 526 { -1, 0xfff8001f, NULL, NULL, V850E_PUSH_POP }, /* The setting of the 4th bit is a flag to disassmble() in v850-dis.c */ 527 } ; 528 529 530 /* reg-reg instruction format (Format I) */ 531 #define IF1 {R1, R2} 532 533 /* imm-reg instruction format (Format II) */ 534 #define IF2 {I5, R2} 535 536 /* conditional branch instruction format (Format III) */ 537 #define IF3 {D9_RELAX} 538 539 /* 3 operand instruction (Format VI) */ 540 #define IF6 {I16, R1, R2} 541 542 /* 3 operand instruction (Format VI) */ 543 #define IF6U {I16U, R1, R2} 544 545 546 547 /* The opcode table. 548 549 The format of the opcode table is: 550 551 NAME OPCODE MASK { OPERANDS } MEMOP PROCESSOR 552 553 NAME is the name of the instruction. 554 OPCODE is the instruction opcode. 555 MASK is the opcode mask; this is used to tell the disassembler 556 which bits in the actual opcode must match OPCODE. 557 OPERANDS is the list of operands. 558 MEMOP specifies which operand (if any) is a memory operand. 559 PROCESSORS specifies which CPU(s) support the opcode. 560 561 The disassembler reads the table in order and prints the first 562 instruction which matches, so this table is sorted to put more 563 specific instructions before more general instructions. It is also 564 sorted by major opcode. 565 566 The table is also sorted by name. This is used by the assembler. 567 When parsing an instruction the assembler finds the first occurance 568 of the name of the instruciton in this table and then attempts to 569 match the instruction's arguments with description of the operands 570 associated with the entry it has just found in this table. If the 571 match fails the assembler looks at the next entry in this table. 572 If that entry has the same name as the previous entry, then it 573 tries to match the instruction against that entry and so on. This 574 is how the assembler copes with multiple, different formats of the 575 same instruction. */ 576 577 const struct v850_opcode v850_opcodes[] = 578 { 579 { "breakpoint", 0xffff, 0xffff, {UNUSED}, 0, PROCESSOR_ALL }, 580 581 { "jmp", one (0x0060), one (0xffe0), {R1}, 1, PROCESSOR_ALL }, 582 583 /* load/store instructions */ 584 { "sld.bu", one (0x0300), one (0x0780), {D7, EP, R2_NOTR0}, 1, PROCESSOR_V850EA }, 585 { "sld.bu", one (0x0060), one (0x07f0), {D4, EP, R2_NOTR0}, 1, PROCESSOR_V850E }, 586 587 { "sld.hu", one (0x0400), one (0x0780), {D8_7, EP, R2_NOTR0}, 1, PROCESSOR_V850EA }, 588 { "sld.hu", one (0x0070), one (0x07f0), {D5_4, EP, R2_NOTR0}, 1, PROCESSOR_V850E }, 589 590 { "sld.b", one (0x0060), one (0x07f0), {D4, EP, R2}, 1, PROCESSOR_V850EA }, 591 { "sld.b", one (0x0300), one (0x0780), {D7, EP, R2}, 1, PROCESSOR_V850E }, 592 { "sld.b", one (0x0300), one (0x0780), {D7, EP, R2}, 1, PROCESSOR_V850 }, 593 594 { "sld.h", one (0x0070), one (0x07f0), {D5_4, EP, R2}, 1, PROCESSOR_V850EA }, 595 { "sld.h", one (0x0400), one (0x0780), {D8_7, EP, R2}, 1, PROCESSOR_V850E }, 596 { "sld.h", one (0x0400), one (0x0780), {D8_7, EP, R2}, 1, PROCESSOR_V850 }, 597 { "sld.w", one (0x0500), one (0x0781), {D8_6, EP, R2}, 1, PROCESSOR_ALL }, 598 { "sst.b", one (0x0380), one (0x0780), {R2, D7, EP}, 2, PROCESSOR_ALL }, 599 { "sst.h", one (0x0480), one (0x0780), {R2, D8_7, EP}, 2, PROCESSOR_ALL }, 600 { "sst.w", one (0x0501), one (0x0781), {R2, D8_6, EP}, 2, PROCESSOR_ALL }, 601 602 { "pushml", two (0x07e0, 0x0001), two (0xfff0, 0x0007), {LIST18_L}, 0, PROCESSOR_V850EA }, 603 { "pushmh", two (0x07e0, 0x0003), two (0xfff0, 0x0007), {LIST18_H}, 0, PROCESSOR_V850EA }, 604 { "popml", two (0x07f0, 0x0001), two (0xfff0, 0x0007), {LIST18_L}, 0, PROCESSOR_V850EA }, 605 { "popmh", two (0x07f0, 0x0003), two (0xfff0, 0x0007), {LIST18_H}, 0, PROCESSOR_V850EA }, 606 { "prepare", two (0x0780, 0x0003), two (0xffc0, 0x001f), {LIST12, IMM5, SP}, 0, PROCESSOR_NOT_V850 }, 607 { "prepare", two (0x0780, 0x000b), two (0xffc0, 0x001f), {LIST12, IMM5, IMM16}, 0, PROCESSOR_NOT_V850 }, 608 { "prepare", two (0x0780, 0x0013), two (0xffc0, 0x001f), {LIST12, IMM5, IMM16}, 0, PROCESSOR_NOT_V850 }, 609 { "prepare", two (0x0780, 0x001b), two (0xffc0, 0x001f), {LIST12, IMM5, IMM32}, 0, PROCESSOR_NOT_V850 }, 610 { "prepare", two (0x0780, 0x0001), two (0xffc0, 0x001f), {LIST12, IMM5}, 0, PROCESSOR_NOT_V850 }, 611 { "dispose", one (0x0640), one (0xffc0), {IMM5, LIST12, R2DISPOSE},0, PROCESSOR_NOT_V850 }, 612 { "dispose", two (0x0640, 0x0000), two (0xffc0, 0x001f), {IMM5, LIST12}, 0, PROCESSOR_NOT_V850 }, 613 614 { "ld.b", two (0x0700, 0x0000), two (0x07e0, 0x0000), {D16, R1, R2}, 1, PROCESSOR_ALL }, 615 { "ld.h", two (0x0720, 0x0000), two (0x07e0, 0x0001), {D16_15, R1, R2}, 1, PROCESSOR_ALL }, 616 { "ld.w", two (0x0720, 0x0001), two (0x07e0, 0x0001), {D16_15, R1, R2}, 1, PROCESSOR_ALL }, 617 { "ld.bu", two (0x0780, 0x0001), two (0x07c0, 0x0001), {D16_16, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 }, 618 { "ld.hu", two (0x07e0, 0x0001), two (0x07e0, 0x0001), {D16_15, R1, R2_NOTR0}, 1, PROCESSOR_NOT_V850 }, 619 { "st.b", two (0x0740, 0x0000), two (0x07e0, 0x0000), {R2, D16, R1}, 2, PROCESSOR_ALL }, 620 { "st.h", two (0x0760, 0x0000), two (0x07e0, 0x0001), {R2, D16_15, R1}, 2, PROCESSOR_ALL }, 621 { "st.w", two (0x0760, 0x0001), two (0x07e0, 0x0001), {R2, D16_15, R1}, 2, PROCESSOR_ALL }, 622 623 /* byte swap/extend instructions */ 624 { "zxb", one (0x0080), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, 625 { "zxh", one (0x00c0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, 626 { "sxb", one (0x00a0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, 627 { "sxh", one (0x00e0), one (0xffe0), {R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, 628 { "bsh", two (0x07e0, 0x0342), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 }, 629 { "bsw", two (0x07e0, 0x0340), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 }, 630 { "hsw", two (0x07e0, 0x0344), two (0x07ff, 0x07ff), {R2, R3}, 0, PROCESSOR_NOT_V850 }, 631 632 /* jump table instructions */ 633 { "switch", one (0x0040), one (0xffe0), {R1}, 1, PROCESSOR_NOT_V850 }, 634 { "callt", one (0x0200), one (0xffc0), {I6}, 0, PROCESSOR_NOT_V850 }, 635 { "ctret", two (0x07e0, 0x0144), two (0xffff, 0xffff), {0}, 0, PROCESSOR_NOT_V850 }, 636 637 /* arithmetic operation instructions */ 638 { "setf", two (0x07e0, 0x0000), two (0x07f0, 0xffff), {CCCC, R2}, 0, PROCESSOR_ALL }, 639 { "cmov", two (0x07e0, 0x0320), two (0x07e0, 0x07e1), {MOVCC, R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, 640 { "cmov", two (0x07e0, 0x0300), two (0x07e0, 0x07e1), {MOVCC, I5, R2, R3}, 0, PROCESSOR_NOT_V850 }, 641 642 { "mul", two (0x07e0, 0x0220), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, 643 { "mul", two (0x07e0, 0x0240), two (0x07e0, 0x07c3), {I9, R2, R3}, 0, PROCESSOR_NOT_V850 }, 644 { "mulu", two (0x07e0, 0x0222), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, 645 { "mulu", two (0x07e0, 0x0242), two (0x07e0, 0x07c3), {U9, R2, R3}, 0, PROCESSOR_NOT_V850 }, 646 647 { "div", two (0x07e0, 0x02c0), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, 648 { "divu", two (0x07e0, 0x02c2), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, 649 { "divhu", two (0x07e0, 0x0282), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, 650 { "divh", two (0x07e0, 0x0280), two (0x07e0, 0x07ff), {R1, R2, R3}, 0, PROCESSOR_NOT_V850 }, 651 { "divh", OP (0x02), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, 652 653 { "divhn", two (0x07e0, 0x0280), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA }, 654 { "divhun", two (0x07e0, 0x0282), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA }, 655 { "divn", two (0x07e0, 0x02c0), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA }, 656 { "divun", two (0x07e0, 0x02c2), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA }, 657 { "sdivhn", two (0x07e0, 0x0180), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA }, 658 { "sdivhun", two (0x07e0, 0x0182), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA }, 659 { "sdivn", two (0x07e0, 0x01c0), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA }, 660 { "sdivun", two (0x07e0, 0x01c2), two (0x07e0, 0x07c3), {I5DIV, R1, R2, R3}, 0, PROCESSOR_V850EA }, 661 662 { "nop", one (0x00), one (0xffff), {0}, 0, PROCESSOR_ALL }, 663 { "mov", OP (0x10), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL }, 664 { "mov", one (0x0620), one (0xffe0), {IMM32, R1_NOTR0}, 0, PROCESSOR_NOT_V850 }, 665 { "mov", OP (0x00), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, 666 { "movea", OP (0x31), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, 667 { "movhi", OP (0x32), OP_MASK, {I16U, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, 668 { "add", OP (0x0e), OP_MASK, IF1, 0, PROCESSOR_ALL }, 669 { "add", OP (0x12), OP_MASK, IF2, 0, PROCESSOR_ALL }, 670 { "addi", OP (0x30), OP_MASK, IF6, 0, PROCESSOR_ALL }, 671 { "sub", OP (0x0d), OP_MASK, IF1, 0, PROCESSOR_ALL }, 672 { "subr", OP (0x0c), OP_MASK, IF1, 0, PROCESSOR_ALL }, 673 { "mulh", OP (0x17), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL }, 674 { "mulh", OP (0x07), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, 675 { "mulhi", OP (0x37), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, 676 { "cmp", OP (0x0f), OP_MASK, IF1, 0, PROCESSOR_ALL }, 677 { "cmp", OP (0x13), OP_MASK, IF2, 0, PROCESSOR_ALL }, 678 679 /* saturated operation instructions */ 680 { "satadd", OP (0x11), OP_MASK, {I5, R2_NOTR0}, 0, PROCESSOR_ALL }, 681 { "satadd", OP (0x06), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, 682 { "satsub", OP (0x05), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, 683 { "satsubi", OP (0x33), OP_MASK, {I16, R1, R2_NOTR0}, 0, PROCESSOR_ALL }, 684 { "satsubr", OP (0x04), OP_MASK, {R1, R2_NOTR0}, 0, PROCESSOR_ALL }, 685 686 /* logical operation instructions */ 687 { "tst", OP (0x0b), OP_MASK, IF1, 0, PROCESSOR_ALL }, 688 { "or", OP (0x08), OP_MASK, IF1, 0, PROCESSOR_ALL }, 689 { "ori", OP (0x34), OP_MASK, IF6U, 0, PROCESSOR_ALL }, 690 { "and", OP (0x0a), OP_MASK, IF1, 0, PROCESSOR_ALL }, 691 { "andi", OP (0x36), OP_MASK, IF6U, 0, PROCESSOR_ALL }, 692 { "xor", OP (0x09), OP_MASK, IF1, 0, PROCESSOR_ALL }, 693 { "xori", OP (0x35), OP_MASK, IF6U, 0, PROCESSOR_ALL }, 694 { "not", OP (0x01), OP_MASK, IF1, 0, PROCESSOR_ALL }, 695 { "sar", OP (0x15), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL }, 696 { "sar", two (0x07e0, 0x00a0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL }, 697 { "shl", OP (0x16), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL }, 698 { "shl", two (0x07e0, 0x00c0), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL }, 699 { "shr", OP (0x14), OP_MASK, {I5U, R2}, 0, PROCESSOR_ALL }, 700 { "shr", two (0x07e0, 0x0080), two (0x07e0, 0xffff), {R1, R2}, 0, PROCESSOR_ALL }, 701 { "sasf", two (0x07e0, 0x0200), two (0x07f0, 0xffff), {CCCC, R2}, 0, PROCESSOR_NOT_V850 }, 702 703 /* branch instructions */ 704 /* signed integer */ 705 { "bgt", BOP (0xf), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 706 { "bge", BOP (0xe), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 707 { "blt", BOP (0x6), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 708 { "ble", BOP (0x7), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 709 /* unsigned integer */ 710 { "bh", BOP (0xb), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 711 { "bnh", BOP (0x3), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 712 { "bl", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 713 { "bnl", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 714 /* common */ 715 { "be", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 716 { "bne", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 717 /* others */ 718 { "bv", BOP (0x0), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 719 { "bnv", BOP (0x8), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 720 { "bn", BOP (0x4), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 721 { "bp", BOP (0xc), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 722 { "bc", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 723 { "bnc", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 724 { "bz", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 725 { "bnz", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 726 { "br", BOP (0x5), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 727 { "bsa", BOP (0xd), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 728 729 /* Branch macros. 730 731 We use the short form in the opcode/mask fields. The assembler 732 will twiddle bits as necessary if the long form is needed. */ 733 734 /* signed integer */ 735 { "jgt", BOP (0xf), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 736 { "jge", BOP (0xe), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 737 { "jlt", BOP (0x6), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 738 { "jle", BOP (0x7), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 739 /* unsigned integer */ 740 { "jh", BOP (0xb), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 741 { "jnh", BOP (0x3), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 742 { "jl", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 743 { "jnl", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 744 /* common */ 745 { "je", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 746 { "jne", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 747 /* others */ 748 { "jv", BOP (0x0), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 749 { "jnv", BOP (0x8), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 750 { "jn", BOP (0x4), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 751 { "jp", BOP (0xc), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 752 { "jc", BOP (0x1), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 753 { "jnc", BOP (0x9), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 754 { "jz", BOP (0x2), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 755 { "jnz", BOP (0xa), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 756 { "jsa", BOP (0xd), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 757 { "jbr", BOP (0x5), BOP_MASK, IF3, 0, PROCESSOR_ALL }, 758 759 { "jr", one (0x0780), two (0xffc0, 0x0001), {D22}, 0, PROCESSOR_ALL }, 760 { "jarl", one (0x0780), two (0x07c0, 0x0001), {D22, R2}, 0, PROCESSOR_ALL}, 761 762 /* bit manipulation instructions */ 763 { "set1", two (0x07c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL }, 764 { "set1", two (0x07e0, 0x00e0), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, 765 { "not1", two (0x47c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL }, 766 { "not1", two (0x07e0, 0x00e2), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, 767 { "clr1", two (0x87c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL }, 768 { "clr1", two (0x07e0, 0x00e4), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, 769 { "tst1", two (0xc7c0, 0x0000), two (0xc7e0, 0x0000), {B3, D16, R1}, 2, PROCESSOR_ALL }, 770 { "tst1", two (0x07e0, 0x00e6), two (0x07e0, 0xffff), {R2, R1}, 2, PROCESSOR_NOT_V850 }, 771 772 /* special instructions */ 773 { "di", two (0x07e0, 0x0160), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, 774 { "ei", two (0x87e0, 0x0160), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, 775 { "halt", two (0x07e0, 0x0120), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, 776 { "reti", two (0x07e0, 0x0140), two (0xffff, 0xffff), {0}, 0, PROCESSOR_ALL }, 777 { "trap", two (0x07e0, 0x0100), two (0xffe0, 0xffff), {I5U}, 0, PROCESSOR_ALL }, 778 { "ldsr", two (0x07e0, 0x0020), two (0x07e0, 0xffff), {R1, SR2}, 0, PROCESSOR_ALL }, 779 { "stsr", two (0x07e0, 0x0040), two (0x07e0, 0xffff), {SR1, R2}, 0, PROCESSOR_ALL }, 780 { 0, 0, 0, {0}, 0, 0 }, 781 782 } ; 783 784 const int v850_num_opcodes = 785 sizeof (v850_opcodes) / sizeof (v850_opcodes[0]); 786 787