> From: DJ Delorie <[EMAIL PROTECTED]>
>> - ok, and how does it know that it needs a 32-bit unsigned scalar?
> 
> tm.h: #define INT_TYPE_SIZE 32
> 
> Combined with "unsigned int foo;" in the user's source file.
> 
> The MI doesn't need to know that this fits in a QImode.

- agreed, all it needs to know is that a int_mode operand/operator is
  required, which is defined to correspond to some physical mode given
  some name by the target.

>>   the world is it desirable to go go in a big circle to identify
>>   which mode corresponds to a type as defined by the target, rather
>>   than simply having the target define it directly?)
> 
> Because on many targets, small scalars can be held in larger
> registers, and large scalars (or complex or vector types) can be held
> in groups of small registers.  There isn't a strict mapping between C
> types and hardware modes.  Plus, the target might provide attributes
> that alter the mode (think "__attribute__((mode(FRED)))").

- Huh?, can you provide a single example of where a char type would
  be mapped by the target to two different target specified modes?

  (as it seems that although multiple char's may be specified as being
  mapped to into an indexed subreg of a wider target specified mode, the
  middle end is responsible for identifying how and how many and smaller
  datum, may be packed into a vector, as defined by the target's
  specification of it's vector_mode, if supported at all, not the target.)

>>   correspondingly "well known named" types (such as bool, char, int,
> 
> In this case, the "well known named" things are front-end types, like
> "int" and "short", not back-end types, like PSImode or V4QImode.

- fully agree, which is why the MI need/should never need to identify
  the target physical mode (given some name by the target), which
  corresponds to the canonical type mode name like int_mode as used by
  the MI until target rtl templates need to be matched.

> A simple example of this type of problem is when MI uses "SImode" for
> integers, on a target with 16-bit integers.  SImode is wrong.  Any
> time you have "well known" types coming from the *target* you're
> setting yourself up for this type of thing.

- fully agree, no physical mode name (such as SImode) as may be defined
  by the target should ever be referred to by the MI portion of the
  compiler until target specific templates which use the target defined
  physical mode names need to be matched.

>>> BImode in most cases, not really useful that way.
>> 
>> - maybe we are using different terminology, as there would seem to
>> be no reason that a target couldn't define that a bool was a 16-bit
>> wide datum
> 
> I didn't say anything about bools.  See?  You're making the same wrong
> assumptions GCC makes.  "bool" should be a well-known name.  BImode
> shouldn't.  My chip has an addressing mode that addresses individual
> bits, has nothing to do with the "bool" type.

- sorry, I was just attempting to respond given my best guess as to your
  intent when you introduced BI mode into the discussion by with the above
  to:

>>>>   target_unit_mode // presumably the target's smallest addressable datum.

  (presuming that you meant that BI mode as presumed to the narrowest width
   physical mode, which I mistakenly presumed you associated with bool, but
   agree that the MI portion of the compiler should never presume anything
   about any particular target named machine physical mode.)

>>   (in essence, there needs to be a mechanism by which a target may
>>   define the it's address resolution, and alignment requirements,
>>   independently
> 
> The chip I'm working on has three addressing modes, with two different
> resolutions and alignments.  Your assumption - that there is one
> address resolution - already breaks my chip.

- fully agree, the MI portion of the compiler should make no assumptions
  about the equality of pointer modes as may be necessary to be distinct
  for a particular target, but do presume that all stack pointer, function
  pointer, label pointer, readonly_data pointer, heap pointer, etc.
  references utilize a common target defined mode, which may all be mapped
  to the same target physical pointer mode, or different physical pointer
  modes (i.e. function pointers may be defined to map to WILMA mode, where
  label pointers may be defined to map to BARNEY mode physical target
  pointer modes).
  
>>>>   target_word_mode // presumably the target's largest addressable datum.
>>> 
>>> BLKmode in all cases.  Also not useful.
>> 
>> - I hope not, as block mode operands seem to be used for moving data
>> with finer granularity than the target's word-width when
>> initializing char
> 
> You said largest addressable, not largest alignment.  More
> assumptions.  On some chips, for example, "words" may be unaligned,
> but "floats" must be aligned.  Your "well known name" is already
> wrong.

- fully agreed, my mistake in making the same incorrect assumption which
  GCC seems to do on occasion, as alignment should likely be an attribute
  of every target defined logical type -> physical mode mapping definition.

>> - no?, I presume that "target_word_mode" would merely describe
>> (mentioned above), an aspect of the physical target's natural memory
>> access granularity,
> 
> You're assuming the target has ONE "natural" access granularity.  Just
> the dichotomy between scalars and reals breaks that.
> 
> My chip has four "natural" accessing granularities.  Which would I
> choose?  (yes, I was stumped for UNITS_PER_WORD because it was used
> for many things, and I needed different things it was used for to work
> with different sized data).
> 
> Heck, the i386 has five natural modes (QI, HI, SI/SF, DI/DF TF).  Pick
> one.

- fully agreed, as above.

>> - understood, although it would seem much easier if the MI portion simply
>>   identified the type of pointer it required based upon the context of the
>>   access which it inherently knows (which the target may map to whatever
> 
> "inherently" is misleading.  The MI has two feasible options - assume
> all pointers are the same, or let the target decide.  There is no
> usable middle ground.

- given that the target may only "decide" based on the uniqueness of the
  contextual of the pointer's use visible to it, it depends on the MI
  differentiating such uses. Which seems simpler for the MI to do explicitly
  by named canonical pointer modes (such as function_pointer, label_pointer,
  rodata_pointer, etc.) rather than leaving it up to chance that they may
  be discrimated as may be required by the target; which the target may
  define to map to the same or different physical modes as required by the
  target, it would seem?

>>   mode it desires), rather than the target having to try to figure
>>   out based upon the more limited tree/rtx context visible to it?)
> 
> The tree/decl/rtx is all the MI has too.

- but only needs to associate a logical type mode with a target defined
  physical mode when attempting to match the the target's instruction
  rtl definitions defined in terms of physical modes SI, DI, WILMA, etc.),
  it would seem?

>> - understood, although hardly believe that it's a problem to require that
>>   a target define the logical->physical mapping required for for the 20
>>   or so logically distinct type variations that the MI portion is and
>>   should be aware of (rather than subject the mapping to any mishandling)
> 
> Ok, next time a new language front and is added with new data types,
> you get to update all the target backends.

- yes, as would always need to be done if the language's new data-type
  precision or representation is target dependant, as most language
  data-types are?

>> - I do believe were just using somewhat different terminology, as the MI
>>   portion of the compiler does and must deal with "well known named" typed
>>   operations and operands.
> 
> Does?  Yes.  Must?  No, outside of the *language* types (not the
> *target* types).

- fully agree, which is why the MI need only deal with *language* type/modes
  and rely on the target to define their mapping to *target* types/modes.

>> - sorry, I don't see; as the program code, and internal tree representation
>>   of that code (as you've noted below), identifies all nodes as having one
>>   of N  canonical types (bool, char, short, int, *, [], etc.) not an
>>   arbitrary type,
> 
> *Except* when you consider __attribute__ which can modify *anything*
> in gcc.  This is how we get vector variables, interrupt functions,
> etc.

- unless I misunderstand, I suspect you're mixing a few orthogonal issues:

  - the last first, a vector is just another canonical type, no different
    than bool, char, etc. and needs it's target specific attributes
    described by the target, and correspondingly mapped to some target
    defined named physical mode which the target's rtl is described using.

  - interrupt, no-return, etc. attributes aren't types per-se, but rather
    semantic modifiers which GCC has provided as a convenience to both
    programmers, and the middle-end architecture to enable the incremental
    specification of semantics in a canonical way by language front-ends,
    to enable the development of a language neutral middle end?

  - the use of GCC's __attribute__ extension directly in user code, seems
    to simply extend this capability to the programmer. And seemingly may
    be used to introduce "new" types, but only if that "new" type is defined
    as being physically equivalent to an existing supported type/mode known
    already to both the MI and the target portions of the compiler, as
    otherwise neither the MI or target portions of the compiler understands
    it relationship/conversion to/from other types, or it's corresponding
    target specific physical mode to use to represent the type, or
    operations it would seem?

>> - why bother if:  TYPE_MODE :: *target_type_mode, i.e:
>> 
>>   typedef struct {
>>     char* name;
>>     char* mode:
>>     char  size:
>>     enum  attribute {is_signed, is_unsigned, is_floating, is_void};
>>   } target_type_mode;
>>
>>   enum type_mode {
>>     bool_mode = &(target_type_mode){"bool", "QI", 10, is_unsinged},
>>     char_mode = &(target_type_mode){"char", "QI", 10, is_unsigned},
>>     uint_mode = &(target_type_mode){"uint", "HI", 17, is_unsigned},
>>     ...}
>
> No, you're missing a lot of variability here.

- like? (observing that it may be easily augmented as desired/required)

>>   if (TYPE_MODE(...) == char_mode) ...
> 
> I'd rather see
> 
>     if (TYPE_MODE(...) == TYPE_MODE(...))
> 
> or
>     if (BITS_PER_MODE (TYPE_MODE (...)) <= BITS_PER_BYTE)

- out of curiosity, why?

(but suspect you simply like flexibility of another level of abstraction)


Reply via email to