This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
This is an RFC about using mode and code macros in *.md files.
I've attached a patch that implements the suggested constructs
and an example of how they might be used in mips.md.
Motivation
----------
There are at least three major sources of cut-&-paste in mips.md:
(1) It has two patterns for almost every pointer-related operation,
one for when Pmode == SImode and the other for when Pmode == DImode.
For example:
(define_insn "indirect_jump_internal1"
[(set (pc) (match_operand:SI 0 "register_operand" "d"))]
"!(Pmode == DImode)"
"%*j\t%0%/"
[(set_attr "type" "jump")
(set_attr "mode" "none")])
(define_insn "indirect_jump_internal2"
[(set (pc) (match_operand:DI 0 "register_operand" "d"))]
"Pmode == DImode"
"%*j\t%0%/"
[(set_attr "type" "jump")
(set_attr "mode" "none")])
It would be nice to be able to write:
(set (pc) (match_operand:P 0 "register_operand" "d"))
instead.
(2) For almost every 32-bit integer pattern with condition X, there is
an equivalent 64-bit pattern with condition X && TARGET_64BIT.
For example:
(define_insn "*norsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
(and:SI (not:SI (match_operand:SI 1 "register_operand" "d"))
(not:SI (match_operand:SI 2 "register_operand" "d"))))]
"!TARGET_MIPS16"
"nor\t%0,%z1,%z2"
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
(define_insn "*nordi3"
[(set (match_operand:DI 0 "register_operand" "=d")
(and:DI (not:DI (match_operand:DI 1 "register_operand" "d"))
(not:DI (match_operand:DI 2 "register_operand" "d"))))]
"TARGET_64BIT && !TARGET_MIPS16"
"nor\t%0,%z1,%z2"
[(set_attr "type" "arith")
(set_attr "mode" "DI")])
Sometimes, as here, the two patterns use the same machine instruction.
Sometimes they use different instructions, although the 64-bit
mnemonic is often just "d" + the equivalent 32-bit mnemonic.
Note that, unlike in the Pmode case, these patterns are not
mutually-exclusive. 64-bit code can use them both.
(3) For every SFmode instruction, there is an equivalent DFmode
instruction that has exactly the same predicates and constraints,
but which (a) uses '.d' instead of '.s' as the format suffix and
(b) requires TARGET_DOUBLE_FLOAT. For example:
(define_insn "absdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(abs:DF (match_operand:DF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
"abs.d\t%0,%1"
[(set_attr "type" "fabs")
(set_attr "mode" "DF")])
(define_insn "abssf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(abs:SF (match_operand:SF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
"abs.s\t%0,%1"
[(set_attr "type" "fabs")
(set_attr "mode" "SF")])
Mode macros
-----------
In the hope of reducing this sort of duplication, I'd like to make
read-rtl.c support a kind of mode macro. The tentative syntax for
defining a macro is:
(define_mode_macro MACRO [(MODE1 "COND1") ... (MODEN "CONDN")])
This says that every pattern using ':MACRO' as a mode suffix will
be expanded N times, once with every ':MACRO' replaced by ':MODE1',
once with every ':MACRO' replaced by ':MODE2', and so on. The version
that uses ':MODEX' will have 'CONDX' added to every C condition in
the pattern.
If a pattern uses several different macros, it will be expanded once
for every possible combination (the macros being applied in declaration
order).
For example, the definition of ':P' for MIPS looks like:
(define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
We can also add macros for the other variations mentioned above:
(define_mode_macro GPR [SI (DI "TARGET_64BIT")])
(define_mode_macro FPR [SF (DF "TARGET_DOUBLE_FLOAT")])
where, as a minor prettification, '(MODE "true")' is written 'MODE'.
Mode attributes
---------------
The string parts of md patterns often have a mode-dependent component.
In order to make full use of mode macros, we'd need some way of changing
the strings in each expansion.
The patch allows mode-dependent substrings to be defined in a
similar way to macros:
(define_mode_attr ATTR [(MODE1 "VALUE1") ... (MODEN "VALUEN")])
Then, when replacing every occurence of ':MACRO' by ':MODEX', read-rtl.c
also scans each string for suitably-decorated occurences of 'MACRO:ATTR'.
It replaces each such substring with 'VALUEX'.
At the moment, "suitably-decorated" means "in angled brackets",
but I'm not sure if that's the best choice. The 'MACRO:' prefix
can be dropped if there's no ambiguity.
If something in angled brackets doesn't match a known attribute name,
or if it names an attribute that defines no value for MODEX, that
part of the string will be kept as-is. The idea is:
(1) to avoid clobbering or rejecting any fancy asm syntax and
(2) to allow the 'MACRO:' prefix to be dropped more often, such as
when a pattern uses both floating-point and integer mode macros
but uses attributes that only make sense for one or the other.
Note that string substitution only occurs when a macro is being expanded,
so there should be no effect on ports that don't use macros.
The patch also adds two built-in attributes: 'mode', which is the name
of the mode in lower case, and 'MODE', which is the same in upper case.
Examples
--------
This statement defines the format suffix for a MIPS floating-point operation:
(define_mode_attr fmt [(SF "s") (DF "d")])
The floating-point abs patterns can then be combined as follows:
(define_insn "abs<mode>2"
[(set (match_operand:FPR 0 "register_operand" "=f")
(abs:FPR (match_operand:FPR 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
"abs.<fmt>\t%0,%1"
[(set_attr "type" "fabs")
(set_attr "mode" "<MODE>")])
(with :FPR defined as above). The combined nor pattern would look like:
(define_insn "*nor<mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d")
(and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
(not:GPR (match_operand:GPR 2 "register_operand" "d"))))]
"!TARGET_MIPS16"
"nor\t%0,%1,%2"
[(set_attr "type" "arith")
(set_attr "mode" "<MODE>")])
A mode attribute like:
(define_mode_attr load [(SI "lw") (DI "ld")])
means that a single pattern can be used for loading call addresses:
(define_insn "load_call<mode>"
[(set (match_operand:P 0 "register_operand" "=c")
(unspec:P [(match_operand:P 1 "register_operand" "r")
(match_operand:P 2 "immediate_operand" "")
(reg:P FAKE_CALL_REGNO)]
UNSPEC_LOAD_CALL))]
"TARGET_ABICALLS"
"<load>\t%0,%R2(%1)"
[(set_attr "type" "load")
(set_attr "length" "4")])
and for left loads:
(define_insn "mov_<load>l"
[(set (match_operand:GPR 0 "register_operand" "=d")
(unspec:GPR [(match_operand:BLK 1 "memory_operand" "m")
(match_operand:QI 2 "memory_operand" "m")]
UNSPEC_LOAD_LEFT))]
"!TARGET_MIPS16"
"<load>l\t%0,%2"
[(set_attr "type" "load")
(set_attr "mode" "<MODE>")
(set_attr "hazard" "none")])
(to pick two arbitrary examples).
Code macros and attributes
--------------------------
Although most duplication in mips.md comes from using different modes,
there are some examples of code-based duplication. The worst offender
is probably:
(define_expand "bunordered"
[(set (pc)
(if_then_else (unordered:CC (cc0)
(const_int 0))
(label_ref (match_operand 0 ""))
(pc)))]
""
{
gen_conditional_branch (operands, UNORDERED);
DONE;
})
followed by similar define_expands for every other comparison code.
We also have:
(define_insn "sunordered_df"
[(set (match_operand:CC 0 "register_operand" "=z")
(unordered:CC (match_operand:DF 1 "register_operand" "f")
(match_operand:DF 2 "register_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
"c.un.d\t%Z0%1,%2"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")])
followed by a similar pattern for every other native floating-point
comparison code.
The patch therefore adds macro and attribute support for codes as
well as modes. It uses the syntax:
(define_code_macro MACRO [(CODE1 "COND1") ... (CODEN "CONDN")])
(define_code_attr ATTR [(CODE1 "VALUE1") ... (CODEN "VALUEN")])
and defines special "code" and "CODE" attributes that are analagous
to the mode ones. In the case of code macros, every CODEX must have
the same format.
For example, code macros allow us to combine 7 of the c.cond.fmt patterns:
(define_code_macro floatcond [unordered unlt uneq unle eq le lt])
(define_code_attr floatcond [(unordered "un")
(unlt "ult")
(uneq "ueq")
(unle "ule")
(eq "eq")
(le "le")
(lt "lt")])
(define_insn "s<code>_<mode>"
[(set (match_operand:CC 0 "register_operand" "=z")
(floatcond:CC (match_operand:FPR 1 "register_operand" "f")
(match_operand:FPR 2 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
"c.<floatcond>.<fmt>\t%Z0%1,%2"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")])
The patch
---------
The patch is only an RFC at this stage. The mips.md part in particular
is only proof of concept since:
(1) It's unlikely that I'd apply such a big change in one go.
(Far too easy to make mistakes.)
(2) There are other bits that could also be cleaned up as well.
I decided to stop when I'd whittled it down to <6000 lines.
The current diffstat for mips.md is:
mips.md | 2937 ++++++++++++--------------------------------------------
1 files changed, 676 insertions(+), 2261 deletions(-)
but like I say, I'm hoping there's more to come.
The patch to read-rtl.c relies on two feeder changes:
(1) Promote the string obstack to file scope and give it a more
appropriate name.
(2) Simplify the format walk.
I've attached these two patches separately so that the main one is
easier to read. I've also tried to provide some suitable md.texi docs.
FWIW, a slightly earlier version of the patch has been bootstrapped
& regression tested on mips-sgi-irix6.5. It's just been code clean-up
since then.
So, what do folks think? Would a feature like this be acceptable?
If so, are there any suggestions on how it could be improved?
Any concerns or ideas about the syntax?
Richard
Attachment:
macro-prep-1.diff
Description: Text document
Attachment:
macro-prep-2.diff
Description: Text document
Attachment:
macro-main.diff
Description: Text document
Attachment:
macro-mips.diff.bz2
Description: Binary data
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |