[comp.unix.questions] HELP needed with inline expansions!!!

rcvie@tuvie (ELIN Forsch.z.) (01/21/88)

Programming in C I urgently need to improve the runtime of one of my programs.
Reading the UNIX Commands Reference Manual I detected that there is the
possibility of adding filenames with extension .il as in-line expansion
template files to the cc command line. This seems to be one way of improving
runtime. The program inline is even invoked by cc if there is such a filename
on my command line but I cannot find any further hint how to produce a correct
.il file. For this reason inline has no effect on my generated object file
either. Please help me how to use this UNIX feature.

			Many thanks in advance,
				Dietmar Weickert,
				ALCATEL-ELIN Research Center, Vienna, Austria

ok@quintus.UUCP (Richard A. O'Keefe) (01/23/88)

In article <563@tuvie>, rcvie@tuvie (ELIN Forsch.z.) writes:
> Please help me .. use .. in-line expansion template files.
This is a BSD-ism.  It should be described somewhere in your manual set.
If you are using SUNs, check the
	"Floating-Point Programmer's Guide for the Sun Workstation".
Whatever you are using, look in
	/usr/lib/
for examples (e.g. /usr/lib/pc2.il).  I learned how to use .il files
from reading these examples.

Basically, a .il file is a collection of definitions

	.inline	<function name>,<#bytes popped from stack>
	<instructions>		^ this may be different on a VAX
	.end

What this thing does is to take function calls which have already
been compiled as function calls and replace them by your in-line
expansions.  The <function name> is the full thing, e.g. for C
it is _{C name} and for Fortran it is _{lower cased Fortran name}_
Within the <instructions> you should assume that the arguments
have already been pushed on the stack.  You can use the registers
that function calls do not preserve (on a 680x0, d0..d2, a0..a1,
and maybe some others).  Your expansion should pop the arguments
from the stack.  This will probably be optimised away.

For example, suppose that the IEEE function copysign(x,y) did not
exist, and you wanted to implement it as an in-line function.

| copysign.il
| Implement double copysign(double x, double y)

	.inline	_copysign,16
	movl	sp@+,d0	| d0 := x.highbits
	bclr	#31,d0	| d0 := abs(x).highbits
	movl	sp@+,d1	| d1 := x.lowbits
	tstl	sp@+	| test y.sign
	bges	1f	| if y.sign == 1 then
	  bset	#31,d0	|    d0.sign := 1
1:			| endif
	addql	#4,sp	| discard y.lowbits
	.end

The SUN 3.2 C compiler, presented with
	x = copysign(x, y);
this inline file, and the -O option, produced
	movl	a6@(-12),sp@-	{low bits of y}
	movl	a6@(-8),d0	{high bits of x}
	bclr	#31,d0
	movl	a6@(-4),d1	{low bits of x}
	tstl	a6@(-16)	{high bits of y}
	bges	LX1000000
	bset	#31,d0
LX1000000:
	addql	#4,sp
	movl	d0,a6@(-8)	{set high bits of x}
	movl	d1,a6@(-4)	{set low bits of x}

This is particularly useful for things like overflow-checked
arithmetic.  For example,
	.inline	_ov_add,8
	movl	sp@+,d0
	addl	sp@+,d0
	trapv
	.end