E.2 Repeat Blocks

The gcc assembler provides two varieties of repeat blocks: those with an explicitly specified repetition count and those that are known as indefinite repeat blocks. These capabilities can assist with the formulation of repetitive code segments.

E.2.1 Simple Repeat Blocks

An astute reader may have speculated whether an assembler could provide any aids to automate the repeating pattern of instructions required by the algorithm for the SQUARES program presented in Chapter 1. If we wanted to extend the program toward some much larger total number of squares, would we really have to "copy and paste" with the text editor ad nauseam, or is there some alternative to that?

A repeat block indeed provides an alternative. A sequence of instructions, and other assembler directives if desired, can be repeated by surrounding them with .rept and .endr directives:

 .rept     HowManyTimes ... <sequence of instructions and directives> ... .endr 

The parameter denoted here as HowManyTimes may be a constant, a previously defined symbolic value, or an expression that the assembler can evaluate explicitly. If the value is less than or equal to zero, the repeat range is not assembled at all. If the value is greater than zero, the sequence is repeated the specified number of times.

In Figure 1-3, a sequence of four Itanium instructions is repeated for each of the N squares to be calculated:

 add    r21 = r22,r21;;         // Adjust first difference add    r20 = r21,r20;;         // Gr20 = nth square addl   r14 = @gprel(sqn),gp;;  // Point to storage st8    [r14] = r20;;           //         for sqn 

If we were to replicate the same symbolic location sqn for repeated store instructions, we would of course not produce a list of squares stored in successive quad words, because each computed value would overwrite the previous value.

The simple .rept directive lacks any capability to vary the symbolic location sqn. A programmer or compiler writer typically provides only one symbolic name for an entire vector, not a symbolic name for each element. With that clue, we might set up an appropriate storage pointer and write a repeat block like this:

 N = <whatever we want> addl    r14 = @gprel(sq),gp;;  // Point to storage .auto                          // Switch to automatic .rept   N add     r21 = r22,r21          // Adjust first difference add     r20 = r21,r20          // Gr20 = nth square st8     [r14] = r20,8          //         to be stored .endr .default                       // Revert to default 

where postincrementing on the store instruction advances the storage pointer without the need for an additional instruction.

Having accomplished this rather modest elaboration in the code section, which would require modifying labels in the data section, we should have little reluctance towards writing a loop-free program like SQUARES for a much larger N than the previous single-digit value.

Simple repeat blocks have the obvious limitation of allowing no variability in each execution. The other types of repeat blocks and macros are more versatile, though sometimes harder to devise and perfect. Simple repeat blocks can, however, contain most of the other constructs in this appendix and gain versatility that way.

E.2.2 Indefinite Repeat Blocks Using the .irp Directive

As we have just seen, simple repeat blocks merely produce some N identical replications of a sequence of code and/or directives. Greater power or usefulness would seem to require the capability to vary some crucial detail within that sequence. An indefinite repeat block fills this need, using the .irp directive in the following way:

 .irp      symbol, parameter value(s) ... <sequence containing 'symbol'> ... .endr 

where symbol is a formal parameter i.e., a pro forma symbolic place-holder. This formal parameter takes on each successive actual parameter value enumerated in the list i.e., a different value during each repetition through the sequence. These parameter values, which are separated by commas, comprise a set over which the formal parameter can vary. If the list is empty, one expansion may occur with the symbol set to a null string.

The symbol for an indefinite repeat block may appear any number of times or in any field of instructions or directives. Each occurrence of \symbol is subjected to the same text substitution. The process resembles the find and replace operation within a word processor.

The SQUARES program (Figure 1-3) can again serve to illustrate how .irp works. Suppose that we want to compute the first nine squares. A repeat block introduced by .irp could be devised as follows:

 .auto         .irp    N, 1,2,3,4,5,6,7,8,9         .data sq\N:   .skip   8                // Space for square \N         .text         add     r21 = r22,r21    // Adjust first difference         add     r20 = r21,r20    // Gr20 = square \N         addl    r14 = @gprel(sq\N),gp   // Point to storage         st8     [r14] = r20      //           for square \N         .endr         .default 

The expansion of this repeat block should produce data storage and code for the nine squares. Remember that an assembler maintains separate location counters for each segment of a program (Section 3.5.4). For each repetitive expansion, a new symbol will be constructed for use as a label in the data segment and as a reference in the text segment.

Such use of .irp can make the source file clearer because attention is drawn to a general pattern, not to a plethora of particular instances.

E.2.3 Indefinite Repeat Blocks Using the .irpc Directive

Another variety of indefinite repeat block uses the .irpc directive and, again, the .endr directive:

 .irpc     symbol, string ... <sequence containing 'symbol'> ... .endr 

For each repetition of the body of the repeat block, symbol takes on the value of the next character in the string. Hence the length of the string determines the number of repetitions. Yet if the string is null, one expansion may occur with the symbol set to a null string.

There is no fundamental difference between the .irp and .irpc directives, but the latter obviates the need for a lot of commas when only single characters are to be specified for substitution.

The symbol for this type of indefinite repeat block may appear any number of times or in any field of instructions or directives. Each occurrence of \symbol is subjected to the same text substitution. The process resembles the find and replace operation within a word processor.

The SQUARES program (Figure 1-3) can again serve to illustrate how .irpc works. Suppose that we want to compute the first nine squares. A repeat block introduced by .irpc could be devised as follows:

         .auto         .irpc   N, 123456789         .data sq\N:   .skip   8                // Space for square \N         .text         add     r21 = r22,r21    // Adjust first difference         add     r20 = r21,r20    // Gr20 = square \N         addl    r14 = @gprel(sq\N),gp  // Point to storage         st8     [r14] = r20      //           for square \N         .endr         .default 

The expansion of this repeat block should produce data storage and code for the nine squares. Remember that an assembler maintains separate location counters for each segment of a program (Section 3.5.4). For each repetitive expansion, a new symbol will be constructed for use as a label in the data segment and as a reference in the text segment.

Such use of .irpc can make the source file clearer because attention is drawn to a general pattern, not to a plethora of particular instances.

Both .irp and .irpc, like .repeat, can also contain macro definitions. Conversely, a macro definition can contain any combination of these types of repeat blocks.



ItaniumR Architecture for Programmers. Understanding 64-Bit Processors and EPIC Principles
ItaniumR Architecture for Programmers. Understanding 64-Bit Processors and EPIC Principles
ISBN: N/A
EAN: N/A
Year: 2003
Pages: 223

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net