|
|
1.1 root 1: /* Generate code to initialize optabs from machine description. 1.1.1.2 ! root 2: Copyright (C) 1993, 1994 Free Software Foundation, Inc. 1.1 root 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19: 20: 21: #include <stdio.h> 22: #include "hconfig.h" 23: #include "rtl.h" 24: #include "obstack.h" 25: #include <ctype.h> 26: 27: static struct obstack obstack; 28: struct obstack *rtl_obstack = &obstack; 29: 30: #define obstack_chunk_alloc xmalloc 31: #define obstack_chunk_free free 32: 33: extern void free (); 34: extern rtx read_rtx (); 35: 36: char *xmalloc (); 37: static void fatal (); 38: void fancy_abort (); 39: 40: /* Many parts of GCC use arrays that are indexed by machine mode and 41: contain the insn codes for pattern in the MD file that perform a given 42: operation on operands of that mode. 43: 44: These patterns are present in the MD file with names that contain 45: the mode(s) used and the name of the operation. This program 46: writes a function `init_all_optabs' that initializes the optabs with 47: all the insn codes of the relevant patterns present in the MD file. 48: 49: This array contains a list of optabs that need to be initialized. Within 50: each string, the name of the pattern to be matched against is delimited 51: with %( and %). In the string, %a and %b are used to match a short mode 52: name (the part of the mode name not including `mode' and converted to 53: lower-case). When writing out the initializer, the entire string is 54: used. %A and %B are replaced with the full name of the mode; %a and %b 55: are replaced with the short form of the name, as above. 56: 57: If %N is present in the pattern, it means the two modes must be consecutive 58: widths in the same mode class (e.g, QImode and HImode). %I means that 59: only integer modes should be considered for the next mode, and %F means 60: that only float modes should be considered. 61: 62: For some optabs, we store the operation by RTL codes. These are only 63: used for comparisons. In that case, %c and %C are the lower-case and 64: upper-case forms of the comparison, respectively. */ 65: 66: /* The reason we use \% is to avoid sequences of the form %-capletter-% 67: which SCCS treats as magic. This gets warnings which you should ignore. */ 68: 69: char *optabs[] = 70: { "extendtab[(int) %B][(int) %A][0] = CODE_FOR_%(extend%a\%b2%)", 71: "extendtab[(int) %B][(int) %A][1] = CODE_FOR_%(zero_extend%a\%b2%)", 72: "fixtab[(int) %A][(int) %B][0] = CODE_FOR_%(fix%F\%a%I\%b2%)", 73: "fixtab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns%F\%a%b2%)", 74: "fixtrunctab[(int) %A][(int) %B][0] = CODE_FOR_%(fix_trunc%F\%a%I\%b2%)", 75: "fixtrunctab[(int) %A][(int) %B][1] = CODE_FOR_%(fixuns_trunc%F\%a%I\%b2%)", 76: "floattab[(int) %B][(int) %A][0] = CODE_FOR_%(float%I\%a%F\%b2%)", 77: "floattab[(int) %B][(int) %A][1] = CODE_FOR_%(floatuns%I\%a%F\%b2%)", 78: "add_optab->handlers[(int) %A].insn_code = CODE_FOR_%(add%a3%)", 79: "sub_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sub%a3%)", 80: "smul_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mul%a3%)", 1.1.1.2 ! root 81: "umul_highpart_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umul%a3_highpart%)", ! 82: "smul_highpart_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smul%a3_highpart%)", 1.1 root 83: "smul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(mul%a%b3%)%N", 84: "umul_widen_optab->handlers[(int) %B].insn_code = CODE_FOR_%(umul%a%b3%)%N", 85: "sdiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%I\%a3%)", 86: "udiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udiv%I\%a3%)", 87: "sdivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(divmod%a4%)", 88: "udivmod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(udivmod%a4%)", 89: "smod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mod%a3%)", 90: "umod_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umod%a3%)", 91: "flodiv_optab->handlers[(int) %A].insn_code = CODE_FOR_%(div%F\%a3%)", 92: "ftrunc_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ftrunc%F\%a2%)", 93: "and_optab->handlers[(int) %A].insn_code = CODE_FOR_%(and%a3%)", 94: "ior_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ior%a3%)", 95: "xor_optab->handlers[(int) %A].insn_code = CODE_FOR_%(xor%a3%)", 96: "ashl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashl%a3%)", 97: "ashr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ashr%a3%)", 98: "lshr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(lshr%a3%)", 99: "rotl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotl%a3%)", 100: "rotr_optab->handlers[(int) %A].insn_code = CODE_FOR_%(rotr%a3%)", 101: "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smin%I\%a3%)", 102: "smin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(min%F\%a3%)", 103: "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(smax%I\%a3%)", 104: "smax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(max%F\%a3%)", 105: "umin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umin%I\%a3%)", 106: "umax_optab->handlers[(int) %A].insn_code = CODE_FOR_%(umax%I\%a3%)", 107: "neg_optab->handlers[(int) %A].insn_code = CODE_FOR_%(neg%a2%)", 108: "abs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(abs%a2%)", 109: "sqrt_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sqrt%a2%)", 110: "sin_optab->handlers[(int) %A].insn_code = CODE_FOR_%(sin%a2%)", 111: "cos_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cos%a2%)", 112: "strlen_optab->handlers[(int) %A].insn_code = CODE_FOR_%(strlen%a%)", 113: "one_cmpl_optab->handlers[(int) %A].insn_code = CODE_FOR_%(one_cmpl%a2%)", 114: "ffs_optab->handlers[(int) %A].insn_code = CODE_FOR_%(ffs%a2%)", 115: "mov_optab->handlers[(int) %A].insn_code = CODE_FOR_%(mov%a%)", 116: "movstrict_optab->handlers[(int) %A].insn_code = CODE_FOR_%(movstrict%a%)", 117: "cmp_optab->handlers[(int) %A].insn_code = CODE_FOR_%(cmp%a%)", 118: "tst_optab->handlers[(int) %A].insn_code = CODE_FOR_%(tst%a%)", 119: "bcc_gen_fctn[(int) %C] = gen_%(b%c%)", 120: "setcc_gen_code[(int) %C] = CODE_FOR_%(s%c%)", 121: "reload_in_optab[(int) %A] = CODE_FOR_%(reload_in%a%)", 122: "reload_out_optab[(int) %A] = CODE_FOR_%(reload_out%a%)", 123: "movstr_optab[(int) %A] = CODE_FOR_%(movstr%a%)" }; 124: 125: /* Allow linking with print-rtl.c. */ 126: char **insn_name_ptr; 127: 128: static void 129: gen_insn (insn) 130: rtx insn; 131: { 132: char *name = XSTR (insn, 0); 133: int m1, m2, op; 134: int pindex; 135: int i; 136: char *np, *pp, *p, *q; 137: struct obstack *obstack_ptr; 138: 139: /* Don't mention instructions whose names are the null string. 140: They are in the machine description just to be recognized. */ 141: if (*name == 0) 142: return; 143: 144: /* See if NAME matches one of the patterns we have for the optabs we know 145: about. */ 146: 147: for (pindex = 0; pindex < sizeof optabs / sizeof optabs[0]; pindex++) 148: { 149: int force_float = 0, force_int = 0; 150: int force_consec = 0; 151: int matches = 1; 152: 153: for (pp = optabs[pindex]; pp[0] != '%' || pp[1] != '('; pp++) 154: ; 155: 156: for (pp += 2, np = name; matches && ! (pp[0] == '%' && pp[1] == ')'); 157: pp++) 158: { 159: if (*pp != '%') 160: { 161: if (*pp != *np++) 162: break; 163: } 164: else 165: switch (*++pp) 166: { 167: case 'N': 168: force_consec = 1; 169: break; 170: case 'I': 171: force_int = 1; 172: break; 173: case 'F': 174: force_float = 1; 175: break; 176: case 'c': 177: for (op = 0; op < NUM_RTX_CODE; op++) 178: { 179: for (p = rtx_name[op], q = np; *p; p++, q++) 180: if (*p != *q) 181: break; 182: 183: /* We have to be concerned about matching "gt" and 184: missing "gtu", e.g., so verify we have reached the 185: end of thing we are to match. We do not have this 186: problem with modes since no mode is a prefix of 187: another. */ 188: if (*p == 0 && *q == 0 && rtx_class[op] == '<') 189: break; 190: } 191: 192: if (op == NUM_RTX_CODE) 193: matches = 0; 194: else 195: np += strlen (rtx_name[op]); 196: break; 197: case 'a': 198: case 'b': 199: for (i = 0; i < (int) MAX_MACHINE_MODE; i++) 200: { 201: for (p = mode_name[i], q = np; *p; p++, q++) 202: if (tolower (*p) != *q) 203: break; 204: 205: if (*p == 0 206: && (! force_int || mode_class[i] == MODE_INT) 207: && (! force_float || mode_class[i] == MODE_FLOAT)) 208: break; 209: } 210: 211: if (i == (int) MAX_MACHINE_MODE) 212: matches = 0; 213: else if (*pp == 'a') 214: m1 = i, np += strlen (mode_name[i]); 215: else 216: m2 = i, np += strlen (mode_name[i]); 217: 218: force_int = force_float = 0; 219: break; 220: 221: default: 222: abort (); 223: } 224: } 225: 226: if (matches && pp[0] == '%' && pp[1] == ')' 227: && *np == 0 228: && (! force_consec || (int) mode_wider_mode[m1] == m2)) 229: break; 230: } 231: 232: if (pindex == sizeof optabs / sizeof optabs[0]) 233: return; 234: 235: /* We found a match. If this pattern is only conditionally present, 236: write out the "if" and two extra blanks. */ 237: 238: if (*XSTR (insn, 2) != 0) 239: printf (" if (HAVE_%s)\n ", name); 240: 241: printf (" "); 242: 243: /* Now write out the initialization, making all required substitutions. */ 244: for (pp = optabs[pindex]; *pp; pp++) 245: { 246: if (*pp != '%') 247: printf ("%c", *pp); 248: else 249: switch (*++pp) 250: { 251: case '(': case ')': 252: case 'I': case 'F': case 'N': 253: break; 254: case 'a': 255: for (np = mode_name[m1]; *np; np++) 256: printf ("%c", tolower (*np)); 257: break; 258: case 'b': 259: for (np = mode_name[m2]; *np; np++) 260: printf ("%c", tolower (*np)); 261: break; 262: case 'A': 263: printf ("%smode", mode_name[m1]); 264: break; 265: case 'B': 266: printf ("%smode", mode_name[m2]); 267: break; 268: case 'c': 269: printf ("%s", rtx_name[op]); 270: break; 271: case 'C': 272: for (np = rtx_name[op]; *np; np++) 273: printf ("%c", toupper (*np)); 274: break; 275: } 276: } 277: 278: printf (";\n"); 279: } 280: 281: char * 282: xmalloc (size) 283: unsigned size; 284: { 285: register char *val = (char *) malloc (size); 286: 287: if (val == 0) 288: fatal ("virtual memory exhausted"); 289: 290: return val; 291: } 292: 293: char * 294: xrealloc (ptr, size) 295: char *ptr; 296: unsigned size; 297: { 298: char *result = (char *) realloc (ptr, size); 299: if (!result) 300: fatal ("virtual memory exhausted"); 301: return result; 302: } 303: 304: static void 305: fatal (s, a1, a2) 306: char *s; 307: { 308: fprintf (stderr, "genopinit: "); 309: fprintf (stderr, s, a1, a2); 310: fprintf (stderr, "\n"); 311: exit (FATAL_EXIT_CODE); 312: } 313: 314: /* More 'friendly' abort that prints the line and file. 315: config.h can #define abort fancy_abort if you like that sort of thing. */ 316: 317: void 318: fancy_abort () 319: { 320: fatal ("Internal gcc abort."); 321: } 322: 323: int 324: main (argc, argv) 325: int argc; 326: char **argv; 327: { 328: rtx desc; 329: rtx dummy; 330: rtx *insn_ptr; 331: FILE *infile; 332: register int c; 333: 334: obstack_init (rtl_obstack); 335: 336: if (argc <= 1) 337: fatal ("No input file name."); 338: 339: infile = fopen (argv[1], "r"); 340: if (infile == 0) 341: { 342: perror (argv[1]); 343: exit (FATAL_EXIT_CODE); 344: } 345: 346: init_rtl (); 347: 348: printf ("/* Generated automatically by the program `genopinit'\n\ 349: from the machine description file `md'. */\n\n"); 350: 351: printf ("#include \"config.h\"\n"); 352: printf ("#include \"rtl.h\"\n"); 353: printf ("#include \"flags.h\"\n"); 354: printf ("#include \"insn-flags.h\"\n"); 355: printf ("#include \"insn-codes.h\"\n"); 356: printf ("#include \"insn-config.h\"\n"); 357: printf ("#include \"recog.h\"\n"); 358: printf ("#include \"expr.h\"\n"); 359: printf ("#include \"reload.h\"\n\n"); 360: 361: printf ("void\ninit_all_optabs ()\n{\n"); 362: 363: /* Read the machine description. */ 364: 365: while (1) 366: { 367: c = read_skip_spaces (infile); 368: if (c == EOF) 369: break; 370: ungetc (c, infile); 371: 372: desc = read_rtx (infile); 373: if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND) 374: gen_insn (desc); 375: } 376: 377: printf ("}\n"); 378: 379: fflush (stdout); 380: exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); 381: /* NOTREACHED */ 382: return 0; 383: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.