00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "sysdep.h"
00028 #include <stdio.h>
00029 #include "ansidecl.h"
00030 #include "dis-asm.h"
00031 #include "bfd.h"
00032 #include "symcat.h"
00033 #include "xstormy16-desc.h"
00034 #include "xstormy16-opc.h"
00035 #include "opintl.h"
00036 #include "safe-ctype.h"
00037
00038 #undef min
00039 #define min(a,b) ((a) < (b) ? (a) : (b))
00040 #undef max
00041 #define max(a,b) ((a) > (b) ? (a) : (b))
00042
00043
00044 #define FLD(f) (fields->f)
00045
00046 static const char * insert_normal
00047 (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
00048 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
00049 static const char * insert_insn_normal
00050 (CGEN_CPU_DESC, const CGEN_INSN *,
00051 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
00052 static int extract_normal
00053 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
00054 unsigned int, unsigned int, unsigned int, unsigned int,
00055 unsigned int, unsigned int, bfd_vma, long *);
00056 static int extract_insn_normal
00057 (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
00058 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
00059 #if CGEN_INT_INSN_P
00060 static void put_insn_int_value
00061 (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
00062 #endif
00063 #if ! CGEN_INT_INSN_P
00064 static CGEN_INLINE void insert_1
00065 (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
00066 static CGEN_INLINE int fill_cache
00067 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma);
00068 static CGEN_INLINE long extract_1
00069 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
00070 #endif
00071
00072
00073
00074 #if ! CGEN_INT_INSN_P
00075
00076
00077
00078 static CGEN_INLINE void
00079 insert_1 (CGEN_CPU_DESC cd,
00080 unsigned long value,
00081 int start,
00082 int length,
00083 int word_length,
00084 unsigned char *bufp)
00085 {
00086 unsigned long x,mask;
00087 int shift;
00088
00089 x = cgen_get_insn_value (cd, bufp, word_length);
00090
00091
00092 mask = (((1L << (length - 1)) - 1) << 1) | 1;
00093 if (CGEN_INSN_LSB0_P)
00094 shift = (start + 1) - length;
00095 else
00096 shift = (word_length - (start + length));
00097 x = (x & ~(mask << shift)) | ((value & mask) << shift);
00098
00099 cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
00100 }
00101
00102 #endif
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 static const char *
00121 insert_normal (CGEN_CPU_DESC cd,
00122 long value,
00123 unsigned int attrs,
00124 unsigned int word_offset,
00125 unsigned int start,
00126 unsigned int length,
00127 unsigned int word_length,
00128 unsigned int total_length,
00129 CGEN_INSN_BYTES_PTR buffer)
00130 {
00131 static char errbuf[100];
00132
00133 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
00134
00135
00136 if (length == 0)
00137 return NULL;
00138
00139 #if 0
00140 if (CGEN_INT_INSN_P
00141 && word_offset != 0)
00142 abort ();
00143 #endif
00144
00145 if (word_length > 32)
00146 abort ();
00147
00148
00149
00150 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
00151 {
00152 if (word_offset == 0
00153 && word_length > total_length)
00154 word_length = total_length;
00155 }
00156
00157
00158 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
00159 {
00160 long minval = - (1L << (length - 1));
00161 unsigned long maxval = mask;
00162
00163 if ((value > 0 && (unsigned long) value > maxval)
00164 || value < minval)
00165 {
00166
00167 sprintf (errbuf,
00168 _("operand out of range (%ld not between %ld and %lu)"),
00169 value, minval, maxval);
00170 return errbuf;
00171 }
00172 }
00173 else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
00174 {
00175 unsigned long maxval = mask;
00176
00177 if ((unsigned long) value > maxval)
00178 {
00179
00180 sprintf (errbuf,
00181 _("operand out of range (%lu not between 0 and %lu)"),
00182 value, maxval);
00183 return errbuf;
00184 }
00185 }
00186 else
00187 {
00188 if (! cgen_signed_overflow_ok_p (cd))
00189 {
00190 long minval = - (1L << (length - 1));
00191 long maxval = (1L << (length - 1)) - 1;
00192
00193 if (value < minval || value > maxval)
00194 {
00195 sprintf
00196
00197 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
00198 value, minval, maxval);
00199 return errbuf;
00200 }
00201 }
00202 }
00203
00204 #if CGEN_INT_INSN_P
00205
00206 {
00207 int shift;
00208
00209 if (CGEN_INSN_LSB0_P)
00210 shift = (word_offset + start + 1) - length;
00211 else
00212 shift = total_length - (word_offset + start + length);
00213 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
00214 }
00215
00216 #else
00217
00218 {
00219 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
00220
00221 insert_1 (cd, value, start, length, word_length, bufp);
00222 }
00223
00224 #endif
00225
00226 return NULL;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236 static const char *
00237 insert_insn_normal (CGEN_CPU_DESC cd,
00238 const CGEN_INSN * insn,
00239 CGEN_FIELDS * fields,
00240 CGEN_INSN_BYTES_PTR buffer,
00241 bfd_vma pc)
00242 {
00243 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
00244 unsigned long value;
00245 const CGEN_SYNTAX_CHAR_TYPE * syn;
00246
00247 CGEN_INIT_INSERT (cd);
00248 value = CGEN_INSN_BASE_VALUE (insn);
00249
00250
00251
00252
00253 #if CGEN_INT_INSN_P
00254
00255 put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
00256 CGEN_FIELDS_BITSIZE (fields), value);
00257
00258 #else
00259
00260 cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
00261 (unsigned) CGEN_FIELDS_BITSIZE (fields)),
00262 value);
00263
00264 #endif
00265
00266
00267
00268
00269
00270
00271 for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
00272 {
00273 const char *errmsg;
00274
00275 if (CGEN_SYNTAX_CHAR_P (* syn))
00276 continue;
00277
00278 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
00279 fields, buffer, pc);
00280 if (errmsg)
00281 return errmsg;
00282 }
00283
00284 return NULL;
00285 }
00286
00287 #if CGEN_INT_INSN_P
00288
00289
00290
00291 static void
00292 put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00293 CGEN_INSN_BYTES_PTR buf,
00294 int length,
00295 int insn_length,
00296 CGEN_INSN_INT value)
00297 {
00298
00299
00300 if (length > insn_length)
00301 *buf = value;
00302 else
00303 {
00304 int shift = insn_length - length;
00305
00306 CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
00307 *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
00308 }
00309 }
00310 #endif
00311
00312
00313
00314 #if ! CGEN_INT_INSN_P
00315
00316
00317
00318
00319
00320
00321
00322 static CGEN_INLINE int
00323 fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00324 CGEN_EXTRACT_INFO *ex_info,
00325 int offset,
00326 int bytes,
00327 bfd_vma pc)
00328 {
00329
00330
00331 unsigned int mask;
00332 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
00333
00334
00335 mask = (1 << bytes) - 1;
00336 if (((ex_info->valid >> offset) & mask) == mask)
00337 return 1;
00338
00339
00340 for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
00341 if (! (mask & ex_info->valid))
00342 break;
00343
00344 if (bytes)
00345 {
00346 int status;
00347
00348 pc += offset;
00349 status = (*info->read_memory_func)
00350 (pc, ex_info->insn_bytes + offset, bytes, info);
00351
00352 if (status != 0)
00353 {
00354 (*info->memory_error_func) (status, pc, info);
00355 return 0;
00356 }
00357
00358 ex_info->valid |= ((1 << bytes) - 1) << offset;
00359 }
00360
00361 return 1;
00362 }
00363
00364
00365
00366 static CGEN_INLINE long
00367 extract_1 (CGEN_CPU_DESC cd,
00368 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
00369 int start,
00370 int length,
00371 int word_length,
00372 unsigned char *bufp,
00373 bfd_vma pc ATTRIBUTE_UNUSED)
00374 {
00375 unsigned long x;
00376 int shift;
00377 #if 0
00378 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
00379 #endif
00380 x = cgen_get_insn_value (cd, bufp, word_length);
00381
00382 if (CGEN_INSN_LSB0_P)
00383 shift = (start + 1) - length;
00384 else
00385 shift = (word_length - (start + length));
00386 return x >> shift;
00387 }
00388
00389 #endif
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 static int
00412 extract_normal (CGEN_CPU_DESC cd,
00413 #if ! CGEN_INT_INSN_P
00414 CGEN_EXTRACT_INFO *ex_info,
00415 #else
00416 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
00417 #endif
00418 CGEN_INSN_INT insn_value,
00419 unsigned int attrs,
00420 unsigned int word_offset,
00421 unsigned int start,
00422 unsigned int length,
00423 unsigned int word_length,
00424 unsigned int total_length,
00425 #if ! CGEN_INT_INSN_P
00426 bfd_vma pc,
00427 #else
00428 bfd_vma pc ATTRIBUTE_UNUSED,
00429 #endif
00430 long *valuep)
00431 {
00432 long value, mask;
00433
00434
00435
00436 if (length == 0)
00437 {
00438 *valuep = 0;
00439 return 1;
00440 }
00441
00442 #if 0
00443 if (CGEN_INT_INSN_P
00444 && word_offset != 0)
00445 abort ();
00446 #endif
00447
00448 if (word_length > 32)
00449 abort ();
00450
00451
00452
00453 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
00454 {
00455 if (word_offset == 0
00456 && word_length > total_length)
00457 word_length = total_length;
00458 }
00459
00460
00461
00462 if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
00463 {
00464 if (CGEN_INSN_LSB0_P)
00465 value = insn_value >> ((word_offset + start + 1) - length);
00466 else
00467 value = insn_value >> (total_length - ( word_offset + start + length));
00468 }
00469
00470 #if ! CGEN_INT_INSN_P
00471
00472 else
00473 {
00474 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
00475
00476 if (word_length > 32)
00477 abort ();
00478
00479 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
00480 return 0;
00481
00482 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
00483 }
00484
00485 #endif
00486
00487
00488 mask = (((1L << (length - 1)) - 1) << 1) | 1;
00489
00490 value &= mask;
00491
00492 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
00493 && (value & (1L << (length - 1))))
00494 value |= ~mask;
00495
00496 *valuep = value;
00497
00498 return 1;
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510 static int
00511 extract_insn_normal (CGEN_CPU_DESC cd,
00512 const CGEN_INSN *insn,
00513 CGEN_EXTRACT_INFO *ex_info,
00514 CGEN_INSN_INT insn_value,
00515 CGEN_FIELDS *fields,
00516 bfd_vma pc)
00517 {
00518 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
00519 const CGEN_SYNTAX_CHAR_TYPE *syn;
00520
00521 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
00522
00523 CGEN_INIT_EXTRACT (cd);
00524
00525 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
00526 {
00527 int length;
00528
00529 if (CGEN_SYNTAX_CHAR_P (*syn))
00530 continue;
00531
00532 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
00533 ex_info, insn_value, fields, pc);
00534 if (length <= 0)
00535 return length;
00536 }
00537
00538
00539 return CGEN_INSN_BITSIZE (insn);
00540 }
00541
00542
00543
00544 const char * xstormy16_cgen_insert_operand
00545 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 const char *
00562 xstormy16_cgen_insert_operand (cd, opindex, fields, buffer, pc)
00563 CGEN_CPU_DESC cd;
00564 int opindex;
00565 CGEN_FIELDS * fields;
00566 CGEN_INSN_BYTES_PTR buffer;
00567 bfd_vma pc ATTRIBUTE_UNUSED;
00568 {
00569 const char * errmsg = NULL;
00570 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
00571
00572 switch (opindex)
00573 {
00574 case XSTORMY16_OPERAND_RB :
00575 errmsg = insert_normal (cd, fields->f_Rb, 0, 0, 17, 3, 32, total_length, buffer);
00576 break;
00577 case XSTORMY16_OPERAND_RBJ :
00578 errmsg = insert_normal (cd, fields->f_Rbj, 0, 0, 11, 1, 32, total_length, buffer);
00579 break;
00580 case XSTORMY16_OPERAND_RD :
00581 errmsg = insert_normal (cd, fields->f_Rd, 0, 0, 12, 4, 32, total_length, buffer);
00582 break;
00583 case XSTORMY16_OPERAND_RDM :
00584 errmsg = insert_normal (cd, fields->f_Rdm, 0, 0, 13, 3, 32, total_length, buffer);
00585 break;
00586 case XSTORMY16_OPERAND_RM :
00587 errmsg = insert_normal (cd, fields->f_Rm, 0, 0, 4, 3, 32, total_length, buffer);
00588 break;
00589 case XSTORMY16_OPERAND_RS :
00590 errmsg = insert_normal (cd, fields->f_Rs, 0, 0, 8, 4, 32, total_length, buffer);
00591 break;
00592 case XSTORMY16_OPERAND_ABS24 :
00593 {
00594 {
00595 FLD (f_abs24_1) = ((FLD (f_abs24)) & (255));
00596 FLD (f_abs24_2) = ((unsigned int) (FLD (f_abs24)) >> (8));
00597 }
00598 errmsg = insert_normal (cd, fields->f_abs24_1, 0, 0, 8, 8, 32, total_length, buffer);
00599 if (errmsg)
00600 break;
00601 errmsg = insert_normal (cd, fields->f_abs24_2, 0, 0, 16, 16, 32, total_length, buffer);
00602 if (errmsg)
00603 break;
00604 }
00605 break;
00606 case XSTORMY16_OPERAND_BCOND2 :
00607 errmsg = insert_normal (cd, fields->f_op2, 0, 0, 4, 4, 32, total_length, buffer);
00608 break;
00609 case XSTORMY16_OPERAND_BCOND5 :
00610 errmsg = insert_normal (cd, fields->f_op5, 0, 0, 16, 4, 32, total_length, buffer);
00611 break;
00612 case XSTORMY16_OPERAND_HMEM8 :
00613 {
00614 long value = fields->f_hmem8;
00615 value = ((value) - (32512));
00616 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, buffer);
00617 }
00618 break;
00619 case XSTORMY16_OPERAND_IMM12 :
00620 errmsg = insert_normal (cd, fields->f_imm12, 0|(1<<CGEN_IFLD_SIGNED), 0, 20, 12, 32, total_length, buffer);
00621 break;
00622 case XSTORMY16_OPERAND_IMM16 :
00623 errmsg = insert_normal (cd, fields->f_imm16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
00624 break;
00625 case XSTORMY16_OPERAND_IMM2 :
00626 errmsg = insert_normal (cd, fields->f_imm2, 0, 0, 10, 2, 32, total_length, buffer);
00627 break;
00628 case XSTORMY16_OPERAND_IMM3 :
00629 errmsg = insert_normal (cd, fields->f_imm3, 0, 0, 4, 3, 32, total_length, buffer);
00630 break;
00631 case XSTORMY16_OPERAND_IMM3B :
00632 errmsg = insert_normal (cd, fields->f_imm3b, 0, 0, 17, 3, 32, total_length, buffer);
00633 break;
00634 case XSTORMY16_OPERAND_IMM4 :
00635 errmsg = insert_normal (cd, fields->f_imm4, 0, 0, 8, 4, 32, total_length, buffer);
00636 break;
00637 case XSTORMY16_OPERAND_IMM8 :
00638 errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 8, 8, 32, total_length, buffer);
00639 break;
00640 case XSTORMY16_OPERAND_IMM8SMALL :
00641 errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 8, 8, 32, total_length, buffer);
00642 break;
00643 case XSTORMY16_OPERAND_LMEM8 :
00644 errmsg = insert_normal (cd, fields->f_lmem8, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, buffer);
00645 break;
00646 case XSTORMY16_OPERAND_REL12 :
00647 {
00648 long value = fields->f_rel12;
00649 value = ((value) - (((pc) + (4))));
00650 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 20, 12, 32, total_length, buffer);
00651 }
00652 break;
00653 case XSTORMY16_OPERAND_REL12A :
00654 {
00655 long value = fields->f_rel12a;
00656 value = ((int) (((value) - (((pc) + (2))))) >> (1));
00657 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 4, 11, 32, total_length, buffer);
00658 }
00659 break;
00660 case XSTORMY16_OPERAND_REL8_2 :
00661 {
00662 long value = fields->f_rel8_2;
00663 value = ((value) - (((pc) + (2))));
00664 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
00665 }
00666 break;
00667 case XSTORMY16_OPERAND_REL8_4 :
00668 {
00669 long value = fields->f_rel8_4;
00670 value = ((value) - (((pc) + (4))));
00671 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
00672 }
00673 break;
00674 case XSTORMY16_OPERAND_WS2 :
00675 errmsg = insert_normal (cd, fields->f_op2m, 0, 0, 7, 1, 32, total_length, buffer);
00676 break;
00677
00678 default :
00679
00680 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
00681 opindex);
00682 abort ();
00683 }
00684
00685 return errmsg;
00686 }
00687
00688 int xstormy16_cgen_extract_operand
00689 PARAMS ((CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
00690 CGEN_FIELDS *, bfd_vma));
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 int
00708 xstormy16_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
00709 CGEN_CPU_DESC cd;
00710 int opindex;
00711 CGEN_EXTRACT_INFO *ex_info;
00712 CGEN_INSN_INT insn_value;
00713 CGEN_FIELDS * fields;
00714 bfd_vma pc;
00715 {
00716
00717 int length = 1;
00718 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
00719
00720 switch (opindex)
00721 {
00722 case XSTORMY16_OPERAND_RB :
00723 length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 3, 32, total_length, pc, & fields->f_Rb);
00724 break;
00725 case XSTORMY16_OPERAND_RBJ :
00726 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_Rbj);
00727 break;
00728 case XSTORMY16_OPERAND_RD :
00729 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_Rd);
00730 break;
00731 case XSTORMY16_OPERAND_RDM :
00732 length = extract_normal (cd, ex_info, insn_value, 0, 0, 13, 3, 32, total_length, pc, & fields->f_Rdm);
00733 break;
00734 case XSTORMY16_OPERAND_RM :
00735 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 3, 32, total_length, pc, & fields->f_Rm);
00736 break;
00737 case XSTORMY16_OPERAND_RS :
00738 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_Rs);
00739 break;
00740 case XSTORMY16_OPERAND_ABS24 :
00741 {
00742 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_abs24_1);
00743 if (length <= 0) break;
00744 length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_abs24_2);
00745 if (length <= 0) break;
00746 FLD (f_abs24) = ((((FLD (f_abs24_2)) << (8))) | (FLD (f_abs24_1)));
00747 }
00748 break;
00749 case XSTORMY16_OPERAND_BCOND2 :
00750 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_op2);
00751 break;
00752 case XSTORMY16_OPERAND_BCOND5 :
00753 length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 4, 32, total_length, pc, & fields->f_op5);
00754 break;
00755 case XSTORMY16_OPERAND_HMEM8 :
00756 {
00757 long value;
00758 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, pc, & value);
00759 value = ((value) + (32512));
00760 fields->f_hmem8 = value;
00761 }
00762 break;
00763 case XSTORMY16_OPERAND_IMM12 :
00764 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 20, 12, 32, total_length, pc, & fields->f_imm12);
00765 break;
00766 case XSTORMY16_OPERAND_IMM16 :
00767 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_imm16);
00768 break;
00769 case XSTORMY16_OPERAND_IMM2 :
00770 length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 2, 32, total_length, pc, & fields->f_imm2);
00771 break;
00772 case XSTORMY16_OPERAND_IMM3 :
00773 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 3, 32, total_length, pc, & fields->f_imm3);
00774 break;
00775 case XSTORMY16_OPERAND_IMM3B :
00776 length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 3, 32, total_length, pc, & fields->f_imm3b);
00777 break;
00778 case XSTORMY16_OPERAND_IMM4 :
00779 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_imm4);
00780 break;
00781 case XSTORMY16_OPERAND_IMM8 :
00782 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_imm8);
00783 break;
00784 case XSTORMY16_OPERAND_IMM8SMALL :
00785 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_imm8);
00786 break;
00787 case XSTORMY16_OPERAND_LMEM8 :
00788 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, pc, & fields->f_lmem8);
00789 break;
00790 case XSTORMY16_OPERAND_REL12 :
00791 {
00792 long value;
00793 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 20, 12, 32, total_length, pc, & value);
00794 value = ((value) + (((pc) + (4))));
00795 fields->f_rel12 = value;
00796 }
00797 break;
00798 case XSTORMY16_OPERAND_REL12A :
00799 {
00800 long value;
00801 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 4, 11, 32, total_length, pc, & value);
00802 value = ((((value) << (1))) + (((pc) + (2))));
00803 fields->f_rel12a = value;
00804 }
00805 break;
00806 case XSTORMY16_OPERAND_REL8_2 :
00807 {
00808 long value;
00809 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, pc, & value);
00810 value = ((value) + (((pc) + (2))));
00811 fields->f_rel8_2 = value;
00812 }
00813 break;
00814 case XSTORMY16_OPERAND_REL8_4 :
00815 {
00816 long value;
00817 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, pc, & value);
00818 value = ((value) + (((pc) + (4))));
00819 fields->f_rel8_4 = value;
00820 }
00821 break;
00822 case XSTORMY16_OPERAND_WS2 :
00823 length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 1, 32, total_length, pc, & fields->f_op2m);
00824 break;
00825
00826 default :
00827
00828 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
00829 opindex);
00830 abort ();
00831 }
00832
00833 return length;
00834 }
00835
00836 cgen_insert_fn * const xstormy16_cgen_insert_handlers[] =
00837 {
00838 insert_insn_normal,
00839 };
00840
00841 cgen_extract_fn * const xstormy16_cgen_extract_handlers[] =
00842 {
00843 extract_insn_normal,
00844 };
00845
00846 int xstormy16_cgen_get_int_operand
00847 PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
00848 bfd_vma xstormy16_cgen_get_vma_operand
00849 PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
00850
00851
00852
00853
00854
00855
00856 int
00857 xstormy16_cgen_get_int_operand (cd, opindex, fields)
00858 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
00859 int opindex;
00860 const CGEN_FIELDS * fields;
00861 {
00862 int value;
00863
00864 switch (opindex)
00865 {
00866 case XSTORMY16_OPERAND_RB :
00867 value = fields->f_Rb;
00868 break;
00869 case XSTORMY16_OPERAND_RBJ :
00870 value = fields->f_Rbj;
00871 break;
00872 case XSTORMY16_OPERAND_RD :
00873 value = fields->f_Rd;
00874 break;
00875 case XSTORMY16_OPERAND_RDM :
00876 value = fields->f_Rdm;
00877 break;
00878 case XSTORMY16_OPERAND_RM :
00879 value = fields->f_Rm;
00880 break;
00881 case XSTORMY16_OPERAND_RS :
00882 value = fields->f_Rs;
00883 break;
00884 case XSTORMY16_OPERAND_ABS24 :
00885 value = fields->f_abs24;
00886 break;
00887 case XSTORMY16_OPERAND_BCOND2 :
00888 value = fields->f_op2;
00889 break;
00890 case XSTORMY16_OPERAND_BCOND5 :
00891 value = fields->f_op5;
00892 break;
00893 case XSTORMY16_OPERAND_HMEM8 :
00894 value = fields->f_hmem8;
00895 break;
00896 case XSTORMY16_OPERAND_IMM12 :
00897 value = fields->f_imm12;
00898 break;
00899 case XSTORMY16_OPERAND_IMM16 :
00900 value = fields->f_imm16;
00901 break;
00902 case XSTORMY16_OPERAND_IMM2 :
00903 value = fields->f_imm2;
00904 break;
00905 case XSTORMY16_OPERAND_IMM3 :
00906 value = fields->f_imm3;
00907 break;
00908 case XSTORMY16_OPERAND_IMM3B :
00909 value = fields->f_imm3b;
00910 break;
00911 case XSTORMY16_OPERAND_IMM4 :
00912 value = fields->f_imm4;
00913 break;
00914 case XSTORMY16_OPERAND_IMM8 :
00915 value = fields->f_imm8;
00916 break;
00917 case XSTORMY16_OPERAND_IMM8SMALL :
00918 value = fields->f_imm8;
00919 break;
00920 case XSTORMY16_OPERAND_LMEM8 :
00921 value = fields->f_lmem8;
00922 break;
00923 case XSTORMY16_OPERAND_REL12 :
00924 value = fields->f_rel12;
00925 break;
00926 case XSTORMY16_OPERAND_REL12A :
00927 value = fields->f_rel12a;
00928 break;
00929 case XSTORMY16_OPERAND_REL8_2 :
00930 value = fields->f_rel8_2;
00931 break;
00932 case XSTORMY16_OPERAND_REL8_4 :
00933 value = fields->f_rel8_4;
00934 break;
00935 case XSTORMY16_OPERAND_WS2 :
00936 value = fields->f_op2m;
00937 break;
00938
00939 default :
00940
00941 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
00942 opindex);
00943 abort ();
00944 }
00945
00946 return value;
00947 }
00948
00949 bfd_vma
00950 xstormy16_cgen_get_vma_operand (cd, opindex, fields)
00951 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
00952 int opindex;
00953 const CGEN_FIELDS * fields;
00954 {
00955 bfd_vma value;
00956
00957 switch (opindex)
00958 {
00959 case XSTORMY16_OPERAND_RB :
00960 value = fields->f_Rb;
00961 break;
00962 case XSTORMY16_OPERAND_RBJ :
00963 value = fields->f_Rbj;
00964 break;
00965 case XSTORMY16_OPERAND_RD :
00966 value = fields->f_Rd;
00967 break;
00968 case XSTORMY16_OPERAND_RDM :
00969 value = fields->f_Rdm;
00970 break;
00971 case XSTORMY16_OPERAND_RM :
00972 value = fields->f_Rm;
00973 break;
00974 case XSTORMY16_OPERAND_RS :
00975 value = fields->f_Rs;
00976 break;
00977 case XSTORMY16_OPERAND_ABS24 :
00978 value = fields->f_abs24;
00979 break;
00980 case XSTORMY16_OPERAND_BCOND2 :
00981 value = fields->f_op2;
00982 break;
00983 case XSTORMY16_OPERAND_BCOND5 :
00984 value = fields->f_op5;
00985 break;
00986 case XSTORMY16_OPERAND_HMEM8 :
00987 value = fields->f_hmem8;
00988 break;
00989 case XSTORMY16_OPERAND_IMM12 :
00990 value = fields->f_imm12;
00991 break;
00992 case XSTORMY16_OPERAND_IMM16 :
00993 value = fields->f_imm16;
00994 break;
00995 case XSTORMY16_OPERAND_IMM2 :
00996 value = fields->f_imm2;
00997 break;
00998 case XSTORMY16_OPERAND_IMM3 :
00999 value = fields->f_imm3;
01000 break;
01001 case XSTORMY16_OPERAND_IMM3B :
01002 value = fields->f_imm3b;
01003 break;
01004 case XSTORMY16_OPERAND_IMM4 :
01005 value = fields->f_imm4;
01006 break;
01007 case XSTORMY16_OPERAND_IMM8 :
01008 value = fields->f_imm8;
01009 break;
01010 case XSTORMY16_OPERAND_IMM8SMALL :
01011 value = fields->f_imm8;
01012 break;
01013 case XSTORMY16_OPERAND_LMEM8 :
01014 value = fields->f_lmem8;
01015 break;
01016 case XSTORMY16_OPERAND_REL12 :
01017 value = fields->f_rel12;
01018 break;
01019 case XSTORMY16_OPERAND_REL12A :
01020 value = fields->f_rel12a;
01021 break;
01022 case XSTORMY16_OPERAND_REL8_2 :
01023 value = fields->f_rel8_2;
01024 break;
01025 case XSTORMY16_OPERAND_REL8_4 :
01026 value = fields->f_rel8_4;
01027 break;
01028 case XSTORMY16_OPERAND_WS2 :
01029 value = fields->f_op2m;
01030 break;
01031
01032 default :
01033
01034 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
01035 opindex);
01036 abort ();
01037 }
01038
01039 return value;
01040 }
01041
01042 void xstormy16_cgen_set_int_operand
01043 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, int));
01044 void xstormy16_cgen_set_vma_operand
01045 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma));
01046
01047
01048
01049
01050
01051
01052 void
01053 xstormy16_cgen_set_int_operand (cd, opindex, fields, value)
01054 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
01055 int opindex;
01056 CGEN_FIELDS * fields;
01057 int value;
01058 {
01059 switch (opindex)
01060 {
01061 case XSTORMY16_OPERAND_RB :
01062 fields->f_Rb = value;
01063 break;
01064 case XSTORMY16_OPERAND_RBJ :
01065 fields->f_Rbj = value;
01066 break;
01067 case XSTORMY16_OPERAND_RD :
01068 fields->f_Rd = value;
01069 break;
01070 case XSTORMY16_OPERAND_RDM :
01071 fields->f_Rdm = value;
01072 break;
01073 case XSTORMY16_OPERAND_RM :
01074 fields->f_Rm = value;
01075 break;
01076 case XSTORMY16_OPERAND_RS :
01077 fields->f_Rs = value;
01078 break;
01079 case XSTORMY16_OPERAND_ABS24 :
01080 fields->f_abs24 = value;
01081 break;
01082 case XSTORMY16_OPERAND_BCOND2 :
01083 fields->f_op2 = value;
01084 break;
01085 case XSTORMY16_OPERAND_BCOND5 :
01086 fields->f_op5 = value;
01087 break;
01088 case XSTORMY16_OPERAND_HMEM8 :
01089 fields->f_hmem8 = value;
01090 break;
01091 case XSTORMY16_OPERAND_IMM12 :
01092 fields->f_imm12 = value;
01093 break;
01094 case XSTORMY16_OPERAND_IMM16 :
01095 fields->f_imm16 = value;
01096 break;
01097 case XSTORMY16_OPERAND_IMM2 :
01098 fields->f_imm2 = value;
01099 break;
01100 case XSTORMY16_OPERAND_IMM3 :
01101 fields->f_imm3 = value;
01102 break;
01103 case XSTORMY16_OPERAND_IMM3B :
01104 fields->f_imm3b = value;
01105 break;
01106 case XSTORMY16_OPERAND_IMM4 :
01107 fields->f_imm4 = value;
01108 break;
01109 case XSTORMY16_OPERAND_IMM8 :
01110 fields->f_imm8 = value;
01111 break;
01112 case XSTORMY16_OPERAND_IMM8SMALL :
01113 fields->f_imm8 = value;
01114 break;
01115 case XSTORMY16_OPERAND_LMEM8 :
01116 fields->f_lmem8 = value;
01117 break;
01118 case XSTORMY16_OPERAND_REL12 :
01119 fields->f_rel12 = value;
01120 break;
01121 case XSTORMY16_OPERAND_REL12A :
01122 fields->f_rel12a = value;
01123 break;
01124 case XSTORMY16_OPERAND_REL8_2 :
01125 fields->f_rel8_2 = value;
01126 break;
01127 case XSTORMY16_OPERAND_REL8_4 :
01128 fields->f_rel8_4 = value;
01129 break;
01130 case XSTORMY16_OPERAND_WS2 :
01131 fields->f_op2m = value;
01132 break;
01133
01134 default :
01135
01136 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
01137 opindex);
01138 abort ();
01139 }
01140 }
01141
01142 void
01143 xstormy16_cgen_set_vma_operand (cd, opindex, fields, value)
01144 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
01145 int opindex;
01146 CGEN_FIELDS * fields;
01147 bfd_vma value;
01148 {
01149 switch (opindex)
01150 {
01151 case XSTORMY16_OPERAND_RB :
01152 fields->f_Rb = value;
01153 break;
01154 case XSTORMY16_OPERAND_RBJ :
01155 fields->f_Rbj = value;
01156 break;
01157 case XSTORMY16_OPERAND_RD :
01158 fields->f_Rd = value;
01159 break;
01160 case XSTORMY16_OPERAND_RDM :
01161 fields->f_Rdm = value;
01162 break;
01163 case XSTORMY16_OPERAND_RM :
01164 fields->f_Rm = value;
01165 break;
01166 case XSTORMY16_OPERAND_RS :
01167 fields->f_Rs = value;
01168 break;
01169 case XSTORMY16_OPERAND_ABS24 :
01170 fields->f_abs24 = value;
01171 break;
01172 case XSTORMY16_OPERAND_BCOND2 :
01173 fields->f_op2 = value;
01174 break;
01175 case XSTORMY16_OPERAND_BCOND5 :
01176 fields->f_op5 = value;
01177 break;
01178 case XSTORMY16_OPERAND_HMEM8 :
01179 fields->f_hmem8 = value;
01180 break;
01181 case XSTORMY16_OPERAND_IMM12 :
01182 fields->f_imm12 = value;
01183 break;
01184 case XSTORMY16_OPERAND_IMM16 :
01185 fields->f_imm16 = value;
01186 break;
01187 case XSTORMY16_OPERAND_IMM2 :
01188 fields->f_imm2 = value;
01189 break;
01190 case XSTORMY16_OPERAND_IMM3 :
01191 fields->f_imm3 = value;
01192 break;
01193 case XSTORMY16_OPERAND_IMM3B :
01194 fields->f_imm3b = value;
01195 break;
01196 case XSTORMY16_OPERAND_IMM4 :
01197 fields->f_imm4 = value;
01198 break;
01199 case XSTORMY16_OPERAND_IMM8 :
01200 fields->f_imm8 = value;
01201 break;
01202 case XSTORMY16_OPERAND_IMM8SMALL :
01203 fields->f_imm8 = value;
01204 break;
01205 case XSTORMY16_OPERAND_LMEM8 :
01206 fields->f_lmem8 = value;
01207 break;
01208 case XSTORMY16_OPERAND_REL12 :
01209 fields->f_rel12 = value;
01210 break;
01211 case XSTORMY16_OPERAND_REL12A :
01212 fields->f_rel12a = value;
01213 break;
01214 case XSTORMY16_OPERAND_REL8_2 :
01215 fields->f_rel8_2 = value;
01216 break;
01217 case XSTORMY16_OPERAND_REL8_4 :
01218 fields->f_rel8_4 = value;
01219 break;
01220 case XSTORMY16_OPERAND_WS2 :
01221 fields->f_op2m = value;
01222 break;
01223
01224 default :
01225
01226 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
01227 opindex);
01228 abort ();
01229 }
01230 }
01231
01232
01233
01234 void
01235 xstormy16_cgen_init_ibld_table (cd)
01236 CGEN_CPU_DESC cd;
01237 {
01238 cd->insert_handlers = & xstormy16_cgen_insert_handlers[0];
01239 cd->extract_handlers = & xstormy16_cgen_extract_handlers[0];
01240
01241 cd->insert_operand = xstormy16_cgen_insert_operand;
01242 cd->extract_operand = xstormy16_cgen_extract_operand;
01243
01244 cd->get_int_operand = xstormy16_cgen_get_int_operand;
01245 cd->set_int_operand = xstormy16_cgen_set_int_operand;
01246 cd->get_vma_operand = xstormy16_cgen_get_vma_operand;
01247 cd->set_vma_operand = xstormy16_cgen_set_vma_operand;
01248 }