2.11BSD/src/lib/pcc/INFO

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.