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
00028
00029
00030
00031
00032
00033
00034 #include "sysdep.h"
00035 #include <stdio.h>
00036 #include "ansidecl.h"
00037 #include "bfd.h"
00038 #include "symcat.h"
00039 #include "iq2000-desc.h"
00040 #include "iq2000-opc.h"
00041 #include "opintl.h"
00042 #include "xregex.h"
00043 #include "libiberty.h"
00044 #include "safe-ctype.h"
00045
00046 #undef min
00047 #define min(a,b) ((a) < (b) ? (a) : (b))
00048 #undef max
00049 #define max(a,b) ((a) > (b) ? (a) : (b))
00050
00051 static const char * parse_insn_normal
00052 (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
00053
00054
00055
00056
00057
00058 #include "safe-ctype.h"
00059
00060 static int iq2000_cgen_isa_register PARAMS ((const char **));
00061 static const char * parse_jtargq10 PARAMS ((CGEN_CPU_DESC, const char **, int, int, enum cgen_parse_operand_result *, bfd_vma *));
00062 static const char * parse_mimm PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
00063 static const char * parse_imm PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
00064 static const char * parse_hi16 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
00065 static const char * parse_lo16 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
00066 static const char * parse_mlo16 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
00067
00068
00069 int
00070 iq2000_cgen_insn_supported (cd, insn)
00071 CGEN_CPU_DESC cd;
00072 const CGEN_INSN *insn;
00073 {
00074 int machs = cd->machs;
00075
00076 return ((CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH) & machs) != 0);
00077 }
00078
00079 static int iq2000_cgen_isa_register (strp)
00080 const char **strp;
00081 {
00082 int len;
00083 int ch1, ch2;
00084 if (**strp == 'r' || **strp == 'R')
00085 {
00086 len = strlen (*strp);
00087 if (len == 2)
00088 {
00089 ch1 = (*strp)[1];
00090 if ('0' <= ch1 && ch1 <= '9')
00091 return 1;
00092 }
00093 else if (len == 3)
00094 {
00095 ch1 = (*strp)[1];
00096 ch2 = (*strp)[2];
00097 if (('1' <= ch1 && ch1 <= '2') && ('0' <= ch2 && ch2 <= '9'))
00098 return 1;
00099 if ('3' == ch1 && (ch2 == '0' || ch2 == '1'))
00100 return 1;
00101 }
00102 }
00103 if (**strp == '%' && TOLOWER((*strp)[1]) != 'l' && TOLOWER((*strp)[1]) != 'h')
00104 return 1;
00105 return 0;
00106 }
00107
00108
00109
00110 static const char *
00111 parse_mimm (cd, strp, opindex, valuep)
00112 CGEN_CPU_DESC cd;
00113 const char **strp;
00114 int opindex;
00115 unsigned long *valuep;
00116 {
00117 const char *errmsg;
00118
00119
00120 if (iq2000_cgen_isa_register (strp))
00121 errmsg = _("immediate value cannot be register");
00122 else
00123 {
00124 long value;
00125
00126 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
00127 if (errmsg == NULL)
00128 {
00129 long x = (-value) & 0xFFFF0000;
00130
00131 if (x != 0 && x != (long) 0xFFFF0000)
00132 errmsg = _("immediate value out of range");
00133 else
00134 *valuep = (-value & 0xFFFF);
00135 }
00136 }
00137 return errmsg;
00138 }
00139
00140
00141
00142 static const char *
00143 parse_imm (cd, strp, opindex, valuep)
00144 CGEN_CPU_DESC cd;
00145 const char **strp;
00146 int opindex;
00147 unsigned long *valuep;
00148 {
00149 const char *errmsg;
00150
00151 if (iq2000_cgen_isa_register (strp))
00152 errmsg = _("immediate value cannot be register");
00153 else
00154 {
00155 long value;
00156
00157 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
00158 if (errmsg == NULL)
00159 {
00160 long x = value & 0xFFFF0000;
00161 if (x != 0 && x != (long) 0xFFFF0000)
00162 errmsg = _("immediate value out of range");
00163 else
00164 *valuep = (value & 0xFFFF);
00165 }
00166 }
00167 return errmsg;
00168 }
00169
00170
00171
00172 static const char *
00173 parse_jtargq10 (cd, strp, opindex, reloc, type_addr, valuep)
00174 CGEN_CPU_DESC cd;
00175 const char **strp;
00176 int opindex;
00177 int reloc ATTRIBUTE_UNUSED;
00178 enum cgen_parse_operand_result *type_addr ATTRIBUTE_UNUSED;
00179 bfd_vma *valuep;
00180 {
00181 const char *errmsg;
00182 bfd_vma value;
00183 enum cgen_parse_operand_result result_type = CGEN_PARSE_OPERAND_RESULT_NUMBER;
00184
00185 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_OFFSET_21,
00186 &result_type, &value);
00187 if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
00188 {
00189
00190 if (value > 0x7fffff)
00191 return _("21-bit offset out of range");
00192 }
00193 *valuep = (value & 0x7FFFFF);
00194 return errmsg;
00195 }
00196
00197
00198
00199 static const char *
00200 parse_hi16 (cd, strp, opindex, valuep)
00201 CGEN_CPU_DESC cd;
00202 const char **strp;
00203 int opindex;
00204 unsigned long *valuep;
00205 {
00206 if (strncasecmp (*strp, "%hi(", 4) == 0)
00207 {
00208 enum cgen_parse_operand_result result_type;
00209 bfd_vma value;
00210 const char *errmsg;
00211
00212 *strp += 4;
00213 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
00214 &result_type, &value);
00215 if (**strp != ')')
00216 return _("missing `)'");
00217
00218 ++*strp;
00219 if (errmsg == NULL
00220 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
00221 {
00222
00223
00224
00225 if (value & 0x8000)
00226 value += 0x10000;
00227 value >>= 16;
00228 }
00229 *valuep = value;
00230
00231 return errmsg;
00232 }
00233
00234
00235
00236 if (strncasecmp (*strp, "%uhi(", 5) == 0)
00237 {
00238 enum cgen_parse_operand_result result_type;
00239 bfd_vma value;
00240 const char *errmsg;
00241
00242 *strp += 5;
00243 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_IQ2000_UHI16,
00244 &result_type, &value);
00245 if (**strp != ')')
00246 return _("missing `)'");
00247
00248 ++*strp;
00249 if (errmsg == NULL
00250 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
00251 {
00252 value >>= 16;
00253 }
00254 *valuep = value;
00255
00256 return errmsg;
00257 }
00258
00259 return parse_imm (cd, strp, opindex, valuep);
00260 }
00261
00262
00263
00264
00265
00266 static const char *
00267 parse_lo16 (cd, strp, opindex, valuep)
00268 CGEN_CPU_DESC cd;
00269 const char **strp;
00270 int opindex;
00271 unsigned long *valuep;
00272 {
00273 if (strncasecmp (*strp, "%lo(", 4) == 0)
00274 {
00275 const char *errmsg;
00276 enum cgen_parse_operand_result result_type;
00277 bfd_vma value;
00278
00279 *strp += 4;
00280 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
00281 &result_type, &value);
00282 if (**strp != ')')
00283 return _("missing `)'");
00284 ++*strp;
00285 if (errmsg == NULL
00286 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
00287 value &= 0xffff;
00288 *valuep = value;
00289 return errmsg;
00290 }
00291
00292 return parse_imm (cd, strp, opindex, valuep);
00293 }
00294
00295
00296
00297
00298
00299 static const char *
00300 parse_mlo16 (cd, strp, opindex, valuep)
00301 CGEN_CPU_DESC cd;
00302 const char **strp;
00303 int opindex;
00304 unsigned long *valuep;
00305 {
00306 if (strncasecmp (*strp, "%lo(", 4) == 0)
00307 {
00308 const char *errmsg;
00309 enum cgen_parse_operand_result result_type;
00310 bfd_vma value;
00311
00312 *strp += 4;
00313 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
00314 &result_type, &value);
00315 if (**strp != ')')
00316 return _("missing `)'");
00317 ++*strp;
00318 if (errmsg == NULL
00319 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
00320 value = (-value) & 0xffff;
00321 *valuep = value;
00322 return errmsg;
00323 }
00324
00325 return parse_mimm (cd, strp, opindex, valuep);
00326 }
00327
00328
00329
00330 const char * iq2000_cgen_parse_operand
00331 PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 const char *
00347 iq2000_cgen_parse_operand (cd, opindex, strp, fields)
00348 CGEN_CPU_DESC cd;
00349 int opindex;
00350 const char ** strp;
00351 CGEN_FIELDS * fields;
00352 {
00353 const char * errmsg = NULL;
00354
00355 long junk ATTRIBUTE_UNUSED;
00356
00357 switch (opindex)
00358 {
00359 case IQ2000_OPERAND__INDEX :
00360 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND__INDEX, (unsigned long *) (& fields->f_index));
00361 break;
00362 case IQ2000_OPERAND_BASE :
00363 errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rs);
00364 break;
00365 case IQ2000_OPERAND_BASEOFF :
00366 {
00367 bfd_vma value;
00368 errmsg = cgen_parse_address (cd, strp, IQ2000_OPERAND_BASEOFF, 0, NULL, & value);
00369 fields->f_imm = value;
00370 }
00371 break;
00372 case IQ2000_OPERAND_BITNUM :
00373 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_BITNUM, (unsigned long *) (& fields->f_rt));
00374 break;
00375 case IQ2000_OPERAND_BYTECOUNT :
00376 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_BYTECOUNT, (unsigned long *) (& fields->f_bytecount));
00377 break;
00378 case IQ2000_OPERAND_CAM_Y :
00379 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CAM_Y, (unsigned long *) (& fields->f_cam_y));
00380 break;
00381 case IQ2000_OPERAND_CAM_Z :
00382 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CAM_Z, (unsigned long *) (& fields->f_cam_z));
00383 break;
00384 case IQ2000_OPERAND_CM_3FUNC :
00385 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CM_3FUNC, (unsigned long *) (& fields->f_cm_3func));
00386 break;
00387 case IQ2000_OPERAND_CM_3Z :
00388 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CM_3Z, (unsigned long *) (& fields->f_cm_3z));
00389 break;
00390 case IQ2000_OPERAND_CM_4FUNC :
00391 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CM_4FUNC, (unsigned long *) (& fields->f_cm_4func));
00392 break;
00393 case IQ2000_OPERAND_CM_4Z :
00394 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_CM_4Z, (unsigned long *) (& fields->f_cm_4z));
00395 break;
00396 case IQ2000_OPERAND_COUNT :
00397 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_COUNT, (unsigned long *) (& fields->f_count));
00398 break;
00399 case IQ2000_OPERAND_EXECODE :
00400 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_EXECODE, (unsigned long *) (& fields->f_excode));
00401 break;
00402 case IQ2000_OPERAND_HI16 :
00403 errmsg = parse_hi16 (cd, strp, IQ2000_OPERAND_HI16, (unsigned long *) (& fields->f_imm));
00404 break;
00405 case IQ2000_OPERAND_IMM :
00406 errmsg = parse_imm (cd, strp, IQ2000_OPERAND_IMM, (unsigned long *) (& fields->f_imm));
00407 break;
00408 case IQ2000_OPERAND_JMPTARG :
00409 {
00410 bfd_vma value;
00411 errmsg = cgen_parse_address (cd, strp, IQ2000_OPERAND_JMPTARG, 0, NULL, & value);
00412 fields->f_jtarg = value;
00413 }
00414 break;
00415 case IQ2000_OPERAND_JMPTARGQ10 :
00416 {
00417 bfd_vma value = 0;
00418
00419 errmsg = parse_jtargq10 (cd, strp, IQ2000_OPERAND_JMPTARGQ10, 0, NULL, & value);
00420 fields->f_jtargq10 = value;
00421 }
00422 break;
00423 case IQ2000_OPERAND_LO16 :
00424 errmsg = parse_lo16 (cd, strp, IQ2000_OPERAND_LO16, (unsigned long *) (& fields->f_imm));
00425 break;
00426 case IQ2000_OPERAND_MASK :
00427 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_MASK, (unsigned long *) (& fields->f_mask));
00428 break;
00429 case IQ2000_OPERAND_MASKL :
00430 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_MASKL, (unsigned long *) (& fields->f_maskl));
00431 break;
00432 case IQ2000_OPERAND_MASKQ10 :
00433 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_MASKQ10, (unsigned long *) (& fields->f_maskq10));
00434 break;
00435 case IQ2000_OPERAND_MASKR :
00436 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_MASKR, (unsigned long *) (& fields->f_rs));
00437 break;
00438 case IQ2000_OPERAND_MLO16 :
00439 errmsg = parse_mlo16 (cd, strp, IQ2000_OPERAND_MLO16, (unsigned long *) (& fields->f_imm));
00440 break;
00441 case IQ2000_OPERAND_OFFSET :
00442 {
00443 bfd_vma value;
00444 errmsg = cgen_parse_address (cd, strp, IQ2000_OPERAND_OFFSET, 0, NULL, & value);
00445 fields->f_offset = value;
00446 }
00447 break;
00448 case IQ2000_OPERAND_RD :
00449 errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rd);
00450 break;
00451 case IQ2000_OPERAND_RD_RS :
00452 errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rd_rs);
00453 break;
00454 case IQ2000_OPERAND_RD_RT :
00455 errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rd_rt);
00456 break;
00457 case IQ2000_OPERAND_RS :
00458 errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rs);
00459 break;
00460 case IQ2000_OPERAND_RT :
00461 errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rt);
00462 break;
00463 case IQ2000_OPERAND_RT_RS :
00464 errmsg = cgen_parse_keyword (cd, strp, & iq2000_cgen_opval_gr_names, & fields->f_rt_rs);
00465 break;
00466 case IQ2000_OPERAND_SHAMT :
00467 errmsg = cgen_parse_unsigned_integer (cd, strp, IQ2000_OPERAND_SHAMT, (unsigned long *) (& fields->f_shamt));
00468 break;
00469
00470 default :
00471
00472 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
00473 abort ();
00474 }
00475
00476 return errmsg;
00477 }
00478
00479 cgen_parse_fn * const iq2000_cgen_parse_handlers[] =
00480 {
00481 parse_insn_normal,
00482 };
00483
00484 void
00485 iq2000_cgen_init_asm (cd)
00486 CGEN_CPU_DESC cd;
00487 {
00488 iq2000_cgen_init_opcode_table (cd);
00489 iq2000_cgen_init_ibld_table (cd);
00490 cd->parse_handlers = & iq2000_cgen_parse_handlers[0];
00491 cd->parse_operand = iq2000_cgen_parse_operand;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 char *
00508 iq2000_cgen_build_insn_regex (CGEN_INSN *insn)
00509 {
00510 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
00511 const char *mnem = CGEN_INSN_MNEMONIC (insn);
00512 char rxbuf[CGEN_MAX_RX_ELEMENTS];
00513 char *rx = rxbuf;
00514 const CGEN_SYNTAX_CHAR_TYPE *syn;
00515 int reg_err;
00516
00517 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
00518
00519
00520 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
00521 return _("missing mnemonic in syntax string");
00522 ++syn;
00523
00524
00525
00526
00527
00528
00529
00530 for (; *mnem; mnem++)
00531 {
00532 char c = *mnem;
00533
00534 if (ISALPHA (c))
00535 {
00536 *rx++ = '[';
00537 *rx++ = TOLOWER (c);
00538 *rx++ = TOUPPER (c);
00539 *rx++ = ']';
00540 }
00541 else
00542 *rx++ = c;
00543 }
00544
00545
00546 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
00547 {
00548 if (CGEN_SYNTAX_CHAR_P (* syn))
00549 {
00550 char c = CGEN_SYNTAX_CHAR (* syn);
00551
00552 switch (c)
00553 {
00554
00555 case '.': case '[': case '\\':
00556 case '*': case '^': case '$':
00557
00558 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
00559 case '?': case '{': case '}':
00560 case '(': case ')': case '*':
00561 case '|': case '+': case ']':
00562 #endif
00563 *rx++ = '\\';
00564 *rx++ = c;
00565 break;
00566
00567 default:
00568 if (ISALPHA (c))
00569 {
00570 *rx++ = '[';
00571 *rx++ = TOLOWER (c);
00572 *rx++ = TOUPPER (c);
00573 *rx++ = ']';
00574 }
00575 else
00576 *rx++ = c;
00577 break;
00578 }
00579 }
00580 else
00581 {
00582
00583 *rx++ = '.';
00584 *rx++ = '*';
00585 }
00586 }
00587
00588
00589 * rx++ = '[';
00590 * rx++ = ' ';
00591 * rx++ = '\t';
00592 * rx++ = ']';
00593 * rx++ = '*';
00594
00595
00596 * rx++ = '$';
00597 * rx = '\0';
00598
00599 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
00600 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
00601
00602 if (reg_err == 0)
00603 return NULL;
00604 else
00605 {
00606 static char msg[80];
00607
00608 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
00609 regfree ((regex_t *) CGEN_INSN_RX (insn));
00610 free (CGEN_INSN_RX (insn));
00611 (CGEN_INSN_RX (insn)) = NULL;
00612 return msg;
00613 }
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 static const char *
00631 parse_insn_normal (CGEN_CPU_DESC cd,
00632 const CGEN_INSN *insn,
00633 const char **strp,
00634 CGEN_FIELDS *fields)
00635 {
00636
00637 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
00638 const char *str = *strp;
00639 const char *errmsg;
00640 const char *p;
00641 const CGEN_SYNTAX_CHAR_TYPE * syn;
00642 #ifdef CGEN_MNEMONIC_OPERANDS
00643
00644 int past_opcode_p;
00645 #endif
00646
00647
00648
00649
00650
00651 p = CGEN_INSN_MNEMONIC (insn);
00652 while (*p && TOLOWER (*p) == TOLOWER (*str))
00653 ++p, ++str;
00654
00655 if (* p)
00656 return _("unrecognized instruction");
00657
00658 #ifndef CGEN_MNEMONIC_OPERANDS
00659 if (* str && ! ISSPACE (* str))
00660 return _("unrecognized instruction");
00661 #endif
00662
00663 CGEN_INIT_PARSE (cd);
00664 cgen_init_parse_operand (cd);
00665 #ifdef CGEN_MNEMONIC_OPERANDS
00666 past_opcode_p = 0;
00667 #endif
00668
00669
00670
00671 syn = CGEN_SYNTAX_STRING (syntax);
00672
00673
00674 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
00675 abort ();
00676
00677 ++syn;
00678
00679 while (* syn != 0)
00680 {
00681
00682 if (CGEN_SYNTAX_CHAR_P (* syn))
00683 {
00684
00685
00686
00687
00688 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
00689 {
00690 #ifdef CGEN_MNEMONIC_OPERANDS
00691 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
00692 past_opcode_p = 1;
00693 #endif
00694 ++ syn;
00695 ++ str;
00696 }
00697 else if (*str)
00698 {
00699
00700 static char msg [80];
00701
00702
00703 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
00704 CGEN_SYNTAX_CHAR(*syn), *str);
00705 return msg;
00706 }
00707 else
00708 {
00709
00710 static char msg [80];
00711
00712
00713 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
00714 CGEN_SYNTAX_CHAR(*syn));
00715 return msg;
00716 }
00717 continue;
00718 }
00719
00720
00721 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
00722 &str, fields);
00723 if (errmsg)
00724 return errmsg;
00725
00726
00727 ++ syn;
00728 }
00729
00730
00731 if (* syn == 0)
00732 {
00733
00734
00735
00736
00737 while (ISSPACE (* str))
00738 ++ str;
00739
00740 if (* str != '\0')
00741 return _("junk at end of line");
00742
00743 return NULL;
00744 }
00745
00746
00747 return _("unrecognized instruction");
00748 }
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 const CGEN_INSN *
00772 iq2000_cgen_assemble_insn (CGEN_CPU_DESC cd,
00773 const char *str,
00774 CGEN_FIELDS *fields,
00775 CGEN_INSN_BYTES_PTR buf,
00776 char **errmsg)
00777 {
00778 const char *start;
00779 CGEN_INSN_LIST *ilist;
00780 const char *parse_errmsg = NULL;
00781 const char *insert_errmsg = NULL;
00782 int recognized_mnemonic = 0;
00783
00784
00785 while (ISSPACE (* str))
00786 ++ str;
00787
00788
00789
00790 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
00791
00792
00793 start = str;
00794 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
00795 {
00796 const CGEN_INSN *insn = ilist->insn;
00797 recognized_mnemonic = 1;
00798
00799 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
00800
00801
00802
00803 if (! iq2000_cgen_insn_supported (cd, insn))
00804 continue;
00805 #endif
00806
00807
00808
00809 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
00810 continue;
00811
00812 str = start;
00813
00814
00815 if (CGEN_INSN_RX (insn) != NULL &&
00816 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
00817 continue;
00818
00819
00820 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
00821
00822 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
00823 if (parse_errmsg != NULL)
00824 continue;
00825
00826
00827 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
00828 (bfd_vma) 0);
00829 if (insert_errmsg != NULL)
00830 continue;
00831
00832
00833
00834 return insn;
00835 }
00836
00837 {
00838 static char errbuf[150];
00839 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
00840 const char *tmp_errmsg;
00841
00842
00843
00844 tmp_errmsg = (insert_errmsg ? insert_errmsg :
00845 parse_errmsg ? parse_errmsg :
00846 recognized_mnemonic ?
00847 _("unrecognized form of instruction") :
00848 _("unrecognized instruction"));
00849
00850 if (strlen (start) > 50)
00851
00852 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
00853 else
00854
00855 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
00856 #else
00857 if (strlen (start) > 50)
00858
00859 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
00860 else
00861
00862 sprintf (errbuf, _("bad instruction `%.50s'"), start);
00863 #endif
00864
00865 *errmsg = errbuf;
00866 return NULL;
00867 }
00868 }
00869
00870 #if 0
00871
00872
00873
00874
00875
00876
00877
00878
00879 void
00880 iq2000_cgen_asm_hash_keywords (CGEN_CPU_DESC cd, CGEN_KEYWORD *opvals)
00881 {
00882 CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
00883 const CGEN_KEYWORD_ENTRY * ke;
00884
00885 while ((ke = cgen_keyword_search_next (& search)) != NULL)
00886 {
00887 #if 0
00888 if (! iq2000_cgen_opval_supported (ke))
00889 continue;
00890 #endif
00891 cgen_asm_record_register (cd, ke->name, ke->value);
00892 }
00893 }
00894
00895 #endif