The target macros described in the "Addressing Modes" section of the internals manual are rather badly in need of cleaning up. I see three primary reasons why this is so:
1) These are the macros subject to REG_OK_STRICT. For those of you who have managed so far to avoid finding out about this particular detail: It is defined by reload.c (and only by reload.c) prior to including all headers. This is required to cause tm.h to define GO_IF_LEGITIMATE_ADDRESS, REG_OK_FOR_BASE_P, and REG_OK_FOR_INDEX_P according to a different specification (this may or may not require actual code changes to all of these, depending on the architecture). There's nothing stopping a tm.h file from mutating other macros in response to it. I inventoried all of the occurrences of REG_OK_STRICT in existing target files and found direct effects on definitions of EXTRA_CONSTRAINT, LEGITIMATE_PIC_OPERAND_P, and a gaggle of macros which I *think* are not part of the formal tm.h interface (that is, they are defined for internal use by other macros or for use in CPU.c). Also, any macro which uses any of the above macros is perforce affected. 2) Several of these macros are specified to alter control flow. They take a label as an argument, and should "goto" it under specified conditions. These are: GO_IF_LEGITIMATE_ADDRESS, GO_IF_MODE_DEPENDENT_ADDRESS, LEGITIMIZE_ADDRESS, and LEGITIMIZE_RELOAD_ADDRESS. Because of this, they are used in an obscure fashion (especially the latter two) and are difficult to define as function calls. Which brings us to ... 3) The definitions of these macros are necessarily complicated on a lot of architectures, so that it is desirable to take them out-of-line into the CPU.c file, but this is difficult because of points 1 and 2. I have worked out a tentative plan for replacing most of these macros with ordinary target hooks, and eliminating REG_OK_STRICT. I propose to change GO_IF_LEGITIMATE_ADDRESS, GO_IF_MODE_DEPENDENT_ADDRESS, LEGITIMIZE_ADDRESS, LEGITIMIZE_RELOAD_ADDRESS, REG_OK_FOR_BASE_P, REG_MODE_OK_FOR_BASE_P, REG_MODE_OK_FOR_REG_BASE_P, REG_OK_FOR_INDEX_P, CONSTANT_ADDRESS_P, FIND_BASE_TERM, and LEGITIMATE_CONSTANT_P. The other macros in this section are all numeric constants and in at least one case are used to size static arrays, so conversion to hooks doesn't make sense (yet). The majority of the work will be dealing with the first four, and to a lesser extent the first eight. It's a lot of work, and I would like to get both initial buy-in from people familiar with the details of these macros (never having written a port, I am not the best-qualified to assess what is and is not safe) and pledges of assistance from port maintainers in cleaning up their own code. In order to do this in a sensible manner, we need to decouple problems 1 and 2 above, and we need to deal with problem 1 from the caller's side, by making it explicit which behavior is expected at which call sites. Conveniently, the introduction of a target hook in DJ's style (that is, with a default that invokes the old macro) does exactly this. For macros that are expected to vary with REG_OK_STRICT, we replace with two hooks; for macros that should not vary, we replace with one. (Even if a macro has been defined to vary, we don't need two hooks unless it is used both inside and outside reload.c.) Also conveniently, there are only a small number of call sites for the really nasty macros. GO_IF_LEGITIMATE_ADDRESS is called from memory_address_p, strict_memory_address_p, and a handful of places in target-specific code (m68hc11.h, m68k.h, pdp11.c, sh.c). GO_IF_MODE_DEPENDENT_ADDRESS is used only in mode_dependent_address_p. LEGITIMIZE_ADDRESS is used only in memory_address, and LEGITIMIZE_RELOAD_ADDRESS only in find_reloads_address. Furthermore, memory_address_p, strict_memory_address_p, and mode_dependent_address_p are tiny wrappers which turn macros with inconvenient control flow properties into ordinary predicate functions. So, the plan: Step 1 introduces - one at a time - target hooks corresponding to each of the above macros. All callers are changed to use the hooks. The default definitions of the hooks invoke the existing macros. The hardest part of this is working out exactly what their sole callers expect of LEGITIMIZE_ADDRESS and LEGITIMIZE_RELOAD_ADDRESS. The manual, unfortunately, is not very clear. I think that in both cases it amounts to "either replace X with a new value and jump to WIN, or leave X unmodified and drop through", which can be translated to "return a new value for X, or NULL", but I'm not sure, particularly about LEGITIMIZE_RELOAD_ADDRESS and its interaction with push_reload. Step 2 is to convert each architecture, one at a time, to make target-hook definitions. I think it makes most sense to do each architecture in one go, because the definitions of these macros tend to be intertwined. In particular, REG_OK_FOR_BASE_P etc are often used in the definition of GO_IF_LEGITIMATE_ADDRESS. It will require some care to be sure that the hooks retain the same semantics wrt REG_OK_STRICT. Some of the macros have sensible defaults; for instance, it is allowed to define a LEGITIMIZE_ADDRESS that does nothing. In this stage we should identify what those defaults are, and add appropriate functions to hooks.c; but we cannot change the default settings in target-def.h until all architectures are converted. Step 3 cleans up after step 2: we remove the default definitions, poison the macros, change the settings in target-def.h, and remove any now-redundant hook settings in cpu.c files. This can safely be done all at once. Step 4 is to remove all remaining references to REG_OK_STRICT from target headers, one architecture at a time. In many cases there won't be any left. This is when we deal with variable definitions of EXTRA_CONSTRAINT, for instance (where I think the appropriate thing is to make a single definition containing a (reload_in_progress||reload_completed) conditional). Thoughts? zw