Copyright (c) 1985 Regents of the University of California. All rights reserved. The Berkeley software License Agreement specifies the terms and conditions for redistribution. @(#)INFO 5.1 (Berkeley) 1/8/86 HOW TO INTERPRET TEMPLATES: Goals (represented by 'visit' fields) indicate the shape of what is produced by using a template: Goal Form of result FOREFF Can be used for just side effects. Used for things like initializing data, or gotos. INAREG Result can end up in a register. INTAREG Result can end up in a scratch register. INBREG Result can end up in an index, address or floating point register -- not used on the VAX. INTBREG The same except for temporary index registers. FORCC Condition codes are set. INTEMP Computes into a temporary location. FORARG Computes a function argument onto the stack. FORREW Forces the code generator to rewrite the tree. Shapes are restrictions on operands: Shape Form of operand SANY Anything. SAREG A register. STAREG A temporary register (one that can be stomped on). SBREG A secondary register -- not used on the VAX. STBREG Ditto except this a temporary register. SCON An int (32-bit or smaller) constant. SCCON A short (16-bit) constant. SSCON A char (8-bit) constant. SZERO The constant 0. SONE The constant 1. SMONE The constant -1. SCC Condition codes. SNAME A constant address; not on the stack or indirect through a pointer. SFLD A bit field. SOREG A value whose address is the sum of a register and an offset. E.g. 8(ap). SSOREG A 'simple' OREG: not a pointer (e.g. rules out *8(ap)). SWADD A value with an offset that is larger than a byte. STARNM A value whose address is at some known address. An indirect value. E.g. *_a, *8(ap). STARREG Indirect through a register with auto-increment or -decrement. Types restrict the type of an operand. There are two ways of representing types in the compiler; one is a specific type that indicates things like indirection, and the other is used as a template for the first. To see whether a type matches a template, you call ttype(). The template variety is what you see in code templates, and has its own typedef, TWORD. Here are some things you can ask for in the way of type templates: Name What it buys you TANY Matches anything 'within reason'. TCHAR Chars. TUCHAR Unsigned chars. TSHORT Shorts. TUSHORT Unsigned shorts. TINT Ints. TLONG Longs. (VAX ints.) TULONG Unsigned longs. TUNSIGNED Any unsigned type. TWORD An integral type the size of an int, or a pointer. TFLOAT Floats. TDOUBLE Doubles. TSTRUCT Structures or unions. TPTRTO A pointer. This must be or'ed in with other types; e.g. TPTRTO|TFLOAT|TDOUBLE matches pointers to floats or pointers to doubles. Can be multiply indirect. TPOINT Complex types -- things with stars or brackets or etc. WPTR Pointer to anything except structures/unions. ANYSIGNED Pointers or signed integral types. ANYUSIGNED Any unsigned integral type. ANYFIXED Any integral type (excludes floating point or structs). The template may request special resources. These are indicated by things in the needs field of a template: Needs Resource wanted NAREG Needs a register. Can be multiplied up to 4 times to get up to 4 registers. NBREG Ditto for secondary registers (not used on the VAX). NASL Can share a register with the left operand. NASR Can share a register with the right operand. NTEMP Needs stack space. Can be multiplied up to 8 times. EITHER Don't settle for some of A and some of B. The template indicates where the results end up, too. The symbols in the rewrite field have the following meanings: Result Where the result is RNULL Don't care about the result -- clobber it. RLEFT Register associated with the left operand. RRIGHT Register associated with the right operand. RESC1 First register requested by 'needs'. RESC2 Second register requested by 'needs'. RESC3 Third register requested by 'needs'. RESCC The condition codes. RNOP Doesn't make anything -- e.g. initializations, gotos. The assembly language templates contain capital letter abbreviations which are expanded in context to whatever is useful. These abbreviations may be 1, 2 or 3 characters long; the first character codes for the length and generally tells what to do. A standard second or third character often indicates the location of an object in the following way: Modifier Meaning L Left operand. R Right operand 1, 2, 3 Nth requested register (from 'needs'). Below are the various abbreviations; 'n' is used to indicate one of the standard modifiers: Abbreviation Rewrites as An Address of operand n -- the most common abbreviation. Produces register names, externals, almost everything. Bn Byte offset in a word (? -- not used on VAX). Cn Only constants may be written this way. F The rest of the line is ignored if this value is only being computed for side effects. H Field shift; used with masks and bit fields. In Illegal -- not currently used. L A label. M Field mask. N Field mask, complemented. O[BWLFD] Opcode string; used to rewrite operands of templates with generic opcodes like add, sub, mul. The modifier is changed to lower case and appended. For example if the template is OPFLOAT, the abbreviation is 'OD2' and the current node's operand is OPMUL, you get 'muld2'. S Field size. T Rewriting of the register type is suppressed. I'm not sure what's going on but here's the explanation: 'The C language requires intermediate results to change type. This is inefficient or impossible on some machines; the "T" command in match supresses this type changing.' Un Illegal -- not currently used. Zx Local abbreviations (zzzcode()). The x's are spelled out below: ZA Used for straightforward conversions and assignments. Clever perhaps to excess in its coding. ZB Gets difficult shapes into register prior to a shift. ZC Interpolates the argument count in a function call. ZD Get the value of the operand, then increment or decrement the original, depending on the opcode. ZE Increment or decrement the operand. ZF Produces 'd', 'f' or 'l' depending on whether the right operand (the node itself, for unary operators) is double, float or long; used for moves into register. ZI Produces the appropriate conditional branch. ZL Opcode type [bwlfd] for the left operand. ZN Produces a jump and a clear to get logical values converted into 0 or 1. ZP Just like ZI. ZR Opcode type [bwlfd] for the right operand. ZS Generates a structure assignment. ZT Rounds up structure lengths for struct arguments. ZU Subtracts the value of the constant right operand from 32 and uses that for unsigned right shift offsets. ZZ Complements the value of the constant right operand of a bit instruction and produces it.