Back to main, after creating data for using modesfrom machmode.def and i386-modes.def, complete_all_modes is invoked to finish thecreation.
389 static void
390 complete_all_modes (void) ingenmodes.c
391 {
392 struct mode_data*m;
393 enum mode_class c;
394
395 for_all_modes (c, m)
396 complete_mode (m);
397 }
for_all_modes is a macro to iterate all data in modes.
191 #define for_all_modes(C, M) \ in genmodes.c
192 for (C = 0; C < MAX_MODE_CLASS; C++) \
193 for (M = modes[C]; M; M = M->next)
For every mode, fills the known fields if it is valid.
282 static void
283 complete_mode (struct mode_data *m) ingenmodes.c
284 {
285 unsigned int alignment;
286
287 if (!m->name)
288 {
289 error ("%s:%d: mode with no name", m->file, m->line);
290 return;
291 }
292 if (m->class == MAX_MODE_CLASS)
293 {
294 error ("%s:%d: %smode has no mode class", m->file,m->line, m->name);
295 return;
296 }
297
298 switch (m->class)
299 {
300 case MODE_RANDOM:
301 /* Nothing more need be said. */
302 if (!strcmp (m->name, "VOID"))
303 void_mode= m;
304
305 validate_mode (m, UNSET, UNSET, UNSET,UNSET, UNSET);
306
307 m->precision = 0;
308 m->bytesize = 0;
309 m->ncomponents = 0;
310 m->component = 0;
311 break;
312
313 case MODE_CC:
314 /* Again, nothing more need be said. For historical reasons,
315 the size of a CC mode is fourunits. */
316 validate_mode (m, UNSET, UNSET, UNSET,UNSET, UNSET);
317
318 m->bytesize = 4;
319 m->ncomponents = 1;
320 m->component = 0;
321 break;
322
323 case MODE_INT:
324 case MODE_FLOAT:
325 /* A scalar mode must have a byte size, mayhave a bit size,
326 and must not have components. A floatmode must have a
327 format. */
328 validate_mode (m, OPTIONAL, SET, UNSET,UNSET,
329 m->class == MODE_FLOAT ? SET : UNSET);
330
331 m->ncomponents = 1;
332 m->component = 0;
333 break;
334
335 case MODE_PARTIAL_INT:
336 /* A partial integer mode uses ->componentto say what the
337 corresponding full-size integer modeis, and may also
338 specify a bit size. */
339 validate_mode (m, OPTIONAL, UNSET, SET,UNSET, UNSET);
340
341 m->bytesize = m->component->bytesize;
342
343 m->ncomponents = 1;
344 m->component = 0; /* ??? preserve this */
345 break;
346
347 case MODE_COMPLEX_INT:
348 case MODE_COMPLEX_FLOAT:
349 /* Complex modes should have a component indicated,but no more. */
350 validate_mode (m, UNSET, UNSET, SET, UNSET,UNSET);
351 m->ncomponents = 2;
352 if (m->component->precision != (unsigned int)-1)
353 m->precision = 2 * m->component->precision;
354 m->bytesize = 2 * m->component->bytesize;
355 break;
356
357 case MODE_VECTOR_INT:
358 case MODE_VECTOR_FLOAT:
359 /* Vector modes should have a component and anumber of components. */
360 validate_mode (m, UNSET, UNSET, SET, SET,UNSET);
361 if (m->component->precision != (unsigned int)-1)
362 m->precision = m->ncomponents * m->component->precision;
363 m->bytesize = m->ncomponents * m->component->bytesize;
364 break;
365
366 default:
367 abort ();
368 }
369
370 /* If not already specified, the modealignment defaults to the largest
371 power of two that divides the size of theobject. Complex types are
372 not more aligned than their contents. */
373 if (m->class == MODE_COMPLEX_INT || m->class ==MODE_COMPLEX_FLOAT)
374 alignment = m->component->bytesize;
375 else
376 alignment = m->bytesize;
377
378 m->alignment = alignment & (~alignment + 1);
379
380 /* If this mode has components, make thecomponent mode point back
381 to this mode, for the sake ofadjustments. */
382 if (m->component)
383 {
384 m->next_cont = m->component->contained;
385 m->component->contained = m;
386 }
387 }
Modes are validated by validate_mode.
263 static void
264 validate_mode (struct mode_data*m,
265 enumrequirement r_precision,
266 enumrequirement r_bytesize,
267 enum requirementr_component,
268 enumrequirement r_ncomponents,
269 enumrequirement r_format)
270 {
271 validate_field (m, precision);
272 validate_field (m, bytesize);
273 validate_field (m, component);
274 validate_field (m, ncomponents);
275 validate_field (m, format);
276 }
277 #undef validate_field
278 #undef validate_field_
validate_field above is macro definedbelow. That is why we need so many parameters during invoking validate_mode.
243 #define validate_field_(mname, fname, req,val, unset, file, line) do { \ in genmodes.c
244 switch (req) \
245 { \
246 case SET: \
247 if (val == unset) \
248 error ("%s:%d: (%s) field %s must be set", \
249 file, line, mname, fname); \
250 break; \
251 case UNSET: \
252 if (val != unset) \
253 error ("%s:%d: (%s) field %s must not be set", \
254 file, line, mname, fname); \
255 case OPTIONAL: \
256 break; \
257 } \
258 } while(0)
259
260 #define validate_field(M, F) \
261 validate_field_(M->name, #F, r_##F,M->F, blank_mode.F,M->file, M->line)
Notice that the unset value in validate_field_ comes from blank_modewhich is the templet for creating modes in new_mode. The validation just ensures modes arecorrectly initialized.
Before outputting the data, calc_wider_mode sorts mode_data based upon thesame mode with following example, QI < HI < SI < DI < TI and V4QI< V2HI < V8QI < V4HI < V2SI.
692 static void
693 calc_wider_mode (void) ingenmodes.c
694 {
695 enum mode_class c;
696 struct mode_data*m;
697 struct mode_data**sortbuf;
698 unsigned int max_n_modes = 0;
699 unsigned int i, j;
700
701 for (c = 0; c < MAX_MODE_CLASS; c++)
702 max_n_modes = MAX (max_n_modes, n_modes[c]);
703
704 /* Allocate max_n_modes + 1 entries to leaveroom for the extra null
705 pointer assigned after the qsort callbelow. */
706 sortbuf = alloca ((max_n_modes + 1) * sizeof(struct mode_data *));
707
708 for (c = 0; c < MAX_MODE_CLASS; c++)
709 {
710 /* "wider" is not meaningful forMODE_RANDOM and MODE_CC.
711 However, we want these in textual order,and we have
712 precisely the reverse. */
713 if (c == MODE_RANDOM || c == MODE_CC)
714 {
715 struct mode_data*prev, *next;
716
717 for (prev = 0, m = modes[c]; m; m = next)
718 {
719 m->wider = void_mode;
720
721 /* this is nreverse */
722 next = m->next;
723 m->next = prev;
724 prev = m;
725 }
726 modes[c]= prev;
727 }
728 else
729 {
730 if (!modes[c])
731 continue;
732
733 for (i = 0, m = modes[c]; m; i++, m = m->next)
734 sortbuf[i] = m;
735
736 qsort (sortbuf, i, sizeof (struct mode_data *), cmp_modes);
737
738 sortbuf[i] = 0;
739 for(j = 0; j < i; j++)
740 sortbuf[j]->next =sortbuf[j]->wider = sortbuf[j + 1];
741
742
743 modes[c] = sortbuf[0];
744 }
745 }
746 }
Now in main, we can output the header file(insn-modes.h) if –h option used in invoking genmodes.
766 static void
767 emit_insn_modes_h (void) ingenmodes.c
768 {
769 enum mode_class c;
770 struct mode_data*m, *first, *last;
771
772 printf ("/* Generated automatically from machmode.def%s%s\n",
773 HAVE_EXTRA_MODES ? " and " : "",
774 EXTRA_MODES_FILE);
775
776 puts ("\
777 by genmodes. */\n\
778 \n\
779 #ifndef GCC_INSN_MODES_H\n\
780 #define GCC_INSN_MODES_H\n\
781 \n\
782 enum machine_mode\n{");
783
784 for (c = 0; c < MAX_MODE_CLASS; c++)
785 for (m = modes[c]; m; m = m->next)
786 {
787 int count_;
788 printf (" %smode,%n",m->name, &count_);
789 printf ("%*s/* %s:%d */\n", 27 - count_, "",
790 trim_filename (m->file),m->line);
791 }
792
793 puts (" MAX_MACHINE_MODE,\n");
794
795 for (c = 0; c < MAX_MODE_CLASS; c++)
796 {
797 first = modes[c];
798 last = 0;
799 for (m = first; m; last = m, m =m->next)
800 ;
801
802 /* Don't use BImode for MIN_MODE_INT, sinceotherwise the middle
803 end will try to use it for bitfields instructures and the
804 like, which we do not want. Only thetarget md file should
805 generate BImode widgets. */
806 if (first && first->precision == 1)
807 first = first->next;
808
809 if (first && last)
810 printf (" MIN_%s =%smode,\n MAX_%s = %smode,\n\n",
811 mode_class_names[c], first->name,
812 mode_class_names[c], last->name);
813 else
814 printf (" MIN_%s =%smode,\n MAX_%s = %smode,\n\n",
815 mode_class_names[c], void_mode->name,
816 mode_class_names[c], void_mode->name);
817 }
818
819 puts ("\
820 NUM_MACHINE_MODES =MAX_MACHINE_MODE\n\
821 };\n");
822
823 /* I can't think of a better idea, canyou? */
824 printf ("#define CONST_MODE_SIZE%s\n", adj_bytesize ? "" :" const");
825 printf ("#define CONST_MODE_BASE_ALIGN%s\n", adj_alignment? "" : " const");
826 #if 0 /* disabled for backward compatibility,temporary */
827 printf ("#defineCONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :"const");
828 #endif
829 puts ("\
830 \n\
831 #endif /* insn-modes.h */");
832 }
This header file defines the enumerate machine_mode, and the output fromline 784 to 791 is like following.
VOIDmode, /* machmode.def:146 */
BLKmode, /* machmode.def:150 */
CCmode, /* machmode.def:178 */
And the output from line 795 to 817 is like (we dump all relatedoutput, as it is useful when reading code of other parts).
MIN_MODE_RANDOM = VOIDmode,
MAX_MODE_RANDOM = BLKmode,
MIN_MODE_CC = CCmode,
MAX_MODE_CC = CCFPUmode,
MIN_MODE_INT = QImode,
MAX_MODE_INT = TImode,
MIN_MODE_PARTIAL_INT = VOIDmode,
MAX_MODE_PARTIAL_INT = VOIDmode,
MIN_MODE_FLOAT = SFmode,
MAX_MODE_FLOAT = TFmode,
MIN_MODE_COMPLEX_INT = CQImode,
MAX_MODE_COMPLEX_INT = CTImode,
MIN_MODE_COMPLEX_FLOAT = SCmode,
MAX_MODE_COMPLEX_FLOAT = TCmode,
MIN_MODE_VECTOR_INT = V2QImode,
MAX_MODE_VECTOR_INT = V8DImode,
MIN_MODE_VECTOR_FLOAT = V2SFmode,
MAX_MODE_VECTOR_FLOAT= V8DFmode,
For using option –h, we need to output insn-modes.c following abovestep.
1153 static void
1154 emit_insn_modes_c (void) ingenmodes.c
1155 {
1156 emit_insn_modes_c_header ();
1157 emit_mode_name ();
1158 emit_mode_class ();
1159 emit_mode_precision ();
1160 emit_mode_size ();
1161 emit_mode_nunits ();
1162 emit_mode_wider ();
1163 emit_mode_mask ();
1164 emit_mode_inner ();
1165 emit_mode_base_align ();
1166 emit_class_narrowest_mode ();
1167 emit_real_format_for_mode ();
1168 emit_mode_adjustments ();
1169 }
The output functions are simple and straightforward. They willoutput corresponding data from the modes.