[8833] | 1 | /* Generate code from machine description to extract operands from insn as rtl. |
---|
| 2 | Copyright (C) 1987, 1991, 1992, 1993 Free Software Foundation, Inc. |
---|
| 3 | |
---|
| 4 | This file is part of GNU CC. |
---|
| 5 | |
---|
| 6 | GNU CC is free software; you can redistribute it and/or modify |
---|
| 7 | it under the terms of the GNU General Public License as published by |
---|
| 8 | the Free Software Foundation; either version 2, or (at your option) |
---|
| 9 | any later version. |
---|
| 10 | |
---|
| 11 | GNU CC is distributed in the hope that it will be useful, |
---|
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 14 | GNU General Public License for more details. |
---|
| 15 | |
---|
| 16 | You should have received a copy of the GNU General Public License |
---|
| 17 | along with GNU CC; see the file COPYING. If not, write to |
---|
| 18 | the Free Software Foundation, 59 Temple Place - Suite 330, |
---|
| 19 | Boston, MA 02111-1307, USA. */ |
---|
| 20 | |
---|
| 21 | |
---|
| 22 | #include <stdio.h> |
---|
| 23 | #include "hconfig.h" |
---|
| 24 | #include "rtl.h" |
---|
| 25 | #include "obstack.h" |
---|
| 26 | #include "insn-config.h" |
---|
| 27 | |
---|
| 28 | static struct obstack obstack; |
---|
| 29 | struct obstack *rtl_obstack = &obstack; |
---|
| 30 | |
---|
| 31 | #define obstack_chunk_alloc xmalloc |
---|
| 32 | #define obstack_chunk_free free |
---|
| 33 | |
---|
| 34 | extern void free (); |
---|
| 35 | extern rtx read_rtx (); |
---|
| 36 | |
---|
| 37 | /* Names for patterns. Need to allow linking with print-rtl. */ |
---|
| 38 | char **insn_name_ptr; |
---|
| 39 | |
---|
| 40 | /* This structure contains all the information needed to describe one |
---|
| 41 | set of extractions methods. Each method may be used by more than |
---|
| 42 | one pattern if the operands are in the same place. |
---|
| 43 | |
---|
| 44 | The string for each operand describes that path to the operand and |
---|
| 45 | contains `0' through `9' when going into an expression and `a' through |
---|
| 46 | `z' when going into a vector. We assume here that only the first operand |
---|
| 47 | of an rtl expression is a vector. genrecog.c makes the same assumption |
---|
| 48 | (and uses the same representation) and it is currently true. */ |
---|
| 49 | |
---|
| 50 | struct extraction |
---|
| 51 | { |
---|
| 52 | int op_count; |
---|
| 53 | char *oplocs[MAX_RECOG_OPERANDS]; |
---|
| 54 | int dup_count; |
---|
| 55 | char *duplocs[MAX_DUP_OPERANDS]; |
---|
| 56 | int dupnums[MAX_DUP_OPERANDS]; |
---|
| 57 | struct code_ptr *insns; |
---|
| 58 | struct extraction *next; |
---|
| 59 | }; |
---|
| 60 | |
---|
| 61 | /* Holds a single insn code that use an extraction method. */ |
---|
| 62 | |
---|
| 63 | struct code_ptr |
---|
| 64 | { |
---|
| 65 | int insn_code; |
---|
| 66 | struct code_ptr *next; |
---|
| 67 | }; |
---|
| 68 | |
---|
| 69 | static struct extraction *extractions; |
---|
| 70 | |
---|
| 71 | /* Number instruction patterns handled, starting at 0 for first one. */ |
---|
| 72 | |
---|
| 73 | static int insn_code_number; |
---|
| 74 | |
---|
| 75 | /* Records the large operand number in this insn. */ |
---|
| 76 | |
---|
| 77 | static int op_count; |
---|
| 78 | |
---|
| 79 | /* Records the location of any operands using the string format described |
---|
| 80 | above. */ |
---|
| 81 | |
---|
| 82 | static char *oplocs[MAX_RECOG_OPERANDS]; |
---|
| 83 | |
---|
| 84 | /* Number the occurrences of MATCH_DUP in each instruction, |
---|
| 85 | starting at 0 for the first occurrence. */ |
---|
| 86 | |
---|
| 87 | static int dup_count; |
---|
| 88 | |
---|
| 89 | /* Records the location of any MATCH_DUP operands. */ |
---|
| 90 | |
---|
| 91 | static char *duplocs[MAX_DUP_OPERANDS]; |
---|
| 92 | |
---|
| 93 | /* Record the operand number of any MATCH_DUPs. */ |
---|
| 94 | |
---|
| 95 | static int dupnums[MAX_DUP_OPERANDS]; |
---|
| 96 | |
---|
| 97 | /* Record the list of insn_codes for peepholes. */ |
---|
| 98 | |
---|
| 99 | static struct code_ptr *peepholes; |
---|
| 100 | |
---|
| 101 | static void walk_rtx (); |
---|
| 102 | static void print_path (); |
---|
| 103 | char *xmalloc (); |
---|
| 104 | char *xrealloc (); |
---|
| 105 | static void fatal (); |
---|
| 106 | static char *copystr (); |
---|
| 107 | static void mybzero (); |
---|
| 108 | void fancy_abort (); |
---|
| 109 | |
---|
| 110 | static void |
---|
| 111 | gen_insn (insn) |
---|
| 112 | rtx insn; |
---|
| 113 | { |
---|
| 114 | register int i; |
---|
| 115 | register struct extraction *p; |
---|
| 116 | register struct code_ptr *link; |
---|
| 117 | |
---|
| 118 | op_count = 0; |
---|
| 119 | dup_count = 0; |
---|
| 120 | |
---|
| 121 | /* No operands seen so far in this pattern. */ |
---|
| 122 | mybzero (oplocs, sizeof oplocs); |
---|
| 123 | |
---|
| 124 | /* Walk the insn's pattern, remembering at all times the path |
---|
| 125 | down to the walking point. */ |
---|
| 126 | |
---|
| 127 | if (XVECLEN (insn, 1) == 1) |
---|
| 128 | walk_rtx (XVECEXP (insn, 1, 0), ""); |
---|
| 129 | else |
---|
| 130 | for (i = XVECLEN (insn, 1) - 1; i >= 0; i--) |
---|
| 131 | { |
---|
| 132 | char *path = (char *) alloca (2); |
---|
| 133 | |
---|
| 134 | path[0] = 'a' + i; |
---|
| 135 | path[1] = 0; |
---|
| 136 | |
---|
| 137 | walk_rtx (XVECEXP (insn, 1, i), path); |
---|
| 138 | } |
---|
| 139 | |
---|
| 140 | link = (struct code_ptr *) xmalloc (sizeof (struct code_ptr)); |
---|
| 141 | link->insn_code = insn_code_number; |
---|
| 142 | |
---|
| 143 | /* See if we find something that already had this extraction method. */ |
---|
| 144 | |
---|
| 145 | for (p = extractions; p; p = p->next) |
---|
| 146 | { |
---|
| 147 | if (p->op_count != op_count || p->dup_count != dup_count) |
---|
| 148 | continue; |
---|
| 149 | |
---|
| 150 | for (i = 0; i < op_count; i++) |
---|
| 151 | if (p->oplocs[i] != oplocs[i] |
---|
| 152 | && ! (p->oplocs[i] != 0 && oplocs[i] != 0 |
---|
| 153 | && ! strcmp (p->oplocs[i], oplocs[i]))) |
---|
| 154 | break; |
---|
| 155 | |
---|
| 156 | if (i != op_count) |
---|
| 157 | continue; |
---|
| 158 | |
---|
| 159 | for (i = 0; i < dup_count; i++) |
---|
| 160 | if (p->dupnums[i] != dupnums[i] |
---|
| 161 | || strcmp (p->duplocs[i], duplocs[i])) |
---|
| 162 | break; |
---|
| 163 | |
---|
| 164 | if (i != dup_count) |
---|
| 165 | continue; |
---|
| 166 | |
---|
| 167 | /* This extraction is the same as ours. Just link us in. */ |
---|
| 168 | link->next = p->insns; |
---|
| 169 | p->insns = link; |
---|
| 170 | return; |
---|
| 171 | } |
---|
| 172 | |
---|
| 173 | /* Otherwise, make a new extraction method. */ |
---|
| 174 | |
---|
| 175 | p = (struct extraction *) xmalloc (sizeof (struct extraction)); |
---|
| 176 | p->op_count = op_count; |
---|
| 177 | p->dup_count = dup_count; |
---|
| 178 | p->next = extractions; |
---|
| 179 | extractions = p; |
---|
| 180 | p->insns = link; |
---|
| 181 | link->next = 0; |
---|
| 182 | |
---|
| 183 | for (i = 0; i < op_count; i++) |
---|
| 184 | p->oplocs[i] = oplocs[i]; |
---|
| 185 | |
---|
| 186 | for (i = 0; i < dup_count; i++) |
---|
| 187 | p->dupnums[i] = dupnums[i], p->duplocs[i] = duplocs[i]; |
---|
| 188 | } |
---|
| 189 | |
---|
| 190 | static void |
---|
| 191 | walk_rtx (x, path) |
---|
| 192 | rtx x; |
---|
| 193 | char *path; |
---|
| 194 | { |
---|
| 195 | register RTX_CODE code; |
---|
| 196 | register int i; |
---|
| 197 | register int len; |
---|
| 198 | register char *fmt; |
---|
| 199 | register struct code_ptr *link; |
---|
| 200 | int depth = strlen (path); |
---|
| 201 | char *newpath; |
---|
| 202 | |
---|
| 203 | if (x == 0) |
---|
| 204 | return; |
---|
| 205 | |
---|
| 206 | code = GET_CODE (x); |
---|
| 207 | |
---|
| 208 | switch (code) |
---|
| 209 | { |
---|
| 210 | case PC: |
---|
| 211 | case CC0: |
---|
| 212 | case CONST_INT: |
---|
| 213 | case SYMBOL_REF: |
---|
| 214 | return; |
---|
| 215 | |
---|
| 216 | case MATCH_OPERAND: |
---|
| 217 | case MATCH_SCRATCH: |
---|
| 218 | oplocs[XINT (x, 0)] = copystr (path); |
---|
| 219 | op_count = MAX (op_count, XINT (x, 0) + 1); |
---|
| 220 | break; |
---|
| 221 | |
---|
| 222 | case MATCH_DUP: |
---|
| 223 | case MATCH_PAR_DUP: |
---|
| 224 | duplocs[dup_count] = copystr (path); |
---|
| 225 | dupnums[dup_count] = XINT (x, 0); |
---|
| 226 | dup_count++; |
---|
| 227 | break; |
---|
| 228 | |
---|
| 229 | case MATCH_OP_DUP: |
---|
| 230 | duplocs[dup_count] = copystr (path); |
---|
| 231 | dupnums[dup_count] = XINT (x, 0); |
---|
| 232 | dup_count++; |
---|
| 233 | |
---|
| 234 | newpath = (char *) alloca (depth + 2); |
---|
| 235 | strcpy (newpath, path); |
---|
| 236 | newpath[depth + 1] = 0; |
---|
| 237 | |
---|
| 238 | for (i = XVECLEN (x, 1) - 1; i >= 0; i--) |
---|
| 239 | { |
---|
| 240 | newpath[depth] = '0' + i; |
---|
| 241 | walk_rtx (XVECEXP (x, 1, i), newpath); |
---|
| 242 | } |
---|
| 243 | return; |
---|
| 244 | |
---|
| 245 | case MATCH_OPERATOR: |
---|
| 246 | oplocs[XINT (x, 0)] = copystr (path); |
---|
| 247 | op_count = MAX (op_count, XINT (x, 0) + 1); |
---|
| 248 | |
---|
| 249 | newpath = (char *) alloca (depth + 2); |
---|
| 250 | strcpy (newpath, path); |
---|
| 251 | newpath[depth + 1] = 0; |
---|
| 252 | |
---|
| 253 | for (i = XVECLEN (x, 2) - 1; i >= 0; i--) |
---|
| 254 | { |
---|
| 255 | newpath[depth] = '0' + i; |
---|
| 256 | walk_rtx (XVECEXP (x, 2, i), newpath); |
---|
| 257 | } |
---|
| 258 | return; |
---|
| 259 | |
---|
| 260 | case MATCH_PARALLEL: |
---|
| 261 | oplocs[XINT (x, 0)] = copystr (path); |
---|
| 262 | op_count = MAX (op_count, XINT (x, 0) + 1); |
---|
| 263 | |
---|
| 264 | newpath = (char *) alloca (depth + 2); |
---|
| 265 | strcpy (newpath, path); |
---|
| 266 | newpath[depth + 1] = 0; |
---|
| 267 | |
---|
| 268 | for (i = XVECLEN (x, 2) - 1; i >= 0; i--) |
---|
| 269 | { |
---|
| 270 | newpath[depth] = 'a' + i; |
---|
| 271 | walk_rtx (XVECEXP (x, 2, i), newpath); |
---|
| 272 | } |
---|
| 273 | return; |
---|
| 274 | |
---|
| 275 | case ADDRESS: |
---|
| 276 | walk_rtx (XEXP (x, 0), path); |
---|
| 277 | return; |
---|
| 278 | } |
---|
| 279 | |
---|
| 280 | newpath = (char *) alloca (depth + 2); |
---|
| 281 | strcpy (newpath, path); |
---|
| 282 | newpath[depth + 1] = 0; |
---|
| 283 | |
---|
| 284 | fmt = GET_RTX_FORMAT (code); |
---|
| 285 | len = GET_RTX_LENGTH (code); |
---|
| 286 | for (i = 0; i < len; i++) |
---|
| 287 | { |
---|
| 288 | if (fmt[i] == 'e' || fmt[i] == 'u') |
---|
| 289 | { |
---|
| 290 | newpath[depth] = '0' + i; |
---|
| 291 | walk_rtx (XEXP (x, i), newpath); |
---|
| 292 | } |
---|
| 293 | else if (fmt[i] == 'E') |
---|
| 294 | { |
---|
| 295 | int j; |
---|
| 296 | for (j = XVECLEN (x, i) - 1; j >= 0; j--) |
---|
| 297 | { |
---|
| 298 | newpath[depth] = 'a' + j; |
---|
| 299 | walk_rtx (XVECEXP (x, i, j), newpath); |
---|
| 300 | } |
---|
| 301 | } |
---|
| 302 | } |
---|
| 303 | } |
---|
| 304 | |
---|
| 305 | /* Given a PATH, representing a path down the instruction's |
---|
| 306 | pattern from the root to a certain point, output code to |
---|
| 307 | evaluate to the rtx at that point. */ |
---|
| 308 | |
---|
| 309 | static void |
---|
| 310 | print_path (path) |
---|
| 311 | char *path; |
---|
| 312 | { |
---|
| 313 | register int len = strlen (path); |
---|
| 314 | register int i; |
---|
| 315 | |
---|
| 316 | /* We first write out the operations (XEXP or XVECEXP) in reverse |
---|
| 317 | order, then write "insn", then the indices in forward order. */ |
---|
| 318 | |
---|
| 319 | for (i = len - 1; i >=0 ; i--) |
---|
| 320 | { |
---|
| 321 | if (path[i] >= 'a' && path[i] <= 'z') |
---|
| 322 | printf ("XVECEXP ("); |
---|
| 323 | else if (path[i] >= '0' && path[i] <= '9') |
---|
| 324 | printf ("XEXP ("); |
---|
| 325 | else |
---|
| 326 | abort (); |
---|
| 327 | } |
---|
| 328 | |
---|
| 329 | printf ("pat"); |
---|
| 330 | |
---|
| 331 | for (i = 0; i < len; i++) |
---|
| 332 | { |
---|
| 333 | if (path[i] >= 'a' && path[i] <= 'z') |
---|
| 334 | printf (", 0, %d)", path[i] - 'a'); |
---|
| 335 | else if (path[i] >= '0' && path[i] <= '9') |
---|
| 336 | printf (", %d)", path[i] - '0'); |
---|
| 337 | else |
---|
| 338 | abort (); |
---|
| 339 | } |
---|
| 340 | } |
---|
| 341 | |
---|
| 342 | char * |
---|
| 343 | xmalloc (size) |
---|
| 344 | unsigned size; |
---|
| 345 | { |
---|
| 346 | register char *val = (char *) malloc (size); |
---|
| 347 | |
---|
| 348 | if (val == 0) |
---|
| 349 | fatal ("virtual memory exhausted"); |
---|
| 350 | return val; |
---|
| 351 | } |
---|
| 352 | |
---|
| 353 | char * |
---|
| 354 | xrealloc (ptr, size) |
---|
| 355 | char *ptr; |
---|
| 356 | unsigned size; |
---|
| 357 | { |
---|
| 358 | char *result = (char *) realloc (ptr, size); |
---|
| 359 | if (!result) |
---|
| 360 | fatal ("virtual memory exhausted"); |
---|
| 361 | return result; |
---|
| 362 | } |
---|
| 363 | |
---|
| 364 | static void |
---|
| 365 | fatal (s, a1, a2) |
---|
| 366 | char *s; |
---|
| 367 | { |
---|
| 368 | fprintf (stderr, "genextract: "); |
---|
| 369 | fprintf (stderr, s, a1, a2); |
---|
| 370 | fprintf (stderr, "\n"); |
---|
| 371 | exit (FATAL_EXIT_CODE); |
---|
| 372 | } |
---|
| 373 | |
---|
| 374 | /* More 'friendly' abort that prints the line and file. |
---|
| 375 | config.h can #define abort fancy_abort if you like that sort of thing. */ |
---|
| 376 | |
---|
| 377 | void |
---|
| 378 | fancy_abort () |
---|
| 379 | { |
---|
| 380 | fatal ("Internal gcc abort."); |
---|
| 381 | } |
---|
| 382 | |
---|
| 383 | static char * |
---|
| 384 | copystr (s1) |
---|
| 385 | char *s1; |
---|
| 386 | { |
---|
| 387 | register char *tem; |
---|
| 388 | |
---|
| 389 | if (s1 == 0) |
---|
| 390 | return 0; |
---|
| 391 | |
---|
| 392 | tem = (char *) xmalloc (strlen (s1) + 1); |
---|
| 393 | strcpy (tem, s1); |
---|
| 394 | |
---|
| 395 | return tem; |
---|
| 396 | } |
---|
| 397 | |
---|
| 398 | static void |
---|
| 399 | mybzero (b, length) |
---|
| 400 | register char *b; |
---|
| 401 | register unsigned length; |
---|
| 402 | { |
---|
| 403 | while (length-- > 0) |
---|
| 404 | *b++ = 0; |
---|
| 405 | } |
---|
| 406 | |
---|
| 407 | int |
---|
| 408 | main (argc, argv) |
---|
| 409 | int argc; |
---|
| 410 | char **argv; |
---|
| 411 | { |
---|
| 412 | rtx desc; |
---|
| 413 | FILE *infile; |
---|
| 414 | register int c, i; |
---|
| 415 | struct extraction *p; |
---|
| 416 | struct code_ptr *link; |
---|
| 417 | |
---|
| 418 | obstack_init (rtl_obstack); |
---|
| 419 | |
---|
| 420 | if (argc <= 1) |
---|
| 421 | fatal ("No input file name."); |
---|
| 422 | |
---|
| 423 | infile = fopen (argv[1], "r"); |
---|
| 424 | if (infile == 0) |
---|
| 425 | { |
---|
| 426 | perror (argv[1]); |
---|
| 427 | exit (FATAL_EXIT_CODE); |
---|
| 428 | } |
---|
| 429 | |
---|
| 430 | init_rtl (); |
---|
| 431 | |
---|
| 432 | /* Assign sequential codes to all entries in the machine description |
---|
| 433 | in parallel with the tables in insn-output.c. */ |
---|
| 434 | |
---|
| 435 | insn_code_number = 0; |
---|
| 436 | |
---|
| 437 | printf ("/* Generated automatically by the program `genextract'\n\ |
---|
| 438 | from the machine description file `md'. */\n\n"); |
---|
| 439 | |
---|
| 440 | printf ("#include \"config.h\"\n"); |
---|
| 441 | printf ("#include \"rtl.h\"\n\n"); |
---|
| 442 | |
---|
| 443 | /* This variable exists only so it can be the "location" |
---|
| 444 | of any missing operand whose numbers are skipped by a given pattern. */ |
---|
| 445 | printf ("static rtx junk;\n"); |
---|
| 446 | |
---|
| 447 | printf ("extern rtx recog_operand[];\n"); |
---|
| 448 | printf ("extern rtx *recog_operand_loc[];\n"); |
---|
| 449 | printf ("extern rtx *recog_dup_loc[];\n"); |
---|
| 450 | printf ("extern char recog_dup_num[];\n"); |
---|
| 451 | |
---|
| 452 | printf ("void\ninsn_extract (insn)\n"); |
---|
| 453 | printf (" rtx insn;\n"); |
---|
| 454 | printf ("{\n"); |
---|
| 455 | printf (" register rtx *ro = recog_operand;\n"); |
---|
| 456 | printf (" register rtx **ro_loc = recog_operand_loc;\n"); |
---|
| 457 | printf (" rtx pat = PATTERN (insn);\n"); |
---|
| 458 | printf (" switch (INSN_CODE (insn))\n"); |
---|
| 459 | printf (" {\n"); |
---|
| 460 | printf (" case -1:\n"); |
---|
| 461 | printf (" fatal_insn_not_found (insn);\n\n"); |
---|
| 462 | |
---|
| 463 | /* Read the machine description. */ |
---|
| 464 | |
---|
| 465 | while (1) |
---|
| 466 | { |
---|
| 467 | c = read_skip_spaces (infile); |
---|
| 468 | if (c == EOF) |
---|
| 469 | break; |
---|
| 470 | ungetc (c, infile); |
---|
| 471 | |
---|
| 472 | desc = read_rtx (infile); |
---|
| 473 | if (GET_CODE (desc) == DEFINE_INSN) |
---|
| 474 | { |
---|
| 475 | gen_insn (desc); |
---|
| 476 | ++insn_code_number; |
---|
| 477 | } |
---|
| 478 | |
---|
| 479 | else if (GET_CODE (desc) == DEFINE_PEEPHOLE) |
---|
| 480 | { |
---|
| 481 | struct code_ptr *link |
---|
| 482 | = (struct code_ptr *) xmalloc (sizeof (struct code_ptr)); |
---|
| 483 | |
---|
| 484 | link->insn_code = insn_code_number; |
---|
| 485 | link->next = peepholes; |
---|
| 486 | peepholes = link; |
---|
| 487 | ++insn_code_number; |
---|
| 488 | } |
---|
| 489 | |
---|
| 490 | else if (GET_CODE (desc) == DEFINE_EXPAND |
---|
| 491 | || GET_CODE (desc) == DEFINE_SPLIT) |
---|
| 492 | ++insn_code_number; |
---|
| 493 | } |
---|
| 494 | |
---|
| 495 | /* Write out code to handle peepholes and the insn_codes that it should |
---|
| 496 | be called for. */ |
---|
| 497 | if (peepholes) |
---|
| 498 | { |
---|
| 499 | for (link = peepholes; link; link = link->next) |
---|
| 500 | printf (" case %d:\n", link->insn_code); |
---|
| 501 | |
---|
| 502 | /* The vector in the insn says how many operands it has. |
---|
| 503 | And all it contains are operands. In fact, the vector was |
---|
| 504 | created just for the sake of this function. */ |
---|
| 505 | printf ("#if __GNUC__ > 1 && !defined (bcopy)\n"); |
---|
| 506 | printf ("#define bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)\n"); |
---|
| 507 | printf ("#endif\n"); |
---|
| 508 | printf (" bcopy (&XVECEXP (pat, 0, 0), ro,\n"); |
---|
| 509 | printf (" sizeof (rtx) * XVECLEN (pat, 0));\n"); |
---|
| 510 | printf (" break;\n\n"); |
---|
| 511 | } |
---|
| 512 | |
---|
| 513 | /* Write out all the ways to extract insn operands. */ |
---|
| 514 | for (p = extractions; p; p = p->next) |
---|
| 515 | { |
---|
| 516 | for (link = p->insns; link; link = link->next) |
---|
| 517 | printf (" case %d:\n", link->insn_code); |
---|
| 518 | |
---|
| 519 | for (i = 0; i < p->op_count; i++) |
---|
| 520 | { |
---|
| 521 | if (p->oplocs[i] == 0) |
---|
| 522 | { |
---|
| 523 | printf (" ro[%d] = const0_rtx;\n", i); |
---|
| 524 | printf (" ro_loc[%d] = &junk;\n", i); |
---|
| 525 | } |
---|
| 526 | else |
---|
| 527 | { |
---|
| 528 | printf (" ro[%d] = *(ro_loc[%d] = &", i, i); |
---|
| 529 | print_path (p->oplocs[i]); |
---|
| 530 | printf (");\n"); |
---|
| 531 | } |
---|
| 532 | } |
---|
| 533 | |
---|
| 534 | for (i = 0; i < p->dup_count; i++) |
---|
| 535 | { |
---|
| 536 | printf (" recog_dup_loc[%d] = &", i); |
---|
| 537 | print_path (p->duplocs[i]); |
---|
| 538 | printf (";\n"); |
---|
| 539 | printf (" recog_dup_num[%d] = %d;\n", i, p->dupnums[i]); |
---|
| 540 | } |
---|
| 541 | |
---|
| 542 | printf (" break;\n\n"); |
---|
| 543 | } |
---|
| 544 | |
---|
| 545 | /* This should never be reached. Note that we would also reach this abort |
---|
| 546 | if we tried to extract something whose INSN_CODE was a DEFINE_EXPAND or |
---|
| 547 | DEFINE_SPLIT, but that is correct. */ |
---|
| 548 | printf (" default:\n abort ();\n"); |
---|
| 549 | |
---|
| 550 | printf (" }\n}\n"); |
---|
| 551 | |
---|
| 552 | fflush (stdout); |
---|
| 553 | exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); |
---|
| 554 | /* NOTREACHED */ |
---|
| 555 | return 0; |
---|
| 556 | } |
---|