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 "frv-desc.h"
00040 #include "frv-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 static const char * parse_ulo16
00058 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
00059 static const char * parse_uslo16
00060 PARAMS ((CGEN_CPU_DESC, const char **, int, signed long *));
00061 static const char * parse_uhi16
00062 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
00063 static long parse_register_number
00064 PARAMS ((const char **));
00065 static const char * parse_spr
00066 PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
00067 static const char * parse_d12
00068 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
00069 static const char * parse_s12
00070 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
00071 static const char * parse_u12
00072 PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
00073 static const char * parse_even_register
00074 PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
00075 static const char * parse_A0
00076 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
00077 static const char * parse_A1
00078 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
00079 static const char * parse_A
00080 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *, unsigned long));
00081
00082 inline static const char *
00083 parse_symbolic_address (CGEN_CPU_DESC cd,
00084 const char **strp,
00085 int opindex,
00086 int opinfo,
00087 enum cgen_parse_operand_result *resultp,
00088 bfd_vma *valuep)
00089 {
00090 enum cgen_parse_operand_result result_type;
00091 const char *errmsg = (* cd->parse_operand_fn)
00092 (cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo,
00093 &result_type, valuep);
00094
00095 if (errmsg == NULL
00096 && result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)
00097 return "symbolic expression required";
00098
00099 if (resultp)
00100 *resultp = result_type;
00101
00102 return errmsg;
00103 }
00104
00105 static const char *
00106 parse_ldd_annotation (CGEN_CPU_DESC cd,
00107 const char **strp,
00108 int opindex,
00109 unsigned long *valuep)
00110 {
00111 const char *errmsg;
00112 enum cgen_parse_operand_result result_type;
00113 bfd_vma value;
00114
00115 if (**strp == '#' || **strp == '%')
00116 {
00117 if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0)
00118 {
00119 *strp += 9;
00120 errmsg = parse_symbolic_address (cd, strp, opindex,
00121 BFD_RELOC_FRV_TLSDESC_RELAX,
00122 &result_type, &value);
00123 if (**strp != ')')
00124 return "missing ')'";
00125 if (valuep)
00126 *valuep = value;
00127 ++*strp;
00128 if (errmsg)
00129 return errmsg;
00130 }
00131 }
00132
00133 while (**strp == ' ' || **strp == '\t')
00134 ++*strp;
00135
00136 if (**strp != '@')
00137 return "missing `@'";
00138
00139 ++*strp;
00140
00141 return NULL;
00142 }
00143
00144 static const char *
00145 parse_call_annotation (CGEN_CPU_DESC cd,
00146 const char **strp,
00147 int opindex,
00148 unsigned long *valuep)
00149 {
00150 const char *errmsg;
00151 enum cgen_parse_operand_result result_type;
00152 bfd_vma value;
00153
00154 if (**strp == '#' || **strp == '%')
00155 {
00156 if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
00157 {
00158 *strp += 11;
00159 errmsg = parse_symbolic_address (cd, strp, opindex,
00160 BFD_RELOC_FRV_GETTLSOFF_RELAX,
00161 &result_type, &value);
00162 if (**strp != ')')
00163 return "missing ')'";
00164 if (valuep)
00165 *valuep = value;
00166 ++*strp;
00167 if (errmsg)
00168 return errmsg;
00169 }
00170 }
00171
00172 while (**strp == ' ' || **strp == '\t')
00173 ++*strp;
00174
00175 if (**strp != '@')
00176 return "missing `@'";
00177
00178 ++*strp;
00179
00180 return NULL;
00181 }
00182
00183 static const char *
00184 parse_ld_annotation (CGEN_CPU_DESC cd,
00185 const char **strp,
00186 int opindex,
00187 unsigned long *valuep)
00188 {
00189 const char *errmsg;
00190 enum cgen_parse_operand_result result_type;
00191 bfd_vma value;
00192
00193 if (**strp == '#' || **strp == '%')
00194 {
00195 if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0)
00196 {
00197 *strp += 8;
00198 errmsg = parse_symbolic_address (cd, strp, opindex,
00199 BFD_RELOC_FRV_TLSOFF_RELAX,
00200 &result_type, &value);
00201 if (**strp != ')')
00202 return "missing ')'";
00203 if (valuep)
00204 *valuep = value;
00205 ++*strp;
00206 if (errmsg)
00207 return errmsg;
00208 }
00209 }
00210
00211 while (**strp == ' ' || **strp == '\t')
00212 ++*strp;
00213
00214 if (**strp != '@')
00215 return "missing `@'";
00216
00217 ++*strp;
00218
00219 return NULL;
00220 }
00221
00222 static const char *
00223 parse_ulo16 (cd, strp, opindex, valuep)
00224 CGEN_CPU_DESC cd;
00225 const char **strp;
00226 int opindex;
00227 unsigned long *valuep;
00228 {
00229 const char *errmsg;
00230 enum cgen_parse_operand_result result_type;
00231 bfd_vma value;
00232
00233 if (**strp == '#' || **strp == '%')
00234 {
00235 if (strncasecmp (*strp + 1, "lo(", 3) == 0)
00236 {
00237 *strp += 4;
00238 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
00239 &result_type, &value);
00240 if (**strp != ')')
00241 return "missing `)'";
00242 ++*strp;
00243 if (errmsg == NULL
00244 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
00245 value &= 0xffff;
00246 *valuep = value;
00247 return errmsg;
00248 }
00249 if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
00250 {
00251 *strp += 9;
00252 errmsg = parse_symbolic_address (cd, strp, opindex,
00253 BFD_RELOC_FRV_GPRELLO,
00254 &result_type, &value);
00255 if (**strp != ')')
00256 return "missing ')'";
00257 ++*strp;
00258 *valuep = value;
00259 return errmsg;
00260 }
00261 else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
00262 {
00263 *strp += 7;
00264 errmsg = parse_symbolic_address (cd, strp, opindex,
00265 BFD_RELOC_FRV_GOTLO,
00266 &result_type, &value);
00267 if (**strp != ')')
00268 return "missing ')'";
00269 ++*strp;
00270 *valuep = value;
00271 return errmsg;
00272 }
00273 else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
00274 {
00275 *strp += 15;
00276 errmsg = parse_symbolic_address (cd, strp, opindex,
00277 BFD_RELOC_FRV_FUNCDESC_GOTLO,
00278 &result_type, &value);
00279 if (**strp != ')')
00280 return "missing ')'";
00281 ++*strp;
00282 *valuep = value;
00283 return errmsg;
00284 }
00285 else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
00286 {
00287 *strp += 10;
00288 errmsg = parse_symbolic_address (cd, strp, opindex,
00289 BFD_RELOC_FRV_GOTOFFLO,
00290 &result_type, &value);
00291 if (**strp != ')')
00292 return "missing ')'";
00293 ++*strp;
00294 *valuep = value;
00295 return errmsg;
00296 }
00297 else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
00298 {
00299 *strp += 18;
00300 errmsg = parse_symbolic_address (cd, strp, opindex,
00301 BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
00302 &result_type, &value);
00303 if (**strp != ')')
00304 return "missing ')'";
00305 ++*strp;
00306 *valuep = value;
00307 return errmsg;
00308 }
00309 else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
00310 {
00311 *strp += 14;
00312 errmsg = parse_symbolic_address (cd, strp, opindex,
00313 BFD_RELOC_FRV_GOTTLSDESCLO,
00314 &result_type, &value);
00315 if (**strp != ')')
00316 return "missing ')'";
00317 ++*strp;
00318 *valuep = value;
00319 return errmsg;
00320 }
00321 else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
00322 {
00323 *strp += 11;
00324 errmsg = parse_symbolic_address (cd, strp, opindex,
00325 BFD_RELOC_FRV_TLSMOFFLO,
00326 &result_type, &value);
00327 if (**strp != ')')
00328 return "missing ')'";
00329 ++*strp;
00330 *valuep = value;
00331 return errmsg;
00332 }
00333 else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
00334 {
00335 *strp += 13;
00336 errmsg = parse_symbolic_address (cd, strp, opindex,
00337 BFD_RELOC_FRV_GOTTLSOFFLO,
00338 &result_type, &value);
00339 if (**strp != ')')
00340 return "missing ')'";
00341 ++*strp;
00342 *valuep = value;
00343 return errmsg;
00344 }
00345 }
00346 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
00347 }
00348
00349 static const char *
00350 parse_uslo16 (cd, strp, opindex, valuep)
00351 CGEN_CPU_DESC cd;
00352 const char **strp;
00353 int opindex;
00354 signed long *valuep;
00355 {
00356 const char *errmsg;
00357 enum cgen_parse_operand_result result_type;
00358 bfd_vma value;
00359
00360 if (**strp == '#' || **strp == '%')
00361 {
00362 if (strncasecmp (*strp + 1, "lo(", 3) == 0)
00363 {
00364 *strp += 4;
00365 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
00366 &result_type, &value);
00367 if (**strp != ')')
00368 return "missing `)'";
00369 ++*strp;
00370 if (errmsg == NULL
00371 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
00372 value &= 0xffff;
00373 *valuep = value;
00374 return errmsg;
00375 }
00376 else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
00377 {
00378 *strp += 9;
00379 errmsg = parse_symbolic_address (cd, strp, opindex,
00380 BFD_RELOC_FRV_GPRELLO,
00381 &result_type, &value);
00382 if (**strp != ')')
00383 return "missing ')'";
00384 ++*strp;
00385 *valuep = value;
00386 return errmsg;
00387 }
00388 else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
00389 {
00390 *strp += 7;
00391 errmsg = parse_symbolic_address (cd, strp, opindex,
00392 BFD_RELOC_FRV_GOTLO,
00393 &result_type, &value);
00394 if (**strp != ')')
00395 return "missing ')'";
00396 ++*strp;
00397 *valuep = value;
00398 return errmsg;
00399 }
00400 else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
00401 {
00402 *strp += 15;
00403 errmsg = parse_symbolic_address (cd, strp, opindex,
00404 BFD_RELOC_FRV_FUNCDESC_GOTLO,
00405 &result_type, &value);
00406 if (**strp != ')')
00407 return "missing ')'";
00408 ++*strp;
00409 *valuep = value;
00410 return errmsg;
00411 }
00412 else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
00413 {
00414 *strp += 10;
00415 errmsg = parse_symbolic_address (cd, strp, opindex,
00416 BFD_RELOC_FRV_GOTOFFLO,
00417 &result_type, &value);
00418 if (**strp != ')')
00419 return "missing ')'";
00420 ++*strp;
00421 *valuep = value;
00422 return errmsg;
00423 }
00424 else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
00425 {
00426 *strp += 18;
00427 errmsg = parse_symbolic_address (cd, strp, opindex,
00428 BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
00429 &result_type, &value);
00430 if (**strp != ')')
00431 return "missing ')'";
00432 ++*strp;
00433 *valuep = value;
00434 return errmsg;
00435 }
00436 else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
00437 {
00438 *strp += 14;
00439 errmsg = parse_symbolic_address (cd, strp, opindex,
00440 BFD_RELOC_FRV_GOTTLSDESCLO,
00441 &result_type, &value);
00442 if (**strp != ')')
00443 return "missing ')'";
00444 ++*strp;
00445 *valuep = value;
00446 return errmsg;
00447 }
00448 else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
00449 {
00450 *strp += 11;
00451 errmsg = parse_symbolic_address (cd, strp, opindex,
00452 BFD_RELOC_FRV_TLSMOFFLO,
00453 &result_type, &value);
00454 if (**strp != ')')
00455 return "missing ')'";
00456 ++*strp;
00457 *valuep = value;
00458 return errmsg;
00459 }
00460 else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
00461 {
00462 *strp += 13;
00463 errmsg = parse_symbolic_address (cd, strp, opindex,
00464 BFD_RELOC_FRV_GOTTLSOFFLO,
00465 &result_type, &value);
00466 if (**strp != ')')
00467 return "missing ')'";
00468 ++*strp;
00469 *valuep = value;
00470 return errmsg;
00471 }
00472 }
00473 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
00474 }
00475
00476 static const char *
00477 parse_uhi16 (cd, strp, opindex, valuep)
00478 CGEN_CPU_DESC cd;
00479 const char **strp;
00480 int opindex;
00481 unsigned long *valuep;
00482 {
00483 const char *errmsg;
00484 enum cgen_parse_operand_result result_type;
00485 bfd_vma value;
00486
00487 if (**strp == '#' || **strp == '%')
00488 {
00489 if (strncasecmp (*strp + 1, "hi(", 3) == 0)
00490 {
00491 *strp += 4;
00492 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
00493 &result_type, &value);
00494 if (**strp != ')')
00495 return "missing `)'";
00496 ++*strp;
00497 if (errmsg == NULL
00498 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
00499 {
00500
00501
00502 if (value >= - ((bfd_vma)1 << 31)
00503 || value <= ((bfd_vma)1 << 31) - (bfd_vma)1)
00504 value &= (((bfd_vma)1 << 16) << 16) - 1;
00505 value >>= 16;
00506 }
00507 *valuep = value;
00508 return errmsg;
00509 }
00510 else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
00511 {
00512 *strp += 9;
00513 errmsg = parse_symbolic_address (cd, strp, opindex,
00514 BFD_RELOC_FRV_GPRELHI,
00515 &result_type, &value);
00516 if (**strp != ')')
00517 return "missing ')'";
00518 ++*strp;
00519 *valuep = value;
00520 return errmsg;
00521 }
00522 else if (strncasecmp (*strp + 1, "gothi(", 6) == 0)
00523 {
00524 *strp += 7;
00525 errmsg = parse_symbolic_address (cd, strp, opindex,
00526 BFD_RELOC_FRV_GOTHI,
00527 &result_type, &value);
00528 if (**strp != ')')
00529 return "missing ')'";
00530 ++*strp;
00531 *valuep = value;
00532 return errmsg;
00533 }
00534 else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0)
00535 {
00536 *strp += 15;
00537 errmsg = parse_symbolic_address (cd, strp, opindex,
00538 BFD_RELOC_FRV_FUNCDESC_GOTHI,
00539 &result_type, &value);
00540 if (**strp != ')')
00541 return "missing ')'";
00542 ++*strp;
00543 *valuep = value;
00544 return errmsg;
00545 }
00546 else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0)
00547 {
00548 *strp += 10;
00549 errmsg = parse_symbolic_address (cd, strp, opindex,
00550 BFD_RELOC_FRV_GOTOFFHI,
00551 &result_type, &value);
00552 if (**strp != ')')
00553 return "missing ')'";
00554 ++*strp;
00555 *valuep = value;
00556 return errmsg;
00557 }
00558 else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0)
00559 {
00560 *strp += 18;
00561 errmsg = parse_symbolic_address (cd, strp, opindex,
00562 BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
00563 &result_type, &value);
00564 if (**strp != ')')
00565 return "missing ')'";
00566 ++*strp;
00567 *valuep = value;
00568 return errmsg;
00569 }
00570 else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0)
00571 {
00572 *strp += 14;
00573 errmsg = parse_symbolic_address (cd, strp, opindex,
00574 BFD_RELOC_FRV_GOTTLSDESCHI,
00575 &result_type, &value);
00576 if (**strp != ')')
00577 return "missing ')'";
00578 ++*strp;
00579 *valuep = value;
00580 return errmsg;
00581 }
00582 else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0)
00583 {
00584 *strp += 11;
00585 errmsg = parse_symbolic_address (cd, strp, opindex,
00586 BFD_RELOC_FRV_TLSMOFFHI,
00587 &result_type, &value);
00588 if (**strp != ')')
00589 return "missing ')'";
00590 ++*strp;
00591 *valuep = value;
00592 return errmsg;
00593 }
00594 else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0)
00595 {
00596 *strp += 13;
00597 errmsg = parse_symbolic_address (cd, strp, opindex,
00598 BFD_RELOC_FRV_GOTTLSOFFHI,
00599 &result_type, &value);
00600 if (**strp != ')')
00601 return "missing ')'";
00602 ++*strp;
00603 *valuep = value;
00604 return errmsg;
00605 }
00606 }
00607 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
00608 }
00609
00610 static long
00611 parse_register_number (strp)
00612 const char **strp;
00613 {
00614 int regno;
00615 if (**strp < '0' || **strp > '9')
00616 return -1;
00617
00618 regno = **strp - '0';
00619 for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
00620 regno = regno * 10 + (**strp - '0');
00621
00622 return regno;
00623 }
00624
00625 static const char *
00626 parse_spr (cd, strp, table, valuep)
00627 CGEN_CPU_DESC cd;
00628 const char **strp;
00629 CGEN_KEYWORD * table;
00630 long *valuep;
00631 {
00632 const char *save_strp;
00633 long regno;
00634
00635
00636 if (strncasecmp (*strp, "spr[", 4) == 0)
00637 {
00638 *strp += 4;
00639 regno = parse_register_number (strp);
00640 if (**strp != ']')
00641 return "missing `]'";
00642 ++*strp;
00643 if (! spr_valid (regno))
00644 return "Special purpose register number is out of range";
00645 *valuep = regno;
00646 return NULL;
00647 }
00648
00649 save_strp = *strp;
00650 regno = parse_register_number (strp);
00651 if (regno != -1)
00652 {
00653 if (! spr_valid (regno))
00654 return "Special purpose register number is out of range";
00655 *valuep = regno;
00656 return NULL;
00657 }
00658
00659 *strp = save_strp;
00660 return cgen_parse_keyword (cd, strp, table, valuep);
00661 }
00662
00663 static const char *
00664 parse_d12 (cd, strp, opindex, valuep)
00665 CGEN_CPU_DESC cd;
00666 const char **strp;
00667 int opindex;
00668 long *valuep;
00669 {
00670 const char *errmsg;
00671 enum cgen_parse_operand_result result_type;
00672 bfd_vma value;
00673
00674
00675 if (**strp == '#' || **strp == '%')
00676 {
00677 if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
00678 {
00679 *strp += 9;
00680 errmsg = parse_symbolic_address (cd, strp, opindex,
00681 BFD_RELOC_FRV_GPREL12,
00682 &result_type, &value);
00683 if (**strp != ')')
00684 return "missing `)'";
00685 ++*strp;
00686 *valuep = value;
00687 return errmsg;
00688 }
00689 else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
00690 {
00691 *strp += 7;
00692 errmsg = parse_symbolic_address (cd, strp, opindex,
00693 BFD_RELOC_FRV_GOT12,
00694 &result_type, &value);
00695 if (**strp != ')')
00696 return "missing ')'";
00697 ++*strp;
00698 *valuep = value;
00699 return errmsg;
00700 }
00701 else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
00702 {
00703 *strp += 15;
00704 errmsg = parse_symbolic_address (cd, strp, opindex,
00705 BFD_RELOC_FRV_FUNCDESC_GOT12,
00706 &result_type, &value);
00707 if (**strp != ')')
00708 return "missing ')'";
00709 ++*strp;
00710 *valuep = value;
00711 return errmsg;
00712 }
00713 else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
00714 {
00715 *strp += 10;
00716 errmsg = parse_symbolic_address (cd, strp, opindex,
00717 BFD_RELOC_FRV_GOTOFF12,
00718 &result_type, &value);
00719 if (**strp != ')')
00720 return "missing ')'";
00721 ++*strp;
00722 *valuep = value;
00723 return errmsg;
00724 }
00725 else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
00726 {
00727 *strp += 18;
00728 errmsg = parse_symbolic_address (cd, strp, opindex,
00729 BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
00730 &result_type, &value);
00731 if (**strp != ')')
00732 return "missing ')'";
00733 ++*strp;
00734 *valuep = value;
00735 return errmsg;
00736 }
00737 else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
00738 {
00739 *strp += 14;
00740 errmsg = parse_symbolic_address (cd, strp, opindex,
00741 BFD_RELOC_FRV_GOTTLSDESC12,
00742 &result_type, &value);
00743 if (**strp != ')')
00744 return "missing ')'";
00745 ++*strp;
00746 *valuep = value;
00747 return errmsg;
00748 }
00749 else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
00750 {
00751 *strp += 11;
00752 errmsg = parse_symbolic_address (cd, strp, opindex,
00753 BFD_RELOC_FRV_TLSMOFF12,
00754 &result_type, &value);
00755 if (**strp != ')')
00756 return "missing ')'";
00757 ++*strp;
00758 *valuep = value;
00759 return errmsg;
00760 }
00761 else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
00762 {
00763 *strp += 13;
00764 errmsg = parse_symbolic_address (cd, strp, opindex,
00765 BFD_RELOC_FRV_GOTTLSOFF12,
00766 &result_type, &value);
00767 if (**strp != ')')
00768 return "missing ')'";
00769 ++*strp;
00770 *valuep = value;
00771 return errmsg;
00772 }
00773 }
00774 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
00775 }
00776
00777 static const char *
00778 parse_s12 (cd, strp, opindex, valuep)
00779 CGEN_CPU_DESC cd;
00780 const char **strp;
00781 int opindex;
00782 long *valuep;
00783 {
00784 const char *errmsg;
00785 enum cgen_parse_operand_result result_type;
00786 bfd_vma value;
00787
00788
00789 if (**strp == '#' || **strp == '%')
00790 {
00791 if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
00792 {
00793 *strp += 9;
00794 errmsg = parse_symbolic_address (cd, strp, opindex,
00795 BFD_RELOC_FRV_GPREL12,
00796 &result_type, &value);
00797 if (**strp != ')')
00798 return "missing `)'";
00799 ++*strp;
00800 *valuep = value;
00801 return errmsg;
00802 }
00803 else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
00804 {
00805 *strp += 7;
00806 errmsg = parse_symbolic_address (cd, strp, opindex,
00807 BFD_RELOC_FRV_GOT12,
00808 &result_type, &value);
00809 if (**strp != ')')
00810 return "missing ')'";
00811 ++*strp;
00812 *valuep = value;
00813 return errmsg;
00814 }
00815 else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
00816 {
00817 *strp += 15;
00818 errmsg = parse_symbolic_address (cd, strp, opindex,
00819 BFD_RELOC_FRV_FUNCDESC_GOT12,
00820 &result_type, &value);
00821 if (**strp != ')')
00822 return "missing ')'";
00823 ++*strp;
00824 *valuep = value;
00825 return errmsg;
00826 }
00827 else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
00828 {
00829 *strp += 10;
00830 errmsg = parse_symbolic_address (cd, strp, opindex,
00831 BFD_RELOC_FRV_GOTOFF12,
00832 &result_type, &value);
00833 if (**strp != ')')
00834 return "missing ')'";
00835 ++*strp;
00836 *valuep = value;
00837 return errmsg;
00838 }
00839 else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
00840 {
00841 *strp += 18;
00842 errmsg = parse_symbolic_address (cd, strp, opindex,
00843 BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
00844 &result_type, &value);
00845 if (**strp != ')')
00846 return "missing ')'";
00847 ++*strp;
00848 *valuep = value;
00849 return errmsg;
00850 }
00851 else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
00852 {
00853 *strp += 14;
00854 errmsg = parse_symbolic_address (cd, strp, opindex,
00855 BFD_RELOC_FRV_GOTTLSDESC12,
00856 &result_type, &value);
00857 if (**strp != ')')
00858 return "missing ')'";
00859 ++*strp;
00860 *valuep = value;
00861 return errmsg;
00862 }
00863 else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
00864 {
00865 *strp += 11;
00866 errmsg = parse_symbolic_address (cd, strp, opindex,
00867 BFD_RELOC_FRV_TLSMOFF12,
00868 &result_type, &value);
00869 if (**strp != ')')
00870 return "missing ')'";
00871 ++*strp;
00872 *valuep = value;
00873 return errmsg;
00874 }
00875 else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
00876 {
00877 *strp += 13;
00878 errmsg = parse_symbolic_address (cd, strp, opindex,
00879 BFD_RELOC_FRV_GOTTLSOFF12,
00880 &result_type, &value);
00881 if (**strp != ')')
00882 return "missing ')'";
00883 ++*strp;
00884 *valuep = value;
00885 return errmsg;
00886 }
00887 }
00888
00889 if (**strp == '#')
00890 ++*strp;
00891 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
00892 }
00893
00894 static const char *
00895 parse_u12 (cd, strp, opindex, valuep)
00896 CGEN_CPU_DESC cd;
00897 const char **strp;
00898 int opindex;
00899 long *valuep;
00900 {
00901 const char *errmsg;
00902 enum cgen_parse_operand_result result_type;
00903 bfd_vma value;
00904
00905
00906 if ((**strp == '#' || **strp == '%')
00907 && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
00908 {
00909 *strp += 9;
00910 errmsg = parse_symbolic_address (cd, strp, opindex,
00911 BFD_RELOC_FRV_GPRELU12,
00912 &result_type, &value);
00913 if (**strp != ')')
00914 return "missing `)'";
00915 ++*strp;
00916 *valuep = value;
00917 return errmsg;
00918 }
00919 else
00920 {
00921 if (**strp == '#')
00922 ++*strp;
00923 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
00924 }
00925 }
00926
00927 static const char *
00928 parse_A (cd, strp, opindex, valuep, A)
00929 CGEN_CPU_DESC cd;
00930 const char **strp;
00931 int opindex;
00932 unsigned long *valuep;
00933 unsigned long A;
00934 {
00935 const char *errmsg;
00936
00937 if (**strp == '#')
00938 ++*strp;
00939
00940 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
00941 if (errmsg)
00942 return errmsg;
00943
00944 if (*valuep != A)
00945 return "Value of A operand must be 0 or 1";
00946
00947 return NULL;
00948 }
00949
00950 static const char *
00951 parse_A0 (cd, strp, opindex, valuep)
00952 CGEN_CPU_DESC cd;
00953 const char **strp;
00954 int opindex;
00955 unsigned long *valuep;
00956 {
00957 return parse_A (cd, strp, opindex, valuep, 0);
00958 }
00959
00960 static const char *
00961 parse_A1 (cd, strp, opindex, valuep)
00962 CGEN_CPU_DESC cd;
00963 const char **strp;
00964 int opindex;
00965 unsigned long *valuep;
00966 {
00967 return parse_A (cd, strp, opindex, valuep, 1);
00968 }
00969
00970 static const char *
00971 parse_even_register (cd, strP, tableP, valueP)
00972 CGEN_CPU_DESC cd;
00973 const char ** strP;
00974 CGEN_KEYWORD * tableP;
00975 long * valueP;
00976 {
00977 const char * errmsg;
00978 const char * saved_star_strP = * strP;
00979
00980 errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
00981
00982 if (errmsg == NULL && ((* valueP) & 1))
00983 {
00984 errmsg = _("register number must be even");
00985 * strP = saved_star_strP;
00986 }
00987
00988 return errmsg;
00989 }
00990
00991 static const char *
00992 parse_call_label (CGEN_CPU_DESC cd,
00993 const char **strp,
00994 int opindex,
00995 int opinfo,
00996 enum cgen_parse_operand_result *resultp,
00997 bfd_vma *valuep)
00998 {
00999 const char *errmsg;
01000 bfd_vma value;
01001
01002
01003 if (opinfo == 0 && (**strp == '#' || **strp == '%'))
01004 {
01005 if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
01006 {
01007 *strp += 11;
01008 errmsg = parse_symbolic_address (cd, strp, opindex,
01009 BFD_RELOC_FRV_GETTLSOFF,
01010 resultp, &value);
01011 if (**strp != ')')
01012 return "missing `)'";
01013 ++*strp;
01014 *valuep = value;
01015 return errmsg;
01016 }
01017 }
01018
01019 return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
01020 }
01021
01022
01023
01024 const char * frv_cgen_parse_operand
01025 PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040 const char *
01041 frv_cgen_parse_operand (cd, opindex, strp, fields)
01042 CGEN_CPU_DESC cd;
01043 int opindex;
01044 const char ** strp;
01045 CGEN_FIELDS * fields;
01046 {
01047 const char * errmsg = NULL;
01048
01049 long junk ATTRIBUTE_UNUSED;
01050
01051 switch (opindex)
01052 {
01053 case FRV_OPERAND_A0 :
01054 errmsg = parse_A0 (cd, strp, FRV_OPERAND_A0, (unsigned long *) (& fields->f_A));
01055 break;
01056 case FRV_OPERAND_A1 :
01057 errmsg = parse_A1 (cd, strp, FRV_OPERAND_A1, (unsigned long *) (& fields->f_A));
01058 break;
01059 case FRV_OPERAND_ACC40SI :
01060 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si);
01061 break;
01062 case FRV_OPERAND_ACC40SK :
01063 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk);
01064 break;
01065 case FRV_OPERAND_ACC40UI :
01066 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui);
01067 break;
01068 case FRV_OPERAND_ACC40UK :
01069 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk);
01070 break;
01071 case FRV_OPERAND_ACCGI :
01072 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi);
01073 break;
01074 case FRV_OPERAND_ACCGK :
01075 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk);
01076 break;
01077 case FRV_OPERAND_CCI :
01078 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi);
01079 break;
01080 case FRV_OPERAND_CPRDOUBLEK :
01081 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
01082 break;
01083 case FRV_OPERAND_CPRI :
01084 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi);
01085 break;
01086 case FRV_OPERAND_CPRJ :
01087 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj);
01088 break;
01089 case FRV_OPERAND_CPRK :
01090 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
01091 break;
01092 case FRV_OPERAND_CRI :
01093 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi);
01094 break;
01095 case FRV_OPERAND_CRJ :
01096 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj);
01097 break;
01098 case FRV_OPERAND_CRJ_FLOAT :
01099 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float);
01100 break;
01101 case FRV_OPERAND_CRJ_INT :
01102 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int);
01103 break;
01104 case FRV_OPERAND_CRK :
01105 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk);
01106 break;
01107 case FRV_OPERAND_FCCI_1 :
01108 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1);
01109 break;
01110 case FRV_OPERAND_FCCI_2 :
01111 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2);
01112 break;
01113 case FRV_OPERAND_FCCI_3 :
01114 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3);
01115 break;
01116 case FRV_OPERAND_FCCK :
01117 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk);
01118 break;
01119 case FRV_OPERAND_FRDOUBLEI :
01120 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
01121 break;
01122 case FRV_OPERAND_FRDOUBLEJ :
01123 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
01124 break;
01125 case FRV_OPERAND_FRDOUBLEK :
01126 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
01127 break;
01128 case FRV_OPERAND_FRI :
01129 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
01130 break;
01131 case FRV_OPERAND_FRINTI :
01132 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
01133 break;
01134 case FRV_OPERAND_FRINTIEVEN :
01135 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
01136 break;
01137 case FRV_OPERAND_FRINTJ :
01138 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
01139 break;
01140 case FRV_OPERAND_FRINTJEVEN :
01141 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
01142 break;
01143 case FRV_OPERAND_FRINTK :
01144 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
01145 break;
01146 case FRV_OPERAND_FRINTKEVEN :
01147 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
01148 break;
01149 case FRV_OPERAND_FRJ :
01150 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
01151 break;
01152 case FRV_OPERAND_FRK :
01153 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
01154 break;
01155 case FRV_OPERAND_FRKHI :
01156 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
01157 break;
01158 case FRV_OPERAND_FRKLO :
01159 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
01160 break;
01161 case FRV_OPERAND_GRDOUBLEK :
01162 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
01163 break;
01164 case FRV_OPERAND_GRI :
01165 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi);
01166 break;
01167 case FRV_OPERAND_GRJ :
01168 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj);
01169 break;
01170 case FRV_OPERAND_GRK :
01171 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
01172 break;
01173 case FRV_OPERAND_GRKHI :
01174 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
01175 break;
01176 case FRV_OPERAND_GRKLO :
01177 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
01178 break;
01179 case FRV_OPERAND_ICCI_1 :
01180 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1);
01181 break;
01182 case FRV_OPERAND_ICCI_2 :
01183 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2);
01184 break;
01185 case FRV_OPERAND_ICCI_3 :
01186 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3);
01187 break;
01188 case FRV_OPERAND_LI :
01189 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, (unsigned long *) (& fields->f_LI));
01190 break;
01191 case FRV_OPERAND_LRAD :
01192 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAD, (unsigned long *) (& fields->f_LRAD));
01193 break;
01194 case FRV_OPERAND_LRAE :
01195 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAE, (unsigned long *) (& fields->f_LRAE));
01196 break;
01197 case FRV_OPERAND_LRAS :
01198 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAS, (unsigned long *) (& fields->f_LRAS));
01199 break;
01200 case FRV_OPERAND_TLBPRL :
01201 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPRL, (unsigned long *) (& fields->f_TLBPRL));
01202 break;
01203 case FRV_OPERAND_TLBPROPX :
01204 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPROPX, (unsigned long *) (& fields->f_TLBPRopx));
01205 break;
01206 case FRV_OPERAND_AE :
01207 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, (unsigned long *) (& fields->f_ae));
01208 break;
01209 case FRV_OPERAND_CALLANN :
01210 errmsg = parse_call_annotation (cd, strp, FRV_OPERAND_CALLANN, (unsigned long *) (& fields->f_reloc_ann));
01211 break;
01212 case FRV_OPERAND_CCOND :
01213 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, (unsigned long *) (& fields->f_ccond));
01214 break;
01215 case FRV_OPERAND_COND :
01216 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, (unsigned long *) (& fields->f_cond));
01217 break;
01218 case FRV_OPERAND_D12 :
01219 errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, (long *) (& fields->f_d12));
01220 break;
01221 case FRV_OPERAND_DEBUG :
01222 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, (unsigned long *) (& fields->f_debug));
01223 break;
01224 case FRV_OPERAND_EIR :
01225 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, (unsigned long *) (& fields->f_eir));
01226 break;
01227 case FRV_OPERAND_HINT :
01228 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, (unsigned long *) (& fields->f_hint));
01229 break;
01230 case FRV_OPERAND_HINT_NOT_TAKEN :
01231 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint);
01232 break;
01233 case FRV_OPERAND_HINT_TAKEN :
01234 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint);
01235 break;
01236 case FRV_OPERAND_LABEL16 :
01237 {
01238 bfd_vma value;
01239 errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL, & value);
01240 fields->f_label16 = value;
01241 }
01242 break;
01243 case FRV_OPERAND_LABEL24 :
01244 {
01245 bfd_vma value;
01246 errmsg = parse_call_label (cd, strp, FRV_OPERAND_LABEL24, 0, NULL, & value);
01247 fields->f_label24 = value;
01248 }
01249 break;
01250 case FRV_OPERAND_LDANN :
01251 errmsg = parse_ld_annotation (cd, strp, FRV_OPERAND_LDANN, (unsigned long *) (& fields->f_reloc_ann));
01252 break;
01253 case FRV_OPERAND_LDDANN :
01254 errmsg = parse_ldd_annotation (cd, strp, FRV_OPERAND_LDDANN, (unsigned long *) (& fields->f_reloc_ann));
01255 break;
01256 case FRV_OPERAND_LOCK :
01257 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, (unsigned long *) (& fields->f_lock));
01258 break;
01259 case FRV_OPERAND_PACK :
01260 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack);
01261 break;
01262 case FRV_OPERAND_S10 :
01263 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, (long *) (& fields->f_s10));
01264 break;
01265 case FRV_OPERAND_S12 :
01266 errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, (long *) (& fields->f_d12));
01267 break;
01268 case FRV_OPERAND_S16 :
01269 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, (long *) (& fields->f_s16));
01270 break;
01271 case FRV_OPERAND_S5 :
01272 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, (long *) (& fields->f_s5));
01273 break;
01274 case FRV_OPERAND_S6 :
01275 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, (long *) (& fields->f_s6));
01276 break;
01277 case FRV_OPERAND_S6_1 :
01278 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, (long *) (& fields->f_s6_1));
01279 break;
01280 case FRV_OPERAND_SLO16 :
01281 errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, (long *) (& fields->f_s16));
01282 break;
01283 case FRV_OPERAND_SPR :
01284 errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr);
01285 break;
01286 case FRV_OPERAND_U12 :
01287 errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, (long *) (& fields->f_u12));
01288 break;
01289 case FRV_OPERAND_U16 :
01290 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, (unsigned long *) (& fields->f_u16));
01291 break;
01292 case FRV_OPERAND_U6 :
01293 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, (unsigned long *) (& fields->f_u6));
01294 break;
01295 case FRV_OPERAND_UHI16 :
01296 errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, (unsigned long *) (& fields->f_u16));
01297 break;
01298 case FRV_OPERAND_ULO16 :
01299 errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, (unsigned long *) (& fields->f_u16));
01300 break;
01301
01302 default :
01303
01304 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
01305 abort ();
01306 }
01307
01308 return errmsg;
01309 }
01310
01311 cgen_parse_fn * const frv_cgen_parse_handlers[] =
01312 {
01313 parse_insn_normal,
01314 };
01315
01316 void
01317 frv_cgen_init_asm (cd)
01318 CGEN_CPU_DESC cd;
01319 {
01320 frv_cgen_init_opcode_table (cd);
01321 frv_cgen_init_ibld_table (cd);
01322 cd->parse_handlers = & frv_cgen_parse_handlers[0];
01323 cd->parse_operand = frv_cgen_parse_operand;
01324 }
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339 char *
01340 frv_cgen_build_insn_regex (CGEN_INSN *insn)
01341 {
01342 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
01343 const char *mnem = CGEN_INSN_MNEMONIC (insn);
01344 char rxbuf[CGEN_MAX_RX_ELEMENTS];
01345 char *rx = rxbuf;
01346 const CGEN_SYNTAX_CHAR_TYPE *syn;
01347 int reg_err;
01348
01349 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
01350
01351
01352 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
01353 return _("missing mnemonic in syntax string");
01354 ++syn;
01355
01356
01357
01358
01359
01360
01361
01362 for (; *mnem; mnem++)
01363 {
01364 char c = *mnem;
01365
01366 if (ISALPHA (c))
01367 {
01368 *rx++ = '[';
01369 *rx++ = TOLOWER (c);
01370 *rx++ = TOUPPER (c);
01371 *rx++ = ']';
01372 }
01373 else
01374 *rx++ = c;
01375 }
01376
01377
01378 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
01379 {
01380 if (CGEN_SYNTAX_CHAR_P (* syn))
01381 {
01382 char c = CGEN_SYNTAX_CHAR (* syn);
01383
01384 switch (c)
01385 {
01386
01387 case '.': case '[': case '\\':
01388 case '*': case '^': case '$':
01389
01390 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
01391 case '?': case '{': case '}':
01392 case '(': case ')': case '*':
01393 case '|': case '+': case ']':
01394 #endif
01395 *rx++ = '\\';
01396 *rx++ = c;
01397 break;
01398
01399 default:
01400 if (ISALPHA (c))
01401 {
01402 *rx++ = '[';
01403 *rx++ = TOLOWER (c);
01404 *rx++ = TOUPPER (c);
01405 *rx++ = ']';
01406 }
01407 else
01408 *rx++ = c;
01409 break;
01410 }
01411 }
01412 else
01413 {
01414
01415 *rx++ = '.';
01416 *rx++ = '*';
01417 }
01418 }
01419
01420
01421 * rx++ = '[';
01422 * rx++ = ' ';
01423 * rx++ = '\t';
01424 * rx++ = ']';
01425 * rx++ = '*';
01426
01427
01428 * rx++ = '$';
01429 * rx = '\0';
01430
01431 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
01432 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
01433
01434 if (reg_err == 0)
01435 return NULL;
01436 else
01437 {
01438 static char msg[80];
01439
01440 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
01441 regfree ((regex_t *) CGEN_INSN_RX (insn));
01442 free (CGEN_INSN_RX (insn));
01443 (CGEN_INSN_RX (insn)) = NULL;
01444 return msg;
01445 }
01446 }
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462 static const char *
01463 parse_insn_normal (CGEN_CPU_DESC cd,
01464 const CGEN_INSN *insn,
01465 const char **strp,
01466 CGEN_FIELDS *fields)
01467 {
01468
01469 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
01470 const char *str = *strp;
01471 const char *errmsg;
01472 const char *p;
01473 const CGEN_SYNTAX_CHAR_TYPE * syn;
01474 #ifdef CGEN_MNEMONIC_OPERANDS
01475
01476 int past_opcode_p;
01477 #endif
01478
01479
01480
01481
01482
01483 p = CGEN_INSN_MNEMONIC (insn);
01484 while (*p && TOLOWER (*p) == TOLOWER (*str))
01485 ++p, ++str;
01486
01487 if (* p)
01488 return _("unrecognized instruction");
01489
01490 #ifndef CGEN_MNEMONIC_OPERANDS
01491 if (* str && ! ISSPACE (* str))
01492 return _("unrecognized instruction");
01493 #endif
01494
01495 CGEN_INIT_PARSE (cd);
01496 cgen_init_parse_operand (cd);
01497 #ifdef CGEN_MNEMONIC_OPERANDS
01498 past_opcode_p = 0;
01499 #endif
01500
01501
01502
01503 syn = CGEN_SYNTAX_STRING (syntax);
01504
01505
01506 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
01507 abort ();
01508
01509 ++syn;
01510
01511 while (* syn != 0)
01512 {
01513
01514 if (CGEN_SYNTAX_CHAR_P (* syn))
01515 {
01516
01517
01518
01519
01520 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
01521 {
01522 #ifdef CGEN_MNEMONIC_OPERANDS
01523 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
01524 past_opcode_p = 1;
01525 #endif
01526 ++ syn;
01527 ++ str;
01528 }
01529 else if (*str)
01530 {
01531
01532 static char msg [80];
01533
01534
01535 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
01536 CGEN_SYNTAX_CHAR(*syn), *str);
01537 return msg;
01538 }
01539 else
01540 {
01541
01542 static char msg [80];
01543
01544
01545 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
01546 CGEN_SYNTAX_CHAR(*syn));
01547 return msg;
01548 }
01549 continue;
01550 }
01551
01552
01553 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
01554 &str, fields);
01555 if (errmsg)
01556 return errmsg;
01557
01558
01559 ++ syn;
01560 }
01561
01562
01563 if (* syn == 0)
01564 {
01565
01566
01567
01568
01569 while (ISSPACE (* str))
01570 ++ str;
01571
01572 if (* str != '\0')
01573 return _("junk at end of line");
01574
01575 return NULL;
01576 }
01577
01578
01579 return _("unrecognized instruction");
01580 }
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603 const CGEN_INSN *
01604 frv_cgen_assemble_insn (CGEN_CPU_DESC cd,
01605 const char *str,
01606 CGEN_FIELDS *fields,
01607 CGEN_INSN_BYTES_PTR buf,
01608 char **errmsg)
01609 {
01610 const char *start;
01611 CGEN_INSN_LIST *ilist;
01612 const char *parse_errmsg = NULL;
01613 const char *insert_errmsg = NULL;
01614 int recognized_mnemonic = 0;
01615
01616
01617 while (ISSPACE (* str))
01618 ++ str;
01619
01620
01621
01622 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
01623
01624
01625 start = str;
01626 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
01627 {
01628 const CGEN_INSN *insn = ilist->insn;
01629 recognized_mnemonic = 1;
01630
01631 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
01632
01633
01634
01635 if (! frv_cgen_insn_supported (cd, insn))
01636 continue;
01637 #endif
01638
01639
01640
01641 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
01642 continue;
01643
01644 str = start;
01645
01646
01647 if (CGEN_INSN_RX (insn) != NULL &&
01648 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
01649 continue;
01650
01651
01652 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
01653
01654 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
01655 if (parse_errmsg != NULL)
01656 continue;
01657
01658
01659 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
01660 (bfd_vma) 0);
01661 if (insert_errmsg != NULL)
01662 continue;
01663
01664
01665
01666 return insn;
01667 }
01668
01669 {
01670 static char errbuf[150];
01671 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
01672 const char *tmp_errmsg;
01673
01674
01675
01676 tmp_errmsg = (insert_errmsg ? insert_errmsg :
01677 parse_errmsg ? parse_errmsg :
01678 recognized_mnemonic ?
01679 _("unrecognized form of instruction") :
01680 _("unrecognized instruction"));
01681
01682 if (strlen (start) > 50)
01683
01684 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
01685 else
01686
01687 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
01688 #else
01689 if (strlen (start) > 50)
01690
01691 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
01692 else
01693
01694 sprintf (errbuf, _("bad instruction `%.50s'"), start);
01695 #endif
01696
01697 *errmsg = errbuf;
01698 return NULL;
01699 }
01700 }
01701
01702 #if 0
01703
01704
01705
01706
01707
01708
01709
01710
01711 void
01712 frv_cgen_asm_hash_keywords (CGEN_CPU_DESC cd, CGEN_KEYWORD *opvals)
01713 {
01714 CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
01715 const CGEN_KEYWORD_ENTRY * ke;
01716
01717 while ((ke = cgen_keyword_search_next (& search)) != NULL)
01718 {
01719 #if 0
01720 if (! frv_cgen_opval_supported (ke))
01721 continue;
01722 #endif
01723 cgen_asm_record_register (cd, ke->name, ke->value);
01724 }
01725 }
01726
01727 #endif