Initial revision
This commit is contained in:
		
							parent
							
								
									96d9890d86
								
							
						
					
					
						commit
						df86573d4c
					
				
					 3 changed files with 877 additions and 0 deletions
				
			
		
							
								
								
									
										6
									
								
								doc/top/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								doc/top/Makefile
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					top.f:
 | 
				
			||||||
 | 
						refer -sA+T -l4,2 -p refs.top top.n | nroff -ms > top.f
 | 
				
			||||||
 | 
					top.f.35:
 | 
				
			||||||
 | 
						refer -sA+T -l4,2 -p refs.top top.n | nroff -ms -Thr35 > top.f.35
 | 
				
			||||||
 | 
					top.f.agfa:
 | 
				
			||||||
 | 
						refer -sA+T -l4,2 -p refs.top top.n | nroff -ms -Tlp > top.f.agfa
 | 
				
			||||||
							
								
								
									
										79
									
								
								doc/top/refs.top
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								doc/top/refs.top
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,79 @@
 | 
				
			||||||
 | 
					%T A Practical Toolkit for Making Portable Compilers
 | 
				
			||||||
 | 
					%A A.S. Tanenbaum
 | 
				
			||||||
 | 
					%A J.M. van Staveren
 | 
				
			||||||
 | 
					%A E.G. Keizer
 | 
				
			||||||
 | 
					%A J.W. Stevenson
 | 
				
			||||||
 | 
					%I Vrije Universiteit, Amsterdam
 | 
				
			||||||
 | 
					%R Rapport nr IR-74
 | 
				
			||||||
 | 
					%D October 1981
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%T A Practical Toolkit for Making Portable Compilers
 | 
				
			||||||
 | 
					%A A.S. Tanenbaum
 | 
				
			||||||
 | 
					%A J.M. van Staveren
 | 
				
			||||||
 | 
					%A E.G. Keizer
 | 
				
			||||||
 | 
					%A J.W. Stevenson
 | 
				
			||||||
 | 
					%J CACM
 | 
				
			||||||
 | 
					%V 26
 | 
				
			||||||
 | 
					%N 9
 | 
				
			||||||
 | 
					%P 654-660
 | 
				
			||||||
 | 
					%D September 1983
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%T A Unix Toolkit for Making Portable Compilers
 | 
				
			||||||
 | 
					%A A.S. Tanenbaum
 | 
				
			||||||
 | 
					%A J.M. van Staveren
 | 
				
			||||||
 | 
					%A E.G. Keizer
 | 
				
			||||||
 | 
					%A J.W. Stevenson
 | 
				
			||||||
 | 
					%J Proceedings USENIX conf.
 | 
				
			||||||
 | 
					%C Toronto, Canada
 | 
				
			||||||
 | 
					%V 26
 | 
				
			||||||
 | 
					%D July 1983
 | 
				
			||||||
 | 
					%P 255-261
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%T Using Peephole Optimization on Intermediate Code
 | 
				
			||||||
 | 
					%A A.S. Tanenbaum
 | 
				
			||||||
 | 
					%A J.M. van Staveren
 | 
				
			||||||
 | 
					%A J.W. Stevenson
 | 
				
			||||||
 | 
					%J TOPLAS
 | 
				
			||||||
 | 
					%V 4
 | 
				
			||||||
 | 
					%N 1
 | 
				
			||||||
 | 
					%P 21-36
 | 
				
			||||||
 | 
					%D January 1982
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%T Amsterdam Compiler Kit documentation
 | 
				
			||||||
 | 
					%A A.S. Tanenbaum
 | 
				
			||||||
 | 
					%A E.G. Keizer
 | 
				
			||||||
 | 
					%A J.M. van Staveren
 | 
				
			||||||
 | 
					%A J.W. Stevenson
 | 
				
			||||||
 | 
					%I Vrije Universiteit, Amsterdam
 | 
				
			||||||
 | 
					%R Rapport nr IR-90
 | 
				
			||||||
 | 
					%D June 1984
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%T Language- and Machine-independant Global Optimization on
 | 
				
			||||||
 | 
					Intermediate Code
 | 
				
			||||||
 | 
					%A H.E. Bal
 | 
				
			||||||
 | 
					%A A.S. Tanenbaum
 | 
				
			||||||
 | 
					%I Vrije Universiteit, Amsterdam
 | 
				
			||||||
 | 
					%R Rapport IR-98
 | 
				
			||||||
 | 
					%D March 1985
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%T The Design and Implementation of the EM Global Optimizer
 | 
				
			||||||
 | 
					%A H.E. Bal
 | 
				
			||||||
 | 
					%I Vrije Universiteit, Amsterdam
 | 
				
			||||||
 | 
					%R Rapport IR-99
 | 
				
			||||||
 | 
					%D March 1985
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%T The C Programming Language
 | 
				
			||||||
 | 
					%A B.W. Kernighan
 | 
				
			||||||
 | 
					%A D.M. Ritchie
 | 
				
			||||||
 | 
					%I Prentice-Hall, Inc
 | 
				
			||||||
 | 
					%C Englewood Cliffs,NJ
 | 
				
			||||||
 | 
					%D 1978
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%T Principles of compiler design
 | 
				
			||||||
 | 
					%A A.V. Aho
 | 
				
			||||||
 | 
					%A J.D. Ullman
 | 
				
			||||||
 | 
					%I Addison-Wesley
 | 
				
			||||||
 | 
					%C Reading, Massachusetts
 | 
				
			||||||
 | 
					%D 1978
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										792
									
								
								doc/top/top.n
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										792
									
								
								doc/top/top.n
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,792 @@
 | 
				
			||||||
 | 
					.ND
 | 
				
			||||||
 | 
					.pl 11.7i
 | 
				
			||||||
 | 
					.ll 80m
 | 
				
			||||||
 | 
					.nr LL 80m
 | 
				
			||||||
 | 
					.nr tl 78m
 | 
				
			||||||
 | 
					.tr ~
 | 
				
			||||||
 | 
					.ds >. .
 | 
				
			||||||
 | 
					.TL
 | 
				
			||||||
 | 
					The ACK Target Optimizer
 | 
				
			||||||
 | 
					.AU
 | 
				
			||||||
 | 
					H.E. Bal
 | 
				
			||||||
 | 
					.AI
 | 
				
			||||||
 | 
					Vrije Universiteit
 | 
				
			||||||
 | 
					Wiskundig Seminarium, Amsterdam
 | 
				
			||||||
 | 
					.AB
 | 
				
			||||||
 | 
					The Target Optimizer is one of several optimizers that are part of
 | 
				
			||||||
 | 
					the Amsterdam Compiler Kit.
 | 
				
			||||||
 | 
					It operates directly on assembly code,
 | 
				
			||||||
 | 
					rather than on a higher level intermediate code,
 | 
				
			||||||
 | 
					as the Peephole Optimizer and Global Optimizer do.
 | 
				
			||||||
 | 
					Consequently, the Target Optimizer can do optimizations
 | 
				
			||||||
 | 
					that are highly machine-dependent.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					Each target machine has its own Target Optimizer.
 | 
				
			||||||
 | 
					New optimizers are generated by the Target Optimizer Generator,
 | 
				
			||||||
 | 
					which uses a machine-dependent table as input.
 | 
				
			||||||
 | 
					This document contains full information on how to
 | 
				
			||||||
 | 
					write such a table for a new machine.
 | 
				
			||||||
 | 
					It also discusses the implementation of the
 | 
				
			||||||
 | 
					Target Optimizer and its generator.
 | 
				
			||||||
 | 
					.AE
 | 
				
			||||||
 | 
					.bp
 | 
				
			||||||
 | 
					.NH 1
 | 
				
			||||||
 | 
					Introduction
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					.FS
 | 
				
			||||||
 | 
					This work was supported by the
 | 
				
			||||||
 | 
					Stichting Technische Wetenschappen (STW)
 | 
				
			||||||
 | 
					under grant VWI03.0001.
 | 
				
			||||||
 | 
					.FE
 | 
				
			||||||
 | 
					This document describes the target optimizer component
 | 
				
			||||||
 | 
					of the Amsterdam Compiler Kit (ACK) .
 | 
				
			||||||
 | 
					.[
 | 
				
			||||||
 | 
					tanenbaum staveren amsterdam toolkit
 | 
				
			||||||
 | 
					.]
 | 
				
			||||||
 | 
					.[
 | 
				
			||||||
 | 
					tanenbaum staveren cacm
 | 
				
			||||||
 | 
					.]
 | 
				
			||||||
 | 
					.[
 | 
				
			||||||
 | 
					tanenbaum staveren toronto
 | 
				
			||||||
 | 
					.]
 | 
				
			||||||
 | 
					Optimization takes place in several parts of ACK compilers,
 | 
				
			||||||
 | 
					most notably in the Peephole Optimizer
 | 
				
			||||||
 | 
					.[
 | 
				
			||||||
 | 
					staveren peephole toplas
 | 
				
			||||||
 | 
					.]
 | 
				
			||||||
 | 
					and
 | 
				
			||||||
 | 
					the Global Optimizer,
 | 
				
			||||||
 | 
					.[
 | 
				
			||||||
 | 
					bal tanenbaum global optimization
 | 
				
			||||||
 | 
					.]
 | 
				
			||||||
 | 
					.[
 | 
				
			||||||
 | 
					bal implementation global optimizer
 | 
				
			||||||
 | 
					.]
 | 
				
			||||||
 | 
					which are both language- and machine-independent,
 | 
				
			||||||
 | 
					and in the machine-specific code generators.
 | 
				
			||||||
 | 
					.[
 | 
				
			||||||
 | 
					documentation amsterdam compiler kit
 | 
				
			||||||
 | 
					.]
 | 
				
			||||||
 | 
					The target optimizer is the finishing touch in this sequence of
 | 
				
			||||||
 | 
					optimizers.
 | 
				
			||||||
 | 
					It can be used to capture those optimizations that are hard
 | 
				
			||||||
 | 
					to express in the other parts of ACK.
 | 
				
			||||||
 | 
					These optimizations will typically be very machine-specific.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The target optimizer operates on the assembly code of some target machine.
 | 
				
			||||||
 | 
					Hence there is one target optimizer per machine.
 | 
				
			||||||
 | 
					However, just as for the ACK code generators and assemblers,
 | 
				
			||||||
 | 
					a framework has been build that allows easy generation of
 | 
				
			||||||
 | 
					target optimizers out of machine-independent parts and a
 | 
				
			||||||
 | 
					machine-dependent description table (see figure 1.).
 | 
				
			||||||
 | 
					So the major part of the code of a target optimizer is
 | 
				
			||||||
 | 
					shared among all target optimizers.
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                       |-------------------------|
 | 
				
			||||||
 | 
					                                       | machine-independent     |
 | 
				
			||||||
 | 
					                                       | code                    |
 | 
				
			||||||
 | 
					                                       |                         |
 | 
				
			||||||
 | 
					          |-----------------|          |-------------------------|
 | 
				
			||||||
 | 
					descrip-  |target optimizer |          | machine-dependent code  |
 | 
				
			||||||
 | 
					 tion --> |generator        | ---->    | + tables                |
 | 
				
			||||||
 | 
					table     |                 |          |                         |
 | 
				
			||||||
 | 
					          |-----------------|          |-------------------------|
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					                                              target optimizer
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					    Figure 1: Generation of a target optimizer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					This document focusses on the description of the machine-dependent table.
 | 
				
			||||||
 | 
					In chapter 2 we give an informal introduction to the optimization
 | 
				
			||||||
 | 
					algorithm and to the definition of the table format.
 | 
				
			||||||
 | 
					Chapters 3 and 4 discuss the implementation of the target optimizer
 | 
				
			||||||
 | 
					and the target optimizer generator.
 | 
				
			||||||
 | 
					Appendix A gives full information for writing a description table.
 | 
				
			||||||
 | 
					.bp
 | 
				
			||||||
 | 
					.NH 1
 | 
				
			||||||
 | 
					Global structure of the target optimizer
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The target optimizer is based on the well understood model
 | 
				
			||||||
 | 
					of a \fIpeephole optimizer\fR.
 | 
				
			||||||
 | 
					.[
 | 
				
			||||||
 | 
					aho ullman compiler
 | 
				
			||||||
 | 
					.]
 | 
				
			||||||
 | 
					It contains a machine-dependent table
 | 
				
			||||||
 | 
					of (pattern,replacement) pairs.
 | 
				
			||||||
 | 
					Each pattern describes
 | 
				
			||||||
 | 
					a sequence of one or more assembler instructions
 | 
				
			||||||
 | 
					that can be replaced by zero or more equivalent, yet cheaper,
 | 
				
			||||||
 | 
					instructions (the 'replacement').
 | 
				
			||||||
 | 
					The optimizer maintains a \fIwindow\fR that moves over the input.
 | 
				
			||||||
 | 
					At any moment, the window contains some contiguous part of the input.
 | 
				
			||||||
 | 
					If the instructions in the current window match some pattern
 | 
				
			||||||
 | 
					in the table,
 | 
				
			||||||
 | 
					they are replaced by the corresponding replacement;
 | 
				
			||||||
 | 
					else, the window moves one instruction to the right.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					In the remainder of this section we will give an informal
 | 
				
			||||||
 | 
					description of the machine-dependent table.
 | 
				
			||||||
 | 
					A more precise definition is given in appendix A.
 | 
				
			||||||
 | 
					We will first discuss the restrictions put on the
 | 
				
			||||||
 | 
					format of the assembly code.
 | 
				
			||||||
 | 
					.NH 2
 | 
				
			||||||
 | 
					Assumptions about the assembly code format
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					We assume that a line of assembly code begins with an
 | 
				
			||||||
 | 
					instruction \fImnemonic\fR (opcode),
 | 
				
			||||||
 | 
					followed by zero or more \fIoperands\fR.
 | 
				
			||||||
 | 
					The mnemonic and the first operand must be separated by a special
 | 
				
			||||||
 | 
					character (e.g. a space or a tab).
 | 
				
			||||||
 | 
					Likewise, the operands must be separated by a special
 | 
				
			||||||
 | 
					character (e.g. a comma).
 | 
				
			||||||
 | 
					These separators need not be the same for all machines.
 | 
				
			||||||
 | 
					.NH 2
 | 
				
			||||||
 | 
					Informal description of the machine-dependent tables
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The major part of the table consists of (pattern,replacement) pairs
 | 
				
			||||||
 | 
					called \fIentries\fR.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					A pattern is a list of instruction descriptions.
 | 
				
			||||||
 | 
					Each instruction description describes the instruction mnemonic and
 | 
				
			||||||
 | 
					the operands.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					A mnemonic is described either by a string constant or by the
 | 
				
			||||||
 | 
					keyword ANY.
 | 
				
			||||||
 | 
					As all entities dealt with by the target optimizer are strings,
 | 
				
			||||||
 | 
					string constants do not contain quotes.
 | 
				
			||||||
 | 
					A string constant matches only itself.
 | 
				
			||||||
 | 
					ANY matches every instruction mnemonic.
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples of mnemonic descriptions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        add
 | 
				
			||||||
 | 
					        sub.l
 | 
				
			||||||
 | 
					        mulw3
 | 
				
			||||||
 | 
					        ANY
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					An operand can also be described by a string constant.
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       (sp)+
 | 
				
			||||||
 | 
					       r5
 | 
				
			||||||
 | 
					       -4(r6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					Alternatively, it can be described by means of a \fIvariable name\fR.
 | 
				
			||||||
 | 
					Variables have values which are strings.
 | 
				
			||||||
 | 
					They have to be declared in the table before the patterns.
 | 
				
			||||||
 | 
					Each such declaration defines the name of a variable and
 | 
				
			||||||
 | 
					a \fIrestriction\fR to which its value is subjected.
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					Example of variable declarations:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      CONST       { VAL[0] == '$' };
 | 
				
			||||||
 | 
					      REG         { VAL[0] == 'r' && VAL[1] >= '0' && VAL[1] <= '3' &&
 | 
				
			||||||
 | 
					                    VAL[2] == '\\0' };
 | 
				
			||||||
 | 
					      X           { TRUE };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					The keyword VAL denotes the value of the variable, which is
 | 
				
			||||||
 | 
					a null-terminated string.
 | 
				
			||||||
 | 
					An operand description given via a variable name matches an
 | 
				
			||||||
 | 
					actual operand if the actual operand obeys the associated restriction.
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     CONST  matches   $1, $-5, $foo etc.
 | 
				
			||||||
 | 
					     REG    matches   r0, r1, r2 and r3
 | 
				
			||||||
 | 
					     X      matches   anything
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					The restriction (between curly braces) may be any legal "C"
 | 
				
			||||||
 | 
					.[
 | 
				
			||||||
 | 
					kernighan ritchie c programming
 | 
				
			||||||
 | 
					.]
 | 
				
			||||||
 | 
					expression.
 | 
				
			||||||
 | 
					It may also contain calls to user-defined procedures.
 | 
				
			||||||
 | 
					These procedures must be added to the table after the patterns.
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     FERMAT_NUMBER    { VAL[0] == '$' && is_fermat_number(&VAL[1]) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					An operand can also be described by a mixture of a string constant
 | 
				
			||||||
 | 
					and a variable name.
 | 
				
			||||||
 | 
					The most general form allowed is:
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       string_constant1 variable_name string_constant2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       (REG)+  matches  (r0)+, (r1)+, (r2)+ and (r3)+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					Any of the three components may be omitted,
 | 
				
			||||||
 | 
					so the first two forms are just special cases of the general form.
 | 
				
			||||||
 | 
					The name of a variable can not be used as a string constant.
 | 
				
			||||||
 | 
					In the above context, it is impossible to define an operand that
 | 
				
			||||||
 | 
					matches the string "REG".
 | 
				
			||||||
 | 
					This limitation is of little consequence,
 | 
				
			||||||
 | 
					as the table writer is free to choose the names of variables.
 | 
				
			||||||
 | 
					This approach, however, avoids the need for awkward escape sequences.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					A pattern consists of one or more instruction descriptions
 | 
				
			||||||
 | 
					(separated by a colon)
 | 
				
			||||||
 | 
					followed by an optional constraint.
 | 
				
			||||||
 | 
					A pattern "P1 : P2 : .. : Pn C" matches the sequence of
 | 
				
			||||||
 | 
					instructions "I1 I2 .. In" if:
 | 
				
			||||||
 | 
					.IP (i) 7
 | 
				
			||||||
 | 
					for each i, 1 <= i <= n, Pi matches Ii, as described above;
 | 
				
			||||||
 | 
					.IP (ii)
 | 
				
			||||||
 | 
					multiple occurrences of the same variable name or of
 | 
				
			||||||
 | 
					the keyword ANY stand for the same values throughout the pattern;
 | 
				
			||||||
 | 
					.IP (iii)
 | 
				
			||||||
 | 
					the optional constraint C is satisfied, i.e. it evaluates to TRUE.
 | 
				
			||||||
 | 
					.LP
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					The pattern:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      dec REG : move.b CONST,(REG)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					matches:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      dec r0 : move.b $4,(r0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					but not:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      dec r0 : move.b $4,(r1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(as the variable REG matches two different strings).
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					If a pattern containing different registers must be described,
 | 
				
			||||||
 | 
					extra names for a register should be declared, all sharing
 | 
				
			||||||
 | 
					the same restriction.
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     REG1,REG2  { VAL[0] == 'r' &&  .....  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     addl3 REG1,REG1,REG2 : subl2 REG2,REG1
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The optional constraint is an auxiliary "C" expression (just like
 | 
				
			||||||
 | 
					the parameter restrictions).
 | 
				
			||||||
 | 
					The expression may refer to the variables and to ANY.
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    move REG1,REG2    { REG1[1] == REG2[1] + 1 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					matches
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    move r1,r0
 | 
				
			||||||
 | 
					    move r2,r1
 | 
				
			||||||
 | 
					    move r3,r2
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The replacement part of a (pattern,replacement) table entry
 | 
				
			||||||
 | 
					has the same structure as a pattern, except that:
 | 
				
			||||||
 | 
					.IP (i)
 | 
				
			||||||
 | 
					it may not contain an additional constraint;
 | 
				
			||||||
 | 
					.IP (ii)
 | 
				
			||||||
 | 
					it may be empty.
 | 
				
			||||||
 | 
					.LP
 | 
				
			||||||
 | 
					A replacement may also refer to the values of variables and ANY.
 | 
				
			||||||
 | 
					.NH 2
 | 
				
			||||||
 | 
					Examples
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					This section contains some realistic examples for
 | 
				
			||||||
 | 
					optimization on PDP-11 and Vax assembly code.
 | 
				
			||||||
 | 
					.NH 3
 | 
				
			||||||
 | 
					Vax examples
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					Suppose the table contains the following declarations:
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					         X, LOG        { TRUE };
 | 
				
			||||||
 | 
					         LAB           { VAL[0] == 'L' };   /* e.g. L0017 */
 | 
				
			||||||
 | 
					         A             { no_side_effects(VAL) };
 | 
				
			||||||
 | 
					         NUM           { is_number(VAL) };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					The procedure "no_side_effects" checks if its argument
 | 
				
			||||||
 | 
					contains any side effects, i.e. auto increment or auto decrement.
 | 
				
			||||||
 | 
					The procedure "is_number" checks if its argument contains only digits.
 | 
				
			||||||
 | 
					These procedures must be supplied by the table-writer and must be
 | 
				
			||||||
 | 
					included in the table.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					\fIentry:\fR  addl3 X,A,A    -> addl2 X,A;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					This entry changes a 3-operand instruction into a cheaper  2-operand
 | 
				
			||||||
 | 
					instruction.
 | 
				
			||||||
 | 
					An optimization like:
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        addl3 r0,(r2)+,(r2)+   -> addl2 r0,(r2)+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					is illegal, as r2 should be incremented twice.
 | 
				
			||||||
 | 
					Hence the second argument is required to
 | 
				
			||||||
 | 
					be side-effect free.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					\fIentry:\fR  addw2 $-NUM,X  -> subw2 $NUM,X;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					An instruction like "subw2 $5,r0" is cheaper
 | 
				
			||||||
 | 
					than "addw2 $-5,r0",
 | 
				
			||||||
 | 
					because constants in the range 0 to 63 are represented
 | 
				
			||||||
 | 
					very efficiently on the Vax.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					\fIentry:\fR  bitw $NUM,A : jneq LAB
 | 
				
			||||||
 | 
					                { is_poweroftwo(NUM,LOG) }  -> jbs $LOG,A,LAB;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					A "bitw x,y" sets the condition codes to the bitwise "and" of
 | 
				
			||||||
 | 
					x and y.
 | 
				
			||||||
 | 
					A "jbs n,x,l" branches to l if bit n of x is set.
 | 
				
			||||||
 | 
					So, for example, the following transformation is possible:
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      bitw $32,r0 : jneq L0017 ->  jbs $5,r0,L0017
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					The user-defined  procedure "is_poweroftwo" checks if its first argument is
 | 
				
			||||||
 | 
					a power of 2 and, if so, sets its second argument to the logarithm
 | 
				
			||||||
 | 
					of the first argument. (Both arguments are strings).
 | 
				
			||||||
 | 
					Note that the variable LOG is not used in the pattern itself.
 | 
				
			||||||
 | 
					It is assigned a (string) value by "is_poweroftwo" and is used
 | 
				
			||||||
 | 
					in the replacement.
 | 
				
			||||||
 | 
					.NH 3
 | 
				
			||||||
 | 
					PDP-11 examples
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					Suppose we have the following declarations:
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					         X             { TRUE };
 | 
				
			||||||
 | 
					         A             { no_side_effects(VAL) };
 | 
				
			||||||
 | 
					         L1, L2        { VAL[0] == 'I' };
 | 
				
			||||||
 | 
					         REG           { VAL[0] == 'r' && VAL[1] >= '0' && VAL[1] <= '5' &&
 | 
				
			||||||
 | 
					                         VAL[2] == '\\0' };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					The implementation of "no_side_effects" may of course
 | 
				
			||||||
 | 
					differ for the PDP-11 and the Vax.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					\fIentry:\fR  mov REG,A : ANY A,X  ->  mov REG,A : ANY REG,X ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					This entry implements register subsumption.
 | 
				
			||||||
 | 
					If A and REG hold the same value (which is true after "mov REG,A")
 | 
				
			||||||
 | 
					and A is used as source (first) operand, it is cheaper to use REG instead.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					\fIentry:\fR  jeq L1 : jbr L2 : labdef L1  ->  jne L2 : labdef L1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					The "jeq L1" is a "skip over an unconditional jump". "labdef L1"
 | 
				
			||||||
 | 
					denotes the definition (i.e. defining occurrence) of label L1.
 | 
				
			||||||
 | 
					As the target optimizer has to know how such a definition
 | 
				
			||||||
 | 
					looks like, this must be expressed in the table (see Appendix A).
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					\fIentry:\fR  add $01,X { carry_dead(REST) }  -> inc X;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					On the PDP-11, an add-one is not equivalent to an increment.
 | 
				
			||||||
 | 
					The latter does not set the carry-bit of the condition codes,
 | 
				
			||||||
 | 
					while the former does.
 | 
				
			||||||
 | 
					So a look-ahead is needed to see if the rest of the input uses
 | 
				
			||||||
 | 
					the carry-bit before changing the condition codes.
 | 
				
			||||||
 | 
					A look-ahead of one instruction is provided by
 | 
				
			||||||
 | 
					the target optimizer.
 | 
				
			||||||
 | 
					This will normally be sufficient for compiler-generated code.
 | 
				
			||||||
 | 
					The keyword REST contains the mnemonic of the first instruction of
 | 
				
			||||||
 | 
					the rest of the input.
 | 
				
			||||||
 | 
					If this instruction uses the carry-bit (e.g. an adc, subc, bhis)
 | 
				
			||||||
 | 
					the transformation is not allowed.
 | 
				
			||||||
 | 
					.bp
 | 
				
			||||||
 | 
					.NH 1
 | 
				
			||||||
 | 
					Implementation of the target optimizer
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The target optimizer reads one input file of assembler instructions,
 | 
				
			||||||
 | 
					processes it, and writes the optimized code
 | 
				
			||||||
 | 
					to the output file.
 | 
				
			||||||
 | 
					So it performs one pass over the input.
 | 
				
			||||||
 | 
					.NH 2
 | 
				
			||||||
 | 
					The window mechanism
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The optimizer uses a \fIwindow\fR that moves over the input.
 | 
				
			||||||
 | 
					It repeatedly tries to match the instructions in the window
 | 
				
			||||||
 | 
					with the patterns in the table.
 | 
				
			||||||
 | 
					If no match is possible, the window moves
 | 
				
			||||||
 | 
					one instruction forwards (to the right).
 | 
				
			||||||
 | 
					After a successful match the matched instructions are
 | 
				
			||||||
 | 
					removed from the window and are replaced by the
 | 
				
			||||||
 | 
					replacement part of the table entry.
 | 
				
			||||||
 | 
					Furthermore, the window is moved a few instructions
 | 
				
			||||||
 | 
					backwards,
 | 
				
			||||||
 | 
					as it is possible that instructions that were rejected earlier now do match.
 | 
				
			||||||
 | 
					For example, consider the following patterns:
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					cmp $0, X           -> tst X ;
 | 
				
			||||||
 | 
					mov REG,X : tst X   -> move REG.X ;   /* redundant test */
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					If the input is:
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					mov r0,foo : cmp $0,foo
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					then the first instruction is initially rejected.
 | 
				
			||||||
 | 
					However, after the transformation
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					cmp $0,foo   ->  tst foo
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					the following optimization is possible:
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					mov r0,foo : tst foo  ->  mov r0,foo
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The window is implemented a a \fIqueue\fR.
 | 
				
			||||||
 | 
					Matching takes place at the head of the queue.
 | 
				
			||||||
 | 
					New instructions are added at the tail.
 | 
				
			||||||
 | 
					If the window is moved forwards, the instruction at the head
 | 
				
			||||||
 | 
					is not yet written to the output,
 | 
				
			||||||
 | 
					as it may be needed later on.
 | 
				
			||||||
 | 
					Instead it is added to a second queue,
 | 
				
			||||||
 | 
					the \fIbackup queue\fR.
 | 
				
			||||||
 | 
					After a successful match, the entire backup queue is
 | 
				
			||||||
 | 
					inserted at the front of the window queue,
 | 
				
			||||||
 | 
					which effectively implements the shift backwards.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					Both queues have the length of the longest pattern in the table.
 | 
				
			||||||
 | 
					If, as a result of a forward window move,
 | 
				
			||||||
 | 
					the backup queue gets full,
 | 
				
			||||||
 | 
					the instruction at its head is outputted and removed.
 | 
				
			||||||
 | 
					Instructions are read from the input whenever the
 | 
				
			||||||
 | 
					window queue contains fewer elements than the length
 | 
				
			||||||
 | 
					of the longest pattern.
 | 
				
			||||||
 | 
					.NH 2
 | 
				
			||||||
 | 
					Pattern matching
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					Pattern matching is done in three steps:
 | 
				
			||||||
 | 
					.IP (i) 7
 | 
				
			||||||
 | 
					find patterns in the table whose instruction mnemonics
 | 
				
			||||||
 | 
					match the mnemonics of the instructions in the
 | 
				
			||||||
 | 
					current window;
 | 
				
			||||||
 | 
					.IP (ii)
 | 
				
			||||||
 | 
					check if the operands of the pattern match the operands of the
 | 
				
			||||||
 | 
					instructions in the current window;
 | 
				
			||||||
 | 
					.IP (iii)
 | 
				
			||||||
 | 
					check if the optional constraint is satisfied.
 | 
				
			||||||
 | 
					.LP
 | 
				
			||||||
 | 
					For step (i) hashing is used.
 | 
				
			||||||
 | 
					The mnemonic of the first instruction of the window
 | 
				
			||||||
 | 
					is used to determine a list of possible patterns.
 | 
				
			||||||
 | 
					Patterns starting with ANY are always tried.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					Matching of operand descriptions against actual operands
 | 
				
			||||||
 | 
					takes place as follows.
 | 
				
			||||||
 | 
					The general form of an operand description is:
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					string_constant1 variable_name string_constant2
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					The actual operand should begin with string_constant1 and end
 | 
				
			||||||
 | 
					on string_constant2.
 | 
				
			||||||
 | 
					If so, these strings are stripped from it and the remaining string is
 | 
				
			||||||
 | 
					matched against the variable.
 | 
				
			||||||
 | 
					Matching a string against a variable is
 | 
				
			||||||
 | 
					defined as follows:
 | 
				
			||||||
 | 
					.IP 1.
 | 
				
			||||||
 | 
					initially (before the entire pattern match)
 | 
				
			||||||
 | 
					all variables are uninstantiated;
 | 
				
			||||||
 | 
					.IP 2.
 | 
				
			||||||
 | 
					matching a string against an uninstantiated variable
 | 
				
			||||||
 | 
					succeeds if the restriction associated with the variable is
 | 
				
			||||||
 | 
					satisfied.
 | 
				
			||||||
 | 
					As a side effect, it causes the variable to be instantiated to
 | 
				
			||||||
 | 
					the string;
 | 
				
			||||||
 | 
					.IP 3.
 | 
				
			||||||
 | 
					matching a string against an instantiated variable succeeds
 | 
				
			||||||
 | 
					only if the variable was instantiated to the same string.
 | 
				
			||||||
 | 
					.LP
 | 
				
			||||||
 | 
					Matching an actual mnemonic against the keyword ANY is defined likewise.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The matching scheme implements the requirement that multiple occurrences
 | 
				
			||||||
 | 
					of the same variable name or of the keyword ANY should
 | 
				
			||||||
 | 
					stand for the same values throughout the entire pattern
 | 
				
			||||||
 | 
					(see section 2.).
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					Both the parameter restriction of 2. and the constraint of step (iii)
 | 
				
			||||||
 | 
					are checked by executing the "C" expression.
 | 
				
			||||||
 | 
					.NH 2
 | 
				
			||||||
 | 
					Data structures
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The most important data structure is the representation
 | 
				
			||||||
 | 
					of the input instructions.
 | 
				
			||||||
 | 
					For every instruction we use two representations:
 | 
				
			||||||
 | 
					.IP (i)
 | 
				
			||||||
 | 
					the textual representation,
 | 
				
			||||||
 | 
					i.e. the exact code as it appeared in the input;
 | 
				
			||||||
 | 
					.IP (ii)
 | 
				
			||||||
 | 
					a structural representation,
 | 
				
			||||||
 | 
					containing the opcode and the operands.
 | 
				
			||||||
 | 
					.LP
 | 
				
			||||||
 | 
					The opcode of an instruction is determined as soon as it is read.
 | 
				
			||||||
 | 
					If the line contains a label definition, the opcode is set
 | 
				
			||||||
 | 
					to "labdef", so a label definition is treated like a normal
 | 
				
			||||||
 | 
					instruction.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The operands of an instruction are not determined until
 | 
				
			||||||
 | 
					they are needed, i.e. until step (i) of the pattern matching
 | 
				
			||||||
 | 
					process has succeeded.
 | 
				
			||||||
 | 
					For every instruction we keep track of a \fIstate\fR.
 | 
				
			||||||
 | 
					After the opcode has successfully been determined,
 | 
				
			||||||
 | 
					the state is OPC_ONLY.
 | 
				
			||||||
 | 
					Once the operands have been recognized, the state is set to DONE.
 | 
				
			||||||
 | 
					If the opcode or operands can not be determined,
 | 
				
			||||||
 | 
					or if the instruction cannot be optimized for any other
 | 
				
			||||||
 | 
					reason (see Appendix A), the state is set to JUNK
 | 
				
			||||||
 | 
					and any attempt to match it will fail.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					For each table entry we record the following information:
 | 
				
			||||||
 | 
					.IP (i) 7
 | 
				
			||||||
 | 
					the length of the pattern (i.e. the number of instruction descriptions)
 | 
				
			||||||
 | 
					.IP (ii)
 | 
				
			||||||
 | 
					a description of the instructions of the pattern
 | 
				
			||||||
 | 
					.IP (iii)
 | 
				
			||||||
 | 
					the length of the replacement
 | 
				
			||||||
 | 
					.IP (iv)
 | 
				
			||||||
 | 
					a description of the instructions of the replacement.
 | 
				
			||||||
 | 
					.LP
 | 
				
			||||||
 | 
					The description of an instruction consists of:
 | 
				
			||||||
 | 
					.IP (i)
 | 
				
			||||||
 | 
					the opcode
 | 
				
			||||||
 | 
					.IP (ii)
 | 
				
			||||||
 | 
					for each operand, a description of the operand.
 | 
				
			||||||
 | 
					.LP
 | 
				
			||||||
 | 
					The description of an operand of the form:
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					string_constant1 variable_name string_constant2
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					contains:
 | 
				
			||||||
 | 
					.IP (i)
 | 
				
			||||||
 | 
					both string constants
 | 
				
			||||||
 | 
					.IP (ii)
 | 
				
			||||||
 | 
					the number of the variable.
 | 
				
			||||||
 | 
					.LP
 | 
				
			||||||
 | 
					Each declared variable is assigned a unique number.
 | 
				
			||||||
 | 
					For every variable we maintain:
 | 
				
			||||||
 | 
					.IP (i)
 | 
				
			||||||
 | 
					its state (instantiated or not instantiated)
 | 
				
			||||||
 | 
					.IP (ii)
 | 
				
			||||||
 | 
					its current value (a string).
 | 
				
			||||||
 | 
					.LP
 | 
				
			||||||
 | 
					The restrictions on variables and the constraints are stored
 | 
				
			||||||
 | 
					in a switch-statement,
 | 
				
			||||||
 | 
					indexed by variable number and entry number respectively.
 | 
				
			||||||
 | 
					.bp
 | 
				
			||||||
 | 
					.NH 1
 | 
				
			||||||
 | 
					Implementation of the target optimizer generator
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The target optimizer generator (\fItopgen\fR)
 | 
				
			||||||
 | 
					reads a target machine description table and produces
 | 
				
			||||||
 | 
					two files:
 | 
				
			||||||
 | 
					.IP gen.h: 9
 | 
				
			||||||
 | 
					contains macro definitions for
 | 
				
			||||||
 | 
					machine parameters that were changed
 | 
				
			||||||
 | 
					in the parameter section of the table (see appendix A)
 | 
				
			||||||
 | 
					and for some attributes derived from the table
 | 
				
			||||||
 | 
					(longest pattern, number of patterns, number
 | 
				
			||||||
 | 
					of variables).
 | 
				
			||||||
 | 
					.IP gen.c:
 | 
				
			||||||
 | 
					contains the entry description tables,
 | 
				
			||||||
 | 
					code for checking the parameter restrictions and constraints
 | 
				
			||||||
 | 
					(switch statements)
 | 
				
			||||||
 | 
					and the user-defined procedures.
 | 
				
			||||||
 | 
					.LP
 | 
				
			||||||
 | 
					These two files are compiled together with some machine-independent
 | 
				
			||||||
 | 
					files to produce a target optimizer.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					Topgen is implemented using 
 | 
				
			||||||
 | 
					the LL(1) parser generator system LLgen,
 | 
				
			||||||
 | 
					a powerful tool of the Amsterdam Compiler Kit.
 | 
				
			||||||
 | 
					This system provides a flexible way of describing the syntax of the tables.
 | 
				
			||||||
 | 
					The syntactical description of the table format included
 | 
				
			||||||
 | 
					in Appendix A was derived from the LLgen syntax rules.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The parser uses a simple, hand-written, lexical analyzer (scanner).
 | 
				
			||||||
 | 
					The scanner returns a single character in most cases.
 | 
				
			||||||
 | 
					The recognition of identifiers is left to the parser, as
 | 
				
			||||||
 | 
					this eases the analysis of operand descriptions.
 | 
				
			||||||
 | 
					Comments are removed from the input by the scanner,
 | 
				
			||||||
 | 
					but white space is passed to the parser,
 | 
				
			||||||
 | 
					as it is meaningful in some contexts (it separates the
 | 
				
			||||||
 | 
					opcode description from the description of the first operand).
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					Topgen maintains two symbol tables, one for variable names and one
 | 
				
			||||||
 | 
					for tunable parameters.
 | 
				
			||||||
 | 
					The symbol tables are organized as binary trees.
 | 
				
			||||||
 | 
					.bp
 | 
				
			||||||
 | 
					.SH
 | 
				
			||||||
 | 
					Appendix A
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					In this appendix we present a complete definition of the target
 | 
				
			||||||
 | 
					optimizer description table format.
 | 
				
			||||||
 | 
					This appendix is intended for table-writers.
 | 
				
			||||||
 | 
					We use syntax rules for the description of the table format.
 | 
				
			||||||
 | 
					The following notation is used:
 | 
				
			||||||
 | 
					.nf
 | 
				
			||||||
 | 
					      { a }      zero or more of a
 | 
				
			||||||
 | 
					      [ a ]      zero or one of a
 | 
				
			||||||
 | 
					      a b        a followed by b
 | 
				
			||||||
 | 
					      a | b      a or b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.fi
 | 
				
			||||||
 | 
					Terminals are given in quotes, as in ';'.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The table may contain white space and comment at all reasonable places.
 | 
				
			||||||
 | 
					Comments are as in "C", so they begin with /* and end on */.
 | 
				
			||||||
 | 
					Identifiers are sequences of letters, digits and the underscore ('_'),
 | 
				
			||||||
 | 
					beginning with a letter.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					table   ->   {parameter_line} '%%;' {variable_declaration} '%%;'
 | 
				
			||||||
 | 
					             {entry} '%%;' user_routines.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					A table consists of four sections, containing machine-dependent
 | 
				
			||||||
 | 
					constants, variable declarations, pattern rules and
 | 
				
			||||||
 | 
					user-supplied subroutines.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					parameter_line ->  identifier value ';' .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					A parameter line defines some attributes of the target machines
 | 
				
			||||||
 | 
					assembly code.
 | 
				
			||||||
 | 
					For unspecified parameters default values apply.
 | 
				
			||||||
 | 
					The names of the parameters and the corresponding defaults
 | 
				
			||||||
 | 
					are shown in table 1.
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					       OPC_TERMINATOR       ' '
 | 
				
			||||||
 | 
					       OP_SEPARATOR         ','
 | 
				
			||||||
 | 
					       LABEL_STARTER        'I'
 | 
				
			||||||
 | 
					       LABEL_TERMINATOR     ':'
 | 
				
			||||||
 | 
					       MAXOP                  2
 | 
				
			||||||
 | 
					       MAXOPLEN              25
 | 
				
			||||||
 | 
					       MAX_OPC_LEN           10
 | 
				
			||||||
 | 
					       MAXVARLEN             25
 | 
				
			||||||
 | 
					       MAXLINELEN           100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       table 1: parameter names and defaults
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					The OPC_TERMINATOR is the character that separates the instruction
 | 
				
			||||||
 | 
					mnemonic from the first operand (if any).
 | 
				
			||||||
 | 
					The OP_SEPARATOR separates adjacent operands.
 | 
				
			||||||
 | 
					A LABEL_STARTER is the first character of an instruction label.
 | 
				
			||||||
 | 
					(Instruction labels are assumed to start with the same character).
 | 
				
			||||||
 | 
					The LABEL_TERMINATOR is the last character of a label definition.
 | 
				
			||||||
 | 
					It is assumed that this character is not used in an applied
 | 
				
			||||||
 | 
					occurrence of the label identifier.
 | 
				
			||||||
 | 
					For example, the defining occurrence may be "I0017:"
 | 
				
			||||||
 | 
					and the applied occurrence may be "I0017"
 | 
				
			||||||
 | 
					as in "jmp I0017".
 | 
				
			||||||
 | 
					MAXOP defines the maximum number of operands an instruction can have.
 | 
				
			||||||
 | 
					MAXOPLEN is the maximum length (in characters) of an operand.
 | 
				
			||||||
 | 
					MAX_OPC_LEN is the maximum length of an instruction opcode.
 | 
				
			||||||
 | 
					MAXVARLEN is the maximum length of a declared string variable.
 | 
				
			||||||
 | 
					As variables may be set by user routines (see "bitw" example for
 | 
				
			||||||
 | 
					the Vax) the table-writer must have access to this length and
 | 
				
			||||||
 | 
					must be able to change it.
 | 
				
			||||||
 | 
					MAXLINELEN denotes the maximum length of a line of assembly code.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					If a line of assembly code violates any of the assumptions or
 | 
				
			||||||
 | 
					exceeds some limit,
 | 
				
			||||||
 | 
					the line is not optimized.
 | 
				
			||||||
 | 
					Optimization does, however, proceed with the rest of the input.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					variable_declaration  -> identifier {',' identifier} restriction ';' .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					restriction           ->  '{' anything '}' .
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					A variable declaration declares one or more string variables
 | 
				
			||||||
 | 
					that may be used in the patterns and in the replacements.
 | 
				
			||||||
 | 
					If a variable is used as part of an operand description in
 | 
				
			||||||
 | 
					a pattern, the entire pattern can only match if the
 | 
				
			||||||
 | 
					restriction evaluates to TRUE.
 | 
				
			||||||
 | 
					If the pattern does match, the variable is assigned the matching
 | 
				
			||||||
 | 
					part of the actual operand.
 | 
				
			||||||
 | 
					Variables that are not used in a pattern are initialized to
 | 
				
			||||||
 | 
					null-strings and may be assigned a value in the constraint-part of
 | 
				
			||||||
 | 
					the pattern.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The restriction must be a legal "C" expression.
 | 
				
			||||||
 | 
					It may not contain a closing bracket ('}').
 | 
				
			||||||
 | 
					Inside the expression, the name VAL stands for the part of the actual
 | 
				
			||||||
 | 
					(matching) operand.
 | 
				
			||||||
 | 
					The expression may contain calls to procedures that are defined in the
 | 
				
			||||||
 | 
					user-routines section.
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					entry             ->  pattern '->' replacement ';' .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pattern           ->  instruction_descr
 | 
				
			||||||
 | 
							      { ':' instruction_descr }
 | 
				
			||||||
 | 
							      constraint .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replacement       ->  [ instruction_descr { ':' instruction_descr } ] .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					instruction_descr -> opcode
 | 
				
			||||||
 | 
							     white
 | 
				
			||||||
 | 
							     [ operand_descr { ',' operand_descr } ] .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constraint        -> '{' anything '}' .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					operand_descr     -> [ string_constant ]
 | 
				
			||||||
 | 
							     [ variable_name ]
 | 
				
			||||||
 | 
							     [ string_constant ] .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					variable_name     -> identifier .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					opcode            -> anything .
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					The symbol 'white' stands for white space (space or tab).
 | 
				
			||||||
 | 
					An opcode can be any string not containing the special
 | 
				
			||||||
 | 
					symbols ';', '{', '}', ':', ',', '->' or white space.
 | 
				
			||||||
 | 
					To be recognized, it must begin with a letter.
 | 
				
			||||||
 | 
					The opcode should either be a mnemonic of a target machine
 | 
				
			||||||
 | 
					instruction or it should be one of the keywords ANY and labdef.
 | 
				
			||||||
 | 
					ANY matches any actual opcode. labdef matches only label definitions.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					If an operand description contains an identifier (as defined earlier),
 | 
				
			||||||
 | 
					it is checked if the identifier is the name of a declared variable.
 | 
				
			||||||
 | 
					This effects the semantics of the matching rules for the operand,
 | 
				
			||||||
 | 
					as described in section 2.
 | 
				
			||||||
 | 
					An operand may contain at most one such variable name.
 | 
				
			||||||
 | 
					.PP
 | 
				
			||||||
 | 
					The constraint must be a legal "C" expression, just as the operand restriction.
 | 
				
			||||||
 | 
					It may call user-defined procedures and use or change the value of
 | 
				
			||||||
 | 
					declared variables.
 | 
				
			||||||
 | 
					It may also use the string variable REST,
 | 
				
			||||||
 | 
					which contains the mnemonic of the first instruction of the
 | 
				
			||||||
 | 
					rest of the input. (REST is a null-string if this mnemonic can
 | 
				
			||||||
 | 
					not be determined).
 | 
				
			||||||
 | 
					.DS
 | 
				
			||||||
 | 
					user_routines -> anything .
 | 
				
			||||||
 | 
					.DE
 | 
				
			||||||
 | 
					The remainder of the table consists of user-defined subroutines.
 | 
				
			||||||
 | 
					.bp
 | 
				
			||||||
 | 
					.[
 | 
				
			||||||
 | 
					$LIST$
 | 
				
			||||||
 | 
					.]
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue