1 /* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */ 2 /* Assembler interface for targets using CGEN. -*- C -*- 3 CGEN: Cpu tools GENerator 4 5 THIS FILE IS MACHINE GENERATED WITH CGEN. 6 - the resultant file is machine generated, cgen-asm.in isn't 7 8 Copyright (C) 1996-2026 Free Software Foundation, Inc. 9 10 This file is part of libopcodes. 11 12 This library is free software; you can redistribute it and/or modify 13 it under the terms of the GNU General Public License as published by 14 the Free Software Foundation; either version 3, or (at your option) 15 any later version. 16 17 It is distributed in the hope that it will be useful, but WITHOUT 18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 19 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 20 License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software Foundation, Inc., 24 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 25 26 27 /* ??? Eventually more and more of this stuff can go to cpu-independent files. 28 Keep that in mind. */ 29 30 #include "sysdep.h" 31 #include <stdio.h> 32 #include "ansidecl.h" 33 #include "bfd.h" 34 #include "symcat.h" 35 #include "mt-desc.h" 36 #include "mt-opc.h" 37 #include "opintl.h" 38 #include "xregex.h" 39 #include "libiberty.h" 40 #include "safe-ctype.h" 41 42 #undef min 43 #define min(a,b) ((a) < (b) ? (a) : (b)) 44 #undef max 45 #define max(a,b) ((a) > (b) ? (a) : (b)) 46 47 static const char * parse_insn_normal 48 (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *); 49 50 /* -- assembler routines inserted here. */ 52 53 /* -- asm.c */ 54 /* Range checking for signed numbers. Returns 0 if acceptable 55 and 1 if the value is out of bounds for a signed quantity. */ 56 57 static int 58 signed_out_of_bounds (long val) 59 { 60 if ((val < -32768) || (val > 32767)) 61 return 1; 62 return 0; 63 } 64 65 static const char * 66 parse_loopsize (CGEN_CPU_DESC cd, 67 const char **strp, 68 int opindex, 69 void *arg) 70 { 71 signed long * valuep = (signed long *) arg; 72 const char *errmsg; 73 bfd_reloc_code_real_type code = BFD_RELOC_NONE; 74 enum cgen_parse_operand_result result_type; 75 bfd_vma value; 76 77 /* Is it a control transfer instructions? */ 78 if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_LOOPSIZE) 79 { 80 code = BFD_RELOC_MT_PCINSN8; 81 errmsg = cgen_parse_address (cd, strp, opindex, code, 82 & result_type, & value); 83 *valuep = value; 84 return errmsg; 85 } 86 87 abort (); 88 } 89 90 static const char * 91 parse_imm16 (CGEN_CPU_DESC cd, 92 const char **strp, 93 int opindex, 94 void *arg) 95 { 96 signed long * valuep = (signed long *) arg; 97 const char *errmsg; 98 enum cgen_parse_operand_result result_type; 99 bfd_reloc_code_real_type code = BFD_RELOC_NONE; 100 bfd_vma value; 101 102 /* Is it a control transfer instructions? */ 103 if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16O) 104 { 105 code = BFD_RELOC_16_PCREL; 106 errmsg = cgen_parse_address (cd, strp, opindex, code, 107 & result_type, & value); 108 if (errmsg == NULL) 109 { 110 if (signed_out_of_bounds (value)) 111 errmsg = _("Operand out of range. Must be between -32768 and 32767."); 112 } 113 *valuep = value; 114 return errmsg; 115 } 116 117 /* If it's not a control transfer instruction, then 118 we have to check for %OP relocating operators. */ 119 if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16L) 120 ; 121 else if (strncmp (*strp, "%hi16", 5) == 0) 122 { 123 *strp += 5; 124 code = BFD_RELOC_HI16; 125 } 126 else if (strncmp (*strp, "%lo16", 5) == 0) 127 { 128 *strp += 5; 129 code = BFD_RELOC_LO16; 130 } 131 132 /* If we found a %OP relocating operator, then parse it as an address. 133 If not, we need to parse it as an integer, either signed or unsigned 134 depending on which operand type we have. */ 135 if (code != BFD_RELOC_NONE) 136 { 137 /* %OP relocating operator found. */ 138 errmsg = cgen_parse_address (cd, strp, opindex, code, 139 & result_type, & value); 140 if (errmsg == NULL) 141 { 142 switch (result_type) 143 { 144 case (CGEN_PARSE_OPERAND_RESULT_NUMBER): 145 if (code == BFD_RELOC_HI16) 146 value = (value >> 16) & 0xFFFF; 147 else if (code == BFD_RELOC_LO16) 148 value = value & 0xFFFF; 149 else 150 errmsg = _("Biiiig Trouble in parse_imm16!"); 151 break; 152 153 case (CGEN_PARSE_OPERAND_RESULT_QUEUED): 154 /* No special processing for this case. */ 155 break; 156 157 default: 158 errmsg = _("The percent-operator's operand is not a symbol"); 159 break; 160 } 161 } 162 *valuep = value; 163 } 164 else 165 { 166 /* Parse hex values like 0xffff as unsigned, and sign extend 167 them manually. */ 168 int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MT_OPERAND_IMM16); 169 170 if ((*strp)[0] == '0' 171 && ((*strp)[1] == 'x' || (*strp)[1] == 'X')) 172 parse_signed = 0; 173 174 /* No relocating operator. Parse as an number. */ 175 if (parse_signed) 176 { 177 /* Parse as as signed integer. */ 178 179 errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep); 180 181 if (errmsg == NULL) 182 { 183 #if 0 184 /* Manual range checking is needed for the signed case. */ 185 if (*valuep & 0x8000) 186 value = 0xffff0000 | *valuep; 187 else 188 value = *valuep; 189 190 if (signed_out_of_bounds (value)) 191 errmsg = _("Operand out of range. Must be between -32768 and 32767."); 192 /* Truncate to 16 bits. This is necessary 193 because cgen will have sign extended *valuep. */ 194 *valuep &= 0xFFFF; 195 #endif 196 } 197 } 198 else 199 { 200 /* MT_OPERAND_IMM16Z. Parse as an unsigned integer. */ 201 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep); 202 203 if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16 204 && *valuep >= 0x8000 205 && *valuep <= 0xffff) 206 *valuep -= 0x10000; 207 } 208 } 209 210 return errmsg; 211 } 212 213 214 static const char * 215 parse_dup (CGEN_CPU_DESC cd, 216 const char **strp, 217 int opindex, 218 unsigned long *valuep) 219 { 220 const char *errmsg = NULL; 221 222 if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0) 223 { 224 *strp += 3; 225 *valuep = 1; 226 } 227 else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0) 228 { 229 *strp += 2; 230 *valuep = 0; 231 } 232 else 233 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 234 235 return errmsg; 236 } 237 238 239 static const char * 240 parse_ball (CGEN_CPU_DESC cd, 241 const char **strp, 242 int opindex, 243 unsigned long *valuep) 244 { 245 const char *errmsg = NULL; 246 247 if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0) 248 { 249 *strp += 3; 250 *valuep = 1; 251 } 252 else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0) 253 { 254 *strp += 3; 255 *valuep = 0; 256 } 257 else 258 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 259 260 return errmsg; 261 } 262 263 static const char * 264 parse_xmode (CGEN_CPU_DESC cd, 265 const char **strp, 266 int opindex, 267 unsigned long *valuep) 268 { 269 const char *errmsg = NULL; 270 271 if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0) 272 { 273 *strp += 2; 274 *valuep = 1; 275 } 276 else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0) 277 { 278 *strp += 2; 279 *valuep = 0; 280 } 281 else 282 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 283 284 return errmsg; 285 } 286 287 static const char * 288 parse_rc (CGEN_CPU_DESC cd, 289 const char **strp, 290 int opindex, 291 unsigned long *valuep) 292 { 293 const char *errmsg = NULL; 294 295 if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0) 296 { 297 *strp += 1; 298 *valuep = 1; 299 } 300 else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0) 301 { 302 *strp += 1; 303 *valuep = 0; 304 } 305 else 306 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 307 308 return errmsg; 309 } 310 311 static const char * 312 parse_cbrb (CGEN_CPU_DESC cd, 313 const char **strp, 314 int opindex, 315 unsigned long *valuep) 316 { 317 const char *errmsg = NULL; 318 319 if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0) 320 { 321 *strp += 2; 322 *valuep = 1; 323 } 324 else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0) 325 { 326 *strp += 2; 327 *valuep = 0; 328 } 329 else 330 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 331 332 return errmsg; 333 } 334 335 static const char * 336 parse_rbbc (CGEN_CPU_DESC cd, 337 const char **strp, 338 int opindex, 339 unsigned long *valuep) 340 { 341 const char *errmsg = NULL; 342 343 if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0) 344 { 345 *strp += 2; 346 *valuep = 0; 347 } 348 else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0) 349 { 350 *strp += 3; 351 *valuep = 1; 352 } 353 else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0) 354 { 355 *strp += 3; 356 *valuep = 2; 357 } 358 else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0) 359 { 360 *strp += 2; 361 *valuep = 3; 362 } 363 else 364 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 365 366 return errmsg; 367 } 368 369 static const char * 370 parse_type (CGEN_CPU_DESC cd, 371 const char **strp, 372 int opindex, 373 unsigned long *valuep) 374 { 375 const char *errmsg = NULL; 376 377 if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0) 378 { 379 *strp += 3; 380 *valuep = 0; 381 } 382 else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0) 383 { 384 *strp += 4; 385 *valuep = 1; 386 } 387 else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0) 388 { 389 *strp += 2; 390 *valuep = 2; 391 } 392 else 393 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 394 395 if ((errmsg == NULL) && (*valuep == 3)) 396 errmsg = _("invalid operand. type may have values 0,1,2 only."); 397 398 return errmsg; 399 } 400 401 /* -- dis.c */ 402 403 const char * mt_cgen_parse_operand 404 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *); 405 406 /* Main entry point for operand parsing. 407 408 This function is basically just a big switch statement. Earlier versions 409 used tables to look up the function to use, but 410 - if the table contains both assembler and disassembler functions then 411 the disassembler contains much of the assembler and vice-versa, 412 - there's a lot of inlining possibilities as things grow, 413 - using a switch statement avoids the function call overhead. 414 415 This function could be moved into `parse_insn_normal', but keeping it 416 separate makes clear the interface between `parse_insn_normal' and each of 417 the handlers. */ 418 419 const char * 420 mt_cgen_parse_operand (CGEN_CPU_DESC cd, 421 int opindex, 422 const char ** strp, 423 CGEN_FIELDS * fields) 424 { 425 const char * errmsg = NULL; 426 /* Used by scalar operands that still need to be parsed. */ 427 long junk ATTRIBUTE_UNUSED; 428 429 switch (opindex) 430 { 431 case MT_OPERAND_A23 : 432 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_A23, (unsigned long *) (& fields->f_a23)); 433 break; 434 case MT_OPERAND_BALL : 435 errmsg = parse_ball (cd, strp, MT_OPERAND_BALL, (unsigned long *) (& fields->f_ball)); 436 break; 437 case MT_OPERAND_BALL2 : 438 errmsg = parse_ball (cd, strp, MT_OPERAND_BALL2, (unsigned long *) (& fields->f_ball2)); 439 break; 440 case MT_OPERAND_BANKADDR : 441 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_BANKADDR, (unsigned long *) (& fields->f_bankaddr)); 442 break; 443 case MT_OPERAND_BRC : 444 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_BRC, (unsigned long *) (& fields->f_brc)); 445 break; 446 case MT_OPERAND_BRC2 : 447 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_BRC2, (unsigned long *) (& fields->f_brc2)); 448 break; 449 case MT_OPERAND_CB1INCR : 450 errmsg = cgen_parse_signed_integer (cd, strp, MT_OPERAND_CB1INCR, (long *) (& fields->f_cb1incr)); 451 break; 452 case MT_OPERAND_CB1SEL : 453 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CB1SEL, (unsigned long *) (& fields->f_cb1sel)); 454 break; 455 case MT_OPERAND_CB2INCR : 456 errmsg = cgen_parse_signed_integer (cd, strp, MT_OPERAND_CB2INCR, (long *) (& fields->f_cb2incr)); 457 break; 458 case MT_OPERAND_CB2SEL : 459 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CB2SEL, (unsigned long *) (& fields->f_cb2sel)); 460 break; 461 case MT_OPERAND_CBRB : 462 errmsg = parse_cbrb (cd, strp, MT_OPERAND_CBRB, (unsigned long *) (& fields->f_cbrb)); 463 break; 464 case MT_OPERAND_CBS : 465 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CBS, (unsigned long *) (& fields->f_cbs)); 466 break; 467 case MT_OPERAND_CBX : 468 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CBX, (unsigned long *) (& fields->f_cbx)); 469 break; 470 case MT_OPERAND_CCB : 471 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CCB, (unsigned long *) (& fields->f_ccb)); 472 break; 473 case MT_OPERAND_CDB : 474 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CDB, (unsigned long *) (& fields->f_cdb)); 475 break; 476 case MT_OPERAND_CELL : 477 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CELL, (unsigned long *) (& fields->f_cell)); 478 break; 479 case MT_OPERAND_COLNUM : 480 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_COLNUM, (unsigned long *) (& fields->f_colnum)); 481 break; 482 case MT_OPERAND_CONTNUM : 483 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CONTNUM, (unsigned long *) (& fields->f_contnum)); 484 break; 485 case MT_OPERAND_CR : 486 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CR, (unsigned long *) (& fields->f_cr)); 487 break; 488 case MT_OPERAND_CTXDISP : 489 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CTXDISP, (unsigned long *) (& fields->f_ctxdisp)); 490 break; 491 case MT_OPERAND_DUP : 492 errmsg = parse_dup (cd, strp, MT_OPERAND_DUP, (unsigned long *) (& fields->f_dup)); 493 break; 494 case MT_OPERAND_FBDISP : 495 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_FBDISP, (unsigned long *) (& fields->f_fbdisp)); 496 break; 497 case MT_OPERAND_FBINCR : 498 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_FBINCR, (unsigned long *) (& fields->f_fbincr)); 499 break; 500 case MT_OPERAND_FRDR : 501 errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_dr); 502 break; 503 case MT_OPERAND_FRDRRR : 504 errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_drrr); 505 break; 506 case MT_OPERAND_FRSR1 : 507 errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_sr1); 508 break; 509 case MT_OPERAND_FRSR2 : 510 errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_sr2); 511 break; 512 case MT_OPERAND_ID : 513 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ID, (unsigned long *) (& fields->f_id)); 514 break; 515 case MT_OPERAND_IMM16 : 516 errmsg = parse_imm16 (cd, strp, MT_OPERAND_IMM16, (long *) (& fields->f_imm16s)); 517 break; 518 case MT_OPERAND_IMM16L : 519 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_IMM16L, (unsigned long *) (& fields->f_imm16l)); 520 break; 521 case MT_OPERAND_IMM16O : 522 errmsg = parse_imm16 (cd, strp, MT_OPERAND_IMM16O, (unsigned long *) (& fields->f_imm16s)); 523 break; 524 case MT_OPERAND_IMM16Z : 525 errmsg = parse_imm16 (cd, strp, MT_OPERAND_IMM16Z, (unsigned long *) (& fields->f_imm16u)); 526 break; 527 case MT_OPERAND_INCAMT : 528 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_INCAMT, (unsigned long *) (& fields->f_incamt)); 529 break; 530 case MT_OPERAND_INCR : 531 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_INCR, (unsigned long *) (& fields->f_incr)); 532 break; 533 case MT_OPERAND_LENGTH : 534 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_LENGTH, (unsigned long *) (& fields->f_length)); 535 break; 536 case MT_OPERAND_LOOPSIZE : 537 errmsg = parse_loopsize (cd, strp, MT_OPERAND_LOOPSIZE, (unsigned long *) (& fields->f_loopo)); 538 break; 539 case MT_OPERAND_MASK : 540 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_MASK, (unsigned long *) (& fields->f_mask)); 541 break; 542 case MT_OPERAND_MASK1 : 543 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_MASK1, (unsigned long *) (& fields->f_mask1)); 544 break; 545 case MT_OPERAND_MODE : 546 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_MODE, (unsigned long *) (& fields->f_mode)); 547 break; 548 case MT_OPERAND_PERM : 549 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_PERM, (unsigned long *) (& fields->f_perm)); 550 break; 551 case MT_OPERAND_RBBC : 552 errmsg = parse_rbbc (cd, strp, MT_OPERAND_RBBC, (unsigned long *) (& fields->f_rbbc)); 553 break; 554 case MT_OPERAND_RC : 555 errmsg = parse_rc (cd, strp, MT_OPERAND_RC, (unsigned long *) (& fields->f_rc)); 556 break; 557 case MT_OPERAND_RC1 : 558 errmsg = parse_rc (cd, strp, MT_OPERAND_RC1, (unsigned long *) (& fields->f_rc1)); 559 break; 560 case MT_OPERAND_RC2 : 561 errmsg = parse_rc (cd, strp, MT_OPERAND_RC2, (unsigned long *) (& fields->f_rc2)); 562 break; 563 case MT_OPERAND_RC3 : 564 errmsg = parse_rc (cd, strp, MT_OPERAND_RC3, (unsigned long *) (& fields->f_rc3)); 565 break; 566 case MT_OPERAND_RCNUM : 567 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_RCNUM, (unsigned long *) (& fields->f_rcnum)); 568 break; 569 case MT_OPERAND_RDA : 570 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_RDA, (unsigned long *) (& fields->f_rda)); 571 break; 572 case MT_OPERAND_ROWNUM : 573 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ROWNUM, (unsigned long *) (& fields->f_rownum)); 574 break; 575 case MT_OPERAND_ROWNUM1 : 576 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ROWNUM1, (unsigned long *) (& fields->f_rownum1)); 577 break; 578 case MT_OPERAND_ROWNUM2 : 579 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ROWNUM2, (unsigned long *) (& fields->f_rownum2)); 580 break; 581 case MT_OPERAND_SIZE : 582 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_SIZE, (unsigned long *) (& fields->f_size)); 583 break; 584 case MT_OPERAND_TYPE : 585 errmsg = parse_type (cd, strp, MT_OPERAND_TYPE, (unsigned long *) (& fields->f_type)); 586 break; 587 case MT_OPERAND_WR : 588 errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_WR, (unsigned long *) (& fields->f_wr)); 589 break; 590 case MT_OPERAND_XMODE : 591 errmsg = parse_xmode (cd, strp, MT_OPERAND_XMODE, (unsigned long *) (& fields->f_xmode)); 592 break; 593 594 default : 595 /* xgettext:c-format */ 596 opcodes_error_handler 597 (_("internal error: unrecognized field %d while parsing"), 598 opindex); 599 abort (); 600 } 601 602 return errmsg; 603 } 604 605 cgen_parse_fn * const mt_cgen_parse_handlers[] = 606 { 607 parse_insn_normal, 608 }; 609 610 void 611 mt_cgen_init_asm (CGEN_CPU_DESC cd) 612 { 613 mt_cgen_init_opcode_table (cd); 614 mt_cgen_init_ibld_table (cd); 615 cd->parse_handlers = & mt_cgen_parse_handlers[0]; 616 cd->parse_operand = mt_cgen_parse_operand; 617 #ifdef CGEN_ASM_INIT_HOOK 618 CGEN_ASM_INIT_HOOK 619 #endif 620 } 621 622 623 625 /* Regex construction routine. 626 627 This translates an opcode syntax string into a regex string, 628 by replacing any non-character syntax element (such as an 629 opcode) with the pattern '.*' 630 631 It then compiles the regex and stores it in the opcode, for 632 later use by mt_cgen_assemble_insn 633 634 Returns NULL for success, an error message for failure. */ 635 636 char * 637 mt_cgen_build_insn_regex (CGEN_INSN *insn) 638 { 639 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn); 640 const char *mnem = CGEN_INSN_MNEMONIC (insn); 641 char rxbuf[CGEN_MAX_RX_ELEMENTS]; 642 char *rx = rxbuf; 643 const CGEN_SYNTAX_CHAR_TYPE *syn; 644 int reg_err; 645 646 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc)); 647 648 /* Mnemonics come first in the syntax string. */ 649 if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) 650 return _("missing mnemonic in syntax string"); 651 ++syn; 652 653 /* Generate a case sensitive regular expression that emulates case 654 insensitive matching in the "C" locale. We cannot generate a case 655 insensitive regular expression because in Turkish locales, 'i' and 'I' 656 are not equal modulo case conversion. */ 657 658 /* Copy the literal mnemonic out of the insn. */ 659 for (; *mnem; mnem++) 660 { 661 char c = *mnem; 662 663 if (ISALPHA (c)) 664 { 665 *rx++ = '['; 666 *rx++ = TOLOWER (c); 667 *rx++ = TOUPPER (c); 668 *rx++ = ']'; 669 } 670 else 671 *rx++ = c; 672 } 673 674 /* Copy any remaining literals from the syntax string into the rx. */ 675 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn) 676 { 677 if (CGEN_SYNTAX_CHAR_P (* syn)) 678 { 679 char c = CGEN_SYNTAX_CHAR (* syn); 680 681 switch (c) 682 { 683 /* Escape any regex metacharacters in the syntax. */ 684 case '.': case '[': case '\\': 685 case '*': case '^': case '$': 686 687 #ifdef CGEN_ESCAPE_EXTENDED_REGEX 688 case '?': case '{': case '}': 689 case '(': case ')': case '*': 690 case '|': case '+': case ']': 691 #endif 692 *rx++ = '\\'; 693 *rx++ = c; 694 break; 695 696 default: 697 if (ISALPHA (c)) 698 { 699 *rx++ = '['; 700 *rx++ = TOLOWER (c); 701 *rx++ = TOUPPER (c); 702 *rx++ = ']'; 703 } 704 else 705 *rx++ = c; 706 break; 707 } 708 } 709 else 710 { 711 /* Replace non-syntax fields with globs. */ 712 *rx++ = '.'; 713 *rx++ = '*'; 714 } 715 } 716 717 /* Trailing whitespace ok. */ 718 * rx++ = '['; 719 * rx++ = ' '; 720 * rx++ = '\t'; 721 * rx++ = ']'; 722 * rx++ = '*'; 723 724 /* But anchor it after that. */ 725 * rx++ = '$'; 726 * rx = '\0'; 727 728 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t)); 729 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB); 730 731 if (reg_err == 0) 732 return NULL; 733 else 734 { 735 static char msg[80]; 736 737 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80); 738 regfree ((regex_t *) CGEN_INSN_RX (insn)); 739 free (CGEN_INSN_RX (insn)); 740 (CGEN_INSN_RX (insn)) = NULL; 741 return msg; 742 } 743 } 744 745 746 /* Default insn parser. 748 749 The syntax string is scanned and operands are parsed and stored in FIELDS. 750 Relocs are queued as we go via other callbacks. 751 752 ??? Note that this is currently an all-or-nothing parser. If we fail to 753 parse the instruction, we return 0 and the caller will start over from 754 the beginning. Backtracking will be necessary in parsing subexpressions, 755 but that can be handled there. Not handling backtracking here may get 756 expensive in the case of the m68k. Deal with later. 757 758 Returns NULL for success, an error message for failure. */ 759 760 static const char * 761 parse_insn_normal (CGEN_CPU_DESC cd, 762 const CGEN_INSN *insn, 763 const char **strp, 764 CGEN_FIELDS *fields) 765 { 766 /* ??? Runtime added insns not handled yet. */ 767 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); 768 const char *str = *strp; 769 const char *errmsg; 770 const char *p; 771 const CGEN_SYNTAX_CHAR_TYPE * syn; 772 #ifdef CGEN_MNEMONIC_OPERANDS 773 /* FIXME: wip */ 774 int past_opcode_p; 775 #endif 776 777 /* For now we assume the mnemonic is first (there are no leading operands). 778 We can parse it without needing to set up operand parsing. 779 GAS's input scrubber will ensure mnemonics are lowercase, but we may 780 not be called from GAS. */ 781 p = CGEN_INSN_MNEMONIC (insn); 782 while (*p && TOLOWER (*p) == TOLOWER (*str)) 783 ++p, ++str; 784 785 if (* p) 786 return _("unrecognized instruction"); 787 788 #ifndef CGEN_MNEMONIC_OPERANDS 789 if (* str && ! ISSPACE (* str)) 790 return _("unrecognized instruction"); 791 #endif 792 793 CGEN_INIT_PARSE (cd); 794 cgen_init_parse_operand (cd); 795 #ifdef CGEN_MNEMONIC_OPERANDS 796 past_opcode_p = 0; 797 #endif 798 799 /* We don't check for (*str != '\0') here because we want to parse 800 any trailing fake arguments in the syntax string. */ 801 syn = CGEN_SYNTAX_STRING (syntax); 802 803 /* Mnemonics come first for now, ensure valid string. */ 804 if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) 805 abort (); 806 807 ++syn; 808 809 while (* syn != 0) 810 { 811 /* Non operand chars must match exactly. */ 812 if (CGEN_SYNTAX_CHAR_P (* syn)) 813 { 814 /* FIXME: While we allow for non-GAS callers above, we assume the 815 first char after the mnemonic part is a space. */ 816 /* FIXME: We also take inappropriate advantage of the fact that 817 GAS's input scrubber will remove extraneous blanks. */ 818 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn))) 819 { 820 #ifdef CGEN_MNEMONIC_OPERANDS 821 if (CGEN_SYNTAX_CHAR(* syn) == ' ') 822 past_opcode_p = 1; 823 #endif 824 ++ syn; 825 ++ str; 826 } 827 else if (*str) 828 { 829 /* Syntax char didn't match. Can't be this insn. */ 830 static char msg [80]; 831 832 /* xgettext:c-format */ 833 sprintf (msg, _("syntax error (expected char `%c', found `%c')"), 834 CGEN_SYNTAX_CHAR(*syn), *str); 835 return msg; 836 } 837 else 838 { 839 /* Ran out of input. */ 840 static char msg [80]; 841 842 /* xgettext:c-format */ 843 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"), 844 CGEN_SYNTAX_CHAR(*syn)); 845 return msg; 846 } 847 continue; 848 } 849 850 #ifdef CGEN_MNEMONIC_OPERANDS 851 (void) past_opcode_p; 852 #endif 853 /* We have an operand of some sort. */ 854 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields); 855 if (errmsg) 856 return errmsg; 857 858 /* Done with this operand, continue with next one. */ 859 ++ syn; 860 } 861 862 /* If we're at the end of the syntax string, we're done. */ 863 if (* syn == 0) 864 { 865 /* FIXME: For the moment we assume a valid `str' can only contain 866 blanks now. IE: We needn't try again with a longer version of 867 the insn and it is assumed that longer versions of insns appear 868 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */ 869 while (ISSPACE (* str)) 870 ++ str; 871 872 if (* str != '\0') 873 return _("junk at end of line"); /* FIXME: would like to include `str' */ 874 875 return NULL; 876 } 877 878 /* We couldn't parse it. */ 879 return _("unrecognized instruction"); 880 } 881 882 /* Main entry point. 884 This routine is called for each instruction to be assembled. 885 STR points to the insn to be assembled. 886 We assume all necessary tables have been initialized. 887 The assembled instruction, less any fixups, is stored in BUF. 888 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value 889 still needs to be converted to target byte order, otherwise BUF is an array 890 of bytes in target byte order. 891 The result is a pointer to the insn's entry in the opcode table, 892 or NULL if an error occured (an error message will have already been 893 printed). 894 895 Note that when processing (non-alias) macro-insns, 896 this function recurses. 897 898 ??? It's possible to make this cpu-independent. 899 One would have to deal with a few minor things. 900 At this point in time doing so would be more of a curiosity than useful 901 [for example this file isn't _that_ big], but keeping the possibility in 902 mind helps keep the design clean. */ 903 904 const CGEN_INSN * 905 mt_cgen_assemble_insn (CGEN_CPU_DESC cd, 906 const char *str, 907 CGEN_FIELDS *fields, 908 CGEN_INSN_BYTES_PTR buf, 909 char **errmsg) 910 { 911 const char *start; 912 CGEN_INSN_LIST *ilist; 913 const char *parse_errmsg = NULL; 914 const char *insert_errmsg = NULL; 915 int recognized_mnemonic = 0; 916 917 /* Skip leading white space. */ 918 while (ISSPACE (* str)) 919 ++ str; 920 921 /* The instructions are stored in hashed lists. 922 Get the first in the list. */ 923 ilist = CGEN_ASM_LOOKUP_INSN (cd, str); 924 925 /* Keep looking until we find a match. */ 926 start = str; 927 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist)) 928 { 929 const CGEN_INSN *insn = ilist->insn; 930 recognized_mnemonic = 1; 931 932 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 933 /* Not usually needed as unsupported opcodes 934 shouldn't be in the hash lists. */ 935 /* Is this insn supported by the selected cpu? */ 936 if (! mt_cgen_insn_supported (cd, insn)) 937 continue; 938 #endif 939 /* If the RELAXED attribute is set, this is an insn that shouldn't be 940 chosen immediately. Instead, it is used during assembler/linker 941 relaxation if possible. */ 942 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0) 943 continue; 944 945 str = start; 946 947 /* Skip this insn if str doesn't look right lexically. */ 948 if (CGEN_INSN_RX (insn) != NULL && 949 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH) 950 continue; 951 952 /* Allow parse/insert handlers to obtain length of insn. */ 953 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); 954 955 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields); 956 if (parse_errmsg != NULL) 957 continue; 958 959 /* ??? 0 is passed for `pc'. */ 960 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, 961 (bfd_vma) 0); 962 if (insert_errmsg != NULL) 963 continue; 964 965 /* It is up to the caller to actually output the insn and any 966 queued relocs. */ 967 return insn; 968 } 969 970 { 971 static char errbuf[150]; 972 const char *tmp_errmsg; 973 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS 974 #define be_verbose 1 975 #else 976 #define be_verbose 0 977 #endif 978 979 if (be_verbose) 980 { 981 /* If requesting verbose error messages, use insert_errmsg. 982 Failing that, use parse_errmsg. */ 983 tmp_errmsg = (insert_errmsg ? insert_errmsg : 984 parse_errmsg ? parse_errmsg : 985 recognized_mnemonic ? 986 _("unrecognized form of instruction") : 987 _("unrecognized instruction")); 988 989 if (strlen (start) > 50) 990 /* xgettext:c-format */ 991 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start); 992 else 993 /* xgettext:c-format */ 994 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start); 995 } 996 else 997 { 998 if (strlen (start) > 50) 999 /* xgettext:c-format */ 1000 sprintf (errbuf, _("bad instruction `%.50s...'"), start); 1001 else 1002 /* xgettext:c-format */ 1003 sprintf (errbuf, _("bad instruction `%.50s'"), start); 1004 } 1005 1006 *errmsg = errbuf; 1007 return NULL; 1008 } 1009 } 1010