Next:Compact Syntax, Previous:Output Templates and Operand Substitution, Up:Machine Descriptions [Contents][Index]
Often a single fixed template string cannot produce correct and efficientassembler code for all the cases that are recognized by a singleinstruction pattern. For example, the opcodes may depend on the kinds ofoperands; or some unfortunate combinations of operands may require extramachine instructions.
If the output control string starts with a ‘@’, then it is actuallya series of templates, each on a separate line. (Blank lines andleading spaces and tabs are ignored.) The templates correspond to thepattern’s constraint alternatives (seeMultiple Alternative Constraints). For example,if a target machine has a two-address add instruction ‘addr’ to addinto a register and another ‘addm’ to add a register to memory, youmight write this pattern:
(define_insn "addsi3" [(set (match_operand:SI 0 "general_operand" "=r,m") (plus:SI (match_operand:SI 1 "general_operand" "0,0") (match_operand:SI 2 "general_operand" "g,r")))] "" "@ addr %2,%0 addm %2,%0")
If the output control string starts with a ‘*’, then it is not anoutput template but rather a piece of C program that should compute atemplate. It should execute areturn statement to return thetemplate-string you want. Most such templates use C string literals, whichrequire doublequote characters to delimit them. To include thesedoublequote characters in the string, prefix each one with ‘\’.
If the output control string is written as a brace block instead of adouble-quoted string, it is automatically assumed to be C code. In thatcase, it is not necessary to put in a leading asterisk, or to escape thedoublequotes surrounding C string literals.
The operands may be found in the arrayoperands, whose C data typeisrtx [].
It is very common to select different ways of generating assembler codebased on whether an immediate operand is within a certain range. Becareful when doing this, because the result ofINTVAL is aninteger on the host machine. If the host machine has more bits in anint than the target machine has in the mode in which the constantwill be used, then some of the bits you get fromINTVAL will besuperfluous. For proper results, you must carefully disregard thevalues of those bits.
It is possible to output an assembler instruction and then go on to outputor compute more of them, using the subroutineoutput_asm_insn. Thisreceives two arguments: a template-string and a vector of operands. Thevector may beoperands, or it may be another array ofrtxthat you declare locally and initialize yourself.
When an insn pattern has multiple alternatives in its constraints, oftenthe appearance of the assembler code is determined mostly by which alternativewas matched. When this is so, the C code can test the variablewhich_alternative, which is the ordinal number of the alternativethat was actually satisfied (0 for the first, 1 for the second alternative,etc.).
For example, suppose there are two opcodes for storing zero, ‘clrreg’for registers and ‘clrmem’ for memory locations. Here is howa pattern could usewhich_alternative to choose between them:
(define_insn "" [(set (match_operand:SI 0 "general_operand" "=r,m") (const_int 0))] "" { return (which_alternative == 0 ? "clrreg %0" : "clrmem %0"); })The example above, where the assembler code to generate wassolely determined by the alternative, could also have been specifiedas follows, having the output control string start with a ‘@’:
(define_insn "" [(set (match_operand:SI 0 "general_operand" "=r,m") (const_int 0))] "" "@ clrreg %0 clrmem %0")
If you just need a little bit of C code in one (or a few) alternatives,you can use ‘*’ inside of a ‘@’ multi-alternative template:
(define_insn "" [(set (match_operand:SI 0 "general_operand" "=r,<,m") (const_int 0))] "" "@ clrreg %0 * return stack_mem_p (operands[0]) ? \"push 0\" : \"clrmem %0\"; clrmem %0")
Next:Compact Syntax, Previous:Output Templates and Operand Substitution, Up:Machine Descriptions [Contents][Index]